2012-12-28 89 views

回答

38

您可以設置調度程序爲您執行此操作。

當你引導你的應用程序,你可以做到這一點($di是你DI廠):

use \Phalcon\Mvc\Dispatcher as PhDispatcher; 

$di->set(
    'dispatcher', 
    function() use ($di) { 

     $evManager = $di->getShared('eventsManager'); 

     $evManager->attach(
      "dispatch:beforeException", 
      function($event, $dispatcher, $exception) 
      { 
       switch ($exception->getCode()) { 
        case PhDispatcher::EXCEPTION_HANDLER_NOT_FOUND: 
        case PhDispatcher::EXCEPTION_ACTION_NOT_FOUND: 
         $dispatcher->forward(
          array(
           'controller' => 'error', 
           'action'  => 'show404', 
          ) 
         ); 
         return false; 
       } 
      } 
     ); 
     $dispatcher = new PhDispatcher(); 
     $dispatcher->setEventsManager($evManager); 
     return $dispatcher; 
    }, 
    true 
); 

創建ErrorController

<?php 

/** 
* ErrorController 
*/ 
class ErrorController extends \Phalcon\Mvc\Controller 
{ 
    public function show404Action() 
    { 
     $this->response->setStatusCode(404, 'Not Found'); 
     $this->view->pick('404/404'); 
    } 
} 

和404視圖(/views/404/404.volt

<div align="center" id="fourohfour"> 
    <div class="sub-content"> 
     <strong>ERROR 404</strong> 
     <br /> 
     <br /> 
     You have tried to access a page which does not exist or has been moved. 
     <br /> 
     <br /> 
     Please click the links at the top navigation bar to 
     navigate to other parts of the site, or 
     if you wish to contact us, there is information in the About page. 
     <br /> 
     <br /> 
     [ERROR] 
    </div> 
</div> 
+0

這對我來說非常有幫助(幾乎精確的複製,除了控制器/操作名稱)。非常感謝! – Trenton

+0

完美運作。 – vee

+0

以及如果我想從404頁面以外的某些操作設置503狀態頁面,該怎麼辦?我可以將狀態碼設置爲參數等,並從ErrorController中讀取它嗎?我怎樣才能做到這一點 ? – alexglue

3

您也可以在errorC中設置標題ontroller by

class ErrorController extends ControllerBase 
{ 
    public function error404Action() 
    { 
     $this->response->setHeader('HTTP/1.0 404','Not Found'); 
     // $this->response->setHeader(404, 'Not Found'); <- did not work 
    } 
} 

而之前,在控制器中發生錯誤的地方,可以轉發到這個錯誤控制器。

class IndexController extends ControllerBase 
{ 
    public function indexAction() 
    { 
     $id = (int)$this->getId($param); 
     if ($id > 0) { 

      // do you stuff 
     } else { 
      $this->dispatcher->forward(array(
       'controller' => 'error', 'action' => 'error404') 
      ); 
     } 
    } 
} 

這是一個快速和骯髒的(?)的方式,也是不錯的,如果你得到來自數據庫的內容,並希望拋出一個錯誤,如果沒有被發現。

5

由季莫普洛斯提出的解決辦法是行不通的。它會產生一個循環條件。

Phalcon路由器組件有一個默認行爲,提供了一個非常簡單的路由,它始終需要一個與以下模式匹配的URI:/:controller /:action /:params。這會導致很多問題,因爲Phalcon將搜索一個當服務器收到請求的URL不匹配任何定義的路由時不存在的控制器。

所以,首先,你必須禁用這種行爲。這是可以做到的Router實例創建過程中傳遞FALSE,如下:

$router = Phalcon\Mvc\Router(FALSE); 

在這一點上,你可以使用@阮仲砰提出的解決方案。

$router->notFound(
    [ 
    "namespace" => "MyNamespace\Controller" 
    "controller" => "index", 
    "action" => "route404" 
    ] 
); 

重要的是要注意,如果您使用的是命名空間的調度員將無法找到控制器,除非你指定它,就像我上面做了很重要的。

這不僅是最簡單的解決方案,而且是唯一可行的解​​決方案。

+0

如果通過將false傳遞給Router來禁用,則無法找到所有其他路由,並且所有頁面都轉到404路由。 – vee

+2

@vee,這是不正確的。只有在不定義路線時纔會發生這種情況:路徑與其相對控制器/操作之間的映射。正如我上面所寫的,路由器有一個默認行爲來匹配/:controller /:action /:params,但是你可以自由地定義你的路由和它們相關的行爲之間的關聯。然後你可以禁用默認行爲。在downvote之前閱讀文檔。 – noun

+0

我被閱讀文檔。並且我已經定義了路線並且已經測試過這是行不通的。 //創建路由器 $ router = new \ Phalcon \ Mvc \ Router(false); $ router-> add( '/ index/page3 /([a-zA-Z0-9 _-] +)/([a-zA-Z0-9 _-] +)/ {pagename}', array( '控制器'=> '索引', '動作'=> 'PAGE3', '滾'=> 1, '軌道'=> 2, ) ); $ router-> not found( array( 「controller」=>「error」, 「action」=>「e404」 ) ); 轉到http:// localhost/phalcon />頁面未找到 轉到http:// localhost/phalcon/index/page3>頁面未找到 轉到路由中定義的任何頁面>找不到頁面 – vee

相關問題