YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl...

197
半端なPHPDisPHPerに陰で笑われないための Perl Monger向け最新PHP事情 YAPC::Asia 2014 @uzulla

description

YAPC::Asia 2014にてトークした、Perl Monger向けのPHP紹介トークのスライドです。

Transcript of YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl...

Page 1: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

  YAPC::Asia 2014

@uzulla

Page 2: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Breaking news

(このタイミングでリリース…)

Page 3: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Meanwhile in YAPC::Europe 2014

Page 4: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

I am ...@uzulla

Hachioji.pmPHPer

Page 5: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

I ❤️PHP

Page 6: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

皆さんに質問PHPを使っている人?

Page 7: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHPに苦しめられている人?

DISりたくてここにいる人?

Page 8: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Do you know PHP ?

Page 9: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHP is ... ?• Webに特化• LAMPというありふれた環境(Linux Apache Mysql PHP)

• 初心者でもイケるゆるふわなコード• 「Wordpress」「ECCUBE」「phpMyAdmin」等といった超有名アプリ

Page 10: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHP is .... ?• レンタルサーバー(レン鯖)

• FTPでデプロイ• 関数のかたまり• レガシーコードがやばい• テンプレートエンジン(笑)

Page 11: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Q: PHPはテンプレートエンジン?A: はいPHP: Hypertext Preprocessor

Page 12: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

...<div id="user_name"><?php echo $_GET['name']; ?></div>...

Page 13: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Q: DBつかえるってきいたけど?A: 勿論ですMysql,sqlite,Pgsql,Oracle,Sqlserver ...

Page 14: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

traditional PHP code

<div id="user_name"><?php $db = mysql_connect('localhost', 'yay_id', 'yay_pass');

mysql_select_db('yay', $db);

$res = mysql_query("SELECT * FROM user_account WHERE user_id=".$_GET['id']);

$row = mysql_fetch_assoc($res);

echo $row['name'];?></div>

Page 15: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

transitional PHP code

<div id="user_name"><?php if(isset($_GET['id'])&&is_string($_GET['id'])){ $id = (int)$_GET['id']; try { $pdo = new \PDO('mysql:host=localhost;dbname=yay;charset=utf8mb4', 'yay_id', 'yay_pass'); $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare('SELECT * FROM user_account WHERE user_id=:user_id'); $stmt->bindValue('user_id', $id, \PDO::PARAM_INT); $sth = $stmt->execute(); $user = $sth->fetch(\PDO::FETCH_ASSOC); if(!empty($user)){ echo htmlspecialchars($user[0]['name'], ENT_QUOTES, "UTF-8"); }else{ echo "oh, i don't know that id."; } $pdo = null; } catch (\PDOException $e) { if(count(ob_get_status())===0){ http_response_code(500); } error_log("db fail ".$e->getMessage()); echo "oh, db fail sorry."; } catch (\Exception $e) { if(count(ob_get_status())===0){ http_response_code(500); } error_log("terrible error".$e->getMessage()); echo "uhoh, sorry."; } finally { // it's joke. }}else{ echo "oh, id is require.";}?></div>

Page 16: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

…もう帰りたい?(NAOYAさんの発表が裏ですよ!)

Page 17: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

MODERN PHP ?

Page 18: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

MODERN PHP (probably)• オブジェクト指向プログラミングを駆使• イケてるライブラリを使う• 「Herokuにデプロイ」• 「継続的テストも必須だよね」• とかなんやかんや、やる感じ個人差有ります

Page 19: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Q: まって、テンプレートエンジンじゃないの?

Page 20: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Q: まって、テンプレートエンジンじゃないの?

A: PHPはクラス、インターフェイス、抽象クラスと基本からはじまり、単一継承ではあるものの

Traitによって柔軟さを確保し、例外機構、Finalizeなどもきちんと存在し、簡単なメタプロもできる程度のマジックメソッドを持ったオブジェクト指向プログラミング対応のテンプレートエ

ンジンです。

Page 21: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

A『は?飛躍したぞ?』B「OOPって =& のこと?」C『PEARのことでしょ?』

Page 22: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

論よりナントカ百聞は一見にしかずとりあえずウェブアプリケーションを作ってみます。残念ながらライブではありません。

Page 23: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

はじめる前に

• Windows > PHPはいってない(XAMPPとかWebmatrixとかで入る)

• Linux > (Cent5以外なら)AptとかYumとか• Mac > 「それマヴェリック?もう5.4はいってるよ!!」

Macの人はすぐにできます

Page 24: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

そんなに慌ててPHPを削除しないでください

Page 25: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

1,ディレクトリ作ります

Page 26: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

2,Composerをいれます。

ワンライナーで入る。ComposerはPerlで言う所のcpanmみたいなパッケージマネージャです。

Page 27: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

3,おもむろにWAFをインストールします。

※今後php composer.pharをcomposerとタイプします

Page 28: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

4,コードを書く

$ (vim|emacs) index.php

Page 29: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

5,PHPでサーバーをたてる

• plackupみたいなの(開発のみに使う)

• PHP>=5.4からhttpdが組み込み• コンソールに色つきログが出て便利• (余談:HTML開発にもつかえる)

Page 30: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

6,hello world!

Tadaa!!!できた!!!(Composerを手元で走らせて全部あげれば、世の中の90%(適当)の実行環境であるレンサバでも問題ありません)

Page 31: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

繰り返しになりますがMacをお使いの皆さんは• 宗教上の理由• お医者さんに止められている• 家族の薦め、死んだ婆さんの遺言とかないかぎり今すぐ使えますよ!

言い訳はできません

Page 32: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHPのOOPの話

Page 33: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

…の前に、クラスのロード方法• 古代:全部コピペ(そもそも非クラス)

• 昔 :先頭に大量のrequire_once()

• 近代:自前でオートローダーを実装• 現代:PSR-0,4対応のローダー(主にComposerの機能)

(番外 PEARはinclude_path)

Page 34: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Composerのオートローダーの設定composer.json修正→composer update(等)

Page 35: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Composerのオートローダーの利用<?phprequire_once('vendor/autoload.php');

vendor/autoload.phpをrequire_onceするだけ

Page 36: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

クラス名、ファイル名規約、PSR-0(または4)• 昔は規約なんてなかった、カオスだった

• Net_Services_Twitterとか…(長い)• 今はネームスペースを使う• ネームスペース例

\Uzulla\My\Library

• それに対応するファイルパス例/path/to/lib/Uzulla/My/Library.php

Page 37: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「PSR」?• PHPの規約、PHP-FIGが策定(PHP本体ではない)http://www.php-fig.org/

• 策定済→ 0,4:Auto load周り1,2:code style系、3:Logger Interface

• 策定中→ 5:PHPDoc、6:Cache Interface

• 世紀末フリーダム世界PHPに秩序を

Page 38: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

さっさとOOPはい

Page 39: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

こういう感じのファイル配置

(PSR-4だとYapcはショートカットできるけどわかりやすさの為)

Page 40: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

コントローラーのベースクラスがこんなんで

Yapc/Controller/Base.php<?phpnamespace Yapc\Controller;use Slim\Slim;

class Base{ protected $slim;

public function __construct(){ $this->slim = Slim::getInstance(); }}

Page 41: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

継承したクラスはこんなんです

Yapc/Controller/Index.php<?phpnamespace Yapc\Controller;

class Index extends Base{ public function run(){ $this->slim->render('template/index.twig'); }}

Page 42: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Perlだと?(雰囲気です)

package Index;use Mouse;extends 'Base';

has slim => ( is => 'rw', isa => 'Slim' );

sub run { my ($self) = @_; $self->slim->render('template/index.tt');}

no Mouse;1;

Page 43: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHPのOOP…これは…

• JavaっぽいのOOP、Blessみたいなのはない• 「OOPの本」とかの例が(ある程度)書ける

Page 44: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

つまり怖くない気付いてる人は気付いてると思いますが、PHPはHTMLのテンプレートエンジンですが、PHPのコード内にはHTMLは一切かかず、普通のプログラミング言語のフリをして使うのが今の書き方です。

Page 45: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Q: じゃあHTMLはどこに書くの?A: テンプレートエンジンである所のPHPで書かれた、別な安全なテンプレートエンジンを使うと良いでしょう!!

冗談ではありません。PHPはHTMLの中でいきなりDBにSELECTとかできて強力すぎるし、オートエスケープがないので、正しく安全に使うのは非常に面倒。なので、Twigとかつかうべきでしょう。

Page 46: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Type Hinting

function ( \My\Class $my_class_instance ){

• 引数の「型」っぽくクラス名書ける• クラス名、インターフェイス名、array等• 間違えると例外が上がって安心• 静的解析がはかどる

=>IDEが補完ガンガン(超重要)

Page 47: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

でも…残念…

• integer、Stringなどのスカラ型がない• traitもダメ

※PHP.netでRFCにはなってるのでいつかは…(でも「…そうか…」という箇所もある)https://wiki.php.net/rfc/scalar_type_hinting_with_cast

Page 48: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

独自例外クラス<?phpnamespace Yapc;class MyException extends \Exception{ public function scream(){ echo "うぎゃ~";

}}

Page 49: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

独自例外クラスをキャッチとFinally

<?phptry { if($hoge){ throw new \Exception('汎用'); }

if($huge){ throw new \Yapc\MyException('オレオレ'); }

} catch (\Yapc\MyException $e) { //独自例外クラス $e->scream(); // <--独自例外に生やしたやつ} catch (\Exception $e) { //そのほか echo $e->getMessage();} finally { // PHP>=5.5から使える echo "終わりだ…";

}

Page 50: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

SPL

• Standard PHP Library

• 色々な継承に使えるテンプレートがある• イテレータとかイテレータとか• 継承でForeachにわたせるようになるとか• 例外とか例外とか例外とか• 独自例外つくるより選ぶ方が楽

Page 51: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

他にも…

• __set(),__get()、__toString()、__clone()等の少々のマジックメソッド

• final指定• trait

(多重継承の代用等)

Page 52: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

OOPじゃないけど

• password_hash (PHP>=5.5)「PHPerでも」「将来にわたって使いやすい」「安全な」パスワードハッシュをつくれる

• Generator (PHP>=5.5)巨大ファイルや終わりの不明なデータ処理につかいやすい。

• [1,2] (配列リテラル)(PHP>=5.4)昔はarray(1,2)というダサイ記法だった

Page 53: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

OOPじゃないけど2IDEによるリアルタイムLint

Typoや未宣言変数の指摘

クラス名の重複や

Page 54: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

未使用変数の指摘

「型」の違う変数の指摘

めっちゃイライラが減る!!!「自分よりPHPStorm(等)が信用できる」

Page 55: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

まとめ• PHPはOOPできるようにがんばってる• 例外とかもちゃんとある• 「Javaっぽい?」• IDEの静的解析が果てしなく便利

=> プロはIDEいらないかもですが=> 補完のために自然とクラスを作り出す

Page 56: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHP5.6-RC4 now-

Released!! Yeah!!

Page 57: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

• (割とマニアックな機能追加が多い)• 累乗演算子、GMPの演算子オーバーロード• (constによる)定数宣言で式利用可能に• 可変長引数記法や関数の名前空間、誰得?• 各種制限撤廃は嬉しい(php://input再利用可、ファイルアップロード2GBの天井消滅)

• 「余波で」PHP5.3が終了へ(これは重要)

Page 58: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

ライブラリ

Page 59: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

最近のライブラリ事情• PEARは消滅の流れ(PHPUnit、AWSなど)• Packagist+Composerが台頭• Packagist.orgのRSSが加速している

=> PHPのライブラリがドンドンふえている!(=>「ACME」ライブラリも多い…)

Page 60: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Packagist ?

• http://packagist.org

• ライブラリのリポジトリ(インデクスのみ)• npm,rubygemsと似てる• Composerから利用される• ホストはGithub 95%(適当体感)、残り

Bitbucketなど• 登録・投稿に一切の審査無し

Page 61: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

増え続けるパッケージ(2014/08/25)

• 「36772 packages registered」• 「142437 versions available」

Page 62: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

http://www.modulecounts.com/

Page 63: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Packagist監視業務は結構たのしい(つらい)

• よくわからんWAF

• よくわからんORM

• よくわからんルーター• よくわからんテンプレートエンジン• 「砂場では?」「スターを見よう…」• 監視業にはRSSが便利

• Twitter: @call_user_func

Page 64: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

監視おじさんのスターリストから• id:uzullaのGithubのスターリストから抜粋• ライブラリやツール• 全部試した訳ではない• 趣味、偏りがあります

Page 65: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

• https://github.com/Seldaek/monolog鉄板なLogger

• https://github.com/fabpot/Twig鉄板なテンプレートエンジン

• https://github.com/sebastianbergmann/phpunit鉄板のテストフレームワーク

• https://github.com/fabpot/Goutte要はLWP

• https://github.com/swiftmailer/swiftmailer鉄板のメール送信するやつ

Page 66: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

• https://github.com/Halleck45/PhpMetricsコードを静的解析してスコアつけとかするやつ

• https://github.com/squizlabs/PHPCodeSniffer要はPerl::Critic、Perl::Lint

(他にもPHPMD)• https://github.com/fabpot/PHP-CS-Fixerコードフォーマット修正ツール(PHPStormがあるからつかってない…)

• https://github.com/bobthecow/psysh組み込みより高機能なREPL

Page 67: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

• https://github.com/Bee-Lab/bowerphpJavascriptのBowerコンパチツール

• https://github.com/indeyets/pake要はmake的なやつ

• https://github.com/rocketeers/rocketeerデプロイツール

• https://github.com/nategood/commandoPHPでCLIプログラム書く時につかうGetOp的ライブラリ

Page 68: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

• https://github.com/illuminate/databaseLaravelというWAFのORM部分切り出し

• https://github.com/j4mie/idiorm要はORM

• https://github.com/jpfuentes2/php-activerecord要はActiveRecord(他にもARはある)

• https://github.com/memememomo/php-SQL-Maker要はSQL::Maker

Page 69: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

• https://github.com/clue/psocksdSOCKSトンネル、サーバーデーモンの実装のやつ

• https://github.com/bravo3/sshsshクライアント的なやつ

• https://github.com/fpoirotte/psshtssh「サーバー」

• https://github.com/clue/php-wake-on-lan-reactWOL(WakeOnLan)叩くやつ

Page 70: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

• https://github.com/reactphp/react「Event-driven, non-blocking I/O with PHP.」

• https://github.com/ratchetphp/RatchetWebSocketサーバー(スタンドアロンでサーバーになります)

• https://github.com/marcj/php-pm「PHP ProcessManager for Request-Response Applications」

Page 71: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

• https://github.com/videlalvaro/phacterl「Implementation of The Actor Model in PHP.」「アクターモデル」「マジで!?」

• https://github.com/ircmaxell/PHPPHP「A PHP VM implementation written in PHP.」「PHPでPHP実装した」「マジで?!」

• https://github.com/runekaagaard/snowscript要はPHPのCoffeScript、更新ほぼない

Page 72: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

ライブラリまとめ• かなり面白いライブラリやツール増えた• 「これPHPでやるドメインか??」• 「ホントに動くのかこれ??」• Packagistは自分でも気軽に登録できる• 国産ライブラリもっと増えて欲しい

Page 73: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

実行環境

Page 74: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「PHPの実行環境は沢山あるんじゃぞ」本家PHP、HHVM、HippyVM、PHP.js、Quercus、Phalanger、pipp、HappyJIT、PHP Compiler (PHC)、Rose、Roadsend PHP、Roadsend PHP: Raven (RPHP)Project_Zero/sMash、talaria Runtime、PHP4Mono、php-llvm、Zend Server

Page 75: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「本当の所は?」実用できるのは以下三つ• 本家PHP

• HHVM

• ZendServer

ZendServerは有料なのでよくわからないけど、プロファイラとか、5.3を今後もサポートとか、そういう強みがある模様

Page 76: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

本家の特徴

• 本物である• pecl(c拡張)がつかえる• 安定している• mod_phpがある

Page 77: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

HHVMの特徴

• 速い• 速い• なんかカッコイイ• httpd 動作可能• チョイチョイたりない互換性• Hack langつかえる• 速い

Page 78: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Q: どっちをつかうべきでしょうか?

A: 本家です

Page 79: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

本家?HHVM?

• どっちか迷う人がHHVMはやめた方が良い• 速度以外のメリットはない(大体倍)• でも、実際のネックはDBとかでしょ?• 「本家でありえない物」も、あまりない(将来永続インスタンスとかでてきたらワンチャンあるで)

• Hack?使ってる所をまだみたことない

Page 80: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「ところでLAMPはオワコン?」「nginx+PHPが今ドキでは?」

Page 81: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Apacheの特徴• htaccessの楽さ

• mod_phpとmod_rewriteの組み合わせはやっぱり柔軟で強力(FastCGIはURIのマップでかゆいところに手が届かないか、コンフィグが複雑で面倒)

• 手間&手離れ

Page 82: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

nginxの特徴• 特に遅いモバイル相手で裁ける量が違う• 複数アプリを相乗りしだすと色々面倒(複数のrepoがデプロイされてるとか…)

• 協力会社とお客様のご理解(「なんでhtaccessがないの!?」 「(秘伝のタレ)を置いて下さい」)

• 監視点や監視ログが増える

Page 83: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

まとめ• 「PHPらしく」つかうとLAMPしかない事も• Apache+mod_phpの楽さ、柔軟さハンパない• nginx+php-fpmは速度が欲しければ良い• nginx+HHVM(fastCGI)は最悪php-fpmに戻せる

Page 84: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

それPHP?

Page 85: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHPの欠点遅い

Page 86: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

本当なの?

• plackで 1000req/s の所 50~300req/sくらい※ 条件によります(雑だw)

• 超々重量級WAFで、一切調整しないと一桁とか

Page 87: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

さて、ちょっとこれをみてくれないか

Page 88: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Perl (Plack)

#!/usr/bin/env perluse strict;use warnings;use utf8;use JSON::XS qw(encode_json);my $app = sub { my $env = shift; return [ 200, [ 'Content-Type' => 'application/json' ], [ encode_json({ message => 'Hello, World!' }) ], ];};return $app;

変哲のない生PlackなHelloWorldウェブアプリ

Page 89: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

突然ですがベンチマーク• 環境• Vultr (VPS) の下から二つ目のプラン• 1コア (Vultr Virtual CPU 3392Mhz)

• Mem 1024MB、SSD

• CentOS6

Page 90: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Perl 5.20.0start_server --port=5000 --backlog 16384

-- plackup -E production -s Starlet --max-keepalive-reqs 1000 --max-reqs-per-child 50000 --min-reqs-per-child 40000 --max-

worker 1 -a ./helloworld.psgi

ab -n 10000 -c 10

Page 91: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

result - perl

Server Software: Plack::Handler::StarletServer Hostname: 127.0.0.1Server Port: 5000

Document Path: /Document Length: 27 bytes

Concurrency Level: 10Time taken for tests: 1.606 secondsComplete requests: 10000Failed requests: 0Write errors: 0Total transferred: 1670000 bytesHTML transferred: 270000 bytesRequests per second: 6225.76 [#/sec] (mean)Time per request: 1.606 [ms] (mean)Time per request: 0.161 [ms] (mean, across all concurrent requests)Transfer rate: 1015.33 [Kbytes/sec] received

Page 92: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

result - perl

Concurrency Level: 10Complete requests: 10000Requests per second: 6225.76 [#/sec] (mean)

Page 93: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「我がPerlは6000超え、PHPはどうだね?」『PHPは遅い…でも武器を手に入れたんだぜ!』「なんだと?」『PHPだってサーバーになれるんだ!!』「フッこざかしい、見せてみろ」

Page 94: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHPの武器libev

Page 95: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

php + reactPHP

<?phprequire_once 'vendor/autoload.php';

$app = function (\React\Http\Request $req,\React\Http\Response $res) { $res->writeHead(200, ['Content-Type' => 'application/json']); $res->end(json_encode(['message'=>'Hello World']));};

$loop = React\EventLoop\Factory::create();$socket = new React\Socket\Server($loop);$http = new React\Http\Server($socket);$http->on('request', $app);$socket->listen(5000);$loop->run();

Page 96: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHP 5.6.0php boot.php

ab -n 10000 -c 10

Page 97: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

result - php + reactPHP

Server Software:Server Hostname: 127.0.0.1Server Port: 5000

Document Path: /Document Length: 36 bytes

Concurrency Level: 10Time taken for tests: 3.397 secondsComplete requests: 10000Failed requests: 0Write errors: 0Total transferred: 1420000 bytesHTML transferred: 360000 bytesRequests per second: 2943.53 [#/sec] (mean)Time per request: 3.397 [ms] (mean)Time per request: 0.340 [ms] (mean, across all concurrent requests)Transfer rate: 408.18 [Kbytes/sec] received

Page 98: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

result - php + reactPHP

Concurrency Level: 10Complete requests: 10000Requests per second: 2943.53 [#/sec] (mean)

Page 99: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「なんだこの無様な値は」『…こんなハズでは…PHPerに未来はないというのか!?』「ISUC○Nでハブられるような言語がパフォーマンスに口出しするなど10年速い、言語を変えて出直してこい」「いや!言語は変えない…俺はPHPerだ!!」

Page 100: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHPの最終兵器HHVM

Page 101: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

HipHop VM 3.1.0hhvm boot.php

ab -n 10000 -c 10

Page 102: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

result - HHVM

Server Software:Server Hostname: 127.0.0.1Server Port: 5000

Document Path: /index.phpDocument Length: 36 bytes

Concurrency Level: 10Time taken for tests: 1.230 secondsComplete requests: 10000Failed requests: 0Write errors: 0Total transferred: 1420000 bytesHTML transferred: 360000 bytesRequests per second: 8132.90 [#/sec] (mean)Time per request: 1.230 [ms] (mean)Time per request: 0.123 [ms] (mean, across all concurrent requests)Transfer rate: 1127.81 [Kbytes/sec] received

Page 103: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

result - HHVM

Concurrency Level: 10Complete requests: 10000Requests per second: 8132.90 [#/sec] (mean)

Page 104: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

8132.90 [#/sec]

Page 105: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「さっきHHVMはお勧めしないとかいってたじゃねーか!」『手段を選んでいる場合ではなかった!』「貴様には矜持というものはないのか!!!」

Page 106: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

『某有名パンダの人も言っていた …ような気がする…んだが、 得意な言語で勝負はきまらないんだ!』

※意味が違う

Page 107: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「…ところで、これはどこで実際につかわれてるんだ?」『これはベンチ番長で、reactPHP(のhttpd)を本番に使う度胸はない』「えっ」『本番は普通にHHVMをhttpdモード(等)でつかう』「えっ」

(※reactPHPのhttpdは機能が全くもって不足(POST周りとかChunckedとか))

Page 108: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

HHVM httpd

hhvm -p 5000 -m s

ab -n 10000 -c 10

index.php<?phpheader('Content-Type: application/json');echo json_encode(["message" => 'Hello, World!']);

Page 109: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

HHVM httpd result

Server Software:Server Hostname: 127.0.0.1Server Port: 5000

Document Path: /index.phpDocument Length: 27 bytes

Concurrency Level: 10Time taken for tests: 1.704 secondsComplete requests: 10000Failed requests: 0Write errors: 0Total transferred: 1240000 bytesHTML transferred: 270000 bytesRequests per second: 5868.96 [#/sec] (mean)Time per request: 1.704 [ms] (mean)Time per request: 0.170 [ms] (mean, across all concurrent requests)Transfer rate: 710.69 [Kbytes/sec] received

Page 110: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

HHVM httpd result

Concurrency Level: 10Complete requests: 10000Requests per second: 5868.96 #/sec

Page 111: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「6225.76と5868.96で、負けとるやんけ」『普通にやったんじゃPerlには勝てなかったよ…』

Page 112: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

• 『PHPは(それなりに)速いですが、リクエスト毎に全てをディスポーズするイミュータブル世界観による限界が…』

• 「それこそがPHPの特徴だろ?」• 『php-pm(reactPHPをワーカにしたプロセスマネージャ)に夢を感じる』

• こういう話好きな人友達になってください。

Page 113: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

まとめ

• VPS&ローカルab => 計測誤差あるやろ• jsonのエンコードベンチ => マシなベンチを• 「実用的なものでなく、ベンチ番長で勝ってなんの意義があるのか?」『チャレンジしたい(という強い心)』

Page 114: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

• 実は「kazeburoパラメタ」をオフにすると勝ってた(5000くらいになる)(start_server --port=5000 --backlog 16384 -- plackup -E production -s Starlet -a ./hw.psgi)http://www.slideshare.net/kazeburo/yapcasia-2014lttfb(Max-workerは1コアなので効果無かった)

• (上のLTの後で良かった、危ない)• kazeburoさんには勝てなかったよ…(違

Page 115: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

それPHP?↓

それはもはやPHP(テンプレートエンジン)ではない

Page 116: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

まとめのまとめ• PHPはWEB向けなら手軽です• 今なら道具もそろっている• 今風の書き方もできる• 皆さんなら、いいPHPコードが書けるでしょう• (ダークサイドにおちなければよい)• 「それなりな」速度出るぞ• ズル(?)すればさらに上も狙える

Page 117: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

さて、こんなPHPをおぼえたいなら?(経験者向け)

Page 118: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

php the right way

http://ja.phptherightway.com/

安心の日本語翻訳です。ここをよめばとりあえず最初迷わないでしょう。PerlMongerの人はこれだけ覚えて帰って下さい。(ちなみに、PHPの情報を集めるなら、できれば海外の物が良いでしょう…まあ、海外もスットコな情報多いですが)

Page 119: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

基本的に以上ですが…時間はあまっている?

One more thing「s」または質問タイム

ーーーーーーーーーーーYAPC登壇者3人+パーフェクトRuby執筆者1人が書いた「Webアプリケーションエンジニア養成読本」好評発売中!

Page 120: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

ゆるふわ暗黒PHP

Page 121: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「こんなの暗黒か?PHPerは息をするように避けてるぞ」と思いますけど、この間あるPerlMongerに話したらウケた内容多めです。

Page 122: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

自動変換の闇

Page 123: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

有名なPHPの自動変換ですね。true == "1" // truetrue == "0" // falsetrue == "-1" // truetrue == "" // false

Page 124: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

皆様『PHPクソだな^^』

Page 125: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

まあ自動変換つかわなきゃいいtrue === "1" // falsetrue === "0" // falsetrue === "-1" // falsetrue === "" // false

true === true // true"1" === "1" // true

※ しかし、例えばin_array()とか既存関数内のマッチは==が…(ウウウゥ~!!)

Page 126: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「そもそも1がtrueとかありえないでしょwワロスw」

 『それ絶対JSON::xx::true周りの事知ってて言ってるで

しょ!!!』

Page 127: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

閑話休題0+"1" => int(1)0+"a1" => int(0)0+"1a" => int(1)0+".1" => double(0.1)0+"1." => double(1);

PHPは文字列を数値にキャストするとき、先頭にある数字的な文字だけを拾う…まあギリギリ?

…だけとおもいきや。

Page 128: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

これだ。0+"0e" => int(0)0+"0e0" => double(0) // <-- ???0+"2e2" => double(200) // <--!?0+"0XF" => int(15) // <--!?

数字の後にeやxがくると別の数値表現として解釈

Page 129: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「ウーーッ!!」(突如泡を吹いて倒れるPerlMonger)

Page 130: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

はい

Page 131: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

自動変換とは違うけどシンタックスが…な件

Page 132: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

print "a" . 1; // => "a1"

…まあ普通?しかし…

Page 133: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

print "a" . 1; // => "a1"!print "a".1; // Syntax Error

「突然のエラー」『冗談でしょう!?』

Page 134: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

"a" .1; // NG(Syntax Error) "a". 1; // OK => "a1"

『ハァ!?』「ほら、.1は数値リテラルだから…」『なるほど!?いやダメでしょこれ!?』

Page 135: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

現在のみなさんの脳内「PHP最悪ですね!^^」

Page 136: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「かかったな!」

Page 137: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Perlも.1が「先頭だと」0.1あつかい$ perl -e "print .1;"0.1

Page 138: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

余談ですが...

#!perl@a = (1);print (1 .@a); # ok ==> 11print (1.@a); # NG

まあ、言語って難しいですね。(別にどうという話ではない)

Page 139: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

はい

Page 140: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

いわゆるsplitの闇

Page 141: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

"1234" => ["1","2","3","4"]

としたい、よくありますね。PHPでこれはどうやるか?

Page 142: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

最初にみつかるexplode()

文字列を文字列により分割する例: explode("", "1234");

=> エラーになる、空文字不許可

残念

Page 143: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

それstr_split()

— 文字列を配列に変換する例: str_split("1234");

=> OKとおもいきやマルチバイト非対応

残念

Page 144: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

(ちょっと詳しい人なら)

『えっ、mb_str_split()あるんでしょ?』「無い!!!」

Page 145: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

mb_split() はどうか?

マルチバイト文字列を正規表現により分割するphp> var_dump(mb_split('', '1234'));array(1) { [0] => string(4) "1234"}

=> ダメ。しかもeregっぽいし…

残念

Page 146: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

php.netを見ると…

アホか!!!!!

Page 147: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「使い物にならんものばっかりや…」

Page 148: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

正解 preg_split()

正規表現で文字列を分割するpreg_split('//u', "あいう", -1, PREG_SPLIT_NO_EMPTY)

※//uはUnicode扱うやつです。

Page 149: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

php > var_dump(preg_split('//u', "あいう", -1, PREG_SPLIT_NO_EMPTY));

array(3) { [0] => string(3) "あ"

[1] => string(3) "い"

[2] => string(3) "う"

}

php > var_dump(preg_split('//u', ""/*空文字*/, -1, PREG_SPLIT_NO_EMPTY));

array(0) {}

期待通りの結果です!

「…なんかながくね?うしろのいらなくね?」

Page 150: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

外すと奇行に走り出す…php > var_dump( preg_split('//u', "あいう") );

array(5) { [0] => string(0) "" // < -- なにこれ [1] => string(3) "あ"

[2] => string(3) "い"

[3] => string(3) "う"

[4] => string(0) "" // < -- なにこれ}

php > var_dump( preg_split('//u', ""/*空文字*/ ) );

array(2) { [0] => string(0) "" // < -- なにこれ [1] => string(0) "" // < -- なにこれ}

Page 151: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

なので -1, PREG_SPLIT_NO_EMPTYは必要です…

他の言語ならめっちゃ短くかけるのに、どうしてこうなった??

「オプションの長さなら、json_encodeも負けてないぞ!」<?phpjson_encode($data, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_BIGINT_AS_STRING | JSON_PRETTY_PRINT );

Page 152: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

はい

Page 153: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

返値の謎

Page 154: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHPにも返値はあります。本当です。※ CLI、Cronとかで実行するときとかちゃんと見ますよね?例die();exit(1);

安心してください、0と1が返ります。※ 二つはエイリアスです

Page 155: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

実例$ cat exit.php<?phpexit(1);

$ php exit.php

$ echo $?1

正気ですね。

Page 156: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

exit("1");

Page 157: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

$ cat exit.php<?phpexit("1");

$ php exit.php1 < --- なにこいつ?

$ echo $?0

Page 158: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情
Page 159: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

exit(true);(まあこんなのやらんけど)

Page 160: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

$ cat exit.php<?phpexit(true);

$ php exit.php1 < --- ウワァァァッァァァァ!?!?!

$ echo $?0

( 単にboolのtrueをintでキャストすると1になるだけなんですけどね(多分) )

Page 161: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

はい

Page 162: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHP.netの闇

Page 163: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「http://php.netよくできてる」と、比較的多くの方から言われますね。

しかし「User Contributed Notes」は参考にしてはならない常識

ところで最近PHP.netがリニューアルされて少し対策されました。

Page 164: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「評価低いやつ、色が薄くなってる…」

Page 165: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

はい

Page 166: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

まとめ• 以上、氷山の一角でした。• 「危険PHP」を(訓練された)PHPerは書かない• 「安全PHP」書けばいい!• 疑ってかかれば大丈夫

• preg_splitとかは暗記すればいい

Page 167: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

皆様『覚えたくないよ!』私「はい」

Page 168: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

はい

Page 169: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

異常でした

Page 170: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

以上ですどうですか?ゆるふわ暗黒話で、最初の方を全部忘れている人がいたら悲しいですね。これを機会に一人でもPHPを使って見たいと思って頂ければ幸いです。トークの投票が好評なら来年もがんばります(?)

Page 171: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

ご静聴有り難うございました

きたれ! Hachioji.pmPerl,PHP,Javasript,Java(スマホ)等

http://hachiojipm.org/ や @hachiojipm

Page 172: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

質問ありますか? 

YAPC登壇者3人+パーフェクトRuby執筆者1人が書いた「Webアプリケーションエンジニア養成読本」好評発売中!

Page 173: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

おまけ(誰も質問とかしてくれなくて、はやく終わったらやる)

Page 174: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

余談:namespaceが\が区切り文字ということは…

<?phpnamespace ¥\¥{ class ¥{ static public function ¥(){ echo "\\ is not ¥".PHP_EOL; } }}

namespace { \¥\¥\¥::¥();}

こういうコードが可能なので…

Page 175: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

Meanwhile in windows

Windowsの一部のフォントはツライかもしれませんね!(こんなの書く人いないでしょうけど)

Page 176: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

関数名変数名に寿司もビアもいけるぞ!

PHPたのしいですね!!

Page 177: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

エラー処理の闇というか仕様

Page 178: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

PHPの「エラー」

• (スタートアップエラー)• 実行時エラーよく画面にでてるNoticeとかFATALとかのやつ

• 例外

(※ E_USER等のエラーの話はしません)

Page 179: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

実行時エラーの闇

• よくPHPサイトで出てくるエラーの事です• 画面に出す/出さない設定が可能

=> エラーログには出る• エラーレベルの設定も可能• NOTICEやDEPRECATED等は終了しない

=> (意図的に無視するPHPerの存在)• ERROR、PARSEなどは強制終了される

Page 180: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

ゆるふわPHPerの例

• 「エラー消せました!^^シェアします!」

• 「@」やerror_reportingでエラーレベルを変更してエラーを握りつぶす

• display_errorsで「画面から隠す」=> エラーログが数ギガとかになる&見ない

そう言う方々は無視するにせよ、PHPにはPerlのuse strict、use warningsが無いのが不便…(軽いエラーでも終了してくれる)

Page 181: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

無いならつくろ!!

set_error_handler( function ($errno, $errstr, $errfile, $errline){ echo("エラーだ~!ボク死ぬね^^!");

exit; });

エラーがきたら => 死ぬ

※適切に引数を表示したりerror_logしたりすると良いでしょう;

Page 182: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

エラーハンドリングの仕様の話

• 前述の通り、自前のエラーハンドリング関数がは登録できる

• が、場所によって頻繁に差し替えるのはダルい=> ログや、詳細を抑制位にしかつかいづらい

• 例外みたいにつかいたいよーー=> 例外に変換しよう!!

Page 183: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

例外に変換だ!!!

set_error_handler( function($errno, $errstr, $errfile, $errline){ throw new ErrorException( $errstr, $errno, 0, $errfile, $errline ); });

「ヤッタッ!これで例外に統一できる!!」

Page 184: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

これで完璧…?

• 自前エラーハンドリング関数は作れた• 例外に変換とかもできた• 「これで制覇した??!!」• んなわきゃーない

Page 185: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

残念仕様でてきたぞー^^

• FATAL(関数無いとか)やPARSEなどの強いエラーはトラップできない

• ログもエラーメッセージを出す事すらできない=> 「白い画面」がでてお客さんがおこ!!!=> そして闇っぽい解決策へ…

Page 186: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

闇っぽい解決策

• register_shutdown_function()関数登録するとスクリプト終了時にコール

• FATALなエラーで死ぬ時も呼ばれる• そこで「最後のエラーコード」を見て、エラーっぽいならエラー処理をする

• 「なにをいってるんだこいつは??」

Page 187: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

register_shutdown_function( function(){ // <-- スクリプト終了時に必ず呼ばれる $e = error_get_last(); // <-- 前のエラーをひろって if( $e['type'] == E_ERROR || // <-- 内容を見てよしなに…

$e['type'] == E_PARSE || // NOTICEとかは抜いてます $e['type'] == E_CORE_ERROR || $e['type'] == E_COMPILE_ERROR || $e['type'] == E_USER_ERROR ){ echo "致命的なエラーが発生しました。\n";

error_log("ERROR:". "/t:{$e['type']}/m:{$e['message']}". "/f:{$e['file']}/l:{$e['line']}"); } });

※正常終了時も無駄に呼ばれます

Page 188: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

やってられるか!!!• といいつつやる、結局定型だし。• PHPのエラー処理を真面目に書くのはしんどい• そもそも、Fatalとか自分のコードが悪い• そもそも例外に統一してほしい…

• エラーハンドラでFATALも扱いたい…

Page 189: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

はい

Page 190: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

パターンマッチの闇ともいいづらい闇

Page 191: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

「/(.*)-(.*)/ で "2014-8"をキャプチャしたい」

Page 192: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

/(.)-(.)/ < よくある

Page 193: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

preg_match()をつかえばよい

php > var_dump( preg_match("/(.*)-(.*)/u", "2014-8", $_));int(1)

php > var_dump( $_ );array(3) { [0] => string(6) "2014-8" [1] => string(4) "2014" [2] => string(1) "8"}

$_がPerlの$+{~}みたいなわけですねまあよさそう

Page 194: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

でもダメかもしれない存在しない$_をいきなり渡してる。(phpにmy(宣言)は無い)preg_match( "/(?year.*)-(?month.*)/u", "2014-8", $_ /*<--こいつ*/

)

ちなみにE_NOTICEではない。でもちょっと前の静的解析ツールは怒る。

Page 195: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

よくある折衷案php > $_ = []; // <--非常に無駄な空配列代入php > var_dump( preg_match("/(.*)-(.*)/u", "2014-8", $_));int(1)

php > var_dump( $_ );array(3) { [0] => string(6) "2014-8" [1] => string(4) "2014" [2] => string(1) "8"}

Page 196: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

ダサい

Page 197: YAPC::Asia 2014 - 半端なPHPDisでPHPerに陰で笑われないためのPerl Monger向け最新PHP事情

はい