未经测试,只是很快就被黑掉了,但我希望你明白。而不是使用文字foo()->bar()表示法,请使用简化的foo.bar表示法,您可以通过各种方式处理自己。
function getPropertyFromString($obj, $string) {
if (is_array($obj) && array_key_exists($string, $obj)) {
return $obj[$string];
} else if (is_object($obj)) {
if (isset($obj->$string)) {
return $obj->$string;
} else if (method_exists($obj, $string)) {
return call_user_func(array($obj, $string));
} else if (method_exists($obj, 'get' . ucfirst($string))) {
return call_user_func(array($obj, 'get' . ucfirst($string)));
}
}
return null;
}
function getValue($obj, $getter) {
if (is_string($getter)) {
return array_reduce(explode('.', $getter), 'getPropertyFromString', $obj);
} else if (is_callable($getter)) {
return call_user_func($getter, $obj);
}
throw new InvalidArgumentException('Invalid getter');
}
function mapper(array $array, $keyGetter, $valueGetter) {
$result = array();
foreach ($array as $value) {
$result[getValue($value, $keyGetter)] = getValue($value, $valueGetter);
}
return $result;
}
例子:
mapper($array, 'id', 'name'); // simple properties
mapper($array, 'foo.bar', 'baz'); // nested properties
// super complex values
mapper($array, 'id', function ($obj) { return strtoupper($obj->foo(42)->bar()->baz); });