本格入門シリーズPHP本格入門[下]
~オブジェクト指向設計、セキュリティ、現場で使える実践ノウハウまで

書籍の概要

この本の概要

Webアプリケーションの定番言語であるPHPの基礎から実践までを,上下巻のフルボリュームで集大成。

「この目的を実現するためには,どの文法テクニックが適合しやすいだろう?」
「このプログラムをより読みやすくするために,どんなアプローチができるだろう?」

といったことを思考しつつ,「とりあえずは動く」だけで終わらない,現場に求められる品質を形にするための知識とテクニックを解説します。

こんな方におすすめ

  • プログラミング入門,PHPの超入門レベルの知識はあるが,実践レベルの知識がないプログラマ

著者の一言

PHPは,動的なWebページ(Webアプリケーション)を実現するために使われるプログラム言語です。自由度の高さと習得のしやすさに定評があり,今でも高い人気を維持し続けています。そして,自由度の高さが,ときとして裏目に出ることもあります。

著者は,自身の20年来のプログラマーとしての経歴の中で,大小含めて50を超えるPHPプロジェクトの開発に携わってきました。トラブルプロジェクトの調査役や火消し役としてあとから参加したプロジェクトもありますが,その中のいくつかは,ゼロからの作り直しを余儀なくされたこともありました。その原因は以下のようなものでした。

  • 潜在的に品質が悪く,多くのバグフィックスを入れても安定稼働にいたらなかった
  • 離脱したチームメンバーが書いたプログラムが複雑怪奇で,だれも手を入れることができなくなった

なぜそのようなことになったのかをソースコードから突き詰めていくと,PHPの持つ自由度の高さへの,甘えのようなものが本質にあったのではないかと思います。

PHPは,凝ったプログラム設計をせず,実直にプログラミングしても,とりあえずは動いてくれます。そのような「とりあえずは動く」状態に持っていくだけであれば,それほど多くの習得時間を必要としません。一方で,そのようなPHPの寛容さが,チーム開発になると裏目に出てきます。チームメンバーがひとりよがりな流儀でプログラミングをした結果,それぞれの機能を書いた本人にしか読解できない,複雑怪奇なアプリケーションに仕上がりがちなのです。

このようなPHP開発にありがちな状況をふまえ,著者は

  • よいPHPアプリケーションの「あるべき姿」
  • あるべき姿に近づくための,アプリケーション設計ポリシー

を共通理解としてもつことが,今のPHP習得者にはとりわけ重要であると考えました。そして,本書ではこの考えのもと,以下のような内容も積極的に取り入れることにしました。

  • 目的の理解……その文法要素が使われやすい用途
  • 読みやすさ……コーディング規約/読みやすいプログラミング作法
  • 変更へのしなやかさ……独立性の高いオブジェクト指向設計
  • 品質の見える化……プロファイリング/デバッグ手法
  • 安心感を維持する仕組み作り……自動テスト/リファクタリング手法

本書は,理路整然と文法テクニックが並べられただけの入門書ではありません。

「この目的を実現するためには,どの文法テクニックが適合しやすいだろう?」
「このプログラムをより読みやすくするために,どんなアプローチができるだろう?」

といったことを思考しながら進めていきます。

これらのことは,手練のプロでも日常的に思い悩むことです。なぜなら,1つの目的を実現するためのアプローチが3~4パターンあることは普通で,明確な答えがないことも多いからです。だからこそ,PHP習得の早い段階で,こういった思考のトレーニングを積んでおくことが肝要なのです。そして,その思考の時間は楽しいものです。

本書をとおして,あたかもPHP開発プロジェクトの現場にいるような気分で,思考するプロセスの楽しさを味わっていただければ幸いです。

目次

8章 よりよいオブジェクト指向デザインのためのベストプラクティス

8-1 よりよいオブジェクト指向設計を通して目指すべきもの

  • 8-1-1 後から機能を変更するのは,新規でプログラミングするより数倍の労力がかかる
  • 8-1-2 オブジェクト指向を活かし,直感的で無駄のないアプリケーションを作る

8-2 オブジェクト指向がもたらす独立性 ― カプセル化と多態性

  • 8-2-1 独立性とはクラスの「自立」である
  • 8-2-2 クラスの中身を「保護」する ― カプセル化と隠ぺい
  • 8-2-3 うまくカプセル化されたアプリケーションは,小説の「あらすじ」のように読める
  • 8-2-4 具象を意識しないための性質 ― 多態性

8-3 クラスの独立性を高める ― 凝集度と結合度

  • 8-3-1 凝集度は高く
  • 8-3-2 結合度は低く
  • 8-3-3 どこまで細かくクラス分けすべきか? ― 将来を見すえて,適切なサイズ感を考える

8-4 クラスの関係性を表すキーワード ― is-a関係とhas-a関係

  • 8-4-1 is-a ― ●●は▲▲である
  • 8-4-2 has-a ― ●●は▲▲をもっている
  • 8-4-3 関連 ― ゆるやかな関係をもっている
  • 8-4-4 委譲 - ほかの人に任せる
  • 8-4-5 is-aとhas-aは,見誤りやすい
  • 8-4-6 カプセル化を守る ― なるべくならis-aよりhas-a
  • 8-4-7 多重継承はできなくても,コンポジションならできる

8-5 クラス同士の依存を解消する ― 依存性の注入,Factoryクラス

  • 8-5-1 依存は具象クラスのインスタンス化から生まれる
  • 8-5-2 依存対象のクラスを外部から挿し込む ― 依存性の注入
  • 8-5-3 たくさんのクラスに対する依存をまとめてなくす ― Factoryクラス

8-6 好ましくない設計を知る ~アンチパターン

  • 8-6-1 神クラス ― 1人で何でもやるクラス
  • 8-6-2 自由すぎて不安になる ― なんでもpublicなクラス
  • 8-6-3 共通化のために,関係のないメソッドまで持たされたスーパークラス
  • 8-6-4 求めていない処理までやってしまう ― 世話好きなメソッド
  • 8-6-5 引数が多すぎるメソッド
  • 8-6-6 状態を持てないクラス ― ユーティリティクラス

9章 能率を高める,一歩進んだ文法テクニック

9-1 変数名やメソッド名を流動的に切り替える ― 動的アクセス

  • 9-1-1 プロパティに動的アクセスする
  • 9-1-2 メソッドを動的にコールする
  • 9-1-3 クラスに動的にアクセスする

9-2 配列のように扱えるクラスを作る

  • 9-2-1 foreachループ可能なクラスを作る ― IteratorAggregateインターフェース
  • 9-2-2 配列の形式でアクセスできるクラスを作る ― ArrayAccess

9-3 複雑な規則性を持つ配列をシンプルに扱う ― ジェネレーター

  • 9-3-1 続けざまに値を返すシンプルなジェネレーター ― yield命令
  • 9-3-2 連想配列のように扱えるジェネレーター
  • 9-3-3 ジェネレーターで要素数の多い配列生成を省メモリ化する ― Excel列名リストの生成
  • 9-3-4 生成処理をサブジェネレーターに分担させる ― yield from
  • 9-3-5 ジェネレーターで最終的な戻り値を返す
  • 9-3-6 ジェネレーターに配列のフィルタリングを委ね,プログラムの見通しをよくする

9-4 1つのインスタンスに対する複数のメソッド呼び出しをスマートに書く ― メソッドチェーン

  • 9-4-1 3ステップで,メソッドチェーンに対応したクラスを作る
  • 9-4-2 メソッドチェーンに対応した四則演算クラス
  • 9-4-3 メソッドチェーン対応クラスのアイディア例

9-5 クラスをグルーピングするためのインターフェース ― マーカーインターフェース

  • 9-5-1 マーカーインターフェースを使わない,冗長な例外処理
  • 9-5-2 マーカーインターフェースを使って,例外をグループ分けする

10章 外部ライブラリを開発に役立てる ― Composer

10-1 モダンなPHP開発における外部ライブラリの管理手法

  • 10-1-1 依存関係を自動で解決してくれるパッケージ管理ツール ― Composer
  • 10-1-2 多くのPHPライブラリがつどうリポジトリ ― Packagist
  • 10-1-3 外部ライブラリを使ってどんなことができるか

10-2 Composerでパッケージを管理する

  • 10-2-1 Composerをインストールする
  • 10-2-2 composerコマンドでパッケージをインストールする
  • 10-2-3 適切なバージョンを指定する ― バージョン記法とセマンティックバージョニング
  • 10-2-4 すべての環境でまったく同じバージョンが使えるようにする ― composer.lock,composer installコマンド
  • 10-2-5 開発環境でのみ使いたいパッケージを管理する ― --devオプション
  • 10-2-6 最新のバージョンに更新する ― composer update
  • 10-2-7 require_once命令なしでクラスを自動読み込みする ― オートロード
  • 10-2-8 自作のクラスをオートロードする ― composer dump-autoloadコマンド

10-3 PhpSpreadsheetでExcel出力する

  • 10-3-1 PhpSpreadsheetをインストールする
  • 10-3-2 テンプレートを元にExcelファイルを出力する
  • 10-3-3 テンプレートを使わずにExcelファイルを出力する

10-4 GoutteでWebスクレイピングする

  • 10-4-1 外部のWebサイトをパースして情報を収集する ― Webスクレイピング
  • 10-4-2 HTML文書をプログラムで階層的に扱う ― DOMの概念
  • 10-4-3 Goutteをインストールする
  • 10-4-4 Goutteを使う準備 ― GoutteからWebページにアクセスする
  • 10-4-5 filterメソッドでノードを絞り込む ― CSSセレクタによるノード指定
  • 10-4-6 複数のノードを繰り返し処理する ― eachメソッド

10-5 なるべく失敗しない,外部ライブラリの選び方

  • 10-5-1 選定のための基準 ― 最低限,対応品質は調べておきたい
  • 10-5-2 「ライブラリ開発チームの対応品質」にもとづく4つの選定基準
  • 10-5-3 パフォーマンスと限界を知っておく ― 性能テスト
  • 10-5-4 ひととおりの機能を網羅した実験プログラムを作る

11章 WebAPIを使った外部システムとの連携

11-1 WebAPIを使った外部システム連携でできること

  • 11-1-1 外部Webサービスのデータを提供してもらう
  • 11-1-2 特定のユーザによる投稿/閲覧の操作をおこなう
  • 11-1-3 難しい計算処理を外部システムに委ねる
  • 11-1-4 サーバーの一部の機能をまるごと,外部システムに任せる

11-2 WebAPIによる連携の仕組み

  • 11-2-1 標準的なWebAPIの設計方式 ― RESTful API
  • 11-2-2 利用ユーザの認証は1リクエストごとにおこなう

11-3 WebAPIとデータを送受信する(1) ― 電文フォーマット「JSON」

  • 11-3-1 JSONデータが取り扱うデータ型を理解する
  • 11-3-2 Unicode文字は「\u」で表す
  • 11-3-3 一部の記号はエスケープで無効化する必要がある
  • 11-3-4 改行/タブは特殊文字で表す
  • 11-3-5 値をJSON形式にエンコードする ― json_encode関数
  • 11-3-6 JSON文字列をデコードし,PHPの値に変換する ― json_decode関数
  • 11-3-7 エンコード/デコード失敗時のエラーを検出する ― json_last_error関数

11-4 WebAPIとデータを送受信する(2) ― 電文フォーマット「XML」

  • 11-4-1 XMLを生成する ― DomDocumentクラス
  • 11-4-2 XMLをパースする ― DomDocument::loadXMLメソッド

11-5 RESTful APIサーバー/クライアントをプログラム実装する

  • 11-5-1 WebAPIサーバーを実装する
  • 11-5-2 WebAPIクライアントを実装する ― cURL関数
  • 11-5-3 ファイルのアップロードはPUTメソッドを使う

11-6 外部サービスのAPIを使う ― Google自然言語API

  • 11-6-1 APIを使う準備をする ― Google Cloud Platformの登録~APIキーの取得
  • 11-6-2 Google感情分析APIを使う
  • 11-6-3 Google感情分析APIのリクエスト/レスポンスフォーマット
  • 11-6-4 Google感情分析APIにHTTPリクエストを送信する

12章 Webアプリケーションのセキュリティ

12-1 システム全体の基本的なセキュリティ

  • 12-1-1 多重防御が基本
  • 12-1-2 なるべく機械的に判断する
  • 12-1-3 内部の人間にもアクセス権を設ける
  • 12-1-4 あらゆる外部からのデータは信用しない
  • 12-1-5 事後対策も考えておく

12-2 Webアプリケーションのセキュリティ

  • 12-2-1 パスワードは強固なものにし,ユーザにもそれを求める
  • 12-2-2 ログイン機能を強固にする
  • 12-2-3 ログイン認証失敗時のエラーメッセージにも気を配る
  • 12-2-4 IPアドレスが特定できる画面はIP制限をかける
  • 12-2-5 攻撃の手がかりになる情報を見せない ― コメント,スクリプト,エラーメッセージ
  • 12-2-6 見せてはいけないファイルを公開ディレクトリに置かない
  • 12-2-7 連番をパラメータで使う時は気をつける
  • 12-2-8 アップロードファイルのチェックはサーバーサイドでもおこなう
  • 12-2-9 セキュリティリスクを少なくするためのphp.iniの設定

12-3 SQLインジェクション攻撃とその対策

  • 12-3-1 SQLインジェクションとは ― SQLの意味を書き換え,不正なデータベース操作をおこなう
  • 12-3-2 SQLインジェクション攻撃の試行
  • 12-3-3 SQLインジェクション攻撃への対策を施す
  • 12-3-4 SQLインジェクションでログイン情報を盗み出す

12-4 XSS攻撃とその対策

  • 12-4-1 XSSとは ― 不正なスクリプトを入力値に埋め込んでWebブラウザに実行させる
  • 12-4-2 XSS攻撃を試行する
  • 12-4-3 XSS攻撃への対策を施す(1) ― もっとも基本的な対策
  • 12-4-4 XSS攻撃への対策を施す(2) ― イレギュラーな入力パターンへの対応

12-5 CSRF攻撃とその対策

  • 12-5-1 CSRFとは ― ユーザが意図しないHTTP送信を強制する
  • 12-5-2 CSRF攻撃を試行する
  • 12-5-3 CSRF攻撃への対策を施す

12-6 その他のさまざまな攻撃パターン

  • 12-6-1 メールヘッダインジェクション ― 不正なメールヘッダを注入する
  • 12-6-2 オープンリダイレクト ― どこへもリダイレクトできてしまう脆弱性
  • 12-6-3 ディレクトリトラバーサル ― 不正なパスを注入する
  • 12-6-4 OSコマンドインジェクション ― 不正なコマンドを注入する
  • 12-6-5 ペネトレーションテストのためのツール

13章 強く,しなやかなPHPアプリケーション

13-1 品質を構成する要素

  • 13-1-1 品質の見える化 ― ISO/IEC 9126の品質特性モデル
  • 13-1-2 PHPプログラマーができる,ソフトウェア品質への働きかけとは

13-2 前提条件を表明し,ソースコードに起因するバグを減らす ― アサーション

  • 13-2-1 アサーションは開発時にのみ使い,本番運用では使わない ― zend.assertionsオプション
  • 13-2-2 アサーションは外部データ値の異常ではなく,ソースコードの異常を伝えるために使う
  • 13-2-3 アサーション,バリデーション,範囲外チェック例外の違い
  • 13-2-4 アサーションを使って処理結果をセルフチェックする

13-3 PHPUnitによる自動テスト ― 強度を高め,変更作業を安全におこなう

  • 13-3-1 自動テストの対象範囲 ― おもに関数やメソッドの戻り値をテストする
  • 13-3-2 PHPUnitのインストール
  • 13-3-3 PHPUnitによる自動テストプログラムの基本的な書き方
  • 13-3-4 PHPUnitによる自動テストプログラムの実例 ― ページャークラスのテスト
  • 13-3-5 関連する自動テストをまとめる ― テストスイート
  • 13-3-6 実行したいテストスイートを定義するもう1つの方法 ― phpunit.xml
  • 13-3-7 自動テストがしやすいプログラム構成 ― データベースやHTTPへの依存を避ける

13-4 コーディング規約の自動チェック ― 規約チェックツールPHP_CodeSniffer

  • 13-4-1 PHP_CodeSnifferで規約チェックする
  • 13-4-2 phpcbfコマンドでコードスタイルを自動整形する

13-5 バグを生み出しそうなコードをあぶり出す ― phpmd

  • 13-5-1 phpmdでバグ発見の手がかりを得る

13-6 もしものときのために履歴を残す ― ロギングツールMonolog

  • 13-6-1 Monologの全体像 ― ロガー,ハンドラー,プロセッサー,フォーマッター
  • 13-6-2 出力レベルをコントロールする ― ログレベル
  • 13-6-3 Monologをインストールする
  • 13-6-4 Monologの基本的な使い方
  • 13-6-5 ログメッセージを蓄積するハンドラー ― BufferHandler,FingersCrossedHandler
  • 13-6-6 ログメッセージにプレースホルダを埋め込む ― PsrLogMessageProcessor
  • 13-6-7 MariaDBのテーブルにログを記録する ― MySQLHandler

13-7 プログラムの使い方マニュアルを自動生成する ― phpDocumentorによるドキュメンテーション

  • 13-7-1 ドキュメンテーションのためのコメント「PHPDocコメント」
  • 13-7-2 phpDocumentorの使い方

13-8 プロファイリングによるボトルネック調査 ― blackfire

  • 13-8-1 blackfireをセットアップする
  • 13-8-2 重い商品検索アプリケーションを実行する
  • 13-8-3 blackfireでプロファイリングする
  • 13-8-4 blackfireのプロファイリング結果を読み解く
  • 13-8-5 プロファイリング結果に基づいてプログラムを改良する

13-9 Webアプリケーションフレームワークを理解する

  • 13-9-1 フレームワークとは
  • 13-9-2 ひしめき合うPHPフレームワークの世界
  • 13-9-3 フレームワークが提供する最低限の機能 ― ルーティング
  • 13-9-4 MVCモデルを理解する
  • 13-9-5 フレームワークが提供するその他の機能
  • 13-9-6 フレームワークのサイズと制約 ― マイクロフレームワークとフルスタックフレームワーク
  • 13-9-7 有名どころのフレームワークを押さえる

13-10 自動生成でヒューマンエラーを防止する ― 開発効率アップのためのコンソールプログラム

  • 13-10-1 繰り返し作業は,なるべく自動化する
  • 13-10-2 オリジナルのプログラムにScaffoldさせる

13-11 IDEでプログラミングの生産効率を上げる

  • 13-11-1 IDEが備える,強力な開発サポート機能
  • 13-11-2 PHPプロジェクトで使われる,主要なIDE
  • 13-11-3 PhpStormのセットアップ
  • 13-11-4 PhpStormプロジェクトを作成する
  • 13-11-5 PhpStormによるプログラミング体験の内容を確認する
  • 13-11-6 PhpStormでクラス図を自動生成する
  • 13-11-7 PhpStorm上でプログラミングしてみる

13-12 アプリケーションの内部構造を安全に変える ― リファクタリング

  • 13-12-1 命名を変更する
  • 13-12-2 メソッド,プロパティの階層を変える ― プルアップとプッシュダウン

13-13 バグを調査する ― PhpStorm+Xdebugによるデバッグ手法

  • 13-13-1 IDEデバッグ機能の具体的な内容
  • 13-13-2 不具合の現象を確認する
  • 13-13-3 PhpStorm+Xdebugによるデバッグ環境のセットアップ
  • 13-13-4 デバッグ手順(1) ― バグがある箇所の当たりをつけ,プログラムを中断する場所を決める
  • 13-13-5 デバッグ手順(2) ― ブレークポイントを設定する
  • 13-13-6 デバッグ手順(3) ― Webブラウザで実行して変数値を見る
  • 13-13-7 デバッグ手順(4) ― ステップ実行しながら,変数値の遷移を確認する
  • 13-13-8 デバッグ手順(5) ― 原因をさらに細かく追求する
  • 13-13-9 デバッグ手順(6) ― プログラムを修正する
  • 13-13-10 デバッグ手順(7) ― 修正後の動作確認をする

13-14 どうしてもデバッグできないときは ― 良質な情報が得やすい質問の手順

  • 13-14-1 質問にあたっての心構え
  • 13-14-2 情報が散らばっていると,よい回答を得にくい
  • 13-14-3 最小セットのプログラムで,問題の本質を見きわめる
  • 13-14-4 聞きたいことを構造的に組み立てる
  • 13-14-5 結局,どこにバグがあったのか?
  • 13-14-6 そのほかに質問をするうえで気をつけること

著者プロフィール

大家正登(おおいえまさと)

1979年,佐賀県生まれ。20歳よりフリープログラマーの下でプログラミングやサーバー管理の実務を,21歳より大学の研究室でPerl言語を使った自然言語処理を学ぶ。東京外国語大学外国語学部欧米第二課程スペイン語専攻卒業後,2003年より,株式会社ワイ・ディ・シー中部支社にてJava,PHP,Cなどによる生産管理システムの開発に従事する。2006年より,フリープログラマーとして独立。2008年,デジタルハリウッド横浜校「PHP講座」講師。2009年より現在まで,東京IT株式会社代表取締役。
おもな執筆歴として,『PHP逆引き大全516の極意』『たったコレだけでPHPプログラミングが理解できる本』『たったコレだけでJavaプログラミングが理解できる本』(以上,秀和システム),「プログラミング未経験から始めるPHP入門」(翔泳社CodeZine・全15回)がある。現在の夢は,幼児・小学生~大学生まで幅広く,プログラミングの楽しさを体験してもらう場を世に広めること。