On Frameworks, RoR & PHP

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

Jenk wrote:Example of a callback in php (from Phaux:) http://phaux.googlecode.com/svn/trunk/C ... veTest.php
So this is the code that registers the callback:

Code: Select all

/*
					** The following registers a live callback on this anchor
					** onClick tells the object that we want this actions to 
					** exec on the link being clicked
					** the next line $this,"renderMessageOn",array()
					** tells the anchor what message we want to use to rerender a 
					** portion on the page (commented above)
					** 
					** the last line $this,"setMessage",array($message)
					** tells the anchor what callback to run when the action occurs
					*/
		return $html->anchor()->with($message)->
			liveUpdateWithCallbackOn("onClick",
			$this,"renderMessageOn",array(),
			$this,"setMessage",array($message)).
Where renderMessageOn() and setMessage() are programmer defined methods in the controller. It is a fluent interface, so the method liveUpdateWithCallbackOn() is the thing of interest here. Where in the codebase is this method? I haven't dug through the code, but I assume that it either saves this info in the session or passes it via the request some how.
(#10850)
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

Code: Select all

/*
	** Returns the new callback key
	*/
	public function createCallback($object,$function,$arguments = ""){
		global $app;
		if(!is_array($arguments)){
			$arguments = array();
		}
		$key = $_SESSION[$app]['session']->registerCallback(
												$object,$function,$arguments
												)->key();
		return $key;
	}
Stores the state in the session.
ev0l
Forum Commoner
Posts: 56
Joined: Thu Jun 21, 2007 1:50 pm

Post by ev0l »

kyberfabrikken wrote: Because of PHP's stateless nature, you can't use continuations, which - if I'm not mistaken - is the way Seaside works? A continuation is even more powerful way of preserving state than the way application servers such as JSP or .NET does it. With a continuation, you not only preserve data, but also the program pointer/stack frame. Smalltalk can be a bit alien to developers, who primarily work with C-like languages. For an idea about, what a continuation is, have a look at cocoon:
http://cocoon.apache.org/2.1/userdocs/f ... tions.html
Yes that is correct. PHP does not support this but Seaside offers a lot of very powerful concepts not just continuations.

The two questions people appear to be floating around are programatic HTML generation and callbacks. I would like to address both those things and briefly cover how they are implemented in Phaux.

Have a look at WHCounter's renderContentOn method. All components that want to render something to a users web-browser must implement renderContentOn. renderContentOn gets passed one argument, an instance of WHHtmlCanvas. WHHtmlCanvas's job is to return instances of subclasses of WHTag. Phaux expects renderContentOn to return the product of using WHHtmlCanvas and it's tags which is actually a sting of HTML. WHTag impliments __toString to return exactly what you would expect (an HTML tag). It would not be difficult to swap out Phaux's rendering system for another, in fact using different rendering systems interchangeably would be possible as well.

Rendering HTML programatically encourages the programmer to utilize the language concepts in describing the output. In Phaux you would not describe the entire output of a component in one method you would split up the output across multiple methods. Doing so greatly increases reusability, making it easy to subclass and only change the behavior that you want to with out reconstructing the entire view. A good example of this is WHNavigation and WHLiveNavigation. WHNavigation renders a tab based, notebook style navigation component. WHLiveNavigation makes WHNavigation use AJAX to chage it's content area. WHLiveNavigation only redefined the methods it needed to. Flexibility like this is exceptionality difficult with templates.

Back to WHCounter.

Code: Select all

$html->anchor()->callback($this,"add")->with("++")
The above creates an anchor tag, assigned the callback $this->add() to it, and gives it a label ("++"). When a user clicks on the link the method add() of $this will be run.

$this does not need to be $this. It could be your model object on any other object that you might want to operate on.

Code: Select all

public function add(){
		$this->counter++;
	}
Bacause Phaux is completely stateful the above code works as expected. No need to store the value of $this->counter in a database, file, or the POST/GET vars. The object and everything it references persists in the users session.

Phaux keeps a reference to the callback object and the name of the method to be run when that callback is called in the users session. One of the things that surprised me about PHP was the speed in which it handles session serialization and deserialization. Large applications would most likely want to use tempfs or some other means of session cache.

I hope the above begins to answer some of your questions. Happy hacking :-)
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

I think I am getting an understanding of your code. There are obviously three ways to do this kind of thing: pass it, store it, put it in code. I think my concern is that you have locked yourself into one method: store it. I don't dislike maintaining state in the session when applicable. I do question only doing it that way. I am also suspicious of your examples. I have never had to implement what WHCounter does. It is one of those bits of code that newbies implement when they are trying to figure out how the session works.

I should also note that persisting data also causes its own set of problems as reality creeps in. On real pages, values need to be reset when the user returns to the page anew. So request values are still necessary to indicate some state. Otherwise you need garbage collection of persisted valued (which I have had to do on occasion, ugh).

I do like the linkage between anchors/forms and the controllers that run them. I tend to only use the session for Application Controllers and in special cases. I think I will look into whether expanding this to general Input Controllers would provide some automation benefits.


I would also like to note separately that kyberfabrikken's link to Cocoon's Continuations page starts with the following paragraph:
Cocoon wrote:Web applications are essentially event-driven applications. Such applications have to react to events generated from the client browser, and they respond to these perhaps by changing their internal state and generating a response.
Note the word I highlighted -- even on the J2EE biased site. Stateful is one way to do things ... not the only way or necessarily the best way ... just a way.
(#10850)
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

That's not the correct context. He means that maybe the state will update, maybe it won't - not that it may update the state, or use some other means.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

Jenk wrote:That's not the correct context. He means that maybe the state will update, maybe it won't - not that it may update the state, or use some other means.
No ... I read it both ways, you are only reading it one way. But if you do not have to update the internal state then you don't need to be internally stateful. You can also preserve state in the request/response which is one of the tenets of REST. The set and copy logic of either is essentially identical. The question becomes -- do you think always doing it only one way is the right thing to do?
(#10850)
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

ev0l wrote: Rendering HTML programatically encourages the programmer to utilize the language concepts in describing the output. In Phaux you would not describe the entire output of a component in one method you would split up the output across multiple methods. Doing so greatly increases reusability, making it easy to subclass and only change the behavior that you want to with out reconstructing the entire view. A good example of this is WHNavigation and WHLiveNavigation. WHNavigation renders a tab based, notebook style navigation component. WHLiveNavigation makes WHNavigation use AJAX to chage it's content area. WHLiveNavigation only redefined the methods it needed to. Flexibility like this is exceptionality difficult with templates.
Great passage! This reminds me of how uncomfortable I felt when digging into Code Igniter. The present implementations of MVC feel very rigid. Besides, back during the days of the great template debate in the PHP community, I allways felt that the language was the templating engine. :D

ev0l wrote: Bacause Phaux is completely stateful the above code works as expected. No need to store the value of $this->counter in a database, file, or the POST/GET vars. The object and everything it references persists in the users session.

Phaux keeps a reference to the callback object and the name of the method to be run when that callback is called in the users session. One of the things that surprised me about PHP was the speed in which it handles session serialization and deserialization. Large applications would most likely want to use tempfs or some other means of session cache.


This scares me just a little bit. Another nice thing about PHP Sessions is the flexibility of how one may handle them. To date, I've built 2 LVS style clusters where PHP was a big part of the operations and the only way to provide a rock solid garauntee that a users session would never be lost in the event of a server failure was to store the sessions in the DB (there may be network wide in memory type solutions now but that's not as important in this discussion). Ergo, the question: Does Phaux allow me to use my favorite sessions mechanism (as in one other then the default)?
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

While this conversation as strayed a bit, I'd like to zero back in on something along the lines of the original intent of splitting this thread.

What is it about MVC that would make some of us believe we are in a post MVC era in ours (PHP) or any other community?

Personally, I think MVC feels right, but I'd better state a couple of things first to frame my statement.

1) For my own stuff, I don't use any of the frameworks out there. I've harvested my own.

2) I'm very light on M portion of MVC.

3) My controllers are switches. Using an object as a controller feels like a God object too me. Another advantage of this to me (due to my apparently non-standard use of switches) is that the potential logic paths are very easily visualized and groked at a quick glance.

I personally feel that a good deal of the problem today is that we are attempting to implement the patterns 'en toto' and aren't leaving much room for flexibility as a result. Remaining pure to the pattern results in some things being very difficult in most MVC frameworks.

That said, do we throw out MVC period? I really think doing so would be kind of a "baby with the bathwater" kind of thing and simply lead us down the next promissing looking shining path.

One more thing: This isn't to take away from what Phaux is doing. I'm just simply trying to frame further discussion into a more managable portion if you will by simply focusing on what people perceive to be problematic with MVC or various implentations of it.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

BDKR wrote:While this conversation as strayed a bit, I'd like to zero back in on something along the lines of the original intent of splitting this thread.

What is it about MVC that would make some of us believe we are in a post MVC era in ours (PHP) or any other community?
Actually I never said "post MVC", what I said was post-ZF/RoR. But you have to understand that I don't think either are too MVC. RoR is famous for convention, an ActiveRecord-O/RM blend and scaffolding. ZF isn't famous for anything yet. ;) Their MVC is a bit of a mess if you ask me. They are learning but they really don't get it yet. Just look at the View mess -- is was so bad they just gave up and put a render method in the controller. That's not MVC!
BDKR wrote:Personally, I think MVC feels right, but I'd better state a couple of things first to frame my statement.

1) For my own stuff, I don't use any of the frameworks out there. I've harvested my own.

2) I'm very light on M portion of MVC.

3) My controllers are switches. Using an object as a controller feels like a God object too me. Another advantage of this to me (due to my apparently non-standard use of switches) is that the potential logic paths are very easily visualized and groked at a quick glance.

I personally feel that a good deal of the problem today is that we are attempting to implement the patterns 'en toto' and aren't leaving much room for flexibility as a result. Remaining pure to the pattern results in some things being very difficult in most MVC frameworks.
I agree that MVC feels right ... but you have to buy into all the benefits before it actually works for you. That is a leap of faith for those who have not experienced the benefits first hand. Looking at you specific comments it seems like you have not fully embraced MVC. One note about your "god object" comment -- a "god object" is a code smell. Code smells are warnings that say "if you are not doing this for good reason then you probably should not me doing it." They are not prohibitions. Implementing Action Controllers is a good reason.
BDKR wrote:That said, do we throw out MVC period? I really think doing so would be kind of a "baby with the bathwater" kind of thing and simply lead us down the next promissing looking shining path.

One more thing: This isn't to take away from what Phaux is doing. I'm just simply trying to frame further discussion into a more managable portion if you will by simply focusing on what people perceive to be problematic with MVC or various implentations of it.
I would actually like to add what Phaux is doing to the mix. However, I do think they are limiting themselves to a specific style because it makes sense to them. But I really think that a framework at its lowest level should support all these things -- and then add layers on top to support specific styles for specific solutions. Best would be if you could mix-and-match.

I also don't think that anyone except maybe Google has really integrated the server side stuff with the Javascript to make a building block system that encompasses both languages. As ev0l notes, part of what he is doing is Ajax talking back to his controllers. Google generates their Javascript -- maybe that is an interesting direction to take.
(#10850)
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

arborint wrote: Actually I never said "post MVC", ...
My bad. :oops:
arborint wrote: I agree that MVC feels right ... but you have to buy into all the benefits before it actually works for you.
This is where we part company (big time). But since this is a track that I don't think is good for the discussion in general, I'll let it go.
arborint wrote: That is a leap of faith for those who have not experienced the benefits first hand. Looking at you specific comments it seems like you have not fully embraced MVC.
What i've embraced is the pattern alone. Nothing more and nothing less. What I've decided to leave go is the religion and it's strict adherence to dogma. A pattern is a pattern regardless of implementation.
arborint wrote: One note about your "god object" comment -- a "god object" is a code smell. Code smells are warnings that say "if you are not doing this for good reason then you probably should not me doing it." They are not prohibitions. Implementing Action Controllers is a good reason.
A God Object is an Anti-Pattern. We can begin to chisel away at that definition if we want, but doing so isn't helping me any. :wink:
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

BDKR wrote:What i've embraced is the pattern alone. Nothing more and nothing less. What I've decided to leave go is the religion and it's strict adherence to dogma. A pattern is a pattern regardless of implementation.
With the simpler patterns maybe a pattern is a pattern. But these enterprise patterns are wound up in a continuum of decisions. MVC plays off of N-Tier and a bunch of other ideas. And wrapped up in MVC are a bunch of concepts and patterns from Front Controller to Command that are not explicit, but have grown related through the trial and error of finding implementation best practices. It's not like we can pick and choose from a body of knowledge like that. It is really not about purity, it is just where we currently are at. If you are still using switches instead of dispatching Commands then you have not embraced the current state of MVC. It's not enough to know the what of a pattern ... you need to know the why of the pattern.
BDKR wrote:A God Object is an Anti-Pattern. We can begin to chisel away at that definition if we want, but doing so isn't helping me any. :wink:
But Action Controllers to do not really include the main functionality of the entire program. In fact they are a reasonable guideline for dividing up a program by request. They do meet the "Large Class" code smell, but there are some things you can do to minimize that. And again, the point of anti-patterns and code smells is to warn you that you might be doing something that you shouldn't be doing -- not to stop you when you are doing what you need to do.
(#10850)
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

But Action Controllers to do not really include the main functionality of the entire program. In fact they are a reasonable guideline for dividing up a program by request. They do meet the "Large Class" code smell, but there are some things you can do to minimize that
Whereas a switch is a design smell.
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

ole wrote:
But Action Controllers to do not really include the main functionality of the entire program. In fact they are a reasonable guideline for dividing up a program by request. They do meet the "Large Class" code smell, but there are some things you can do to minimize that
Whereas a switch is a design smell.
Too bad that the use of the switch in that example is brain dead anyways. Of course (and in typical fashion in this community) rather then simply say that something is a bad decision (as in, there is a proper usage in other places), it's simply labeled as the devils spawn to bolster some other position.

From the article:
Then we can eliminate the switch statement code smell very easily. We replace it with polymorphism.
How much of that is simply spin? Let's change it a little and see what we come up with.
Then we can eliminate the switch and replace it with polymorphism.
That's really the heart of the article right there. It's truest objective: to show how to refactor a bad design decision to be more flexible and less verbose via polymorphism.
You don't even need to read much of it to see that. A switch in that case IS a code smell, but to arrive at the conclusion that's allways evil because it's clearly poor in some places is dimented. The interesting thing is that he said an IF/ELSEIF block is even worse, but doesn't continue to adorn that idea at every opportunity with the "code smell" moniker. He clearly has a feeling about switches that goes beyond this article.

Once again, we're about to derail another thread with incidentals. :roll:
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

BDKR wrote:A switch in that case IS a code smell, but to arrive at the conclusion that's allways evil because it's clearly poor in some places is dimented. The interesting thing is that he said an IF/ELSEIF block is even worse, but doesn't continue to adorn that idea at every opportunity with the "code smell" moniker. He clearly has a feeling about switches that goes beyond this article.
Could you rephrase that, I don't understand what you are trying to say.

The name of the refactor for this smell is called "Replace Conditional with Polymorphism" and this is the motivation behind it:
One of the grandest sounding words in object jargon is polymorphism. The essence of polymorphsim is that it allows you to avoid writing an explicit conditional when you have objects whose behavior varies depending on their types.

As a result you find that switch statements that switch on type codes or if-then-else statements that switch on type strings are much less common in an object-oriented program.

Polymorphism gives you many advantages. The biggest gain occurs when this same set of conditions appears in many places in the program. If you want to add a new type, you have to find and update all the conditionals. But with subclasses you just create a new subclass and provide the appropriate methods. Clients of the class don't need to know about the subclasses, which reduces the dependencies in your system and makes it easier to update.
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

arborint wrote: MVC plays off of N-Tier ....
You're kidding right? Oh, I get it. You mean to assume that I can't understant that, much less implement it, with my own harvested framework. Oohhhh clever you, but you're wrong. :D
arborint wrote: If you are still using switches instead of dispatching Commands then you have not embraced the current state of MVC.
The current state of it? There are others? Don't confuse 'state', however vague that may be, with 'practice'. What's obvious here is that I don't embrace the current practice. Plain and simple as that.
arborint wrote: But Action Controllers to do not really include the main functionality of the entire program. In fact they are a reasonable guideline for dividing up a program by request. They do meet the "Large Class" code smell, but there are some things you can do to minimize that. And again, the point of anti-patterns and code smells is to warn you that you might be doing something that you shouldn't be doing -- not to stop you when you are doing what you need to do.
Look. I know what you are saying and actually understand it. In professional settings (which aren't allways that professional) i've played ball and made use of MVC in it's more current practice (RonR in particular). As an individual and for my own projects, I choose to do something else. Plain and simple as that. Continued Image ... is just end with us both being blue in the face.
Post Reply