__callStatic(): создание объектов из статического контекста?
6 Dennis [2013-11-07 19:11:00]
Я смущен тем, как "статические" и "динамические" функции и объекты в PHP работают вместе, особенно в отношении __callStatic().
Как работает __callStatic():
У вас может быть обычный класс MyClass, где внутри класса вы можете статическую функцию, называемую __callStatic(), которая вызывается только когда MyClass не имеет статической функции по имени, которое вы хотите.
то есть. Я звоню
MyClass::newFunction();
newFunction()
называется статическим, ноMyClass
не объявили ли они это. Итак, тогда__callStatic()
вызывается и внутри вы можете сказать$myObject=new SomeOtherClass(); $myObject->newFunction();
который вызывает функцию, которую вы хотите, но на какой-то другой объект.
Краткая версия:
Другими словами, __callStatic() делает следующее:
MyClass::newFunction();
который скрывает это:
(new SomeOtherClass())->newFunction();
Скажи, что теперь? То, что выглядит как код, вызывающий статическую функцию из класса, оказывается вызывающим эту функцию из какого-то другого класса и вызывающим ее через экземпляр, а не статически.
Объясните это, пожалуйста!
Почему это было сделано? Можете ли вы сделать что-нибудь подобное в другом месте, например С++ или Java? Я ищу краткое и краткое, но информативное объяснение статических и динамических функций в языках, и в этом случае, будь то __callStatic() violates
или conforms
к большой картине языковых конструкций. Или это новая языковая конструкция целиком.
instantiation php static
3 ответа
6 Решение hek2mgl [2013-11-07 19:16:00]
__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');
Понял?
1 Dennis [2013-11-12 01:01:00]
Почему это было сделано?
Это экзистенциальный вопрос, но я думаю, что ответ "потому что вы можете". PHP - это динамический язык, и эти конструкции __call
и __callStatic()
показывают свою силу, и эта сила может быть полезна в некоторых ситуациях.
Можете ли вы сделать что-нибудь подобное в другом месте, например С++ или Java?
Нет. У них нет подобных магических методов.
Я ищу краткое и краткое, но информативное объяснение статических и динамических функций в языках
Статические функции инкапсулируют код. Они существуют, даже если ни один класс не был создан. Вы можете вызвать их с помощью оператора разрешения области. Динамические функции хорошо, динамически
... __callStatic() нарушает или соответствует большой картине языковых конструкций. Или это новая языковая конструкция целиком.
Это конструкция динамического языка. Не уверен, что эта функциональность существует на всех динамических языках, но она работает в PHP. Это ничего не нарушает, просто вводит новую парадигму сквозных функций catch-all, когда вызываемая вами функция не существует/недоступна в текущей области.
1 Marlies [2013-11-07 19:40:00]
Я не совсем уверен, почему здесь важна __callStatic()?
Я не совсем понимаю разницу между:
class Foo {
static function bar() {
$obj = new Foo();
$obj->quux();
}
function quux() {
return "whatever";
}
}
и ваш пример? В обоих сценариях вы вызываете статический метод, который вызывает другой метод для объекта того же класса.
Да, это возможно. На самом деле это говорит о том, что вы, возможно, захотите реорганизовать свой код. В примере вы создаете объект с его состоянием по умолчанию, выполняете на нем метод и затем бросаете объект. Это указывает на то, что метод, который делает, фактически не нуждается в состоянии объектов. Это означает, что он либо не принадлежит этому классу, либо просто может быть переписан как статический метод.
И знаете ли вы о __call? Он делает то же самое, что и __callStatic, но для объектов, а не для классов. Например. $Foo- > myMissingMethod(); будет идти в __call, если такой метод существует для класса, для которого $foo является экземпляром.