이미 Yii 프로그램을 시작하는 과정과 페이지를 렌더링하는 방법을 살펴보았습니다. 오늘 분석하고 싶은 것은 Yii가 사용자 요청을 처리하는 방식입니다. 컨트롤과 액션 부분입니다.
이 프로세스를 보여주기 위해 helloworld를 예로 들어보겠습니다. 주소 표시줄에 http://localhost/study/yii/demos/helloworld/index.php를 입력하면 페이지에 hello world가 표시됩니다.
이전 분석에서는 기본값을 사용했는데 URL에 매개변수가 있는 경우 Yii는 이를 어떻게 처리하나요? 이 질문을 염두에 두고 자세히 분석해 보겠습니다.
CWebApplication에는 다음 코드 줄이 있습니다.
<span>$route</span>=<span>$this</span>->getUrlManager()->parseUrl(<span>$this</span>->getRequest());
이건 전설의 루트 아닌가요? 먼저 getUrlManager가 얼마나 멋진지 살펴보겠습니다.
<span>public</span> <span>function</span><span> getUrlManager() { </span><span>return</span> <span>$this</span>->getComponent('urlManager'<span>); }</span>
이를 위해서는 다시 관계를 찾아야 합니다.
<span>public</span> <span>function</span> getComponent(<span>$id</span>,<span>$createIfNull</span>=<span>true</span><span>) { </span><span>if</span>(<span>isset</span>(<span>$this</span>->_components[<span>$id</span><span>])) </span><span>return</span> <span>$this</span>->_components[<span>$id</span><span>]; </span><span>elseif</span>(<span>isset</span>(<span>$this</span>->_componentConfig[<span>$id</span>]) && <span>$createIfNull</span><span>) { </span><span>$config</span>=<span>$this</span>->_componentConfig[<span>$id</span><span>]; </span><span>if</span>(!<span>isset</span>(<span>$config</span>['enabled']) || <span>$config</span>['enabled'<span>]) { Yii</span>::trace("Loading \"<span>$id</span>\" application component",'system.CModule'<span>); </span><span>unset</span>(<span>$config</span>['enabled'<span>]); </span><span>$component</span>=Yii::createComponent(<span>$config</span><span>); </span><span>$component</span>-><span>init(); </span><span>return</span> <span>$this</span>->_components[<span>$id</span>]=<span>$component</span><span>; } } }</span>
$this->_comComponents[$id];가 실행됩니다. id는 전달된 urlManager입니다. 실제로 여기에서는 아무것도 볼 수 없습니다. urlManager 클래스를 직접 찾아보세요.
<span>public</span> <span>function</span> parseUrl(<span>$request</span><span>) { </span><span>if</span>(<span>$this</span>->getUrlFormat()===self::<span>PATH_FORMAT) { </span><span>$rawPathInfo</span>=<span>$request</span>-><span>getPathInfo(); </span><span>$pathInfo</span>=<span>$this</span>->removeUrlSuffix(<span>$rawPathInfo</span>,<span>$this</span>-><span>urlSuffix); </span><span>foreach</span>(<span>$this</span>->_rules <span>as</span> <span>$i</span>=><span>$rule</span><span>) { </span><span>if</span>(<span>is_array</span>(<span>$rule</span><span>)) </span><span>$this</span>->_rules[<span>$i</span>]=<span>$rule</span>=Yii::createComponent(<span>$rule</span><span>); </span><span>if</span>((<span>$r</span>=<span>$rule</span>->parseUrl(<span>$this</span>,<span>$request</span>,<span>$pathInfo</span>,<span>$rawPathInfo</span>))!==<span>false</span><span>) </span><span>return</span> <span>isset</span>(<span>$_GET</span>[<span>$this</span>->routeVar]) ? <span>$_GET</span>[<span>$this</span>->routeVar] : <span>$r</span><span>; } </span><span>if</span>(<span>$this</span>-><span>useStrictParsing) </span><span>throw</span> <span>new</span> CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".', <span>array</span>('{route}'=><span>$pathInfo</span><span>))); </span><span>else</span> <span>return</span> <span>$pathInfo</span><span>; } </span><span>elseif</span>(<span>isset</span>(<span>$_GET</span>[<span>$this</span>-><span>routeVar])) </span><span>return</span> <span>$_GET</span>[<span>$this</span>-><span>routeVar]; </span><span>elseif</span>(<span>isset</span>(<span>$_POST</span>[<span>$this</span>-><span>routeVar])) </span><span>return</span> <span>$_POST</span>[<span>$this</span>-><span>routeVar]; </span><span>else</span> <span>return</span> ''<span>; }</span>
위 코드로 판단하면 URL에 무언가를 업로드하지 않으면 ''만 반환하면 됩니다. 그러면 매개변수를 어떻게 전달하느냐는 질문이 생깁니다.
isset($_GET[$this-><span>routeVar]) <br></span>
<span>public</span> <span>$routeVar</span>='r';
그래서 해결책이 있습니다. 함께 해를 끼치도록 합시다. helloworld/index.php?r=abc
와 같은 매개변수를 추가하세요.오류를 발견했습니다. abc컨트롤러가 없다는 뜻인데 사실 존재하지 않는다는게 좀 아쉽습니다.
hello world를 표시하려면 helloworld/index.php?r=site로 변경하세요. 이것은 도대체 무엇입니까? 그 이유는 사이트 컨트롤러가 정의되어 있기 때문에 매우 간단합니다.
<span>class</span> SiteController <span>extends</span><span> CController { </span><span>/*</span><span>* * Index action is the default action in a controller. </span><span>*/</span> <span>public</span> <span>function</span><span> actionIndex() { </span><span>echo</span> 'Hello World'<span>; }</span><span> }</span>
그렇습니다. 저는 반대하지 않습니다. 그런데 ActionIndex가 도대체 뭐죠? Yii에서는 이것을 액션이라고 합니다. 컨트롤러 뒤에 있는 매개변수를 캡처합니다. ?r=site/index를 입력하면 인덱스입니다. 내가 여자에게 거짓말을 하고 있지 않은지 확인하기 위해 해당 사이트를 제어합니다. 표시할 작업을 도구에 추가하세요.
<span>class</span> SiteController <span>extends</span><span> CController { </span><span>/*</span><span>* * Index action is the default action in a controller. </span><span>*/</span> <span>public</span> <span>function</span><span> actionIndex() { </span><span>echo</span> 'Hello World'<span>; } </span><span>public</span> <span>function</span><span> actionView() { </span><span>echo</span> 'Hello View'<span>; } }</span>
?r=site/view에 접속하면 'Hello View' 출력이 보이나요? 물론 책을 많이 읽지는 않았지만 사진과 진실이 있으니 속일 수는 없습니다.
저는 이름 사이트를 사용하는 것을 전혀 좋아하지 않고 테스트를 가장 좋아하므로 테스트 컨트롤러를 하나 더 만들어 사용해 보았습니다.
눈썰미 있는 분들은 액션 쓰는 법도 보셨을 텐데요. 실제로 시도해 본 후에야 이것이 실제로는 또 다른 표현 방법이라는 것을 깨달았습니다.
블로그 예시에서 인증 코드를 표시하기 위해 사용한 기억이 납니다.
<span>/*</span><span>* * Declares class-based actions. </span><span>*/</span> <span>public</span> <span>function</span><span> actions() { </span><span>return</span> <span>array</span><span>( </span><span>//</span><span> captcha action renders the CAPTCHA image displayed on the contact page</span> 'captcha'=><span>array</span><span>( </span>'class'=>'CCaptchaAction', 'backColor'=>0xFFFFFF,<span> )</span>, <span>//</span><span> page action renders "static" pages stored under 'protected/views/site/pages' // They can be accessed via: index.php?r=site/page&view=FileName</span> 'page'=><span>array</span><span>( </span>'class'=>'CViewAction',<span> )</span>,<span> ); }</span>
이 컨트롤러의 작업은 여전히 작업+ID 형식으로 간단하기 때문에 이를 중앙에서 타사 비즈니스를 선언하는 작업 모음으로 이해합니다.
대체 뭐야? index.php?r=site/captcha 대신 index.php/site/captcha를 사용했다고 말씀하셨습니다. 이것은 구성 파일부터 시작해야 합니다.
'urlManager'=><span>array</span><span>( </span>'urlFormat'=>'path', 'rules'=><span>array</span><span>( </span>'post/<id:\d+>/<title:.*?>'=>'post/view', 'posts/<tag:.*?>'=>'post/index', '<controller:\w+>/<action:\w+>'=>'<controller>/<action>',<span> )</span>,<span> )</span>,
urlFormat에는 path와 get의 두 가지 유형이 있습니다. main.php에 지정되지 않은 경우 index.php?r=site/captcha인 get 메소드입니다. 지정하면 index.php/site/captcha가 됩니다
말 그대로 이해하기 쉽습니다. path는 path 형식이고, get은 ? 형식입니다.
라우팅 및 컨트롤러 부분에 대해 다루어야 할 내용이 더 많지만 이 섹션에서는 여기까지입니다.
위 내용은 YII(3)의 소스코드 분석을 내용적인 측면까지 포함하여 소개하고 있는데, PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.