问题
I have setup two different PHP systems this summer. Each uses two different methods:
Method #1: One PHP File Per Task
This method requires that a PHP
file be created for each major task. For example, my upload script would be access via http://www.domain.com/upload.php
. On upload.php
, a "controller" and a "view" class are instantiated and used. For example, upload.php
might look something like this:
<?php
require_once PATH_LIBRARY . 'control/Uploader.class.php';
require_once PATH_LIBRARY . 'view/UploaderPage.class.php';
$uploader = new Uploader();
$uploader->setView(new UploaderPage());
$uploader->init();
?>
In the above script, if I wanted to call on another script, I would simply redirect and append the neccessary URL encoded variables (header('Location: edit_details.php?image_id=456');
).
Method #2: A main index.php
file that handles all requests
This method does not require that a PHP
file be created for each major task. Instead, each "controller" class that will be used in the system is registered on index.php
with a unique class that I call Router
. The router decides if the specified Controller is legal or illegal and acts accordingly (routes the browser to the correct controller). For example, a simplified version of the index.php
script:
<?php
require_once 'bootstrap.inc';
require_once PATH_LIBRARY . 'router/Router.class.php';
$router = new Router();
$router->register('Uploader', PATH_LIBRARY . 'control/Uploader.class.php');
$router->register('DetailsEditor', PATH_LIBRARY . 'control/DetailsEditor.class.php');
$router->route();
?>
Thus, every action takes place at index.php
. There is no need for a lot of files which don't do much else that instantiate a specific view and controller class. BUT, if you want to call script/class A from script/class B, then you need to pass the controller class's name along on the URL: header('Location: index.php?controller=DetailsEditor&image_id=456')
.
So far, I don't really like the fact that I need to include the Controller name in the URL. I feel that it exposes too much of my underlying system to the end-user. But, I do like the fact that I can register all controller classes on one page. Mostly, I don't know if exposing the controller name is safe or not. One other annoyance is that, if I want to call on a script via POST requests, I have to include a hidden input that specifies the required controller class (e.g. <input type="hidden" name="controller" value="DetailsEditor" />
).
I hope that is enough to go on. I am just nervous that the second method is not really going to serve me well in the months ahead. I have a small window of time soon to choose one or the other.
Thank-you.
回答1:
Not so fast. The approach with one PHP file per action can be faster and better. It depends on how you set things up.
The web server will route the HTTP request to the correct handler based on the filename. Why reinvent that?
Most times, all you need for a "handler" is:
<?php include "everything.php"; // do some work // Bounce the browser to a "view" url or display an error.
which is all at least as concise.
回答2:
Handling with Router is more efficient, because You have only one place to change, if You'll be forced to change file/dir structure in a future, and if any collaborators will come, its much more easy to understand how system works if every loads is done by just one "router/algorithm"
Just my opinion
PS imagine if You'll have to change dir structure, You'll be forced to rewrite a bunch of includes, witch is time consuming, and can produce mistakes, and takes time :)
回答3:
If you use the second option you should use URL rewriting to turn the URLs into a nice, human-readable format. That way gives you flexibility and power - definitely the way to go. This method is generally called a front controller, btw.
回答4:
The front controller is nice b/c you avoid all of those simple script files, and it also gives you lots more flexibility. In this method, you don't have to specify the controller name in the url, as long as the Router has a way to find the correct view.
My advice would be to use the Router class to generate your links, too. That way, instead of
header('Location: index.php?controller=DetailsEditor&image_id=456')
your redirect would look like
$router->redirect ($router->getUrl ('editimagedetails', array(456)));
// example getUrl method signature is
// string getUrl (string $viewOrActionName, array $params)
Naturally, getUrl
would be used to generate links and form action urls as well.
Any changes (say turning URL-rewriting on or off or renaming query string parameters) involve only the Router class because the name DetailEditor
and the query string parameter image_id
are implementation details unknown to the client code.
来源:https://stackoverflow.com/questions/3538242/what-are-the-pros-and-cons-of-specifying-a-controller-class-via-url-vs-having-a