2012-02-16 96 views
4

我想在我的应用程序中使用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); 
    } 
} 

助手是不是在控制器中使用。我想我的应用程序,看看是否所有是正确的,我得到这个错误:

Fatal error: Maximum execution time of 30 seconds exceeded in /usr/share/php/ZendFramework-1.11.11/Zend/Filter/PregReplace.php on line 171

有了这个调用堆栈:

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,但它始终是相同的:第一4堆仍然不变,第五反映max_execution_time(30秒=> 31.7462,40秒=> 42.6546等等)

所以我怀疑Zend_Controller_Front->dispatch()是我的问题的根源,但为什么它始终以最大时间?我有点困惑。有人对我应该挖掘的地方有一些想法吗?

编辑:我进一步在我的调试。当用户不被允许时,我现在怀疑我的帮助器中的4个请求设置是错误的。我也编辑了帮手代码并添加了评论。

编辑2:帕特里克,你是如此的正确!我重新检查过,并且陷入了一个无限循环:没有登录页面登录页面去登录页面:今天浪费了多少时间......无论如何它结束了,非常感谢每一个人。

+0

对于这样的情况下,可以先[启用分析](http://xdebug.org/docs/profile):

CSysTracer确实使用PHP's tick function特技。稍后,您可以通过[KCachegrind](http://kcachegrind.sourceforge.net/)或[wincachegrind](http://sourceforge.net/projects/wincachegrind/)检查输出文件。 – 2012-02-16 20:40:08

+0

谢谢,我会的。 – FredRoger 2012-02-16 21:53:23

回答

5
if (!$this->_acl->isAllowed($role, $resource, $privilege)) { 
    $request->setModuleName('default'); 
    $request->setControllerName('login'); 
    $request->setActionName('login'); 
    $request->setDispatched(false);    
} 

您确定您总是有权限访问登录控制器而不管角色吗?

无论如何,这听起来像你最终在一个无限循环,ZF的调度循环从未完成。

+0

你真是太棒了!我重新检查了一下,我陷入了一个无限循环:没有登录页面登录页面去登录页面:今天多么浪费时间......无论如何它结束了! :-D谢谢 – FredRoger 2012-02-16 21:52:38

1

如果调试器不可用,则可以使用纯PHP代码。这是一个选项,使用称为CSysTracer的小型助手类。

基于该接口的:

abstract class CSTReportDelegate { 

    abstract public function emitVariableChange($variableName, $oldValue, $newValue); 
    abstract public function emitVariableSetNew($variableName, $newValue); 

} 

创造了这个具体的实例

class CSTSimpleReportDelegate extends CSTReportDelegate { 

    public function emitVariableChange($variableName, $oldValue, $newValue) { 
     echo '<br />[global/change] '. $variableName . ' : ' . print_r($oldValue, true) . ' &rarr; ' . print_r($newValue, true); 
    } 

    public function emitVariableSetNew($variableName, $newValue) { 
     echo '<br />[global/init] '. $variableName . ' &rarr; ' . print_r($newValue, TRUE); 
    } 

} 

...把​​它传递给CSysTracer:

CSysTracer::setReportDelegate(new CSTSimpleReportDelegate()); 

...和使用跟踪启用声明这个:

CSysTracer::start(5); 

虽然CSTSimpleReportDelegate打印输出,但它可以将内容写入日志文件,并且例如对某些语句做有选择的写操作。

请注意,此版本的CSysTracer跟踪全局变量的变化。重写它来记录每条语句非常简单。通过Xdebug的

class CSysTracer { 

    static protected 
     $reportDelegate; 

    static private 
     $globalState = array(); 

    static private 
     $traceableGlobals = array(); 

    static private 
     $globalTraceEnabled = FALSE; 

    const 
     DEFAULT_TICK_AMOUNT = 1; 

    static public 
    function setReportDelegate(CSTReportDelegate $aDelegate) { 
     self::$reportDelegate = $aDelegate; 
    } 


    static public 
    function start($tickAmount = self::DEFAULT_TICK_AMOUNT) { 

     register_tick_function (array('CSysTracer', 'handleTick')); 

    } 


    static public 
    function stop() { 

     unregister_tick_function(array('CSysTracer', 'handleTick')); 

    } 

    static public 
    function evalAndTrace($someStatement) { 

     declare(ticks = 1); { 
      self::start(); 
      eval($someStatement); 
      self::stop(); 
     } 
    } 

    static public 
    function addTraceableGlobal($varName) { 

     if (is_array($varName)) { 
      foreach($varName as $singleName) { 
       self::addTraceableGlobal($singleName); 
      } 
      return; 
     } 

     self::$traceableGlobals[ $varName ] = $varName; 

    } 

    static public 
    function removeTraceableGlobal($varName) { 
     unset(self::$traceableGlobals[ $varName ]); 
    } 

    /** 
    * Main function called at each tick. Calls those functions, which 
    * really perform the checks. 
    * 
    */ 
    static public 
    function handleTick() { 

     if (TRUE === self::$globalTraceEnabled) { 
      self::traceGlobalVariable(); 
     } 

    } 

    static public 
    function enableGlobalsTrace() { 
     self::$globalTraceEnabled = TRUE; 
    } 


    static public 
    function disableGlobalsTrace() { 
     self::$globalTraceEnabled = FALSE; 
    } 

    static public 
    function traceGlobalVariable() { 

     foreach(self::$traceableGlobals as $aVarname) { 

      if (! isset($GLOBALS[ $aVarname ])) { 
       continue; 
      } 

      if (! isset(self::$globalState[ $aVarname ])) { 

       self::$reportDelegate->emitVariableSetNew($aVarname, $GLOBALS[ $aVarname ]); 
       self::$globalState[ $aVarname ] = $GLOBALS[ $aVarname ]; 
       continue; 
      } 

      if (self::$globalState[ $aVarname ] !== $GLOBALS[ $aVarname ]) { 

      self::$reportDelegate->emitVariableChange($aVarname, self::$globalState[ $aVarname ], $GLOBALS[ $aVarname ]); 

      } 

      self::$globalState[ $aVarname ] = $GLOBALS[ $aVarname ]; 

     } 

    } 

} 
相关问题