Home  >  Article  >  Backend Development  >  YII source code analysis (3), yii source code analysis_PHP tutorial

YII source code analysis (3), yii source code analysis_PHP tutorial

WBOY
WBOYOriginal
2016-07-13 10:11:13883browse

YII source code analysis (3), yii source code analysis

I have already seen the process of starting a yii program and how to render a page. What we want to analyze today is how Yii handles user requests. That is the control and action part.

Let’s take helloworld as an example to demonstrate this process. We enter http://localhost/study/yii/demos/helloworld/index.php in the address bar, and the page displays hello world.

The previous analysis used the default value, but if the URL has parameters, how does Yii handle it? With this question in mind, let’s analyze it in detail.

There is this line of code in CWebApplication:

<span>$route</span>=<span>$this</span>->getUrlManager()->parseUrl(<span>$this</span>->getRequest());

This is the legendary route. Isn’t it a little chicken-jelly? Let’s first take a look at how awesome getUrlManager is.

    <span>public</span> <span>function</span><span> getUrlManager()
    {
        </span><span>return</span> <span>$this</span>->getComponent('urlManager'<span>);
    }</span>

This requires finding a relationship again.

    <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>

The return $this->_components[$id]; is executed. The id is the urlManager passed in. In fact, nothing can be seen from here. Just find the urlManager class directly and look at parseUrl:

    <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>

Judging from the above code, if we don’t upload something to the url, we can just return ''. So the question arises, how to pass parameters?

isset($_GET[$this-><span>routeVar]) <br /><br /></span>
<span>public</span> <span>$routeVar</span>='r';

So we have a solution, let’s do some harm together. Add a parameter like helloworld/index.php?r=abc

Found an error. It means that the abc controller does not exist. In fact, it does not exist. It is just a little bad. As the saying goes, if a man is not bad, a woman will not love him.

Change to helloworld/index.php?r=site to display hello world. What the hell is this? The reason is very simple, because the site controller is defined.

<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>

Okay, I have no objection to this, but what the hell is actionIndex? In Yii this is called an action. It captures the parameters behind the controller. If we enter ?r=site/index, it is index. The actions are separated by "/". In order to verify that I am not lying to girls, I control the site in the site Add an action to the tool to show you:

<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>

When you access ?r=site/view, do you see 'Hello View' output? It’s definitely true. Although I haven’t read many books, you can’t deceive me. There are pictures and the truth:

I don’t like using the name site at all, test is my favorite, so I built another test controller to try it out.

Those with sharp eyes must have seen how to write an action. What the hell is this? Only after I tried it did I realize that it is actually another way of expression.

I remember using it in the blog example to display the verification code:

    <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>

I understand it as a collection of actions that centrally declare third-party businesses, because the actions in this controller are still straightforward in the form of action+ID.

What the hell? You said that I used index.php/site/captcha instead of index.php?r=site/captcha. This has to start with the configuration file.

        '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 has two types: path and get. If it is not specified in main.php, then it is the get method, which is index.php?r=site/captcha. If specified, it will be index.php/site/captcha

It is easy to understand literally, path is in the format of a path, and get is in the form of ?.

There is a lot more to cover about the routing and controller parts, but that’s it for this section.

www.bkjia.comtruehttp: //www.bkjia.com/PHPjc/930706.htmlTechArticleYII source code analysis (3), yii source code analysis has already seen the process of starting a yii program. And how rendering a page is done. What I want to analyze today is how yii is...
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn