PHPでコーディング規約の自動化 PHP CodeSniffer
どうしても開発者が増えてきたりするとコーディング規約が適当になりがちです。
そこでコーディング規約を自動化しようと思いました。
職場のコーディング規約はPEARを元にしたものですが、現在では時代遅れ感が否めないのでPSRを採用する方向で考えました。
最近のPHP系のフレームワークはこれを採用しているところが多いです。
www.php-fig.org
実際に試したのはPHP_CodeSnifferと
github.com
PHP-CS-Fixerです。
github.com
某QiitaでPHP_CodeSnifferは古いと書かれていたのでPHP-CS-Fixerを先に使ってみましたが、現在self-updateすると落ちてくるのが2.0のDEV版なのですが、2.0からどうやらオプションが変わるようで1.x系のオプションが使えないので苦労しました。それとDEV版だからなのか、if文が複数行あるとインデントが崩れるため今回の使用は見送りました。
PHP_CodeSnifferは古いと書かれていましたが、現在でも開発は行われているようで全然問題ありませんでした。PHP_CodeSnifferはxmlのruleset.xmlを元にオレオレコーディング規約も作れるので便利です。
ダウンロード
PHP_CodeSnifferは2種類ありまして、phpcs.pharがコーディング規約を適用したさいのdiffを取れます。phpcbf.pharがコーディング規約の適用です。
それぞれgithubから落としてきます。
wget https://github.com/squizlabs/PHP_CodeSniffer/releases/download/2.6.1/phpcs.phar -O phpcs.phar wget https://github.com/squizlabs/PHP_CodeSniffer/releases/download/2.6.1/phpcbf.phar -O phpcbf.phar mv ./phpcs.phar /usr/local/bin/phpcs.phar mv ./phpcbf.phar /usr/local/bin/phpcbf.phar chmod 755 /usr/local/bin/phpcs.phar chmod 755 /usr/local/bin/phpcbf.phar
使い方
--standardでコーディング規約を指定します。--report=diffをつけるとどこが変わったか見ることができます。
php phpcs.phar --standard=PSR2 /foo/foo.php php phpcs.phar --standard=PSR2 --report=diff /foo/foo.php
コーディング規約を改造したい方はGithubのPSR2のxmlを元に自分流に改造できます。改造したファイルのPathを--standardに指定すれば使えます。
PSR2 ruleset.xml
https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/PSR2/ruleset.xml
変換実行
php phpcbf.phar --standard=ruleset.xml /foo/foo.php ignoreで除外もできます。 php phpcbf.phar --standard=ruleset.xml /foo/foo.php --ignore=*Base.php
AndroidとiPhoneでhtml5を使用して音声と動画にアクセス時にユーザエージェントが変わる件
Html5で音声と動画にアクセスする際にAndroidとiPhoneだとユーザエージェントが異なるものでアクセスされることが分かった。
Androidの場合(Zenfone5)
stagefright/1.2
iPhoneの場合(iPhone6の9.2)
AppleCoreMedia/1.0.0.13D15 (iPhone; U; CPU OS 9_2_1 like Mac OS X; ja_jp)
私が試した環境だと音声だけだが、調べてみると動画でも起きるらしい。Androidの場合は端末によって端末名が入っていたり、Zenfone5のようにAndroidの文字すら入ってない場合もあるのでユーザエージェントをandroidで判定していると痛い目を見る。
UITableViewでUITableViewCellの高さを自動で可変する
今回はUILabelとUITextViewを使用した場合にUITableViewCellの高さを自動で可変する方法を書きます。UITableViewは予め設定し終わった状態と過程して話を進めます。
StoryBoard上の設定は以下のようにmarginをセットしてます。
画像はUILabelですが、UITextViewも同じようにします。
UILabelを使用するときは設定でLinesを0にしてください。
UITextViewを使用するときは設定でScrolling Enabledのチェックを外してください。
そして以下のコードを追記します。
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension }
estimatedHeightForRowAtIndexPathは予めUITableViewCellの高さを指定してやることで実際に表示した際に負荷を軽減してくれます。
heightForRowAtIndexPathは実際のUITableViewCellの高さを取得します。
今回は返り値にUITableViewAutomaticDimensionというUITableViewCellの高さを自動で取得してくれる値を書きます。
ちなみにネット上で色々コードが転がっていたので、それぞれ試してみました。
//OK tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = 100 //OK tableView.rowHeight = UITableViewAutomaticDimension func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } //OK これが同じ所に書けるし、一番いいのでは? func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } //NG 何故・・・estimatedRowHeightにはUITableViewAutomaticDimensionを直に設定することが出来ない tableView.rowHeight = UITableViewAutomaticDimension tableView.estimatedRowHeight = UITableViewAutomaticDimension
iPhoneアプリを一人で開発している俺がstoryboardの分割に踏み切った理由
iPhoneアプリを複数人で開発していると衝突を避けるためstoryboardの分割は必須だと思いますが、一人で開発している分には別に衝突しないし特に気にする必要もないと思っていたのですが、画面数が増えてきたところで色々と問題が出てきたので同じように一人で開発している人に共有したいと思います。
分割しない場合
メリット
・なにも考えないでstoryboardが書ける。
デメリット
・画面数が増えてくると表示に時間がかかる
・新規画面を追加している際に既存の画面を間違えて変更した時に気づきにくい
特に"画面数が増えてくると表示に時間がかかる"
これが結構問題で、作業効率が著しく落ちます。
(※私の仕事で使用しているMacMiniが5年前以上に買った物というのもありますが・・・)
最初はイメージで画面1枚に付き、storyboardを1枚用意しないといけないと思っていたのですがiOS8以降が対象であるならば以下が使用できます。
Storyboard Reference
developer.apple.com
xcodeの右下のほうにあるのですが、これをstoryboard上に持ってきます。
Storyboard Reference内の設定でStoryboardのファイル名の一覧がでてきます。
あとはStoryboard Referenceに対して今までどおりにSegueを張るだけでOKです。
Storyboard Referenceを導入すると
メリット
・画面分割を機能ごとのStoryboardで分割できる
・Segueがそのまま使える
デメリット
・iOS8の場合はRelationship Segueが使用できない
対してデメリットはないのでオススメです!!
PHP5.2でSwiftみたいなmapや、filterみたいなことして見たい
結論:できませんでした。釣りタイトルで申し分けない(´;ω;`)
付き合って頂ける方は下にスクロールをどうぞ
swiftのmapやfilterみたいなことPHPで出来たらいいなぁーと考えてたら、もしかしたら自分が知らないだけで似たようなこと出来るのでは?
とPHPのドキュメント漁ってたらあるものを見つけた
PHP: array_map - Manual
PHP: array_walk - Manual
array_mapとarray_walkである
mapって同じ名前が付いているので期待できる!!!
関数はarray_walkが、array_mapの上位互換な感じがあるので以下はarray_walkで説明
<?php $data = array(1 => 'りんご', 2 => 'みかん', 3=> 'ぶどう'); array_walk($data, function(&$value, $key) { $value = $value."ジュース"; }); var_dump($data);
array_walkは第一引数に配列を、第二引数にCallBackを指定することで配列内の値に対して変更を加えることができます。
しかし残念ながらこれはPHP5.3以降にできる書き方。PHP5.2は無名関数が使えないのだ!!
ちなみにPHP5.2で書くと
<?php $data = array(1 => 'りんご', 2 => 'みかん', 3=> 'ぶどう'); array_walk($data, create_function('&$value, $key', '$value = $value."ジュース";' )); var_dump($data);
create_functionだと!?・・・
(ヽ´ω`)
それでもPHP5.3なら!!
PHP5.3なら!!
foreachとarray_walkの処理速度比較 - rh7's blog
foreachの方がはやい・・・
それでもarray_walkにも何かいいところが!!
PHP5.3.14以降のarray_walkで内部ポインタが破壊される – この先生きのこるには
foreachイイヨネ!!
PexJSで引数にURLではなくバイナリをセットして使用する方法
新年初投稿です。
最近までGoogleのSwiffyを使ってswfをhtml5に変換して使っていたのですが
developers.google.com
特定のバージョンから内部的にCanvasからWebGLに変更されたのか動かなくなってしまった古い端末が増えたため、別の方法を取り入れることになりましてDeNA様のPexJSを使わせて頂く事になりました。
github.com
Swiffyは公開されているruntimeとGoogleのサーバー上で変換されたhtml5は常に揃えないといけないのですが、実はv5.2のruntimeを使用するとv7.3が公開されるまでの間そのまま使用することが出来ました。(古いruntimeはサーバーに残ってるので直打ちでダウンロードできる)
v5.2を使用すると古い端末でも再生できたりします。v7.3辺りからGoogleで生成されるJsonの形式が微妙に変わってしまったため遂に動かなくなりました。
Flashの生成にはswfmillを使用して行っていたのですが、PexJSをそのまま使うと第一引数にURLをセットする必要があるのでPexJSを使用する画面とswfを生成する画面の二画面が必要でした。
どうしても一画面で完結したいので最初はwindow.URL.createObjectURL()を使って試していましたが、Android4.0.4では動かないため別の方法を模索する必要がありました。
PexJSは日本語のドキュメントも充実しているのですが、実は書かれていないオプションがありましてそれが「swfBinary」です
■サンプル(PHP+Javascript)
PHP側でswfのバイナリをbase64にしてhtml側に渡す
base64_encode($swf);
Javascriptでbase64をdecodeしてセットする
var option = { swfBinary : atob(swf); }; var pex = new Pex("", "container", option);
これで一画面で完結できます。