【PHP8.x】is_a関数の使い方

作成日: 更新日:

is_a関数は、指定されたオブジェクトが特定のクラスまたはその親クラスのインスタンスであるか、あるいは指定されたインターフェースを実装しているかを判定する関数です。

この関数は二つの主要な引数を受け取ります。第一引数には検査したいオブジェクト、またはクラス名を文字列で指定します。第二引数には、比較対象となるクラス名またはインターフェース名を文字列で指定します。オプションの第三引数にtrueを設定することで、第二引数で指定したクラスのオートロードを試みることが可能です。

判定の結果は真偽値(trueまたはfalse)で返されます。is_a関数はinstanceof演算子と似た機能を提供しますが、クラス名を文字列で動的に指定できる点が特徴です。これにより、実行時にオブジェクトの型を柔軟に確認したり、特定のインターフェースを実装しているかを判定したりできます。プログラムの多態性を活用し、堅牢で柔軟なコードを記述する際に有用な関数です。

基本的な使い方

構文(syntax)

is_a(new stdClass(), 'stdClass');

引数(parameters)

object|string $object_or_class, string $class, bool $allow_string = false

  • object|string $object_or_class: クラスをチェックしたいオブジェクト、またはクラス名(文字列)
  • string $class: 判定対象のクラス名(文字列)
  • bool $allow_string = false: trueを指定すると、$object_or_class が文字列の場合でも、その文字列が有効なクラス名であれば true を返します。デフォルトは false です。

戻り値(return)

bool

指定された変数やオブジェクトが、指定されたクラスのインスタンスであるか、またはそのクラスを継承している場合に true を返します。それ以外の場合は false を返します。

サンプルコード

PHP is_a() でオブジェクトの型をチェックする

<?php

// 親クラスを定義します。
class Vehicle
{
    // クラスの存在を示すための簡単なメソッドです。
    public function move(): string
    {
        return "The vehicle moves.";
    }
}

// Vehicleクラスを継承する子クラスを定義します。
class Car extends Vehicle
{
    public function honk(): string
    {
        return "Car honks!";
    }
}

// インターフェースを定義します。
interface Drivable
{
    public function start(): string;
}

// Drivableインターフェースを実装するクラスを定義します。
class Truck implements Drivable
{
    public function start(): string
    {
        return "Truck engine starts.";
    }
}

// 様々な型の変数を準備します。
$myCar = new Car();
$myTruck = new Truck();
$myVehicle = new Vehicle();
$someString = "Hello PHP";
$someArray = [1, 2, 3]; // キーワード'is_array'に関連付けるための配列

// is_a() 関数を使ったオブジェクトの型チェックの例
// オブジェクトが特定のクラスのインスタンスであるかチェックします。
echo "Is \$myCar an instance of Car? " . (is_a($myCar, 'Car') ? 'Yes' : 'No') . PHP_EOL;

// オブジェクトが親クラスのインスタンスであるかチェックします(継承関係があるため true)。
echo "Is \$myCar an instance of Vehicle (parent class)? " . (is_a($myCar, 'Vehicle') ? 'Yes' : 'No') . PHP_EOL;

// オブジェクトが特定のインターフェースを実装しているかチェックします。
echo "Is \$myTruck an instance of Drivable (interface)? " . (is_a($myTruck, 'Drivable') ? 'Yes' : 'No') . PHP_EOL;

// オブジェクトが異なるクラスのインスタンスであるかチェックします。
echo "Is \$myVehicle an instance of Car? " . (is_a($myVehicle, 'Car') ? 'Yes' : 'No') . PHP_EOL;

// is_a() 関数の第3引数 ($allow_string = true) を使ったクラス名の階層チェックの例
// クラス名文字列が別のクラスの子孫であるかチェックします。
echo "Is 'Car' a descendant of 'Vehicle'? " . (is_a('Car', 'Vehicle', true) ? 'Yes' : 'No') . PHP_EOL;

// クラス名文字列がインターフェースを実装しているかチェックします。
echo "Is 'Truck' a descendant of 'Drivable'? " . (is_a('Truck', 'Drivable', true) ? 'Yes' : 'No') . PHP_EOL;

// is_a() 関数と is_array() 関数の違い
// is_a() はオブジェクトやクラスの階層チェックに使用され、配列のチェックには適していません。
echo "Is \$someArray an instance of 'array' using is_a()? " . (is_a($someArray, 'array') ? 'Yes' : 'No') . PHP_EOL; // 結果は 'No'

// 配列のチェックには is_array() 関数を使用するのが適切です。
echo "Is \$someArray an array using is_array()? " . (is_array($someArray) ? 'Yes' : 'No') . PHP_EOL; // 結果は 'Yes'

// is_a() は文字列のようなプリミティブ型の直接的なチェックには使用しません。
echo "Is \$someString an instance of 'string' using is_a()? " . (is_a($someString, 'string') ? 'Yes' : 'No') . PHP_EOL; // 結果は 'No'

// 文字列のチェックには is_string() 関数を使用するのが適切です。
echo "Is \$someString a string using is_string()? " . (is_string($someString) ? 'Yes' : 'No') . PHP_EOL; // 結果は 'Yes'

PHPのis_a関数は、指定したオブジェクトが特定のクラスのインスタンスであるか、または特定のインターフェースを実装しているかをチェックするために使用します。この関数は、チェック結果を真偽値(trueまたはfalse)で返します。

第1引数にはチェックしたい「オブジェクト」または「クラス名を表す文字列」を、第2引数には比較対象となる「クラス名またはインターフェース名を表す文字列」を指定します。例えば、is_a($myCar, 'Car')と記述すると、$myCarがCarクラスのインスタンスであればtrueが返されます。

is_a関数は、継承関係やインターフェースの実装も考慮します。親クラスであるVehicleを継承したCarクラスのインスタンスである$myCarに対してis_a($myCar, 'Vehicle')とすると、trueを返します。インターフェースについても同様で、Drivableインターフェースを実装したTruckクラスのインスタンス$myTruckに対してis_a($myTruck, 'Drivable')とするとtrueとなります。

第3引数$allow_stringtrueに設定すると、第1引数に「クラス名を表す文字列」を指定して、そのクラスが第2引数で指定されたクラスやインターフェースの子孫であるかをチェックできます。

ただし、is_a関数はオブジェクトやクラスの階層チェックに特化しており、配列や文字列といったプリミティブ型の変数の型チェックには適していません。配列の型をチェックしたい場合はis_array()関数を、文字列の場合はis_string()関数を使用するのが適切です。

PHPのis_a関数は、指定した変数が特定のクラスのインスタンスであるか、あるいは特定のインターフェースを実装しているかをチェックするために利用します。継承関係も考慮され、子クラスのインスタンスは親クラスのインスタンスであると判定されます。第3引数をtrueにすると、オブジェクトではなくクラス名文字列自体が別のクラスの子孫であるか、インターフェースを実装しているかを比較できます。

特に重要な注意点は、is_a関数が配列や文字列のようなプリミティブ型のチェックには適さないことです。例えばis_a($someArray, 'array')falseを返します。配列のチェックにはis_array()、文字列のチェックにはis_string()といった、各型専用の関数を適切に使い分けてください。これにより、意図しない誤動作を防ぎ、コードの信頼性を向上させることができます。

PHP is_a 関数でクラス継承を判定する

<?php

// 親クラスを定義します
class Animal
{
    public function speak(): string
    {
        return "Generic animal sound.";
    }
}

// Animalを継承する子クラスを定義します
class Dog extends Animal
{
    public function speak(): string
    {
        return "Woof!";
    }
}

// Animalを継承しない別のクラスを定義します
class Cat
{
    public function speak(): string
    {
        return "Meow!";
    }
}

/**
 * is_a関数の使い方をオブジェクトインスタンスで示す関数
 *
 * @param object|null $instance  チェックするオブジェクトインスタンス
 * @param string      $className 比較対象のクラス名
 * @return void
 */
function demonstrateIsAWithObject(?object $instance, string $className): void
{
    echo "--- is_a(\$instance, '{$className}') のテスト ---\n";

    // is_a関数の第一引数にはオブジェクトか文字列が必要です。
    // nullを直接渡すとTypeErrorが発生するため、事前にチェックします。
    if ($instance === null) {
        echo "  インスタンスはnullです。is_a関数はオブジェクトを期待します。\n";
        echo "  結果: false (is_aは呼び出されません)\n";
        return;
    }

    // オブジェクトが特定のクラスのインスタンスであるか、またはその子孫であるかをチェックします。
    // instanceof 演算子と同様の働きをしますが、is_aはクラス名を文字列で指定できます。
    if (is_a($instance, $className)) {
        echo "  " . get_class($instance) . " は '{$className}' のインスタンス、またはその子孫です。\n";
        echo "  結果: true\n";
    } else {
        echo "  " . get_class($instance) . " は '{$className}' のインスタンス、またはその子孫ではありません。\n";
        echo "  結果: false\n";
    }
}

/**
 * is_a関数の使い方をクラス名文字列で示す関数
 *
 * @param string $objectOrClassName チェックするクラス名文字列
 * @param string $className         比較対象のクラス名
 * @return void
 */
function demonstrateIsAWithString(string $objectOrClassName, string $className): void
{
    echo "--- is_a('{$objectOrClassName}', '{$className}', true) のテスト ---\n";

    // 第3引数に true を設定することで、第一引数にクラス名文字列を渡して比較できます。
    // '{$objectOrClassName}' が '{$className}' の子孫であるか、または同じクラスであるかをチェックします。
    if (is_a($objectOrClassName, $className, true)) {
        echo "  '{$objectOrClassName}' は '{$className}' の子孫、または同じクラスです。\n";
        echo "  結果: true\n";
    } else {
        echo "  '{$objectOrClassName}' は '{$className}' の子孫、または同じクラスではありません。\n";
        echo "  結果: false\n";
    }
}

// ----------------------------------------------------
// is_a 関数の使用例の実行
// ----------------------------------------------------

// オブジェクトインスタンスを作成
$dog = new Dog();
$animal = new Animal();
$cat = new Cat();
$nullValue = null; // null値

echo "========== オブジェクトインスタンスでの is_a 使用例 ==========\n";

// Dogオブジェクトとクラス名の比較
demonstrateIsAWithObject($dog, 'Dog');
demonstrateIsAWithObject($dog, 'Animal'); // DogはAnimalを継承しているためtrue
demonstrateIsAWithObject($dog, 'Cat');

echo "\n";

// Animalオブジェクトとクラス名の比較
demonstrateIsAWithObject($animal, 'Animal');
demonstrateIsAWithObject($animal, 'Dog'); // AnimalはDogではないためfalse

echo "\n";

// Catオブジェクトとクラス名の比較
demonstrateIsAWithObject($cat, 'Cat');
demonstrateIsAWithObject($cat, 'Animal'); // CatはAnimalを継承していないためfalse

echo "\n";

// null値を渡した場合の例(is_aは呼び出されず、nullチェックで処理されます)
demonstrateIsAWithObject($nullValue, 'Animal');

echo "\n========== クラス名文字列での is_a 使用例 (allow_string = true) ==========\n";

// クラス名文字列とクラス名の比較
demonstrateIsAWithString('Dog', 'Dog');
demonstrateIsAWithString('Dog', 'Animal'); // 'Dog'クラスは'Animal'クラスの子孫であるためtrue
demonstrateIsAWithString('Dog', 'Cat');

echo "\n";

demonstrateIsAWithString('Animal', 'Animal');
demonstrateIsAWithString('Animal', 'Dog'); // 'Animal'クラスは'Dog'クラスの子孫ではないためfalse

echo "\n";

demonstrateIsAWithString('Cat', 'Cat');
demonstrateIsAWithString('Cat', 'Animal'); // 'Cat'クラスは'Animal'クラスの子孫ではないためfalse

PHPのis_a関数は、特定のオブジェクトがあるクラスのインスタンスであるか、またはその子孫であるかを判定するために使用します。この関数は、instanceof演算子と似ていますが、比較対象のクラス名を文字列で指定できる点が特徴です。

引数は三つあります。一つ目の$object_or_classには、チェックしたいオブジェクトインスタンス、またはクラス名を表す文字列を渡します。二つ目の$classには、比較対象となるクラス名を文字列で指定します。三つ目の$allow_stringはオプションで、デフォルトはfalseです。これをtrueにすると、一つ目の引数にオブジェクトではなくクラス名を表す文字列を渡して比較できるようになります。戻り値は真偽値(bool)で、条件に合致すればtrueを、そうでなければfalseを返します。

サンプルコードでは、Animalクラス、それを継承するDogクラス、そして独立したCatクラスを定義しています。demonstrateIsAWithObject関数では、is_aの第一引数に実際のオブジェクトインスタンスを渡して、そのオブジェクトが指定されたクラスのインスタンスか、またはその子孫であるかをチェックします。例えば、DogオブジェクトはAnimalを継承しているので、is_a($dog, 'Animal')trueとなります。nullを直接is_a関数に渡すとエラーになるため、事前にチェックする処理も含まれています。

一方、demonstrateIsAWithString関数では、is_aの第三引数をtrueに設定し、第一引数に'Dog'のようなクラス名文字列を渡して比較しています。これにより、クラス名文字列同士で継承関係を判定することが可能です。例えば、'Dog'クラスは'Animal'クラスの子孫であるため、is_a('Dog', 'Animal', true)trueを返します。このようにis_a関数を使うことで、オブジェクトやクラス間の継承関係を柔軟に確認することができます。

PHPのis_a関数は、オブジェクトが特定のクラスのインスタンスか、その子孫かを判定します。第一引数にオブジェクトを渡す際、nullを直接指定するとTypeErrorが発生するため、事前にnullチェックが必要です。第二引数には比較対象のクラス名を文字列で渡します。第一引数にクラス名文字列を渡し、その継承関係をチェックしたい場合は、必ず第三引数にtrueを指定してください。これを忘れると正しく判定されません。is_ainstanceof演算子に似ていますが、クラス名を文字列で指定できる点が特徴です。動的にクラスを判定したい場合に特に役立ちます。

PHP is_a() でオブジェクトとクラスの関連性を調べる

<?php

/**
 * 商品情報を扱うクラスを定義します。
 */
class Product
{
    public string $name;
    public float $price;
    public array $details; // 商品の詳細情報を連想配列で保持するプロパティ

    /**
     * Product クラスのコンストラクタ。
     *
     * @param string $name 商品名
     * @param float $price 価格
     * @param array $details 連想配列形式の商品詳細
     */
    public function __construct(string $name, float $price, array $details)
    {
        $this->name = $name;
        $this->price = $price;
        $this->details = $details;
    }

    /**
     * 商品の詳細情報を取得します。
     *
     * @return array 連想配列形式の商品詳細
     */
    public function getDetails(): array
    {
        return $this->details;
    }
}

/**
 * Product クラスを継承するデジタル商品クラスを定義します。
 */
class DigitalProduct extends Product
{
    public string $licenseKey;

    /**
     * DigitalProduct クラスのコンストラクタ。
     *
     * @param string $name 商品名
     * @param float $price 価格
     * @param array $details 連想配列形式の商品詳細
     * @param string $licenseKey ライセンスキー
     */
    public function __construct(string $name, float $price, array $details, string $licenseKey)
    {
        parent::__construct($name, $price, $details);
        $this->licenseKey = $licenseKey;
    }
}

// サンプルオブジェクトの作成
$physicalProduct = new Product(
    '高性能マウス',
    49.99,
    [
        'manufacturer' => 'XYZ Tech',
        'weight_g' => 120,
        'color' => 'Black'
    ]
);

$digitalDownload = new DigitalProduct(
    'eBook: PHP入門',
    29.99,
    [
        'format' => 'PDF',
        'pages' => 300
    ],
    'PHP-GUIDE-12345'
);

echo "--- is_a() 関数の使用例 ---" . PHP_EOL;

// 1. オブジェクトが特定のクラスのインスタンスであるかをチェック
// $physicalProduct は Product クラスのインスタンスです
if (is_a($physicalProduct, 'Product')) {
    echo "1. \$physicalProduct は 'Product' クラスのインスタンスです。" . PHP_EOL;
}

// 2. 継承関係もチェックされます
// $digitalDownload は DigitalProduct クラスのインスタンスですが、Product クラスも継承しています
if (is_a($digitalDownload, 'Product')) {
    echo "2. \$digitalDownload は 'Product' クラスを継承しているため、'Product' のインスタンスと見なされます。" . PHP_EOL;
}

// 3. 自身のクラスであるかをチェック
if (is_a($digitalDownload, 'DigitalProduct')) {
    echo "3. \$digitalDownload は 'DigitalProduct' クラスのインスタンスです。" . PHP_EOL;
}

// 4. 存在しないクラス名を指定した場合 (false が返る)
if (!is_a($physicalProduct, 'NonExistentClass')) {
    echo "4. \$physicalProduct は 'NonExistentClass' クラスのインスタンスではありません。" . PHP_EOL;
}

echo PHP_EOL . "--- is_a() でクラス名文字列をチェックする例 (\$allow_string = true) ---" . PHP_EOL;

// 5. 第一引数にクラス名を文字列で渡し、$allow_string を true に設定
// 'Product' という文字列が 'Product' クラスと同一であるかをチェック
if (is_a('Product', 'Product', true)) {
    echo "5. 'Product' という文字列は 'Product' クラスを参照します。" . PHP_EOL;
}

// 6. クラス名文字列が指定されたクラスを継承しているかをチェック
// 'DigitalProduct' クラスは 'Product' クラスを継承しています
if (is_a('DigitalProduct', 'Product', true)) {
    echo "6. 'DigitalProduct' という文字列は 'Product' クラスを継承しているため、'Product' と見なされます。" . PHP_EOL;
}

echo PHP_EOL . "--- キーワード 'is_array' と '連想配列' の関連付け ---" . PHP_EOL;

// 7. Product クラスのプロパティとして連想配列を扱い、is_array() で確認
$productDetails = $physicalProduct->getDetails(); // getDetails() は連想配列を返す
if (is_array($productDetails)) {
    echo "7. \$physicalProduct の 'details' プロパティ(取得した情報)は連想配列です。" . PHP_EOL;
    echo "   詳細情報: " . json_encode($productDetails, JSON_UNESCAPED_UNICODE) . PHP_EOL;
}

// 8. デジタル商品の詳細情報も同様に確認
$digitalDetails = $digitalDownload->getDetails();
if (is_array($digitalDetails)) {
    echo "8. \$digitalDownload の 'details' プロパティ(取得した情報)も連想配列です。" . PHP_EOL;
    echo "   詳細情報: " . json_encode($digitalDetails, JSON_UNESCAPED_UNICODE) . PHP_EOL;
}

is_a関数は、指定したオブジェクトが特定のクラスのインスタンスであるか、あるいはそのクラスを継承しているかを判定する際に利用されます。第一引数には検証したいオブジェクト、第二引数には比較対象のクラス名を文字列で指定します。もし第三引数$allow_stringtrueにすると、第一引数にオブジェクトではなくクラス名の文字列を渡して、クラス間の継承関係をチェックすることも可能です。この関数は判定結果を真偽値(trueまたはfalse)で返します。

サンプルコードでは、Productクラスとその子クラスであるDigitalProductのインスタンスを用いてis_a関数の挙動を具体的に示しています。例えば、DigitalProductのインスタンスは、自身のクラスだけでなく、継承元であるProductクラスのインスタンスとしても正しく認識されることがわかります。また、$allow_stringtrueに設定した例では、オブジェクトを生成せずにクラス名文字列だけで継承関係を確認できることが示されています。

さらに、サンプルコードではPHPのis_array関数も登場します。この関数は、与えられた変数が配列であるかを判定するもので、特に連想配列のような構造を持つデータが期待通りに扱われているかを確認する際に役立ちます。Productクラスのdetailsプロパティは連想配列として定義されており、is_array関数を使ってそのデータ型が適切であるかを検証しています。これにより、プログラムの安全性を高めることができます。

is_a関数は、指定したオブジェクトが特定のクラスのインスタンスであるか、またはそのクラスを継承しているかを判定します。親クラスを指定した場合でも、子クラスのインスタンスはtrueと評価される点が重要です。また、第三引数$allow_stringtrueにすると、第一引数にオブジェクトではなくクラス名を示す文字列を渡して、クラス間の継承関係をチェックできます。一方、is_array関数は、数値添字配列と連想配列の両方を区別なく「配列」として認識し、trueを返します。PHPでは連想配列も通常の配列の一種として扱われるため、連想配列だけを特別に判定する機能ではないことに注意してください。

【PHP8.x】is_a関数の使い方 | いっしー@Webエンジニア