CakePHP 控制器中的 __call() 函数?
CakePHP 的控制器中可以使用 __call()
函数吗?我在 Zend Framework 中使用了这个功能。
class UsersController extends AppController {
function home(){
/*some action*/
}
function __call($m, $p){
print_r($m);
print_r($p);
}
}
我收到这样的错误:
UsersController 中缺少方法
<前><代码>对于 URL site.com/users/somemethodsnotincontoller
is __call()
function available in CakePHP's controllers? I used this function in Zend Framework.
class UsersController extends AppController {
function home(){
/*some action*/
}
function __call($m, $p){
print_r($m);
print_r($p);
}
}
I'm getting error like this:
Missing Method in UsersController
<?php class UsersController extends AppController { var $name = 'Users'; function somemethodsnotincontoller() { } } ?>
for the URL site.com/users/somemethodsnotincontoller
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
正如许多人在这里指出的那样,__call() 是 PHP5 语言本机“神奇”方法,用于捕获对不存在的类方法的调用。
然而,Cake 的核心(我认为它是调度程序)在调用该方法之前首先检查该方法是否存在,如果不存在,则会呈现缺少方法的错误。
解决方案可能是您创建自己的 AppError 类,并在其中处理“catch all”方法。
烹饪书中错误处理下的信息量有限
As many have pointed out here, __call() is a native PHP5 language "magic" method for catching calls to class methods that don't exist.
HOWEVER, Cake's core (I think it's the dispatcher) checks to see if the method exists first before calling it, and if it doesn't it renders the missing method error.
A solution might be for you to create your own AppError class, and handle the "catch all" method in there.
There is a limited amount of information in the cook book under Error handling
是的,但它不起作用,因为 CakePHP 通过
ReflectionMethod
调用操作,并以这种方式调用 不被
_call
处理。Yes but it won't work because CakePHP invokes actions through
ReflectionMethod
and methods called this way are not processed by
_call
.用它来做什么?
__call() 方法是 PHP 中的一个构造,您可以在类中使用它,它允许您“捕获”对类中不存在的方法的显式调用。
来自 PHP.net:
所以答案是是,只要您使用 PHP 5 或更高版本。
Used it for what?
The __call() method is a construct in PHP that you can use from within classes that allow you to "catch" calls to methods that don't exist in the class explicitly.
From PHP.net:
So the answer is yes, as long as you are using PHP 5 or up.
__call() 是一种语言构造,因此它在支持它的所有 php 版本中都可用。
__call() is a language construct so it is available in all versions of php that support it.
__call() 是 PHP 的一种神奇方法,而不是任何特定的框架。没有任何上下文就不可能回答这个问题,因为 __call() 是在特定对象中定义的,而不是全局的。由于 CakePHP 宣称它与 php4 兼容,并且 __call() 是在 php5 中引入的,所以我会说不。
我查看了 Models 的生产分支,发现有一个 call__() 方法,它看起来像是试图模拟 PHP5 的 __call() 。
https:// trac.cakephp.org/browser/branches/1.2.xx/cake/libs/model/model.php?rev=4211#L437
编辑(回复评论):
看看 Cake 的基本控制器中,控制器中似乎没有一个“包罗万象”的方法可以模仿 Zend 的 __call() 实现。实现此目的的替代方法是设置类似于 cake 页面路由的路由,以捕获针对控制器的所有操作并将它们发送到单个方法。
基本控制器的 Cake Trac:
https://trac。 cakephp.org/browser/branches/1.2.xx/cake/libs/controller/controller.php?rev=4211
Cake 路由文档:
http://book.cakephp.org/view/46/Routes-Configuration
我引用的文档中的示例之一看起来像是您可以用来完成我上面提到的任务的东西:
无论给定的操作如何,始终使用索引操作。
__call() is a magic-method of PHP, not any particular framework. It's impossible to answer this question without any context since __call() is defined in a particular object, not globally. Since CakePHP touts the fact that it is php4 compatible and __call() was introduced in php5 I would say no.
I looked at the production branch for Models and there is a call__() method, which looks like it tries to emulate PHP5's __call().
https://trac.cakephp.org/browser/branches/1.2.x.x/cake/libs/model/model.php?rev=4211#L437
Edit (Responding to comment):
Looking at Cake's base controller, there does not appear to be a 'catch-all' method available in controllers that mimics Zend's implementation of __call(). Your alternative to accomplish this would be to setup a route similar to cake's page route to catch all actions directed at a controller and send them to a single method.
Cake Trac for base controller:
https://trac.cakephp.org/browser/branches/1.2.x.x/cake/libs/controller/controller.php?rev=4211
Cake documentation on routing:
http://book.cakephp.org/view/46/Routes-Configuration
One of the examples in that documentation I referenced looks like something you can play with to accomplish what I mentioned above:
Regardless of the given-action, always use the index action.
在CakePHP 3中,您绝对可以使用
__call
,只需确保控制器定义isAction()
即可。例如:In CakePHP 3, you definitely can use
__call
, just ensure that the controller definesisAction()
. For example:__call
是 PHP 5 的神奇方法 (参见“方法重载 ”了解更多详情)。如果您使用 PHP 5(如果您使用的是 Zend Framework),您可以在类中使用
__call
方法,而不取决于您使用的框架与. 一起工作。__call
is one of PHP 5's magic methods (see "Method overloading" for more details).If you are using PHP 5 (and you are, if you are usinf Zend Framework), you can have a
__call
method in your classes, not depending on the framework you are working with.