PHPの基本知識をゼロから学ぶハンズオン学習(中編)

本PHPのページは、3部作となります。焦らず進めていきましょう。

  1. クラス
    1. 1. クラス
      1. 1-1. クラスの定義
      2. 1-2. クラス名の命名規則
      3. 1-3. クラスの管理
    2. 2. メンバ
      1. 2-1. プロパティ
      2. 2-2. メソッド
    3. 3. インスタンス化
      1. 3-1. インスタンス化
      2. 3-2. プロパティとメソッドの呼び出し
      3. 3-3. null安全演算子
      4. 3-4. オブジェクトの代入
      5. 3-5. オブジェクトの比較
        1. 3-5-1. ==(等価演算子)
        2. 3-5-2. ===(同一性演算子)
    4. 4. コンストラクタとデストラクタ
      1. 4-1. コンストラクタ
      2. 4-2. デストラクタ
    5. 5. 静的メソッドと静的プロパティ
      1. 5-1. 静的メソッド
        1. 5-1-1. 静的メソッドの定義
        2. 5-1-2. 静的メソッドの呼び出し
      2. 5-2. 静的プロパティ
      3. 5-2-1. 静的プロパティの定義
        1. 5-2-2. 静的プロパティの呼び出し
    6. 6. アクセス修飾子
      1. 6-1. public(公開)
      2. 6-2. protected(保護)
      3. 6-3. private(非公開)
    7. 7. 抽象クラス・抽象メソッド
      1. 7-1. 抽象クラス
      2. 7-2. 抽象メソッド
    8. 8. インターフェース
      1. 8-1. インターフェースの定義
      2. 8-2. インターフェースの実現
    9. 9. 無名クラス
    10. 10. instanceof 演算子
    11. 11. トレイト
      1. 11-1. トレイトの定義
      2. 11-2. トレイトの利用
      3. 11-3. 名前競合
    12. 12. 名前空間
      1. 12-1. 名前空間の定義
        1. 12-1-1. 名前空間名の記法
          1. 12-1-1-1. 非修飾名
          2. 12-1-1-2. 修飾名
          3. 12-1-1-3. 完全修飾名
        2. 12-1-2. 名前空間の定義位置
      2. 12-2. インポート
        1. 12-2-1. 名前空間の定義位置
          1. 12-2-1-1. グローバルスコープでの呼び出し
          2. 12-2-1-2. namespace ブロック内での呼び出し
        2. 12-2-2. インポートの有効範囲
      3. 12-3. 名前競合時に別名を設定
    13. 13. クラスの自動ローディング
      1. 13-1. オートローダーの定義
      2. 13-2. オートローダーの呼び出し
  2. オブジェクト指向
    1. 1. オブジェクト指向
      1. 1-1. クラス(設計図)
      2. 1-2. オブジェクト(実体)
      3. 1-3. カプセル化(まとめる)
      4. 1-4. 継承(引き継ぐ)
      5. 1-5. 多態性(ポリモーフィズム)
    2. 2. カプセル化
      1. 2-1. カプセル化とは
      2. 2-2. アクセサーメソッド
    3. 3. 継承
      1. 3-1. 継承を行う
      2. 3-2. スーパークラスのメソッドを呼び出す
      3. 3-3. オーバーライド
        1. 3-3-1. オーバーライドの定義
        2. 3-3-2. オーバーライドを禁止する
      4. 3-4. 多重継承
    4. 4. ポリモーフィズム
  3. 例外処理
    1. 1. 例外処理とは
    2. 2. 例外クラスの型
      1. 2-1. Exception
        1. 2-1-1. ErrorException
        2. 2-1-2. RuntimeException
        3. 2-1-3. LogicException
        4. 2-1-4. 独自の例外
      2. 2-2. Error
    3. 3. エラーハンドリング
      1. 3-1. 例外処理
        1. 3-1-1. try
        2. 3-1-2. catch
        3. 3-1-3. finally
      2. 3-2. エラー処理関数
        1. 3-2-1. ErrorException に変換
        2. 3-2-2. カスタムエラーハンドラを元に戻す
      3. 3-3. Exceptionで捕捉しない
    4. 4. 例外をスローする
      1. 4-1. throw文
      2. 4-2. throw 式
    5. 5. 条件が真であることをチェックする
    6. 6. スタックトレース情報
      1. 6-1. スタックトレースの内容
      2. 6-2. 取得方法
        1. 6-2-1. 文字列形式
        2. 6-2-2. 配列形式
  4. デフォルトで用意されているPHPの機能
    1. 1. 組み込み関数
      1. 1-1. 文字列関数
        1. 1-1-1. 文字列の長さを取得する
        2. 1-1-2. 文字列のサイズを取得する
        3. 1-1-3. 半角全角を区別してサイズを取得
        4. 1-1-4. 文字列の大文字・小文字変換
        5. 1-1-5. 文字列の一部分を取得
          1. 1-1-5-1. mb_substr関数
          2. 1-1-5-2. mb_strstr関数
        6. 1-1-6. 文字列の一部分を置換する
        7. 1-1-7. 文字列を特定の区切り文字で分割
        8. 1-1-8. 特定の文字位置を検索
          1. 1-1-8-1. 最初に現れる位置を検索する
          2. 1-1-8-2. 最後に現れる位置を検索する
        9. 1-1-9. 特定の文字列が含まれているか判定
          1. 1-1-9-1. 含まれているか
          2. 1-1-9-2. 文字列が指定した部分文字列で始まっているか
          3. 1-1-9-3. 文字列が指定した部分文字列で終わっているか
        10. 1-1-10. 指定した文字を文字列から除去
          1. 1-1-10-1. 前後の指定した文字を文字列から除去
          2. 1-1-10-2. 前方の指定した文字を文字列から除去
          3. 1-1-10-3. 後方の指定した文字を文字列から除去
        11. 1-1-11. 文字列を整形
        12. 1-1-12. 文字列を変換
        13. 1-1-13. 文字エンコーディングを変換
        14. 1-1-14. 電子メールを送信
      2. 1-2. 配列関数
        1. 1-2-1. 配列の要素数を取得
        2. 1-2-2. 要素の登場回数をカウント
        3. 1-2-3. 複数の配列を結合
        4. 1-2-4. 配列の各要素を結合
        5. 1-2-5. 配列の末尾に要素を追加
        6. 1-2-6. 配列の末尾の要素を取り出して削除
        7. 1-2-7. 配列の先頭の要素を取り出して削除
        8. 1-2-8. 配列の先頭に1つ以上の要素を追加
        9. 1-2-9. 配列の指定範囲の要素を削除・置換・追加
        10. 1-2-10. 配列の一部を切り出して新しい配列を返す
        11. 1-2-11. 配列の内容を検索
        12. 1-2-12. 配列に特定の要素が存在するか確認
        13. 1-2-13. 配列の要素を並べ替える
        14. 1-2-14. ユーザー定義の比較関数を使って配列を並び替える
        15. 1-2-15. 配列の内容を順に処理する
        16. 1-2-16. 配列内の要素を加工する
        17. 1-2-17. 配列の内容を特定の条件で絞り込む
        18. 1-2-18. 配列内の要素を順に処理して1つにまとめる
      3. 1-3. 正規表現関数
        1. 1-3-1. 正規表現で文字列を検索する
        2. 1-3-2. 全てのマッチ文字列を取得する
        3. 1-3-3. 正規表現で文字列を置換する
        4. 1-3-4. 正規表現で置換したものをコールバック関数で処理する
        5. 1-3-5. 正規表現で文字列を分割する
      4. 1-4. ファイルシステム関数
        1. 1-4-1. ファイルを開く
          1. 1-4-1-1. fopen() 関数
          2. 1-4-2. ファイルを閉じる
        2. 1-4-3. データの読み込み
          1. 1-4-3-1. 指定したバイト数だけデータを読み込む
          2. 1-4-3-2. 1行分のデータを読み込み
          3. 1-4-3-3. 指定されたファイルをまとめて読み込み
          4. 1-4-3-4. 定型フォーマットテキストの読み込み
          5. 1-4-3-5. file_get_contents() 関数
        3. 1-4-4. ファイルへの書き込み
          1. 1-4-4-1. 開いたファイルにデータを書き込む
          2. 1-4-4-2. file_put_contents関数
        4. 1-4-5. ファイルをロックする
      5. 1-5. 数学関数

クラス

1. クラス
2. メンバ
3. インスタンス化
4. コンストラクタとデストラクタ
5. 静的メソッドと静的プロパティ
6. アクセス修飾子
7. 抽象クラス・抽象メソッド
8. インターフェース
9. 無名クラス
10. instanceof 演算子
11. トレイト
12. 名前空間
13. クラスの自動ローディング

1. クラス

1-1. クラスの定義

クラスとは、データを操作するための様々な処理(関数)やデータ(変数)をひとまとめにして管理できるようにしたものです。
クラスは設計図であり、その設計図によりオブジェクトを複数作成することが可能です。
クラスを定義するには、 class キーワードを使用します。

class クラス名 {

}

例文

class Car {

}

1-2. クラス名の命名規則

クラス名は、全ての単語の頭文字を大文字にするアッパーキャメルケース記法を用いるのが一般的です。
また、慣例的に目的に応じてサフィックスを付けます。

サフィックス概要
〜Exception例外クラス
〜Errorエラークラス
〜Testテストクラス
〜Abstract抽象クラス

1-3. クラスの管理

慣例として、1つのクラスは1つのファイルで管理して、そのファイルの命名も「クラス名.php」といったファイル名で管理します。

  • クラス単位でファイルが分離している方が余計なクラスまで読み込む必要がない
  • ファイル名でクラスが識別できる
  • オートローダーを利用する場合に便利である

2. メンバ

メンバとは、クラスで保持している データ や 処理 をまとめたものです。
データをプロパティ(メンバ変数)、処理をメソッド(メンバ関数)といいます。

2-1. プロパティ

プロパティとは、クラスの中で定義される「変数」のことで、 オブジェクトが持つデータや状態を表すもの です。

例文

class Car {
    // プロパティ(情報)
    public $color;  // 色の情報
    public $brand;  // 車種の情報
    public $speed;  // スピードの情報
}

プロパティには「見える範囲」を決められ、それをアクセス修飾子によって決定されます。
アクセス修飾子は、「5. アクセス修飾子」で説明します。

2-2. メソッド

メソッドとは、クラスの中で定義する 関数(処理・動作) のことで、オブジェクトが「何ができるのか」を表します。

例文

class Car {
    public $color;
    public $brand;

    // メソッド(動作)
    public function drive() {
        echo "車が走っています";
    }

    public function stop() {
        echo "車が止まりました";
    }
}

3. インスタンス化

3-1. インスタンス化

インスタンス化とは、クラス(設計図)から実体(オブジェクト)を作ること です。
クラスを利用するには、new を使用してインスタンス化を行います。

オブジェクト変数名 = new オブジェクトを作成するクラス名(引数)

3-2. プロパティとメソッドの呼び出し

プロパティ や メソッド 「インスタンス(オブジェクト)」を通して呼ぶ必要がある ので、
-> 演算子 を使います。
インスタンスメソッド

オブジェクト変数名 -> メソッド

インスタンス変数

オブジェクト変数名 -> プロパティ

例文
車のクラス

class Car {
    public $color;
    public $brand;

    public function drive() {
        echo "{$this->brand}の{$this->color}の車が走っています";
    }
}

コントローラークラス

$myCar = new Car();   // Carクラスからオブジェクトを作成
$myCar->color = "赤"; // プロパティを設定
$myCar->brand = "トラック";

$myCar->drive();      // トラックの赤の車が走っています

また、同じクラスからいくつもオブジェクトを作れます。

$car1 = new Car();
$car1->color = "青";
$car1->brand = "軽自動車";

$car2 = new Car();
$car2->color = "黒";
$car2->brand = "普通車";

$car1->drive(); // 軽自動車の青の車が走っています
$car2->drive(); // 普通車の黒の車が走っています

3-3. null安全演算子

オブジェクトがnullでない場合のときだけ、そのメンバにアクセスしたいときは、?-> 演算子を使用します。
もし途中で null が出てきてもエラーを出さずに null を返します。

例文

class User {
    public function getProfile() {
        return null; // プロファイルが存在しない場合
    }
}

$user = new User();

// 従来の書き方
$profile = null;
if ($user !== null) {
    $profile = $user->getProfile();
}

// null安全演算子(PHP8.0〜)
$profile = $user?->getProfile();

var_dump($profile); // null
  • $user?->getProfile()$usernull なら即座に null を返す。
  • $user がオブジェクトなら getProfile() を実行する。

3-4. オブジェクトの代入

オブジェクト変数は参照渡しが基本となります。(変数の場合は、値渡し)

概要
変数値渡し(コピー)
渡された先で値を変更しても、元の変数には影響しない。
オブジェクト変数参照渡し
渡された先で変更すると、元の変数も変わる。

そのため、オブジェクトを値渡し(コピー)したい場合は、clone 命令を利用します。

clone オブジェクト変数

例文

class User {
    public $name;
}

$user1 = new User();
$user1->name = "Taro";

$user2 = clone $user1;

$user2->name = "Jiro";

echo $user1->name; // Taro
echo $user2->name; // Jiro

3-5. オブジェクトの比較

オブジェクト同士を比較する場合、PHP では ==(等価演算子)」と「===(同一性演算子)」 で挙動が異なります。
同じと判断されれば、true を返し、別と判断されれば false となります。

3-5-1. ==(等価演算子)

等価演算子では、以下の条件のときに true が返されます。

  • プロパティの値が同じなら等しい と判定される
  • クラスの型が同じ であることも条件

例文

class User {
    public $name;
}

$a = new User();
$a->name = "Taro";

$b = new User();
$b->name = "Taro";

var_dump($a == $b);  // true(プロパティが同じだから)
var_dump($a === $b); // false(別インスタンスだから)
3-5-2. ===(同一性演算子)

同一性演算子では、以下の条件のときに true が返されます。

  • 同じインスタンス(同じ参照先)かどうか を判定する
  • つまり「完全に同じオブジェクト」でないと true にならない

例文

$c = $a; // 同じオブジェクトを参照

var_dump($a === $c); // true(同じインスタンス)
var_dump($a === $b); // false(別インスタンス)

まとめ

比較方法判定基準
==クラスが同じ & プロパティの値が同じなら true
===同じインスタンス(同じ参照) なら true

4. コンストラクタとデストラクタ

インスタンス化を行うとオブジェクトを生成することができます。このオブジェクトを生成するタイミングや破棄するタイミングで自動的に呼び出される特別なメソッドがあります。

4-1. コンストラクタ

オブジェクトが生成されるときに自動で呼び出される特別なメソッド のことです。
PHP では以下のように定義します。

__construct(引数)
  • __construct はクラスごとに 1 つだけ定義できる
  • 引数を受け取って初期化処理ができる
  • オブジェクトを作るときに必ず実行される

例文
コンストラクタを使用しない場合

class Car {
    public $color;
    public $brand;

    public function drive() {
        echo "{$this->color}の{$this->brand}が走っています";
    }
}

$car = new Car();
$car->color = "赤色";
$car->brand = "トラック";
$car->drive();

プロパティを毎回セットする必要があります。

コンストラクタを使う場合

class Car {
    public $color;
    public $brand;

    // コンストラクタ(newされたときに自動で呼ばれる)
    public function __construct($color, $brand) {
        $this->color = $color;
        $this->brand = $brand;
    }

    public function drive() {
        echo "{$this->color}の{$this->brand}が走っています";
    }
}

$car = new Car("赤色", "トラック"); // ← 作ると同時に初期化できる
$car->drive(); // 赤色のトラックが走っています

__construct を使うと、インスタンス化と同時に初期値を設定できます。

4-2. デストラクタ

オブジェクトが不要になったときに自動的に呼び出されるメソッド です。
PHP では以下のように定義します。

__destruct()

デストラクタは、変数がスコープから外れたときや、プログラムが終了したときに自動で呼ばれます。そのため、ファイルを閉じるや、データベース接続を切断する、後始末処理(ログ出力など)などに使用します。

例文

class Car {
    public $brand;

    public function __construct($brand) {
        $this->brand = $brand;
        echo "{$this->brand} を作りました<br>";
    }

    public function __destruct() {
        echo "{$this->brand} を片付けました<br>";
    }
}

$car1 = new Car("トラック");
$car2 = new Car("バイク");

echo "プログラムの途中処理中...<br>";

実行結果

トラック を作りました
バイク を作りました
プログラムの途中処理中...
トラック を片付けました
バイク を片付けました

5. 静的メソッドと静的プロパティ

5-1. 静的メソッド

5-1-1. 静的メソッドの定義

オブジェクトを作らなくても(インスタンス化しなくても)呼び出せるメソッド のことで、 クラス全体で共通の処理をまとめたいときに使います。
static キーワードを使います。

アクセス修飾子 static function メソッド名() { }

インスタンスがないため、$this は使えません。

5-1-2. 静的メソッドの呼び出し

静的メソッドの呼び出しには「::」を使用します。

クラス名::静的メソッド名

例文1

class Car {
    public static function horn() {
        echo "プップー!";
    }
}

// インスタンス化しなくても呼べる
Car::horn();  // プップー!

例文2

class Math {
    public static function add($a, $b) {
        return $a + $b;
    }

    public static function multiply($a, $b) {
        return $a * $b;
    }
}

// インスタンス化しなくても計算できる
echo Math::add(3, 5);      // 8
echo Math::multiply(4, 6); // 24

5-2. 静的プロパティ

5-2-1. 静的プロパティの定義

オブジェクトごとではなく、クラス全体で共有されるプロパティであり、宣言するときに static をつけます。

アクセス修飾子 static プロパティ名;
5-2-2. 静的プロパティの呼び出し

静的プロパティの呼び出しには「クラス名」または「self」に対して「::」を使用します。

クラス名::プロパティ名

または

self::プロパティ名

例文
普通のプロパティとの違い

class Car {
    public $color; // インスタンスごとに違う
    public static $count = 0; // 全体で共有される
}

// インスタンスを2つ作成
$car1 = new Car();
$car1->color = "赤";
Car::$count++; // クラス全体のカウンターを増やす

$car2 = new Car();
$car2->color = "青";
Car::$count++;

echo $car1->color;  // 赤
echo $car2->color;  // 青
echo Car::$count;   // 2 (全体で共有される)

通常のプロパティはインスタンスごとに独立
静的プロパティはクラス全体で1つだけ

6. アクセス修飾子

アクセス修飾子とは、その変数に対して「どこから」アクセスできるかを決めるキーワードです。

修飾子クラス内部継承クラス外部クラスから
public
protected
private

6-1. public(公開)

  • どこからでもアクセスできる
  • クラスの外からでも値を読み書きできる

例文

class Car {
    public $color = "赤"; // 公開プロパティ
}

$car = new Car();
echo $car->color;  // 赤
$car->color = "青"; // 外から変更も可能

6-2. protected(保護)

  • クラス自身と、継承したクラス(子クラス)からアクセスできる
  • クラスの外からはアクセスできない

例文

class Car {
    protected $color = "赤";
}

class SportsCar extends Car {
    public function showColor() {
        echo $this->color; // 子クラスからOK
    }
}

$car = new SportsCar();
$car->showColor(); 
// echo $car->color; // ❌ エラー(外からはアクセス不可)

6-3. private(非公開)

  • クラス自身の中だけでアクセスできる
  • 継承したクラス(子クラス)からもアクセスできない

例文

class Car {
    private $engine = "V8";

    public function showEngine() {
        echo $this->engine; // クラス内部からOK
    }
}

class SportsCar extends Car {
    public function showEngineChild() {
        // echo $this->engine; // ❌ エラー(子クラスからも見えない)
    }
}

$car = new Car();
$car->showEngine(); // V8
// echo $car->engine; // ❌ エラー(外からも見えない)

7. 抽象クラス・抽象メソッド

7-1. 抽象クラス

抽象クラスとは、共通の振る舞いをまとめつつ、後に学ぶ「継承」によりサブクラスごとに異なる実装を強制したい場合に定義します。そのため、抽象クラスに定義されている抽象メソッドは必ず実装しなくてはいけません。もちろん具象メソッドも定義が可能です。
サブクラスで実現する前提のクラスのため、直接インスタンス化できません。
抽象クラスを定義するには、abstract キーワードを付与します。

abstract class 抽象クラス名 { }

7-2. 抽象メソッド

抽象クラスに定義され、サブクラスで必ず実装してほしいメソッドの事を、抽象メソッドといいます。
抽象メソッドを定義するには、abstract キーワードを付与します。

abstract アクセス修飾子 function 抽象メソッド名() { }

例文
抽象クラス

abstract class Animal {
    public $name;

    // コンストラクタ
    public function __construct($name) {
        $this->name = $name;
    }

    // 抽象メソッド(子クラスで必ず実装する必要がある)
    abstract public function speak();

    // 具象メソッド
    public function eat() {
        echo "{$this->name} が食べています。<br>";
    }
}

サブクラス

class Dog extends Animal {
    public function speak() {
        echo "{$this->name} はワンワンと鳴きます。<br>";
    }
}

class Cat extends Animal {
    public function speak() {
        echo "{$this->name} はニャーと鳴きます。<br>";
    }
}

// 抽象クラスはインスタンス化できない
// $animal = new Animal("テスト"); // ❌ エラー

$dog = new Dog("ポチ");
$cat = new Cat("ミケ");

$dog->eat();   // ポチ が食べています。
$dog->speak(); // ポチ はワンワンと鳴きます。

$cat->eat();   // ミケ が食べています。
$cat->speak(); // ミケ はニャーと鳴きます。

8. インターフェース

抽象クラスは必ず継承により、サブクラスで実現しなければいけません。しかし、抽象クラスはクラスのため、多重継承が禁止されています。
そこで、複数のファイルで定義されている必ず実装したいメソッドを受け継ぎたい場合は、インターフェースを使用します。
インターフェースは、「実装すべきメソッドの名前・引数だけを定義した契約書のようなもの」で、中身(処理)は書けません。

8-1. インターフェースの定義

インターフェースの定義には、interface キーワードを付与し、その中で、実装すべきメソッドの名前・引数だけを定義します。
また、そのメソッドのアクセス修飾子は必ず public になります。(省略してもpublic)

interface インターフェース名 {
    public function メソッド名();
    public function メソッド名();
}

8-2. インターフェースの実現

インターフェースを実現するには、 implements キーワードを使用します。

class 実現クラス implements インターフェース { }

複数実現するには、「 , 」で区切ります。

class 実現クラス implements インターフェースA, インターフェースB { }

例文
インターフェース

interface Animal {
    public function speak();
    public function eat();
}

実現クラス

class Dog implements Animal {
    public function speak() {
        echo "ワンワン!<br>";
    }

    public function eat() {
        echo "ドッグフードを食べています。<br>";
    }
}

class Cat implements Animal {
    public function speak() {
        echo "ニャー!<br>";
    }

    public function eat() {
        echo "魚を食べています。<br>";
    }
}

$dog = new Dog();
$dog->speak(); // ワンワン!
$dog->eat();   // ドッグフードを食べています。

$cat = new Cat();
$cat->speak(); // ニャー!
$cat->eat();   // 魚を食べています。

抽象クラスとインターフェースの違い

特徴抽象クラスインターフェース
インスタンス化❌ できない❌ できない
メソッド実装一部実装可能実装不可(定義だけ)
プロパティ〇(定義できる)❌(できない)
継承の数1つだけ複数実装可能
使いどころ共通の処理を含めたい場合処理内容は違うが、同じ操作ができることを保証したい場合

9. 無名クラス

無名クラスとは、名前を付けずにその場で定義・生成できるクラスのことです。
通常のクラスはあらかじめ class クラス名 { ... } と宣言しますが、無名クラスは 一度きりの使い捨てクラス(その場限り) を作りたい場合に便利です。

  • 簡単な一時的オブジェクトを作るとき
  • テストコード内でダミー実装(モック)を作るとき
  • 名前をつけるほどでもない軽いクラスが欲しいとき
  • 抽象メソッドを定義できない
  • 無名クラスを継承することはできない

無名クラスを定義するには、new キーワードを使用してインスタンス化を行いますが、その際にクラス名は記述しません。

new class {
    プロパティ / メソッドの定義
}

継承することも可能です

new class extends スーパークラス名 {
    プロパティ / メソッドの定義
}

インターフェースも可能です。

new class implements インターフェース名 {
    プロパティ / メソッドの定義
}

例文1

$obj = new class {
    public function hello() {
        return "Hello!";
    }
};

echo $obj->hello(); // Hello!

例文2

interface Greet {
    public function hello();
}

$greeter = new class("PHP") implements Greet {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function hello() {
        return "Hello, " . $this->name;
    }
};

echo $greeter->hello(); // Hello, PHP

10. instanceof 演算子

instanceof 演算子 は、オブジェクトがあるクラス、親クラス、インターフェースを元に作られたものかどうか を調べるために使います。(トレイトには使用できません)
関数やメソッドの中で「引数がどの型のオブジェクトか」を安全に確認するときに便利です。

変数 instanceof 型名

例文1

$object instanceof ClassName
  • 左側:調べたいオブジェクト
  • 右側:クラス名、親クラス名、インターフェース名
  • 戻り値:boolean型(true または false

例文2

class Animal {}
class Dog extends Animal {}

$dog = new Dog();

var_dump($dog instanceof Dog);    // true
var_dump($dog instanceof Animal); // true(親クラス)
var_dump($dog instanceof stdClass); // false

例文3

interface Movable {
    public function move();
}

class Car implements Movable {
    public function move() {
        echo "車が走る!";
    }
}

$car = new Car();

var_dump($car instanceof Car);      // true
var_dump($car instanceof Movable);  // true(インターフェースを実装している)

11. トレイト

11-1. トレイトの定義

トレイトとは、再利用可能なコード(プロパティ/メソッド)をまとめて切り出しておける仕組みです。
PHP は 多重継承ができない ので、トレイトを使うことで「共通のメソッドを複数のクラスで再利用」できます。
トレイトは「クラスに機能を追加する仕組み」であって、独立した型ではないため、instanceof 演算子は使用できません。
トレイトは、 trait キーワードを付与し定義します。

trait トレイト名 {
    プロパティ / メソッド
}
  • 定数は持てない
  • クラスの継承やインターフェースの実現はできない

11-2. トレイトの利用

トレイトを利用するには、クラスの内部で use 命令を利用しそのクラスに組み込みます。

use トレイト名

例文1

trait HelloTrait {
    public function sayHello() {
        echo "Hello!";
    }
}

class MyClass {
    use HelloTrait; // トレイトを組み込む
}

$obj = new MyClass();
$obj->sayHello(); // Hello!

複数のトレイトを利用するには「 , 」で区切ります。

class MyClass {
    use HelloTrait, WorldTrait;
}

11-3. 名前競合

トレイトを利用すると、トレイト同士で名前が衝突することがしばしばありエラーが生じます。
競合時は insteadof 演算子 as で解決します。

例文
同名メソッドの競合解決

trait A {
    public function hello() { echo "A"; }
}
trait B {
    public function hello() { echo "B"; }
}

class MyClass {
    use A, B {
        A::hello insteadof B; // A を優先
        B::hello as helloFromB; // B に別名をつけて使う
    }
}

$obj = new MyClass();
$obj->hello();       // A
$obj->helloFromB();  // B

12. 名前空間

12-1. 名前空間の定義

名前空間 とは、クラス・関数・定数などの名前が他のライブラリやコードと衝突しないように管理する仕組み です。
名前空間を定義するには、namespace を利用します。

namespace 名前空間名

例文
名前空間 MyApp\Models を使う場合

プロジェクト/
│
├─ src/
│   ├─ Models/
│   │   └─ User.php
│   └─ Controllers/
│       └─ UserController.php

User.php 内での名前空間宣言

<?php
namespace MyApp\Models;

class User {
// クラス定義
}
12-1-1. 名前空間名の記法

名前空間名は、フォルダ構造と名前空間の階層に準じさせるのが一般的です。
名前空間名の記法には、「非修飾名」、「修飾名」、「完全修飾名」に分けられます。

12-1-1-1. 非修飾名

名前空間を指定せず、単純なクラス名だけを書きます。現在の名前空間内で解決できます。

namespace MyApp\Models;

class User {}

// 同じ namespace 内での参照
$user = new User(); // 非修飾名
  • 現在の名前空間 MyApp\Models 内の User クラスを指す
  • use 文を使えば、他の名前空間のクラスも非修飾名で参照可能
12-1-1-2. 修飾名

名前空間の一部を付けて書きます。現在の名前空間に対して相対的に解決できます。

namespace MyApp\Controllers;

$user = new Models\User(); // 修飾名
  • 現在の namespace は MyApp\Controllers
  • Models\UserMyApp\Controllers\Models\User ではなく、MyApp\Models\User を指す場合は use が必要
12-1-1-3. 完全修飾名

グローバルルートからの絶対パスで指定します。先頭に \ を付けます。

$user = new \MyApp\Models\User(); // 完全修飾名
  • 現在の namespace に関係なく、必ずこのクラスを参照
  • 外部ライブラリや他の名前空間を明示的に指定する場合に便利

まとめ

種類記法例解説
非修飾名User現在の名前空間内で解決
修飾名Models\User現在の名前空間を基準に部分的に指定
完全修飾名\MyApp\Models\Userグローバルルートからの絶対指定
  • 非修飾名 → 修飾名 → 完全修飾名 の順に範囲が広くなるイメージ
  • use 文と組み合わせると、非修飾名で簡単に書ける

PHP では 可読性のために、通常は非修飾名 + use 文 が推奨されています。

12-1-2. 名前空間の定義位置

名前空間は、<?php 以外何も記述されていないファイルの先頭で定義します。<?php以外のタグや、空白文字なども不可です。

   ←余計な改行があり、エラー
<?phpnamespace 名前空間名

また、同じファイル内で複数の namespace を切り替えることも可能だが、可読性のため通常は 1 ファイル 1 namespace が推奨されています。

12-2. インポート

定義された名前空間を利用するには、use 命令にによる型のインポートを行います。

use 名前空間\クラス名;

例文
use で指定したクラスを、以降のコードで 非修飾名で使用可能です。

namespace MyApp\Controllers;

use MyApp\Models\User;

$user = new User(); // use でインポートしたので非修飾名でOK
$user->sayHello();

出力結果

Hello from MyApp\Models\User
12-2-1. 名前空間の定義位置

use 文は namespace ブロックの先頭に書くのが基本です。classやfunction、制御構文の配下で呼び出すことはできません。

12-2-1-1. グローバルスコープでの呼び出し

名前空間に属さない場所(グローバルスコープ) では、フルパスや use 文を使って名前空間内のクラスを呼び出します。

namespace MyApp\Models;

class User {
    public function sayHello() {
        echo "Hello from MyApp\Models\User";
    }
}

// グローバルスコープ
$user = new \MyApp\Models\User(); // 完全修飾名で呼び出し
$user->sayHello();
12-2-1-2. namespace ブロック内での呼び出し

同じ名前空間内 なら、非修飾名でそのまま呼び出せます。

namespace MyApp\Models;

class User {
    public function sayHello() {
        echo "Hello";
    }
}

// 同じ namespace 内の別クラス
class Admin {
    public function greet() {
        $user = new User(); // 非修飾名で OK
        $user->sayHello();
    }
}

他の名前空間のクラスを使う場合は use 文が必要です。

namespace MyApp\Controllers;

use MyApp\Models\User;

class UserController {
    public function action() {
        $user = new User(); // use でインポート済み
        $user->sayHello();
    }
}

まとめ

スコープ呼び出し方法
グローバルスコープ完全修飾名 (\MyApp\Models\User) または use でインポート
同じ namespace 内非修飾名で直接呼び出せる
他の namespaceuse 文でインポートするか、完全修飾名で呼び出す
12-2-2. インポートの有効範囲

インポートの有効範囲は、そのファイルでのみ認識されます。

12-3. 名前競合時に別名を設定

名前空間内で同じ名前のクラス・関数・定数が複数存在する場合use 文で エイリアス(別名)を設定 して競合を回避できます。

use 名前空間\クラス名 as 別名;
  • as キーワードで 別名を付ける
  • 以降はその別名でクラスを参照可能
  • ファイル先頭または namespace ブロックの先頭で宣言する

例文1
クラス名にエイリアス

namespace MyApp\Controllers;

use LibraryA\User as UserA;
use LibraryB\User as UserB;

$a = new UserA();
$b = new UserB();

例文2
関数にエイリアス

use function LibraryA\sayHello as sayHelloA;
use function LibraryB\sayHello as sayHelloB;

sayHelloA();
sayHelloB();

例文3
定数にエイリアス

use const LibraryA\VERSION as VERSION_A;
use const LibraryB\VERSION as VERSION_B;

echo VERSION_A;
echo VERSION_B;

13. クラスの自動ローディング

13-1. オートローダーの定義

クラスは複数のスクリプトから再利用されるという性質上、1クラスを1ファイルで管理していきます。
ただ、扱うファイルが増えてきた場合にクラスファイル1つずつを require_once 命令で呼び出さなくてはならなくなり、記述漏れによるリスクを伴います。
その際に spl_autoload_register 関数を利用すると良いです。
PHPには「オートローダー」という仕組みがあり、spl_autoload_register を使うことで require_once を毎回書かなくても、クラスが呼ばれた時点で自動的に対応するファイルを読み込んでくれる ようにできます。
1度クラスが読み込まれた後は、再度オートローダーは呼ばれません。

spl_autoload_register( callable $autoload_function, bool $throw, bool $prepend) : bool

引数の意味

$autoload_functionクラスが見つからなかった時に呼び出す関数(またはメソッド)を指定します。
省略すると、デフォルトの __autoload が使われます。
$throw省略可、デフォルト = true
true の場合、登録に失敗したら例外を投げます。
false の場合、エラーを返すだけ。
$prepend省略可、デフォルト = false
true にすると、そのオートローダーを 先頭に登録します。
デフォルトは false(末尾に登録)。

例文

<?php
// オートローダーを登録
spl_autoload_register(function ($className) {
    // クラスファイルの場所を定義(例: classes ディレクトリ配下)
    $file = __DIR__ . '/classes/' . $className . '.php';

    if (file_exists($file)) {
        require_once $file;
    }
});

// クラスを利用(必要な時に自動で読み込まれる)
$user = new User();
$product = new Product();
  • spl_autoload_register に登録した関数は、クラスが初めて使われるタイミングで実行される
  • PSR-4 という命名規則に従えば、composer のオートローダーも利用できて、より便利。
  • require_once の書き忘れによるエラーを防げる。

13-2. オートローダーの呼び出し

spl_autoload_register を使うと「クラスやインターフェースが見つからなかったときに、自動でオートローダーが呼び出される」仕組みになります。
自動呼び出しの流れは以下のとおりです。

  1. new クラス名()クラス名::メソッド() など、まだ定義されていないクラスを使う。
  2. PHP が「このクラスどこ?」と探す。
  3. 事前に spl_autoload_register で登録しておいた関数が 自動で呼ばれる
  4. その関数の中で requireinclude を行い、クラス定義ファイルを読み込む。
  5. 読み込まれたクラスを使えるようになる。

例文

<?php
// オートローダー登録
spl_autoload_register(function ($className) {
    echo "オートローダーが呼ばれました: {$className}\n";
    require_once __DIR__ . "/classes/" . $className . ".php";
});

// クラスを利用(まだ require してない)
$user = new User(); // <= この瞬間にオートローダーが自動で呼び出される
$user->hello();

classes/User.php の中身

<?php
class User {
    public function hello() {
        echo "Hello User!";
    }
}

実行結果

オートローダーが呼ばれました: User
Hello User!

オブジェクト指向

1. オブジェクト指向
2. カプセル化
3. 継承
4. ポリモーフィズム

1. オブジェクト指向

オブジェクト指向とは、プログラムを「モノ(オブジェクト)」の集まりとしてとらえて設計・開発する考え方です。
複雑な処理を「データ(属性)」と「振る舞い(操作)」をセットにした「オブジェクト」に分けて整理することで、わかりやすく、再利用しやすいプログラムを作ることができます。

オブジェクト指向の3大要素

カプセル化データ(変数)と処理(メソッド)をひとまとめにする。
外部から中身を勝手にいじれないように制御できる。
継承既存のクラスの機能を引き継ぎつつ、新しい機能を追加できる。
共通部分をまとめて、重複コードを減らせる。
ポリモーフィズム同じ名前の操作でも、クラスごとに異なる振る舞いを持たせられる。
(例)「動物」という型で 鳴く() を呼び出すと、犬なら「ワン」、猫なら「ニャー」となる。

オブジェクト指向のメリットとして以下の点が挙げられます。

  • わかりやすい:現実世界のモノの関係をイメージしやすい
  • 再利用性が高い:クラスを作っておけば何度も使える
  • 拡張しやすい:継承やポリモーフィズムで機能追加しやすい
  • 保守性が高い:部品ごとに分けて修正できる

1-1. クラス(設計図)

オブジェクト指向では、まず クラス という「設計図」を作ります。
車の場合、「車クラス」という設計図を考えます。

  • 車には「色」「メーカー」「車種」などの 属性(データ) がある
  • 車には「走る」「止まる」「曲がる」といった 機能(メソッド) がある

つまり クラス = 車の設計図 です。

1-2. オブジェクト(実体)

設計図から実際の車を作ったものが オブジェクト(インスタンス) です。
例:

  • 赤い車
  • 青い車

これらは同じ「車クラス」から生まれた、別々のオブジェクト です。

1-3. カプセル化(まとめる)

車の中身(エンジンの仕組みなど)は、普通の人は気にせず「アクセルを踏む」だけで車が走ります。
内部の複雑な仕組みを隠して、外からは「操作方法」だけ見せるのが カプセル化 です。

1-4. 継承(引き継ぐ)

「車クラス」を基に「スポーツカー」「トラック」などを作れます。

  • 車クラス → 共通の機能「走る」「止まる」
  • スポーツカー → さらに「ターボ機能」を追加
  • トラック → 「荷物を積む」機能を追加

これが 継承 です。

1-5. 多態性(ポリモーフィズム)

「走る」という操作は同じでも、スポーツカーなら速く、トラックならゆっくり動きます。
同じ命令でも、オブジェクトごとに動きが変わるのが 多態性(ポリモーフィズム) です。

まとめると、以下のような感じです。

  • クラス = 設計図
  • オブジェクト = 実際の車
  • カプセル化 = 内部は隠して操作を提供
  • 継承 = 機能を引き継いで新しい車を作る
  • 多態性 = 同じ操作でも動きが変わる

2. カプセル化

2-1. カプセル化とは

カプセル化とは、データ(プロパティ)処理(メソッド) をまとめて外部から隠すことです。
「クラス」という箱の中にデータや処理をカプセル(カプセル薬の中身)のように閉じ込め、外部からは直接中身を触れないようにして、必要な操作だけをメソッドを通じて提供します。
中身を隠し、外からは安全に使える仕組みだけ公開します。
カプセル化のメリットとして以下の点があります。

  • データを守る
    → 直接いじれないので、不正な値が入らない
  • 使いやすいインターフェースを提供
    → 「deposit()」「withdraw()」など分かりやすい操作で利用できる
  • 変更に強くなる
    → 内部の仕組みを変えても、外から使うメソッドが同じなら影響が少ない

2-2. アクセサーメソッド

アクセサーメソッドとは、クラスの プロパティに安全にアクセスするためのメソッド のことです。
プロパティを privateprotected にして直接触れないようにし、外部から値を読み書きしたいときは アクセサーメソッド経由で操作 します。

アクセサーメソッド概要
ゲッター
(getter)
プロパティの値を取得するメソッド
セッター
(setter)
プロパティの値を設定するメソッド

メリットとして以下の点があります。

  • 不正な値を防げる
    (例: 年齢にマイナスを入れられないようにする)
  • 外部からのアクセスを制御できる
  • 内部の実装を隠せる

例文

class User {
    private $name; // 外部から直接アクセス不可

    // コンストラクタ
    public function __construct($name) {
        $this->name = $name;
    }

    // ゲッター(値を取得)
    public function getName() {
        return $this->name;
    }

    // セッター(値を設定)
    public function setName($name) {
        if (!empty($name)) {  // バリデーションもできる
            $this->name = $name;
        }
    }
}

$user = new User("太郎");

// 直接アクセスはできない
// echo $user->name; ❌ エラー

// アクセサーメソッド経由ならOK
echo $user->getName(); // 太郎

$user->setName("次郎");
echo $user->getName(); // 次郎

3. 継承

3-1. 継承を行う

継承とは、既存のクラス(スーパークラスや親クラスという)を基にして、新しいクラス(サブクラスや子クラスという)を作る仕組み です。
サブクラスはスーパークラスの プロパティメソッド を引き継ぎ、さらに 独自の機能を追加したり、上書き(オーバーライド) することができます。
継承するには、extends キーワードを利用します。

class スーパークラス名 {
    // プロパティやメソッド
}

class サブクラス名 extends スーパークラス名 {
    // 追加のプロパティやメソッド
}
  • コードの再利用
    スーパークラスのプロパティやメソッドをそのまま使える
  • 拡張性
    同じ名前のメソッドを定義するとオーバーライド(上書き)される

例文

// 親クラス
class Animal {
    public $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function speak() {
        echo "{$this->name} が鳴きます。";
    }
}

// 子クラス
class Dog extends Animal {
    public function speak() {
        echo "{$this->name} がワンワンと鳴きます。";
    }
}

// 子クラスのインスタンス
$dog = new Dog("ポチ");
$dog->speak(); // ポチ がワンワンと鳴きます。

3-2. スーパークラスのメソッドを呼び出す

スーパークラスのメソッドを呼び出すには、以下のようにします。

スーパークラス::メソッド名()

例文

class Dog extends Animal {
    public function speak() {
        parent::speak(); // 親クラスのメソッドを呼び出す
        echo " さらに、{$this->name} はワンワンと鳴きます。";
    }
}

$dog = new Dog("コロ");
$dog->speak();
// コロ が鳴きます。 さらに、コロ はワンワンと鳴きます。

3-3. オーバーライド

3-3-1. オーバーライドの定義

オーバーライドとは、スーパークラスで定義されたメソッドを、サブクラスで上書きして再定義すること です。

  • 親クラスの処理をそのまま使うこともできる
  • 子クラス独自の振る舞いに変更できる

オーバーライドを行う条件としては、以下のとおりです。

  • メソッド名は親と同じ
  • 引数の数や型も同じにするのが原則
  • アクセス修飾子は親と同等かより広くする必要がある

スーパークラスの処理を呼びたければ parent キーワードで呼び出します。

parent::メソッド名() 

例文

// 親クラス
class Animal {
    public function speak() {
        echo "動物が鳴きます";
    }
}

// 子クラス
class Dog extends Animal {
    // オーバーライド
    public function speak() {
        echo "犬がワンワンと鳴きます";
    }
}

$dog = new Dog();
$dog->speak(); // 犬がワンワンと鳴きます
3-3-2. オーバーライドを禁止する

オーバーライドを禁止するには、final修飾子を付与し安全に親クラスの処理を固定できます。
それにより、サブクラスでそのメソッドを上書きできなくなります。

クラスに付ける場合

final class クラス名 { }

メソッドに付ける場合

final アクセス修飾子 function メソッド名() { } 

例文1
クラスに付ける場合

class Animal {
    final public function breathe() {
        echo "息を吸って吐く";
    }
}

class Dog extends Animal {
    // ❌ オーバーライドできない
    // public function breathe() {
    //     echo "犬の呼吸";
    // }
}

$dog = new Dog();
$dog->breathe(); // 息を吸って吐く

例文2
クラスに付ける

final class Utility {
    public static function help() {
        echo "役立つ処理";
    }
}

// ❌ 継承不可
// class MyUtility extends Utility {}

まとめ

付与対象概要
クラスに final継承禁止(サブクラス作れない)
メソッドに final子クラスでfinalが付与されたメソッドがオーバーライド禁止

3-4. 多重継承

多重継承とは、1つのクラスが複数の親クラスを継承すること を指します。
しかし PHP では多重継承はサポートしておらず、1つのクラスは 1つの親クラスしか extends できません

// ❌ PHPではこれはできない
class Child extends Parent1, Parent2 {
}

多重継承の代わりに、インターフェースや、トレイトを用いて実装していきます。

4. ポリモーフィズム

ポリモーフィズムとは、同じ操作(メソッド呼び出し)が、オブジェクトの型によって異なる振る舞いをすること を指し、同名のメソッドで異なる挙動を実現することを言います。
例えば、「同じ名前のメソッドでも、オブジェクトによって結果が変わる」ことです。

例文

abstract class Animal {
    abstract public function speak();
}

class Dog extends Animal {
    public function speak() {
        echo "ワンワン<br>";
    }
}

class Cat extends Animal {
    public function speak() {
        echo "ニャー<br>";
    }
}

// 配列に複数の動物を格納
$animals = [new Dog(), new Cat()];

foreach ($animals as $animal) {
    $animal->speak(); // それぞれの動物の speak が呼ばれる
}

実行結果

ワンワン
ニャー

例外処理

1. 例外処理とは
2. 例外クラスの型
3. エラーハンドリング
4. 例外をスローする
5. 条件が真であることをチェックする
6. スタックトレース情報

1. 例外処理とは

プログラム実行中に エラーや異常な状態が発生したとき に、そのまま処理を止めるのではなく、
「例外(Exception)」という特別なオブジェクトを投げて(throw)、受け取って(catch)安全に処理する仕組み です。
例外処理を実装するタイミングですが、「通常では発生しない異常事態」に使い、ファイル/DB/外部API/入力チェック/致命的エラー などが代表例です。ただの条件分岐(if で済むもの)には使いません。

2. 例外クラスの型

PHP の例外は最上位 Throwable をベースにException(通常の例外)とError(致命的なエラー)の2系統に分かれています。

Throwable (インターフェースみたいな最上位)
 ├── Exception (通常の例外)
 │    ├── ErrorException
 │    ├── RuntimeException
 │    │    ├── OutOfBoundsException
 │    │    ├── OverflowException
 │    │    ├── RangeException
 │    │    ├── UnderflowException
 │    │    └── UnexpectedValueException
 │    ├── LogicException
 │    │    ├── BadFunctionCallException
 │    │    │    └── BadMethodCallException
 │    │    ├── DomainException
 │    │    ├── InvalidArgumentException
 │    │    └── LengthException
 │    └── 独自の例外
 └── Error (致命的エラーを例外化したもの)
      ├── TypeError
      ├── ParseError
      └── ArithmeticError
           └── DivisionByZeroError

2-1. Exception

ほとんどの例外はこれを継承しています。

2-1-1. ErrorException

PHP で発生する 通常のエラー(Warning, Notice, Deprecated など)を例外オブジェクトとして扱えるようにしたクラス です。
エラー関連の情報(エラーレベル・ファイル・行番号など) を保持します。

2-1-2. RuntimeException

実行中にしか起きないエラーです。
データーベースに接続できないや、指定されたテーブルが存在しないなど、外部環境の問題が大半です。

2-1-3. LogicException

プログラムの書き方が論理的に誤っている際のエラーです。
ロジックの誤りなので、コードそのものを修正することとなります。

2-1-4. 独自の例外

PHPで用意されている標準の例外クラスでは思うような処理ができない場合も出てきます。そこで独自の例外クラスを作って より柔軟で意味のある例外処理 ができます。
独自の例外クラスを定義するには、Exceptionクラスを継承します。

class 独自例外クラス extends Exception { }

例文

// Exception を継承して独自例外を定義
class MyCustomException extends Exception {
    private $errorCode;

    public function __construct($message, $errorCode = 0, Exception $previous = null) {
        parent::__construct($message, $errorCode, $previous);
        $this->errorCode = $errorCode;
    }

    public function getErrorCode() {
        return $this->errorCode;
    }
}

2-2. Error

PHP5 以前は、次のような問題が起きると Fatal error(致命的エラー) として表示され、スクリプトが強制終了していました。
PHP7 からは、このような致命的エラーを 例外オブジェクト(Error クラス) として扱えるようになりました。

3. エラーハンドリング

エラーハンドリング とは、プログラム実行中に発生する エラーや異常を検知して、安全に処理する仕組みを行う例外処理 のことです。

以下の3点を組み合わせて実装していきます。

  • 例外処理 (try-catch)
  • エラー処理関数 (set_error_handler)
  • ログ出力やユーザー向けメッセージ表示

エラーハンドリングの目的としては、以下の点が挙げられます。

  • プログラムの クラッシュを防ぐ
  • ユーザーにわかりやすいエラー表示 を行う
  • ログ記録 して後で原因を追跡できる
  • 外部リソース(DB, ファイル, API)の 安全な操作 を保証する

3-1. 例外処理

例外処理を実装するには、try-catch を利用します。

try {
    // 処理
} catch (例外クラスの型 例外の変数) {
    // エラー処理
} finally {
    // 後処理(リソース解放など)
}
3-1-1. try

例外が発生する可能性のある処理を囲むブロック内に定義します。
このブロック内で例外が生じた場合は、その時点でcatchに制御が遷移します。

3-1-2. catch

投げられた例外を受け取り処理を行います。
catchは複数定義することも可能です。
また継承関係にある例外クラスの場合、サブクラスから順に定義していかなくてはいけませんPHP は catch ブロックを上から順に評価するため、先に親クラスをキャッチすると、サブクラスの例外はすべて親クラスに捕まってしまいます。

try {
    // 何らかの処理
} catch (TypeError $e) {
    echo "型エラー: " . $e->getMessage();
} catch (ErrorException $e) {
    echo "通常のエラー: " . $e->getMessage();
} catch (Exception $e) {
    echo "その他の例外: " . $e->getMessage();
}

マルチキャッチを使って、複数の例外クラスを1つの catch ブロックでまとめて処理できます。
利用する場合は「 | 」を使用して共通の処理 をまとめられます。

例文

try {
    // 例外が発生する可能性のある処理
    if (rand(0,1)) {
        throw new TypeError("型エラー発生");
    } else {
        throw new RuntimeException("実行時例外発生");
    }
} catch (TypeError | ArithmeticError $e) {
    echo "型エラーまたは算術エラーをキャッチ: " . $e->getMessage();
} catch (RuntimeException $e) {
    echo "RuntimeException をキャッチ: " . $e->getMessage();
}

ここで重要なことは、例外をその場で対処できないからと言って、以下のように空のcatchブロックを設置して例外は握りつぶさないようにしてください。

} catch(Exception $e) {
    // 何も処理を記述しない
}
3-1-3. finally

例外が発生しても、しなくても必ず実行されるブロック で、主にリソースの後始末などに使います。複数の catch があっても、finally は一度だけ実行されます。
finallyは、省略はできます。

  • ファイルやデータベースの接続を閉じる
  • ログを必ず残す

例文

try {
    echo "処理開始\n";
    // 例外が発生するかもしれない処理
    throw new Exception("例外発生!");
} catch (Exception $e) {
    echo "例外キャッチ: " . $e->getMessage() . "\n";
} finally {
    echo "必ず実行される処理\n";
}

3-2. エラー処理関数

3-2-1. ErrorException に変換

PHP の set_error_handler() は、通常の PHP エラー(Warning, Notice, Deprecated など)をカスタム関数で処理できる仕組み です。
通常の Warning / Notice / Deprecated などの軽微なエラー は try-catch で捕まえられません、しかし set_error_handler() を使うと ErrorException に変換して try-catch で処理可能となります。
例外処理とは別に、エラーを自分でハンドリングしたい場合に使います。

set_error_handler(function ($severity, $message, $file, $line) {
    echo "カスタムエラー処理: $message in $file on line $line\n";
});

引数

引数内容
$severityエラーの種類(E_WARNING, E_NOTICE, E_USER_ERROR など)
$messageエラーメッセージ
$fileエラー発生ファイル
$lineエラー発生行番号

例文

set_error_handler(function ($severity, $message, $file, $line) {
    throw new ErrorException($message, 0, $severity, $file, $line);
});

try {
    echo 1 / 0; // Warning が発生 → ErrorException に変換
} catch (ErrorException $e) {
    echo "キャッチしました: " . $e->getMessage();
}
3-2-2. カスタムエラーハンドラを元に戻す

以前に set_error_handler() で設定した カスタムエラーハンドラを元に戻す 場合は、restore_error_handler()を利用します。

  • デフォルトの PHP エラー処理に戻したいときに使用します
  • 複数のカスタムエラーハンドラを切り替える場合に便利

例文

set_error_handler(function($severity, $message, $file, $line) {
    echo "カスタムエラー: $message\n";
});

trigger_error("カスタムエラー発生", E_USER_NOTICE);

restore_error_handler(); // 元の PHP 標準のエラーハンドラに戻す

trigger_error("通常エラー発生", E_USER_NOTICE);

3-3. Exceptionで捕捉しない

Exceptionは、すべての例外をキャッチしてしまいます。そのため、例外の対象が曖昧になり、本来のバグや異常が隠れてしまい、結果として、後で原因不明の不具合につながります。また、すべての例外を無条件で捕捉すると、本来想定していない例外まで処理してしまいます。
catchブロックでは、具体的な例外クラスを指定して処理する のがベストです

例文
NG

try {
    riskyOperation();
} catch (Exception $e) {
    logError($e);  // すべての例外をログに残すだけ
}
// RuntimeException や TypeError もすべて捕捉される → 本来止めるべき重大なエラーまで進んでしまう

4. 例外をスローする

4-1. throw文

例外(Exception オブジェクト)を投げるには、throw文 を利用します。
new で例外オブジェクトを生成して、throw で例外クラスに投げます。

throw new 例外クラスの型();

例文

function divide($a, $b) {
    if ($b === 0) {
        throw new Exception("0で割ることはできません");
    }
    return $a / $b;
}

try {
    echo divide(10, 0);
} catch (Exception $e) {
    echo "例外をキャッチ: " . $e->getMessage();
}

4-2. throw 式

throw文は、代入や三項演算子には使えませんでした。
PHP8以降ではthrow 式が使用でき、throw を 値として評価できるようになりました。
代入や三項演算子、関数引数などに直接使えます。

例文1
三項演算子で使用

function getValue($data) {
    return $data['key'] ?? throw new Exception("key が存在しません");
}

try {
    $value = getValue([]);
} catch (Exception $e) {
    echo "例外キャッチ: " . $e->getMessage();
}

例文2
関数引数で使用

function printValue(string $value) {
    echo $value;
}

$data = null;
printValue($data ?? throw new Exception("値が null です"));

5. 条件が真であることをチェックする

条件が真であることをチェックするには、assert 命令を主にデバッグ目的で利用します。
条件が偽の場合、エラー(Warning や AssertionError)を発生させることができます。

assert(condition: bool, description: string|null = null);
  • condition:真であることを確認したい式
  • description(任意):条件が偽の場合に表示されるメッセージ

例文
条件が偽の場合

$x = -1;
assert($x > 0, "x は正の値でなければなりません");

$x > 0 が偽なので、AssertionError が発生

6. スタックトレース情報

スタックトレース情報 とは、例外やエラーが発生した時の「呼び出し履歴」を記録した情報 のことです。
エントリーポイントから呼び出し順(最新の呼び出しが一番上)に記録され、デバッグやエラー解析に非常に役立ちます。

6-1. スタックトレースの内容

スタックトレースには、主に以下の情報が含まれます。

項目内容
ファイル名エラーや例外が発生したファイル
行番号エラーや例外が発生した行
関数名呼び出された関数やメソッド名
引数関数に渡された引数(値やオブジェクト)
呼び出し順スタック(呼び出し履歴)の順序

6-2. 取得方法

スタックトレースの取得方法は、文字列形式や配列形式によって違います。
なお、Fatal Error や Parse Error は 通常の Exception では捕捉できず、スタックトレースを取得できない場合があります。そのため、PHP7 以降は Error クラスが例外として扱えるので、try-catch でスタックトレースを取得します。

取得メソッド
文字列形式getTraceAsString()
配列形式getTrace()
6-2-1. 文字列形式

文字列形式では、getTraceAsString() メソッドで取得します。

例文

try {
    throw new Exception("例外発生");
} catch (Exception $e) {
    echo $e->getTraceAsString();
}

出力例:

#0 /path/to/file.php(5): someFunction()
#1 /path/to/file.php(9): main()
#2 {main}
  • #0 が最新の呼び出し(例外発生箇所)
  • #1, #2 が順に呼び出した関数やスクリプト
6-2-2. 配列形式

配列形式では、getTrace() メソッドで取得します。

例文

try {
    throw new Exception("例外発生");
} catch (Exception $e) {
    $trace = $e->getTrace();
    print_r($trace);
}

出力例:

Array
(
    [0] => Array
        (
            [file] => /path/to/file.php
            [line] => 5
            [function] => someFunction
            [args] => Array()
        )
    [1] => Array
        (
            [file] => /path/to/file.php
            [line] => 9
            [function] => main
            [args] => Array()
        )
)
  • 配列として取得すると、個別に処理・解析が可能
  • ログに詳細を残す、条件に応じて処理を変える、といった用途に便利

デフォルトで用意されているPHPの機能

1. 組み込み関数
2. 標準クラスライブラリ
3. マジックメソッド

1. 組み込み関数

組み込み関数とは、PHPが標準で提供する関数のことをいいます。
ここでは、組み込み関数は多くあるため、一部のみを紹介していきます。

1-1. 文字列関数

1-1-1. 文字列の長さを取得する

文字列の半角全角を区別せずに長さを取得するには、mb_strlen関数を使用します。

mb_strlen(長さを取得したい文字列(変数など)を指定);

例文

$str = "こんにちは";
echo mb_strlen($str);   // 5(文字数)
1-1-2. 文字列のサイズを取得する

文字列のサイズを取得するには、strlen関数を使用します。
なお、文字エンコードによって、返り値が異なります。

strlen長さを取得したい文字列(変数など)を指定);

例文

$str = "こんにちは";
echo strlen($str);      // 15(UTF-8では1文字=3バイト)
1-1-3. 半角全角を区別してサイズを取得

文字列の半角全角を区別して長さを取得するには、mb_strwidth関数を使用します。
日本語や全角文字は2としてカウント、英数字や半角記号は1としてカウントします。

mb_strwidth(長さを取得したい文字列(変数など)を指定);

例文

$str = "PHPあ";
echo mb_strlen($str);    // 4(文字数)
echo mb_strwidth($str);  // 5(半角3文字=3 + 全角「あ」=2)
1-1-4. 文字列の大文字・小文字変換

mb_convert_case 関数は、マルチバイト文字列の大文字・小文字変換を行うPHPの組み込み関数です。

mb_convert_case(変換対象の文字列, 変換モード, 文字コード): string

変換モードは以下のとおりです。

MB_CASE_UPPER全て大文字に変換
MB_CASE_LOWER全て小文字に変換
MB_CASE_TITLE単語の先頭文字を大文字、それ以外は小文字

例文

$str = "pHp プログラミング";

// 全て大文字
echo mb_convert_case($str, MB_CASE_UPPER, "UTF-8");  // PHP プログラミング

// 全て小文字
echo mb_convert_case($str, MB_CASE_LOWER, "UTF-8");  // php プログラミング

// 単語の頭を大文字
echo mb_convert_case("hello world", MB_CASE_TITLE, "UTF-8");  // Hello World
1-1-5. 文字列の一部分を取得
1-1-5-1. mb_substr関数

mb_substr 関数は、マルチバイト文字列を安全に一部分だけ切り出すためのPHP組み込み関数です。

mb_substr(対象の文字列, 取り出し開始位置(0が先頭), 取り出す長さ(省略すると最後まで), 文字コード): string

例文

$str = "こんにちは世界";

// 2文字目から3文字分取得(0スタート)
echo mb_substr($str, 1, 3, "UTF-8");  // んにち

// 最後の2文字を取得
echo mb_substr($str, -2, null, "UTF-8");  // 世界
1-1-5-2. mb_strstr関数

mb_strstr 関数は、マルチバイト文字列から指定した文字列を検索し、見つかった位置以降(または以前)の部分を返す関数です。
見つからなければ false を返します。

mb_strstr(検索対象の文字列, 探す文字列, bool, 文字コード): string|false

bool:trueにするとneedleより前を返す。falseにするとneedleより後を返す。

例文

$str = "こんにちは世界";

// 「にち」を含む部分を取得(デフォルト: needle以降)
echo mb_strstr($str, "にち", false, "UTF-8");  // にちは世界

// 「にち」より前の部分を取得
echo mb_strstr($str, "にち", true, "UTF-8");  // こん
1-1-6. 文字列の一部分を置換する

str_replace 関数は、文字列の中で特定の文字や文字列を別の文字や文字列に置き換えるための組み込み関数です。

str_replace(置き換えたい文字列, 新しく置き換える文字列, 処理対象の文字列, 置き換えが何回行われたかを格納する変数(省略可能));

例文

$text = "I like apple and apple pie.";
$result = str_replace("apple", "banana", $text);

echo $result;  // 出力: I like banana and banana pie.
1-1-7. 文字列を特定の区切り文字で分割

explode関数 は、文字列を指定した区切り文字で分割し、配列として返す関数です。

explode(区切り文字 , 分割対象の文字列, 返す配列の要素数の上限(省略可));

例文1

$str = "apple,banana,cherry";
$array = explode(",", $str);

print_r($array);

結果

Array
(
    [0] => apple
    [1] => banana
    [2] => cherry
)

例文2
limitパラメータの例
limitを3にしたため、配列の3番目以降はまとめて1つの要素として扱われます。

$str = "one,two,three,four,five";
$array = explode(",", $str, 3);

print_r($array);

結果

Array
(
    [0] => one
    [1] => two
    [2] => three,four,five
)
1-1-8. 特定の文字位置を検索
1-1-8-1. 最初に現れる位置を検索する

mb_strpos 関数は、マルチバイト文字列の中で、指定した文字列が最初に現れる位置を検索する関数です。
見つからなければ false を返します。

mb_strpos (検索対象の文字列, 検索したい文字列, 検索開始位置, 文字エンコーディング): int|false

例文
文字列「こんにちは世界」の中で「世界」は5文字目(0始まりのため5)から始まっているので、5が返ります。

$str = "こんにちは世界";
$pos = mb_strpos($str, "世界");

echo $pos;  // 出力: 5
1-1-8-2. 最後に現れる位置を検索する

mb_strrpos 関数は、マルチバイト文字列の中で、指定した文字列が最後に現れる位置を検索する関数です。
見つからなければ false を返します。

mb_strpos (検索対象の文字列, 検索したい文字列, 検索開始位置, 文字エンコーディング): int|false

例文
文字列「abcあいうabc」の中で「abc」が最後に現れるのは6文字目からなので、6が返ります。

$str = "abcあいうabc";
$pos = mb_strrpos($str, "abc");

echo $pos;  // 出力: 6
1-1-9. 特定の文字列が含まれているか判定
1-1-9-1. 含まれているか

str_contains 関数は、ある文字列が別の文字列を含んでいるかどうかを調べる関数です。
含まれていなければfalseを返します。

str_contains (検索対象の文字列, 検索したい文字列): bool

例文

$str = "こんにちは、世界!";

if (str_contains($str, "世界")) {
    echo "「世界」が含まれています。";
} else {
    echo "含まれていません。";
}
1-1-9-2. 文字列が指定した部分文字列で始まっているか

str_starts_with 関数は、文字列が指定した部分文字列で始まっているかどうかを判定する関数です。

str_starts_with(調べたい元の文字列, 開始部分としてチェックしたい文字列): bool

例文

$str = "Hello, world!";

if (str_starts_with($str, "Hello")) {
    echo "「Hello」で始まっています。";
} else {
    echo "始まっていません。";
}
1-1-9-3. 文字列が指定した部分文字列で終わっているか

str_ends_with 関数は、文字列が指定した部分文字列で終わっているかどうかを判定する関数です。

str_ends_with(調べたい元の文字列, 開始部分としてチェックしたい文字列): bool

例文

$str = "example.php";

if (str_ends_with($str, ".php")) {
    echo "「.php」で終わっています。";
} else {
    echo "終わっていません。";
}
1-1-10. 指定した文字を文字列から除去
1-1-10-1. 前後の指定した文字を文字列から除去

trim関数は、文字列の両端(先頭と末尾)から指定した文字(デフォルトは空白などのホワイトスペース)を取り除きます。

trim(処理対象の文字列, 取り除きたい文字(省略した場合は、空白)): string

例文

$str = "  こんにちは  ";
echo trim($str);  // 出力: "こんにちは"
1-1-10-2. 前方の指定した文字を文字列から除去

ltrim関数は、文字列の先頭から指定した文字を取り除きます。

ltrim(処理対象の文字列, 取り除きたい文字(省略した場合は、空白)): string

例文

$str = "  こんにちは  ";
echo ltrim($str);  // 出力: "こんにちは  "
1-1-10-3. 後方の指定した文字を文字列から除去

rtrim関数は、文字列の末尾から指定した文字を取り除きます。

rtrim(処理対象の文字列, 取り除きたい文字(省略した場合は、空白)): string

例文

$str = "  こんにちは  ";
echo rtrim($str);  // 出力: "  こんにちは"
1-1-11. 文字列を整形

printf 関数は、フォーマット指定子を使って文字列を整形し、その結果を画面(標準出力)に直接表示する関数です。

  • printf は画面に直接出力します
  • 出力した文字数(バイト数)を返します。
printf(フォーマット文字列, フォーマット文字列の中で指定された順番に埋め込む値(可変個)): int

主なフォーマット指定子

指定子概要
%s文字列“Hello”
%d整数(10進数)123
%f浮動小数点数3.14
%x整数を16進数(小文字)255ff
%X整数を16進数(大文字)255FF
%c文字(ASCIIコードの数値)65A

例文1

$number = 123;
$name = "太郎";
printf("名前: %s, 点数: %d\n", $name, $number);  // 名前: 太郎, 点数: 123

例文2
小数点以下の桁数指定

$pi = 3.14159;
printf("円周率は %.2f です。\n", $pi); // 円周率は 3.14 です。
1-1-12. 文字列を変換

mb_convert_kana 関数は、マルチバイト文字列(特に日本語)の全角・半角変換やカタカナ・ひらがな変換など、多彩な文字種変換を行う関数です。

mb_convert_kana (変換対象の文字列, 変換オプション文字列, 文字エンコーディング): string

変換オプション一覧

変換オプション説明
A全角英数字を半角に変換
a半角英数字を全角に変換
K全角カタカナを半角カタカナに変換
k半角カタカナを全角カタカナに変換
V濁点付き半角カタカナを濁点付き全角に変換(kとセットで使うことが多い)
H全角ひらがなを全角カタカナに変換
h全角カタカナを全角ひらがなに変換
S全角スペースを半角スペースに変換
s半角スペースを全角スペースに変換

※複数のオプション文字は組み合わせて使えます(例:"KV")。

例文

$str = "Hello カタカナ";
echo mb_convert_kana($str, "as");  // 半角英数字を全角に、半角スペースを全角に変換

$str2 = "カタカナ";
echo mb_convert_kana($str2, "KV"); // 半角カタカナを全角カタカナに変換
1-1-13. 文字エンコーディングを変換

mb_convert_encoding 関数は、文字列の文字エンコーディングを別のエンコーディングに変換する関数です。

mb_convert_encoding(変換対象の文字列, 変換後の文字エンコーディング名, 変換前の文字エンコーディング名): string | array | false

例文

// Shift_JISの文字列をUTF-8に変換する例
$sjis_str = "\x82\xa0\x82\xa2\x82\xa4";  // あいう(Shift_JISのバイト列)
$utf8_str = mb_convert_encoding($sjis_str, "UTF-8", "SJIS");

echo $utf8_str;  // 正常に「あいう」と表示される
1-1-14. 電子メールを送信

mb_send_mail 関数は、マルチバイト文字(日本語など)を含むメールを送信するときに使う関数です。
mail() 関数のマルチバイト対応版で、メールの件名や本文、ヘッダーに日本語が使われても文字化けしにくいように処理してくれます。

mb_send_mail(送信先メールアドレス, メールの件名, メール本文, 追加のメールヘッダー(FromやCcなど), 追加の送信パラメータ(省略可)): bool

例文

mb_language("Japanese");   // 日本語メール用の言語設定
mb_internal_encoding("UTF-8");  // 内部文字エンコーディング設定

$to = "example@example.com";
$subject = "テストメール";
$message = "これは日本語のメール本文です。";
$headers = "From: sender@example.com";

if (mb_send_mail($to, $subject, $message, $headers)) {
    echo "メール送信成功";
} else {
    echo "メール送信失敗";
}

なお、mb_send_mail 関数を利用するには、メール送信に必要な情報をphp.iniに設定する必要があります。設定は使用する端末の環境によって異なります。

1-2. 配列関数

1-2-1. 配列の要素数を取得

count() 関数 は、配列や Countable インターフェイスを実装したオブジェクトの要素数を数えるための組み込み関数です。
null を渡すと 0 を返す(警告は出ない)

count(配列, カウントモード): int

カウントモードは以下のとおりです。

カウントモード説明
COUNT_NORMAL(デフォルト)1階層目だけ数える
COUNT_RECURSIVE多次元配列の全要素を再帰的に数える

例文1
COUNT_NORMAL(デフォルト)

$fruits = ["apple", "banana", "orange"];
echo count($fruits); // 3

例文2
COUNT_RECURSIVE

$data = [
    "fruits" => ["apple", "banana"],
    "colors" => ["red", "yellow"]
];
echo count($data); // 2(第一階層の要素数)
echo count($data, COUNT_RECURSIVE); // 6(全階層の要素をカウント)
1-2-2. 要素の登場回数をカウント

array_count_values() 関数 は、配列の各値が何回出現したかを集計して、値をキー・出現回数を値とする連想配列を返す 関数です。
値は 文字列か整数 でなければなく、浮動小数点や配列を含むと 警告(Warning)が出ます

array_count_values(配列): array

例文

$data = ["apple", "banana", "apple", "orange", "banana", "apple"];

$result = array_count_values($data);

print_r($result);

結果

Array
(
    [apple] => 3
    [banana] => 2
    [orange] => 1
)
1-2-3. 複数の配列を結合

array_merge() 関数 は、複数の配列を結合して1つの配列を作る 組み込み関数です。
結合したい配列をカンマ区切りで複数指定可能です。

array_merge(結合したい配列1, 結合したい配列2 ): array

例文

$a = ["a", "b"];
$b = ["c"];
$c = ["d", "e"];
$result = array_merge($a, $b, $c);

print_r($result);

結果

Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => d
    [4] => e
)
1-2-4. 配列の各要素を結合

implode() 関数 は、配列の要素を文字列として連結する 組み込み関数です。

implode(連結に使用する文字列, 連結する配列): string

例文

$fruits = ["apple", "banana", "orange"];
$result = implode(", ", $fruits);

echo $result;

結果

apple, banana, orange
1-2-5. 配列の末尾に要素を追加

array_push() 関数は、配列の末尾に要素を追加するための組み込み関数です。
キーが数値の場合はそのまま末尾に追加され、インデックスは自動採番です。
連想配列にも使えるが、キーは自動で数値キーになります。

array_push(要素を追加したい配列, 追加したい値): int

例文

$fruits = ["apple", "banana"];
array_push($fruits, "orange", "grape");

print_r($fruits);

結果

Array
(
    [0] => apple
    [1] => banana
    [2] => orange
    [3] => grape
)
1-2-6. 配列の末尾の要素を取り出して削除

array_pop() 関数は、配列の末尾の要素を取り出して削除するための組み込み関数です。

array_pop(要素を削除したい配列): mixed

例文

$fruits = ["apple", "banana", "orange"];
$last = array_pop($fruits);

echo $last;      // orange
print_r($fruits);

結果

orange
Array
(
    [0] => apple
    [1] => banana
)
1-2-7. 配列の先頭の要素を取り出して削除

array_shift() 関数は、配列の先頭の要素を取り出して削除するための組み込み関数です。

array_shift(要素を削除したい配列): mixed

例文

$fruits = ["apple", "banana", "orange"];
$first = array_shift($fruits);

echo $first;      // apple
print_r($fruits);

結果

apple
Array
(
    [0] => banana
    [1] => orange
)
1-2-8. 配列の先頭に1つ以上の要素を追加

array_unshift() 関数は、配列の先頭に1つ以上の要素を追加するための組み込み関数です。

array_unshift(要素を追加したい配列, 先頭に追加したい値): int

例文

$fruits = ["orange"];
array_unshift($fruits, "apple", "banana");

print_r($fruits);

結果

Array
(
    [0] => apple
    [1] => banana
    [2] => orange
)
1-2-9. 配列の指定範囲の要素を削除・置換・追加

array_splice() 関数は、配列の指定範囲の要素を削除・置換・追加 するための強力な組み込み関数です。

array_splice(配列, 削除・置換を開始する位置(負の値なら末尾からの位置), 削除する要素の数, 削除した部分を置き換える配列): array

例文1
指定範囲の削除

$fruits = ["apple", "banana", "orange", "grape"];
$removed = array_splice($fruits, 1, 2); // インデックス1から2個削除

print_r($fruits);   // 残りの配列
print_r($removed);  // 削除された要素

結果

Array
(
    [0] => apple
    [1] => grape
)
Array
(
    [0] => banana
    [1] => orange
)

例文2
削除しつつ置換

$fruits = ["apple", "banana", "orange"];
array_splice($fruits, 1, 1, ["grape", "melon"]); // インデックス1を置換

print_r($fruits);

結果

Array
(
    [0] => apple
    [1] => grape
    [2] => melon
    [3] => orange
)

例文3
挿入のみ

$fruits = ["apple", "banana"];
array_splice($fruits, 1, 0, ["grape"]); // インデックス1に追加

print_r($fruits);

結果

Array
(
    [0] => apple
    [1] => grape
    [2] => banana
)
1-2-10. 配列の一部を切り出して新しい配列を返す

array_slice() 関数 は、配列の一部を切り出して新しい配列を返す関数です。

array_slice(配列, 切り出し開始位置(負の値なら末尾からの位置), 切り出す要素数, true にすると元のキーを保持(デフォルトは false)): array

例文1

$fruits = ["apple", "banana", "orange", "grape"];
$slice = array_slice($fruits, 1, 2); // インデックス1から2個切り出し

print_r($slice);

結果

Array
(
    [0] => banana
    [1] => orange
)

例文2
キーを保持

$fruits = ["a" => "apple", "b" => "banana", "c" => "orange"];
$slice = array_slice($fruits, 1, 2, true);

print_r($slice);

結果

Array
(
    [b] => banana
    [c] => orange
)

例文3
末尾から切り出し

$fruits = ["apple", "banana", "orange", "grape"];
$slice = array_slice($fruits, -2);

print_r($slice);

結果

Array
(
    [0] => orange
    [1] => grape
)
1-2-11. 配列の内容を検索

array_search() 関数 は、配列の中から指定した値を検索し、そのキーを返すための関数です。
見つからなかった場合は、 falseが返されます。

array_search(検索したい値, 配列, 厳密比較をするか(デフォルト false)): int|string|false

例文

$fruits = ["apple", "banana", "orange"];
$key = array_search("banana", $fruits);

echo $key; // 1
1-2-12. 配列に特定の要素が存在するか確認

in_array() 関数 は、配列の中に指定した値が存在するかどうかを調べるための関数です。

in_array(検索したい値, 配列, 厳密比較をするか(デフォルト false)): bool

例文

$fruits = ["apple", "banana", "orange"];
if (in_array("banana", $fruits)) {
    echo "見つかりました";
}

in_array関数 と array_search関数 の違い

項目in_array()array_search()
目的配列に値が存在するかを確認配列に値が存在するか確認し、キーを取得
戻り値true / false見つかった場合 → キー(数値または文字列)、見つからなければ false
キー情報取得できない取得できる
型チェック$strict = true で型もチェック$strict = true で型もチェック
使用例存在確認だけでよい場合存在確認 + キーが必要な場合
1-2-13. 配列の要素を並べ替える

sort() 関数 は、配列の要素を昇順に並べ替える(ソートする) 組み込み関数です。

sort(配列, ソート方法の指定(省略可、デフォルト SORT_REGULAR)): bool

ソート方法の指定

定数説明
SORT_REGULAR標準的な比較(デフォルト)
SORT_NUMERIC数値として比較
SORT_STRING文字列として比較
SORT_LOCALE_STRINGロケール設定に基づく文字列比較
SORT_NATURAL人間が見た自然順序で比較
SORT_FLAG_CASE大文字小文字を無視(SORT_STRING と併用)

例文

$numbers = [4, 2, 8, 1];
sort($numbers);
print_r($numbers);

結果

Array
(
    [0] => 1
    [1] => 2
    [2] => 4
    [3] => 8
)
1-2-14. ユーザー定義の比較関数を使って配列を並び替える

usort() 関数 は、ユーザー定義の比較関数を使って配列をソートするための関数です。

usort(配列, 比較用のコールバック関数): bool

コールバック関数のルール

比較する 2 つの値 $a$b を引数に取り、戻り値は 整数です。

  • < 0$a$b より前
  • 0 → 並び順は変わらない
  • > 0$a$b より後

例文1
数値を昇順でソート

$numbers = [4, 2, 8, 1];

usort($numbers, function($a, $b) {
    return $a - $b; // 昇順
});

print_r($numbers);

結果

Array
(
    [0] => 1
    [1] => 2
    [2] => 4
    [3] => 8
)

例文2
文字列の長さでソート

$words = ["apple", "banana", "kiwi", "orange"];

usort($words, function($a, $b) {
    return strlen($a) - strlen($b); // 文字数昇順
});

print_r($words);

結果

Array
(
    [0] => kiwi
    [1] => apple
    [2] => banana
    [3] => orange
)
1-2-15. 配列の内容を順に処理する

array_walk() 関数 は、配列の各要素に対してユーザー定義の関数を適用するための関数です。

array_walk(配列, 各要素に適用するコールバック関数, コールバック関数に渡す追加データ): bool

例文

$fruits = ["apple", "banana", "orange"];

array_walk($fruits, function(&$value, $key) {
    $value = strtoupper($value);
});

print_r($fruits);

結果

Array
(
    [0] => APPLE
    [1] => BANANA
    [2] => ORANGE
)
1-2-16. 配列内の要素を加工する

array_map() 関数 は、配列の各要素にユーザー定義の関数を適用し、新しい配列を返す関数です。

array_map(各要素に適用する関数, 配列, 複数の配列も渡せる): array

例文
各要素を2倍にする

$numbers = [1, 2, 3, 4];

$newNumbers = array_map(function($n) {
    return $n * 2;
}, $numbers);

print_r($newNumbers);

結果

Array
(
    [0] => 2
    [1] => 4
    [2] => 6
    [3] => 8
)
1-2-17. 配列の内容を特定の条件で絞り込む

array_filter() 関数 は、配列の要素を条件に応じてフィルター(抽出)する関数です。

array_filter(配列, 各要素を評価する関数, コールバックに渡す値の指定): array

コールバックに渡す値の指定

設定値概要
ARRAY_FILTER_USE_KEYキーを引数として渡す(値は渡さない)
ARRAY_FILTER_USE_BOTHキーと値を渡す

例文

$numbers = [0, 1, 2, 3, false, null];

$result = array_filter($numbers);

print_r($result);

結果

Array
(
    [1] => 1
    [2] => 2
    [3] => 3
)
1-2-18. 配列内の要素を順に処理して1つにまとめる

array_reduce() 関数 は、配列の全要素を順番に処理して、1つの値にまとめる(畳み込み・集約) 関数です。

array_reduce(配列, 配列の要素を順に処理する関数, 初期値(省略可): mixed

例文

$numbers = [1, 2, 3, 4];

$sum = array_reduce($numbers, function($carry, $item) {
    return $carry + $item;
}, 0);

echo $sum; // 10

1-3. 正規表現関数

正規表現とは、文字列のパターンを表す特殊な文字列です。PHP の正規表現関数は 文字列に対してパターンマッチングや置換、分割などを行うことができます。

1-3-1. 正規表現で文字列を検索する

preg_match() 関数 は、文字列が正規表現にマッチするかどうかを調べるための関数です。

preg_match(正規表現パターン, 検索対象の文字列, マッチした部分を格納する配列, マッチ結果の取得方法, 検索開始位置): int|false

戻り値

  • マッチした場合 → 1
  • マッチしなかった場合 → 0
  • エラー → false

例文

$str = "Hello123";
if (preg_match("/[0-9]+/", $str, $matches)) {
    echo "数字が含まれています: " . $matches[0];
}

結果

数字が含まれています: 123
1-3-2. 全てのマッチ文字列を取得する

preg_match_all() 関数 は、文字列中の正規表現にマッチするすべての部分を取得するための関数です。
preg_match()最初の1つのマッチ しか取得できないのに対して、こちらは 全てのマッチ を配列で取得できます。

preg_match_all(正規表現パターン, 検索対象の文字列, マッチした結果を格納する配列, 結果の格納方法, 検索開始位置): int|false

戻り値

  • マッチした数(整数)
  • エラー → false

例文1
数字をすべて抽出

$str = "電話番号は080-1234-5678、緊急番号は110です";
preg_match_all("/\d+/", $str, $matches);

print_r($matches[0]);

結果

Array
(
    [0] => 080
    [1] => 1234
    [2] => 5678
    [3] => 110
)

例文2
英単語をすべて取得

$str = "I love PHP and JavaScript";
preg_match_all("/[a-zA-Z]+/", $str, $matches);

print_r($matches[0]);

結果

Array
(
    [0] => I
    [1] => love
    [2] => PHP
    [3] => and
    [4] => JavaScript
)
1-3-3. 正規表現で文字列を置換する

preg_replace() 関数 は、正規表現にマッチした文字列を別の文字列に置換するための関数です。

preg_replace(検索する正規表現パターン, 置換後の文字列, 置換対象の文字列または配列, 置換する回数(省略時は -1 で全て置換), 実際に置換された回数が入る): mixed

例文

$str = "I like banana and orange.";
$newStr = preg_replace("/banana/", "apple", $str);

echo $newStr;

結果

I like apple and orange.
1-3-4. 正規表現で置換したものをコールバック関数で処理する

preg_replace_callback() 関数 は、正規表現にマッチした部分を、コールバック関数の処理結果で置換するための関数です。
preg_replace() が固定文字列や配列で置換するのに対して、こちらは マッチ内容に応じて柔軟に置換文字列を生成できます。

preg_replace_callback(検索する正規表現パターン, マッチごとに呼ばれるコールバック関数, 置換対象の文字列または配列, 置換の最大回数, 実際に置換された回数を取得できる): string|array|null

例文

$str = "値は10と20です";

$newStr = preg_replace_callback("/\d+/", function($matches) {
    return $matches[0] * 2;
}, $str);

echo $newStr;

結果

値は20と40です
1-3-5. 正規表現で文字列を分割する

preg_split() 関数 は、
正規表現にマッチした部分で文字列を分割し、配列として返す関数です。

preg_split(区切りとして使う正規表現パターン, 分割対象の文字列, 分割する最大数, 分割の方法を指定): array|false

例文
カンマで分割

$str = "apple,banana,orange";
$result = preg_split("/,/", $str);

print_r($result);

結果

Array
(
    [0] => apple
    [1] => banana
    [2] => orange
)

1-4. ファイルシステム関数

1-4-1. ファイルを開く
1-4-1-1. fopen() 関数

fopen() 関数 は、ファイルを開く(または新規作成する)ための基本関数です。
開いたファイルは ファイルポインタ(リソース) として返され、その後 fread()fwrite() などでファイル操作ができます。
ファイル操作の後は 必ず fclose() で閉じます

fopen(開くファイル名(パス指定可), ファイルを開くモード, include_path も検索するか, ストリームコンテキスト): resource|false

ファイルを開くモード

モード説明
'r'読み込み専用、ファイルが存在しない場合は失敗
'r+'読み書き両方、ファイルが存在しない場合は失敗
'w'書き込み専用、存在する場合は上書き、なければ作成
'w+'読み書き両方、上書き、なければ作成
'a'追記専用、末尾に書き込み、なければ作成
'a+'読み書き両方、末尾に追記、なければ作成
'x'新規作成、既存ファイルがある場合は失敗
'x+'読み書き両方、新規作成のみ
'b'バイナリモード(Windowsで必要な場合)
't'テキストモード(Windowsデフォルト)

※モードは組み合わせて使用可能。例: 'rb' → バイナリ読み込み

例文1
ファイルを読み込む

$fp = fopen("sample.txt", "r");
if ($fp) {
    while (($line = fgets($fp)) !== false) {
        echo $line;
    }
    fclose($fp);
} else {
    echo "ファイルを開けませんでした";
}

例文2
ファイルに書き込む

$fp = fopen("sample.txt", "w");
if ($fp) {
    fwrite($fp, "Hello, World!\n");
    fclose($fp);
}

例文3
ファイルに追記

$fp = fopen("sample.txt", "a");
if ($fp) {
    fwrite($fp, "追記します\n");
    fclose($fp);
}
1-4-2. ファイルを閉じる

fclose() 関数は、開いたファイルポインタを閉じるための関数です。
PHPはスクリプト終了時に自動でファイルを閉じますが、明示的に fclose() を呼ぶことが推奨されます。

fclose() を忘れると、ファイルがロックされたままになる場合や、メモリ使用量が増える原因になります。

fclose(開いたファイルポインタ): bool

例文

$fp = fopen("sample.txt", "r");
if ($fp) {
    $content = fread($fp, filesize("sample.txt"));
    echo $content;

    // ファイルを閉じる
    fclose($fp);
} else {
    echo "ファイルを開けませんでした。";
}
1-4-3. データの読み込み
1-4-3-1. 指定したバイト数だけデータを読み込む

fread() 関数 は、開いたファイルから指定したバイト数だけデータを読み込むための関数です。
部分的に読み込みたい場合やストリーム処理には fread() が適しています。

fread(fopen() で取得したファイルポインタ, 読み込むバイト数): string|false

例文1
ファイルを一部読み込む

$fp = fopen("sample.txt", "r");
if ($fp) {
    $content = fread($fp, 10); // 先頭10バイトを読み込む
    echo $content;
    fclose($fp);
}

例文2
ファイル全体を読み込む

$fp = fopen("sample.txt", "r");
if ($fp) {
    $filesize = filesize("sample.txt"); // ファイルサイズを取得
    $content = fread($fp, $filesize);   // ファイル全体を読み込む
    echo $content;
    fclose($fp);
}
1-4-3-2. 1行分のデータを読み込み

fgets() 関数は、ファイルポインタから1行分の文字列を読み込む 関数です。
改行文字 \n も含めて返します(ただし末尾の改行を削除する場合は trim() を使う)。
ファイルの終端(EOF)に達すると false を返します。

string fgets(開いたファイルポインタ, 読み込む最大バイト数。省略すると改行が出るまで読み込みます。)

例文

<?php
$fp = fopen("test.txt", "r");

if ($fp) {
    while (($line = fgets($fp)) !== false) {
        echo "読み込み: " . $line;
    }
    fclose($fp);
}
1-4-3-3. 指定されたファイルをまとめて読み込み

file() 関数 は、ファイル全体を1行ごとに配列として読み込む 関数です。

file(読み込むファイルのパス, 動作を制御するフラグ, ストリームコンテキスト): array

動作を制御するフラグ

フラグ名意味
FILE_USE_INCLUDE_PATH$filenameinclude_path からも探す(php.iniinclude_path設定やset_include_path()で設定されたパス)
FILE_IGNORE_NEW_LINES各行の最後の 改行コード(\n など)を除去 して配列に格納
FILE_SKIP_EMPTY_LINES空行をスキップ(配列に入れない)

例文
テキストファイルを配列として読み込む

<?php
$lines = file("test.txt");

foreach ($lines as $line) {
    echo $line;
}
1-4-3-4. 定型フォーマットテキストの読み込み

fgetcsv() 関数とは、PHPで CSVファイルを1行ずつ読み込み、配列として取得する 関数です。
カンマ区切りやタブ区切りなどのテキストデータを扱うときに便利です。

fgetcsv(
    resource $stream,
    int $length = 0,
    string $separator = ",",
    string $enclosure = '"',
    string $escape = "\\"
): array|false

引数

引数説明省略時の値
$streamfopen() などで開いたファイルポインタ必須
$length読み込む最大バイト数(0だと制限なし)0
$separator区切り文字(通常は,","
$enclosure項目を囲む文字(通常は"'"'
$escapeエスケープ文字"\"

例文

<?php
$fp = fopen("sample.csv", "r");

while (($data = fgetcsv($fp)) !== false) {
    // $data は1行分の配列
    print_r($data);
}

fclose($fp);
?>
1-4-3-5. file_get_contents() 関数

file_get_contents() 関数 は、指定したファイルや URL の内容をまるごと文字列として取得する便利な関数です。
fopen() + fread() のようにファイルポインタを操作する必要がなく、簡単にファイル全体を読み込むことができます。

file_get_contents(読み込むファイル名や URL, include_path も検索するか, ストリームコンテキスト, 読み込み開始位置(バイト単位), 読み込む長さ(バイト単位)): string|false

例文1
ファイル全体を読み込む

$content = file_get_contents("sample.txt");
if ($content !== false) {
    echo $content;
} else {
    echo "ファイルを読み込めませんでした";
}

例文2
一部分だけ読み込む

$content = file_get_contents("sample.txt", false, null, 0, 10);
echo $content; // 先頭10バイトだけ取得

例文3
URL の内容を取得

$content = file_get_contents("https://example.com");
echo $content; // WebページのHTMLを文字列として取得


1-4-4. ファイルへの書き込み
1-4-4-1. 開いたファイルにデータを書き込む

fwrite() 関数は、開いたファイルにデータを書き込むための関数です。
fopen() で取得したファイルポインタを使って、文字列をファイルに書き出します。

fwrite(開いたファイルポインタ, 書き込む文字列, 書き込む最大バイト数。省略すると文字列全体を書き込み): int|false

例文

$fp = fopen("sample.txt", "w"); // 書き込みモードで開く
if ($fp) {
    $text = "Hello, World!\n";
    fwrite($fp, $text);
    fclose($fp);
    echo "書き込み完了!";
} else {
    echo "ファイルを開けませんでした。";
}
1-4-4-2. file_put_contents関数

file_put_contents() 関数 は、文字列や配列の内容をファイルに書き込むための関数です。
fopen() + fwrite() のようにファイルポインタを操作する必要がなく、簡単にファイルにデータを書き込むことができます。

file_put_contents(書き込むファイル名, 書き込む文字列または配列, 書き込みモード): int|false
  • デフォルトでは 既存ファイルを上書き
  • 追記する場合は FILE_APPEND を指定

例文1
ファイルに書き込む(上書き)

$data = "Hello, World!\n";
$result = file_put_contents("sample.txt", $data);

if ($result !== false) {
    echo "書き込み成功: $result バイト";
} else {
    echo "書き込み失敗";
}

例文2
ファイルに追記

$data = "追記します\n";
file_put_contents("sample.txt", $data, FILE_APPEND);
1-4-5. ファイルをロックする

flock() 関数は、ファイルに対して 排他制御(ロック) を行うための関数です。
複数のプロセスやユーザーが同時に同じファイルへアクセスするときの競合を防ぎます。

flock(開いたファイルポインタ, ロックモードの種類, ロックできなかった場合に 1 が入るようにするか): bool

ロックモードの種類

定数意味
LOCK_SH共有ロック(読み込み用)他の共有ロックは許可されるが、排他ロックは不可
LOCK_EX排他ロック(書き込み用)他の共有・排他ロックをすべてブロック
LOCK_UNロック解除
LOCK_NB非ブロッキングモードロックが取れない場合、待たずにすぐ戻る

例文

$fp = fopen("data.txt", "a");

if (flock($fp, LOCK_EX)) { // 排他ロックを取得
    fwrite($fp, "ログの書き込み: " . date("Y-m-d H:i:s") . "\n");
    flock($fp, LOCK_UN); // ロック解除
} else {
    echo "ロックできませんでした";
}

fclose($fp);

1-5. 数学関数

PHP の 数学関数 は、数値の計算や処理を簡単に行うための組み込み関数群です。
四則演算以外にも、絶対値や切り上げ・切り捨て、乱数生成など様々な関数があります。

主な数学関数一覧

関数説明
abs($value)絶対値を返す
ceil($value)小数点を切り上げて整数にする
floor($value)小数点を切り捨てて整数にする
round($value, $precision = 0)四捨五入(小数点指定可)
max($val1, $val2, ...)最大値を返す
min($val1, $val2, ...)最小値を返す
pow($base, $exp)累乗($base^$exp)を計算
sqrt($value)平方根を返す
rand($min, $max) / mt_rand($min, $max)ランダムな整数を返す
pi()円周率 π を返す
sin($angle) / cos($angle) / tan($angle)三角関数(ラジアン単位)
deg2rad($deg) / rad2deg($rad)度 ↔ ラジアン変換

例文1
絶対値

echo abs(-10); // 10

例文2
切り上げ・切り捨て・四捨五入

$num = 3.7;

echo ceil($num);  // 4
echo floor($num); // 3
echo round($num); // 4

例文3
平方根・累乗

echo sqrt(16);   // 4
echo pow(2, 3);  // 8

例文4
最大値・最小値

echo max(5, 9, 2); // 9
echo min(5, 9, 2); // 2

例文5
ランダム値

echo rand(1, 100);     // 1〜100のランダム整数
echo mt_rand(1, 100);  // 高速なランダム整数

例文6
三角関数

$rad = deg2rad(90); // 度→ラジアン
echo sin($rad);      // 1