Php __callStatic():从静态上下文实例化对象?
我对PHP中的“静态”和“动态”函数和对象如何协同工作感到困惑,尤其是关于_callStatic() callStatic()的工作原理: 您可以有一个普通的类MyClass,在该类中您可以 放置一个名为uu callStatic()的静态函数,该函数仅被调用 当MyClass没有所需名称的静态函数时 i、 e.我调用Php __callStatic():从静态上下文实例化对象?,php,static,instantiation,magic-methods,Php,Static,Instantiation,Magic Methods,我对PHP中的“静态”和“动态”函数和对象如何协同工作感到困惑,尤其是关于_callStatic() callStatic()的工作原理: 您可以有一个普通的类MyClass,在该类中您可以 放置一个名为uu callStatic()的静态函数,该函数仅被调用 当MyClass没有所需名称的静态函数时 i、 e.我调用MyClass::newFunction() newFunction()被静态调用,但MyClass没有 请申报。因此,然后调用\uu callStatic(),并 你可以说 $m
MyClass::newFunction()代码>
newFunction()
被静态调用,但MyClass
没有
请申报。因此,然后调用\uu callStatic()
,并
你可以说
$myObject=new SomeOtherClass();
$myObject->newFunction();
调用您想要的函数,但在其他对象上
短版:
换句话说,\uuu callStatic()执行以下操作:
MyClass::newFunction();
这就隐藏了这一点:
(new SomeOtherClass())->newFunction();
现在说什么?看起来像是从一个类调用静态函数的代码,实际上是从另一个类调用该函数,并通过实例化来调用它,而不是静态调用
请解释一下强>
为什么要这样做?你能在其他地方做任何事情吗,比如C++或java?我正在寻找关于语言中静态和动态函数的简短、简洁但信息丰富的解释,在本例中,uu callStatic()是否违反了
或符合
语言结构的大局。或者它完全是一种新的语言构造。\uuu callStatic()
为开发人员提供了对静态方法调用作出反应的可能性,即使该方法不存在或从类外部无法访问(受保护)。这对于动态通用代码生成非常有用
示例:您有这样一个类:
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');
我不完全确定为什么这里与调用static()相关
我不太明白以下两者之间的区别:
class Foo {
static function bar() {
$obj = new Foo();
$obj->quux();
}
function quux() {
return "whatever";
}
}
你的例子呢?在这两种情况下,您都在调用一个静态方法,该方法在同一类的对象上调用另一个方法
是的,那是可能的。实际上,这样做意味着您可能需要重构代码。在本例中,您正在实例化一个具有默认状态的对象,对其执行一个方法,然后丢弃该对象。这意味着无论方法在做什么,实际上都不需要对象状态。这意味着它要么不属于这个类,要么可以简单地重写为一个静态方法本身
你知道你的电话吗?它与uu callStatic做的事情相同,但它是针对对象而不是类。例如$foo->myMissingMethod();如果$foo是其实例的类存在这样的方法,则将转到_调用
为什么要这样做
这是一个存在主义问题,但我认为答案是“因为你可以”。PHP是一种动态语言,这些结构\uuuu call
和\uuuu callStatic()
展示了它的强大功能,在某些情况下,这种功能非常有用
<>你能在别处做任何事情吗,比如C++或java?p>
不,他们没有类似的魔法方法
我正在寻找关于语言中的静态和动态函数的简短、简洁但信息丰富的解释
静态函数封装代码。即使没有实例化类,它们也存在。可以使用范围解析运算符调用它们。
动态功能很好,动态的
。。__callStatic()是否违反或符合语言结构的大局。或者它完全是一种新的语言结构
它是一种动态语言的结构。不确定此功能是否存在于所有动态语言中,但在PHP中确实存在。它没有违反任何规定,只是在当前范围内您调用的函数不存在/不可访问时引入了一种新的fall-through-catch-all函数范例。如何Test::notFound()代码>触发致命错误?也许你忘记了一个默认值:
案例来做这件事?我不明白你的意思。你能详细说明一下吗?(或者试试代码,看看吧。这是很好的自我解释)你当然是对的。是我的错。。由于存在\uu callStatic()
不会抛出致命错误。删除了那个。是一个坏例子。我否决了“[你]应该继续学习基础知识”,这是难以置信的假设和高傲,特别是对于一个合理的语言结构的问题。谢谢,我改为投票,谢谢你的回答,我觉得我很困惑,因为像C++这样的语言没有这样的“CaskALL”功能。我认为PHP唯一的新功能就是catchalls。我只是重写了C++中的那些,没有意识到它也能做到这一点,只是没有CATCAS.StaseBar()方法,它几乎就像一个代码块,只要你想,调用一个短的“别名”Fo:Bar();换句话说,我可以将bar函数从Foo中取出,并将其移动到全局范围中,并将其称为bar();但在Foo中使用bar更能说明bar在某种程度上属于面向对象的Foo。至于为什么要在bar()内实例化另一个对象,我不知道,但可能是基于某些用例,即希望避免编写实例化代码并将其隐藏在对静态函数的调用之后,因为在我的示例中,它更短。基本上在PHP中,您有常规函数(类声明之外)、对象方法(类定义中的函数)和静态方法(关键字为“static”的类定义中的函数)。对象方法根据对象的状态返回某些内容或更改状态。类方法与类相关(例如,可以返回对象的特定类型的实例)。