Как установить контроллер / действие на страницу не найдена - PullRequest
9 голосов
/ 03 октября 2010

У меня есть контроллер и действие, к которому я обращаюсь через пользовательский URL.Исходный маршрут по-прежнему доступен, хотя в расположении по умолчанию

zend.com/controller/action

Как я могу изменить это для имитации «Страница не найдена», когда пользователь пытается получить доступ к этому URL?Возможно ли это?

Ответы [ 7 ]

6 голосов
/ 15 октября 2010

Если обработчик действия используется для ответа на оба URL-адреса, сначала необходимо определить, какой URL-адрес запрашивается (используя $ this -> _ request-> getRequestUri ()). Если обнаружен URL-адрес по умолчанию, я думаю, что самый простой способ создать «страницу не найдена» - использовать

$this->_redirect("/path/to/simulated/404/page") 

и настройте контроллер и действие для ответа.

Хотя на самом деле это не отправит HTTP 404. Я думаю, что для этого вам нужно вызвать исключение в вашем обработчике действий. Я не знаю, каков официальный "зенди" способ сделать это, но, похоже, это работает:

throw new Zend_Controller_Action_Exception('Not Found', 404);
6 голосов
/ 03 октября 2010

Вы можете изменить скрипт основного контроллера, чтобы перенаправить определенное имя контроллера и имя действия на новую страницу.Но, вероятно, проще добавить новое правило в файл .htaccess, указывающее, что этот конкретный URL-адрес должен быть перенаправлен на страницу ошибки.Пример:

RewriteRule ^controller/action/?$ / [R=404,L]

Или перенаправить страницу на страницу с ошибкой на вашем сайте:

RewriteRule ^controller/action/?$ /error/page-not-found/ [L]
3 голосов
/ 18 октября 2010

По умолчанию маршрутизатор включает маршруты по умолчанию для :module/:controller/:action/ и :controller/:action/. Вы можете отключить их с помощью:

$router->removeDefaultRoutes();

тогда будут работать только те маршруты, которые вы установили. Если вы все еще хотите использовать маршруты по умолчанию для каких-то других вещей, вам нужно будет либо опубликовать один из других ответов, либо добавить свои собственные маршруты по умолчанию, которые будут соответствовать всем, кроме модулей / контроллеров, для которых у вас есть собственные маршруты. .

3 голосов
/ 15 октября 2010

Вам необходимо использовать:

$this->getResponse()->setHttpResponseCode(404);

И создайте свой собственный вид 404

$this->view->message = 'Page not found';

Или вы можете перенаправить на контроллер ошибок, например

$this->_forward('page-not-found', 'error');

Наконец, если у вас в контроллере ошибок

//...
switch ($errors->type) {
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:

                // 404 error -- controller or action not found
                $this->getResponse()->setHttpResponseCode(404);
                $this->view->message = 'Page not found';
                break;
//...

Вы можете просто сделать, как сказал @bogeymin:

throw new Zend_Controller_Action_Exception('Not Found', 404);
3 голосов
/ 15 октября 2010

Если вы ищете решения, отличные от mod_rewrite, вы можете создать маршрут Regex , соответствующий действиям, которые вам нужно скрыть.

Другое решение - ограничить доступ к действиям с помощью Zend_Acl , рассматривая каждое действие как ресурс ACL.

Но самое простое и легкое решение по-прежнему mod_rewrite в .htaccess.

Edit:

Как видите, это можно сделать разными способами. Но, вероятно, вам понадобится какой-то переключатель , чтобы все же как-то разрешить доступ к «скрытому» действию. В этом случае используйте:

  • mod_rewrite для быстрого внедрения (для переключения требуется, чтобы человек знал .htaccess правила)
  • Zend_Router - человек, который знает правильный маршрут, все еще может получить доступ к функции
  • Zend_Acl + Zend_Auth для масштабируемого и безопасного решения.

Если вам не нужны аутентифицированные пользователи, Zend_Acl в сочетании с Zend_Router может быть решением.

Для интеллектуальной обработки исключений и создания списков ACL см. Этот (и другие посты в этом блоге):

Обработка ошибок в Zend Framework | CodeUtopia - блог Яни Хартикайнен

2 голосов
/ 21 октября 2010

Если вы не хотите удалять маршрут по умолчанию, как подсказывает @ Tim Fountain , вы должны сделать что-то подобное в вашем контроллере (либо preDispatch, либо whateverAction методы)

$router = $this->getFrontController()->getRouter();
$route = $router->getCurrentRouteName();
// if we reached this controller/action from the default route, 404
if ($route == 'default')
{
  throw new Zend_Controller_Action_Exception('Not Found', 404);
}
0 голосов
/ 22 октября 2010

Я думаю, все ответы выше неверны.Они показывают способы достижения того же самого, но представляют логику в неправильном месте в вашем приложении, что в конечном итоге может вызвать проблемы в дальнейшем.

Правильная часть вашей логики маршрута, насколько чрезвычайно проста, в маршрутах,Чего не хватает, так это того, что маршрут по умолчанию Zend_Controller_Router_Route_Module не позволяет добавлять исключения для определенных маршрутов.Так что вам нужно сделать, это удалить маршрут по умолчанию из ваших маршрутов и добавить новый собственный маршрут (который должен функционировать точно так же, как маршрут по умолчанию, но допускает исключения) на его месте.

Вы можете написатьновый маршрут путем расширения класса маршрута по умолчанию.

class My_Custom_Route extends Zend_Controller_Router_Route_Module
{
    protected $_excludes = array();

    public function exclude($abc)
    {
         //add to $_excludes here the controller/action you want to exclude
    }

    public function match($abc)
    {
         //add functionality here that denies if the mod/contr/action is in $_excludes
         //you can also add this in a separate method
         //re-use parent code
    }
}

Теперь вы можете добавить добавить исключения, например, в файле конфигурации, и загрузить + добавить исключения в месте, где вы инициируете новый маршрут (идобавить его в роутер).Пошли.

...