Mon, 30 Jul 2018 22:47:02 +0000/home/kaizhang@bearzk's blog
https://kaizhang.de/
Mon, 30 Jul 2018 22:47:02 +0000Mon, 30 Jul 2018 22:47:02 +0000Jekyll v3.7.3Migrate Homebrewed MySQL from OS X to macOS<p><img src="https://cloud.githubusercontent.com/assets/775611/18817718/bdb52116-8367-11e6-9312-6ebccfc2ec8a.png" alt="mysql" />
<img src="https://cloud.githubusercontent.com/assets/775611/18817715/aea511cc-8367-11e6-8d3f-cd57d78b708e.png" alt="homebrew" /></p>
<p>So Apple has released newer version of its OS, reusing the old name macOS. As
always I upgrade my working system to macOS, then <a href="http://brew.sh/">homebrewed</a>
MySQL won’t work anymore, to be precise, it cannot do <code class="highlighter-rouge">write</code> anymore.</p>
<p>In this post I will write down what I’ve done to make it work again, even with all
data kept. Hope it will help someone digging around for hours but still no clue.</p>
<p>Basically what I do is to reinstall <a href="https://www.mysql.com/">MySQL</a> with homebrew.
As usual I did a upgrade with:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>brew upgrade mysql</code></pre></figure>
<p>but no, no difference, still cannot write.</p>
<p>Then I removed MySQL with:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>brew uninstall mysql
<span class="nv">$ </span>brew prune mysql
<span class="nv">$ </span>brew cleanup</code></pre></figure>
<p>After this all MySQL binaries are removed from my system, but still there were
database default files and databases left in <code class="highlighter-rouge">/usr/local/var/mysql</code>. And here the
databases and innodb files should be kept.</p>
<p>I copied all these to another place and delete every other thing:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>cp /usr/local/var/mysql/ib<span class="k">*</span> /path/to/my_back_up_folder/.
<span class="nv">$ </span>cp <span class="nt">-R</span> /usr/local/var/mysql/<span class="o">{</span>database1, database2<span class="o">}</span> /path/to/my_back_up_folder/.
<span class="nv">$ </span>rm <span class="nt">-rf</span> /usr/local/var/mysql</code></pre></figure>
<p>Then I did a fresh MySQL install with homebrew and copied back all the backuped
files, start MySQL:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>homebrew install MySQL
<span class="nv">$ </span>cp <span class="nt">-R</span> /path/to/my_back_up_folder/<span class="o">{</span>database1, database2<span class="o">}</span> /usr/local/var/mysql/.
<span class="nv">$ </span>brew services start mysql</code></pre></figure>
<p>Finally MySQL is working, all my old databases are all kept!</p>
Sat, 24 Sep 2016 20:23:56 +0000
https://kaizhang.de/2016/09/24/Migrate-Homebrewed-MySQL-from-OS-X-to-macOS.html
https://kaizhang.de/2016/09/24/Migrate-Homebrewed-MySQL-from-OS-X-to-macOS.htmlMySQLOSXmacOSAuto deploy to AWS with CircleCI and Opsworks<p><img src="https://cloud.githubusercontent.com/assets/775611/13204595/1b16fa26-d8d4-11e5-81e2-5ca93371ab15.png" alt="please deploy" /></p>
<p>When we develop a feature, eventually we will want to see it running on a staging
server and test it, or simply the code reviewer would like to do the same.</p>
<p>The old way is to <code class="highlighter-rouge">git pull</code> our branch on the staging server, later we have opsworks,
much better, but still, have to click a few buttons to have it done.</p>
<p>Then I finally found a way to auto deploy my feature branch when all tests passed
on CircleCI. So in the <code class="highlighter-rouge">circle.yml</code> file you can write:</p>
<figure class="highlight"><pre><code class="language-yml" data-lang="yml"><span class="na">deployment</span><span class="pi">:</span>
<span class="na">staging</span><span class="pi">:</span>
<span class="na">branch</span><span class="pi">:</span> <span class="s">/feature\/.*|develop/</span>
<span class="na">commands</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">aws opsworks update-app --region <region-name> --app-id <app-id> --app-source Revision="${CIRCLE_BRANCH}"</span>
<span class="pi">-</span> <span class="s">aws opsworks create-deployment --region <region-name> --app-id <app-id> --command "{\"Name\":\"deploy\"}" --comment="CircleCI deploy staging"</span></code></pre></figure>
<p>that means when some code in <code class="highlighter-rouge">develop</code> branch or any feature branch, if code passed
tests, update the app’s revision on aws firstly, then deploy it. Yes, this simple :)</p>
<p>related docs can be found at <a href="https://circleci.com/docs/introduction-to-continuous-deployment">cicle</a>,
<a href="http://docs.aws.amazon.com/cli/latest/reference/opsworks/update-app.html">awscli update-app</a> and
<a href="http://docs.aws.amazon.com/cli/latest/reference/opsworks/create-deployment.html">awscli create-deployment</a>.</p>
Sun, 21 Feb 2016 18:13:00 +0000
https://kaizhang.de/2016/02/21/Auto-deploy-to-aws-with-circleci-and-opsworks.html
https://kaizhang.de/2016/02/21/Auto-deploy-to-aws-with-circleci-and-opsworks.htmlAWSAPI Content Structures Pros and Cons<p>From today on I will write down notes of what I’ve learned from the book
“Build APIS You Won’t Hate”.</p>
<p>Today the topic is about the response content structure.</p>
<h2 id="json-api">JSON-API</h2>
<p>The famous <a href="http://jsonapi.org/format">JSON-API</a> suggests to use <code class="highlighter-rouge">plural key</code> for
both single resources and resource collections.</p>
<figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w">
</span><span class="s2">"users"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bearzk"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"users"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bearzk"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tom"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span></code></pre></figure>
<h3 id="pros">Pros</h3>
<ul>
<li>consistent response, always very same structure</li>
</ul>
<h3 id="cons">Cons</h3>
<ul>
<li>could be confusing to human when first time see it</li>
</ul>
<h2 id="twitter-style">Twitter Style</h2>
<p>Twitter uses another strategy instead, it will give you single thing or collection
of things when you asked differently.</p>
<figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bearzk"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bearzk"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tom"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span></code></pre></figure>
<h3 id="pros-1">Pros</h3>
<ul>
<li>minimalistic response</li>
</ul>
<h3 id="cons-1">Cons</h3>
<ul>
<li>no possibility for pagination or other meta info</li>
</ul>
<h2 id="facebook-style">Facebook Style</h2>
<p>Ask for one, get one.</p>
<figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bearzk"</span><span class="w">
</span><span class="p">}</span></code></pre></figure>
<p>Ask for more, get more, namespaced.</p>
<figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w">
</span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bearzk"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tom"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span></code></pre></figure>
<h3 id="pros-2">Pros</h3>
<ul>
<li>Space for pagination and other meta info</li>
<li>Simplistic response with extra namespace</li>
</ul>
<h3 id="cons-2">Cons</h3>
<ul>
<li>Single item has no other way than embedding to have meta info</li>
</ul>
<h2 id="baywh-style">BAYWH Style</h2>
<p>always with name space, also when other object wrapped within.</p>
<figure class="highlight"><pre><code class="language-json" data-lang="json"><span class="p">{</span><span class="w">
</span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bearzk"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bearzk"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tom"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="p">,</span><span class="w">
</span><span class="s2">"name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bearzk"</span><span class="p">,</span><span class="w">
</span><span class="s2">"comments"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="s2">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"1234"</span><span class="p">,</span><span class="w">
</span><span class="s2">"text"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Awesome API!"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="s2">"id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"4321"</span><span class="p">,</span><span class="w">
</span><span class="s2">"text"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Yeah!"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="err">page</span><span class="p">:</span><span class="w"> </span><span class="s2">"1"</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span></code></pre></figure>
<h3 id="pros-3">Pros</h3>
<ul>
<li>generic root scope</li>
<li>easily wrapping other meta info into <code class="highlighter-rouge">data</code> scope</li>
</ul>
<h3 id="cons-3">Cons</h3>
<ul>
<li>any? :)</li>
</ul>
Tue, 02 Feb 2016 21:38:00 +0000
https://kaizhang.de/2016/02/02/API-Content-Structures-Pros-and-Cons.html
https://kaizhang.de/2016/02/02/API-Content-Structures-Pros-and-Cons.htmlAPIMultiple virtual hosts with Nginx<p>When we develop web applications, we have to test on our local boxes firstly.
In this case it always comes in handy if we could use a web server to serve the
application just like we plan to use on production server. When we have many
apps, a step further, when we want them talking to each other, we will have
to use virtual hosts. And this is quite simple in nginx.</p>
<p>Here’s one simple config file for 2 virtual hosts in nginx.</p>
<figure class="highlight"><pre><code class="language-nginx" data-lang="nginx"><span class="k">http</span> <span class="p">{</span>
<span class="kn">include</span> <span class="s">mime.types</span><span class="p">;</span>
<span class="kn">default_type</span> <span class="nc">application/octet-stream</span><span class="p">;</span>
<span class="kn">sendfile</span> <span class="no">on</span>
<span class="s">keepalive_timeout</span> <span class="mi">65</span><span class="p">;</span>
<span class="kn">gzip</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">gzip_disable</span> <span class="s">msie6</span><span class="p">;</span>
<span class="kn">gzip_comp_level</span> <span class="mi">6</span><span class="p">;</span>
<span class="kn">gzip_min_length</span> <span class="mi">1100</span><span class="p">;</span>
<span class="kn">gzip_buffers</span> <span class="mi">16</span> <span class="mi">8k</span><span class="p">;</span>
<span class="kn">gzip_proxied</span> <span class="s">any</span><span class="p">;</span>
<span class="kn">gzip_types</span> <span class="nc">text/plain</span>
<span class="nc">application/xml</span>
<span class="nc">text/css</span>
<span class="nc">text/js</span>
<span class="nc">text/xml</span>
<span class="nc">application/x-javascript</span>
<span class="nc">text/javascript</span>
<span class="nc">application/json</span>
<span class="nc">application/xml</span><span class="s">+rss</span><span class="p">;</span>
<span class="kn">gzip_vary</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">app1.dev</span> <span class="s">*.app1.dev</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/path_to_app1_root/public</span><span class="p">;</span>
<span class="kn">index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">app2.dev</span> <span class="s">*.app2.dev</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/path_to_app2_root/public</span><span class="p">;</span>
<span class="kn">index</span> <span class="s">index.py</span>
<span class="err">}</span>
<span class="err">}</span></code></pre></figure>
<p>Now let’s break it down.</p>
<p>Firstly is the top-level block, we are defining a http server, which has many default
settings, the served types, gzip setting and such. All these you can find in official
manual.</p>
<p>The most important part is the code below.</p>
<figure class="highlight"><pre><code class="language-nginx" data-lang="nginx"><span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">app1.dev</span> <span class="s">*.app1.dev</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/path_to_app1_root/public</span><span class="p">;</span>
<span class="kn">index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">app2.dev</span> <span class="s">*.app2.dev</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/path_to_app2_root/public</span><span class="p">;</span>
<span class="kn">index</span> <span class="s">index.py</span>
<span class="err">}</span></code></pre></figure>
<p>Here we defined two virtual hosts.</p>
<ul>
<li>Both of them listen to port 80,</li>
<li>check the requested server with <code class="highlighter-rouge">server_name</code>, if matched, process it.</li>
<li>then it should deliver result from <code class="highlighter-rouge">root</code> with content of <code class="highlighter-rouge">index</code></li>
</ul>
<p><img src="https://cloud.githubusercontent.com/assets/775611/11459658/e879d474-96db-11e5-984d-a6198415c7b4.png" alt="two-hosts" /></p>
<p>In this above example we only serve 2 static pages, but you more or less get the
idea how the structure of this config should look like.</p>
<hr />
<p>What if we actually want to serve few dynamic sites? Of course that’s also possbile!
Inside each server block you need to tell nginx how should it talk to your apps,
for example with following php app running with php-fpm:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">listen <span class="o">=</span> /path_to_php-fpm.sock</code></pre></figure>
<p>Here we let nginx talk to php-fpm with unix-socket, for example in app1:</p>
<figure class="highlight"><pre><code class="language-nginx" data-lang="nginx"><span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">app1.dev</span> <span class="s">*.app1.dev</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/path_to_app1_root/public</span><span class="p">;</span>
<span class="kn">index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="c1"># If file does not exist invoke index.php
</span> <span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri</span><span class="n">/</span> <span class="n">/index.php?</span><span class="nv">$args</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1"># Forward PHP files to FPM
</span> <span class="kn">location</span> <span class="p">~</span> <span class="sr">\.php$</span> <span class="p">{</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="p">=</span><span class="mi">404</span><span class="p">;</span>
<span class="kn">fastcgi_read_timeout</span> <span class="mi">14400</span><span class="p">;</span>
<span class="kn">fastcgi_split_path_info</span> <span class="s">^(.+</span><span class="err">\</span><span class="s">.php)(/.+)</span>$<span class="p">;</span>
<span class="kn">fastcgi_pass</span> <span class="s">unix:/path_to_php-fpm.sock</span><span class="p">;</span>
<span class="kn">fastcgi_index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="kn">include</span> <span class="s">fastcgi_params</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">SCRIPT_FILENAME</span> <span class="nv">$document_root$fastcgi_script_name</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">OPENDI_ENV</span> <span class="s">local</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">SERVER_NAME</span> <span class="s">"App1</span> <span class="no">on</span> <span class="s">my</span> <span class="s">local</span> <span class="s">box"</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span></code></pre></figure>
<p>Above are just simple settings for 2 apps, you can extend them to your usage and
make several apps running at same time on your machine :) Please leave a comment
if you have any question!</p>
Sun, 29 Nov 2015 18:15:00 +0000
https://kaizhang.de/2015/11/29/Multiple-virtual-hosts-with-Nginx.html
https://kaizhang.de/2015/11/29/Multiple-virtual-hosts-with-Nginx.htmlnginxSetting up xdebug for PhpStorm on OSX<p><img src="https://cloud.githubusercontent.com/assets/775611/11454143/7d2e016c-9623-11e5-817c-2b1a21a9d7f8.png" alt="xdebug" /></p>
<p>Maybe it was only me, but it really took me quite long to figure out how to enable
xdebug for Phpstorm and debug my php code with it, now I have to record this whole
process.</p>
<h3 id="1-install-php-and-xdebug">1. Install PHP and xdebug</h3>
<p>The PHP comes with the OSX isn’t optimal for what we want to do here, since we plan
to use <a href="http://brew.sh/">Homebrew</a> as our package management software as much as
possible. You can install PHP with following command:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>brew install php56 php56-xdebug</code></pre></figure>
<h3 id="2-enable-xdebug">2. Enable xdebug</h3>
<p>Now the xdebug is installed, we want to enable it. The <code class="highlighter-rouge">ini</code> file for brewed PHP
should be at <code class="highlighter-rouge">/usr/local/etc/php/5.6/conf.d/ext-xdebug.ini</code>. It should contain:</p>
<figure class="highlight"><pre><code class="language-ini" data-lang="ini"><span class="nn">[xdebug]</span>
<span class="py">zend_extension</span><span class="p">=</span><span class="s">"/usr/local/opt/php56-xdebug/xdebug.so"</span>
<span class="py">xdebug.remote_enable</span> <span class="p">=</span> <span class="s">1</span>
<span class="py">xdebug.remote_port</span> <span class="p">=</span> <span class="s">9000</span>
<span class="py">xdebug.profiler_enable</span> <span class="p">=</span> <span class="s">1</span>
<span class="py">xdebug.profiler_output_dir</span><span class="p">=</span><span class="s">"/tmp"</span>
<span class="py">xdebug.profiler_enable_trigger</span> <span class="p">=</span> <span class="s">1</span></code></pre></figure>
<p>here the very important attributes are <code class="highlighter-rouge">xdebug.remote_enable</code> and <code class="highlighter-rouge">xdebug.remote_port</code>.</p>
<h3 id="3-configure-phpstorm">3. Configure PhpStorm</h3>
<p>In Phpstorm the configuration for xdebug is at <code class="highlighter-rouge">Preference > Languages & Framework > PHP > Debug > Xdebug</code>
remember to change the debug port to what we have in previous step and mark <code class="highlighter-rouge">Can accept external connections</code>.</p>
<p><img src="https://cloud.githubusercontent.com/assets/775611/11454124/e077fc9c-9622-11e5-9b40-bbf7f5c799b0.png" alt="PhpStorm Preference" /></p>
<h3 id="4-debug-with-xdebug-in-phpstorm">4. Debug with Xdebug in PhpStorm</h3>
<p>Now open your project and click on the <code class="highlighter-rouge">listen to the debug button connections</code>
in PhpStorm.</p>
<p><img src="https://cloud.githubusercontent.com/assets/775611/11454151/d682414c-9623-11e5-953c-27c1d2fa3c88.png" alt="Listing to the debug connections" /></p>
<p>Set a break point by click on the gutter of your code. Then start your php server
and open the page you want to debug, append this query <code class="highlighter-rouge">?XDEBUG_SESSION_START=true</code>
at the end of the url, refresh page …</p>
<p><img src="https://cloud.githubusercontent.com/assets/775611/11454203/ef3043c8-9624-11e5-8f51-d876f7799ca1.png" alt="url" /></p>
<p>Voila, now you can debug your code in PhpStorm with xdebug!</p>
<p><img src="https://cloud.githubusercontent.com/assets/775611/11454229/64dcfe72-9625-11e5-97ee-aef34944ce25.png" alt="xdebug in phpstorm" /></p>
Sat, 28 Nov 2015 19:40:00 +0000
https://kaizhang.de/2015/11/28/Setting-up-xdebug-for-PhpStorm-on-OSX.html
https://kaizhang.de/2015/11/28/Setting-up-xdebug-for-PhpStorm-on-OSX.htmlPHPOSXxdebugCreate laravel project on local machine<p>Today my wife asked me to set up <code class="highlighter-rouge">laravel</code> on her box, so she could finally start
to learn some serious PHP.</p>
<p>Then I asked a question: “There must be tutorials or docs for such task. Have
you check them all out?”</p>
<p>“Yes, I have. But the official site told me to install some vagrant thingy first,
I don’t understand what that is and why.”</p>
<p>Then I briefly browsed the <code class="highlighter-rouge">laravel</code> doc, section installation. Truly, vagrant
is a good option for experienced developer because of many reasons, but for
starter, can you just help them to start an example <code class="highlighter-rouge">laravel</code> app?</p>
<p>Within 10 mins, including downloading and installing time, I already got an
<code class="highlighter-rouge">laravel</code> instance running on her machine, without using any virtual machine or
similar. following is how it was set up on OSX:</p>
<h3 id="install-php-and-composer">Install php and composer</h3>
<p>If you don’t have <code class="highlighter-rouge">php</code>, <code class="highlighter-rouge">composer</code> and <code class="highlighter-rouge">mysql</code>, then just install them with:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>brew install php56 mysql
<span class="nv">$ </span>curl <span class="nt">-sS</span> https://getcomposer.org/installer | php</code></pre></figure>
<h3 id="install-laravel-installer">Install laravel installer</h3>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>composer global require <span class="s2">"laravel/installer=~1.1"</span></code></pre></figure>
<h3 id="create-a-laravel-app">Create a laravel app</h3>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>laravel new myapp</code></pre></figure>
<h3 id="just-start-it">Just start it</h3>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span><span class="nb">cd </span>myapp
<span class="nv">$ </span>php artisan serve</code></pre></figure>
<p>yes, as this simple. I understand docs want learner to have the exactly same
perfect env like an app would be deployed on. But for a total beginner, to actually
start something is more important than knowing how it should be properly developed.</p>
Sun, 01 Nov 2015 18:21:00 +0000
https://kaizhang.de/2015/11/01/create-laravel-project-on-local-machine.html
https://kaizhang.de/2015/11/01/create-laravel-project-on-local-machine.htmlPHPlaravelOSXProgrammer Quick Questions<blockquote>
<p>Vim or Emacs ?</p>
</blockquote>
<p>Vim</p>
<blockquote>
<p>IDE ?</p>
</blockquote>
<p>highly depends on task/scenario, e.g. IDE when local, vim when ssh.</p>
<blockquote>
<p>Is PHP the best language in the world ?</p>
</blockquote>
<p>From the size of its community, maybe. From its feature and functionality, hehehehe…</p>
<blockquote>
<p>Java/C++/C#/Ruby/Python … sucks ?</p>
</blockquote>
<p>Every language sucks in certain tasks.</p>
<blockquote>
<p>Is HTML a programming language ?</p>
</blockquote>
<p>No.</p>
<blockquote>
<p>Windows, Linux or OSX ?</p>
</blockquote>
<p>Linux for production, OSX for development.</p>
<blockquote>
<p>Which Linux distro is the best ?</p>
</blockquote>
<p>Choose one with bigger community, for now it’s debian based distros, Ubuntu LTS for example.</p>
<blockquote>
<p>Which shell is the best ?</p>
</blockquote>
<p><a href="http://www.zsh.org/">ZSH</a> + <a href="https://github.com/robbyrussell/oh-my-zsh">oh my zsh</a>.</p>
<blockquote>
<p>Indentation with tabs or spaces ?</p>
</blockquote>
<p>Spaces.</p>
<blockquote>
<p>2 spaces or 4 spaces ?</p>
</blockquote>
<p>Depends on the language, 4 as default, 2 if it utilizes many callbacks.</p>
<blockquote>
<p>i++ or ++i ?</p>
</blockquote>
<p>hmmm… i++.</p>
<blockquote>
<p>underscore or camelCase ?</p>
</blockquote>
<p>Depends on the language Convention, e.g. underscore in Python and camelCase in Java.</p>
<hr />
<blockquote>
<p>Vim 还是 Emacs ?</p>
</blockquote>
<p>Vim。</p>
<blockquote>
<p>IDE ?</p>
</blockquote>
<p>本地开发可以用IDE,SSH到服务器就用Vim。</p>
<blockquote>
<p>PHP 是不是世界上最好的语言 ?</p>
</blockquote>
<p>按照社区排的话,也许是。按特性和功能,你开心就好。</p>
<blockquote>
<p>Java/C++/C#/Ruby/Python/… 是不是很烂 ?</p>
</blockquote>
<p>所有语言都有烂的地方,只有合适的语言,没有万能的语言。</p>
<blockquote>
<p>HTML 是不是「编程语言」?</p>
</blockquote>
<p>不是。</p>
<blockquote>
<p>用 Windows 还是 Linux 还是 OSX ?</p>
</blockquote>
<p>生产服务器用Linux,开发机用OSX。</p>
<blockquote>
<p>Linux 各种发行版哪个好 ?</p>
</blockquote>
<p>社区大/活跃的好,目前是各种debian衍生版,比如Ubuntu。</p>
<blockquote>
<p>最好的 Shell 是哪一个 ?</p>
</blockquote>
<p><a href="http://www.zsh.org/">ZSH</a> + <a href="https://github.com/robbyrussell/oh-my-zsh">oh my zsh</a>。</p>
<blockquote>
<p>缩进用空格还是用 Tab ?</p>
</blockquote>
<p>空格。</p>
<blockquote>
<p>4空格还是2空格 ?</p>
</blockquote>
<p>默认4,语言需要回调多的话用2。</p>
<blockquote>
<p>i++ 还是 ++i ?</p>
</blockquote>
<p>呃…i++吧。</p>
<blockquote>
<p>下划线还是驼峰 ?</p>
</blockquote>
<p>看语言的社区约定,比如写Python就用下划线,Java就用驼峰。</p>
Sun, 18 Jan 2015 10:25:04 +0000
https://kaizhang.de/2015/01/18/programmer-quick-questions.html
https://kaizhang.de/2015/01/18/programmer-quick-questions.htmlProgrammerSetting up Ghost on a Raspberry Pi<p>It is fascinating that this small chip-computer could do so much.
Following is how I installed this Ghost Blog on this RPi.</p>
<p>####1st step</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>wget http://nodejs.org/dist/node-latest.tar.gz
<span class="nv">$ </span><span class="nb">tar</span> <span class="nt">-xzf</span> node-latest.tar.gz
<span class="nv">$ </span><span class="nb">cd</span> <span class="o">[</span>node folder]</code></pre></figure>
<p>download node and unarchive it.</p>
<p>####2nd step</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>./configure
<span class="nv">$ </span>make
<span class="nv">$ </span>make install</code></pre></figure>
<p>compile node and install it. please note the <code class="highlighter-rouge">make</code> could take hours, consider using tmux to put it to a separate session.</p>
<p>####3rd step</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span>wget https://ghost.org/zip/ghost-latest.zip
<span class="nv">$ </span>unzip <span class="nt">-d</span> ghost <span class="o">[</span>Name-of-Ghost-zip].zip</code></pre></figure>
<p>download and install Ghost.</p>
<p>####4th Step</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nv">$ </span><span class="nb">cd </span>ghost/
<span class="nv">$ </span><span class="nb">sudo </span>npm install
<span class="nv">$ </span>cp config.example.js config.js</code></pre></figure>
<p>note that <code class="highlighter-rouge">sudo npm install</code> could take some time as well.</p>
<p>Here change all instance of <code class="highlighter-rouge">host: '127.0.0.1'</code> and <code class="highlighter-rouge">port: '2368'</code> to <code class="highlighter-rouge">host: '[ip of RPi]'</code> and <code class="highlighter-rouge">port: '80'</code>, then we can reach ghost from internet.</p>
<p>Finally we can start Ghost with <code class="highlighter-rouge">npm start</code>, please note that we are starting Ghost with default user <code class="highlighter-rouge">pi</code>, so that binding port under <code class="highlighter-rouge">1024</code> is impossible, in this case you will need to run this command with <code class="highlighter-rouge">sudo</code>.</p>
Fri, 16 Jan 2015 01:13:22 +0000
https://kaizhang.de/2015/01/16/setting-up-ghost-on-a-raspberrypi.html
https://kaizhang.de/2015/01/16/setting-up-ghost-on-a-raspberrypi.htmlRaspberryPiGhost