Seaside in PHP (Phaux)

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
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

kyberfabrikken wrote:
Jenk wrote:
kyberfabrikken wrote:Quite interesting. I don't like the base premise of a stateful framework - HTTP is stateless, and so should HTTP applications.
If you were to change your mind about that, much, much more powerful applications come to light.
I disagree.

Mind you, I realise that some things are better handled with server side state, but they are practical workarounds; I think it's a sane strategy to avoid server side state as far as possible. Using a framework which encourages the opposite is dangerous from my POV.
So you require users to login on every page request? You don't use cookies, get, post or session data? You have absolutely no persistence at all?
User avatar
kyberfabrikken
Forum Commoner
Posts: 84
Joined: Tue Jul 20, 2004 10:27 am

Post by kyberfabrikken »

ev0l wrote: Most stateful applications are load balanced by session. If you are worried about load balancing don't. It's very easy with a stateful application.
I weren't talking about performance. But now you bring it up, if you have server side state, HTTP proxy cache and client side cache are off the table.
ev0l wrote: I am not sure what benefits you gain by not using a stateful framework.
Simplicity in design.

More concretely: What happens if a user press the browsers back/forth buttons? What happens if the user bookmarks a page? What happens if the user have several windows open to the same session (Since tabs have become standard outfit in most browsers, this is not a exotic any more). These are non-issues in a stateless application, but problems which need to be dealt with in a stateful application.
Jenk wrote:So you require users to login on every page request? You don't use cookies, get, post or session data? You have absolutely no persistence at all?
Cookies are stored at the client, and included with each request. Query-string parameters (GET) are part of the URL, and thus part of the request. So are POST parameters. It's only server side state, which is a problem.
ev0l
Forum Commoner
Posts: 56
Joined: Thu Jun 21, 2007 1:50 pm

Post by ev0l »

kyberfabrikken wrote:
Simplicity in design.
Of the framework or of the application. Applications that have to deal with low level HTTP stuff are going to be a lot more complicated, harder to maintain, and more difficult to reuse.
kyberfabrikken wrote: More concretely: What happens if a user press the browsers back/forth buttons?
You register any values you want the back button to follow. See WHRegisteredCounter or WHNavigation. Notice registerObjectOnKeyPath. In fact the back button works better in Phaux because of a redirection after every action callback. Clicking the back button in Phaux will never submit a form again or do an action twice.
kyberfabrikken wrote: What happens if the user bookmarks a page?
You can add meaningful get vars to the URL by overwriting updateRoot in your subclass of WHComponent. See WHREServeModelEdit. Phaux does not yet have a standard way to deal with those url args but the implementation will be easy and the second me or someone else needs it it will be added.

kyberfabrikken wrote: What happens if the user have several windows open to the same session (Since tabs have become standard outfit in most browsers, this is not a exotic any more). These are non-issues in a stateless application, but problems which need to be dealt with in a stateful application.
Works fine. Just register any value you want to follow the back button like the tabs do in WHNavigation.
kyberfabrikken wrote: Cookies are stored at the client, and included with each request. Query-string parameters (GET) are part of the URL, and thus part of the request. So are POST parameters. It's only server side state, which is a problem.
What happens when your state gets complex. Say you are writing an airline reservation system. The data quickly starts getting to large to store in the GET/POST vars. At some point you have to start explicitly storing transient data somewhere. Plus manually dealing with get and post vars on every page is tedious and can hinder reusability.

Say for example you build a color selector widget. This widget has a complex workflow and multiple "pages" that allow a user to select the exact color they want. In a system that stores session state in the URL the color widget must have specific knowledge of where it is coming from and where it is going. You color widget can't clobber other components GET/POST vars.

With Phaux you just call the color widget as a "dialog" and give the dialog an answer callback telling it where you want its value when it is done. Phaux replaces the current component with the dialog (a dialog is just an instance of a component), lets the dialog do it's thing, and send the value to the callback. It is actually more complex to describe than it is to show in code. See WHDialogTest.
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Post by Benjamin »

Hmm, wonders what would happen if I build a site using your framework and google nailed it. :twisted:
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

ev0l wrote: REServe allows you to treat a relational database like an object oriented one. REServe uses a follow reference approach to locating data not a relational one.
8O Beware! Fabian Pascal would kick your butt for this. :lol:

So when you say a "follow reference approach", is that like the "traversal" method that OODBMS vendors speak of?

Another question: Is there not an OODBMS that can be used? It would avoid the obvious overhead of a translational layer between relational and heirarchal layouts (if you will).

If it seems like I am dwelling a bit on that point, it's because I've not allways been a big fan of abstraction of the database to such a level. However, after seeing just how well such a type of layer could work (Ruby's Active Record / RonR with a dead serious cluster of machines) I'm forced to admit that it's got a future.

On the topic of callbacks, I think this is awesome and makes for some amazing functionality and flexibility. Even in PHP4, there is still room for application of this type of functionality. I'm using it to provide flexibility to an Ajax based calander as well custom rules for a reservation system. Awesome shizzle!

I hope I can get some time to check out your stuff. It looks like I may be doing a lot of Ruby in the near future here so I'm not sure how much time I'll have.

Cheers
djot
Forum Contributor
Posts: 313
Joined: Wed Jan 14, 2004 10:21 am
Location: planet earth
Contact:

Post by djot »

-
$html->anchor()->callback($this,"add")->with("++")
This looks like a PHP copy of jQuery ;)

djot
-
ev0l
Forum Commoner
Posts: 56
Joined: Thu Jun 21, 2007 1:50 pm

Post by ev0l »

djot wrote:-
$html->anchor()->callback($this,"add")->with("++")
This looks like a PHP copy of jQuery ;)
I am not familiar with jQuery but the idea was to make the code as clear and as concise as possible. PHP does not support method cascading so every method that does not logically return something in Phaux returns $this. Reduces the amount of typing and leads to more readable code.
ev0l
Forum Commoner
Posts: 56
Joined: Thu Jun 21, 2007 1:50 pm

Post by ev0l »

BDKR wrote: So when you say a "follow reference approach", is that like the "traversal" method that OODBMS vendors speak of?
Yep.
BDKR wrote: Another question: Is there not an OODBMS that can be used? It would avoid the obvious overhead of a translational layer between relational and heirarchal layouts (if you will).
Not in the PHP world. The closest is DyBASE but did not have much luck with it.
BDKR wrote: If it seems like I am dwelling a bit on that point, it's because I've not allways been a big fan of abstraction of the database to such a level. However, after seeing just how well such a type of layer could work (Ruby's Active Record / RonR with a dead serious cluster of machines) I'm forced to admit that it's got a future.
Mapping objects to relational databases by hand it tedious and using a generator can lead to code unmanageability. Using some sort of abstraction is the only long term feasible approach. The impedance mismatch between the two is a difficult problem to solve and I don't know if I am happy with any solution I have seen (including my own). It's an interesting topic but not something I am prepared to discuss after a couple glasses of wine :-).
BDKR wrote: I hope I can get some time to check out your stuff. It looks like I may be doing a lot of Ruby in the near future here so I'm not sure how much time I'll have.
Check it out you got nothing to lose but the afternoon.
djot
Forum Contributor
Posts: 313
Joined: Wed Jan 14, 2004 10:21 am
Location: planet earth
Contact:

Post by djot »

-
I am not familiar with jQuery but the idea was to make the code as clear and as concise as possible. PHP does not support method cascading so every method that does not logically return something in Phaux returns $this.
Well, jQuery is Javascript, but it does this also.

Visit http://jquery.com/ and click on "Run" near "What does jQuery code look like? The quick and dirty:"

or see chainability here:
http://docs.jquery.com/Tutorials:How_jQ ... _jQuery.29

djot
-
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Post by alex.barylski »

I'm missing something, in regards to the PHP being responsible for persisting state...

How do you keep state? Using SESSIONS is the only way to go or some other server side mechanism anyways...

Relying on cookies is just crazy...what happens if the client doesn't support cookies? Users can't login?
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Hockey wrote:I'm missing something, in regards to the PHP being responsible for persisting state...

How do you keep state? Using SESSIONS is the only way to go or some other server side mechanism anyways...

Relying on cookies is just crazy...what happens if the client doesn't support cookies? Users can't login?
Well, actually you only need a session id in the session, the rest can be dealt with however the server pleases (also in session, in database, in memory, on disk).
User avatar
kyberfabrikken
Forum Commoner
Posts: 84
Joined: Tue Jul 20, 2004 10:27 am

Post by kyberfabrikken »

ev0l wrote: Of the framework or of the application. Applications that have to deal with low level HTTP stuff are going to be a lot more complicated, harder to maintain, and more difficult to reuse.
Abstractions hide details. This is good, if you don't need the details, but if you occasionally do, they becomes a burden, rather than a help.
ev0l wrote: Clicking the back button in Phaux will never submit a form again or do an action twice.
Using redirect-after-post is a quite practical pattern, which I use myself, even if it means I need to use (temporary) server side state.

'do an action twice' is only an issue, if your GET requests aren't idempotent, as they should be. That's slightly off topic though, since that doesn't really have anything to do with statefulness.
ev0l wrote: You register any values you want the back button to follow. See WHRegisteredCounter or WHNavigation. Notice registerObjectOnKeyPath.
I'm not sure I completely grasp the registerObjectOnKeyPath() function. Is it correct, that you keep the history of the entire session at the server side? Each new page will then get a new state-id?
ev0l wrote: You can add meaningful get vars to the URL by overwriting updateRoot in your subclass of WHComponent.
And then, you would have a stateless application. That's exactly what I have been suggesting all along.

But why make the stateful solution the default, and require the user to go through a lot of work to get a stateless application, rather than the other way around?
ev0l wrote: Works fine. Just register any value you want to follow the back button like the tabs do in WHNavigation.
OK, let's take a use-case scenario, which illustrates my concerns.
Assume that you have a page with search results, that paginates the results. You open up the same page in two tabs. In the first tab, you make a search for something. In the other tab, you make a search for something else. On tab #1, you click to page 2. Will you not see page 2 of the second search, even though you would expect page 2 of the first search?
ev0l wrote: What happens when your state gets complex. Say you are writing an airline reservation system. The data quickly starts getting to large to store in the GET/POST vars.
There are occasions, where server side state is the most practical solution. A shopping cart for example, or a very complex form, which needs to be broken down into a multi-page form. Or keeping form values, when doing redirect-after-post. I'll use it in these cases, but I wouldn't default to use it.
Hockey wrote:I'm missing something, in regards to the PHP being responsible for persisting state...

How do you keep state? Using SESSIONS is the only way to go or some other server side mechanism anyways...
You have two ways. Either you use cookies, or you embed the state in the URL.
Hockey wrote:Relying on cookies is just crazy...what happens if the client doesn't support cookies? Users can't login?
Use www-authentication.
User avatar
BDKR
DevNet Resident
Posts: 1207
Joined: Sat Jun 08, 2002 1:24 pm
Location: Florida
Contact:

Post by BDKR »

ev0l wrote:
BDKR wrote: If it seems like I am dwelling a bit on that point, it's because I've not allways been a big fan of abstraction of the database to such a level. However, after seeing just how well such a type of layer could work (Ruby's Active Record / RonR with a dead serious cluster of machines) I'm forced to admit that it's got a future.
Mapping objects to relational databases by hand it tedious and using a generator can lead to code unmanageability. Using some sort of abstraction is the only long term feasible approach. The impedance mismatch between the two is a difficult problem to solve and I don't know if I am happy with any solution I have seen (including my own). It's an interesting topic but not something I am prepared to discuss after a couple glasses of wine :-).
I know this would clearly add a good deal more work, but is it possible to go to using an ODB? Ozone is ODMG compliant and there is a paper written on how to use XML as an Object Interchange Format. Using just that single XML layer is bound to be a lot faster then all of the associated overhead of a relational mapper.

For those that don't know, you would need that XML interchange because Ozone (or any other for that matter) is not returning PHP objects.

Now honestly, I'm not 100% sure this is possible as it stands (Heck, I'm not 100% sure of my understanding here), but it sounds good eh? :lol:

Good work BTW. :D
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

If someone ports GLORP to PHP, I'll have their babies.
ev0l
Forum Commoner
Posts: 56
Joined: Thu Jun 21, 2007 1:50 pm

Post by ev0l »

kyberfabrikken wrote: I'm not sure I completely grasp the registerObjectOnKeyPath() function. Is it correct, that you keep the history of the entire session at the server side? Each new page will then get a new state-id?
I keep a copy of the current state as well as any possible callbacks. I then keep another state registry. Any values you have registered using registerObjectOnKeyPath() are kept in that registry. When you access a page you pass along a registry key and the values kept in the registry are restored into your session.
kyberfabrikken wrote: And then, you would have a stateless application. That's exactly what I have been suggesting all along.
No you misunderstand me. The application is still stateful but if you _need_ a user to be able to book mark a page you can add a little bit of meaning full info to the URL. It's completely optional and only takes a second to do. Phaux's URL's are opaque.
kyberfabrikken wrote: But why make the stateful solution the default, and require the user to go through a lot of work to get a stateless application, rather than the other way around?
It's not stateless. It's also not "a lot of work" to add a couple get vars to the url. Overwride updateRoot in your subclass of WHComponent and do something like ....

Code: Select all

$htmlRoot->addUrlArg("varName","value");
kyberfabrikken wrote: OK, let's take a use-case scenario, which illustrates my concerns.
Assume that you have a page with search results, that paginates the results. You open up the same page in two tabs. In the first tab, you make a search for something. In the other tab, you make a search for something else. On tab #1, you click to page 2. Will you not see page 2 of the second search, even though you would expect page 2 of the first search?
Again if you need to you just register that component for backtracking with registerObjectOnKeyPath().
Post Reply