Bitte geben Sie beim Nachdruck an: TheViper http://www.cnblogs.com/TheViper/
Im vorherigen Artikel ging es um ¥route=$this->getUrlManager ()->parseUrl ($this->getRequest()); in CWebApplication und um $route=controler/actionid.
In diesem Artikel geht es um $this->runController ($route);
1 | <span> 1</span> <?<span>php </span><span> 2</span><span> class </span> CWebApplication <span> extends </span><span> CApplication { </span><span> 3</span><span> public </span><span> $controllerNamespace </span><span>; </span><span> 4</span><span> private </span><span> $_controllerPath </span><span>; </span><span> 5</span><span> private </span><span> $_viewPath </span><span>; </span><span> 6</span><span> private </span><span> $_systemViewPath </span><span>; </span><span> 7</span><span> private </span><span> $_controller </span><span>; </span><span> 8</span><span> public </span><span> $controllerMap </span>=<span> array </span><span>(); </span><span> 9</span><span> public </span><span> function </span> processRequest() {<span>
|
Nach dem Login kopieren
$ca = $this->createController ($route)); Die Funktion von createController besteht darin, den Controller und die Aktion in $route zu trennen und eine Controller-Instanz zu erstellen.
Abschließend werden die Controller-Instanz und die Aktions-ID zurückgegeben.
Gehen Sie dann zurück zu runController($route),$controller->init (); und führen Sie es aus, wenn der Controller initialisiert wird. Dies muss beispielsweise in der Unterklasse neu geschrieben werden:
1 | <span> 1</span><span> class </span> VideoController <span> extends </span><span> CController { </span><span> 2</span><span> public </span><span> function </span><span> init() { </span><span> 3</span><span> $this </span>->db = Yii::app ()-><span>db; </span><span> 4</span><span> } </span><span> 5</span><span> public </span><span> function </span><span> actionBroadcast() { </span><span> 6</span><span> $b </span> = <span> $this </span>->db->query ( "" , <span> array </span> (1<span> ) ); </span><span> 7</span><span> $this </span>->render ( "u_broadcast" , <span> array </span><span> ( </span><span> 8</span> 'b' => <span> $b </span> [0<span>] ; </span><span> 9</span><span> ) ); </span><span>10</span><span> } </span><span>11</span> }
|
Nach dem Login kopieren
Auf diese Weise können Sie $this->db verwenden, um die DB-Komponente in VideoController aufzurufen.
$controller->run ($actionID);Übertragung an Ccontroller.
1 | <span> 1</span> <?<span>php </span><span> 2</span><span> class </span><span> CController { </span><span> 3</span><span> protected </span><span> $db </span><span>; </span><span> 4</span><span> public </span><span> $defaultAction </span> = 'index' <span>; </span><span> 5</span><span> private </span><span> $_id </span><span>; </span><span> 6</span><span> private </span><span> $_action </span><span>; </span><span> 7</span><span> public </span><span> function </span> __construct(<span> $id </span>, <span> $module </span> = <span>null</span><span>) { </span><span> 8</span><span> $this </span>->_id = <span> $id </span><span>; </span><span> 9</span><span> } </span><span>10</span><span> public </span><span> function </span><span> init() { </span><span>11</span><span> } </span><span>12</span><span>
|
Nach dem Login kopieren
$this->createAction ( $actionID ); Erstellt eine Aktionsinstanz.
Dann runActionWithFilters($action, $filters); wenn kein filter() vorhanden ist, direkt runAction($action).
$action->runWithParams ( $this->getActionParams () ).$action ist eine CInlineAction-Instanz.
1 | <span> 1</span> <?<span>php </span><span> 2</span><span> class </span> CInlineAction <span> extends </span><span> CAction </span><span> 3</span><span>{ </span><span> 4</span><span>
|
Nach dem Login kopieren
Aktion
1 | <span> 1</span> <?<span>php </span><span> 2</span><span> abstract </span><span> class </span> CAction <span> extends </span><span> CComponent </span><span> 3</span><span>{ </span><span> 4</span><span> private </span><span> $_id </span><span>; </span><span> 5</span><span> private </span><span> $_controller </span><span>; </span><span> 6</span><span> public </span><span> function </span> __construct(<span> $controller </span>,<span> $id </span><span>) </span><span> 7</span><span> { </span><span> 8</span><span> $this </span>->_controller=<span> $controller </span><span>; </span><span> 9</span><span> $this </span>->_id=<span> $id </span><span>; </span><span>10</span><span> } </span><span>11</span><span> public </span><span> function </span><span> getController() </span><span>12</span><span> { </span><span>13</span><span> return </span><span> $this </span>-><span>_controller; </span><span>14</span><span> } </span><span>15</span><span> public </span><span> function </span><span> getId() </span><span>16</span><span> { </span><span>17</span><span> return </span><span> $this </span>-><span>_id; </span><span>18</span><span> } </span><span>19</span><span>
|
Nach dem Login kopieren
Beide Klassen sind sehr einfach, sie führen lediglich die Aktionsmethode in der Controller-Klasse aus.
Zurück zu runActionWithFilters($action, $filters) oben, wenn filter() vorhanden ist, CFilterChain::create ( $this, $action, $filters )->run ();
Wenn ein Filter vorhanden ist, muss die Filterliste natürlich vor dem Ausführen der Aktionsmethode festgelegt werden.
CFilterChain analysiert eine Konfiguration ähnlich „application.filters.LoginFilter upload_video“ in eine Filterkette.
Jedes Element in der Filterkette ist eine CInlineFilter- oder CFilter-Instanz.
1 | <span> 1</span> <?<span>php </span><span> 2</span><span>
|
Nach dem Login kopieren
'application.filters.LoginFilter upload_video' Diese Konfiguration erstellt eine CFilter-Instanz.
1 | <span> 1</span> <?<span>php </span><span> 2</span><span> class </span> CFilter <span> extends </span><span> CComponent { </span><span> 3</span><span> public </span><span> function </span> filter(<span> $filterChain </span><span>) { </span><span> 4</span><span>
|
Nach dem Login kopieren
Dann gibt es run() in CFilterChain::create ($this, $action, $filters)->run (); Wenn die von der Anfrage analysierte Aktion upload_video ist, entfernt Yii die LoginFilter-Instanz.
Zum Beispiel mein LoginFilter
1 | <span> 1</span> <?<span>php </span><span> 2</span><span> class </span> LoginFilter <span> extends </span><span> CFilter { </span><span> 3</span><span> protected </span><span> function </span> preFilter(<span> $filterChain </span><span>) { </span><span> 4</span><span> if </span> (! <span>isset</span> ( <span> $_SESSION </span><span> )) { </span><span> 5</span><span>session_start</span><span> (); </span><span> 6</span><span> } </span><span> 7</span><span> if </span> (<span>isset</span> ( <span> $_SESSION </span> [ 'user' <span>] )) </span><span> 8</span><span> return </span><span>true</span><span>; </span><span> 9</span><span> else </span><span> { </span><span>10</span><span>setcookie</span> ( "return" , Yii::app ()->getRequest ()->getUrl (), <span>time</span> () + 360, '/' <span> ); </span><span>11</span> Yii::app ()->getRequest ()->redirect ( 'http://localhost/youtube/login' , <span>true</span>, 302<span> ); </span><span>12</span><span> return </span><span>false</span><span>; </span><span>13</span><span> } </span><span>14</span><span> } </span><span>15</span><span> protected </span><span> function </span> postFilter(<span> $filterChain </span><span>) { </span><span>16</span><span> } </span><span>17</span><span>} </span><span>18</span> ?>
|
Nach dem Login kopieren
Es gibt ein Präfix und ein Postfix im Inneren, was bedeutet, dass für die Aktionsmethode, die den Filter aktivieren muss, die selbstdefinierten Methoden preFilter und postFilter vor bzw. nach der Ausführung der Aktionsmethode ausgeführt werden.
Dann gibt es $filterChain->run (); hier kann man leicht Fehler machen.
Tatsächlich habe ich run() erneut in CFilterChain verwendet und $this->filterIndex darin bemerkt, was ein bisschen wie eine Rekursion ist.
Wenn der Filter eine Aktion filtern soll, gehen Sie wie folgt zu CFilter, geben Sie dann CFilterChain und $this->filterIndex zurück und fahren Sie dann mit $filterChain->run (); fort. . . . . .
Für mein „application.filters.LoginFilter upload_video“ wird nur die Aktion „upload_video“ gefiltert. Wenn also CFilterChain zurückgegeben wird, ist $this->filterIndex zu 1 geworden und die Filterliste hat nur eine Filterinstanz, also wird es dieses Mal gehen zu $this->controller->runAction ( $this->action );, was dasselbe ist wie $this->runAction ( $action ); wenn kein Filter gesetzt ist.
Nachdem der Filter analysiert wurde, gibt es einige Datenoperationen und dergleichen und schließlich die Rendering-Ansicht render(). Das ist zu einfach: Extrahieren Sie ($ data) und fügen Sie dann die Ansichtsdatei ein.
Es gibt auch die Methode „forward()“, die zu einem anderen Controller/einer anderen Aktion springt. Der Kern besteht darin, zum runController von CWebApplication zurückzukehren und den obigen Analysevorgang zu wiederholen.
Abschließend ist das zugeschnittene yii http://files.cnblogs.com/TheViper/framework.zip beigefügt
Das Obige hat die Analyse des Yii-Framework-Quellcodes (3) vorgestellt, einschließlich des Inhalts des Yii-Framework-Quellcodes. Ich hoffe, dass es für Freunde hilfreich sein wird, die sich für PHP-Tutorials interessieren.