ZendFramework framework routing mechanism code analysis

Source: Internet
Author: User
This article mainly introduces the ZendFramework routing mechanism, and analyzes the controllers, router principles, and related code implementation skills involved in the ZendFramework routing mechanism based on the code, you can refer to this article to analyze the Zend Framework routing mechanism code. We will share this with you for your reference. The details are as follows:

In the framework, the call relationship of related routes is:

1. the mod_rewrite module of apache routes requests to the startup script of the framework, which is generally index. php;

2. the front-end controller Zend_Controller_Front distributes requests through the dispatch function;

3. the router Zend_Controller_Router_Rewrite processes routes through the route function. the matching function is called for each route based on the existing routing rules in the router in reverse order (similar to the stack, first in first out, check whether the request matches the current routing rule. If yes, set the current route variable $ _ currentRoute of the router as a matched route, pass the parsed route parameters to the Zend_Controller_Request_Http object, and complete route settings here.

If no route is found, the framework uses the Index action of the index controller.

Analyze the function code in Zend_Controller_Router_Route:

1. constructor

Public function _ construct ($ route, $ defaults = array (), $ reqs = array () {$ route = trim ($ route, $ this-> _ urlDelimiter ); // remove the url separator (default:/) $ this-> _ defaults = (array) $ defaults; // Default value array, use the variable name as the key $ this-> _ requirements = (array) $ reqs; // the regular expression that the variable needs to meet, and use the variable name as the key if ($ route! = '') {Foreach (explode ($ this-> _ urlDelimiter, $ route) as $ pos => $ part) {// split the rule into an array if (substr ($ part, 0, 1) ==$ this-> _ urlVariable) {// if the definition of a variable $ name = substr ($ part, 1); // Get the variable name // if the variable defines the corresponding regular expression, obtain the expression. otherwise, set it to null $ regex = (isset ($ reqs [$ name])? $ Reqs [$ name]: $ this-> _ defaultRegex); // _ parts array contains all parts of the rule. if it is a variable, the array contains the name element $ this-> _ parts [$ pos] = array ('name' => $ name, 'regex' => $ regex ); // _ vars contains the names of all variables in the rule $ this-> _ vars [] = $ name ;} else {// normal string $ this-> _ parts [$ pos] = array ('regex' => $ part); if ($ part! = '*') {$ This-> _ staticCount ++; // Number of common strings for this rule }}}}}

2. matching algorithm

Public function match ($ path) {$ pathStaticCount = 0; $ defaults = $ this-> _ defaults; // Default value array, the key value of the array element is a copy of the variable name // Default value array, but all the values of the variable are changed to Boolean values. In fact, this value is not actually useful, the following program determines whether a variable exists by determining whether the key value exists. This may be done to save space, however, in this case, // it is better to directly use $ this-> _ defaults? If (count ($ defaults) {$ unique = array_combine (array_keys ($ defaults), array_fill (0, count ($ defaults), true ));} else {$ unique = array () ;}$ path = trim ($ path, $ this-> _ urlDelimiter); // The passed path has removed the baseUrl, here, make sure to remove the separator if ($ path! = '') {$ Path = explode ($ this-> _ urlDelimiter, $ path); foreach ($ path as $ pos => $ pathPart) {if (! Isset ($ this-> _ parts [$ pos]) {// splits the path into an array based on the url separator and compares each part with the corresponding part of the rule, if the path exists, // and the rule does not have the corresponding part, the rule certainly does not match. pay attention to $ pos here, it maps the corresponding part of the rule // and path. Return false;} if ($ this-> _ parts [$ pos] ['regex'] = '*') {// if the current part of the rule is a wildcard *, then, the rest of the path is interpreted as the variables passed by the url. they are paired with $ parts = array_slice ($ path, $ pos); // Obtain the remaining part of the path $ this-> _ getWildcardData ($ parts, $ unique); break ;} $ part = $ this-> _ parts [$ pos]; $ name = isset ($ part ['name'])? $ Part ['name']: null; $ pathPart = urldecode ($ pathPart); // decodes the passed value if ($ name = null) {// normal string, which is equal to the corresponding part of the rule. if ($ part ['regex']! = $ PathPart) {return false ;}} elseif ($ part ['regex'] === null) {// if it is a variable, but there is no regular expression to be satisfied, if (strlen ($ pathPart) = 0) {return false;} else {// if a regular expression is required for the variable, verify $ regex = $ this-> _ regexDelimiter. '^ '. $ part ['regex']. '$ '. $ this-> _ regexDelimiter. 'iu '; if (! Preg_match ($ regex, $ pathPart) {return false ;}} if ($ name! = Null) {// if it is a variable, set the value of the variable $ this-> _ values [$ name] = $ pathPart; $ unique [$ name] = true; // In fact, there is no need to set it. this version does not use it} else {// adds the matching count of the common string to 1, because the regular string in the rule must exist in the path, otherwise, the result is // Match failure $ pathStaticCount ++ ;}}// $ this-> _ values stores the variables obtained from the analysis. if the rule contains '*', $ this-> _ params is the obtained // variable, otherwise it is an empty array, and $ this-> _ defaults is the default variable value provided by the rule, here, '+' is used to add the three arrays. // The advantage is that if the following array has the same non-integer key value as the preceding array, the following array will not overwrite the preceding one, this // is different from the array_merge function, which will be overwritten. That is to say, if $ this-> _ values already has a key controller //, the controller element in $ this-> _ defaults is ignored, in this way, the default value in $ this-> _ defaults appears in the return value only when path/does not exist. $ Return = $ this-> _ values + $ this-> _ params + $ this-> _ defaults; // Check if all static mappings have been met if ($ this-> _ staticCount! = $ PathStaticCount) {// all common strings of the rule must be matched with return false in the path;} // after parsing, all variables defined by the rule must also appear, otherwise, it is considered that the foreach ($ this-> _ vars as $ var) {if (! Array_key_exists ($ var, $ return) {return false ;}} return $ return ;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.