{
    "componentChunkName": "component---src-templates-blog-post-jsx",
    "path": "/post/create-git-hook-to-develop-modern-php/",
    "result": {"data":{"site":{"siteMetadata":{"title":"WEB EGG","author":"Leko - CTO at Yuimedi"}},"markdownRemark":{"id":"7e12e82b-c398-53a0-b1c2-fb186b54eed9","excerpt":"こんにちは。 久々の更新です。 最近Schemaというフレームワークを作っており、 PHPでの開発について色々と新たな知識を得る機会がたくさんあります。 そこでまずは開発環境の構築編として、最低限のお作法を担保する Gitのhook を作成してみました。 目的 –…","html":"<p>こんにちは。<br>\n久々の更新です。</p>\n<p>最近<span class=\"removed_link\" title=\"https://github.com/Leko/schema\">Schema</span>というフレームワークを作っており、<br>\nPHPでの開発について色々と新たな知識を得る機会がたくさんあります。</p>\n<p>そこでまずは開発環境の構築編として、最低限のお作法を担保する <strong>Gitのhook</strong> を作成してみました。</p>\n<!--more-->\n<h2 id=\"目的--5箇条\" style=\"position:relative;\"><a href=\"#%E7%9B%AE%E7%9A%84--5%E7%AE%87%E6%9D%A1\" aria-label=\"目的  5箇条 permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>目的 – 5箇条</h2>\n<p><strong>それくらいきちんとやれよ</strong> という話に尽きるのですが、<br>\n自動で確認してくれるに越したことはありません。<br>\nプログラマは得てして機械的な確認が苦手な生き物です。楽することに全力であるべきです。</p>\n<p>（マジレスをすると、人的要素を排除することで、うっかりや人為的なミスが無くなるので、より確実にコードの品質を担保できます。<br>\nただし、このチェックが通れば完璧というわけではないので、加えて動作確認やコードレビュー等の人的チェックも必要かと思います）。</p>\n<p>と能書きはこのくらいにしておいて、具体的にやりたいことは以下の通りです。</p>\n<ul>\n<li>PHPの構文チェック</li>\n<li>PSRのお作法に反したコードが無いか</li>\n<li>使用してない変数、あまりに長い命名、複雑なループ等を実装してないか</li>\n<li>composer.jsonはvalidになっているか</li>\n<li>テストは通っているか</li>\n</ul>\n<p>上記5点の確認をコミットする前に行い、どれか１つでもコケた場合は <strong>コミットできない</strong> という縛りを加えようと思います。<br>\nさすがに業務や複数人でやるプロジェクトでこれは相当キツイので、<br>\nいくらか縛りを外せば、ちょうどいい感じの制約になると思います。</p>\n<p>それぞれの項目について説明していきます。</p>\n<h3 id=\"1-phpの構文チェック\" style=\"position:relative;\"><a href=\"#1-php%E3%81%AE%E6%A7%8B%E6%96%87%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF\" aria-label=\"1 phpの構文チェック permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. PHPの構文チェック</h3>\n<p>これは5番目のテストとかぶるのですが、<br>\nたまに <strong>自分が書いたコードを一度も実行・確認せずにコミットしやがる輩</strong> が居て、pullした途端に動かなくなるということがあります。</p>\n<p>そんなゴミクズ野郎にならないように、最低限構文エラー起こしてるコードはコミットしないためにチェックします。</p>\n<h3 id=\"2-psrのお作法に反したコードが無いか\" style=\"position:relative;\"><a href=\"#2-psr%E3%81%AE%E3%81%8A%E4%BD%9C%E6%B3%95%E3%81%AB%E5%8F%8D%E3%81%97%E3%81%9F%E3%82%B3%E3%83%BC%E3%83%89%E3%81%8C%E7%84%A1%E3%81%84%E3%81%8B\" aria-label=\"2 psrのお作法に反したコードが無いか permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. PSRのお作法に反したコードが無いか</h3>\n<p>PHPのコーディング標準として、<a href=\"http://www.php-fig.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">PSR</a>というものが挙げられています。</p>\n<ul>\n<li><a href=\"http://www.php-fig.org/psr/psr-0/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">PSR0</a>: クラスのオートロードの規則について</li>\n<li><a href=\"http://www.php-fig.org/psr/psr-1/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">PSR1</a>: エンコーディングや命名規則などコーディング規則について</li>\n<li><a href=\"http://www.php-fig.org/psr/psr-2/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">PSR2</a>: PSR1に加えてインデントやより詳しいコーディング規則について</li>\n</ul>\n<p>コミットの制約に加えるか否かはさておき、読んでおいて損はない規約だと思います。</p>\n<p>あと3と4もあるのですが、とりあえずこれだけ知っておけば問題ないので割愛します。 これら一般的なコーディング規則に則ったコードになっているかをチェックしていきます。</p>\n<h3 id=\"3-使用してない変数あまりに長い命名複雑なループ等を実装してないか\" style=\"position:relative;\"><a href=\"#3-%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%81%AA%E3%81%84%E5%A4%89%E6%95%B0%E3%81%82%E3%81%BE%E3%82%8A%E3%81%AB%E9%95%B7%E3%81%84%E5%91%BD%E5%90%8D%E8%A4%87%E9%9B%91%E3%81%AA%E3%83%AB%E3%83%BC%E3%83%97%E7%AD%89%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%97%E3%81%A6%E3%81%AA%E3%81%84%E3%81%8B\" aria-label=\"3 使用してない変数あまりに長い命名複雑なループ等を実装してないか permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. 使用してない変数、あまりに長い命名、複雑なループ等を実装してないか</h3>\n<p><strong>書いてる途中で気付けよ</strong> というお話ではありますが、<br>\nもしこのようなコードをうっかり書いてしまい、それに気づかずコミットしてしまわないようにコードの品質チェックを行います。</p>\n<h3 id=\"4-composerjsonはvalidになっているか\" style=\"position:relative;\"><a href=\"#4-composerjson%E3%81%AFvalid%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%81%8B\" aria-label=\"4 composerjsonはvalidになっているか permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>4. composer.jsonはvalidになっているか</h3>\n<p>PHPには<a href=\"https://getcomposer.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">composer</a>という依存関係の解決ツールがあります。<br>\nRubyでいうとこの<code>Bundler</code>みたいなものです。</p>\n<p>ナウいPHP開発をしているなら<code>composer</code>の存在はほぼマストになっていると思います。<br>\n昨今では、だいたいのライブラリがcomposer経由でインストールできるようになっています。</p>\n<p>私がよくやらかす<code>ケツカンマ問題</code>と<code>シングルクオートつけちゃう問題</code>のチェックをしてもらいたいがためのチェックです。</p>\n<p>「ケツカンマ」とは、配列の末尾要素のあとにカンマをつけたりオブジェクトの末尾にカンマをつけてしまうアレです。<br>\njsではIE9以降ならケツカンマがきちんとパースされてしまうので、つい忘れがちですがJSONの書式としては不正です。<br>\nシングルクオートは言わずもがな、JSONでは不正な形式です。</p>\n<blockquote class=\"twitter-tweet\" lang=\"ja\">\n  <p>\n    「ケツカンマ問題」\n  </p>&mdash; Sotaro KARASAWA© (@sotarok)   \n  <a href=\"https://twitter.com/sotarok/status/197726558000136192\">2012, 5月 2</a>\n</blockquote>\n<h3 id=\"5-テストは通っているか\" style=\"position:relative;\"><a href=\"#5-%E3%83%86%E3%82%B9%E3%83%88%E3%81%AF%E9%80%9A%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%81%8B\" aria-label=\"5 テストは通っているか permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>5. テストは通っているか</h3>\n<p>「テストを書かずに実装だけドバドバ貯めていって、あとからテストを埋めてく」のはいささか危険です。<br>\n私の経験談では、趣味でのコーディングではほぼ確実に途中で心が折れます。</p>\n<p>最近上司の教えで、コードとテストコードを併せてレビューして頂いているのですが、<br>\n実装と実装した分テストを書くのであれば、記述量がそこまで多くないのと、実装した直後なので割と仕様や考慮漏れに気づくことが出来ます。<br>\n<strong>これは良い習慣だ</strong> と思ったので強制的に癖をつけようということで制約に追加しました。</p>\n<p>あとはREADMEの日本語チェックとかも入れたかったのですが、<br>\n<strong>色々やりすぎるとコミットできなくなって飽きる</strong><br>\nと思ったので制約はこれくらいにしておきます。</p>\n<p>上記の制約なら、普通にコード書いていれば問題ないはずの制約です。<br>\n自分自身の「当たり前」のクオリティを上げるために矯正ギプスをはめます。</p>\n<h2 id=\"学習--git-hookについて\" style=\"position:relative;\"><a href=\"#%E5%AD%A6%E7%BF%92--git-hook%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6\" aria-label=\"学習  git hookについて permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>学習 – Git hookについて</h2>\n<p>Gitプロジェクトであれば、<code>./.git/hooks</code>の中に色々とファイルが入っています。</p>\n<p><span class=\"removed_link\" title=\"http://blog.catatsuy.org/a/142\">bareリポジトリでGit pushされたら云々する</span>、とかにも使うやつです。</p>\n<p>今回はコミット前にチェックをしたいので、<code>pre-commit</code>を使用します。<br>\nhooksディレクトリの中に<code>pre-commit.sample</code>というファイルがあるので、<code>.sample</code>を除去したファイルを複製します。</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">ls</span> .git/hooks\n<span class=\"token function\">cp</span> .git/hooks/pre-commit.sample .git/hooks/pre-commit</code></pre></div>\n<p>エディタはなんでもいいので、複製した<code>pre-commit</code>を開いて下さい。</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token shebang important\">#!/bin/sh</span>\n<span class=\"token comment\">#</span>\n<span class=\"token comment\"># An example hook script to verify what is about to be committed.</span>\n<span class=\"token comment\"># Called by \"git commit\" with no arguments.  The hook should</span>\n<span class=\"token comment\"># exit with non-zero status after issuing an appropriate message if</span>\n<span class=\"token comment\"># it wants to stop the commit.</span>\n<span class=\"token comment\">#</span>\n<span class=\"token comment\"># To enable this hook, rename this file to \"pre-commit\".</span>\n\n<span class=\"token keyword\">if</span> <span class=\"token function\">git</span> rev-parse --verify HEAD <span class=\"token operator\">></span>/dev/null <span class=\"token operator\"><span class=\"token file-descriptor important\">2</span>></span><span class=\"token file-descriptor important\">&amp;1</span>\n<span class=\"token keyword\">then</span>\n    <span class=\"token assign-left variable\">against</span><span class=\"token operator\">=</span>HEAD\n<span class=\"token keyword\">else</span>\n    <span class=\"token comment\"># Initial commit: diff against an empty tree object</span>\n    <span class=\"token assign-left variable\">against</span><span class=\"token operator\">=</span>4b825dc642cb6eb9a060e54bf8d69288fbee4904\n<span class=\"token keyword\">fi</span>\n\n<span class=\"token comment\"># If you want to allow non-ASCII filenames set this variable to true.</span>\n<span class=\"token assign-left variable\">allownonascii</span><span class=\"token operator\">=</span><span class=\"token variable\"><span class=\"token variable\">$(</span><span class=\"token function\">git</span> config --bool hooks.allownonascii<span class=\"token variable\">)</span></span>\n\n<span class=\"token comment\"># Redirect output to stderr.</span>\n<span class=\"token builtin class-name\">exec</span> <span class=\"token operator\"><span class=\"token file-descriptor important\">1</span>></span><span class=\"token file-descriptor important\">&amp;2</span>\n\n<span class=\"token comment\"># --- 長いので割愛 ---</span></code></pre></div>\n<p>という感じのファイルになっていると思います。</p>\n<p>このファイルを実行した時の終了コードが<code>1</code>なら、コミットが失敗するようにできています。</p>\n<p>すでに先駆者の方がいらっしゃったので、そちらをパクりつつ、拡張とカスタマイズを加えます。</p>\n<blockquote>\n<p>gitのpre-commit hookを使って、綺麗なPHPファイルしかコミットできないようにする<br>\n— <a href=\"http://blog.manaten.net/entry/645\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">http://blog.manaten.net/entry/645</a></p>\n</blockquote>\n<p>先ほどの長いので割愛以下に、このコードを貼り付けて下さい。</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token assign-left variable\">IS_ERROR</span><span class=\"token operator\">=</span><span class=\"token number\">0</span>\n<span class=\"token comment\"># コミットされるファイルのうち、.phpで終わるもの</span>\n<span class=\"token keyword\">for</span> <span class=\"token for-or-select variable\">FILE</span> <span class=\"token keyword\">in</span> <span class=\"token variable\"><span class=\"token variable\">`</span><span class=\"token function\">git</span> status -uno --short <span class=\"token operator\">|</span> <span class=\"token function\">grep</span> -E <span class=\"token string\">'^[AUM].*.php$'</span><span class=\"token operator\">|</span> <span class=\"token function\">cut</span> -c3-<span class=\"token variable\">`</span></span><span class=\"token punctuation\">;</span> <span class=\"token keyword\">do</span>\n    <span class=\"token comment\"># シンタックスのチェック</span>\n    <span class=\"token keyword\">if</span> php -l <span class=\"token variable\">$FILE</span><span class=\"token punctuation\">;</span> <span class=\"token keyword\">then</span>\n        <span class=\"token comment\"># PHPMDで未使用変数などのチェック</span>\n        <span class=\"token keyword\">if</span> <span class=\"token operator\">!</span> ./vendor/bin/phpmd <span class=\"token variable\">$FILE</span> text unusedcode,codesize,naming<span class=\"token punctuation\">;</span> <span class=\"token keyword\">then</span>\n            <span class=\"token assign-left variable\">IS_ERROR</span><span class=\"token operator\">=</span><span class=\"token number\">1</span>\n        <span class=\"token keyword\">fi</span>\n        <span class=\"token comment\"># PSR準拠なコードかチェック</span>\n        <span class=\"token keyword\">if</span> <span class=\"token operator\">!</span> ./vendor/bin/php-cs-fixer fix <span class=\"token variable\">$FILE</span> --dry-run -v --diff<span class=\"token punctuation\">;</span> <span class=\"token keyword\">then</span>\n            <span class=\"token assign-left variable\">IS_ERROR</span><span class=\"token operator\">=</span><span class=\"token number\">1</span>\n        <span class=\"token keyword\">fi</span>\n    <span class=\"token keyword\">else</span>\n        <span class=\"token assign-left variable\">IS_ERROR</span><span class=\"token operator\">=</span><span class=\"token number\">1</span>\n    <span class=\"token keyword\">fi</span>\n<span class=\"token keyword\">done</span>\n\n<span class=\"token comment\"># composer.jsonのバリデーション</span>\n<span class=\"token keyword\">if</span> <span class=\"token operator\">!</span> ./composer.phar validate<span class=\"token punctuation\">;</span> <span class=\"token keyword\">then</span>\n    <span class=\"token assign-left variable\">IS_ERROR</span><span class=\"token operator\">=</span><span class=\"token number\">1</span>\n<span class=\"token keyword\">fi</span>\n\n<span class=\"token comment\"># テストを実行</span>\n<span class=\"token keyword\">if</span> <span class=\"token operator\">!</span> ./vendor/bin/phpunit -c tests/phpunit.xml<span class=\"token punctuation\">;</span> <span class=\"token keyword\">then</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"　　　　 ,、,,,、,,, \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"　　　 _,,;' '<span class=\"token entity\" title=\"\\&quot;\">\\\"</span> '' ;;,, \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"　　（rヽ,;''<span class=\"token entity\" title=\"\\&quot;\">\\\"</span><span class=\"token entity\" title=\"\\&quot;\">\\\"</span>''゛゛;,ﾉｒ）　　　　 \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"　　 ,; i ___　、___iヽ゛;,　　テスト書いてないとかお前それ@t_wadaの前でも同じ事言えんの？\"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"　 ,;'''|ヽ・〉〈・ノ |ﾞ ';, \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"　 ,;''<span class=\"token entity\" title=\"\\&quot;\">\\\"</span>|　 　▼　　 |ﾞ゛';, \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"　 ,;''　ヽ ＿人＿  /　,;'_ \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\" ／ｼ、    ヽ  ⌒⌒  /　 ﾘ　＼ \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"|　　 <span class=\"token entity\" title=\"\\&quot;\">\\\"</span>ｒ,,｀<span class=\"token entity\" title=\"\\&quot;\">\\\"</span>'''ﾞ´　　,,ﾐ| \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"|　　 　 ﾘ、　　　　,ﾘ　　 | \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"|　　i 　゛ｒ、ﾉ,,ｒ<span class=\"token entity\" title=\"\\&quot;\">\\\"</span> i _ | \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"|　　｀ー――-----------┴ ⌒´ ） \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"（ヽ  _____________ ,, ＿´） \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\" （_⌒_______________ ,, ィ \"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"     T                 |\"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"     |                 |\"</span>\n\n    <span class=\"token assign-left variable\">IS_ERROR</span><span class=\"token operator\">=</span><span class=\"token number\">1</span>\n<span class=\"token keyword\">fi</span>\n\n<span class=\"token builtin class-name\">exit</span> <span class=\"token variable\">$IS_ERROR</span>\n<span class=\"token operator\">&lt;</span>/code<span class=\"token operator\">></span></code></pre></div>\n<p>テストを書かない人には<a href=\"https://twitter.com/gongoZ/status/521662328752709632\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">サバンナからお導き</a>があるようなので、そちらを使わせていただきました。<br>\nカバレッジの話になると閾値の調整が難しいのでカバレッジは見てません。判断基準は、テストに通るか否かです。テストがない場合も通ってしまいますが、そこは人力チェックで問題ない範囲でしょう。</p>\n<p>参考元の記事では<code>php-cs-fixer</code>は勝手に修正を加えるようになっていたのですが、<br>\n勝手に直されるのは性分じゃないので、自動的な修正はせず怒ってもらって、自分で修正するようにします。</p>\n<p>このpre-commitの実行にはいくつかコマンドが必要なので、<br>\n<code>composer.json</code>にこれらを追加しておいて下さい。</p>\n<div class=\"gatsby-highlight\" data-language=\"json\"><pre class=\"language-json\"><code class=\"language-json\"><span class=\"token property\">\"require-dev\"</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token property\">\"phpmd/phpmd\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"@stable\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token property\">\"fabpot/php-cs-fixer\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"@stable\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token property\">\"phpunit/phpunit\"</span><span class=\"token operator\">:</span> <span class=\"token string\">\"4.*\"</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h2 id=\"プロジェクト作成コマンドまとめ\" style=\"position:relative;\"><a href=\"#%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E4%BD%9C%E6%88%90%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%BE%E3%81%A8%E3%82%81\" aria-label=\"プロジェクト作成コマンドまとめ permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>プロジェクト作成コマンドまとめ</h2>\n<p>これらを考慮し、新規プロジェクトを作成するときの最低限のコマンドをまとめます。</p>\n<div class=\"gatsby-highlight\" data-language=\"shell\"><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">mkdir</span> SOME_PROJECT\n<span class=\"token builtin class-name\">cd</span> SOME_PROJECT\n<span class=\"token function\">git</span> init\n<span class=\"token comment\"># --- composer</span>\n<span class=\"token function\">curl</span> -sS https://getcomposer.org/installer <span class=\"token operator\">|</span> php\n./composer.phar init     <span class=\"token comment\"># 必要事項を入力</span>\n<span class=\"token function\">vim</span> composer.json <span class=\"token comment\"># phpmd,php-cs-fixer,phpunitの指定を追加</span>\n./composer.phar <span class=\"token function\">install</span>\n<span class=\"token builtin class-name\">echo</span> vendor <span class=\"token operator\">>></span> .gitignore\n<span class=\"token comment\"># --- PHPUnit</span>\n<span class=\"token function\">git</span> clone  tests\n<span class=\"token function\">rm</span> -rf tests/.git\n<span class=\"token comment\"># --- git hook</span>\n<span class=\"token function\">cp</span> .git/hooks/pre-commit.sample .git/hooks/pre-commit\n<span class=\"token function\">vim</span> .git/hooks/pre-commit <span class=\"token comment\"># 先ほどのhookを貼り付け</span>\n<span class=\"token comment\"># --- initial commit</span>\n<span class=\"token function\">touch</span> README.md\n<span class=\"token function\">git</span> <span class=\"token function\">add</span> <span class=\"token builtin class-name\">.</span>\n<span class=\"token function\">git</span> commit -m <span class=\"token string\">\"initial commit\"</span></code></pre></div>\n<p>PHPUnitの設定は結構面倒なので、gistにスケルトンを作っておき、それを<code>tests</code>というディレクトリ名でcloneしてます。<br>\nほかは特に変わったところはないと思います。</p>\n<h2 id=\"まとめ\" style=\"position:relative;\"><a href=\"#%E3%81%BE%E3%81%A8%E3%82%81\" aria-label=\"まとめ permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>まとめ</h2>\n<p>いかがでしたでしょうか。</p>\n<p>PHPのプロジェクト作成と一口にとっても、色々と改良の余地がありそうです。 こんな感じで、少しでもウンコード発生率を下げましょう！ ！ ！</p>\n<h2 id=\"言い訳\" style=\"position:relative;\"><a href=\"#%E8%A8%80%E3%81%84%E8%A8%B3\" aria-label=\"言い訳 permalink\" class=\"autolink-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>言い訳</h2>\n<p>冒頭に紹介したschemaはまだこの記事を書く前に作成されたプロジェクトなので、PSR0準拠できていません。<br>\nぼちぼちと修正中です。</p>\n<blockquote>\n<p>PHPMD – PHP Mess Detector<br>\n— <a href=\"http://phpmd.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">http://phpmd.org/</a></p>\n</blockquote>\n<!---->\n<blockquote>\n<p>The PHP Coding Standards Fixer for PSR-1 and PSR-2<br>\n— <a href=\"http://cs.sensiolabs.org/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">http://cs.sensiolabs.org/</a></p>\n</blockquote>","timeToRead":11,"frontmatter":{"title":"PHPで開発するためのgit hookを作った","tags":["Git","PHP"],"date":"October 19, 2014","featuredImage":{"childImageSharp":{"fluid":{"tracedSVG":"data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='400'%20height='135'%20viewBox='0%200%20400%20135'%20preserveAspectRatio='none'%3e%3cpath%20d='M332%2013l-3%203-1%201c-1-1-1%200-1%201%200%202%200%202-1%201-1-3-4%201-9%2010l-3%206%202%204c3%204%203%205-1%202l-2-2v4c1%206%201%206-1%202-2-2-2-2-4%205-3%206-3%207-1%209v3l-1-2h-1c-1%202%200%204%201%203l1%201c-2%202%201%205%204%206l2%202%201%201%202-9%203-10-1-2c-2%200-2-1-2-2l2-2c2%200%203-2%205-7l4-8c1-2%202-2-2%208-3%207-3%207-2%208%203%202%202%204-1%204-1-1-2%200-3%209-2%2012-3%2032-1%2033l1-2%206-3%202-2c-4%201-4-1%201-2%202%200%203%200%202-1-2%200-1-1%201-2%203-2%204-3%204-6l-1-3v-1c2-1%202-2%201-5-2-4-2-4-4-2l-4%201%203-3c6-3%206-2%207-13l2-4c0-2%200-2-2-1l-3%201%201-2c3-1%206-8%204-10v-9c2-2%201-6-2-10l-2-4-3%201m-126%204l-1%204v2c-3%200-2%203%202%207s4%204%202%204l-5%201c-1%202-1%202%202%203l5%202%206%203c5%203%206%208%201%208-2%200-1%202%201%206%202%202%202%204%202%205l-2-1c-1-3-7-5-9-5l-4-2c-6-4-18-1-23%206l-2%203v-4c0-3%200-4-2-4-3%200-3-4%201-7l4-6%205-6%202-5c-1-1%200-2%204-4l4-4-8%204c-8%205-9%205-9%202%200-2-1-3-2-1h-4l3-2%203-2-3%201h-5c-1%200-3%201-4%204l-3%203-2-4c-4-6-5-2-2%207l2%208v2c2%201%202%202%202%205%200%202-1%202-2%201-3%200-3%200-3%205l1%205c1%200%202%203%202%2012%200%2013%200%2013%2011%2021l5%204v1c1%201%200%202-5%201h-6l3%202%203%201-1-1%208%201%207%202h-19l7%201c16%201%2021%203%2021%205l-1%204-1%201v-3c0-3-1-4-4-1h-1c0-3-2-2-3%200l-2%202v-2c-1-5-8-2-8%204%200%202%200%202%203%202h5c1-1%202-2%203-1%200%201%201%201%202-1l2-2v2c0%203%203%203%207-1l3-2v2c0%203%200%203%203%203l9-1c5%201%209%200%208-1v-2l-1-1%201-1%203-1-3-1c-3%200-5%202-5%204s0%202-2%201c-2-3-3-4%200-4%201%201%202-1%200-2s-5%203-3%204v2c-5-4-2-8%2012-11%209-3%209-3%207-4v-1l1-1h-2v-2c2-2%202-2%200-2s-2%200-1-3l3-10c0-4%202-8%203-11%202-4%202-11%200-14v-2l2-9-4%201c-3%201-3%201-5-3l-1-8c0-6-6-19-9-19l-1%203%201%204-5-4c-6-3-7-4-9-2m1%203l4%205c6%206%206%207%200%204-6-4-6-4-2%201%203%203%205%204%206%203%202%200%202%200%201%201l-5%201c-5%201-8%202-5%202l7%202%206%203%203%204c1%203%202%203%205%202%203%200%204-1%202-4l-2-9-2-11c-3-5-5-6-3-1l1%204c-1%200-4-1-3-2%200-1-6-5-8-5l3%203c5%205%203%204-3%200l-5-3m-22%2013l-17%2011%201%203v3c-1%202%200%203%204%203%202%200%203%200%203-3l4-5%209-13-4%201m-63%2034c0%202%200%202-1%200-1-1-1-1-1%201-2%204-7%2011-10%2012l-1%201-1%202-1%208%201-3c0-3%202-3%202-1%202%205%204%205%2017%203%208-1%2012-3%2011-3l1-1c1%201%204-3%204-5l-2-2v-1l2-1-1-1h-2l2-1%201-1h-1l-2-1c-1-1%200-1%201-1s2%200%201-2h-1c-1%202-1%201-3-1%200-2-1-2-1-1l-4%201h-4l5%201%205%201h-5l-8%201h-3l1-4c0-5-1-5-2-1m161%206c-3%202-3%202-2%204v1l-1%202v2c-2%200-1%203%201%205h-1c-2%200-2%200-1%201v4c0%203%200%203%203%205%203%201%203%201%201%201-4-1-5%201-1%202l9%202-2-1v-2c2-1%202-2%202-5v-2l1%2011v8l5-6v-2c2-1%202-1%201-2l1-2c3-2%203-3%203-6-1-4-2-5-3-4l-1-3c1-2-3-10-5-11l-2-1c-3-3-6-3-8-1m-78%202l-4%202-16%202c-3%201-3%201-1%203%201%201%202%203%200%203h-1l2%202%207%206%205%204%202-3%203-2h-3c-4%201-4%200-1-2l1-1v-3c0-3%200-3-3-2h-5c-2-1-2-1%203-1%204%200%204%200%202-1h-6c-2%200-2%200-1-1%201-2%202-2%206-1l5-1%201-1v7c0%204%200%204%202%202s3%200%200%202c-1%202-1%202%201%202h3l-2%201c-2%200-2%200%200%202%201%201%201%201-1%201-1-1-3%200-5%202s-2%202%200%203c4%202%2011-1%2014-5v-3l-1-1%201-1%204-2c0-2%202-3%203-3s1-1-1-3-2-2-6%200c-2%201-2%201%200%201%202-1%203%200%200%201-2%201-4%201-7-1-4-3-4-5%200-3h8v-1l-4-3c-3-3-3-3-5-1'%20fill='%23d3d3d3'%20fill-rule='evenodd'/%3e%3c/svg%3e","aspectRatio":2.9557522123893807,"src":"/static/5690df49e4df5f831089a6cf2c0b7efb/32d53/featured-image.png","srcSet":"/static/5690df49e4df5f831089a6cf2c0b7efb/1ec58/featured-image.png 334w,\n/static/5690df49e4df5f831089a6cf2c0b7efb/32d53/featured-image.png 614w","srcWebp":"/static/5690df49e4df5f831089a6cf2c0b7efb/9b99b/featured-image.webp","srcSetWebp":"/static/5690df49e4df5f831089a6cf2c0b7efb/cd98f/featured-image.webp 334w,\n/static/5690df49e4df5f831089a6cf2c0b7efb/9b99b/featured-image.webp 614w","sizes":"(max-width: 614px) 100vw, 614px"}}}}}},"pageContext":{"slug":"/create-git-hook-to-develop-modern-php/","previous":{"fields":{"slug":"/useful-libraries-in-develop-taskloud/"},"frontmatter":{"title":"Taskloudを制作する際に使用したライブラリまとめ","tags":["Backbone.js","Firebase","JavaScript","Marionette"]}},"next":{"fields":{"slug":"/how-to-implement-fulltext-search-with-fuelphp/"},"frontmatter":{"title":"FuelPHPでInnoDBの全文検索を利用してみる","tags":["PHP","FuelPHP","MySQL"]}}}},
    "staticQueryHashes": ["2585454260","2954598359"]}