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

作成日: 更新日:

property_exists関数は、指定されたオブジェクトまたはクラスに指定されたプロパティが存在するかどうかを確認する関数です。この関数は、プロパティが定義されていてアクセス可能であるかどうかを判断するために使用されます。

具体的には、第一引数にオブジェクトまたはクラス名を文字列で指定し、第二引数に確認したいプロパティ名を文字列で指定します。オブジェクトが渡された場合、そのオブジェクトのプロパティの存在が確認されます。クラス名が渡された場合、そのクラスのプロパティの存在が確認されます。

戻り値は、プロパティが存在する場合に true、存在しない場合に false を返します。プロパティが存在しても、アクセス権がない(例えば、privateプロパティに外部からアクセスしようとした)場合は、true が返されます。存在の有無を確認することがこの関数の目的であるためです。

property_exists関数は、オブジェクト指向プログラミングにおいて、特定のオブジェクトやクラスが期待するプロパティを持っているかどうかを事前に確認し、エラーを回避するために役立ちます。例えば、外部から提供されたオブジェクトに対して処理を行う前に、必要なプロパティが存在するかどうかを検証することで、プログラムの安定性を高めることができます。また、クラスの設計段階で、特定のプロパティが存在するかどうかを条件によって変更する場合などにも利用できます。

基本的な使い方

構文(syntax)

property_exists(object|string $object_or_class, string $property): bool

引数(parameters)

object|string $object_or_class, string $property

  • object|string $object_or_class: プロパティの存在を確認したいオブジェクト、またはクラス名。
  • string $property: 確認したいプロパティの名前。

戻り値(return)

bool

指定されたプロパティがオブジェクトに存在するかどうかを示す真偽値を返します。プロパティが存在すれば true、存在しなければ false を返します。

サンプルコード

PHPのproperty_existsでプロパティ存在チェックする

<?php

/**
 * property_exists 関数のサンプルコード
 */

class MyClass {
    public $public_property = 'Public Value';
    protected $protected_property = 'Protected Value';
    private $private_property = 'Private Value';
    public static $static_property = 'Static Value';
}

// オブジェクトのプロパティ存在チェック
$obj = new MyClass();

// public プロパティの存在チェック
var_dump(property_exists($obj, 'public_property')); // bool(true)

// protected プロパティの存在チェック
var_dump(property_exists($obj, 'protected_property')); // bool(true)

// private プロパティの存在チェック
var_dump(property_exists($obj, 'private_property')); // bool(true)

// 存在しないプロパティの存在チェック
var_dump(property_exists($obj, 'non_existent_property')); // bool(false)

// static プロパティの存在チェック (オブジェクト経由)
var_dump(property_exists($obj, 'static_property')); // bool(true)

// クラス名のプロパティ存在チェック
var_dump(property_exists('MyClass', 'public_property')); // bool(true)

// static プロパティの存在チェック (クラス名経由)
var_dump(property_exists('MyClass', 'static_property')); // bool(true)
?>

property_exists関数は、指定したオブジェクトまたはクラスに、特定のプロパティが定義されているかどうかを確認するための関数です。

この関数は2つの引数を取ります。第1引数には、調査したいオブジェクトのインスタンス、またはクラス名を文字列で指定します。第2引数には、存在を確認したいプロパティの名前を文字列で指定します。関数の戻り値は真偽値(bool型)で、プロパティが存在する場合は true を、存在しない場合は false を返します。

サンプルコードでは、MyClassのオブジェクト$objに対して、様々なプロパティの存在を確認しています。この関数の特徴は、publicprotectedprivateといったアクセス修飾子に関係なく、プロパティが定義されていればtrueを返す点です。これは、プロパティにアクセスできるかどうかではなく、純粋に存在の有無をチェックするためです。staticなプロパティも同様に確認できます。また、オブジェクトのインスタンスだけでなく、クラス名('MyClass')を直接文字列で指定して、プロパティの存在を調べることも可能です。

property_exists関数は、指定されたオブジェクトまたはクラスに指定されたプロパティが存在するかどうかをチェックします。この関数は、public, protected, privateに関わらず、宣言されたすべてのプロパティの存在をtrueで返します。オブジェクト経由だけでなく、クラス名を文字列で指定してもプロパティの存在を確認できます。staticプロパティも同様にチェック可能です。ただし、オブジェクトが存在しない場合やクラス名が誤っている場合はエラーが発生する可能性があるため、事前に存在を確認するようにしましょう。また、配列に対してこの関数を使用しても、意図した結果は得られません。配列のキーの存在を確認する場合は、array_key_exists関数を使用してください。

PHP property_existsでネストされたプロパティをチェックする

<?php

/**
 * Represents an Address.
 */
class Address
{
    public string $street;
    public string $city;
    protected string $zipCode; // Protected property to demonstrate visibility

    public function __construct(string $street, string $city, string $zipCode)
    {
        $this->street = $street;
        $this->city = $city;
        $this->zipCode = $zipCode;
    }
}

/**
 * Represents a User with a nested Address object.
 */
class User
{
    public string $name;
    public string $email;
    public Address $address; // This property holds an instance of the Address class
    private string $password; // Private property to demonstrate visibility

    public function __construct(string $name, string $email, Address $address, string $password)
    {
        $this->name = $name;
        $this->email = $email;
        $this->address = $address;
        $this->password = $password;
    }
}

/**
 * Demonstrates the use of property_exists for properties within an object,
 * including how to check properties on "nested" objects (objects that are
 * properties of other objects).
 */
function demonstratePropertyExistsNested(): void
{
    // 1. Create instances of our classes
    $userAddress = new Address("123 Main St", "Anytown", "12345");
    $user = new User("John Doe", "john.doe@example.com", $userAddress, "securepassword");

    echo "--- Checking properties on the top-level User object ---\n";

    // Check for a public property directly on the User object
    if (property_exists($user, 'name')) {
        echo "✅ Property 'name' exists on the User object.\n";
    } else {
        echo "❌ Property 'name' does NOT exist on the User object.\n";
    }

    // Check for another public property, which itself is an object ('address')
    if (property_exists($user, 'address')) {
        echo "✅ Property 'address' exists on the User object.\n";

        // 2. If 'address' exists and is an object, we can then check its properties.
        // This is how you handle "nested" property checks.
        echo "\n--- Checking properties on the nested Address object ---\n";

        // It's good practice to ensure the property is indeed an object before accessing it.
        if (is_object($user->address)) {
            echo "The 'address' property is an object. Now checking its internal properties.\n";

            // Check for a public property on the nested Address object
            if (property_exists($user->address, 'city')) {
                echo "✅ Property 'city' exists on the nested Address object.\n";
            } else {
                echo "❌ Property 'city' does NOT exist on the nested Address object.\n";
            }

            // Check for a non-existent property on the nested Address object
            if (property_exists($user->address, 'country')) {
                echo "❌ Property 'country' does NOT exist on the nested Address object (expected).\n";
            } else {
                echo "✅ Property 'country' does NOT exist on the nested Address object (correctly not found).\n";
            }

            // property_exists can detect protected/private properties as long as they are declared,
            // regardless of the current scope's visibility rules.
            if (property_exists($user->address, 'zipCode')) {
                echo "✅ Property 'zipCode' exists on the nested Address object (even though it's protected).\n";
            } else {
                echo "❌ Property 'zipCode' does NOT exist on the nested Address object.\n";
            }
        } else {
            echo "The 'address' property is NOT an object or is null.\n";
        }
    } else {
        echo "❌ Property 'address' does NOT exist on the User object.\n";
    }

    echo "\n--- Further checks on User object (non-existent and private properties) ---\n";

    // Check for a property that genuinely does not exist anywhere in the class
    if (property_exists($user, 'age')) {
        echo "❌ Property 'age' exists on User object (unexpected).\n";
    } else {
        echo "✅ Property 'age' does NOT exist on User object (expected).\n";
    }

    // property_exists correctly finds private properties as well, because it checks
    // if the property is declared in the class hierarchy.
    if (property_exists($user, 'password')) {
        echo "✅ Property 'password' exists on User object (even though it's private).\n";
    } else {
        echo "❌ Property 'password' does NOT exist on User object.\n";
    }

    // 3. Demonstrate using a class name (string) instead of an object instance
    echo "\n--- Checking properties using a class name (string) ---\n";

    // Check for a public property on the 'User' class
    if (property_exists('User', 'name')) {
        echo "✅ Property 'name' exists on class 'User'.\n";
    } else {
        echo "❌ Property 'name' does NOT exist on class 'User'.\n";
    }

    // Check for a non-existent property on the 'User' class
    if (property_exists('User', 'nonExistentProperty')) {
        echo "❌ Property 'nonExistentProperty' exists on class 'User' (unexpected).\n";
    } else {
        echo "✅ Property 'nonExistentProperty' does NOT exist on class 'User' (expected).\n";
    }

    // When checking against a class name, property_exists still finds protected/private properties.
    if (property_exists('Address', 'zipCode')) {
        echo "✅ Property 'zipCode' exists on class 'Address' (even though it's protected).\n";
    } else {
        echo "❌ Property 'zipCode' does NOT exist on class 'Address'.\n";
    }
}

// Execute the demonstration function
demonstratePropertyExistsNested();

?>

PHPのproperty_exists関数は、オブジェクトやクラスに特定のプロパティが宣言されているかを確認するために使います。第一引数には調べたいオブジェクトのインスタンス、またはクラス名を文字列で指定し、第二引数にはプロパティ名を文字列で指定します。プロパティが存在すればtrueを、存在しなければfalseを返します。この関数は、プロパティのアクセス修飾子(publicprotectedprivate)に関わらず、クラスにその名前のプロパティが定義されていればtrueを返す点が重要です。

サンプルコードでは、Userオブジェクトのプロパティ(nameなど)の有無をチェックする基本的な使い方から始まります。特に注目すべきは、Userオブジェクトのaddressプロパティが別のAddressオブジェクトを保持する「ネストされたオブジェクト」の場合の確認方法です。まずUseraddressプロパティがあるかを確認し、次にそのaddressプロパティが本当にオブジェクトであれば、そのaddressオブジェクトに対してさらに内部のプロパティ(cityzipCodeなど)の有無をチェックしています。このように段階的に確認することで、オブジェクトの階層構造をたどってプロパティの存在を安全に検証できます。また、存在しないプロパティの確認や、オブジェクトではなくクラス名を直接指定してプロパティの存在を調べる例も示されています。これにより、実行時エラーを防ぎ、堅牢なコードを記述できるようになります。

property_exists関数は、指定したオブジェクトまたはクラスに特定の名前のプロパティが宣言されているかを確認します。この関数はプロパティの可視性(public, protected, private)に関わらず、宣言されていれば「存在する」と判断するため、アクセス権とは異なる点にご注意ください。ネストされたオブジェクトのプロパティを確認する際は、一度の呼び出しでは直接調べられません。まず親オブジェクトに目的のオブジェクトプロパティが存在するかを確認し、その後、そのネストされたオブジェクトに対して改めてproperty_existsを使用する必要があります。また、ネストされたプロパティにアクセスする前に、is_object()などでそのプロパティが実際にオブジェクトであることを確認すると、予期せぬエラーを防ぎ、より安全にコードを記述できます。第一引数には、オブジェクトのインスタンスだけでなく、クラス名の文字列も指定可能です。

PHPのproperty_exists()でプロパティ存在確認

<?php

class User
{
    public string $name;
    protected string $email;
    private string $password;
    public ?int $age = null; // A property explicitly declared and initialized to null

    public function __construct(string $name, string $email, string $password)
    {
        $this->name = $name;
        $this->email = $email;
        $this->password = $password;
    }
}

// Create an object instance of the User class
$user = new User('Alice', 'alice@example.com', 'secure_pass');

// Create a generic object (stdClass) and add a dynamic property
$anonymousObject = new stdClass();
$anonymousObject->id = 123;

echo "--- Checking properties on object instances ---\n";

// Check for a public property on an object
echo "Does \$user object have 'name'? " . (property_exists($user, 'name') ? 'Yes' : 'No') . "\n";

// Check for a protected property (property_exists checks existence, not accessibility)
echo "Does \$user object have 'email'? " . (property_exists($user, 'email') ? 'Yes' : 'No') . "\n";

// Check for a private property
echo "Does \$user object have 'password'? " . (property_exists($user, 'password') ? 'Yes' : 'No') . "\n";

// Check for a property explicitly declared and initialized to null
echo "Does \$user object have 'age'? " . (property_exists($user, 'age') ? 'Yes' : 'No') . "\n";

// Check for a non-existent property on the object
echo "Does \$user object have 'address'? " . (property_exists($user, 'address') ? 'Yes' : 'No') . "\n";

// Check for a dynamically added property on stdClass
echo "Does \$anonymousObject have 'id'? " . (property_exists($anonymousObject, 'id') ? 'Yes' : 'No') . "\n";

// Check for a non-existent property on stdClass
echo "Does \$anonymousObject have 'role'? " . (property_exists($anonymousObject, 'role') ? 'Yes' : 'No') . "\n";


echo "\n--- Checking properties on class names ---\n";

// Check for a public property using the class name string
echo "Does class 'User' have 'name'? " . (property_exists('User', 'name') ? 'Yes' : 'No') . "\n";

// Check for a protected property using the class name string
echo "Does class 'User' have 'email'? " . (property_exists('User', 'email') ? 'Yes' : 'No') . "\n";

// Check for a private property using the class name string
echo "Does class 'User' have 'password'? " . (property_exists('User', 'password') ? 'Yes' : 'No') . "\n";

// Check for a non-existent property using the class name string
echo "Does class 'User' have 'startDate'? " . (property_exists('User', 'startDate') ? 'Yes' : 'No') . "\n";


echo "\n--- Clarifying 'property_exists' vs 'isset()' ---\n";

// Display the current value of the 'age' property
echo "Value of \$user->age is: " . var_export($user->age, true) . "\n";

// property_exists returns true because 'age' is a declared property, regardless of its value (even if null)
echo "Is 'age' property existing in \$user (using property_exists)? " . (property_exists($user, 'age') ? 'Yes' : 'No') . "\n";

// isset() returns false because the 'age' property's value is null
echo "Is 'age' property set and not null in \$user (using isset())? " . (isset($user->age) ? 'Yes' : 'No') . "\n";

?>

PHPのproperty_exists関数は、指定されたオブジェクトまたはクラスに特定のプロパティ(クラス内で宣言された変数)が存在するかどうかを判定する際に使用します。

第一引数には、プロパティを確認したいオブジェクトのインスタンス、またはクラス名を文字列で指定します。第二引数には、確認したいプロパティの名前を文字列で指定します。戻り値は、プロパティが存在すればtrue、存在しなければfalseという真偽値(bool)です。

この関数は、プロパティのアクセス修飾子(public, protected, private)に関わらず、クラスに宣言されていればtrueを返します。例えば、private$passwordプロパティも、宣言されていれば存在すると判断されます。また、stdClassのようなジェネリックなオブジェクトに動的に追加されたプロパティも検出できます。

重要な点として、プロパティが宣言されており、かつその値がnullである場合でも、property_existstrueを返します。これは、プロパティが存在するかどうかを確認する機能であり、値が「セットされているか(nullではないか)」を確認するisset()関数とは挙動が異なります。サンプルコードの$ageプロパティの例では、property_existstrueですが、isset($user->age)falseとなります。

したがって、property_existsは、あるプロパティがクラス定義やオブジェクトの動的な追加によって実際に「存在するか」を確認したい場合に適しています。

property_existsは、オブジェクトやクラスに指定されたプロパティが「宣言されているか」を確認する関数です。プロパティのアクセス修飾子(public, protected, private)や、その値がnullであるかにかかわらず、宣言されていればtrueを返します。動的に追加されたプロパティも検出可能です。

特にisset()関数との違いに注意が必要です。property_existsはプロパティがnull値でも存在を返しますが、isset()はプロパティが存在し、かつ値がnullではない場合にのみtrueを返します。そのため、「プロパティが宣言されているか」の確認にはproperty_existsを、「有効な値が設定されているか」の確認にはisset()を使い分けてください。「思ったように動かない」と感じる場合、この違いが原因であることが多いです。

property_existsとissetの違いを理解する

<?php

class PropertyComparisonExample
{
    public string $publicPropWithValue = 'Hello World';
    public ?string $publicPropWithNull = null; // This property exists, but its value is null.
    protected string $protectedProp = 'I am protected'; // This property exists, but not publicly accessible.
    private string $privateProp = 'I am private'; // This property exists, but not publicly accessible.
    // 'nonExistentProp' is intentionally not declared here.
}

/**
 * Demonstrates the difference between property_exists() and isset() for class properties.
 *
 * property_exists(): Checks if a property is declared in a class or an object,
 *                    regardless of its value (even if null) and its visibility (public, protected, private).
 *
 * isset(): Checks if a variable (or object property) is set AND is not null.
 *          For object properties, it also requires the property to be accessible from the current scope.
 */
function demonstratePropertyChecks(): void
{
    $instance = new PropertyComparisonExample();

    echo "--- Public Property with a Value (\$publicPropWithValue) ---" . PHP_EOL;
    // property_exists() returns true because the property is declared.
    echo "property_exists(\$instance, 'publicPropWithValue'): ";
    var_dump(property_exists($instance, 'publicPropWithValue'));
    // isset() returns true because the property is accessible and its value is not null.
    echo "isset(\$instance->publicPropWithValue): ";
    var_dump(isset($instance->publicPropWithValue));
    echo PHP_EOL;

    echo "--- Public Property with Null Value (\$publicPropWithNull) ---" . PHP_EOL;
    // property_exists() returns true because the property is declared, even if its value is null.
    echo "property_exists(\$instance, 'publicPropWithNull'): ";
    var_dump(property_exists($instance, 'publicPropWithNull'));
    // isset() returns false because although the property exists and is accessible, its value is null.
    echo "isset(\$instance->publicPropWithNull): ";
    var_dump(isset($instance->publicPropWithNull));
    echo PHP_EOL;

    echo "--- Protected Property (\$protectedProp) ---" . PHP_EOL;
    // property_exists() returns true because the property is declared in the class, regardless of visibility.
    echo "property_exists(\$instance, 'protectedProp'): ";
    var_dump(property_exists($instance, 'protectedProp'));
    // Note: Attempting isset(\$instance->protectedProp) from outside the class
    // would result in a Fatal Error due to visibility constraints.
    echo "// (Attempting isset(\$instance->protectedProp) here would cause a Fatal Error)" . PHP_EOL;
    echo PHP_EOL;

    echo "--- Private Property (\$privateProp) ---" . PHP_EOL;
    // property_exists() returns true because the property is declared in the class, regardless of visibility.
    echo "property_exists(\$instance, 'privateProp'): ";
    var_dump(property_exists($instance, 'privateProp'));
    // Note: Attempting isset(\$instance->privateProp) from outside the class
    // would result in a Fatal Error due to visibility constraints.
    echo "// (Attempting isset(\$instance->privateProp) here would cause a Fatal Error)" . PHP_EOL;
    echo PHP_EOL;

    echo "--- Non-existent Property (e.g., 'nonExistentProp') ---" . PHP_EOL;
    // property_exists() returns false because the property is not declared in the class.
    echo "property_exists(\$instance, 'nonExistentProp'): ";
    var_dump(property_exists($instance, 'nonExistentProp'));
    // isset() returns false because the property does not exist. No error is thrown for non-existent properties.
    echo "isset(\$instance->nonExistentProp): ";
    var_dump(isset($instance->nonExistentProp));
    echo PHP_EOL;

    echo "--- Using property_exists() with a Class Name String ---" . PHP_EOL;
    // property_exists() can also check static properties or properties of a class without an instance.
    echo "property_exists(PropertyComparisonExample::class, 'publicPropWithValue'): ";
    var_dump(property_exists(PropertyComparisonExample::class, 'publicPropWithValue'));
    echo "property_exists(PropertyComparisonExample::class, 'protectedProp'): ";
    var_dump(property_exists(PropertyComparisonExample::class, 'protectedProp'));
    echo "property_exists(PropertyComparisonExample::class, 'nonExistentProp'): ";
    var_dump(property_exists(PropertyComparisonExample::class, 'nonExistentProp'));
    echo PHP_EOL;
}

// Execute the function to see the comparisons
demonstratePropertyChecks();

property_exists()関数は、指定されたオブジェクトまたはクラスに、指定された名前のプロパティが存在するかどうかを確認するために使用します。PHP 8.4で利用可能です。この関数は、プロパティの可視性(public, protected, private)や、プロパティの値がnullであるかどうかに関わらず、プロパティが宣言されていればtrueを返します。

引数には、オブジェクトまたはクラス名を文字列で指定する $object_or_class と、確認するプロパティ名を文字列で指定する $property を渡します。クラス名を文字列で渡す場合は、PropertyComparisonExample::classのように::classを使用します。

戻り値はbool型で、プロパティが存在する場合はtrue、存在しない場合はfalseを返します。

サンプルコードでは、property_exists()isset()の違いを明確に示しています。isset()はプロパティが存在し、かつnullでない場合にtrueを返しますが、property_exists()はプロパティの存在のみを確認します。また、isset()はアクセス可能なプロパティに対してのみ使用できますが、property_exists()protectedprivateなプロパティの存在も確認できます。存在しないプロパティに対してisset()を使用してもエラーは発生しませんが、protectedprivateなプロパティに対してアクセスしようとするとFatal Errorが発生します。property_exists()を使うことで、オブジェクトが特定のプロパティを持っているかどうかを安全に確認できます。

property_exists()isset()は、プロパティの存在確認で異なる役割を持ちます。property_exists()は、クラスやオブジェクトにプロパティが宣言されているかを確認し、null値やアクセス制限(protectedprivate)に関わらずtrueを返します。一方、isset()は、プロパティが存在し、かつnullでない場合にtrueを返します。isset()は、アクセス可能なプロパティに対してのみ使用できます。protectedprivateなプロパティに外部からisset()を使用すると、致命的なエラーが発生します。property_exists()は、クラス名を文字列で指定して、インスタンス化せずにプロパティの存在を確認できます。プロパティの存在のみを確認したい場合はproperty_exists()、値が設定されているか確認したい場合はisset()を使い分けましょう。

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