2012-02-16 9 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つのリクエストの設定が間違っていると思われています。ヘルパーコードも編集してコメントを追加しました。

EDIT2:Patrick、あなたは大丈夫です!私は再確認し、私は無限ループに陥っていた:ログインしていないページへのアクセス=>ログインページへ:-D今日の何時間も無駄に...とにかくうまくいく皆さん。

+0

CSysTracerはPHP's tick functionを使用してトリックを行います。後で[KCachegrind](http://kcachegrind.sourceforge.net/)または[wincachegrind](http://sourceforge.net/projects/wincachegrind/)のいずれかで出力ファイルを調べることができます。 –

+0

ありがとう、私はします。 – FredRoger

答えて

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

ロールに関係なく、常にログインコントローラにアクセスする権限がありますか。

とにかく、ZFのディスパッチ・ループが決して完了しない無限ループに終わるように思えます。

+0

あなたは大丈夫です!私は再確認し、私は無限ループに落ちていた:ログインしていないページへのアクセス=>ログインページへ:-D今日の何時間も無駄だ...とにかくうまく終わる! :-Dありがとう – FredRoger

1

デバッガが利用できない場合は、純粋なPHPコードを使用できます。ここでは、CSysTracerと呼ばれる小さなヘルパークラスを使用してオプションがあります。このインターフェイスに基づいて

この具体的なインスタンスに

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); 
    } 

} 

を作成

abstract class CSTReportDelegate { 

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

} 

... CSysTracerに渡し:

CSysTracer::setReportDelegate(new CSTSimpleReportDelegate()); 

...と使用して、トレースステートメントを有効にしますこれは:

CSysTracer::start(5); 

CSTSimpleReportDelegateは出力を出力しますが、ログファイルにstuffなどを書き込むことができます。特定のステートメントに選択的な書き込みを行います。

このバージョンのCSysTracerは、グローバル変数の変更を追跡することに注意してください。それを書き直して各ステートメントを記録するのは簡単です。xdebugのことで、あなたは(http://xdebug.org/docs/profile)プロファイリングを有効]ができ、このような場合について

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 ]; 

     } 

    } 

} 
関連する問題