まえがき
第1章 型別に理解する変数の扱い方
第2章 変数のスコープと特別な変数・定数
第3章 型の変換
第4章 (PHP7) 型宣言
第5章 (PHP5.3)名前空間
第6章 (PHP5.3)オートロード
第7章 外部ライブラリーの活用
第8章 (PHP7)エラーと例外
第9章 アーキテクチャー
第10章 PSRコーディングガイドライン
第11章 正規表現を楽しもう
第12章 テンプレートエンジン
第13章 パフォーマンスとデバッグ
第14章 PHPとバージョンアップ
第15章 良質なPHP情報を得るには?
第16章 Hack/HHVMとPHP
付録A (PHP5.4) ビルトインウェブサーバー
付録B PHPエンジニアとサーバーサイド
付録C 静的コード解析と周辺ツール
付録D セキュリティー
付録E 主要参考文献
あとがき
本書を手にとっていただきまして、ありがとうございます。
本書はPHPの入門書を読み終えた方がさらなる実力をつけるための本です。PHPの本は初心者向けやフレームワークに関するものが多いのですが、本書はPHPそのもので中級者になることを想定して執筆しました。
そのため、本書は一般的なPHPの入門書にはあまり載っていない事柄を中心に掲載しています。言語を深掘りすることで、理解度を高めていくことが狙いです。
また、本書はPHPの言語そのものについて書いた本であり、特定のフレームワークに依存する内容ではありません。どのPHPフレームワークを使っていても役に立つ内容になっています。
・PHPの入門書を読み終え、次のステップを目指している方
・昔のPHPは使っていたが、最近のPHPは分からない方
・プログラミング言語としてのPHPの理解を深めたい方
PHPは常に進化しており、本書の執筆時点ではPHP7.3が最新バージョンです。本書はこのPHP7系の時流に乗った内容を意識しているため、PHP5からPHP7への橋渡しとしてもお使いいただけます。
PHPについての理解度を深めると、普段のPHPプログラミングにも幅が広がります。初級者から中級者を目指すレベルアップの旅路に、本書が少しでもお役に立てば幸いです。
本書のサンプルコードは、GitHub上の次のリポジトリーに掲載しています。
https://github.com/konosumi/techbook-levelupphp-sample.git
「Clone or download」より「Download ZIP」をクリックするか、お手持ちのGitクライアントにてcloneしてご利用ください。
# コマンドラインのGitからサンプルをダウンロードする場合
git clone https://github.com/konosumi/techbook-levelupphp-sample.git
cd techbook-levelupphp-sample
# 本書のサンプルは、コマンドライン(CLI)のPHPで動作します
php hello-levelup.php
本書のサンプルは、全て純粋なPHPコードです。入門書などで構築したPHP環境は、そのままお使いください。
なお、本書のサンプルコードはコマンドライン(CLI)のPHPで動作することを想定しています。Macでの動作も想定して、MacにインストールされているPHP7.1.19での動作確認も行いました。そのため、Macユーザーであれば、とくに環境構築は必要ありません。
ただし一部でPHP7.2以降の文法を使っているため、その場合はPHPBrewなどをご利用ください。PHPBrewを使うと、いつでもPHPのバージョンを切り替えることが可能です。
本書に記載された内容は、情報の提供のみを目的としています。したがって、本書を用いた開発、製作、運用は、必ずご自身の責任と判断によって行ってください。これらの情報による開発、製作、運用の結果について、著者はいかなる責任も負いません。
本書に記載されている会社名、製品名などは、一般に各社の登録商標または商標、商品名です。会社名、製品名については、本文中では©、®、™マークなどは表示していません。
本書籍は、技術系同人誌即売会「技術書典5」で頒布されたものを底本としています。
変数はプログラミングにおいてもっとも基本であり、もっとも重要です。まずは、PHPにおける変数について型別にみていきましょう。
言語リファレンス > 型
http://php.net/manual/ja/language.types.php
PHPの変数には、他のプログラミング言語同様さまざまな型があります。
・論理型(boolean)
・整数(ingeger)
・浮動小数点数(float,double,実数)
・文字列(string)
・配列(array)
・(PHP7.1)繰り返し可能(iterable)
・オブジェクト(object)
・リソース(resource)
・NULL
・(PHP5.4)コールバック(callable)
この中で、iterableとcallableは疑似型と呼ばれる型です。後ほど登場する型宣言で主に利用します。
なお、細かい説明をすると型の情報を持っているのはzval構造体なのですが、興味がある方はPHP7におけるzval構造体について調べてみてください。
中級者のレベルを超える内容かもしれませんが、この点は本書でも触れておきます。PHP7ではPHP5系に比べて大幅にパフォーマンスが向上しています。これには、PHPの内部における変数の管理方法が影響しています。
すぐに理解するのは難しいかもしれません。鍵は、ポインタ参照という構造を理解できるかどうかです。今の時点では、PHP7で内部的なデータ構造が大胆に効率化されているという点は忘れずに覚えておきましょう。次の記事が参考になります。
・PHP7はなぜ速いのか(zval編)
─https://hnw.hatenablog.com/entry/20141207
・PHP7の肝 zval構造体を読み解く
言語リファレンス > 型 > 論理型 (boolean)
http://php.net/manual/ja/language.types.boolean.php
論理型はもっとも単純な型で、真偽の値を表します。真(true)または偽(false)のいずれかの値になります。
$a = true;
$b = false;
echo gettype($a).PHP_EOL; // boolean
論理型は単純な値ですが、とても重要です。なぜならば、PHPには真偽値を返す演算子がたくさんあるからです。
・比較演算子(===, !==, <...)
・論理演算子(and, !, ||...)
・配列演算子(==, <>, !=...)
・型演算子(instanceof)
「if ($c > $d) {}」のような制御構文ではまず比較演算子が働き、論理型の値が生成されます。そして、その結果がifで判定されます。
$c = 1;
$d = 2;
var_dump($c === $d); // bool(false)
var_dump($c > $d); // bool(false)
「ifの判定は、真偽値によって行われる」。この感覚は重要なので、絶対に忘れないようにしてください。PHPに限らず他の多くのプログラミング言語でも、ifの判定は最終的に真偽値によって行われます。
言語リファレンス > 型 > 整数
http://php.net/manual/ja/language.types.integer.php
整数には、大きく分けて「正の整数」「ゼロ」「負の整数」があります。
$a = 3; // 正の整数
$b = 0; // ゼロ
$c = -10; // 負の整数
echo gettype($a).PHP_EOL; // integer
2進数・8進数・16進数による表現も可能です。
$a2 = 0b111; // 2進数(先頭に0b)
var_dump($a2); // int(7)
$a8 = 012; // 8進数(先頭に0)
var_dump($a8); // int(10)
$a16 = 0x1A; // 16進数(先頭に0x)
var_dump($a16); // int(26)
2進数以外を使う機会があるのかと疑問に思う方もいらっしゃるかもしれません。実はWebプログラミングの世界ではよく使われています。たとえば、次のような数値で利用されています。
・16進数の例:HTMLのカラーコード(#ffffffなど)
・8進数の例:Linuxにおけるファイルのパーミッション(0755など)
2・8・16進数について、筆者は基本情報技術者試験の勉強で習得しました。ぜひこの機会に知っておくことをオススメします。
PHPでは整数で表現可能な範囲が決められています。とても大きな値ですのでなかなか意識する機会はありませんが、知っておく必要があります。
なお、PHP7でPHP_INT_MINという定数が追加されています。
// 整数の最大値
$max = PHP_INT_MAX;
var_dump($max); // int(9223372036854775807)
// 整数の最小値
$min = PHP_INT_MIN; // (PHP7.0)
var_dump($min); // int(-9223372036854775808)
この値は、プラットフォーム(環境)に依存する点に注意してください。32ビットの環境下では約20億となり、64ビットの環境下では約900京になります。
なお、PHP5におけるWindows環境では、常に32ビットです。
余談ですが、筆者はシューティングゲーマーです。ギガウイング2(開発:匠、販売:カプコン)では、スコアが京点を超えます。
ギガウイング2は1999年にリリースされたゲームです。当時のPHPでスコアを扱ったら、カンスト(カウンターストップ)を起こすこと必至です。ちなみに、ギガウイング2はアーケードでリリースされ、ドリームキャストに移植されています。
筆者は青春時代をゲームセンターで過ごしました。
整数の範囲を超えても、プログラムはエラーになりません。しかし想定外の現象が発生します。この現象のことを、桁あふれ(オーバーフロー)と言います。
$overMax = PHP_INT_MAX + 100;
var_dump($overMax); // float(9.2233720368548E+18)
$overMin = PHP_INT_MIN - 100;
var_dump($overMin); // float(-9.2233720368548E+18)
整数で表現できる限界を超えてしまったため、10の18乗のような浮動小数点数(float)型に変換されました。なお、変換が強引であることは、次の判定を見るとわかります。
$over100 = PHP_INT_MAX + 100;
$over101 = PHP_INT_MAX + 101;
var_dump($over100 === $over101); // bool(true)
桁あふれ(オーバーフロー)は、誤判定を起こしてしまうほどの想定外な現象です。PHPで整数を扱う場合、オーバーフローしないように注意しなければなりません。特に、ユーザーが入力した数値は必ず範囲内に収まっているかどうか、入力時にチェックするようにしましょう。
PHP5.6で、累乗演算子が追加されました。「2の3乗」など、乗数を使った演算子です。
// PHP5.5まではpow()を使う必要がありました
var_dump(pow(2, 3)); // int(8)
// PHP5.6で**演算子が追加されました
var_dump(2 ** 3); // int(8)
// 数値でない値を累乗しようとすると警告が発生します
// Warning: A non-numeric value encountered
var_dump('a' ** 3); // int(0)
他のプログラミング言語では「べき乗演算子」と呼ばれることもあります。なお、「**」がメジャーですが、「^」が使われる言語もあります。
言語リファレンス > 型 > 浮動小数点数
http://php.net/manual/ja/language.types.float.php
浮動小数点数は、小数を含めた数を表現できる型です。「浮動小数点数(float)」「倍精度浮動小数点数(double)」「実数(real)」などと明確に区別されているプログラミング言語もありますが、PHPではすべてfloatになります。
$a = 1.123; // 通常の小数
$b = 1.1e2; // 指数形式(1.1×10の2乗)
$c = -3E-2; // Eは小文字も大文字も可能(-3×10の-2乗)
var_dump($a); // float(1.123)
var_dump($b); // float(110)
var_dump($c); // float(-0.03)
指数形式では多少の数学についての知識が必要になりますが、通常のWebプログラミングで必要になることはあまりないでしょう。
PHPに限らず、多くのコンピューターは小数を苦手としています。浮動小数点数の精度は有限なため、PHPでは正確に表現できない小数が存在します。表現には限界があるのです。
この点についての理解を深めるため、誤判定が発生するサンプルを用意しました。リスト1.10では「1.1 + 2.2 = 3.3」であるはずなのに、結果が偽(false)になります。
$d = 1.1;
$e = 2.2;
$f = $d + $e;
var_dump($f === 3.3); // bool(false)
このような不具合がおきる原因は、PHPが持つ内部的な値の精度の限界にあります。別の例を見てみましょう。
$g = (0.1 + 0.7) * 10;
var_dump($g === 8.0); // bool(false)
精度の限界により誤差が発生しています。そのため、一致しないという結果になります。
誤判定の例で見てきたように、PHPの小数には限界があります。そのため、次の点に注意してください。
・小数を直接比較して、等しいかどうかを調べてはならない。
・小数は表現の限界により、丸めによる誤差が発生する可能性がある。
正確に値を表現できない小数が存在する、ということを必ず覚えておきましょう。小数を安易に扱ってしまうと、思わぬ不具合に遭遇する可能性があります。
なお、より詳しい理由が気になる方は、公式マニュアルを参照してください。
・警告:浮動小数点数の精度