How does URL rewriting works?

piaoling  2012-07-12 16:43:32

Createa category

 

Diagram1-1

 

Wejust input the category's name, and set "is active" to Yes,and then click Save Category

 

 

Diagram1-2

 

Wecan see that the URL key is automaticly generated. The value is"nikon-camera".

Whena category is created, in database table core_url_rewriting,there is a new record created at the same time.

 

 

Diagram1-3

 

Aswe can see above, the main fields of table core_url_rewriting are:

  • Category_id (if this filed is null, it means this is a product url rewriting record)

  • Product_id (if this field is null, it means this is a category url rewriting record)

  • Id_path

  • Request_path (this is the url suffix which we will use in category page or product page)

  • Target_path (this is the real target url, it is the standard MVC style)

 

Infront end of Magento, when we put mouse on the category we created

 

Diagram1-4

 

Wecan see the target url is looks like:

Diagram1-5

 

 

Weare sure that the links of this menu is related with the databasetable core_url_rewriting, it is generated by the field request_path.Click on the category link, and then the category "Nikon"is opened.

 

Howdoes Magento find the category by this URL? 

 

1ststop: /index.php (this is the entrance of most part of URL request inMagento)

2ndstop: /app/Mage.php -> Mage::run()

3rdstop: Mage_Core_Controller_Varien_Front->dispatch()

 

Allof things are handled in front controller’s dispatch() function, solet’s go inside of this function.

 

Hereis source code of dispatch method, in order to see the mainoperation; we removed the line about Varien_Profiler, which is usedto check programs performance.

 

Diagram1-6

 

 

Requestis a global variable which contain all information about browserrequest, it is an object of class “Mage_Core_Controller_Request_Http”which is extend from class Zend_Controller_Request_Http,here is the hierarchy diagram:

 

Diagram1-7

 

 

  1. Rewriting

Atthe begining of dispatch(), browser request url “/nikon-camera.html"must be stored in request object. We can proof this by adding tracelog to print the value $request->getPathInfo() .

Itwill print the value of request object’s attribute _pathInfo, hereis the value at that moment:

/Nikon-camera.html

Andthen, below program is executed: 

Mage::getModel('core/url_rewrite')->rewrite();

Whatthis line did is modify the global request object, it will usefunction rewrite() of model class Mage_Core_Model_Url_Rewrite,this class is the entity object correspond with database tablecore_url_rewrite. Here isthe last lines of the rewrite() method.

Diagram1-8

 

Weadded trace log to see what is set into $request object, the printedresult is:

RequestURI = /index.php/catalog/category/view/id/7

Pathinfo = catalog/category/view/id/7

 

Atthis moment, the url translation between browser request url andtarget url has been finished.

 

Weguess that there must be a database operation before this, let’slook at the beginning source line of function rewrite().

Diagram1-9

 

$requestCasesis an array which composed of $requestPath and $requestPath +$queryString.

Aswe can see in first highlight line, $requestPath is come from$request->getPathInfo(), as we have said before, this value is“/Nikon-camera.html”, after trimming, the value will become to“Nikon-camera.html”.

 

Let’shave a look what’s inside the function loadByRequestPath($path),here is the function’s source:

Diagram1-10

 

Themeaning of this function can be explained in one SQL:

Select* from core_url_rewrite where request_path = “$pathInfo”

Aswe talked before, the record has already created in database tablecore_url_rewrite when a category is created, so if the parameter$pathInfo can be found in database, then the entity object ofMage_Core_Model_Url_Rewrite will be initialized after above functionexecuted. It means we can use below functions to get information ofdatabase table core_url_rewrite.

$this->getIdPath()

$this->getRequestPath()

$this->getTargetPath()

 

  1. Matching

Aswe can see in diagram 1-6, there is a foreach operation

foreach($this->_routers as $router) {

if($router->match($this->getRequest())) {

break;

}

}

Fromhere, the responsibility transfers to the front controller androuter. The front controller has an array of “routers” that ituses to decide which module the URL should trigger. This correlationbetween URL and module name is defined in the config.xml files.

Theavailable routers are:

• Standard(used in front end request)

• Admin(used in back office request)

• Default(only used for 404s)

 

Thedefinition of a match between a router and a module looks like thisfor the Catalog module:

 

Diagram1-11

 

Beforedispatch() function, there is an init() function calling which willinitial the attribute $this->_routers. Each router will collectall modules information from all config.xml files, standard router(Mage_Core_Controller_Varien_Router_Standard)will collect all frontend modules info and admin router(Mage_Core_Controller_Varien_Router_Admin)will collect all backend modules info.

Let’shave a look what has been done in match() function of router, justfor the sample, we put the standard router’s source here.

 

 

 

 

Bythe pink comments, we can quick overview of the business logic ofmatch() function.

  1. Analyzing target URL, purpose of this is:

  1. Get module name

  2. Get controller name

  3. Get action name

 

  1. Instantiate controller class

  2. Set values to $request (module name, controller name, action name, other parameters)

  3. Dispatch action

 

Wecan add trace log to see each variable’s value, here they are:

$module= ‘catalog’

$realModule= ‘Mage_Catalog’

$controller= ‘category’

$controllerClassName = ‘Mage_Catalog_CategoryController’

$action= ‘view’

$request->getParams()= Array

(

[id]=> 7

)

 

Afterthe last line executed in match() function, the responsibility willtransfer to a specific controller to finish the left business logic.After business logic is finished, there is a result page will berendered and be set into response object. As we can see in diagram1-6, the last line in dispatch():

$this->getResponse()->sendResponse();

Afterthis, the result page will be sent to client browser. That’s all.

类别 :  magento(258)  |  浏览(5123)  |  评论(0)
发表评论(评论将通过邮件发给作者):

Email: