Manuel Amador (Rudd-O) wrote:

> Just for argument's sake: the result is not identical.  Assume, for
> one second, that you have two PHP functions:
>
> function getCitiesAsHTML($countryName);
> function getCitiesAsXML($countryName);
>
> The first issues a snippet of HTML text, with <option>s.  The second
> issues a serialized XML document.
> The first one is engineered to be used with innerHTML.  The second one
> is engineered to be processed by the client so it can do any generic
> transformation.
>
> Which one do you think has the greatest potential for reusability in
> your JS client code?  Option 1 or Option 2?
>
> --------------------
>
> Okay, this is the end of the discussion for me.  You're stating a
> bunch of crap which does not correlate with modern accepted software
> quality practices.  You're conveniently ignoring that server-side
> errors and TCP connection errors are out there, and while they may be
> only 2% of all traffic, you need your JS application to work 100% of
> the time or give reasonable feedback as to why it cannot work.  You're
> grossly oversimplifying matters to prove your point, which flies right
> in the face of orderly, neat, structured, standards-based software
> development.

Manuel,

Your insults are not exactly convincing arguments for your case :).  If
you had even taken 1 second to investigate http://pear.php.net/HTML_AJAX
you would know that your arguments about TCP and server-side errors are
irrelevant.  Why?  I'll tell you why!

In fact, to make things easier, I will quote myself from previous
messages.  Consider this current email to be Message #4.  From Message #2:

"2) HTTP 500?

This should be handled internally by the ajax mechanism (HTML_AJAX does
handle this)"

To rephrase what I said above, HTML_AJAX handles server-side and TCP
connection errors.  I neglected to say exactly how it does so in the
message, perhaps that is the confusion.  Upon a timeout or other error,
a javascript alert() is used.  Upon a server-side error (a PHP error in
the server-side script), by default a javascript alert() is raised with
the contents of the PHP error complete with backtrace - very handy for
debugging.

So, that kills straw man argument number one, which I will quote again
for clarity: "You're conveniently ignoring that server-side errors and
TCP connection errors are out there, and while they may be only 2% of
all traffic..."

As we can see, this statement is untrue.  So, moving on:

HTML_AJAX is designed such that you register classes that simply return
regular old PHP values, and it then serializes them into JSON or any of
a number of choices (as I have said, let me quote myself from Message #1:

"I use http://pear.php.net/HTML_AJAX for the actual ajax details, and it
has several serialization options, JSON by default.")

The fact is, your example php functions miss the point by returning HTML
vs. XML.  The return value of my functions are *strings* which are then
serialized into JSON by HTML_AJAX.  If you need to do client-side
transformation, that's not a problem, as contrary to a previous post,
HTML inserted via assignment to innerHTML *is* accessible via DOM,
otherwise getElementById() wouldn't work on the <select>.  To prove
this, you can look in Firefox's DOM inspector.  After loading HTML
inserted via innerHTML, at first it will not show any changes, but by
closing the DOM inspector and re-opening it, it will refresh with the
current page value, and all of the new innerHTMLed HTML will show up.

Also, let's remember back to the original question from Daevid Vincent,
which was (and I quote):

"I need to dynamically update a select box with results from a SQL
database using AJAX, but I can't find a single example of how to do this."

A select box is not a need to do client-side manipulation.  It is a
select box.  Should you need to re-format the data in another format,
there are several options which all boil down to one of:

1) re-factor so that you don't need to re-format on the client side (my
personal favorite)
2) return another format such as an array and manipulate the data on the
client-side

However, it is not useful to talk about some generic time down the road
- what is important is to design your application so that it is easy to
change it.  If you have a whole bunch of complicated client-side logic,
this makes it more difficult to re-factor.  After all, only one of two
things are certain in programming:

You *will* have to refactor that code in the future, or you will quit. 
Whichever comes first.

So, straw man argument #2: "You're grossly oversimplifying matters to
prove your point, which flies right in the face of orderly, neat,
structured, standards-based software development."

is simply insulting :).  I was posting *actual* javascript code from a
well-working application with only the function names changed.  Want the
original code as written?  Here you go:

var addressesCallback = {
    searchAddressesGetHTMLOptions: function(res) {
       document.getElementById('existingaddresses').innerHTML = res;
    }
};

function searchAddresses(text, id)
{
    if (text.length < 3) {
       return;
    }
    var c = new addresses(addressesCallback);
    c.searchAddressesGetHTMLOptions(text, id);
}

and the PHP code that does this (this one is trimmed because it's got
lots of $adrinfo stuff to make the actual addresses and other database
junk):

<?php
require_once 'HTML/AJAX/Server.php';
class addresses
{
    function searchAddressesGetHTMLOptions($fragment, $id)
    {
       // first, do a query using LIKE to grab addresses from the
$fragment which I trimmed
       $options = '';
       // you may want to use a db-independent tool like PDO, but I know
for a fact
       // that this site will never use anything other than mysql for
speed reasons
       while ($adrinfo = mysqli_fetch_assoc($res)) {
          $address = $adrinfo['Line1'] //etc;
          $options .= ' <option value="' . $adrinfo['AddressID'] . '">'
. htmlspecialchars($address) . '</option>';
       }
       return '<select id="addressesdropdown" size="5">' .
          $options . '</select>';
    }
}

class ChiaraServer extends HTML_AJAX_Server
{
    function initAddresses()
    {
       $this->registerClass(new addresses());
    }
}
$server = new ChiaraServer;
$server->handleRequest();
?>

It is worth noting that I also added the central HTML_AJAX_Server code,
which is in a separate file.  There are many "init*" methods in the
actual code, each of which allows on-demand initialization of classes
for faster startup but that is also irrelevant to the task at hand.

You might note that the actual code that creates the <select> is 3 lines
long, 1 for address formatting, 1 for option creation, and 1 for the
actual select tag.  This in turn is serialized into JSON by
HTML_AJAX_Server and then deserialized into a String object which is
passed (res) to the callback searchAddressesGetHTMLOptions, which in
turn sets the innerHTML of the <div> that should contain the <select>.

You may be wondering how to unit-test this code.  For the javascript
unit testing, there are several options, including Selenium at
http://openqa.org/selenium-ide/.  HTML_AJAX has its own custom unit
tests built in using a mock object for the XMLHttpRequest object, you
could examine that to see how it handles TCP errors and PHP server-side
errors, among other things.

Unit-testing the PHP code would involve instantiating an address object,
and passing input to searchAddressesGetHTMLOptions, and comparing the
string output.  This can be done easily with PHPUnit2, SimpleTest, .phpt
testing, or any number of options (Chris might jump in here to mention
ApacheTest ;).

My point?  This is a real-world example of how to solve the problem of
generating a select using AJAX that is fast, easy to maintain, and easy
to modify.  It's not about complexity vs. simplicity or modern accepted
software quality practices vs. a bunch of crap.  It's about good
programming.

I know complexity, I wrote phpDocumentor 1.3 (http://www.phpdoc.org) and
PEAR 1.4 (http://pear.php.net/PEAR).  I also know how difficult it is to
manage complexity effectively, and PHP/javascript is a fantastic tool
for solving your problems, but only if you don't shoot yourself in the
foot before you even begin.

Greg

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to