What do you call routing that maps one URL directly to a file?
Example:
http://localhost/directory/file.php => /var/www/apache/htdocs/directory/file.php
What do you call routing like one on https://github.com/nikic/FastRoute?
Example:
http://localhost/directory/file => request actually goes to a single index.php file, which then loads routing files or tables and loads appropriate class as defined in the routing table.
What do you call routing that maps one URL directly to a file?
I would call that no routing. Or maybe direct routing? I've never heard anybody use a term specifically for it.
What do you call routing like one on https://github.com/nikic/FastRoute?
That's (typically) the front controller pattern.
Related
I'm currently putting together a little mvc framework for practice, I have a bit of laravel experience so it is loosely based on that. I've made a router that simply returns a specified view for the url that you set.
Now I've also made controller that splits the url and uses the first part after the base url as controller and second part as action. This loads a file corresponding with the controller and a method within that file corresponding with the action.
So if the url is something like: url.com/users/index it will load a UsersController.php file and look for the index() method within that file.
Now I'm wondering with is the exact difference between a controller and a router? It it like a specified? Wherein a router is just a little bit simpler and just reacts to an exact given url and a router chops it up and has a little more depth?
What I currently have seems to overlap quite a bit.
(Presuming that router does not refer to network hardware or wood working tool!)
The router takes the request and decides which controller/controller methods will handle the request.
The controller accepts the requests and handles it!
Now I've also made controller that splits the url and uses the first part after the base url as controller and second part as action. This loads a file corresponding with the controller and a method within that file corresponding with the action.
This isn't really a controller (as far as MVC is concerned) it is part of the routing.
For example take the [GET] uri: example.com/article/view/123
The MVC router will parse the uri and find the following segments
article
view
123
By default most routers would now instantiate the articleController and call its view method passing in 123 as a parameter. (You could alternatively have some getUriSegment(segmentIdx) method, that's a design choice for your framework.)
The ArticleController would have a view method with an $articleId parameter. This method would probably do something like: get the specified article (from a db via a model for example) and then display it (probably by returning a view which has been given the article returned by the model)
The controller sits between the model and the view. It communicates with both to make a response to a request.
The router chooses which controller (and which method on that controller) handles the request. For example it might decide the request 'product/view/123' should call the ProductController's View methods passing 123 as a parameter.
A router might also convert urls. Instead of using, like you said, method and action in the url. You could also have www.example.com/members. And the router would convert it to UsersController's Index method. This allows the user of 'pretty' urls to map to nice logically named controllers.
The router points a request to a controller.
I have an application in Cakephp. In my front-end, it only responses for one request and I have used usual CakeRequest() class, and in my back-end, as far as using extjs, I have defined another Request and Response Class for multi-requests and multi-responses. but I have problem in distinguishing between them. I mean where and when one of them is executed. the default cakephp index.php file for front-end is
$Dispatcher->dispatch(new CakeRequest(), new CakeResponse(array('charset' => Configure::read('App.encoding'))));
and for back-end is
$Dispatcher->dispatch(new TestRequestCollection(...
but I don't know the if clause between them.
To what if clause are you referring to?
CakePHP is not designed to use different request classes in the index.php. Not sure what you are doing here. You might want to go the same route I went with Bancha and create a second frontend controller which does different a dispatching.
CI looks for Segment[1] for controller (in controller dir) and Segment[2] for Method. Now, I have specific requirement by business application which needs that I do not want CI to look or by force go to controller dir to load but I will have something like this "domainURL/module_identifier_id/controller/method/".
Here, every request will be coming along with its associated Module's Identifier ID which will have complete module's configuration and other data (controller files, module location where it was uploaded, all menus and their URLs which will have same URL mechanism which we want to design for developers to develop modules and upload) stored in DB.
We need to get this ID and play with it to fetch relevent records and point CI to load controller from where we want it and indeed rest for methods etc every thing needs to be working as it is.
I hope you understand what we are looking for that we have our own main controller type file where all of the requests will be coming with customizing protocol as described above and developers will be following it by all means, that there must be module identifier first and then controller, method etc...
Let me know if you have any query to be cleared on?
I think I would just use routes for this:
$route[(:any)/(:any)/(:any)] = '$2/$3/$1';
This should just rearrange your segments the way you want, without completely changing the way the native routing system works.
I'm developing a web application in PHP using an MVC-approach (not using any framework, pure PHP). As is often the case with MVC, every request arrives at a front controller which routes it to the corresponding controller, and executes the requested action. The URL structure looks like this:
www.site.com/controller/action
Let's say I'm building an e-commerce site which has products in different categories. Possible URLs could be:
www.site.com/sofas/overview
www.site.com/video-games/overview
For the first URL, the "sofas" controller is loaded, and the overview() method of it is executed. This all works well until we have to nest these products within parent catagories. I'll take the two previous URLs to demonstrate what I mean:
www.site.com/furniture/sofas/overview
www.site.com/electronics/video-games/overview
Now, the "video-games" controller is nested within the "electronics" controller. However, with the current 'load controller -> execute action' structure this won't work.
A possible solution would be to create a method within the parent controller ("electronics") which gets executed in case an unexisting action is requested ("video-games"). This method checks whether the requested action exists as a controller. If so, the controller gets loaded and the action ("overview") of it gets executed.
I fruitlessly searched for solutions to this limitation of the standard front controller pattern, including here on SO. I think my implementation of MVC is now correct, but the front controller still brings limitations.
I think the thought that you have to have a different "controller" for each different product type may where you are running into problems.
Unless you are going to have drastically different views for each product type, I would think the controller would be linked to a concept such as "catalog" (or "product" or whatever you want to call it). So for example your URL structure might look like
www.site.com/catalog/furniture/sofas/overview
www.site.com/catalog/electronics/video-games/overview
With the catalog portion of the URI determining the controller and the additional URI segments in essence being parameters passed to the controller indicating the specifics of the request.
This would work nicely with an OOP inheritance structure in that you could have a root 'product' class, and then extend that class with subclasses for furniture, electronics, etc. which would each have their own properties specific to the category. You would the further sub-class for sofas, video games, etc.
All your controller would have to do is evaluate the request URI to determine which class to load for the request. So something like:
// assume URI has been parsed to get value such as "sofas", "video-games", etc. into a variable called $class_to_load
$product = new $class_to_load;
$product->overview();
You are confusing MVC structure with routing issues.
The controller should be probably something like a product controller, or a category controller. Group controllers by functionality.
Now routing deals with the structure of the request and where this gets sent in the application.
You should have a routing layer that knows (for example) to send /<category>/<subcategory>/<action> to the appropriate controller (say products controller) with appropriate arguments (i.e category and subcategory) so it can construct a response.
Only directly mapping the url to controller and action (i.e enforcing /<controller>/<action>) is a very limited way of constructing the architecture of your application.
I have my own routing rules in routes.php, defined for all the pages that should be accessible via URL, such as mywebsite/blog/ and mywebsite/blog/category/category-name, i.e. the structure of my whole website is covered by my custom routes.
Now, I have a lot of elements that make use of requestAction, such as
$websiteabstract = $this -> requestAction(array(
'controller' => 'assets',
'action' => 'displayHomeAbstract'
));
This gives me an error Error: Controller could not be found, probably because I have not defined a route for /assets/displayHomeAbstract. But why do I have to define a custom route for that, when I explicitly state the name of the controller and the action? Shouldn't that bypass the routing altogether?
Either I have not understand Routing at all. Or do I really have to define ALL the possible routes (even those that are only used by requestAction) in my routes.php? I mean, I don't want to allow users to directly access mywebsite/assets/displayHomeAbstract anyway, only via an Element.
Thank you
EDIT: Here is my routes.php http://pastebin.com/aAKBwNZJ
Please have a look at line 128, this is exactly what I do not want since /assets/displayHomeAbstract is ONLY accessed via requestAction.
EDIT: And this is the element, that makes the request: http://pastebin.com/0tK5dYJk
Okay, after extensive discussion with the devs in IRC, I think I understand this well enough to explain to you:
You do have to define your custom routes for your requestAction in this case. requestAction is emulating a full request. It dispatches a request as if accessed using the string url every time, even when the url provided is an array. The book is referring to how when you have a custom route defined in addition to using the default routes (the last line of routes.php), you can use array urls to be agnostic of those routes. However, these array urls rely on the default routes.php in the /lib/ folder and are used to construct a url string. If you're going to have a custom routing pattern, you have to construct the url strings on your own.
Note: the comments below were from earlier versions of this answer.
The key to your problem is understanding the scope of Cake's routing and how it work.
When you define a route in CakePHP, it isn't just used for mapping URLs to controllers. It's also used by the Router for things like generating link addresses and, in your case, mapping the path supplied to requestAction() to a controller. Behind the scenes, Cake is creating a URL string based on your parameters, and then passes it off to the Router to find the correct controller. Since no such route exists, it fails.
As a solution, I would actually recommend not using a controller for that logic. Depending on what it does, a component or a helper may be a better place.
Look at line 156. You commented out the line that loads CakePHP's default routes.