ReflectionHelper.php 3.1 KB
Newer Older
Qiang Xue committed
1 2 3 4 5 6 7 8 9 10 11
<?php
/**
 * ReflectionHelper class file.
 *
 * @link http://www.yiiframework.com/
 * @copyright Copyright &copy; 2008-2012 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yii\util;

Qiang Xue committed
12 13
use yii\base\Exception;

Qiang Xue committed
14 15 16 17 18 19 20 21 22 23
/**
 * ReflectionHelper
 *
 * @author Qiang Xue <qiang.xue@gmail.com>
 * @since 2.0
 */
class ReflectionHelper
{
	/**
	 * Prepares parameters so that they can be bound to the specified method.
Qiang Xue committed
24 25 26
	 * This method converts the input parameters into an array that can later be
	 * passed to `call_user_func_array()` when calling the specified method.
	 * The conversion is based on the matching of method parameter names
Qiang Xue committed
27 28 29 30 31 32
	 * and the input array keys. For example,
	 *
	 * ~~~
	 * class Foo {
	 *     function bar($a, $b) { ... }
	 * }
Qiang Xue committed
33
	 * $object = new Foo;
Qiang Xue committed
34
	 * $params = array('b' => 2, 'c' => 3, 'a' => 1);
Qiang Xue committed
35 36
	 * var_export(ReflectionHelper::extractMethodParams($object, 'bar', $params));
	 * // output: array('a' => 1, 'b' => 2);
Qiang Xue committed
37 38
	 * ~~~
	 *
Qiang Xue committed
39 40
	 * @param object|string $object the object or class name that owns the specified method
	 * @param string $method the method name
Qiang Xue committed
41
	 * @param array $params the parameters in terms of name-value pairs
Qiang Xue committed
42 43 44
	 * @return array parameters that are needed by the method only and
	 * can be passed to the method via `call_user_func_array()`.
	 * @throws Exception if any required method parameter is not found in the given parameters
Qiang Xue committed
45
	 */
Qiang Xue committed
46
	public static function extractMethodParams($object, $method, $params)
Qiang Xue committed
47
	{
Qiang Xue committed
48
		$m = new \ReflectionMethod($object, $method);
Qiang Xue committed
49
		$ps = array();
Qiang Xue committed
50
		foreach ($m->getParameters() as $param) {
Qiang Xue committed
51 52
			$name = $param->getName();
			if (array_key_exists($name, $params)) {
Qiang Xue committed
53
				$ps[$name] = $params[$name];
Qiang Xue committed
54 55 56
			} elseif ($param->isDefaultValueAvailable()) {
				$ps[$name] = $param->getDefaultValue();
			} else {
Qiang Xue committed
57
				throw new Exception(\Yii::t('yii', 'Missing required parameter "{name}".', array('{name}' => $name)));
Qiang Xue committed
58 59 60 61
			}
		}
		return $ps;
	}
Qiang Xue committed
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102

	/**
	 * Initializes an object with the given parameters.
	 * Only the public non-static properties of the object will be initialized, and their names must
	 * match the given parameter names. For example,
	 *
	 * ~~~
	 * class Foo {
	 *     public $a;
	 *     protected $b;
	 * }
	 * $object = new Foo;
	 * $params = array('b' => 2, 'c' => 3, 'a' => 1);
	 * $remaining = ReflectionHelper::bindObjectParams($object, $params);
	 * var_export($object);    // output: $object->a = 1; $object->b = null;
	 * var_export($remaining); // output: array('b' => 2, 'c' => 3);
	 * ~~~
	 *
	 * @param object $object the object whose properties are to be initialized
	 * @param array $params the input parameters to be used to initialize the object
	 * @return array the remaining unused input parameters
	 */
	public static function initObjectWithParams($object, $params)
	{
		if (empty($params)) {
			return array();
		}

		$class = new \ReflectionClass(get_class($object));
		foreach ($params as $name => $value) {
			if ($class->hasProperty($name)) {
				$property = $class->getProperty($name);
				if ($property->isPublic() && !$property->isStatic()) {
					$object->$name = $value;
					unset($params[$name]);
				}
			}
		}

		return $params;
	}
Qiang Xue committed
103
}