PHPはどのように動くのか ~PHPコアから読み解く仕組みと定石

著者
蒋池東龍こもいけとうりゅう 著
定価
2,508円(本体2,280円+税10%)
発売日
2015.9.17
判型
A5
頁数
248ページ
ISBN
978-4-7741-7642-0 978-4-7741-7679-6

概要

同じようなスクリプトなのに,なぜパフォーマンスが違うのか?
オブジェクト指向だと,なぜ遅いのか?
PHP7は,なぜ速くなったか?

最も人気のあるWeb用プログラム言語であるPHPの知られざる内部構造を解説した,日本初の書。「メモリを節約したり,処理を軽くしたりするスクリプトを書くには」「パフォーマンスの高いExtensionを作るには」「Zend Engineをハックするには」といった,ほかにはない話題が満載です。

こんな方にオススメ

  • PHPの仕組みを知り,定石やパフォーマンスの背景について理解を深めたい中上級者

目次

第1章 なぜ,同じようなスクリプトなのにパフォーマンスが違うのか

スクリプトの良し悪しは何で決まるのか

  • 処理速度はスクリプトの前後の文脈に依存する
  • 内部構造を知ることが正確な判断への手がかり
  • 処理速度を計測するには
  • 論理の判断

スクリプトを比較する

  • forの最大値が変数 vs. 関数
  • 条件分岐 if else vs. 三項演算子
  • 比較演算子 == vs. ===
  • エラー制御演算子がない vs. ある
  • 連想配列の添え字がクォートなし vs. シングルクォート
  • PHPのバージョン取得 phpversion() vs. PHP_VERSION
  • 標準出力 print() vs. echo()
  • echoに渡す引数 カンマ vs. ドット

第2章 オペコードのパフォーマンスを考える

プログラムが実行される仕組みをおさえる

  • オペコードはどのように生成され,実行されるか
  • 字句解析と構文解析で行われること
  • オペコードが実行されるまでの流れをつかむ
  • コンパイル処理の流れをおさえる
  • どのようにしてオペコードが演算されていくのか

パフォーマンスに影響するオペコードをおさえる

  • 型によるパフォーマンスの違い
  • 代入によるパフォーマンスの違い
  • 関数や引数の処理によるパフォーマンスの違い
  • 特殊な処理によるパフォーマンスの違い

第3章 PHPコアの仕組みと開発の定石を知る

メモリの仕組みと定石

  • メモリの確保
  • メモリの解放
  • メモリを操作するAPI

zvalの仕組みと定石

  • zvalに関連した構造体
  • コピーオンライトの仕組みをおさえる
  • zvalを生成/解放する
  • zvalの変数を配列にする
  • zvalの種類を取得する
  • zvalの型を調べる
  • zvalの値を取得する
  • zvalの値を設定する
  • zvalの型を変換する

HashTableの仕組みと定石

  • HashTableにキーとデータを登録する流れ
  • HashTableにキーと値を登録する
  • HashTableのキーに対する値を更新する
  • HashTableへ値を登録する
  • HashTableのインデックスに対する値を更新する
  • HashTableのキーと値を削除する
  • HashTableのインデックスと値を削除する
  • HashTableを展開する
  • HashTableを検索する

クラスの仕組みと定石

  • 構造体zend_object_valueの中を覗く
  • オブジェクトを生成する

関数の仕組みと定石

  • 引数を処理する
  • 引数を参照渡しする
  • 戻り値を設定する

出力の仕組みと定石

  • 標準出力の中身を覗く
  • エラー出力の中身を覗く

第4章 オブジェクト指向だとなぜ遅いのか

クラスの仕組みを覗く

  • クラスの宣言ではどのようなことが行われているか
  • クラスの継承ではどのようなことが行われているか

オブジェクトの仕組みを覗く

  • プロパティを読み込む場合はどのようなことが行われているか
  • プロパティに書き込む場合はどのようなことが行われているか
  • メソッドを実行する場合はどのようなことが行われているか

第5章 PHP7はなぜ速くなったか

HHVMとPHP7

  • HHVMが超高速に動作する理由
  • PHP7はインタプリタ言語でありながらパフォーマンスが高められた

zvalで何が変わったか

  • PHP5のzvalとPHP7のzvalを比較すると
  • 文字列へのアクセスが速くなった
  • 配列型ではHashTableへのアクセスが悪くなった
  • オブジェクトでプロパティを探索するのが速くなった
  • コピーオンライトでポインタをたどるオーバーヘッドがなくなった
  • 変数の扱い方がどのように変わったのか

HashTableで何が変わったか

  • HashTableとBucketの構造体を比較すると
  • Bucketを動的に確保せず,走査も高速に

関数における引数の処理で何が変わったか

  • PHP5では関数の解析でパフォーマンスが落ちていた
  • マクロを利用することでパフォーマンスを高められるように

第6章 Extensionを作る

開発の前におさえておきたいこと

  • PHPコアのライブラリを把握する
  • ビルド環境を構築する

関数をExtensionとして書き直す

  • 元になる関数のスクリプト
  • モジュール構造体の中身や基本的なマクロを知る
  • モジュール構造体に関数を登録する
  • Extensionにおける関数を定義する

関数をクラスとして作りなおす

  • 元となるクラスのスクリプト
  • クラスにメソッドを紐づける
  • クラスを登録してプロパティを追加する
  • メソッドを定義する

C++のクラスをExtensionのクラスに

  • 元となるC++のクラス
  • テンプレートライブラリを用意する
  • Extensionのクラスを実装する
  • Extensionのクラスを登録する

第7章 Zend Engineをハックする

オペコードの8つの分類を把握する

exitでも終了しないようにする

スクリプトで関数を作れないようにする

クラスのインスタンスを生成できないようにする

includeをinclude_onceに,requireをrequire_onceに強制的に変更する

新しい構文を追加する

Appendix オペコード一覧

プロフィール

蒋池東龍こもいけとうりゅう

1976年生まれ。大手IT企業でPHPコアのエバンジェリストを担う。Skyscanner Japan株式会社でCTOを務める。
1999年にプログラマとしてセガ(当時セガ・エンタープライゼス)へ新卒入社し,ゲーム開発に従事。2004年10月に大手IT企業へ転職し,さまざまなサービスに携わり,プラットフォームからミドルウェア,フロントエンドまでを担当する。
コーディングのこだわりは「同じコードを書かない」こと。PHPがどのように動いているかに興味を持ち,ソースファイルを読み解く。PHP Extensionの効率的な開発方法やパフォーマンスが向上する方法を研究。PHPカンファレンスにも登壇。