| About InfoWorld : Advertise : Subscribe : Contact Us : Awards : Events : Store |
|
||||
|
||||
Server-side HTML hell LAST WEEK I weighed Python against Java and I hoped I would not rekindle the age-old Python vs. Java wars. This week I intended to introduce the topic of Python programming for Web applications. But I really can't do it justice unless I say a few words about an even touchier duo than Python vs. Java: Python vs. PHP, or Hypertext Pre-Processor.
The strength of PSP and PHP -- as well as other server-page approaches such as Java Server pages (JSP) and Active Server Pages (ASP) -- is that you can crank out HTML and program code at the same time. The weakness is that you can crank out HTML and program code at the same time. Good applications have three layers: presentation layer, data layer, and application logic layer. It's bad enough that people usually don't expend the effort to separate the data layer from the application layer when they write code. It's even worse when they have the presentation layer (HTML) tightly integrated with their program's logic. It usually leads to a mess that is difficult to maintain. And that is what I don't like about PSP or PHP. The difference between PHP and Python as languages is that it is more natural not to integrate HTML with Python. I'll get into more detail next week, but you can program Web applications in Python the same way you would program any other application in Python. This approach frees you from the kind of twisted HTML hell that PHP often encourages. And it usually leads to a more modular approach to building Web applications. Before you PHP fans begin to rant, allow me to point out that HTML hell is not a necessary consequence of using PHP. It is simply the usual result, at least based on the PHP code I've looked at, including but not limited to PHP-Nuke. If you are willing to put in the effort, you can write quite elegant code, even object-oriented code, using PHP. The problem is that it is so easy to integrate PHP with HTML that it is difficult to resist the temptation to crank out sloppy modules that work immediately. The important point to take away from this is that this weakness is tied to the server page model, not the language of PHP itself. In case you PHP fans are still not satisfied, not only do I admire the way PHP works, but my two Web sites www.varlinux.org and www.petreley.org are based on PHP-Nuke, which is written in (you got it) PHP. So I like it enough to use it, and I learned what little I know about PHP by refining these sites and adding features to the PHP-Nuke system. In fact, I'm about to show you how I used PHP to add a couple new features to PHP-Nuke. And the code takes as quick-and-dirty an approach as I'm advising you not to follow. But one of the first rules of doing anything is that quick-and-dirty isn't always something to be avoided. Whipping up PHP Consider this problem I wanted to solve for www.varlinux.org. Most of the article links in the table of contents for VarLinux.org point to items that are published on other sites. The title of each entry in my table of contents is linked to the off-site article. This makes it easy to jump right to the articles if they look interesting, since you don't have to scan the comments for a link as you might do with similar weblog sites. The problem is that PHP-Nuke only keeps track of the number of times someone looks at the comments associated with off-site articles. It doesn't count the number of times people click on the link and visit that off-site article. So rather than link directly to the off-site article, I tossed together a script that redirects the reader's browser to the off-site item. Before it does the redirection, it increments the counter for that article in the database. Now all the titles in the table of contents point to the redirect script instead of the off-site link. The redirection happens "behind the scenes" and runs in an instant so the user doesn't see any difference in the way the site behaves. But now I can find out which articles people are reading and which ones they aren't. Once I had the redirect script working, I tossed together a script that lists out all the titles, hit counters and dates of the most recent articles. This allows me to track the counter information that I am collecting with the redirect script. I didn't time myself, but it must have taken a maximum of about 15 minutes to put together both of these PHP scripts. PHP is that easy once you get used to it. Next week I'll talk about the Python-based alternatives to Python Server Pages and PHP. Python is harder to use in this way than PHP, but the additional effort can really pay off. EXAMPLES: Here is a sample version of the redirect.php script. The database table field storyurl contains the full URL to the off-site article, and the field sid is the ID number for the article. <pre> $result = mysql_query("SELECT storyurl FROM stories WHERE sid=$op"); list($storyurl) = mysql_fetch_row($result); mysql_free_result($result); mysql_query("UPDATE stories SET counter=counter+1 where sid=$op"); Header("Location: $storyurl"); </pre> In order to use it, you must create a link for each article like the following: <pre> redirect.php?op=sid </pre> As I mentioned above, the variable sid is the story ID number for the article to which users will be redirected. Please note that this code will not work as is with PHP-Nuke. For one thing, PHP-Nuke does not store the URLs for off-site stories in the mySQL database, so you won't find the field storyurl anywhere in the PHP-Nuke code. This is one of the modifications I made to PHP-Nuke and the mySQL-based PHP-Nuke database. For another thing, the theme function themeindex that presents the links on the table of contents does not track the sid ID number by default. I added the code to pass this value to the function. Finally, here is the code I use to look at the article list to see which articles people are reading most: <pre> if ($admin) { include("header.php"); $result = mysql_query("SELECT time, counter, comments, title, sid FROM stories order by time DESC, counter DESC, title"); while(list($storydate, $storycounter, $comments, $storytitle, $sid) = mysql_fetch_row($result)) { echo "<TR>"; echo "<TD>$storydate</TD>"; echo"<TD align=right>$storycounter</TD>"; echo "<TD align=right>$comments</TD>"; echo"<TD> </TD>"; echo"<TD><ahref=article.php?sid=$sid>$storytitle</a></TD>n"; echo "</TR>"; } mysql_free_result($result); include("footer.php"); } else { Header("Location: index.php"); } </pre> This is one example of how you can integrate HTML with PHP code. The multiple lines of echo statements could have been merged into a single line, but I separate them out for readability. It isn't the only way, however. You can write plain HTML code in a PHP file and escape out of it to write occasional PHP code. In the above example, only the administrator gets to see this information. If anyone else tries to look at this file, they will be redirected to the table of contents (index.php). Note that the code includes table rows and data fields without first creating a table. That's because the table is initialized in the file header.php which is "included" in this code and executed first. Then the tables are closed and wrapped up in footer.php, which is included last. This is the kind of arrangement that can lead to HTML hell in your PHP code, and makes the code difficult to debug. If you want to look at my modified version of PHP-Nuke, you can download it from www.varlinux.org/download.php. Unfortunately, I cannot support this forked version, and I can't even guarantee you can start up a site with it, since I haven't modified all the installation details. But it may help you to have a look at the code, anyway. Resources: www.php4.org, www.python.org, java.sun.com, www.varlinux.org, www.petreley.org and www.phpnuke.org Nicholas Petreley is the founding editor of VarLinux.org ( www.varlinux.org ) and LinuxWorld. Reach him at nicholas@petreley.com. RELATED SUBJECTS Discuss this article in our online forums MORE > SPONSORED WHITE PAPERS
SPONSORED LINKS
|
|||||||||||||||||||||||||||||||||||||||||
|
||||||||||