RitoLabo

PHPのオブジェクト内部検査機能まとめ

  • 公開:
  • カテゴリ: PHP Basics
  • タグ: PHP,Basics,Object,Introspection

PHPには、オブジェクトに関する内部検査機能(情報取得用関数)が組み込まれています。これらを用いると、クラス名や定義されているメソッド、プロパティ、さらには継承元クラスの情報など、オブジェクトの性質をチェックする事が出来ます。

今回は、内部検査に関する関数を見ていきます。

アジェンダ
  1. 開発環境
  2. is_object
  3. get_declared_classes
  4. class_exists
  5. get_class
  6. get_class_methods
  7. get_class_vars
  8. get_parent_class
  9. method_exists
  10. get_object_vars

開発環境

デモでは PHP 7.2 を使っていますが、紹介するものは全てPHP 4、PHP 5、PHP 7全てのバージョンで使用できます。

また、今回のデモ用に以下のサンプルクラスを定義しています。

class sample01
{
public $name = "MyName";

public $age = 20;

public $address;

public function sampleMethod01() { }

public function sampleMethod02() { }
}

class sample02 extends sample01
{
public $secondName = "secondName";

public $secondAge = 30;
}

class sample03
{
private $pv1 = 'private';
private $pv2;
public $bl1 = 'public';
public $pl2;
protected $pr1 = 'protected';
protected $pr2;
static $st1 = 'static';
static $st2;
}

is_object

is_object関数は、対象がオブジェクトであるかどうかを確認し返します。

bool is_object ( mixed $var )

引数に変数を渡し、変数がオブジェクトならtrue、違うならfalseが返ります。

$sample = new sample01;

var_dump( is_object($sample) );
// => true

$array = [1, 2, 3];

var_dump( is_object($array) );
// => false

get_declared_classes

get_declared_classes関数は、定義されている全てのクラス名を配列で返します。

array get_declared_classes ( void )

今回のデモでは3つのクラスを定義していますが、組み込まれている拡張モジュール等のクラスも既にロードされているので、結果はそこそこの数になります。

$result = get_declared_classes();

print_r($result);
// => Array
// (
// [0] => stdClass
// [1] => Exception
// [2] => ErrorException
// [3] => Error
// .
// .
// .
// [171] => sample01
// [172] => sample02
// [173] => sample03
// )

class_exists

class_exists関数は、指定したクラスが定義済みであるかどうかを返します。

bool class_exists ( string $class_name [, bool $autoload = TRUE ] )

第一引数にクラス名(文字列)を渡します。第二引数オプションでは、__autoload()をコールする(未定義のクラスのロードを試みる)かを指定できますが、PHP7.2で非推奨になった(autoloaderをチェインできない・spl_autoload_register()と互換性がない)ので使用は避けましょう。

var_dump( class_exists('sample01') );
// => true

class_exists()は、例えば以下のようにして使えます。

$class_name = 'sample01';
if (class_exists($class_name)) {
$sample = new $class_name;
}

上記は、指定のクラスが定義されていたらそのクラスをインスタンス化する処理です。

get_class

get_class関数は、指定オブジェクトのクラス名を返します。

string get_class ([ object $object ] )

引数にはオブジェクトを渡します。

$sample = new sample01;

var_dump( get_class($sample) );
// => 'sample01'

get_class_methods

get_class_methods関数は、指定クラスに定義されているメソッド(クラスメソッド)を配列で返します。

array get_class_methods ( mixed $class_name )

引数はクラス名(文字列)もしくオブジェクトを渡します。

$sample = new sample01;

var_dump( get_class_methods($sample) ); // オブジェクトを渡します。
// 0 => string 'sampleMethod01'
// 1 => string 'sampleMethod02'

$sample = 'sample01';

var_dump( get_class_methods($sample) ); // クラス名を渡します。
// 0 => string 'sampleMethod01'
// 1 => string 'sampleMethod02'

get_class_vars

get_class_vars関数は、指定したクラスのデフォルトプロパティを配列で返します。

array get_class_vars ( string $class_name )

引数にはクラス名(文字列)を渡します。

var_dump( get_class_vars('sample01') );
// 'name' => 'MyName'
// 'age' => 20
// 'address' => null

// オブジェクトからクラス名を取得しプロパティを取得します
$sample2 = new sample02;
var_dump( get_class_vars(get_class($sample2)) ); // 継承先の親プロパティも取得します。
// 'secondName' => 'secondName'
// 'secondAge' => 30
// 'name' => 'MyName'
// 'age' => 20
// 'address' => null

指定したクラスが基底クラスを継承していればそのプロパティも取得します。

get_parent_class

get_parent_class関数は、指定クラスの親クラス名を返します。

string get_parent_class ([ mixed $object ] )

引数にはクラス名(文字列)もしくはオブジェクトを渡します。

var_dump( get_parent_class('sample02') ); // クラス名を渡します。
// => 'sample01'

$sample02 = new sample02();
var_dump( get_parent_class(get_class($sample02)) ); // オブジェクトを渡します。
// => 'sample01'

method_exists

method_exists関数は、クラスメソッドが存在するかどうかを返します。

bool method_exists ( mixed $object , string $method_name )

第一引数にオブジェクトを渡し、第二引数に存在を確認したいメソッド名を渡します。

$sample01 = new sample01();
$sample02 = new sample02();
$sample03 = new sample03();

var_dump( method_exists($sample01, 'sampleMethod01') );
// => true

var_dump( method_exists($sample02, 'sampleMethod01') );
// => true 継承の場合でも真になります

var_dump( method_exists($sample03, 'sampleMethod01') );
// => false

get_object_vars

get_object_vars関数は、指定したオブジェクトのプロパティを返します。

array get_object_vars ( object $object )

引数にはオブジェクトを渡します。

$sample01 = new sample01();
var_dump( get_object_vars($sample01) );
// 'name' => 'MyName'
// 'age' => 20
// 'address' => null

$sample02 = new sample02();
var_dump( get_object_vars($sample02) ); // 継承元のプロパティも返ります。
// 'secondName' => 'secondName'
// 'secondAge' => 30
// 'name' => 'MyName'
// 'age' => 20
// 'address' => null

$sample03 = new sample03();
var_dump( get_object_vars($sample03) ); // publicアクセスのみのプロパティを取得します。
// 'bl1' => 'public'
// 'pl2' => null
  • 継承しているクラスがある場合は親クラスのプロパティも取得します。
  • プロパティのアクセス修飾子がpublicのものだけを返します。

オブジェクトのプロパティを返すという挙動はget_class_vars()と同じですが、get_class_vars関数は引数にクラス名を取りますが、こちらはオブジェクト自体を引数として取ります。

まとめ

PHPの内部検査関数を使えばそのオブジェクトの妥当性を確認できるわけですが、これらを使って汎用的なデバッガやプロファイラを作成したりもできます。

動的なオブジェクトの取り回しを連鎖的に行う場合などは、その構造が複雑化するに従って一連の処理の流れからオブジェクトのあるべき形をを見失ってしまいがちなので、要所要所で内部検査を挟んで堅牢な処理を構築していきましょう。