PHP

次の仕事はなかなか始まらない。
しかたがないので、PHPの勉強でもするために、プログラミングPHPという本を読んでいるが、

この本へんだよ。サンプル動かないよ。

古い本だから仕方ないのかと思って奥付みたら、2014/3/24て書いてある。


<?php
// 呼び出し可能なメソッド(継承したものを含む)を返却 
function getCallableMethods($object) {
	$methods = get_class_methods(get_class($object));

	/*if (get_parent_class($object)) {
		$parent_methods = get_class_methods(get_parent_class($object));
		$methods = array_diff($methods, $parent_methods);
	}*/
	return $methods;
}

// 継承したメソッド(オーバライドしてるものも含む)の配列を返却する
function getInheritedMethods($object) {
	$methods = get_class_methods(get_class($object));

	if (get_parent_class($object)) {
		$parent_methods = get_class_methods(get_parent_class($object));
		$methods = array_intersect($methods, $parent_methods);
	}
	return $methods;
}

// スーパークラスの配列を返却する
function getLineage($object) {
	$parent = get_parent_class($object);
	if ($parent) {
		$parentObject = new $parent;
		$lineage = getLineage($parentObject);
		$lineage[] = get_class($object);
	} else {
		$lineage = array(get_class($object));
	}
	return $lineage;
}

// サブクラスの配列を返却する。
function getChildClasses($object) {
	$classes = get_declared_classes();

	//print_r($classes);

	$children = array();

	foreach($classes as $class) {
		if (substr($class, 0, 2) == '__') {
			continue;
		}
		$child_r = new ReflectionClass($class);
		$child_r->getParentClass();
		//$child = new $class;

		//if (get_parent_class($child) == get_class($object)) {
		if ($child_r->getParentClass() == get_class($object)) {
			$children[] = $class;
		}
	}
	return $children;
}


// オブジェクトについての情報を表示する 
function printObjectInfo($object) {
	$class = get_class($object);
	echo "<h2>クラス</h2>";
	echo "<p>{$class}</p>";
	echo "<h2>継承関係</h2>";
	echo "<h3>親クラス</h3>";
	$lineage = getLineage($object);
	array_pop($lineage);

	if (count($lineage) > 0) {
		echo "<p>" . join(" -&gt; ", $lineage) . "</p>";
	} else {
		echo "<i>なし</i>";
	}

	echo "<h3>子クラス</h3>";
	$children = getChildClasses($object);
	echo "<p>";
	if (count($children) > 0) {
		echo join(", ", $children);
	} else {
		echo "<i>なし</i>";
	}
	echo "</p>";

	echo "<h2>メソッド</h2>";
	$methods = getCallableMethods($object);
	$object_methods = getInheritedMethods($object);
	print_r($methods);
	echo "<br>";
	print_r($object_methods);

	if (!count($methods)) {
		echo "<i>なし</i>";
	}
	else {
		echo '<p>継承しているメソッドは<i>斜体</i>で表示します。</p>';

		foreach ($methods as $method) {
			if (in_array($method, $object_methods)) {
				echo "<i>{$method}</i>();<br />";
			} else {
				echo "<b>{$method}</b>();<br />";
			}
		}
	}

	echo "<h2>プロパティ</h2>";
	$properties = get_class_vars($class);
	if (!count($properties)) {
		echo "<i>なし</i>";
	}
	else {
		foreach(array_keys($properties) as $property) {
			echo "<br>\${$property}</b> = " . $object->$property . "<br />";
		}
	}

	echo "<hr/>";
}

class A
{
	public $foo = "foo";
	public $bar = "bar";
	public $baz = 17.0;

	static function staticFunction() {
	}

	function firestFunction() {
	}

	function secondFunction() {
	}
}

class B extends A
{
	public $quux = "false";

	function thirdFunction($arg1) {
		echo $arg1;
	}
}

class C extends B {
}

$a = new A;
$a->foo = "hoggggggeFOOOO";
$a->bar = 23;

$b = new B;
$b->foo = "BBBBB";
$b->quux = "true";

$c = new C;

printObjectInfo($a);
printObjectInfo($b);
printObjectInfo($c);

?>

だね?意図を察して最小限の修正を加えると。



取り敢えず、オブジェクトの検査には、ネットを見る限り、get_class_methodsとかではなく、ReflectionClassを使うのが良いようだ。
マニュアルがないようだけど。