[MANUAL] English:
[zend.git] / documentation / manual / pl / module_specs / Zend_Controller-Exceptions.xml
bloba57f73ea4c71cb80cdfa8181406d0e9eb091be60
1 <sect1 id="zend.controller.exceptions">
2     <title>Wyjątki MVC</title>
4     <sect2 id="zend.controller.exceptions.introduction">
5         <title>Wprowadzenie</title>
7         <para>
8             Komponenty MVC w Zend Framework używają kontrolera frontowego, co
9             oznacza, że wszystkie żądania do danej strony przechodzą przez
10             pojedynczy punkt. W rezultacie wszystkie wyjątki ostatecznie
11             zbierane są w kontrolerze frontowym, pozwalając programiście na
12             obsłużenie ich w jednym miejscu.
13         </para>
15         <para>
16             Jakkolwiek, wiadomości o wyjątkach oraz informacje o backtrace
17             często zawierają wrażliwe informacje o systemie, jak np. zapytania
18             SQL, informacje o lokacjach plików i wiele innych. Aby pomóc ci
19             chronić swój serwis, domyślnie <code>Zend_Controller_Front</code>
20             łapie wszystkie wyjątki i rejestruje je w obiekcie odpowiedzi; z
21             kolei, obiekt odpowiedzi domyślnie nie wyświetla wiadomości o
22             wyjątkach.
23         </para>
24     </sect2>
26     <sect2 id="zend.controller.exceptions.handling">
27         <title>W jaki sposób możesz obsługiwać wyjątki?</title>
29         <para>
30             Obecnie w komponentach MVC wbudowanych jest kilka mechanizmów
31             pozwalających na obsługę wyjątków
32         </para>
34         <itemizedlist>
35             <listitem>
36                 <para>
37                     Domyślnie rejestrowana i aktywna jest <link
38                         linkend="zend.controller.plugins.standard.errorhandler">wtyczka
39                     obsługi błędów</link>. Ta wtyczka została stworzona aby
40                     obsługiwać:
41                 </para>
43                 <itemizedlist>
44                     <listitem><para>Błędy spowodowane brakującym kontrolerem lub akcją</para></listitem>
46                     <listitem><para>Błędy występujące wewnątrz akcji kontrolerów</para></listitem>
47                 </itemizedlist>
49                 <para>
50                     Wtyczka działa w oparciu o metodę <code>postDispatch()</code>,
51                     i sprawdza czy obiekt uruchamiający, kontroler akcji, lub
52                     inny obiekt wyrzucił wyjątek. Jeśli tak, przekazuje ona
53                     żądanie do kontrolera obsługi błędu.
54                 </para>
56                 <para>
57                     Ta wtyczka obsłuży większość sytuacji, w których został
58                     wyrzucony wyjątek, a także poprawnie obsłuży brakujące
59                     kontrolery oraz akcje.
60                 </para>
61             </listitem>
63             <listitem>
64                 <para><code>Zend_Controller_Front::throwExceptions()</code></para>
66                 <para>
67                     Przekazująć logiczną wartość true do tej metody, możesz
68                     nakazać kontrolerowi frontowemu aby zamiast składować
69                     wyjątki w obiekcie odpowiedzi, wyrzucił je, żebyś mógł
70                     obsłużyć je samodzielnie. Na przykład:
71                 </para>
73                 <programlisting role="php"><![CDATA[
74 $front->throwExceptions(true);
75 try {
76     $front->dispatch();
77 } catch (Exception $e) {
78     // sam obsłuż wyjątki
80 ]]>
81                 </programlisting>
83                 <para>
84                     Ta metoda jest najprawdopodobniej najłatwiejszym sposobem
85                     dodania własnej obsługi wyjątków do twojej aplikacji
86                     używającej kontrolera frontowego.
87                 </para>
88             </listitem>
90             <listitem>
91                 <para><code>Zend_Controller_Response_Abstract::renderExceptions()</code></para>
93                 <para>
94                     Przekazując logiczną wartość true do tej metody, możesz
95                     nakazać obiektowi odpowiedzi aby renderował on wyjątki gdy
96                     sam będzie renderowany. W takim scenariuszu, każdy wyjątek
97                     wyrzucony w twojej aplikacji będzie wyświetlony. To jest
98                     jedynie rekomendowane dla nieprodukcyjnych środowisk.
99                 </para>
100             </listitem>
102             <listitem>
103                 <para>
104                     <code>Zend_Controller_Front::returnResponse()</code> oraz
105                     <code>Zend_Controller_Response_Abstract::isException()</code>
106                 </para>
108                 <para>
109                     Przekazanie wartości logicznej true do metody
110                     <code>Zend_Controller_Front::returnResponse()</code>,
111                     spowoduje, że obiekt
112                     <code>Zend_Controller_Front::dispatch()</code> nie będzie
113                     renderował odpowiedzi, a zamiast tego ją zwróci. Gdy już
114                     masz odpowiedź, możesz sprawdzić czy są w niej wyjątki
115                     używając metody <code>isException()</code>, a następnie
116                     odebrać wyjątki używając metody <code>getException()</code>.
117                     Na przykład:
118                 </para>
120                 <programlisting role="php"><![CDATA[
121 $front->returnResponse(true);
122 $response = $front->dispatch();
123 if ($response->isException()) {
124     $exceptions = $response->getException();
125     // obsługa wyjątków ...
126 } else {
127     $response->sendHeaders();
128     $response->outputBody();
131                 </programlisting>
133                 <para>
134                     Główną zaletą, dzięki której ta metoda umożliwia więcej niż
135                     <code>Zend_Controller_Front::throwExceptions()</code>, jest
136                     to, że możesz warunkowo wyświetlać odpowiedź po obsłudze
137                     wyjątków.
138                 </para>
139             </listitem>
140         </itemizedlist>
141     </sect2>
143     <sect2 id="zend.controller.exceptions.internal">
144         <title>Wyjątki MVC które możesz napotkać</title>
146         <para>
147             Różne komponenty MVC -- obiekt żądania, router, obiekt uruchamiający,
148             kontrolery akcji, oraz obiekt odpowiedzi -- każdy może z różnych
149             przyczyn wyrzucać wyjątki. Niektóre wyjątki mogą być warunkowo
150             nadpisane, a inne są używane aby wskazać programiście potrzebę
151             poprawienia aplikacji.
152         </para>
154         <para>Kilka przykładów:</para>
156         <itemizedlist>
157             <listitem>
158                 <para>
159                     <code>Zend_Controller_Dispatcher::dispatch()</code>
160                     domyślnie wyrzuci wyjątek jeśli zażądano nieprawidłowego
161                     kontrolera. Są dwa zalecane sposoby na obsłużenie tego:
162                 </para>
164                 <itemizedlist>
165                     <listitem>
166                         <para>Ustawienie parametru <code>useDefaultControllerAlways</code>.</para>
168                         <para>
169                             W twoim kontrolerze frontowym, lub w obiekcie
170                             uruchamiającym, dodaj poniższą dyrektywę:
171                         </para>
173                         <programlisting role="php"><![CDATA[
174 $front->setParam('useDefaultControllerAlways', true);
176 // lub
177 $dispatcher->setParam('useDefaultControllerAlways', true);
179                         </programlisting>
181                         <para>
182                             Gdy ta flaga jest ustawiona, obiekt uruchamiający,
183                             użyje domyślnego kontrolera oraz akcji zamiast
184                             wyrzucania wyjątku. Minusem użycia tej metody jest
185                             to, że jakikolwiek błąd literowy w adresie
186                             dostępowym do twojej strony spowoduje wyświetlenie
187                             strony głównej, co może źle wpłynąć na optymalizację
188                             serwisu dla wyszukiwarek internetowych.
189                         </para>
190                     </listitem>
192                     <listitem>
193                         <para>
194                             Wyjątek wyrzucany przez metodę <code>dispatch()</code>
195                             jest wyjątkiem <code>Zend_Controller_Dispatcher_Exception</code>
196                             zawierającym tekst 'Invalid controller specified'.
197                             Użyj jednej z metod opisanych w <link
198                             linkend="zend.controller.exceptions.handling">poprzedniej
199                             sekcji</link> aby złapać wyjątek, a następnie
200                             przekierować do strony błędu lub do strony głownej.
201                         </para>
202                     </listitem>
203                 </itemizedlist>
204             </listitem>
206             <listitem>
207                 <para>
208                     Metoda <code>Zend_Controller_Action::__call()</code> wyrzuci
209                     wyjątek <code>Zend_Controller_Action_Exception</code>
210                     jeśli nie może uruchomić nieistniejącej metody akcji.
211                     Najczęściej będziesz chciał użyć jakiejś domyślnej akcji
212                     w kontrolerze w tego typu sprawach. Przykładowe metody
213                     za pomocą których możesz to osiśgnąć:
214                 </para>
216                 <itemizedlist>
217                     <listitem>
218                         <para>
219                             Rozszerzenie klasy <code>Zend_Controller_Action</code>
220                             i nadpisanie metody <code>__call()</code>. Na przykład:
221                         </para>
223                         <programlisting role="php"><![CDATA[
224 class My_Controller_Action extends Zend_Controller_Action
226     public function __call($method, $args)
227     {
228         if ('Action' == substr($method, -6)) {
229             $controller = $this->getRequest()->getControllerName();
230             $url = '/' . $controller . '/index';
231             return $this->_redirect($url);
232         }
234         throw new Exception('Invalid method');
235     }
238                         </programlisting>
239                         <para>
240                             Powyższa metoda przechwytuje wszystkie wywołane
241                             niezdefiniowane akcje i przekierowuje żądanie do
242                             domyślnej akcji w kontrolerze.
243                         </para>
244                     </listitem>
246                     <listitem>
247                         <para>
248                             Rozszerzenie klasy <code>Zend_Controller_Dispatcher</code> o
249                             nadpisanie metody <code>getAction()</code>, która
250                             sprawdza czy akcja istnieje. Na przykład:
251                         </para>
253                         <programlisting role="php"><![CDATA[
254 class My_Controller_Dispatcher extends Zend_Controller_Dispatcher
256     public function getAction($request)
257     {
258         $action = $request->getActionName();
259         if (empty($action)) {
260             $action = $this->getDefaultAction();
261             $request->setActionName($action);
262             $action = $this->formatActionName($action);
263         } else {
264             $controller = $this->getController();
265             $action     = $this->formatActionName($action);
266             if (!method_exists($controller, $action)) {
267                 $action = $this->getDefaultAction();
268                 $request->setActionName($action);
269                 $action = $this->formatActionName($action);
270             }
271         }
273         return $action;
274     }
277                         </programlisting>
279                         <para>
280                             Powyższy kod sprawdza czy zażądana akcja istnieje w
281                             klasie kontrolera; jeśli nie, resetuje akcję do
282                             akcji domyślnej.
283                         </para>
285                         <para>
286                             Ta metoda jest wygodna ponieważ możesz w niewidoczny
287                             sposób zmienić akcję przed ostatecznym uruchomieniem.
288                             Jednak to także oznacza, że jakikolwiek błąd literowy
289                             w adresie URL może wciąż uruchomić żądanie poprawnie,
290                             co nie jest zbyt dobre dla optymalizacji dla
291                             wyszukiwarek internetowych.
292                         </para>
293                     </listitem>
295                     <listitem>
296                         <para>
297                             Użycie metody <code>Zend_Controller_Action::preDispatch()</code>
298                             lub <code>Zend_Controller_Plugin_Abstract::preDispatch()</code>
299                             do zidentyfikowania nieprawidłowych akcji.
300                         </para>
302                         <para>
303                             Rozszerzając klasę <code>Zend_Controller_Action</code> i
304                             modyfikując metodę <code>preDispatch()</code>, możesz
305                             zmodyfikować wszystkie twoje kontrolery w taki
306                             sposób, aby przenosiły one żądanie do innej akcji
307                             lub przekierowywały zamiast uruchamiać akcję.
308                             Kod wyglądałby podobnie kod nadpisujący metodę
309                             <code>__call()</code>, który został przedstawiony wyżej.
310                         </para>
312                         <para>
313                             Alternatywnie, możesz sprawdzać te informacje we
314                             wtyczce globalnej. Zaletą tego rozwiązania jest to,
315                             że kontroler akcji staje się niezależny; jeśli twoja
316                             aplikacja składa się z różnorodnych kontrolerów
317                             akcji i nie wszystkie dziedziczą z tej samej klasy,
318                             ta metoda może dodać konsekwencji w obsłudze różnych
319                             klas.
320                         </para>
322                         <para>
323                             Przykład:
324                         </para>
326                         <programlisting role="php"><![CDATA[
327 class My_Controller_PreDispatchPlugin extends Zend_Controller_Plugin_Abstract
329     public function preDispatch(Zend_Controller_Request_Abstract $request)
330     {
331         $dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
332         $controller = $dispatcher->getController($request);
333         if (!$controller) {
334             $controller = $dispatcher->getDefaultControllerName($request);
335         }
336         $action     = $dispatcher->getAction($request);
338         if (!method_exists($controller, $action)) {
339             $defaultAction = $dispatcher->getDefaultAction();
340             $controllerName = $request->getControllerName();
341             $response = Zend_Controller_Front::getInstance()->getResponse();
342             $response->setRedirect('/' . $controllerName . '/' . $defaultAction);
343             $response->sendHeaders();
344             exit;
345         }
346     }
349                         </programlisting>
351                         <para>
352                             W tym przykładzie sprawdzamy czy zażądana akcja
353                             jest dostępna w kontrolerze. Jeśli nie,
354                             przekierujemy żądanie do domyślnej akcji w
355                             kontrolerze, i kończymy wykonywanie skryptu.
356                         </para>
357                     </listitem>
358                 </itemizedlist>
359             </listitem>
360         </itemizedlist>
361     </sect2>
362 </sect1>