Here is good article which fits very well into this thread. It was written by Harry Fuecks, which many from this forums know.
http://www.phppatterns.com/index.php...leview/81/1/1/
| SitePoint Sponsor |


Here is good article which fits very well into this thread. It was written by Harry Fuecks, which many from this forums know.
http://www.phppatterns.com/index.php...leview/81/1/1/





I meant "with respect to", sorry for confusionOriginally Posted by Dr Livingston
I was really looking for a KISS CoR, as (I don't think) I've used one before. I see no reason (in principle) why OO can't follow, KISS. If KISS CoR doesn't exist, I guess I won't get to see an example
Edit: I'm also a little fuzzy on how CoR (from what I understand of it) fits in here. Why do you want a chain? Aren't you looking for something which branches instead?
Douglas
Hello World





I wouldn't recommend that. It's a pretty basic OOP idea that classes should have clearly defined responsibilities. A response doesn't have a lot in common with a request.Originally Posted by Dr Livingston
Request objects tend to get passed around almost everywhere and thus can appear as a convenient location to store all kinds of widely-used objects or parameters. A temptation to be resisted.
For one thing it's bad layering. GPC input only exists with a particular kind of presentation layer - http. If domain objects are accessing GPC directly presentation is bleeding into the domain.Originally Posted by kyber
There's also the question of input validation. I'm not suggesting for one moment that you're not doing any validation, but the advantage of a request object is that you can provide named accessors to guaranteed, safe values. They'll either be validated and passed on or set to null if they fail - raw GPC input never gets anywhere near the app.
With a single location for all input validation it's likely to be carried out more carefully and methodically than if it were scattered throughout the app. A request object can create a clear Cartesian boundary between the internal application and the outside world - which as you say also makes it easier to swap out a CLI presentation layer.





Thanks for making it clearer, though I'll more likely forget about the meaning tomorrow"with respect to"
One advantage (of many) of using a Chain of Responsibility (over basic switch) is that the CoR can be configurable. I like this approach
By branching, you mean a hierarchacal structure, again this is where the Composite comes in. At the moment, the Composite for me holds what Controllers (proberly a bad description, as they're not actually controllers) to use for each node, and I use a CoR to sift through each handler, using the Request, to select which action to take.
The action selects which template fragment to use, and returns it to the composite along with any model data. A Visitor puts the model data to the template, and then the template is parsed into the parent composites template fragment... and so on until you reach the root node![]()





Correct, though my Request object is read only all the way McGruffconvenient location to store all kinds of widely-used objects or parameters. A temptation to be resisted.The Request class (which does the encapsulation) is merely a container I suppose, but with additional responsibilities such as verifying that there is an ID parameter for example?
From one application to another, the terminology of an ID can change, thus I don't have it (the responsibility) in the HttpRequest class. It may appear to be madness, but I like the approach and the responsibilities are clearly defined.
For once, I can agree with you on this.There's also the question of input validation. I'm not suggesting for one moment that you're not doing any validation, but the advantage of a request object is that you can provide named accessors to guaranteed, safe values. They'll either be validated and passed on or set to null if they fail - raw GPC input never gets anywhere near the app.
With a single location for all input validation it's likely to be carried out more carefully and methodically than if it were scattered throughout the app. A request object can create a clear Cartesian boundary between the internal application and the outside world - which as you say also makes it easier to swap out a CLI presentation layer.





This is the bit I don't understand: if the chain changes depending on the request, isn't the code that creates the chain the code which replaces the switch? OR, do you just put all your handlers into the chain, then run your action/command/request and see what happens? Won't this lead to loading up the whole app when only part of it is needed for any given request?Originally Posted by Dr Livingston
When I say branching, I mean rendering, say, a news page instead of a contact page. Each will require different data (one a list of articles, the other possibly static html) so needs to be handled differently. I don't mean a composite - that would mean rending the news and contact pages at the same time, which might be a little confusing to the visitor
Douglas
Edit: can't resist a random Ruby example: the Doctor says "though my Request object is read only all the way McGruff", Ruby says "my_request_object.freeze"!
Hello World





A pun? Funny...that would mean rending the news and contact pages at the same time, which might be a little confusing to the visitor
By configurable, I mean that you'd have just a handler class defined by a tight interface. This handler would take a reference (an XPATH reference for example), prior to this (newly created) handler being attached to a chain of handlers.
So... You parse an XML file (for example), lift each node (via XPATH for example), and create a new instance of the handler class. This object is attached to the chain of handlers (basically this is an array, encapsulated within another class).
You pass in the Request to the (lets call the class ActionChainController) class which cycles through the chain of handlers, passing in the Request. So, it's the handler class it's self, which looks at the XPATH reference, to see if there is a match against the Request passed into it (the handler class).
If there is a match, execute a given action, which is found btw, by querying the XPATH reference (the action file, and the class name etc, if a child node of the parent node which you queryied originally you see), and you execute that given action.
If no match found, you move onto the next handler in the chain, defaulting at the end. Hope this helps to clear things up.





Heh, didn't notice that oneOriginally Posted by Dr Livingston
Thanks for describing your setup, its interesting how people solve these problems. Now I see why you wouldn't consider it "light weight" or KISS. I'm guessing too many Java books
Cheers,
Douglas
Hello World





I'll post some script later this week once I get some more time, so you can see how I do things in regards to the configurable Chain of Responsibility.
I had this script developed prior to a written contract, so it's upto myself what I can do with it![]()





This is a really excellent discussion. In response to Ryan Wray, I think I think you ask the right question "Are we answering his question correctly:" and I think you also recognize that cadmiumgreen was implementing a common pattern (Front Controller) without knowing it.
My point for pushing the discussion a little was that I believe that if there was a simple, clean, understandable "skeleton" for the Front Controller and Application Controller patterns it would be of great benefit to users like cadmiumgreen. This same question has come up hundreds of times in PHP forums and it gets answered with lots of words, but seldom with clean example code.
As for the Request object, I undersand kyberfabrikken resistance to a Request object. But I think a Request object adds a couple of best practices that make it a good addition for the purpose of this skeleton:
1. A Request class implements escaping of all request vars transparently. I think this is such an important feature that it is worth having a Request object just for this reason.
2. A Request class encapulates the request which provides a solid basis for adding Filtering and Validation classes.
3. In conjuction with a Response class it abstracts the entire Request enabling more features to be added without breaking things. For example, I added PATH_INFO to the request to show that your Front Controller could dispatch on an "action" param, or on "PATH_INFO" using the same interface.
I like the direction that kyberfabrikken is going. I would like to see the Chain of Responsibility implemented so that you could add an "action" dispatcher and default and error dispatchers to the chain and run it. Support for and addChild() method would allow for this.
Christopher





Attach() would be a better definition, as addChild suggests that there may be a parent, which is not always the case? But that's just me being fussy huhSupport for and addChild() method would allow for this.![]()





Either addChild() or Attach() is fine. I picked addChild() because if someone extended the basic skeleton to support parent/child controllers it would make sense. But attach() works for me to. Maybe you could take a pass at kyberfabrikken code to add the Chain of Responsibility.
Christopher




I disagree. Escaping of quotes in incoming values is necessary to insert them into an SQL statement. Coincidentally, MySQL (and others, not sure which ones though) support quotes that are escaped with slashes, but the SQL standard prescribes that slashes are doubled. In principle, the method by which quotes are escaped is database-dependent. Based on that argument it is my opinion that the code that carries out 'escaping' of values should reside in the database (abstraction) layer.A Request class implements escaping of all request vars transparently. I think this is such an important feature that it is worth having a Request object just for this reason.
But that is nitpicking of course. I'll try to contribute something useful, an answer to cadmiumgreen's questions:
If you're referring to the switch statement code in your post, Very common I believe. Most 'simple' scripts I have looked at use a structure similar to that. Whether it is good practice is not really relevant. I can say that I once started out exactly like that.how common is it to use a 'skeleton' script?
When your website grows, you will find that the switch statement becomes very large and also possibly very complicated (nested switch, plus if/else statements). You'll find that you repeat a lot of the same code: case 'something': include 'something': case 'somethingelse'. A simple solution for this is to use an associative array to lookup the file belonging to the value of the content parameter. Think of it like a dictionary that translates the content parameter to a file to include.
Note to myself and other people: when you throw around design patterns, think of the problem that these patterns are meant to solve and whether that problem is an actual issue.
Your code example is, I believe, general practice. There is nothing wrong with it as far as I can see.I would like to know the general practice that most PHP developers use when designing a website that generally has the same menus, but the content changes.
With a text editorFor all websites out there, how are these HTML/PHP scripts usually written?
I don't see how.Would PEAR help at all?
Last edited by Captain Proton; Jun 11, 2005 at 14:31. Reason: typo
Well, there isn't much to it, but here goes :Originally Posted by arborint
PHP Code:class RequestMapper_DefaultMapper extends RequestMapper
{
var $default=NULL;
function RequestMapper_DefaultMapper($default=NULL) {
$this->default = $default;
}
function & mapRequest() {
if (!is_null($this->default)) {
return new Dispatcher_ServerPage($this->default);
}
return NULL;
}
}
class RequestMapper_ServerPageMapper extends RequestMapper
{
function & mapRequest() {
if (isset($_GET['page'])) {
return new Dispatcher_ServerPage($_GET['page']);
}
return NULL;
}
}
class RequestMapper_ActionMapper extends RequestMapper
{
function & mapRequest() {
if (isset($_GET['action'])) {
if (!preg_match("/^(\w*)$/", $_GET['action'])) {
trigger_error("Illegal Kontrol_Action [".$_GET['action']."]", E_USER_WARNING);
return NULL;
}
return Action::CreateAction($_GET['action']);
}
return NULL;
}
}
class RequestMapper_MapperChain extends RequestMapper
{
var $_requestMappers=Array();
function & mapRequest() {
for ($i=0,$l=count($this->_requestMappers); $i < $l; ++$i) {
$dispatcher =& $this->_requestMappers[$i]->mapRequest();
if (is_a($dispatcher, 'Dispatcher')) {
return $dispatcher;
}
}
return NULL;
}
function addMapper(&$requestMapper) {
$this->_requestMappers[] =& $requestMapper;
}
}
Note that the performance could be improved by adding handles instead of actual objects to the chain.PHP Code:$mapper =& RequestMapper_MapperChain();
$mapper->addMapper(new RequestMapper_ActionMapper());
$mapper->addMapper(new RequestMapper_ServerPageMapper());
$mapper->addMapper(new RequestMapper_DefaultMapper('default.php'));
$frontController =& new InputController($mapper);
$frontController->execute();





It is actually the opposite! PHP, with some php.ini settings, applies addslashes automagically. Which, if you want clean inputs, you have to remove before you apply a db specific escaping.Originally Posted by Captain Proton
Douglas
Hello World
A Request class implements escaping of all request vars transparently. I think this is such an important feature that it is worth having a Request object just for this reason.Actually I think he meant the opposite. That the Request-class could counteract the non-sense of magic-quotes.Originally Posted by Captain Proton
Edit:
I didn't see the above post before hitting send. Seems I was right on that
Well ... sometimes you need access to the model-layer to complete the validation. I put the validation in a seperate class in the controller domain (FormAction ... extended from Action), which is closely related to a dedicated FormModel, that describes the validation-rules. And there's a FormView widget too ofcourse. Quite similar to PEAR's QuickForm, except I have seperate classes for M, V and C.With a single location for all input validation it's likely to be carried out more carefully and methodically than if it were scattered throughout the app.

Hi!
One quick question in the middle of this very interesting discussion: What is the purpose of the Response-object?





I use it to set headers, and cause a redirect![]()





Here is a rearrangement of kyberfabrikken's code. It reduces things a little and name the Front Controller (which kyberfabrikken will not like). I also added the Request class (which kyberfabrikken will also not like) so that the code works with both GET and POST requests.
I did what I could in a quick pass. This code should run without errors. It could certainly use more clean-up. It does not handle errors well. And, I agree that using a Handle class would improve things. Also I was not sure what direction kyberfabrikken wanted to go on the Action class so that part does not work.
You need to create a default.php page and a another page (e.g. test.php) to run the above code.PHP Code:class Request {
var $_request = array();
function Request() {
if (!strcasecmp($_SERVER['REQUEST_METHOD'], 'POST')) {
$this->_request =& $_POST;
} else {
$this->_request =& $_GET;
}
$this->_request['PATH_INFO'] = $_SERVER['PATH_INFO'];
if (! get_magic_quotes_gpc()) {
$this->removeSlashes($this->_request);
}
}
function removeSlashes(&$str) {
if (is_array($str)) {
foreach ($str as $key => $val) {
if (is_array($val)) {
$this->removeSlashes($val);
} else {
$array[$key] = stripslashes($val);
}
}
} else {
$str = stripslashes($str);
}
}
function get($name) {
return $this->_request[$name];
}
function set($name, $value) {
if ($name) {
$this->_request[$name] = $value;
}
}
}
class Dispatcher_ServerPage
{
var $dirName = './'; // 'ServerPages/';
var $fileName;
function Dispatcher_ServerPage($fileName) {
$this->fileName = $fileName;
}
function execute() {
@include($this->dirName . $this->fileName);
}
}
class RequestMapper_DefaultMapper
{
var $default=NULL;
function RequestMapper_DefaultMapper($default=NULL) {
$this->default = $default;
}
function & mapRequest(&$request) {
if (!is_null($this->default)) {
return new Dispatcher_ServerPage($this->default);
}
return NULL;
}
}
class RequestMapper_ServerPageMapper
{
function & mapRequest(&$request) {
$page = $request->get('page');
if ($page != '') {
return new Dispatcher_ServerPage($page);
}
return NULL;
}
}
class RequestMapper_ActionMapper
{
function & mapRequest(&$request) {
$action = $request->get('action');
if ($action != '') {
if (!preg_match("/^(\w*)$/", $action)) {
trigger_error("Illegal Action [".$action."]", E_USER_WARNING);
return NULL;
}
return Action::CreateAction($action);
}
return NULL;
}
}
class FrontController
{
var $_requestMappers = array();
function addMapper(&$requestMapper) {
$this->_requestMappers[] =& $requestMapper;
}
function execute(&$request) {
$n = count($this->_requestMappers);
for ($i=0; $i<$n; ++$i) {
$dispatcher =& $this->_requestMappers[$i]->mapRequest($request);
if (is_a($dispatcher, 'Dispatcher_ServerPage')) {
$dispatcher->execute($request);
break;
}
}
return NULL;
}
}
$frontController =& new FrontController();
$frontController->addMapper(new RequestMapper_ActionMapper());
$frontController->addMapper(new RequestMapper_ServerPageMapper());
$frontController->addMapper(new RequestMapper_DefaultMapper('default.php'));
$frontController->execute(new Request());
Christopher





Thought,
I don't make the destinction of where the request comes from, either $_GET or $_POST, I use $_REQUEST instead. This is within the HttpRequest class, and I leave it to the Request class (encapsulates HttpRequest and HttpResponse) to make the destinction if and when it's required.so that the code works with both GET and POST requests.
Just thought I'd add that to the discussion![]()
$_REQUEST ?Originally Posted by arborint
But anyway ... sometimes you actually might want to distinguish between GET and POST within the same request.
I feel inclined to point out why that makes me sour. I understand the whole solution as eing the frontcontroller, thus having class by the same name is misguiding. That's the reason for calling it InputController. But actually, we could do completely without that class, since all it does is two lines of code - it gets the dispatcher from the requestmapper, and then it executes the dispatcher. We could just put thoose two lines of code directly in the bootstrap file. If that would help to clarify what the FrontController is, I'm willing to go with it.Originally Posted by arborint
If we should have a Request class, I must insist to also have a Response-class. I don't like Dr Livingston's inclination to merge the two, however tempting it may be. McGruff already explained why, and I agree on that.Originally Posted by arborint
So do I.Originally Posted by Dr Livingston
I think you're right. I used InputController because I can't figure out exactly where the difference is between FrontController and ApplicationController, so I don't really bother to distinguish. To me they're just InputControllers. Perhaps they are even just Controllers ? It's about the context anyway, since you could easily have two bootstrap-scripts, each looking like the above code. Would they be FrontControllers ?Originally Posted by arborint
About the Request and Response objects ; arborint's challenge was to make the minimal FrontController. I think we can probably agree on how to implement things, but we will differ on which elements to include. The discussion about Request and Response isn't as much if they are appropriate (I agree that Request has uses, even though it may not seem that way from my posts). The question is if it's needed in very simple applications ? I think not, and you would probably agree?
Some of the reasons why "Frameworks like Mojavi, WACT, etc. have controllers crammed full of code to support the specifics of the framework." (quote:arborint) is that they are prepared to handle very big applications, so they bring in the big guns. I think such things should be optional if we are to stay on the course. The same thing goes for Handle (which I earlier suggested used with the RequestMapper). It's really useful, and I wouldn't leave home without it, but for a minimal setup it's overhead, since it essentially trades simplicity for efficiency.
The Action was meant as a object-oriented dispatcher object, implementing a Command-pattern. It would carriy out updates, and redirect to a view (ServerPage). It wouldn't produce output.Originally Posted by arborint
PHP Code:class RequestMapper_ActionMapper extends RequestMapper
{
var $factory=NULL;
function RequestMapper_ActionMapper(&$factory) {
$this->factory =& $factory;
}
function & mapRequest() {
if (isset($_GET['action'])) {
if (!preg_match("/^(\w*)$/", $_GET['action'])) {
trigger_error("Illegal Kontrol_Action [".$_GET['action']."]", E_USER_WARNING);
return NULL;
}
return $this->factory->createAction($_GET['action']);
}
return NULL;
}
}
class ActionFactory {
function & createAction($actionName) {
$className = 'Action_'.$actionName;
if (!class_exists($className)) {
require_once('Action/'.$actionName.'.php');
}
return new $className;
}
}
/**
* @abstract
*/
class Action extends Dispatcher
{
}





I'm seeling lots of code that extends RequestMapper, but where (and what and why) is this RequestMapper?
Also, what is the distinction between a page and an action? It seems arbitary.
Douglas
Hello World
It's just an abstract class (or interface if you use php5). See post #35Originally Posted by DougBTX
As you see, I use ServerPages (aka DispatcherView) as the default view. So that would be your 'page'. Action is a Command - it performs some sort of update to the Model and redirects to a view (ServerPage).Originally Posted by DougBTX
The Action would most likely deal with POST requests, while the ServerPage's would result from a GET request. This seperation is more about REST than MVC, but it's kind of the same thing.
You might prefer to use a TemplateView rather than DispatcherView, which is fine. In that case you'll need a View which looks a lot like the Action :
View/Test.phpPHP Code:class RequestMapper_ViewMapper extends RequestMapper
{
var $factory=NULL;
function RequestMapper_ViewMapper(&$factory) {
$this->factory =& $factory;
}
function & mapRequest() {
if (isset($_GET['view'])) {
if (!preg_match("/^(\w*)$/", $_GET['view'])) {
trigger_error("Illegal View [".$_GET['view']."]", E_USER_WARNING);
return NULL;
}
return $this->factory->createView($_GET['view']);
}
return NULL;
}
}
class ViewFactory {
function & createView($viewName) {
$className = 'View_'.$viewName;
if (!class_exists($className)) {
require_once('View/'.$viewName.'.php');
}
return new $className;
}
}
/**
* @abstract
*/
class View extends Dispatcher
{
}
As you can see, it's copy&paste from Action, but the distinction is important, so they get seperate classes. They could probably share a common RequestMapper, since the factories are seperated out anyway. Any candidates for a name ?PHP Code:class View_Test extends View
{
function execute() {
$t =& new Template('templates/test.tpl.html');
$t->set('title', 'Test');
$t->set('body', 'Hello World');
echo $t->render();
}
}





Curious bystander...
Is the encapsulation of HttpRequest and HttpResponse an attempt at duplicating how you would handle the situation with a Java Servlet?
Bookmarks