taro-h’s diary

たろログ

ブログです。近況報告とか振り返りとかとか

「プログラミングPHP 第3版」 O'REILLYを読みました。

www.oreilly.co.jp

2013年に発行されたかなり古い本ですが、 プログラミングPHPという書籍を読みました。
PHP5技術者認定上級/準上級試験では主教材とされている書籍です。

「PHP5」技術者認定の主教材とされていることからもわかる通り、この書籍が扱うPHPのバージョンは5系です。
紹介されているライブラリや関数も当時使われていたが今は使われていないものが多く、ライブラリなどはWebの公式マニュアルを見に行くと、"Duplicated"となっているものが多々ありました。

というわけで、内容が古すぎて具体的なサンプルコードやテクニックはあまり役に立たなかったなという感想です。

一方で、

  • PHPの歴史を知る
  • PHPの言語としての基本的な構造を把握する

という面では、優れた書籍だと思いました。

また、

  • Webの基礎が学べた

という点でも有用だったなと思います。

歴史

1章 PHPについて

歴史については主に1章に記されています。
p.2ページからp.7ページにかけて、当時のRasmusのコメントやメール文を引用しながら、PHP1.0~3.0までのリリースについて順を追って説明してくれています。

面白かった箇所としては、

  • 1.0

    • リリース時の名称は、PHP Tools (Personal HomePage Tools)
    • PHPはもともと、C言語で書かれたCGIバイナリを集めたものとして提供された
  • 2.0

    • リリース時の名称は、PHP/FI
    • ApacheAPIを利用し、導入しやすくなった
    • ここからデータベースへのSQLクエリ実行をサポート
  • 3.0

    • 幅広いOS, DB, WEBサーバに対応
  • 4.0

    • 構文解析パーサをほぼ書き直す(Zendエンジンと名付けられる)

のあたり。

全体を通して

今僕らが書くPHPは完全にスクリプト言語で、HTMLはTemplateエンジンから生成するのが一般的です。
しかし、昔のPHPの一般的なユースケースはHTMLに埋め込む形で実行するというのが主流だったのだなというのが全体を通してよくわかりました。

文字列操作のあたりでは、

などをはじめとして豊富なHTML文字列変換のための関数が大量に紹介されています。
おそらく今後利用することはなさそうですが、知らなかったものばかりでした。このような関数が大量に用意されていることから特に、昔のPHPユースケースを強く感じることができました。

PHPの言語としての基本的な構造

2章 PHP言語の基本

2章では、基本的なPHP言語の基本的な項目について記載されています。

などなど、そういやしっかりとは知らなかったなというところを確認できたのがタメになってよかったです。

ガベージコレクション

PHP言語の基本において、この項目が一番面白かったで。す。 マニュアルにもありますが、PHPではcopy_on_write方式を採用しています。 また、その理解のために、シンボルテーブルという変数を管理するテーブルについて踏み込んで説明があります。

ただ、これは5系の実装で、7系ではいろいろと変更になっているようです。

また、PHP7では参照カウンタ(refcount)がzvalから消えているのも特徴的です。PHP5では全ての型がコピーオンライト方式で管理されているためzvalで参照カウンタを持っています。一方、PHP7ではNULL・真偽値・整数・浮動小数点数の4つの型では基本的にスカラー値がコピーされるようになり、参照カウンタが無くなっているのです。 https://hnw.hatenablog.com/entry/20141207

この辺それなりに分かった気になってたんですが、今記事にしてみたらうまく説明できないことがわかりました。 まあ、追い追い把握していこうと思います。

すごくいい記事がリアルタイムに更新されていました。追っていきたいです。

qiita.com

オブジェクト指向

「6章 オブジェクト」にて、オブジェクト指向についての説明がなされます。

trait

trait という、コードの再利用をするための仕組みをこの本で初めて知りました。

継承をせずとも、メソッドを共有することができます。
挙動としては DI (Dependency Injection) とよく似ていますが、以下のブログで記載されているとおり、ケースにおいてはDIと trait を併用することで、コードの保守性を上げることができるようです。 medium.com

検索した感じ、バッドノウハウではなくそれなりに使われている感じでした。
不用意に導入すると可読性が落ちそうですが、うまく使えば冗長なコードを減らすことができそうです。

メソッドの使い回しまわりで困ったときには trait が使えないかなと思い出してみることにします。

ウェブの基礎

「7章 ウェブに関するテクニック」では、ウェブの基本を踏まえた上で、PHPをウェブ上で利用する際のテクニックについて解説されています。
具体的なテクニックについては前述したとおり、情報が古いため現代のPHPユースケースに合わないという理由であまり役に立たないのですが、HTTPの基本についての説明は非常に勉強になりました。

Telnet でのHTTPアクセス

HTTPリクエスト、HTTPレスポンスの出力を確認するために、Telnet でアクセスを行い、その出力を確認する節があります。(p.184)
実際に手元のUbuntuで実行してみました。楽しい。

$ telnet 127.0.0.1 80 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. GET / HTTP/1.0 HTTP/1.1 200 OK Date: Sat, 08 Aug 2020 10:26:15 GMT Server: Apache/2.4.29 (Ubuntu) Last-Modified: Sun, 31 May 2020 00:37:32 GMT ETag: "611f-5a6e6e24d1254" Accept-Ranges: bytes Content-Length: 24863 Vary: Accept-Encoding Connection: close Content-Type: text/html telnetでHTTPリクエストを送る - taro-hida's tech memo

GET, POSTについての思想

これは考えるきっかけになった程度で、まだよくわかりません。

POSTリクエストはべき等ではありません。つまり、その結果はキャッシュできず、そのページを表示するたびに毎回サーバに接続する必要があるということです。 ブラウザ上でページを再読込する際に「フォームのデータを再送信しますか?」というようなメッセージを見たことがあるのではないでしょうか。 これは、POSTリクエストの問い合わせ結果が場合によって変わるということを考えると適切な対応です。
現実には、この「冪等性」はあまり気にされていないようです。ブラウザのキャッシュ機能の実装はあまりよくできておらず、多くの人が深く考えずに「再読み込み」ボタンを押しています。プログラマにしても、GETとPOSTの違いは単にURLにパラメータが表示されるかどうかだけだと考えがちです。 ここで覚えておくべきことは、サーバーに変更を加えるような動作(たとえば注文を行ったり、データベースを更新したりなど)にはGETリクエストを使ってはいけない、ということです。 [プログラミングPHP](https://www.oreilly.co.jp/books/9784873116686/) 第3版 p.188 より引用
「フォームのデータを再送信しますか」の意味 - taro-hida's tech memo

上記で述べられていた、「フォームのデータを再送信しますか?」の意味については「なるほど!」とアハ体験をすることができました。

その後もしばらく調べてたんですが、かなり底の深そうなトピックでした。

GET, POSTの扱いについて調べていると、REST API を前提として説明している記事がたくさん見つかりました。

GET, POSTの扱いについては共通認識の問題だと思います。現在はこの書籍執筆当時より議論も進み、書かれている以上に色んなプラクティスがありそうな印象です。

このあたりについてはまた再度別の書籍等で掘り直してみようと思います。

セッション

セッションについての説明も非常に良かったです。

まず、セッションを追跡する手法の歴史が出てきます。ステートレスなHTTPというプロトコル上において、複数リクエスト感での情報の引き継ぎを実現しようとしたプログラマたちの歴史です。

例としては、以下のようなものが挙げられていました。

  • フォームのhidden要素に格納した情報を引き継ぐ
  • http://www.example.com/catalog.php?catalog.php=123 のように、URLを動的に書き換えて情報を引き継ぐ
  • Cookieをレスポンスヘッダに埋め込み、Clientに送信する
  • Sessionを利用する

最後にセッションが出てきます。
とはいえ、セッションも内部的には3番目のCookieを利用しています。

Cookieは、ヘッダに埋め込んでクライアントと情報をやり取りするものです。
詳しくは 【PHP超入門】Cookieとセッションについて - Qiita の説明がよかったです。

セッションについては、rana_kualu さんの説明がよかったです。

PHPでセッションを使った場合、裏ではSet-Cookie:PHPSESSID=54r0kqh4s67952b8i9qu4nu4jtnpcd6lといった形のCookieが発行されます。 この54r0kqh…というのは$_SESSIONの登録内容とは全く無関係な、ランダムな文字列です。 そして$_SESSIONの中身自体は、サーバのどこかにsess_54r0kqh4s67952b8i9qu4nu4jtnpcd6lのようなファイル名で保存されています。
で、PHPではPHPSESSID=54r0kqh4s67952b8i9qu4nu4jtnpcd6lというCookieが送られてきたら、同名のファイルを探して中身を$_SESSIONに展開してくれます。 この仕組みにより、Cookieをひとつ使うだけで、大量のデータを保持できるようになっています。
setcookie()っていつ使うの? - Qiita

サーバ上のファイルに情報を格納して、そのファイル名を元にした識別子をやり取りしてくれているわけですね。
PHPはファイルの読み込み、書き込みをすることで、セッションに結び付けられた情報を保持することができます。

古かった部分

このあたりは少し読んで、わざわざ把握する必要がないなと感じたため飛ばしました。

あと、「4章 文字列」において、HTMLの要素書き換え用の関数が列挙されている箇所がありました。
一応一通り確認したんですが、今後使うことはなさそうだなと思います。今ほとんど覚えていません*1

バッドノウハウ

PHPの面白い実装についてもこの本を通じて知ることができました。バッドノウハウです。*2
なおPHPバッドノウハウについては、 モダンPHPアンチパターン - Qiita が詳しいです。

可変変数

一番おもしろかったのがこの可変変数です。
モダンPHPアンチパターン > 可変変数(variable variables)でバッチリ紹介されています。

コードを読みにくくすることができることは間違いありません。

関数の閉じカッコの後にセミコロンをつけることができる

参照:PHPの言語仕様 (命令文とセミコロン) - Qiita

PHP終了タグの直前のセミコロンは省略できる

参照:PHPの言語仕様 (命令文とセミコロン) - Qiita

終わりに

3月から読み始め、読み終わったのは8月でした。5ヶ月ww

毎度のごとく、メモ書きのPDFを記録としてブログにくっつけておきます。
いつも画像化していましたが、今回は Google Drive で共有する形にしてみました。

drive.google.com

実用性を考えると、あまりおすすめできる本ではない

  • 良い点

    • 体系的に情報がまとまっており、読みやすい
    • 現行マニュアルに比べると圧倒的に量が少ないので、全体像を把握するのによい
    • PHPの歴史を感じることができる
    • Rasmus Lerdorf が執筆に関わっている
  • 悪い点

    • 情報が古い
    • PHP5系を前提に書かれている

一通り読みましたが、やはり情報があまりに古く、役に立たないだろうな...という情報が多いです。
私もこれでPHPマスター!というわけではなくて、今から現行のマニュアルを読み直していくフェーズに入ります。

ただ、やはり体系的にきれいにまとまっているので、現行のマニュアルを読む足がかりとしてはいいのではないかと感じました。
古い古いとは言いつつ、現行と変わっていないところは多いです。

一方、実用を無視して考えると、PHPの歴史を感じられるという点においてすごく面白かったです。
また、言語製作者のRasmus Lerdorf が執筆に関わってる点が非常に魅力的でした。

PHPに愛を感じ始めた方にはおすすめできる一冊です。

中古本ならではの楽しみ

購入は中古で行いました。前の人の書き込みが残っていて面白かったです。

前の人の書き込み

f:id:mutsu00062:20200816004249p:plain

前の人の書き込みにツッコミを入れる私

f:id:mutsu00062:20200816004257p:plain

読者に総ツッコミを入れられる著者

f:id:mutsu00062:20200816004308p:plain

p.s.

このブログを、Elemの書籍の読書録を書いている彼に捧げます。
俺は読み切ったぞ!(謎に張り合う)
圧を感じていただけると幸いです。第三回はよ。

p.s.2.

悲報兼朗報。。。2020年5月に、英語版ですが第四版が発売されていました。

www.oreilly.com

これも読んでみようかな。

*1:前述の通り、昔のPHPユースケースを感じられた点については良かったです

*2:書籍としてはPHPの実装の一つとして紹介・解説しており、バッドノウハウであるとは書かれていません。