This is kind of an academic question, so feel free to exit now. I've had a dig through Stack for threads pertaining to URL/Controller mapping in MVC frameworks - in particular this one:
PHP Application URL Routing
So far, I can ascertain two practices:
1: dynamic mapping through parsing the URL string (exploded on '/')
2: pattern matching matching url to config file containing available routes
I wanted to get some feedback (or links to some other threads/articles) from folks regarding their views on how best to approach this task.
You can mix both options. Most frameworks do it to manage URL mapping. The first one is the default and the second one is the alternative. One php framework that uses it is Zend. you may check out zend_router for more details.
http://www.framework.zend.com/manual/1.7/en/zend.controller.router.html
I use your first option.
www.mysite.com/section1
this will be exploded and in one file I will check to see if a controller named section1 is on the server if it is then I use that to figure out what is suppose to happen if there is no controller then I look to see if there is a static file with this name and serve that up if the script still cannot find anything it serves a 404 page with some helpful information. This has worked great for me and gives me alot of control over how the site reacts to different situations.
Related
I am currently trying to understand how the MVC framework does work in PHP. Therefore, I have created this basic sketch of how I think that MVC is implemented in PHP:
[I know that some steps are missing, e.g. how the Routerparses the route in order to know what View and Controller to load, but these steps are rather technical based and are not important in order to understand the general flow of MVC in PHP.]
I draw my understanding of MVC in PHP from this article series. However, I think that this structure will differ from most of the structures people think off, when they talk about MVC in PHP, because of this article (The article basically states that not only the Controller but also the View does communicate with the Model).
What I'd like to ask you now are several questions:
Is this generally a right way of implementing MVC in PHP?
How can I add a Login/Logout-System to this approach? So that user, who are not logged in, will always see the LoginView and users who are logged in can see different views? (I know how a login system does work, but I can't figure out where to place it in the MVC, so I don't have to insert the code multiple times, e.g. in each Controller.)
What if my application consist of multiple elements (say a user bar [with user name, link to settings, etc.], a navigation and a content container) that are always loaded? How can I assemble these elements to a final view? (The only idea that comes to my mind is to assemble the final view in each view separately, but that would mean that I have to insert the code for it multiple times in each view, which misses the point of MVC, doesn't it?)
What if I want to use AJAX in my application? My idea would be to send ajax requests through the framework as well, while only accessing controllers and views that are made for ajax? In other words the AjaxViews do only return e.g. json objects and the AjaxControllers do always expect authentication codes to prove that these ajax calls are legtitim?
I know that there have already been asked dozens of questions about MVC in PHP and I've been reading quiet a lot of articles until now, but I think that only reading does not enable me to understand MVC completely.
Furthermore, after reading the articles linked above, I'm not longer sure whether other articles about MVC, I find on the web, does explain MVC the same way as the articles above. Because if they don't, I'm trying to understand one framework while reading about two or multiple different approaches.
Thank you very much in advance for taking the time to answer my question!
-- --- --- Update --- --- --
According to the answer below I've changed my MVC sketch. Just in case someone finds this link and wants to know more.
Let me first answer your questions, then place my take on it.
There's no right way of writing MVC. There are so many flavors and variations, and that get even multiplied when talking about web MVC.
About Logging in and Logging out. I think the most robust system would be a Role Based Access Control combined with an Access Control List, see How can I implement an Access Control List in my Web MVC application?.
There are generally two approaches, either you have a 1:1 ratio between Controllers and Views, and then after the Controller is done, your bootstrap script calls the View with the same name (LoginController, LoginView), or your Controller returns the View name along with action and parameters, to be called by the bootstrapper. The view then picks a template, and that template can include other sub-templates (like the user bar, or the footer).
In that case, your view needs to have an ability to select a different template based on the Accept: HTTP header (and send something like Accept: application/json in your AJAX requests). Your view then returns a JSON template instead of an HTML template.
What is wrong with your sketch?
Your model isn't just the gateway to your database, it's where all the logic happens. All the computation. See this yet another excellent answer that explains How should a model be structured in MVC?.
The idea of MVC is to simply separate your application into three layers: Input (controller), Logic (model) and Output (view). This is to extend on the usual way PHP works (here's a request, give me a response, all in the same page).
For that reason, implementation details may vary, the concept is what matters. "Web MVC" is merely the result of good OOP practices and some naming convention someone made up a few decades ago.
It is for parallel development and code reuse ability. There is a separation of concern how your system works and how users work. This provides a solution of the problem. There is boundry now, MVC.
More and more I find websites that show this kind of links:
website.com/page/
and testing if there's in index.php inside the folder like
website.com/page/index.php
I found always true.
So my question:
Is it a common way to put all your pages in subfolders even if it's a single file that you could also easily put in the root folder (in this case page.php) or is there a "common" rewrite for it?
If yes, I'd like to know how a typical folder structure for this case would look like.
I just got a bit confused and don't want to do it "wrong" on future projects.
And beside: Does this technique effect SEO?
If it's a static site then yes it's quite common to have just one page in a subfolder and having that page named as index.html or index.php because most servers are configured to pick that up without showing the filename.
One reason for doing this is so that if future pages are created that would naturally come under that subfolder then it keeps your site structure and site map neat and tidy.
These days many CMS systems replicate this sort of structure on the fly.
For SEO purposes it's good to have descriptive directory names and/or page names i.e.
news/the-title-of-my-news-article.php
Hope that helps.
URIs more often than not have nothing to do with the actual structure of the files. Take Stack Overflow for example: This page's URL is
http://stackoverflow.com/questions/12090658/is-it-typical-to-put-all-pages-in-subfolders-even-if-its-a-single-page
If we follow your logic, it means that stackoverflow has a questions folder for all questions, then a specific ID folder for every single (over 2 million) question, then another folder, with it's complete name, and inside of it an index file.
No, that's not the case. URLs are often rewritten to allow for increased complexity of application.
As for your specific question, perhaps there's a special meaning, perhaps there is none, it's up to the webmaster to decide that.
Even if you get some results when you hit website.com/page/index.php instead of website.com/page, doesn't mean there's a file there. In fact, it doesn't mean there's even a folder named 'page': the power of mod_rewrite may easily transform the URL
http://example.com/page/index.php
... into
http://example.com/index.php?controller=page
... so there's a single file executed each time someone queries this application (Single Front-End Controller design). Following this approach makes it not necessary to create a slew of folders for each and every possible user story.
But it's quite true that you should organize your web application into modules (which, in turn, are usually organized as sub-sub-folders of /modules application sub-folder). There's a very popular paradigm - MVC; it's quite commonly used by PHP frameworks and CMS built on this language, but it's not necessary to use one of these to follow it. Perhaps this tutorial might be useful for introducing MVC in PHP to you?
When using english the following URL should apply:
http://example.org/services/myservice/
When using another language, the following URL should apply:
http://example.org/sirvici/misirvice/
Any easy/standard way we should handle this withing Yii ?
Yes you can do this in Yii but you will sacrifice:
Automatic Controller/Action mapping (depending how this works out)
A little speed due to the extra work load on every request.
If your still OK with that then you can go ahead with it. You need to create a custom URL rule and have it process every URL, this is well documented. Then you need to manually strip the URL apart (by also well documented methods) and translate each part from the users currently selected language ( you will need to know this unless you want to go through the hell of trying to guess a language O.o ). You now have the translations for each part of the URL. Congrats.
Heres the part that may or may not work
You can pass it back through the Yii URL parser to go through the automatic mapping of controllers and actions and parameters. This would mean your just doing a preparse on the URL and Yii continues from there.
If that can't work you'll have to build your own ( piggy back off Yii a little with CUrlRule etc. ) and do the mapping logic.
My Two Sense
For most Web Apps I wouldn't recommend this. It means you have multiple ways to access the same content, from very different URLs. This is bad thing in SEO terms and also in usability terms. It also doesn't provide you with a way of mapping those back to each other particularly easily to let google know not to index your content again. Plus I can't see that it gains you a whole lot. Most simpleton users won't pay attention to the URL bar, and even if it's in their native language most won't deduce much about the page and it's content from the wording of the URL.
Let me know if you proceed with this though, I'd like to know how it goes.
I’m in the process of learning to use the Zend Framework, and I’m therefore trying to grasp the concept of MVC. Through the Zend manual, and a very helpful Youtube video tutorial I have sort of understood the concept – still there are some things I need to clarify.
The web project I’m currently working on is a web site for an organization I’m a part of. It consists of:
The public portion, mainly consisting of information about us, a calendar and some media – mostly static information, but a couple of pages, like the calendar, will need to retrieve some data from the DB.
The internal pages, which after a login will allow users to RSVP to events and comment them as well.
The administrative controls , allows the admins to add events and manage users etc.
So far it looks like Zend wants the URL to look like this:
http?://[domain]/[controller]/[action]
So here are my questions:
Do I always have to have an action in the url, or will the lack of an action use the index-action as default?
Can I have a subdirectory to distinguish between the internal and public portions of the site: http://[domain]/internal/[controller]/[action] ?
Can this be done simply by having a subfolder within the different MVC-folders somehow?
The latter question isn’t really that important, but I’d like to separate the two portions of the site somehow.
Do I always have to have an action in the url, or will the lack of an action use the index-action as default?
A controller can have a default action which is triggered when no action is specified in the URL. Look for default action or index action.
Can I have a subdirectory to distinguish between the internal and public portions of the site: http://[domain]/internal/[controller]/[action] ?
Yes you can have, but I assume subdirectory refers to your URL, not to the actual file-layout on the server. You can do so by just having a controller per "subdirectory".
Can this be done simply by having a subfolder within the different MVC-folders somehow? The latter question isn’t really that important, but I’d like to separate the two portions of the site somehow.
You can separate per controller and you can even separate with modules. As far as I know of modules in zend-framework, this will all be in it's own sudirectory per module.
I think you're especially looking for Using a Conventional Modular Directory Structure.
The questions you are asking are in the area of routing which generally means: Given a URL on which the HTTP request is being made:
Which controller should be instantiated?
Which action on that controller should be run?
What parameters should be passed to the action?
The routing docs in the ZF Manual explain how routing works by default and how you can specify your own routing. But looking at them now, I don't think they do a great job of introducing the subject matter for a first time user. This post might be better, though it is only a single, simple example.
I am a beginner with PHP but I know most of the basics. I currently have an API for my website, coded myself, of which I can call different methods with different parameters and they will scour my databases for the relevant information.
However I want to convert it to REST.
So instead of having requests like this http://mywebsite.com/api/?param=allPosts I would have something like http://mywebsite.com/api/posts/. I would do this for each of my 23 different params.
How could I do this?
One way would be to use a micro framework for routing. This would 'point' url request patterns to relevant php files (controllers) to manage those requests and serve content (or perform CRUD operations, or whatever it is your API does).
There's a good post here with some discussion and further links.
https://stackoverflow.com/questions/115629/simplest-php-routing-framework
I'm currently in the process of using the framework Silex for this exact purpose
http://silex-project.org/
It may be that you wish to convert your PHP application to use one of the many frameworks out there (which will handle routing amongst other things).
The usual suspects are
CakePHP
Codeigniter
Symfony
Lithium
and there are many more...
This is not strictly speaking RESTful that is just prettifying your URL's.
To "Prettify" your URL's you could implement something like this:
Trim your base URL of the start of the request
explode the remaining string by the "/" component
The first component (normally) is related to your controller
The next component is your action in this case equivalent to how your using ?param=allPosts
RESTful routing is based around the idea of using the different HTTP verbs (GET/POST/PUT/DELETE) to decide what actions to take on your resources on the server. Wikipedia has a good overview.
One way would be to use apache's mod_rewrite to effectively convert the second type of request to the first. It's not necessarily ideal, but it's a pretty straightforward solution to your problem.