Every time I try and do some web application programming that involves forms (i.e. getting data from a user) it ends up being far more complicated than I expect (and more complicated than it should be I feel).
Anywhere else that one programs something to get some data from a user it's fairly direct and simple:-
Output something to ask a question Wait for user to enter response Get return with the response
OK, it's a bit more complex/messier when using a GUI because there isn't necessarily a simple single thread but it still comes down to the program waiting for an event and, when the event happens, it gets handed some data.
However when web programming it's nothing like this, one can't simply ask a question and get the answer. Say one has a PHP script running server side, it creates a form which is then displayed when the client requests it and the client fills in the form. The trouble is that there's no direct way for the PHP script that created the form to get the result - at least there isn't in any of the environment/frameworks that I've used.
What happens is that there is *another* script which gets run (server side) when the client submits the form duly filled in. This other script has no direct connection with the script that created the form, no common environment, nothing.
It's thus very difficult to write simple form driven applications as one can't simply display a form and get the data from the form in 'one place' as it were.
Am I missing something obvious here?
On 17 June 2012 12:23, Chris Green cl@isbd.net wrote:
requests it and the client fills in the form. The trouble is that there's no direct way for the PHP script that created the form to get the result - at least there isn't in any of the environment/frameworks that I've used.
Back in the day when everyone generally thought PHP was a good language to do web development in, I played about a little with PHP.
A very dirty, hacky, nasty way to do this is to call the same php script, with your <form> having a hidden input field. The PHP script checks it and does different things depending on the value. As I said, very nasty.
What happens is that there is *another* script which gets run (server side) when the client submits the form duly filled in. This other script has no direct connection with the script that created the form, no common environment, nothing.
Would something like a session key help? (I have no idea) Script 1 generates a session key, creates a bunch of settings from the form, saves to DB or somewhere, calls script 2 with same session key. Script 2 grabs data relating to session key and carries on.
I can't help but think that's not secure: malicious agent could try to determine or brute force session keys until a valid one is selected, at which point whatever action that session key relates to, would get executed (again). Maybe there's some potential for information leakage? Who knows. Not touched PHP for 10 years.
I bet I will get laughed at by everyone else, since my suggestion must be so silly.
Regards, Srdjan
On Sun, Jun 17, 2012 at 12:45:43PM +0100, Srdjan Todorovic wrote:
On 17 June 2012 12:23, Chris Green cl@isbd.net wrote:
requests it and the client fills in the form. ??The trouble is that there's no direct way for the PHP script that created the form to get the result - at least there isn't in any of the environment/frameworks that I've used.
Back in the day when everyone generally thought PHP was a good language to do web development in, I played about a little with PHP.
A very dirty, hacky, nasty way to do this is to call the same php script, with your <form> having a hidden input field. The PHP script checks it and does different things depending on the value. As I said, very nasty.
The idea isn't wrong, as long as the hidden input field is used as a session key. But by today's standards, any sane web application environment should come with a reasonable session facility, so application programmers shouldn't re-invent that.
Generating the session key isn't too difficult, but getting the server side logic right (timeouts, reasonable defences against session hijacking etc.) is a quite considerable amount of work that should be left to container designers / developers.
What happens is that there is *another* script which gets run (server side) when the client submits the form duly filled in. ??This other script has no direct connection with the script that created the form, no common environment, nothing.
Would something like a session key help? (I have no idea) Script 1 generates a session key, creates a bunch of settings from the form, saves to DB or somewhere, calls script 2 with same session key. Script 2 grabs data relating to session key and carries on.
I can't help but think that's not secure: malicious agent could try to determine or brute force session keys until a valid one is selected, at which point whatever action that session key relates to, would get executed (again). Maybe there's some potential for information leakage? Who knows. Not touched PHP for 10 years.
When processing a session key, the server can check whether the request comes from the host that it has sent the key to in the first place. Using HTTPS provides further protection.
I bet I will get laughed at by everyone else, since my suggestion must be so silly.
Not really -- the idea of using sessions to overcome limitations of HTTP statelessness is entirely reasonable. Implementation practices of contemporary web containers are a bit more refined in some aspects, though, e.g. session data normally is kept in some server process rather than stored in a database.
Best regards, Jan
On 17/06/12 12:45, Srdjan Todorovic wrote:
On 17 June 2012 12:23, Chris Greencl@isbd.net wrote:
requests it and the client fills in the form. The trouble is that there's no direct way for the PHP script that created the form to get the result - at least there isn't in any of the environment/frameworks that I've used.
Back in the day when everyone generally thought PHP was a good language to do web development in, I played about a little with PHP.
A very dirty, hacky, nasty way to do this is to call the same php script, with your<form> having a hidden input field. The PHP script checks it and does different things depending on the value. As I said, very nasty.
I agree with Srdjan, can be very dirty and nasty. Not least by the fact the user can tweak the data while it's at their end. The main problem is, as I think you pointed out, there is no easy way of passing data from the form sent out, to the page that processes the result. Indeed the result may not even be processed on the same server as the one that prepared it.
If there is only a small amount of data then the hidden field will probably do, even if it is dirty, but if there is a lot of data that needs to be passed about then I would suggest using the old mainframe method of writing it all to a database record before you send the form perhaps with the key to that record sent in a hidden field or use session data to store the key. Then when the post data comes back you can recover all of the data stored in the database in the processing page. Obviously you now have a database overhead so you need to decide if it's worth it or not.
All of the large system database systems I've worked on do this write and read automatically by having it built into the screen skeleton processing or in the operating system itself.
Nev
On 17/06/12 22:28, nev young wrote:
On 17/06/12 12:45, Srdjan Todorovic wrote:
On 17 June 2012 12:23, Chris Greencl@isbd.net wrote:
requests it and the client fills in the form. The trouble is that there's no direct way for the PHP script that created the form to get the result - at least there isn't in any of the environment/frameworks that I've used.
Back in the day when everyone generally thought PHP was a good language to do web development in, I played about a little with PHP.
I agree with Srdjan, can be very dirty and nasty. Not least by the fact the user can tweak the data while it's at their end.
I agree with you both about the method, but don't understand why it's "very dirty and nasty". Of-course you can use (or build) a framework around it but no matter what language you're working with, fundamentally this is the nature of web programming over http. It's not that unusual generally in server/client programming in fact; the client generally asks the questions, the server answers them. So when you want the server to ask a question it has to be done in the form of answering a question with another question, and hoping that the next "question" includes the answer somehow.
Maybe an example of what Chris is tying to do would help. But in a simple case such as editing an item in a database (and without using any frameworks etc) I don't see the problem with having a script called "edititem.php" that first looks to see if there is data in $_POST (in which case process it), otherwise displays a form. Indeed, given that part of the job of the script will be to validate the data in $_POST, doing it this way means that if the data isn't valid you just go on to display the form again anyway, probably pre-filled with the form data from last time and adding in error messages.
Mark
On Mon, Jun 18, 2012 at 10:31:31AM +0100, Mark Rogers wrote:
Maybe an example of what Chris is tying to do would help. But in a simple case such as editing an item in a database (and without using any frameworks etc) I don't see the problem with having a script called "edititem.php" that first looks to see if there is data in $_POST (in which case process it), otherwise displays a form. Indeed, given that part of the job of the script will be to validate the data in $_POST, doing it this way means that if the data isn't valid you just go on to display the form again anyway, probably pre-filled with the form data from last time and adding in error messages.
Yes, I think you're right, this is probably the easiest way to do it.
What I'm currently trying to do is, as you say, adding/editing data to a database. However the database is irrelevant really as the sequence is something like:-
Get data out of database Show it somehow Ask user to add to or edit it Get user's data Put data back into database
It's the bits *between* getting the data out of the database and putting it back that I'm finding difficult/clumsy.
So a simpler sequence that simply asks for a response to a question and acts accordingly has the same communication problem:-
Ask user's favourite colour Get favourite colour Set text on page to favourite colour
It's quite complicated to do this from a web application:-
Code creates page with question about colour on it (in my case it's a Wiki page with a PHP plugin called to create the form).
User asks for the page from their browser which runs the Wiki code to create the page including my form plugin which creates the form.
When the user submits the form the form's action is run, this redisplays the page with the new colour (or if it's really clever just changes the colour without full redisplay).
So, by default, the code that 'asked the question' has no simple/natural way to get the user's answer. The form action function has to do something which the 'calling' code can see somehow.
I realise *why* this is so, the process/thread that sent the page has probably long gone by the time there is an answer sent back. However it does seem strange that there don't seem to be any frameworks for handling this in a more natural fashion.
E.g. it should be possible to have a high-level/parent process that both serves the pages (my Wiki software - called by apache) *and* collects the reply when the user sends it back such that one can run a conceptually single-threaded process to both ask the question and handle the reply with some sort of common environment etc.
As it is it's messy. My PHP plugin code doesn't really lend itself to being run as the form action because it depends on quite a lot of the environment etc. provided by the wiki generation, it can't easily be run stand-alone. Thus the form action has to be a separate stand-alone script of some sort that reloads the wiki page with some sort of parameter/data indicating the user's reply.
On 18 June 2012 12:16, Chris Green cl@isbd.net wrote:
So a simpler sequence that simply asks for a response to a question and acts accordingly has the same communication problem:-
Ask user's favourite colour Get favourite colour Set text on page to favourite colour
It's quite complicated to do this from a web application:-
Code creates page with question about colour on it (in my case it's a Wiki page with a PHP plugin called to create the form).
I think this model is probably complicating matters. As someone else suggested (I forget who), it's often easiest to handle the question and the processing of the answer in the same file. So conceptually, it might look like the following. It's no particular language, but hopefully it helps clear things up. I'm assuming you've got some sort of server side session indicating which user is present.
<% IF Form["FavColour"] is present THEN // They've submitted a colour, so use it FavColour = Form["FavColour"] IF FavColour is valid THEN // save it, and send the user elsewhere UPDATE table SET colour=FavColour WHERE user=Session.userId Redirect("Somewhere") Exit ELSE ErrorMessage = "Sorry, that colour is invalid" END IF ELSE // We don't know the users colour, so fetch it from the database SELECT colour FROM table INTO FavColour WHERE user=Session.userId END IF %>
<form action="THISPAGE"> What's your favourite colour? <input type="text" name="FavColour" text="<%=HTMLEncode(FavColour)%>"> <% If ErrorMesage <> "" Then %> <%=HTMLEncode(ErrorMessage )% <% End If %> <input type="submit" name="Save" </form>
E.g. it should be possible to have a high-level/parent process that both serves the pages (my Wiki software - called by apache) *and* collects the reply when the user sends it back such that one can run a conceptually single-threaded process to both ask the question and handle the reply with some sort of common environment etc.
You could do this, but it's not conceptually how the WWW works. It was designed originally to be stateless (which makes it more scaleable), and the model you suggest isn't. Now, state has since been introduced, typically by using cookies or URLs to store a session id, but that's a different solution.
Greg
On Mon, Jun 18, 2012 at 12:54:20PM +0100, Greg Thomas wrote:
On 18 June 2012 12:16, Chris Green cl@isbd.net wrote:
So a simpler sequence that simply asks for a response to a question and acts accordingly has the same communication problem:-
Ask user's favourite colour Get favourite colour Set text on page to favourite colour
It's quite complicated to do this from a web application:-
Code creates page with question about colour on it (in my case it's a Wiki page with a PHP plugin called to create the form).
I think this model is probably complicating matters. As someone else suggested (I forget who), it's often easiest to handle the question and the processing of the answer in the same file.
Exactly what I'd love to be able to do but I don't think I can in any of the programming (Wiki etc.) environments I'm using.
So conceptually, it
might look like the following. It's no particular language, but hopefully it helps clear things up. I'm assuming you've got some sort of server side session indicating which user is present.
<% IF Form["FavColour"] is present THEN // They've submitted a colour, so use it FavColour = Form["FavColour"] IF FavColour is valid THEN // save it, and send the user elsewhere UPDATE table SET colour=FavColour WHERE user=Session.userId Redirect("Somewhere") Exit ELSE ErrorMessage = "Sorry, that colour is invalid" END IF ELSE // We don't know the users colour, so fetch it from the database SELECT colour FROM table INTO FavColour WHERE user=Session.userId END IF %>
<form action="THISPAGE"> What's your favourite colour? <input type="text" name="FavColour" text="<%=HTMLEncode(FavColour)%>"> <% If ErrorMesage <> "" Then %> <%=HTMLEncode(ErrorMessage )% <% End If %> <input type="submit" name="Save" </form>
As you say "It's no particular language" but in reality what language and environment can you *actually* do this? It would be possible with a stand-alone page created using PHP I suppose but in the real world this doesn't integrate well into other applications.
E.g. it should be possible to have a high-level/parent process that both serves the pages (my Wiki software - called by apache) *and* collects the reply when the user sends it back such that one can run a conceptually single-threaded process to both ask the question and handle the reply with some sort of common environment etc.
You could do this, but it's not conceptually how the WWW works. It was designed originally to be stateless (which makes it more scaleable), and the model you suggest isn't. Now, state has since been introduced, typically by using cookies or URLs to store a session id, but that's a different solution.
Quite!
On Monday, 18 June 2012, Chris Green wrote:
As you say "It's no particular language" but in reality what language and environment can you *actually* do this?
Which languages? I've personally done this sort of thing in DCL, Perl, VBScript, VB.NET, C#, PHP, Python and Java off the top of my head. But any modern language should do it.
It would be possible with a stand-alone page created using PHP I suppose but in the real world this doesn't integrate well into other applications.
Unless said application has an extension mechanism of some sort, then yes. However, if you want to fully integrate something in to a Wiki, an AJAX solution (if you don't mind mandating JavaScript) may help. But I'm afraid you'll be on an even steeper learning curve there - but AngularJS may be a good starting point.
Greg
On 18/06/12 12:16, Chris Green wrote:
E.g. it should be possible to have a high-level/parent process that both serves the pages (my Wiki software - called by apache) *and* collects the reply when the user sends it back such that one can run a conceptually single-threaded process to both ask the question and handle the reply with some sort of common environment etc.
I don't think it would be too hard to do something like this in principle. However, you have to remember that you have no control over how long it takes the user to "answer". It could be seconds, minutes, days, or they might never answer. Having a single thread "waiting" for that answer doesn't scale very well. So you could create a framework that helped you develop "apps" for "home use", but I don't think you could do it in a way that would work on a web server out there on the Internet - it would be too easy to bring it to its knees.
As it is it's messy. My PHP plugin code doesn't really lend itself to being run as the form action because it depends on quite a lot of the environment etc. provided by the wiki generation, it can't easily be run stand-alone. Thus the form action has to be a separate stand-alone script of some sort that reloads the wiki page with some sort of parameter/data indicating the user's reply.
I think this may be your problem here; the framework you are using (the wiki) is making this harder than it would otherwise have been.
You might want to look at AJAX approaches; that way your interaction between the server and client can be restricted to just the questions and answers. So to use your colour example: you get the page that asks the user for their favourite colour as you described. But the answer isn't submitted by the browser requesting a new page, instead it's done through Javascript and your code just has to send back the information required to update the page accordingly (whilst also storing it in the users preferences for future use). The "information required to update the page" would, in the simple case, be the content of whichever DIV needed updating.
Indeed, you could do a lot of the work you're trying to do client-side in JavaScript, and just submit the answers back when you have them all. That scales, because you're pushing the work to the client end so as the client count grows the system doesn't get any substantial increase in workload.
NB: When I talk about AJAX, I really mean pick a suitable Javascript library/framework (jQuery comes to mind) but do all the PHP interaction with it yourself. Because the responses from the PHP side will only be affecting the parts of the page you already control in your plugin, they no longer need to be Wiki "aware" in the same way that your plugin itself does.
Mark
On Mon, Jun 18, 2012 at 01:00:01PM +0100, Mark Rogers wrote:
On 18/06/12 12:16, Chris Green wrote:
E.g. it should be possible to have a high-level/parent process that both serves the pages (my Wiki software - called by apache) *and* collects the reply when the user sends it back such that one can run a conceptually single-threaded process to both ask the question and handle the reply with some sort of common environment etc.
I don't think it would be too hard to do something like this in principle. However, you have to remember that you have no control over how long it takes the user to "answer". It could be seconds, minutes, days, or they might never answer. Having a single thread "waiting" for that answer doesn't scale very well. So you could create a framework that helped you develop "apps" for "home use", but I don't think you could do it in a way that would work on a web server out there on the Internet - it would be too easy to bring it to its knees.
Yes, I think you have hit the nail on the head. Many/most of my applications of this sort of thing are for my own use (with maybe a few family members as well). I realise that for a web server handling hundreds/thousands of requests it's not a realistic approach.
As it is it's messy. My PHP plugin code doesn't really lend itself to being run as the form action because it depends on quite a lot of the environment etc. provided by the wiki generation, it can't easily be run stand-alone. Thus the form action has to be a separate stand-alone script of some sort that reloads the wiki page with some sort of parameter/data indicating the user's reply.
I think this may be your problem here; the framework you are using (the wiki) is making this harder than it would otherwise have been.
Yes, probably, but the Wiki allows me to create lots of useful web information quickly and easily. I've not found any other way of putting information up that's anywhere near as quick and efficient.
However there's nothing to stop me having a separate way of creating interactive (i.e. forms) pages withing the mostly Wiki hieararchy.
Indeed, you could do a lot of the work you're trying to do client-side in JavaScript, and just submit the answers back when you have them all. That scales, because you're pushing the work to the client end so as the client count grows the system doesn't get any substantial increase in workload.
NB: When I talk about AJAX, I really mean pick a suitable Javascript library/framework (jQuery comes to mind) but do all the PHP interaction with it yourself. Because the responses from the PHP side will only be affecting the parts of the page you already control in your plugin, they no longer need to be Wiki "aware" in the same way that your plugin itself does.
Yes, I have played a little with jQuery, I'll maybe do some more playing with it and see how I get on.
Thanks all.
On 18/06/12 14:21, Chris Green wrote:
Yes, probably, but the Wiki allows me to create lots of useful web information quickly and easily. I've not found any other way of putting information up that's anywhere near as quick and efficient.
Sorry, I wasn't suggesting that you should get rid of the wiki (although it could have been read that way): you'll have the same issues with most frameworks I am sure.
Yes, I have played a little with jQuery, I'll maybe do some more playing with it and see how I get on.
Well using your colour example, the way I see it: - You write an include file (that will either be included within your wiki plugin or from another script which will be called directly with POST data), which has a function that: -- checks for form data, and validates it then stores is -- uses the form data, or the previously stored value, or a default, to determine the "current" colour choice -- creates the HTML to show the current colour choice and a form for selecting a new one. - Your wiki plugin uses the above function to build the output - The form submits asynchronously via jQuery to a new script (outside the wiki logic). It includes the above script and uses it to update the database and create new HTML, returning that HTML for jQuery to update the current browser window without any redirects or screen refreshes.
All the work is done in one script, it's just included from two different places.
Can I suggest, KnockoutJS... as unless I've missed the point entirely, a MVVM framework would be perfect for your needs :)
On Mon, Jun 18, 2012 at 03:44:07PM +0100, Alex Scotton wrote:
Can I suggest, KnockoutJS... as unless I've missed the point entirely, a MVVM framework would be perfect for your needs :)
That makes the user interaction, input checking and so on easy but makes virtually no difference to the job of getting data back and forth to the the server side code.
They basically say use json but that's just a way of encoding blobs of data really, not a way of sending it.
One still has to fire off data from one server side process to the client side and get it back in a different, effectively unconnected, server side process.
On 18/06/12 16:30, Chris Green wrote:
They basically say use json but that's just a way of encoding blobs of data really, not a way of sending it.
Indeed, but PHP can interpret the data and writing it to a database should be straightforward enough. The point is that the question/answer stuff has been shifted client-side and given you the stateful environment you were looking for.
One still has to fire off data from one server side process to the client side and get it back in a different, effectively unconnected, server side process.
Unconnected, but without any need to be connected, any more than your connection to (eg) MySQL is. The client side is basically just saying "store this" and "retrieve this" much as you do with MySQL (indeed your PHP scripts will probably be little more than wrappers around mysql commands). And they don't need to play ball with your wiki environment, they won't need to know anything about it.
Basically you get the environment you wanted (albeit in Javascript not PHP), and the http stuff is just there to serve your application to your browser and act as an intermediary for your connection to the database. At the "application" level you can do the "what's your favourite colour", wait for response, handle response logic, and only synchronise back to the database via "the web" as necessary.
I've not looked at Knockout before but I've just run through their sample code and I think it deserves a proper play....
Mark
Make the form submit via a post and then you can split the logic in the code so that a GET request renders the form and the POST request deals with the data submitted.
On Sun, 17 Jun 2012, Chris Green wrote:
Every time I try and do some web application programming that involves forms (i.e. getting data from a user) it ends up being far more complicated than I expect (and more complicated than it should be I feel).
About fifteen years ago, I wrote a Java applet for obtaining and using form input from users of a web page. I no longer have the source code, but it seemed fairly painless, even though I was just learning Java (IIRC, from the relevant O'Reilly book) at the time.
About fifteen years ago, I wrote a Java applet for obtaining and using form input from users of a web page. I no longer have the source code, but it seemed fairly painless, even though I was just learning Java (IIRC, from the relevant O'Reilly book) at the time.
Sounds like you need a MVVM model.. Checkout knockout.js (http://knockoutjs.com/) -- Alex Scotton mob: 07950 524744 home: 01603 768361
Web Design | Graphic Design | MySQL Design and Optimization | SEO, advertising and Marketing Services | Computer Repairs | Network, Active Directory and Streaming Services | NLB and Bandwidth Shaping