__callStatic(): создание экземпляров объектов из статического контекста?
Меня смущает, как "статические" и "динамические" функции и объекты в PHP работают вместе, особенно в отношении __callStatic().
Как работает __callStatic ():
У вас может быть нормальный класс MyClass, где в класс можно поместить статическую функцию с именем __callStatic(), которая вызывается только тогда, когда MyClass не имеет статической функции с именем, которое вы хотите.
т.е. я звоню
MyClass::newFunction();
newFunction()
называется статически, ноMyClass
не имеет заявленного. Итак, тогда__callStatic()
звонят и внутри можно сказать$myObject=new SomeOtherClass(); $myObject->newFunction();
которая вызывает функцию, которую вы хотели, но на некотором другом объекте.
Укороченная версия:
Другими словами, __callStatic() делает это:
MyClass::newFunction();
который скрывает это:
(new SomeOtherClass())->newFunction();
Скажи что сейчас? То, что выглядит как код, вызывающий статическую функцию из класса, оказывается вызывающим эту функцию из какого-то другого класса и вызывающим ее через создание экземпляров, а не статически.
Объясните это, пожалуйста!
Почему это было сделано? Можете ли вы сделать что-нибудь подобное в другом месте, например, C++ или Java? Я ищу краткое и краткое, но информативное объяснение статических и динамических функций в языках, и в этом случае __callStatic () violates
или же conforms
к общей картине языковых конструкций. Или это совершенно новая языковая конструкция?
3 ответа
__callStatic()
предоставляет разработчикам возможность реагировать на static
вызовы методов, даже если эти методы не существуют или недоступны извне класса (будучи protected
). Это полезно для динамического генерирования общего кода. Если вы не видите, насколько это полезно, вам, вероятно, не нужна эта функция в данный момент, и вы должны продолжать изучать основы.
Пример: у вас есть этот класс:
class Test {
protected static function myProtected($test) {
var_dump(__METHOD__, $test);
}
public static function __callStatic($method, $args) {
switch($method) {
case 'foo' :
echo 'You have called foo()';
var_dump($args);
break;
case 'helloWorld':
echo 'Hello ' . $args[0];
break;
case 'myProtected':
return call_user_func_array(
array(get_called_class(), 'myProtected'),
$args
);
break;
}
}
}
Попробуй позвонить:
// these ones does not *really* exist
Test::foo('bar');
Test::helloWorld('hek2mgl');
// this one wouldn't be accessible
Test::myProtected('foo');
Понял?
Почему это было сделано?
Это экзистенциальный вопрос, но я думаю, что ответ "потому что вы можете". PHP динамический язык, и эти конструкции __call
а также __callStatic()
показать свою силу, и эта сила может быть полезна в некоторых ситуациях.
Можете ли вы сделать что-нибудь подобное в другом месте, например, C++ или Java?
У них нет похожих магических методов.
Я ищу краткое и краткое, но информативное объяснение статических и динамических функций в языках.
Статические функции инкапсулируют код. Они существуют, даже когда ни один класс не был создан. Вы можете вызвать их, используя оператор разрешения области видимости. Динамические функции хорошо, динамические
.. нарушает ли __callStatic() или соответствует общей картине конструкций языка. Или это совершенно новая языковая конструкция?
Это конструкция динамического языка. Не уверен, что эта функциональность существует во всех динамических языках, но она есть в PHP. Это ничего не нарушает, просто вводит новую парадигму сквозных универсальных функций, когда функция, которую вы вызываете, не существует / недоступна в текущей области.
Я не совсем уверен, почему __callStatic() имеет отношение здесь?
Я не совсем вижу разницу между:
class Foo {
static function bar() {
$obj = new Foo();
$obj->quux();
}
function quux() {
return "whatever";
}
}
а твой пример? В обоих случаях вы вызываете статический метод, который вызывает другой метод для объекта того же класса.
Да, это возможно На самом деле, делая это, вы можете реорганизовать свой код. В этом примере вы создаете экземпляр объекта с его состоянием по умолчанию, выполняете для него метод, а затем выбрасываете объект. Это говорит о том, что, что бы ни делал метод, на самом деле не нужно состояние объектов. Это означает, что он либо не принадлежит этому классу, либо может быть просто переписан как статический метод.
А знаете ли вы о __call? Он делает то же самое, что и __callStatic, но для объектов, а не для классов. Например, $foo->myMissingMethod(); будет идти к __call, если такой метод существует для класса, экземпляром которого является $ foo.