如何调试“最大执行时间”致命错误?
我正在尝试在我的应用程序中使用 Zend_acl 。我遵循了《Zend Framework in action》一书。 我添加了这个助手:
<?php
/**
* Zend Framework
*
* LICENSE "removed for clarity"
*
/** Zend_Controller_Action_Helper_Abstract */
require_once 'Zend/Controller/Action/Helper/Abstract.php';
class Bravo_Controller_Action_Helper_Acl extends Zend_Controller_Action_Helper_Abstract
{
protected $_action;
protected $_auth;
protected $_acl;
protected $_controllerName;
public function __construct(Zend_View_Interface $view = null, array $options = array())
{
$this->_auth = Zend_Auth::getInstance();
$this->_acl = $options['acl'];
//var_dump($this->_acl);die();
}
public function init()
{
$this->_action = $this->getActionController();
// add resource for this controller
$controller = $this->_action->getRequest()->getControllerName();
if(!$this->_acl->has($controller)) {
$this->_acl->add(new Zend_Acl_Resource($controller));
}
}
public function preDispatch()
{
$role = 'guest';
if ($this->_auth->hasIdentity()) {
$user = $this->_auth->getIdentity();
if(is_object($user)) {
$role = $this->_auth->getIdentity()->getUral()->getUralAccessNbr();
}
}
$request = $this->_action->getRequest();
$controller = $request->getControllerName();
$action = $request->getActionName();
$module = $request->getModuleName();
$this->_controllerName = $controller;
$resource = $controller;
$privilege = $action;
if (!$this->_acl->has($resource)) {
$resource = null;
}
//** EDIT: During my test, the user isn't allowed. I'm now suspecting the 4 requests setting to be wrong.
if (!$this->_acl->isAllowed($role, $resource, $privilege)) {
$request->setModuleName('default');
$request->setControllerName('login');
$request->setActionName('login');
$request->setDispatched(false);
}
}
public function allow($roles = null, $actions = null)
{
$resource = $this->_controllerName;
$this->_acl->allow($roles, $resource, $actions);
return $this;
}
public function deny($roles = null, $actions = null)
{
$resource = $this->_controllerName;
$this->_acl->deny($roles, $resource, $actions);
return $this;
}
}
并且引导:
<?php
class Agenda_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected function _initAcl()
{
// acl action helper
$acl = new Bravo_Acl_Acl();
$aclHelper = new Bravo_Controller_Action_Helper_Acl(null, array('acl' => $acl));
Zend_Controller_Action_HelperBroker::addHelper($aclHelper);
}
}
助手不在控制器中使用。我尝试了我的应用程序以查看是否一切正常,但收到此错误:
致命错误:/usr/share/php/ZendFramework-1.11.11/Zend/Filter/PregReplace.php 第 171 行超出最大执行时间 30 秒
使用此调用堆栈:
Call Stack
# Time Memory Function Location
1 0.0001 314556 {main}( ) ../index.php:0
2 0.3275 2039356 Zend_Application->run( ) ../index.php:29
3 0.3275 2039356 Zend_Application_Bootstrap_Bootstrap->run( ) ../Application.php:366
4 0.3276 2039412 Zend_Controller_Front->dispatch( ) ../Bootstrap.php:97
5 31.7462 4813252 Zend_Controller_Dispatcher_Standard->dispatch( ) ../Front.php:954
6 31.7470 4813944 Zend_Controller_Action->__construct( ) ../Standard.php:268
7 31.7470 4814144 Zend_Controller_Action_HelperBroker->__construct( ) ../Action.php:132
8 31.7472 4814924 Zend_Controller_Action_Helper_ViewRenderer->init( ) ../HelperBroker.php:253
9 31.7472 4814924 Zend_Controller_Action_Helper_ViewRenderer->initView( ) ../ViewRenderer.php:516
10 31.7473 4815260 Zend_Controller_Action_Helper_ViewRenderer->_getBasePath( ) ../ViewRenderer.php:469
11 31.7478 4815628 Zend_Filter_Inflector->filter( ) ../ViewRenderer.php:393
12 31.7489 4816768 Zend_Filter_Word_CamelCaseToSeparator->filter( ) ../Inflector.php:473
13 31.7489 4816768 Zend_Filter_PregReplace->filter( ) ../CamelCaseToSeparator.php:46
我尝试增加 max_execution_time,但它总是相同的:前四个堆栈仍然不变,第五个反映
max_execution_time
(30 秒=> 31.7462, 40 sec => 42.6546 等等)
所以我怀疑 Zend_Controller_Front->dispatch( )
是我的问题根源,但为什么它总是花费最大时间?我有点困惑。有人知道我应该在哪里挖掘吗?
编辑:我将进一步进行调试。我现在怀疑当用户不允许时,我的助手中的 4 个请求设置是错误的。我也编辑了帮助程序代码并添加了注释。
编辑2:帕特里克,你说得太对了!!!我重新检查了一下,发现自己陷入了无限循环: don't-have-acces-to-login-page => go-to-login-page :-D 今天真是浪费时间......无论如何结局很好谢谢大家。
I'm trying to use Zend_acl in my application. I followed the "Zend Framework in action" book.
I added this helper:
<?php
/**
* Zend Framework
*
* LICENSE "removed for clarity"
*
/** Zend_Controller_Action_Helper_Abstract */
require_once 'Zend/Controller/Action/Helper/Abstract.php';
class Bravo_Controller_Action_Helper_Acl extends Zend_Controller_Action_Helper_Abstract
{
protected $_action;
protected $_auth;
protected $_acl;
protected $_controllerName;
public function __construct(Zend_View_Interface $view = null, array $options = array())
{
$this->_auth = Zend_Auth::getInstance();
$this->_acl = $options['acl'];
//var_dump($this->_acl);die();
}
public function init()
{
$this->_action = $this->getActionController();
// add resource for this controller
$controller = $this->_action->getRequest()->getControllerName();
if(!$this->_acl->has($controller)) {
$this->_acl->add(new Zend_Acl_Resource($controller));
}
}
public function preDispatch()
{
$role = 'guest';
if ($this->_auth->hasIdentity()) {
$user = $this->_auth->getIdentity();
if(is_object($user)) {
$role = $this->_auth->getIdentity()->getUral()->getUralAccessNbr();
}
}
$request = $this->_action->getRequest();
$controller = $request->getControllerName();
$action = $request->getActionName();
$module = $request->getModuleName();
$this->_controllerName = $controller;
$resource = $controller;
$privilege = $action;
if (!$this->_acl->has($resource)) {
$resource = null;
}
//** EDIT: During my test, the user isn't allowed. I'm now suspecting the 4 requests setting to be wrong.
if (!$this->_acl->isAllowed($role, $resource, $privilege)) {
$request->setModuleName('default');
$request->setControllerName('login');
$request->setActionName('login');
$request->setDispatched(false);
}
}
public function allow($roles = null, $actions = null)
{
$resource = $this->_controllerName;
$this->_acl->allow($roles, $resource, $actions);
return $this;
}
public function deny($roles = null, $actions = null)
{
$resource = $this->_controllerName;
$this->_acl->deny($roles, $resource, $actions);
return $this;
}
}
And bootstrap:
<?php
class Agenda_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected function _initAcl()
{
// acl action helper
$acl = new Bravo_Acl_Acl();
$aclHelper = new Bravo_Controller_Action_Helper_Acl(null, array('acl' => $acl));
Zend_Controller_Action_HelperBroker::addHelper($aclHelper);
}
}
The Helper isn't use in the controller. I tried my app to see if all was right and I got this error:
Fatal error: Maximum execution time of 30 seconds exceeded in /usr/share/php/ZendFramework-1.11.11/Zend/Filter/PregReplace.php on line 171
With this call stack:
Call Stack
# Time Memory Function Location
1 0.0001 314556 {main}( ) ../index.php:0
2 0.3275 2039356 Zend_Application->run( ) ../index.php:29
3 0.3275 2039356 Zend_Application_Bootstrap_Bootstrap->run( ) ../Application.php:366
4 0.3276 2039412 Zend_Controller_Front->dispatch( ) ../Bootstrap.php:97
5 31.7462 4813252 Zend_Controller_Dispatcher_Standard->dispatch( ) ../Front.php:954
6 31.7470 4813944 Zend_Controller_Action->__construct( ) ../Standard.php:268
7 31.7470 4814144 Zend_Controller_Action_HelperBroker->__construct( ) ../Action.php:132
8 31.7472 4814924 Zend_Controller_Action_Helper_ViewRenderer->init( ) ../HelperBroker.php:253
9 31.7472 4814924 Zend_Controller_Action_Helper_ViewRenderer->initView( ) ../ViewRenderer.php:516
10 31.7473 4815260 Zend_Controller_Action_Helper_ViewRenderer->_getBasePath( ) ../ViewRenderer.php:469
11 31.7478 4815628 Zend_Filter_Inflector->filter( ) ../ViewRenderer.php:393
12 31.7489 4816768 Zend_Filter_Word_CamelCaseToSeparator->filter( ) ../Inflector.php:473
13 31.7489 4816768 Zend_Filter_PregReplace->filter( ) ../CamelCaseToSeparator.php:46
I tried to increase the max_execution_time
, but it's always the same: the first four stacks still unchanged and the fifth reflect the max_execution_time
(30 sec => 31.7462, 40 sec => 42.6546 and so on)
So I suspect the Zend_Controller_Front->dispatch( )
to be my source of problem, but why it take always the max time? I'm a bit confused. Someone have some idea of where I should dig?
EDIT: I'm going further in my debug. I'm now suspecting the 4 requests setting to be wrong in my helper when the user isn't allowed. I edited the helper code too and added a comment.
EDIT2: Patrik, you're so right!!! I rechecked and I had fall in an infinite loop: don't-have-acces-to-login-page => go-to-login-page :-D What a waste of time today... anyway it ends well thanks everybody.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您确定无论角色如何,您始终有权访问登录控制器吗?
不管怎样,听起来你最终陷入了无限循环,ZF 的调度循环永远不会完成。
Are you sure that you always have permission to access the login-controller regardless of role?
Anyway, it sounds like you end up in an infinite loop, where the dispatch-loop of ZF is never completed.
如果调试器不可用,您可以使用纯 PHP 代码。这里有一个选项,使用一个名为 CSysTracer 的小帮助器类。
基于此接口:
创建了此具体实例
...将其传递给 CSysTracer:
...并使用以下方式启用语句跟踪:
当 CSTSimpleReportDelegate 打印输出时,它可以将内容写入日志文件,例如对某些语句进行选择性写入。
请注意,此版本的 CSysTracer 跟踪全局变量的更改。重写它来记录每个语句非常简单。
CSysTracer 使用 PHP 的勾选函数来实现这一点:
In case a debugger isn't available, you could use pure PHP code. Here is an option, using a small helper class called CSysTracer.
Based on this interface:
created this concrete instance
... pass it to CSysTracer:
... and enable statement tracing using this:
While CSTSimpleReportDelegate prints output, it could write stuff to a log file and and e.g. do selective writes on certain statements.
Note, that this version of CSysTracer tracks changes of global variable. Rewriting it to log each statement is quite simple.
CSysTracer does the trick using PHP's tick function: