Zend Framework – subdirectories and deprecating action within the URL - php

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.

Related

MVC in PHP – General understanding and specific questions

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.

Is it bad practice to request index.php in order to use other scripts

Is it bad to use index.php as loader for other scripts or does it make a difference?
i.e. requesting index.php with different query strings and inside it, selecting and including the matching script.
e.g.
www.example.com/?sign-in insteade of www.example.com/sign-in.php
www.example.com/?new-post insteade of www.example.com/new-post.php
In this way you can use index.php to do the common inclusions and processes, like, setting timezone, mb encoding, DB connection, auth, etc..
Best practice is to let apache rewrite all urls to an index.php or some other file which you can use as bootstrap. This bootstrap runs all the basic code and then this bootstrap can figure out which other actions to take based on the url.
Every framework works like this.
several things you might want to do in the bootstrap:
setup, autoloading classes
setup mysql connection
check if user is authenticated for a certain action
There are many tutorials on rewriting urls with apache: http://www.workingwith.me.uk/articles/scripting/mod_rewrite
If you really want to learn about best practices i would suggest looking at existing frameworks, at how they implement certain things. eg: Zend or Symfony
Yes and No
The problem is that by doing it you will lose any SEO value, eg: domain.com/index.php?post=story will rank very poorly against domain.com/post/story . Also your index.php is going to get messy very quickly.
That being said MVC's usually use a index.php, so my url would be domain.com/users/edit/123 which is a very logical url, but what actually gets called is domain.com/index.php , it then looks at the first paramater, "users" and instantiates the user controller and then looks for the function edit inside that and passes the "123" (user id) as the first parameter in the function. If you are not familiar with MVC's I would advise codeigniter as a starting one, more on codeigniter.
In the end you will just be re-inventing the wheel by building it from scratch, rather use a MVC make development much easier.
This is the best approach. You can take control of your website.
Create index.php and include other files on demand.
(Define a constant and use it in included files and so on)
But keep in mind to minimize index.php as much as possible.
Also you can use Apache mod_rewrite to generate SEO friendly URL.
Instead of routing all your requests (through htaccess) to index.php you can also split the routes to map to other files:
/blog/hello-there mapping to blog.php?title=hello-there
/sign/in mapping to login.php?login
etc, thus you create your own simple routing based on the request URL; easy to read and easy to maintain.
This solution is suitable in small projects, for bigger project I advise to use a complete framework like Yii or Symfony.

Yii internationalization - URL

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.

How to modularize CodeIgniter?

Well, I have been thinking a lot about the first real CodeIgniter site I am coding. I want to modularize the site in such a way that I have a controller that formats the navbar, one that formats a multipurpose right column, and one that formats the content area.
My idea is to have a controller for each state of any part of the site (an example would be the right column, it would have 3 states; new posts, related posts, and search filters). I would also have the content area be many different states aswell (things like search results, view post, new posts, etc).
The problem is that I can't find a way to take multiple controller outputs and compile it into a single template (notice, I said controllers, not views).
I have seen the HMVC extension, but that is going to far for my first site, and am hoping for a more simplistic solution (unless you can prove me wrong, and show that HMVC is easier than what I've seen).
This seems a little wonky to me in an MVC model.
If you're using a single stateful view for your right panel that might change state based on input (i.e. which page the user is currently on), then I would add a model for the panel. The controller's action would be responsible for setting the correct model state (i.e. "you're in home page state"). The model could be responsible for telling the right panel view which child views to load.
That's how I'd probably implement something like that anyway. HMVC seems overkill and with this example, wouldn't be used as intended.
For what you're trying to accomplish the matchbox module suggested in the comments seems way overkill. I don't think that using controllers to format each of these areas is a very good approach to take.
Usually people who want the type of functionality that you're describing when working with CodeIgniter end up using a template library. There are several open source template libraries for CodeIgniter that can easily be found with a google search for "codeigniter template library".
I've never used any of them so I will not recommend any particular library. However the app that I'm working on has borrowed some ideas from Phil Sturgeon's template library. You may not find an exact match to features that you need but at least you'll be able to draw some inspiration from solutions that others have come up with.

URL Controller Mapping Strategies (PHP)

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.

Categories