目次

まえがき

本書のコンセプト
本書のターゲット
サンプルコードのダウンロード
免責事項
表記関係について
底本について

第1章 型別に理解する変数の扱い方

1.1 変数の型
1.2 論理型(boolean)
1.3 整数(ingeger)
1.4 浮動小数点数(float, double, 実数)
1.5 文字列(string)
1.6 配列(array)
1.7 (PHP7.1)繰り返し可能(iterable)
1.8 オブジェクト(object)
1.9 リソース (resource)
1.10 NULLと未定義
1.11 (PHP5.4)コールバック(callable)

第2章 変数のスコープと特別な変数・定数

2.1 変数のスコープを限定したい
2.2 変数のスコープは3種類
2.3 ローカルスコープ(関数内スコープ)
2.4 グローバルスコープ
2.5 スーパーグローバル
2.6 (PHP7.0)削除された定義済み変数
2.7 定義済み定数

第3章 型の変換

3.1 型変換を理解すべき理由
3.2 型変換の種類
3.3 緩やかな比較と厳密な比較
3.4 論理型(bool)への変換
3.5 整数型(int)への変換
3.6 浮動小数点数型(float)への変換
3.7 文字列型(string)への変換
3.8 配列(array)への変換
3.9 オブジェクト(objece)への変換
3.10 リソース型への変換

第4章 (PHP7) 型宣言

4.1 型宣言の基本的な使い方
4.2 型宣言が必要である理由
4.3 型宣言の特徴
4.4 クラスインスタンスやNULL値への適用
4.5 型宣言の歴史
4.6 弱い型付けと強い型付け
4.7 戻り値の型宣言
4.8 疑似型の型宣言
4.9 (PHP7.0)型宣言のTypeError
4.10 型を意識したPHPアプリケーション
4.11 入力値をフィルターして型を合せる
4.12 PHP7で堅牢なコードを書く

第5章 (PHP5.3)名前空間

5.1 名前空間のない世界
5.2 住所を付与するための名前空間
5.3 名前空間を付与したクラスの呼び出し方
5.4 名前空間はなぜ使われているのか?
5.5 useによるショートカット
5.6 関数や定数の名前空間

第6章 (PHP5.3)オートロード

6.1 オートロードの基本形
6.2 オートロードの自動化
6.3 require_once()との違い

第7章 外部ライブラリーの活用

7.1 PECLによるモジュールのインストール
7.2 PEARによるモジュールのインストール
7.3 Composer + Packagist
7.4 Composerの構成と登場人物をおさらいする

第8章 (PHP7)エラーと例外

8.1 エラー例外(\Error)
8.2 ユーザー例外(\Exception)
8.3 SPL(Standard PHP Library)例外
8.4 (PHP5.5)try〜catchのfinallyブロック
8.5 例外ハンドラとシャットダウンハンドラ
8.6 エラーハンドラ
8.7 例外の追跡にも役立つバックトレースの生成
8.8 (PHP7.0)assertによる簡易テスト

第9章 アーキテクチャー

9.1 サーバーサイドのアーキテクチャー
9.2 レイヤー追加系アーキテクチャー
9.3 アーキテクチャーはフレームワークで学ぼう
9.4 マイクロサービスアーキテクチャー

第10章 PSRコーディングガイドライン

10.1 PSRの全体像
10.2 PSR-0 オートローディング規約
10.3 PSR-1 基本コーディング規約
10.4 PSR-2 コーディングスタイルガイド
10.5 PSR-3 Logger Interface
10.6 PSR-7 HTTP message interfaces

第11章 正規表現を楽しもう

11.1 PHPにおける正規表現とは?
11.2 PCREとは何か?
11.3 デリミタはスラッシュ(/)だけではない
11.4 preg_quoteによる正規表現のエスケープ
11.5 1行モードと複数行モードと終端判定
11.6 最短マッチと最長マッチ
11.7 正規表現と専用関数の速度の違い
11.8 日本語(UTF-8)を含む正規表現
11.9 マルチバイト文字列の正規表現
11.10 正規表現チェッカー

第12章 テンプレートエンジン

12.1 テンプレートエンジンはなぜ使われるのか?
12.2 テンプレートエンジンを試してみよう
12.3 テンプレートエンジンの実装サンプル
12.4 テンプレートエンジンはどのように動くのか?
12.5 その他のテンプレートエンジン
12.6 どのテンプレートエンジンを使えば良いのか?
12.7 素のPHPタグにおける変更点

第13章 パフォーマンスとデバッグ

13.1 Webシステムにおけるパフォーマンス
13.2 PHPのパフォーマンスを計測するには?
13.3 メモリー使用量の計測
13.4 コピーオンライトによるメモリーの節約
13.5 変数の値渡しと参照渡し
13.6 PHPとデバッグ
13.7 バージョンアップで性能が上がるPHP
13.8 プロファイリングツールの活用

第14章 PHPとバージョンアップ

14.1 PHPのバージョンアップの頻度
14.2 PHPのサポート期限(ライフサイクル)
14.3 下位互換性のない変更点
14.4 PHP 7.x.xで推奨されなくなる機能
14.5 PHP7のメジャーバージョンアップによる高速化
14.6 新機能・演算子・関数などの追加
14.7 PHP7の情報を得るには?

第15章 良質なPHP情報を得るには?

15.1 雑誌
15.2 書籍
15.3 イベント・カンファレンス
15.4 ブログ
15.5 ポッドキャスト

第16章 Hack/HHVMとPHP

16.1 HHVMのPHPサポートは終了へ
16.2 Hackとは?
16.3 HHVMのインストール
16.4 PHPにも他の選択肢があることを知っておこう
16.5 周辺の動向にも注目しよう!

付録A (PHP5.4) ビルトインウェブサーバー

A.1 ビルトインウェブサーバーのメリット
A.2 ビルトインウェブサーバーの基本文法
A.3 「-d」オプションによる設定変更
A.4 ビルトインウェブサーバーで学ぶルーティングエンジン

付録B PHPエンジニアとサーバーサイド

B.1 Apache + mod_php
B.2 Nginx + php-fpm
B.3 Web三層アーキテクチャー
B.4 OSとミドルウェアを学習しよう
B.5 LPI教科書ではじめるサーバーサイド学習

付録C 静的コード解析と周辺ツール

C.1 エディターのプラグインを活用する
C.2 周辺ツールとの組み合わせ
C.3 ドキュメント生成
C.4 静的解析
C.5 デバッグ
C.6 ユニットテスト
C.7 気になったツールを試してみよう

付録D セキュリティー

付録E 主要参考文献

E.1 雑誌・ムック
E.2 書籍

あとがき

新しい機能には、必ず意味がある
謝辞


まえがき

 本書を手にとっていただきまして、ありがとうございます。

本書のコンセプト

 本書は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してご利用ください。

リスト1: サンプルコードの利用例

# コマンドラインの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」で頒布されたものを底本としています。

第1章 型別に理解する変数の扱い方

 変数はプログラミングにおいてもっとも基本であり、もっとも重要です。まずは、PHPにおける変数について型別にみていきましょう。

1.1 変数の型

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構造体について調べてみてください。

zval構造体について

 中級者のレベルを超える内容かもしれませんが、この点は本書でも触れておきます。PHP7ではPHP5系に比べて大幅にパフォーマンスが向上しています。これには、PHPの内部における変数の管理方法が影響しています。

 すぐに理解するのは難しいかもしれません。鍵は、ポインタ参照という構造を理解できるかどうかです。今の時点では、PHP7で内部的なデータ構造が大胆に効率化されているという点は忘れずに覚えておきましょう。次の記事が参考になります。


・PHP7はなぜ速いのか(zval編)

 ─https://hnw.hatenablog.com/entry/20141207

・PHP7の肝 zval構造体を読み解く

 ─https://qiita.com/DQNEO/items/a5d9f5d80dc8b14071f4

1.2 論理型(boolean)

PHPマニュアルより

言語リファレンス > 型 > 論理型 (boolean)
http://php.net/manual/ja/language.types.boolean.php

 論理型はもっとも単純な型で、真偽の値を表します。真(true)または偽(false)のいずれかの値になります。

リスト1.1:

$a = true;
$b = false;
echo gettype($a).PHP_EOL; // boolean

1.2.1 真偽値を返す演算子

 論理型は単純な値ですが、とても重要です。なぜならば、PHPには真偽値を返す演算子がたくさんあるからです。

 ・比較演算子(===, !==, <...)

 ・論理演算子(and, !, ||...)

 ・配列演算子(==, <>, !=...)

 ・型演算子(instanceof)

 「if ($c > $d) {}」のような制御構文ではまず比較演算子が働き、論理型の値が生成されます。そして、その結果がifで判定されます。

リスト1.2: 比較演算子を使うと、真偽値が返却される

$c = 1;
$d = 2;
var_dump($c === $d); // bool(false)
var_dump($c > $d);   // bool(false)

 「ifの判定は、真偽値によって行われる」。この感覚は重要なので、絶対に忘れないようにしてください。PHPに限らず他の多くのプログラミング言語でも、ifの判定は最終的に真偽値によって行われます。

1.3 整数(ingeger)

PHPマニュアルより

言語リファレンス > 型 > 整数
http://php.net/manual/ja/language.types.integer.php

 整数には、大きく分けて「正の整数」「ゼロ」「負の整数」があります。

リスト1.3:

$a = 3;   // 正の整数
$b = 0;   // ゼロ
$c = -10; // 負の整数
echo gettype($a).PHP_EOL; // integer

1.3.1 2進数・8進数・16進数

 2進数・8進数・16進数による表現も可能です。

リスト1.4:

$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進数について、筆者は基本情報技術者試験の勉強で習得しました。ぜひこの機会に知っておくことをオススメします。

1.3.2 整数の最大値と最小値

 PHPでは整数で表現可能な範囲が決められています。とても大きな値ですのでなかなか意識する機会はありませんが、知っておく必要があります。

 なお、PHP7でPHP_INT_MINという定数が追加されています。

リスト1.5: 整数の範囲(最大値と最小値)は定数から取得できる

// 整数の最大値
$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(開発:匠、販売:カプコン)では、スコアが京点を超えます。

 ギガウイング2は1999年にリリースされたゲームです。当時のPHPでスコアを扱ったら、カンスト(カウンターストップ)を起こすこと必至です。ちなみに、ギガウイング2はアーケードでリリースされ、ドリームキャストに移植されています。

 筆者は青春時代をゲームセンターで過ごしました。

1.3.3 整数の範囲を超えるとどうなるのか

 整数の範囲を超えても、プログラムはエラーになりません。しかし想定外の現象が発生します。この現象のことを、桁あふれ(オーバーフロー)と言います。

リスト1.6: 整数の範囲を超えると桁あふれ(オーバーフロー)がおきる

$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)型に変換されました。なお、変換が強引であることは、次の判定を見るとわかります。

リスト1.7: 桁あふれの環境下では正確な判定ができない

$over100 = PHP_INT_MAX + 100;
$over101 = PHP_INT_MAX + 101;
var_dump($over100 === $over101); // bool(true)

 桁あふれ(オーバーフロー)は、誤判定を起こしてしまうほどの想定外な現象です。PHPで整数を扱う場合、オーバーフローしないように注意しなければなりません。特に、ユーザーが入力した数値は必ず範囲内に収まっているかどうか、入力時にチェックするようにしましょう。

1.3.4 (PHP5.6)累乗演算子

 PHP5.6で、累乗演算子が追加されました。「2の3乗」など、乗数を使った演算子です。

リスト1.8:

// 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)

 他のプログラミング言語では「べき乗演算子」と呼ばれることもあります。なお、「**」がメジャーですが、「^」が使われる言語もあります。

1.4 浮動小数点数(float, double, 実数)

PHPマニュアルより

言語リファレンス > 型 > 浮動小数点数
http://php.net/manual/ja/language.types.float.php

 浮動小数点数は、小数を含めた数を表現できる型です。「浮動小数点数(float)」「倍精度浮動小数点数(double)」「実数(real)」などと明確に区別されているプログラミング言語もありますが、PHPではすべてfloatになります。

リスト1.9:

$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プログラミングで必要になることはあまりないでしょう。

1.4.1 PHPは小数が得意ではない

 PHPに限らず、多くのコンピューターは小数を苦手としています。浮動小数点数の精度は有限なため、PHPでは正確に表現できない小数が存在します。表現には限界があるのです。

 この点についての理解を深めるため、誤判定が発生するサンプルを用意しました。リスト1.10では「1.1 + 2.2 = 3.3」であるはずなのに、結果が偽(false)になります。

リスト1.10: 小数の誤判定が発生し「1.1 + 2.2 = 3.3」にならない

$d = 1.1;
$e = 2.2;
$f = $d + $e;
var_dump($f === 3.3); // bool(false)

 このような不具合がおきる原因は、PHPが持つ内部的な値の精度の限界にあります。別の例を見てみましょう。

リスト1.11: 7.9999999999999991118になるため、比較が一致しない

$g = (0.1 + 0.7) * 10;
var_dump($g === 8.0); // bool(false)

 精度の限界により誤差が発生しています。そのため、一致しないという結果になります。

1.4.2 小数を扱う上で気をつけるべきこと

 誤判定の例で見てきたように、PHPの小数には限界があります。そのため、次の点に注意してください。

 ・小数を直接比較して、等しいかどうかを調べてはならない。

 ・小数は表現の限界により、丸めによる誤差が発生する可能性がある。

 正確に値を表現できない小数が存在する、ということを必ず覚えておきましょう。小数を安易に扱ってしまうと、思わぬ不具合に遭遇する可能性があります。

 なお、より詳しい理由が気になる方は、公式マニュアルを参照してください。


 ・警告:浮動小数点数の精度

  ─http://php.net/manual/ja/language.types.float.php

試し読みはここまでです。
この続きは、製品版でお楽しみください。