File: Zend_Controller-ActionController.xml

package info (click to toggle)
zendframework 1.12.9%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 133,584 kB
  • sloc: xml: 1,311,829; php: 570,173; sh: 170; makefile: 125; sql: 121
file content (653 lines) | stat: -rw-r--r-- 28,843 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect1 id="zend.controller.action">
    <title>Action Controller</title>

    <sect2 id="zend.controller.action.introduction">
        <title>Einführung</title>

        <para>
            <classname>Zend_Controller_Action</classname> ist eine abstrakte Klasse die verwendet
            werden kann um Aktion Controller zu implementieren die mit dem Front Controller
            verwendet werden können um eine WebSeite zu erstellen die auf dem Model-View-Controller
            (<acronym>MVC</acronym>) Pattern basiert.
        </para>

        <para>
            Um <classname>Zend_Controller_Action</classname> zu verwenden, muß von dieser in der
            eigenen aktuellen Aktions Controller Klasse ererbt werden (oder von dieser erben um eine
            eigene Basisklasse für Aktion Controller zu erstellen). Die grundsätzlichste Operation
            ist es von Ihr zu erben und Aktions Methoden zu erstellen die den verschiedenen Aktionen
            entsprechen die der Controller der eigenen Seite handhaben soll. Das Handhaben von
            Routen und Dispatchen des <classname>Zend_Controller</classname>'s wird automatisch
            jegliche Methode die in der eigenen Klasse auf 'Action' endet, als potentielle
            Controller Aktion herausfinden.
        </para>

        <para>
            Soll unsere Klasse, zum Beispiel, wie folgt definiert sein:
        </para>

        <programlisting language="php"><![CDATA[
class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // mach irgendwas
    }

    public function bazAction()
    {
        // mach irgendwas
    }
}
]]></programlisting>

        <para>
            Die obige <emphasis>FooController</emphasis> Klasse (Controller
            <emphasis>foo</emphasis>)´definiert zwei Aktionen, <emphasis>bar</emphasis> und
            <emphasis>baz</emphasis>.
        </para>

        <para>
            Da gibt es viel mehr das damit getan werden kann als das, wie eigene Initialisierungs
            Aktionen, Standardaktionen die aufgerufen werden wenn keine Aktion (oder eine ungültige
            Aktion) spezifiziert wird, pre- und post Dispatch Hooks, und eine Vielzahl von Helfer
            Methoden. Dieses Kapitel arbeitet als eine Übersicht der Aktion Controller
            Funktionalitäten.
        </para>

        <note>
            <title>Standardverhalten</title>

            <para>
                Standardmäßig aktiviert der <link linkend="zend.controller.front">Front
                Controller</link> den Aktion Helfer des <link
                    linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>'s.
                Dieser Helfer übernimmt das Einfügen des View Objekts in den Controller, sowie das
                automatische Darstellen der View. Er kann innerhalb des Aktion Controllers mit einer
                der folgenden Methoden ausgeschaltet werden:
            </para>

            <programlisting language="php"><![CDATA[
class FooController extends Zend_Controller_Action
{
    public function init()
    {
        // Lokal nur bei diesem Controller; beeinflußt alle Aktionen die mit
        // init geladen wurden:
        $this->_helper->viewRenderer->setNoRender(true);

        // Global:
        $this->_helper->removeHelper('viewRenderer');

        // Auch global, muß aber in Verbindung mit der Lokalen Version sein um
        // für diesen Controller zu gelten:
        Zend_Controller_Front::getInstance()
            ->setParam('noViewRenderer', true);
    }
}
]]></programlisting>

            <para>
                <methodname>initView()</methodname>, <methodname>getViewScript()</methodname>,
                <methodname>render()</methodname>, und <methodname>renderScript()</methodname>
                handeln alle in Vertretung zum <emphasis>ViewRenderer</emphasis> solange der Helfer
                nicht im Helfer Broker ist oder das <emphasis>noViewRenderer</emphasis> Flag nicht
                gesetzt wurde.
            </para>

            <para>
                Das rendern kann für individuelle Views auch ganz einfach ausgeschaltet werden durch
                Setzen des <emphasis>noRender</emphasis> Flags des
                <emphasis>ViewRenderer</emphasis>'s:
            </para>

            <programlisting language="php"><![CDATA[
class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // Nur für diese Aktion das automatische Rendern ausschalten:
        $this->_helper->viewRenderer->setNoRender();
    }
}
]]></programlisting>

            <para>
                Der primäre Grund um den <emphasis>ViewRenderer</emphasis> auszuschalten ist, wenn
                einfach kein View Objekt benötigt wird, oder wenn nicht über ein View Skript
                gerendert werden soll (zum Beispiel wenn ein Aktion Controller verwendet wird um
                Web Service Protokolle wie <acronym>SOAP</acronym>, <acronym>XML-RPC</acronym> oder
                <acronym>REST</acronym> anzubieten. In den meisten Fällen wird man den
                <emphasis>ViewRenderer</emphasis> nie global ausschalten müssen, nur selektiv
                innerhalb einzelner Controller oder Aktionen.
            </para>
        </note>
    </sect2>

    <sect2 id="zend.controller.action.initialization">
        <title>Objekt Initialisierung</title>

        <para>
            Wärend man immer den Konstruktor des Aktion Controller's überschreiben kann ist das
            nicht notwendig. <methodname>Zend_Controller_Action::__construct()</methodname> führt
            einige wichtige Aufgabe aus, wie das registrieren der Anfrage und Antwort Objekte, sowie
            alle eigene einleitenden Argumente die von Front Controller übergeben wurden. Wenn der
            Konstruktor überschrieben werden muß, muß sichergestellt sein das
            <methodname>parent::__construct($request, $response, $invokeArgs)</methodname>
            aufgerufen wird.
        </para>

        <para>
            Der bessere Weg als die Instanzierung zu ändern ist die Verwendung der
            <methodname>init()</methodname> Methode, welche nach der letzten Aufgabe von
            <methodname>__construct()</methodname> aufgerufen wird. Zum Beispiel wenn man sich zu
            einer Datenbank bei der Instanzierung verbinden will:
        </para>

        <programlisting language="php"><![CDATA[
class FooController extends Zend_Controller_Action
{
    public function init()
    {
        $this->db = Zend_Db::factory('Pdo_Mysql', array(
            'host'     => 'myhost',
            'username' => 'user',
            'password' => 'XXXXXXX',
            'dbname'   => 'website'
        ));
    }
}
]]></programlisting>
    </sect2>

    <sect2 id="zend.controller.action.prepostdispatch">
        <title>Pre- und Post-Dispatch Hooks</title>

        <para>
            <classname>Zend_Controller_Action</classname> spezifiziert zwei Methoden die aufgerufen
            werden können um eine angefragte Aktion fertigzustellen,
            <methodname>preDispatch()</methodname> und <methodname>postDispatch()</methodname>.
            Diese können auf viele Wege nützlich sein: zum Beispiel um Authentifizierungen und
            <acronym>ACL</acronym>'s prüfen bevor eine Aktion ausgeführt wird (durch Aufruf von
            <methodname>_forward()</methodname> in <methodname>preDispatch()</methodname> wird die
            Aktion übersprungen), oder erzeugte Inhalte in einem seitenweiten Template zu plazieren
            (<methodname>postDispatch()</methodname>).
        </para>

        <note>
            <title>Verwendung von of init() vs. preDispatch()</title>

            <para>
                In der <link linkend="zend.controller.action.initialization">vorigen Sektion</link>
                haben wir die <methodname>init()</methodname> Methode eingeführt, und in dieser
                Sektion die <methodname>preDispatch()</methodname> Methode. Was ist der Unterschied
                zwischen Ihnen, und welche Aktionen kann man in jeder von Ihnen durchführen?
            </para>

            <para>
                Die <methodname>init()</methodname> Methode ist primär dafür gedacht den Constructor
                zu erweitern. Typischerweise sollte der Constructor einfach den Status des Objekts
                setzen und keine weitere Logik ausführen. Das kann die Initialisierung von
                Ressourcen enthalten die im Kontroller verwendet werden (wie Modelle, Konfigurations
                Objekte, usw.), oder die Zuordnung von Werten die vom Front Controller, der
                Bootstrap oder einer Registry empfangenen wurden.
            </para>

            <para>
                Die <methodname>preDispatch()</methodname> Methode kann auch verwendet werden um den
                Status des Objekts oder der Umgebung (z.B. View, Action Helfer, usw.) zu setzen,
                aber sein primärer Zweck besteht darin Annahme darüber zu treffen, ob eine
                angefragte Aktion ausgeführt werden sollte oder nicht. Wenn nicht, dann sollte
                <methodname>_forward()</methodname> auf eine andere Aktion ausgeführt, oder eine
                Exception geworfen werden.
            </para>

            <para>
                Beachte: <methodname>_forward()</methodname> arbeitet aktuell nicht korrekt wenn es
                von <methodname>init()</methodname> ausgeführt wird, das die Formalisierung der
                Annahmen beider Methoden ist.
            </para>
        </note>
    </sect2>

    <sect2 id="zend.controller.action.accessors">
        <title>Zugriffe</title>

        <para>
            Eine Anzahl von Objekten und Variablen werden im Objekt registriert, und jede hat
            Zugriffsmethoden.
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis>Anfrage Objekt</emphasis>: <methodname>getRequest()</methodname> kann
                    verwendet werden um das Anfrage Objekt zu erhalten das verwendet wurde um die
                    Aktion aufzurufen.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>Antwort Objekt</emphasis>: <methodname>getResponse()</methodname>
                    kann verwendet werden um das Antwort Objekt zu erhalten das die letztendliche
                    Antwort erzeugt. Einige typische Aufrufe können wie folgt aussehen:
                </para>

                <programlisting language="php"><![CDATA[
$this->getResponse()->setHeader('Content-Type', 'text/xml');
$this->getResponse()->appendBody($content);
]]></programlisting>
            </listitem>

            <listitem>
                <para>
                    <emphasis>Aufgerufene Argumente</emphasis>: Der Front Controller kann Parameter
                    in den Router, Dispatcher und Aktion Controller einfügen. Um diese zu erhalten
                    kann <methodname>getInvokeArg($key)</methodname> verwendet werden; alternativ
                    kann man die komplette Liste mit <methodname>getInvokeArgs()</methodname>
                    erhalten.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>Anfrage Parameter</emphasis>: Das Anfrage Objekt liefert die Anfrage
                    Parameter, wie alle <constant>_GET</constant> oder <constant>_POST</constant>
                    Parameter, oder Benutzer Parameter die in der Information des
                    <acronym>URL</acronym> Pfades spezifiziert sind. Um diese zu erhalten kann
                    <methodname>_getParam($key)</methodname> oder
                    <methodname>_getAllParams()</methodname> verwendet werden. Es können auch
                    Anfrage Parameter gesetzt werden indem <methodname>_setParam()</methodname>
                    verwendet wird; das ist nützlich wenn an zusätzliche Aktionen weitergeleitet
                    werden soll.
                </para>

                <para>
                    Um zu Testen ob ein Parameter existiert (nützlich für logische Auswahlen), kann
                    <methodname>_hasParam($key)</methodname> verwendet werden.
                </para>

                <note>
                    <para>
                        <methodname>_getParam()</methodname> kann ein optionales zweites Argument
                        nehmen das einen Standardwert enthält der verwendet wird wenn der Parameter
                        nicht gesetzt oder leer ist. Wenn er verwendet wird ist es nicht mehr
                        notwendig <methodname>_hasParam()</methodname> vor dem Empfangen eines
                        Wertes aufzurufen:
                    </para>

                    <programlisting language="php"><![CDATA[
// Verwende des Standardwert 1 wenn id nicht gesetzt wurde
$id = $this->_getParam('id', 1);

// Statt:
if ($this->_hasParam('id') {
    $id = $this->_getParam('id');
} else {
    $id = 1;
}
]]></programlisting>
                </note>
            </listitem>
        </itemizedlist>
    </sect2>

    <sect2 id="zend.controller.action.viewintegration">
        <title>View Integration</title>

        <note id="zend.controller.action.viewintegration.viewrenderer">
            <title>Standard View Integration über den ViewRenderer</title>

            <para>
                Der Inhalt dieses Kapitel ist nur gültig wenn man den <link
                    linkend="zend.controller.actionhelpers.viewrenderer">ViewRenderer</link>
                explizit deaktiviert hat. Andernfalls kann man dieses kapitel ohne Bedenken
                überspringen.
            </para>
        </note>

        <para>
            <classname>Zend_Controller_Action</classname> bietet einen rudimentären und flexiblen
            Mechanismus für View Integration. Zwei Methoden machen das möglich,
            <methodname>initView()</methodname> und <methodname>render()</methodname>; die erste
            Methode lädt die öffentliche Eigenschaft <varname>$view</varname> träge, und die zweite
            rendert eine View basierend auf der aktuell angefragen Aktion, wobei die Verzeichnis
            Hirarchie verwendet wird um den Pfad des Skripts zu ermitteln.
        </para>

        <sect3 id="zend.controller.action.viewintegration.initview">
            <title>View Initialisierung</title>

            <para>
                <methodname>initView()</methodname> initialisiert das View Objekt.
                <methodname>render()</methodname> ruft <methodname>initView()</methodname> auf um
                das View Objekt zu erhalten, aber es kann jederzeit initialisiert werden;
                standardmäßig wird die <varname>$view</varname> Eigenschaft mit einem
                <classname>Zend_View</classname> Objekt bekanntgegeben, aber jede Klasse die
                <classname>Zend_View_Interface</classname> implementiert kann verwendet werden.
                Wenn <varname>$view</varname> bereits initialisiert wurde, wird diese Eigenschaft
                einfach zurückgegeben.
            </para>

            <para>
                Die Standardimplementation macht die folgenden Annahmen über die
                Verzeichnisstruktur:
            </para>

            <programlisting language="php"><![CDATA[
applicationOrModule/
    controllers/
        IndexController.php
    views/
        scripts/
            index/
                index.phtml
        helpers/
        filters/
]]></programlisting>

            <para>
                In anderen Worten, wird angenommen das View Skripte im
                <filename>/views/scripts/</filename> Unterverzeichnis sind, und das
                <filename>/views/</filename> Unterverzeichnis weitere Funktionalitäten enthält
                (helpers, filters). Wenn der Name und der Pfad des View Skripts ermittelt wird,
                wird das <filename>/views/scripts/</filename> Verzeichnis als Basispfad verwendet,
                mit einem Verzeichnis das nach dem individuellen Controller benannt ist und eine
                Hierarchie von View Skripten bietet.
            </para>
        </sect3>

        <sect3 id="zend.controller.action.viewintegration.render">
            <title>Rendern von Views</title>

            <para>
                <methodname>render()</methodname> hat die folgende Signatur:
            </para>

            <programlisting language="php"><![CDATA[
string render(string $action = null,
              string $name = null,
              bool $noController = false);
]]></programlisting>

            <para>
                <methodname>render()</methodname> rendert ein View Skript. Wenn keine Argumente
                übergeben werden, wird angenommen dass das angefragte Skript
                <filename>[controller]/[action].phtml</filename> ist (wobei
                <filename>.phtml</filename> der Wert der <varname>$viewSuffix</varname> Eigenschaft
                ist). Wenn ein Wert für <varname>$action</varname> angegeben wird, wird das
                Template im <filename>/[controller]/</filename> Unterverzeichnis gerendert. Um die
                Verwendung des <filename>/[controller]/</filename> Unterverzeichnisses zu
                überschreiben kann ein <constant>TRUE</constant> Wert für
                <varname>$noController</varname> übergeben werden. Zuletzt werden
                templates in das Antwort Objekt gerendert; wenn zu einem spezifischen
                <link linkend="zend.controller.response.namedsegments">benannten Segment</link> im
                Antwort Objekt dargestellt werden soll, kann ein Wert an <varname>$name</varname>
                übergeben werden.
            </para>

            <note>
                <para>
                    Da Controller- und Aktionsnamen Wort Begrenzer Zeichen enthalten können wie
                    z.B. '_', '.' und '-', normalisiert <methodname>render()</methodname> diese
                    zu '-' wenn der Skript Name eruiert wird. Intern werden die Wort- und
                    Pfadbegrenzer vom Dispatcher verwendet um die Normalisierung durchzuführen.
                    Deshalb wird eine Anfrage auf <filename>/foo.bar/baz-bat</filename> das Skript
                    auf <filename>foo-bar/baz-bat.phtml</filename> rendern. Wenn eine
                    Aktionsmethode camelCase Zeichen enthält, muß beachtet werden das diese in '-'
                    seperierten Wörter umgewandelt werden wenn der Dateiname des View Skripts
                    eruiert wird.
                </para>
            </note>

            <para>
                Einige Beispiele:
            </para>

            <programlisting language="php"><![CDATA[
class MyController extends Zend_Controller_Action
{
    public function fooAction()
    {
        // Rendert my/foo.phtml
        $this->render();

        // Rendert my/bar.phtml
        $this->render('bar');

        // Rendert baz.phtml
        $this->render('baz', null, true);

        // Rendert my/login.phtml in das 'form' Segment des Antwort Objektes
        $this->render('login', 'form');

        // Rendert site.phtml in das 'page' Segmetn des Antwort Objektes;
        // verwendet nicht das 'my/' Unterverzeichnis
        $this->render('site', 'page', true);
    }

    public function bazBatAction()
    {
        // Rendert my/baz-bat.phtml
        $this->render();
    }
}
]]></programlisting>
        </sect3>
    </sect2>

    <sect2 id="zend.controller.action.utilmethods">
        <title>Nützliche Methoden</title>

        <para>
            Neben den Zugriffs- und View Integrationsmethoden, hat
            <classname>Zend_Controller_Action</classname> verschiedene nützliche Methoden für die
            Durchführung üblicher Aufgaben von innerhalb der Aktionsmethoden (oder vom
            Pre- und Post-Dispatch).
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <methodname>_forward($action, $controller = null, $module = null, array $params
                    = null)</methodname>: führt eine weitere Aktion aus. Wenn in
                    <methodname>preDispatch()</methodname> aufgerufen, wird die aktuelle
                    aufgerufene Aktion übersprungen zugunsten der neuen. Andererseits, wenn die
                    aktuelle Aktion durchgeführt wurde, wird die Aktion die in
                    <methodname>_forward()</methodname> angefragt wird, ausgeführt.
                </para>
            </listitem>

            <listitem>
                <para>
                    <methodname>_redirect($url, array $options = array())</methodname>: leitet zu
                    einem anderen Ort um. Diese Methode nimmt eine <acronym>URL</acronym> und ein
                    optionales Set von Optionen. Standardmäßig führt Sie eine
                    <acronym>HTTP</acronym> 302 Umleitung durch.
                </para>

                <para>
                    Diese Optionen können ein oder mehrere der folgenden enthalten:
                </para>

                <itemizedlist>
                    <listitem>
                        <para>
                            <emphasis>exit:</emphasis> ob oder ob nicht sofort ausgestiegen werden
                            soll. Wenn angefragt, wird jede offene Session sauber beendet und die
                            Umleitung durchgeführt.
                        </para>

                        <para>
                            Diese Option kann global im Controller gesetzt werden indem der
                            <methodname>setRedirectExit()</methodname> Zugriff verwendet wird.
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <emphasis>prependBase:</emphasis> ob oder ob nicht, die im Anfrage
                            Objekt registrierte Basis <acronym>URL</acronym>, dem angebotenen
                            <acronym>URL</acronym> angehängt wird.
                        </para>

                        <para>
                            Diese Option kann gobal im Controller gesetzt werden indem der
                            <methodname>setRedirectPrependBase()</methodname> Zugriff verwendet
                            wird.
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <emphasis>code:</emphasis> welche <acronym>HTTP</acronym> Code für die
                            Umleitung verwendet wird. Standardmäßig wird ein
                            <acronym>HTTP</acronym> 302 erstellt; jeder Code zwischen 301 und 306
                            kann verwendet werden.
                        </para>

                        <para>
                            Diese Option kann global im Controller gesetzt werden indem der
                            <methodname>setRedirectCode()</methodname> Zugriff verwendet wird.
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>
        </itemizedlist>
    </sect2>

    <sect2 id="zend.controller.action.subclassing">
        <title>Erweitern des Aktion Controllers</title>

        <para>
            Vom Design her muß <classname>Zend_Controller_Action</classname> erweitert werden um
            einen Aktion Controller zu erstellen. Als Minimum, muß eine Aktions Methode definiert
            werden die der Controller aufrufen kann.
        </para>

        <para>
            Neben dem erstellen von nützlichen Funktionalitäten für Web Anwendungen, wird auch die
            Notwendigkeit bestehen das vom gleichen Setup oder von den nützlichen Funktionen vieles
            in verschiedenen Controllern wiederholt wird; wenn dem so ist, löst die Erstellung einer
            gemeinsamen Basis Controller Klasse die <classname>Zend_Controller_Action</classname>
            erweitert zu einer Lösung dieser Redundanz.
        </para>

        <example id="zend.controller.action.subclassing.example-call">
            <title>Behandeln nicht-vorhandener Aktionen</title>

            <para>
                Wenn eine Anfrage an einen Controller durchgeführt wird die eine undefinierte
                Aktions Methode enthält, kommt
                <methodname>Zend_Controller_Action::__call()</methodname> zum Einsatz.
                <methodname>__call()</methodname> ist natürlich <acronym>PHP</acronym>'s magische
                Methode für das Überladen von Methoden.
            </para>

            <para>
                Standardmäßig wirft diese Methode eine
                <classname>Zend_Controller_Action_Exception</classname> die anzeigt das die
                angefragte Aktion nicht im Controller gefunden werden konnte. Wenn die angefragte
                Methode mit 'Action' endet, wird angenommen das eine Aktion angefragt wurde die
                nicht existiert; solch ein Fehler resultiert in einer Ausnahme mit dem Code 404.
                Alle anderen Methoden resultieren in einer Ausnahme mit dem Code 500. Das erlaubt
                die einfache Differenzierung zwischen Seiten die nicht gefunden wurden und
                Anwendungsfehlern in der Fehlerbehandlung.
            </para>

            <para>
                Diese Funktionalität sollte überschrieben werden wenn eine andere Operation
                ausgeführt werden soll. Wenn zum Beispiel eine Fehlermeldung angezeigt werden soll
                kann etwas die das folgende geschrieben werden:
            </para>

            <programlisting language="php"><![CDATA[
class MyController extends Zend_Controller_Action
{
    public function __call($method, $args)
    {
        if ('Action' == substr($method, -6)) {
            // Wenn die Aktionsmethode nicht gefunden wurde,
            // das error Template darstellen
            return $this->render('error');
        }

        // Alle anderen Methoden werfen eine Ausnahme
        throw new Exception('Invalid method "'
                            . $method
                            . '" called',
                            500);
    }
}
]]></programlisting>

            <para>
                Eine andere Möglichkeit ist, dass man zu einer standardmäßigen Controller Seiten
                weiterleiten will:
            </para>

            <programlisting language="php"><![CDATA[
class MyController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $this->render();
    }

    public function __call($method, $args)
    {
        if ('Action' == substr($method, -6)) {
            // Wenn die Aktionsmethode nicht gefunden wurde,
            // leite zur Index Aktion weiter
            return $this->_forward('index');
        }

        // Alle anderen Methoden werden eine Ausnahme
        throw new Exception('Invalid method "'
                            . $method
                            . '" called',
                            500);
    }
}
]]></programlisting>
        </example>

        <para>
            Neben dem überschreiben von <methodname>__call()</methodname>, kann jede der
            Initialisierungs-, Utility-, Zugriffs-, View- und Dispatch-Hook Methoden die vorher in
            diesem Kapitel beschrieben wurden, überschrieben werden um eigene Controller
            anzupassen. Wenn man, als Beispiel, die View Objekte in der Registry speichert, kann es
            gewünscht sein die <methodname>initView()</methodname> Methode mit Code zu Ändern der
            das folgende zusammensetzt:
        </para>

        <programlisting language="php"><![CDATA[
abstract class My_Base_Controller extends Zend_Controller_Action
{
    public function initView()
    {
        if (null === $this->view) {
            if (Zend_Registry::isRegistered('view')) {
                $this->view = Zend_Registry::get('view');
            } else {
                $this->view = new Zend_View();
                $this->view->setBasePath(dirname(__FILE__) . '/../views');
            }
        }

        return $this->view;
    }
}
]]></programlisting>

        <para>
            Hoffentlich kann man anhand der Informationen in diesem Kapitel ersehen wie flexibel
            diese spezielle Komponente ist und wie Sie in eigene Anwendungen oder den
            Notwendigkeiten von Seiten damit erfüllt werden kann.
        </para>
    </sect2>
</sect1>