>백엔드 개발 >PHP 튜토리얼 >YII 소스코드 분석(3)

YII 소스코드 분석(3)

WBOY
WBOY원래의
2016-08-08 09:32:18944검색

이미 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 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.