都道府県のリストを出力するWebアプリを作った

サイト: https://morning-refuge-95932.herokuapp.com/

ソース: https://github.com/ryo-utsunomiya/japanese-prefectures-api

なぜつくったのか

1つのページで色々なフォーマットに対応したものがほしかったから。

どうやってつくったのか

アプリを作って、無料でホスティングする方式で考えていたので、Herokuを念頭に置いてPHPで作った。
PHPアプリを無料で動かす場所としてはHerokuはとても便利。
ちなみに、一番ハマったのはTwigテンプレート内でビット演算を行う方法がわからなかったこと。

つくってみて思ったこと

生データをJavaScriptの中にベタ書きするようにすれば、PHP使う必要なかったような…。
そして、PHPを使わないならHerokuを使う必要もなく、無料で使える静的Webサイトホスティングなら他にも選択肢はありそう。

今後の展望

ひらがな読みのフィールドを追加したり、SQLのテーブル名を設定できるようにしたりと、データの充実化や生成機能の柔軟化を図りたい。

PHPカンファレンス2016(東京)で「PHPで学ぶソケットプログラミング入門」というトークをしました

http://slides.com/ryoutsunomiya/php-socket-programming

背景

このようなトークをしようと思った背景を説明すると、

(1) 仕事でソケットプログラミングが必要になった
(2) しかし、日本語で、かつPHPで簡単にソケットプログラミングを学べる資料が無かった

ためです。

(1)については、ネットワーク機器からUDPでログを受け取ったり、TCPで命令を送ったり、といった感じです。
(2)については、「PHPでソケットを使ったプログラムを書いてみた」みたいな記事はいくつもありましたが、「ソケットを使うと何が嬉しいのか」「ソケットはどんな技術か」といった基礎的な部分を解説している記事は見かけませんでした。
そこで、(2)を満たすような資料があるといいなということで、今回の資料を作成し、発表を行いました。

なお、今回のトーク会場や、リハーサルをさせていただいたPHP勉強会で挙手によるアンケートをとったところ、
累計約100名のPHP開発者の中で、業務でPHPでソケットを使ったプログラムを書いたことがある方は(私以外では)わずか1名でした。
仕事にすぐに役に立つ技術ではないですが、一度覚えておくと長持ちする技術です。
「そろそろPHPフレームワークを漁るのにも飽きてきたなー」みたいな人は、ソケットを学んでみると新しい発見があると思います。

ReactPHPについて

資料の中でも何度か登場しているライブラリに ReactPHP があります。
ReactPHPのリポジトリの配下には細かいライブラリがいくつかありますが、PHPでソケットプログラミングを行う上で特に参考になるのは以下の2つです。

PHP Socket Programming Handbook 読書メモ シグナル

php_socket_programming_handbook


OSは以下のようなシグナルを実行中のプログラムに送る

  • SIGINT: プログラムを強制終了する
  • SIGQUIT: プログラムの終了(SIGINTよりも穏やかな方法)
  • SIGCHLD: 子プロセスが終了した際に親プロセスに送られる
  • SIGHUP: プロセスを制御しているターミナルが終了した際に送られ、設定ファイルの再読込に使われることが多い
  • SIGTTIN, SIGTTOU: バックグラウンドでTTYから読み込もうとしているプロセスに送られる

PHPでは、pcntl_signalを使ってシグナルの制御を行える

  • pcntl_signalでシグナル受信時のコールバックを登録する
  • pcntl_dispatchを実行するとシグナル受信確認が行われる

PHP Socket Programming Handbook 読書メモ PHPによるマルチプロセスプログラミング

php_socket_programming_handbook


  • あるプロセスの実行中に、別のプロセスを立ち上げるにはfork(2)を使用する
  • PHPでfork(2)を使用するにはpcntl拡張を使用する
  • pcntl_forkを使ってforkを行うことができる

https://github.com/phpsphb/book-examples/blob/master/multiprocess/limited_forking_echo_server.php

  • pcntl_forkの戻り値は、親プロセスの場合は子プロセスのPID、子プロセスの場合は0、forkに失敗した場合は-1
  • pcntl_waitpidは終了した子プロセスの プロセス ID を返す
    • WNOHANGオプションを指定すると、子プロセスが終了していない場合に直ちに処理を返る
  • pcntl_wifexitedはステータスが正常終了したか調べる

PHP Socket Programming Handbook 読書メモ PHPによるReactorパターンの実装

php_socket_programming_handbook


https://github.com/phpsphb/book-examples/blob/master/reactor/reactor.php

Reactorパターンを使うべき場合:

  • 複数のクライアントコネクションを同時に処理する必要があるが、サーバで複雑なコネクションマネジメントをしたくない場合
  • メモリが限られていて、マシン上で1つのサーバプロセスしか実行できない場合
  • forkが遅かったりメモリ消費量が多いプラットフォーム(主にWindows)で実行する必要がある場合
  • クライアントを処理している最中にコードがクラッシュしても、新しいサーバプロセスを再起動すれば住む場合

Reactorパターンを使うべきでない場合:

  • forkが高速でメモリ効率が良いプラットフォーム(主にUNIX、Linux)で実行する場合
  • 本当に並列処理を行う必要がある場合(Reactorは完全な並列ではない)
  • メモリが潤沢にある場合

PHPライブラリ

PHPによるReactorパターンの実装として著名なものにReactPHPライブラリがある。
また、stream_selectselect(2)に依存しているが、より高パフォーマンスのシステムコールにepoll(2)kqueue(2)などがある。
PHPでepoll(2)等を使いたい場合、これらのシステムコールを抽象化したライブラリであるlibeventのPHP向けインタフェースLibevent等を使用することができる。