Использовать карту массива для возврата массива созданных объектов?
Допустим, у меня есть следующее:
class Thing {
function __construct($id) {
// some functionality to look up the record and initialize the object.
return $this;
}
}
Теперь, получив массив идентификаторов, я хочу получить массив созданных экземпляров. Что-то вроде следующего:
$ids = array(1, 2, 3, 4, 5);
$things = array_map(array('Thing', 'new'), $ids); // Doesn't work
Конечно, для класса Thing нет "нового" метода, и "__конструкция" также была запрещена. Я знаю, что это можно было бы сделать с помощью дополнительных шагов, проходящих через $id, но есть ли простой способ вызвать "новую вещь($id)" для каждого с помощью array_map?
3 answers
Это не может работать, потому что нет статического метода Thing::new
. Вы можете либо добавить его, либо просто предоставить функцию в качестве обратного вызова array_map
:
$ids = array(1, 2, 3, 4, 5);
$things = array_map(function($id){return new Thing($id);}, $ids);
$things = array();
foreach($ids as $id)
$things[] = new Thing($id);
Это способ работы php. Вот как работает язык php. Если вам нравится функциональное программирование, итераторы, понимание и другие хитрости smartxxx, рассмотрите другие языки.
Чтобы ответить на ваш вопрос буквально , вам понадобятся две небольшие функции
// replacement for "new"
function init($klass /* , param, param */) {
$c = new ReflectionClass($klass);
return $c->newInstanceArgs(
array_slice(func_get_args(), 1));
}
// generic currying
function curry($fn /* , param, param */) {
$_ = array_slice(func_get_args(), 1);
return function() use($fn, $_) {
return call_user_func_array($fn,
array_merge($_, func_get_args()));
};
}
И затем
class Thing
{
function __construct($x, $y) {
$this->x = $x;
$this->y = $y;
}
}
// curry one param
print_r(array_map(
curry("init", "Thing"),
array("x1", "x2", "x3"),
array("y1", "y2", "y3")
));
// curry two params
print_r(array_map(
curry("init", "Thing", "x"),
array("y1", "y2", "y3")
));
Стоило ли оно того? Я так не думаю.
Судя по всему, вы пытаетесь проверить, был ли уже инициирован объект/класс.
Вы можете попробовать функцию get_declared_classes(). if вернет массив со всеми созданными экземплярами классов.
С помощью этого массива вы можете проверить, известен ли ваш класс в системе, если нет, вы можете инициировать его на лету.