Wprowadzenie do Zend Framework

     Nauka Zend Framework

    appendix

     Przewodnik po Zend Framework


  • Zend_Gdata
  • Zend_Http
  • Zend_InfoCard
  • Zend_Json
  • Zend_Layout
  • Zend_Ldap
  • Zend_Loader
  • Zend_Locale
  • Zend_Log
  • Zend_Mail
  • Zend_Markup
  • Zend_Measure
  • Zend_Memory
  • Zend_Mime
  • Zend_Navigation
  • Zend_Oauth
  • Zend_OpenId
  • Zend_Paginator
  • Zend_Pdf
  • Zend_ProgressBar
  • Zend_Queue
  • Zend_Reflection
  • Zend_Registry
  • Zend_Rest

  • Zend_Search_Lucene
  • Zend_Serializer
  • Zend_Server
  • Zend_Service
  • Zend_Session
  • Zend_Soap
  • Zend_Tag
  • Zend_Test
  • Zend_Text
  • Zend_TimeSync
  • Zend_Tool
  • Zend_Tool_Framework
  • Zend_Tool_Project
  • Zend_Translate
  • Zend_Uri
  • Zend_Validate
  • Zend_Version
  • Zend_View
  • Zend_Wildfire
  • Zend_XmlRpc
  • ZendX_Console_Process_Unix
  • ZendX_JQuery
  • Translation 21.3% Update 2011-11-16 - Revision 24356 - Version ZF 1.11.x

    22.12. Wyjątki MVC

    22.12.1. Wprowadzenie

    Komponenty MVC w Zend Framework używają kontrolera frontowego, co oznacza, że wszystkie żądania do danej strony przechodzą przez pojedynczy punkt. W rezultacie wszystkie wyjątki ostatecznie zbierane są w kontrolerze frontowym, pozwalając programiście na obsłużenie ich w jednym miejscu.

    Jakkolwiek, wiadomości o wyjątkach oraz informacje o backtrace często zawierają wrażliwe informacje o systemie, jak np. zapytania SQL, informacje o lokacjach plików i wiele innych. Aby pomóc ci chronić swój serwis, domyślnie Zend_Controller_Front łapie wszystkie wyjątki i rejestruje je w obiekcie odpowiedzi; z kolei, obiekt odpowiedzi domyślnie nie wyświetla wiadomości o wyjątkach.

    22.12.2. W jaki sposób możesz obsługiwać wyjątki?

    Obecnie w komponentach MVC wbudowanych jest kilka mechanizmów pozwalających na obsługę wyjątków

    • Domyślnie rejestrowana i aktywna jest wtyczka obsługi błędów. Ta wtyczka została stworzona aby obsługiwać:

      • Błędy spowodowane brakującym kontrolerem lub akcją

      • Błędy występujące wewnątrz akcji kontrolerów

      Wtyczka działa w oparciu o metodę postDispatch(), i sprawdza czy obiekt uruchamiający, kontroler akcji, lub inny obiekt wyrzucił wyjątek. Jeśli tak, przekazuje ona żądanie do kontrolera obsługi błędu.

      Ta wtyczka obsłuży większość sytuacji, w których został wyrzucony wyjątek, a także poprawnie obsłuży brakujące kontrolery oraz akcje.

    • Zend_Controller_Front::throwExceptions()

      Przekazująć logiczną wartość true do tej metody, możesz nakazać kontrolerowi frontowemu aby zamiast składować wyjątki w obiekcie odpowiedzi, wyrzucił je, żebyś mógł obsłużyć je samodzielnie. Na przykład:

      $front->throwExceptions(true);
      try {
          
      $front->dispatch();
      } catch (
      Exception $e) {
          
      // sam obsłuż wyjątki
      }

      Ta metoda jest najprawdopodobniej najłatwiejszym sposobem dodania własnej obsługi wyjątków do twojej aplikacji używającej kontrolera frontowego.

    • Zend_Controller_Response_Abstract::renderExceptions()

      Przekazując logiczną wartość true do tej metody, możesz nakazać obiektowi odpowiedzi aby renderował on wyjątki gdy sam będzie renderowany. W takim scenariuszu, każdy wyjątek wyrzucony w twojej aplikacji będzie wyświetlony. To jest jedynie rekomendowane dla nieprodukcyjnych środowisk.

    • Zend_Controller_Front::returnResponse() oraz Zend_Controller_Response_Abstract::isException()

      Przekazanie wartości logicznej true do metody Zend_Controller_Front::returnResponse(), spowoduje, że obiekt Zend_Controller_Front::dispatch() nie będzie renderował odpowiedzi, a zamiast tego ją zwróci. Gdy już masz odpowiedź, możesz sprawdzić czy są w niej wyjątki używając metody isException(), a następnie odebrać wyjątki używając metody getException(). Na przykład:

      $front->returnResponse(true);
      $response $front->dispatch();
      if (
      $response->isException()) {
          
      $exceptions $response->getException();
          
      // obsługa wyjątków ...
      } else {
          
      $response->sendHeaders();
          
      $response->outputBody();
      }

      Główną zaletą, dzięki której ta metoda umożliwia więcej niż Zend_Controller_Front::throwExceptions(), jest to, że możesz warunkowo wyświetlać odpowiedź po obsłudze wyjątków.

    22.12.3. Wyjątki MVC które możesz napotkać

    Różne komponenty MVC -- obiekt żądania, router, obiekt uruchamiający, kontrolery akcji, oraz obiekt odpowiedzi -- każdy może z różnych przyczyn wyrzucać wyjątki. Niektóre wyjątki mogą być warunkowo nadpisane, a inne są używane aby wskazać programiście potrzebę poprawienia aplikacji.

    Kilka przykładów:

    • Zend_Controller_Dispatcher::dispatch() domyślnie wyrzuci wyjątek jeśli zażądano nieprawidłowego kontrolera. Są dwa zalecane sposoby na obsłużenie tego:

      • Ustawienie parametru useDefaultControllerAlways.

        W twoim kontrolerze frontowym, lub w obiekcie uruchamiającym, dodaj poniższą dyrektywę:

        $front->setParam('useDefaultControllerAlways'true);

        // lub
        $dispatcher->setParam('useDefaultControllerAlways'true);

        Gdy ta flaga jest ustawiona, obiekt uruchamiający, użyje domyślnego kontrolera oraz akcji zamiast wyrzucania wyjątku. Minusem użycia tej metody jest to, że jakikolwiek błąd literowy w adresie dostępowym do twojej strony spowoduje wyświetlenie strony głównej, co może źle wpłynąć na optymalizację serwisu dla wyszukiwarek internetowych.

      • Wyjątek wyrzucany przez metodę dispatch() jest wyjątkiem Zend_Controller_Dispatcher_Exception zawierającym tekst 'Invalid controller specified'. Użyj jednej z metod opisanych w poprzedniej sekcji aby złapać wyjątek, a następnie przekierować do strony błędu lub do strony głownej.

    • Metoda Zend_Controller_Action::__call() wyrzuci wyjątek Zend_Controller_Action_Exception jeśli nie może uruchomić nieistniejącej metody akcji. Najczęściej będziesz chciał użyć jakiejś domyślnej akcji w kontrolerze w tego typu sprawach. Przykładowe metody za pomocą których możesz to osiśgnąć:

      • Rozszerzenie klasy Zend_Controller_Action i nadpisanie metody __call(). Na przykład:

        class My_Controller_Action extends Zend_Controller_Action
        {
            public function 
        __call($method$args)
            {
                if (
        'Action' == substr($method, -6)) {
                    
        $controller $this->getRequest()->getControllerName();
                    
        $url '/' $controller '/index';
                    return 
        $this->_redirect($url);
                }

                throw new 
        Exception('Invalid method');
            }
        }

        Powyższa metoda przechwytuje wszystkie wywołane niezdefiniowane akcje i przekierowuje żądanie do domyślnej akcji w kontrolerze.

      • Rozszerzenie klasy Zend_Controller_Dispatcher o nadpisanie metody getAction(), która sprawdza czy akcja istnieje. Na przykład:

        class My_Controller_Dispatcher extends Zend_Controller_Dispatcher
        {
            public function 
        getAction($request)
            {
                
        $action $request->getActionName();
                if (empty(
        $action)) {
                    
        $action $this->getDefaultAction();
                    
        $request->setActionName($action);
                    
        $action $this->formatActionName($action);
                } else {
                    
        $controller $this->getController();
                    
        $action     $this->formatActionName($action);
                    if (!
        method_exists($controller$action)) {
                        
        $action $this->getDefaultAction();
                        
        $request->setActionName($action);
                        
        $action $this->formatActionName($action);
                    }
                }

                return 
        $action;
            }
        }

        Powyższy kod sprawdza czy zażądana akcja istnieje w klasie kontrolera; jeśli nie, resetuje akcję do akcji domyślnej.

        Ta metoda jest wygodna ponieważ możesz w niewidoczny sposób zmienić akcję przed ostatecznym uruchomieniem. Jednak to także oznacza, że jakikolwiek błąd literowy w adresie URL może wciąż uruchomić żądanie poprawnie, co nie jest zbyt dobre dla optymalizacji dla wyszukiwarek internetowych.

      • Użycie metody Zend_Controller_Action::preDispatch() lub Zend_Controller_Plugin_Abstract::preDispatch() do zidentyfikowania nieprawidłowych akcji.

        Rozszerzając klasę Zend_Controller_Action i modyfikując metodę preDispatch(), możesz zmodyfikować wszystkie twoje kontrolery w taki sposób, aby przenosiły one żądanie do innej akcji lub przekierowywały zamiast uruchamiać akcję. Kod wyglądałby podobnie kod nadpisujący metodę __call(), który został przedstawiony wyżej.

        Alternatywnie, możesz sprawdzać te informacje we wtyczce globalnej. Zaletą tego rozwiązania jest to, że kontroler akcji staje się niezależny; jeśli twoja aplikacja składa się z różnorodnych kontrolerów akcji i nie wszystkie dziedziczą z tej samej klasy, ta metoda może dodać konsekwencji w obsłudze różnych klas.

        Przykład:

        class My_Controller_PreDispatchPlugin extends Zend_Controller_Plugin_Abstract
        {
            public function 
        preDispatch(Zend_Controller_Request_Abstract $request)
            {
                
        $dispatcher Zend_Controller_Front::getInstance()->getDispatcher();
                
        $controller $dispatcher->getController($request);
                if (!
        $controller) {
                    
        $controller $dispatcher->getDefaultControllerName($request);
                }
                
        $action     $dispatcher->getAction($request);

                if (!
        method_exists($controller$action)) {
                    
        $defaultAction $dispatcher->getDefaultAction();
                    
        $controllerName $request->getControllerName();
                    
        $response Zend_Controller_Front::getInstance()->getResponse();
                    
        $response->setRedirect('/' $controllerName '/' $defaultAction);
                    
        $response->sendHeaders();
                    exit;
                }
            }
        }

        W tym przykładzie sprawdzamy czy zażądana akcja jest dostępna w kontrolerze. Jeśli nie, przekierujemy żądanie do domyślnej akcji w kontrolerze, i kończymy wykonywanie skryptu.

    digg delicious meneame google twitter technorati facebook

    Comments

    Loading...