HTTPメッセージ、PHPの 事情ば分かっとっと?
Transcript of HTTPメッセージ、PHPの 事情ば分かっとっと?
![Page 1: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/1.jpg)
HTTPメッセージ、PHPの
事情ば分かっとっと?
第102回 PHP勉強会@東京@sasezaki
『開発者は、ウェブアプリケーションを構築する際に
HTTPメッセージとどう対峙していけばいいのだろ
う?そのためには、SAPI・ストリーム・出力バッファ
リングと向きあなわければいけないのでは?』が今日
のテーマです。
2016.05.25
![Page 2: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/2.jpg)
● 自己紹介ここ数年の記事とか発表– 2015年03月 日記
PHP - 憂鬱な希望としての PSR-7 http://sasezaki.hatenablog.com/entry/2015/03/07/195908
– 2015年06月 Symfony Meetup
Symfony ユーザ向け psr-7 zend-diactoros Middleware 入門http://psr7.net/sasezaki/slide20150620/
– 2015年06月 動作確認
ストリーム 関連のプロジェクトの話https://gistlog.co/sasezaki/fb703148b0542d61f0bb
– 2015年11月 PHP勉強会@相模原
PSR-7 - これは何だhttp://psr7.net/sasezaki/slide20151110/
![Page 3: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/3.jpg)
● 自己紹介ここ数年の記事とか発表– 2016年05月 PHPカンファレンス福岡2016
HTTPメッセージ - PHPで扱う場合の再入門http://psr7.net/sasezaki/phpconfuk2016/
NEW
・・・ということで、察しがついたかも知れませんが、今日の話は先日の発表をベースにしてます。
![Page 4: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/4.jpg)
https://twitter.com/chobi_e/status/193717178615345153
![Page 5: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/5.jpg)
せやな(汗
...........SAPIって何?
![Page 6: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/6.jpg)
「PHPの実行環境は、主にWebサーバ(でのモジュール)」「サーバにはapache以外にも色々ある。」「CLIもサーバ」
『第1回 身近なWeb[PDF] – 放送大学』よりhttp://morimoto.code.ouj.ac.jp/resources/2015_web/01.pdf
![Page 7: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/7.jpg)
図コピペ元:http://tech.respect-pal.jp/php-helloworld/
![Page 8: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/8.jpg)
サーバーリクエスト (Incoming Request )
Webサーバ
HTTPリクエスト
PHPスクリプトコード
・ $_SERVER,$_GET,$_POST,$_COOKIE,$_FILES ・ apache_request_headers() ・ php://input
apache_request_headers()が必要な場面について “In particular, it SHOULD remove any header fields
carrying authentication information, such as 'Authorization'; or that are available to the script in other variables, “
(RFC 3875より)
![Page 9: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/9.jpg)
最大サイズ・最大長などの制限を設けてる● HashDosで知られるmax_input_varsの導入はPHP 5.3.9 から● もちろん、サーバソフト側でも制限設定項目はあり
● ApacheのLimitRequestBody ディレクティブなど
POSTメソッドでの場合の$_POSTへの変換● sapi_activateでのsapi_read_post_dataのコールにて取得
php-src/main/SAPI.c 参照● php.ini のenable_post_data_reading にて$_POST や $_FILESへの格納を無効化可能 (PHP 5.4より)
サーバーリクエストからのスーパーグローバルへ
![Page 10: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/10.jpg)
『今の若い人は CGI なんか知らないと思いますが、そういうのがあって、昔はとてもよく使われてたんですよ。この CGI の仕様を借りて WSGI が Environment の仕様を決め、Rack もそれを継承しています。そのため、CGI を知らない人から見ると奇妙な仕様に見えるでしょう。「なんで User-Agent ヘッダーが HTTP_USER_AGENT に変わってるの?そのまま User-Agent 文字列を使えばいいのに。」のような感想が出てきそうです。』
$_SERVER, CGI, Environment(wsgi, rack)
http://qiita.com/kwatch/items/67657fef43666479bb99
![Page 11: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/11.jpg)
※ ちなみに、PHPにおける”リアル”とは
![Page 12: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/12.jpg)
PHPのひょうじゅんAPIつらぽよ
![Page 13: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/13.jpg)
E_WARNING: Cannot modify header information - headers already sent by (output started at ...
![Page 14: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/14.jpg)
スーパーグローバルを直に触るのはつらいheader()を先に呼ばなきゃいけないのがつらいファイル配列操作がつらいリクエストURIの操作がつらい
『PSR-7: HTTP Message Meta Document』から意訳&抜粋
![Page 15: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/15.jpg)
アプリケーション実装者が行いたいことは、リクエストを受け取って、レスポンスを生成する
![Page 16: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/16.jpg)
function dispatch($request,$response);
![Page 17: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/17.jpg)
HTTPリクエスト
ディスパッチャ ( index.php )
ブートストラップ
コントローラ
ルーティング
リクエスト
レスポンス
View / テンプレート
リクエストルーター利用でのプロジェクト構成(例)
![Page 18: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/18.jpg)
かくして、PHP開発者はHTTPメッセージと末永く暮らしていきましたとさ。
めでたし。めでた.....
![Page 19: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/19.jpg)
Fatal error: Allowed memory size of 6291456 bytes exhausted (tried to allocate 2097153 bytes)
ひー
![Page 20: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/20.jpg)
PHP、おまえだったのか。
いつもHTTPメッセージを
運んでくれたのは
![Page 21: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/21.jpg)
メッセージボディは、文字列で決定やな。 * * @return string */ public function getContent() {
HTTPメッセージコンポーネント設計者
・・・なんや問題あるんか?
![Page 22: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/22.jpg)
何が問題?
メモリを制限なく消費する可能性→ ヘッダやボディに最大長についてRFC規定あっただろうか? 例えばApacheの場合、LimitRequestBodyにて許可バイト数設定
開発者は諦めてアクションでecho→ getContent()にてコールバックを許容した場合、 戻り値の方が一致しない
Streamリソース利用の発想が抜けている→ HTTPクライアントとして、ストリームは利用しているのに...
![Page 23: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/23.jpg)
レスポンスボディの出力・フラッシュ標準の設定では、echoがあれば直ちに送信や文字列すべてを出力はしないパフォーマンスのためにデフォルトのphp.iniではoutput_buffering = 4096 に設定されている。※ CLIは除く
ob_start() コールバック関数ob_start() での引数、またはphp.iniでのoutput_handlerの指定により、出力バッファの内容を操作できる。 ob_gzhandler()関数など
テンプレートエンジン / Viewレンダラーでの応用出力内容を文字列として取得するために、ob_start() ob_get_contents()を行っている。ここでもメモリ使用量増大の可能性
出力出力バッファリング制御制御
![Page 24: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/24.jpg)
せや、streamや!
* * @return stream */ public function getContent() {
HTTPメッセージコンポーネント設計者
![Page 25: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/25.jpg)
抽象化 I/OPHP 4.3から登場したresourceオブジェクト普段のファイルシステムやhttpなどのスキーマは、デフォルトのラッパーにすぎない
入出力ストリームphp://temp により、メモリならびにテンポラリファイルへの読み書きが行える
ストリームフィルタストリームはカスタムフィルタを作成し、登録できる
PHPPHPにおにおけるStreamStream
![Page 26: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/26.jpg)
レスポンス作成時の例外・エラー処理レスポンス作成時の例外・エラー処理 ストリームや出力バッファリング制御 の利用により、メモリ利用量を抑えレスポンス出力時に処理を実行することは可能でしょう。 ただし、レスポンスボディ作成時の例外(DBコネク
ションエラーなど)などを考慮すると一度テンポラリーに書き出しておき、そのストリームリソースを再度渡すなどの対応も考慮すべきでは。
![Page 27: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/27.jpg)
![Page 28: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/28.jpg)
HTTPメッセージコンポーネントがおおすぎる
![Page 29: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/29.jpg)
• Cake\Network\{Request,Response}• CI_Input, CI_Output• Nette\Http\{Request,Response}• PHPixie\HTTP\{Request,Responses}• Symfony\Component\HttpFoundation\{Request,Response}• yii\web\{Request,Response}• Zend\Http\{Request,Response}
Rob Allen 『HTTP, PSR-7 and Middleware』から
![Page 30: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/30.jpg)
依存を抑え、リクエスト・レスポンスを扱う処理
を相互運用するには?
![Page 31: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/31.jpg)
HTTPレスポンス
ディスパッチャ
ブートストラップ
コントローラ
ルーティング
リクエスト
レスポンス
View / テンプレート
Debugツールバー
Authentication
ミドルウェア・ランナー
MiddlewareMiddleware
Middleware
Middleware
ミドルウェア利用でのプロジェクト構成例
while (! $stream->eof()) { echo $stream->read(8192);}
![Page 32: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/32.jpg)
リクエストを受け取って、レスポンスを合成し、次の処理へ渡す
![Page 33: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/33.jpg)
function __invoke( ServerRequestInterface $request, ResponseInterface $response, callable $next);
![Page 34: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/34.jpg)
psr-7はHTTPメッセージの値についてのinterfaceを定義している従来のレスポンスクラスでは、send()メソッドなんて用意していた
サーバーリクエストには、アプリケーションでの相互運用のために attributesプロパティが用意されているミドルウェアシグネチャでの議論・検討の余地従来のEventManagerを利用したプラグインとの使い分けは?HTTPクライアントでのミドルウェアはどうあるべきか?インターフェイスなどにて別途psrを定義すべきでは?
PSR-7 とミドルウェア
![Page 35: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/35.jpg)
PSR-7 PSR-7 に対するご意見に対するご意見
![Page 36: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/36.jpg)
● PHPカンファレンス福岡2016で出た質問・余談
–Q「ストリームだと、今までの文字列関数を利用したフィルタリングに比べて大変では?」●私見「レスポンスボディ全体を文字列置換?(困惑)」(“エンコード”の範囲なら、今までのstream filterの想定範囲と同様に効力あるかと)
![Page 37: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/37.jpg)
● PHPカンファレンス福岡2016で出た質問・余談
–Q「echo に比べてストリーム大変ですよ。。」
これを
![Page 38: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/38.jpg)
● PHPカンファレンス福岡2016で出た質問・余談
–Q「echo に比べてストリーム大変ですよ。。」
こうしたり
![Page 39: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/39.jpg)
● PHPカンファレンス福岡2016で出た質問・余談
–Q「echo に比べてストリーム大変ですよ。。」
こうじゃ!
![Page 40: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/40.jpg)
● PHPカンファレンス福岡2016で出た質問・余談
–Q「PSR-7だと今のPHP組み込みのセッション機構と整合性がないのでは?」●私見「Cookieを利用したセッションということで?本発表で述べたように、PHPはHTTPメッセージ解釈機能を併せ持ってこそツールとしての価値があるのです。私は、それを崩そうとは思いません。従来の($_SESSIONをラップした)セッションコンポーネント使います。」(本音「そこまで、深く考えてなかったンゴwww」 今までのHTTPメッセージコンポーネントでも同様の問題では。。)※ 「PSR-7 and Session Cookies」http://paul-m-jones.com/archives/6310 という記事にセッションのクッキーヘッダーへのハック周りについて記載があります。
![Page 41: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/41.jpg)
おわりです
ご清聴ありがとうございました
![Page 42: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/42.jpg)
イラスト素材●http://www.wanpug.com/●http://hiyokoyarou.com/
![Page 43: HTTPメッセージ、PHPの 事情ば分かっとっと?](https://reader031.fdocuments.net/reader031/viewer/2022021417/587068051a28ab48378b55e3/html5/thumbnails/43.jpg)
参考文献● php と sapi と zendengine2 と..http://www.slideshare.net/do_aki/php-and-sapi-and-zendengine2-and
● PHP による hello world 入門http://tech.respect-pal.jp/php-helloworld/
● PHP output buffer in deephttp://jpauli.github.io/2014/12/19/php-output-buffer-in-deep.html
● PSR-7: HTTP message interfaceshttp://www.php-fig.org/psr/psr-7/
● PSR-7: HTTP Message Meta Documenthttp://www.php-fig.org/psr/psr-7/meta/
● A Case for Higher Level PHP Streams in PSR-7http://mtdowling.com/blog/2014/07/03/a-case-for-higher-level-php-streams/