Есть небольшой момент в методе modX::runProcessor():
if (!empty($className)) {
$c = new $className($this,$scriptProperties);
$processor = call_user_func_array(array($c,'getInstance'),
array($this,$className,$scriptProperties));
}
То есть modX вызывает статический метод modProcessor::getInstance(), который может вернуть как инстанс указанного в параметрах класса, так и инстанс любого другого объекта-процессора. То есть там такой механизм, в котором на лету можно указать, какой именно процессор инициализировать.
НО: строчкой выше MODX так же создает новый объект.
И ведь очевидно, что это зря, только лишнее расходование ресурсов.
$c = new $className($this,$scriptProperties);
Полученный объект $c нужен только для того, чтобы выполнить call_user_func_array().
И вот вопросы в студию:
1. Зачем использовать именно call_user_func_array()? Почему не делать вот так?:
$processor = $className::getInstance($this, $className, $scriptProperties);
И не придется инициализировать лишний объект.
2. Почему без инициализации объекта $c не получается выполнить вот так?:
$processor = call_user_func_array("$className::getInstance",
array($this,$className,$scriptProperties));
Ему обязательно почему-то требуется перед этим new $className($this,$scriptProperties);
Я экспериментировал по разному, и никак мне не удалось сделать, чтобы этот метод не выполнялся. Вот пример:
<?php
ini_set('display_errors', 1);
class test{
public static function get(){
$class = __CLASS__;
return new $class();
}
}
function test(){
$class = 'test';
print_r(call_user_func_array("{$class}::get",array()));
}
test();
Вот это в любом виде работает. Как говорится «найдите 10 отличий».
В общем, если у кого-то есть какие соображения — прошу!
Алексей Александрович 24.10.2013 00:11 #
Николай 24.10.2013 07:57 #
Но мы уже этот вопрос довольно четко прояснили.
1. call_user_func_array() - необходимо для обратной совместимости с php 5.2 и ниже. Там пых-пых не умеет вызывать методы динамических переменных. К примеру $className::getInstance() он развалится. Ему надо четко SomeProcessorClass::getInstance();
2. Чтобы избежать вот этой лишней инициализации $c = new $clasName(); и нормально отработалось $processor = call_user_func_array("$className::getInstance", array($this,$className,$scriptProperties)), надо первым параметром передавать ссылку, то есть
$processor = call_user_func_array("$className::getInstance", array(& $this,$className,$scriptProperties));
Там какая-то ктулхость, из-за чего в момент выполнения getInstance() над классом, класс ожидает, что $this - это будет объект, а ему там $this - просто ничего. Скорее всего связанно с зарезервированностью переменной или типа того. А так, когда это ссылка, тогда уже это объект, и нормально все проходит.
P.S. спасибо за помощь в этом вопросе Сергею http://modx.ru/razrabotchiki-na-modx/685/