Blog Posts

Cgiapp 1.5.2 released

At work, we've been developing a new platform for our website, based entirely on Cgiapp. This week we released the first stage of it: and These should stand as good testament to Cgiapp's robustness!

With all that development, and also with some communication from other Cgiapp users, I've made some changes to Cgiapp, and release version 1.5.2 this evening.

1.5.2 is mainly security and bugfixes. Error handling was somewhat broken in 1.5.1 — it wouldn't restore the original error handler gracefully. This is now corrected. Additionally, I've made run() use the array returned by query() — consisting of the $_GET and $_POST arrays — in determining the run mode. Finally, I've modified the behaviour of how run() determines the current run mode: if the mode parameter is a method or function name, it cannot be a Cgiapp method or a PHP internal function. This allows more flexibility on the part of the programmer in determining the mode param — words like 'run' and 'do' can now be used without causing massive problems (using 'run' would cause a race condition in the past).

As usual, Cgiapp is available in the downloads area. Grab your tarball today!

Continue reading...

Dreamweaver, Text Editors, and Webmasters

I picked up on this article on Friday, glanced through it and moved on, but noticed this evening it had been slashdotted — at which point I realized the author is the current CGI::Application maintainer, so I looked again.

At my first glance through it, it appeared the author was looking for a nice, easy-to-use pre-processor script for generating a site out of templates and content files. To that end, he, in the end, recommended ttree, part of the Template Toolkit distribution.

However, the real gist of the article — something that should probably have been summarized at the end — is that the author was looking for a free and OSS replacement for DreamWeaver's Templates functionality. This functionality allows a developer to create a template with placeholders for content, lock it, and then create pages that have the bits and pieces of content. Finally, the developer compiles the site — creating final HTML pages out of the content merged with the templates.

Now, I can see something like this being useful. I've used webmake for a couple of projects, and, obviously, utilize PHP in many places as a templating language. However, several comments on Slashdot also gave some pause. The tone of these comments was to the effect of, "real developers shouldn't use DW; they should understand HTML and code it directly." Part of me felt this was elitist — the web is such an egalitarian medium that there should be few barriers to entry. However, the webmaster in me — the professional who gets paid each pay period and makes a living off the web — also agreed with this substantially.

I've worked — both professionally and as a freelancer — with individuals who use and rely on DW. The problem I see with the tool and others of its breed is precisely their empowerment of people. Let me explain.

I really do feel anybody should be able to have a presence on the 'net. However, HTML is a fragile language: trivial errors can cause tremendous changes in how a page is rendered — and even crash browsers on occasion. The problem I see is that DW and other GUI webpage applications create, from my viewpoint, garbage HTML. I cannot tell you how many pages generated by these applications that I've had to clean up and reformat. They spuriously add tags, often around empty content, that are simply unnecessary.

The problem is compounded when individuals have neither time nor inclination to learn HTML, but continue using the tool to create pages. They get a false sense of accomplishment — that can be quickly followed by a very real sense of incompetence when the page inexplicably breaks due to an edit they've made — especially when the content is part of a larger framework that includes other files. Of course, as a web professional, I get paid to fix such mistakes. But I feel that this does everybody a disservice — the individual/company has basically paid twice for the presentation of content — once to the person generating it, a second time to me to fix the errors.

This is a big part of the reason why I've been leaning more and more heavily on database-driven web applications. Content then goes into the database, and contains minimal — if any — markup. It is then injected into templates, which go through a formal review process, as well as through the W3C validators, to prevent display problems. This puts everybody in a position of strength: the editor generating content, the designer creating the look-and-feel, and the programmer developing the methods for mapping content with the templates.

There's still a part of me that struggles with what I perceive as an elitist position. However, there's another part of me that has struggled heavily with the multitasking demands made on all web professionals — we're expected to be editors, graphic designers, programmers, and more. In most cases, we're lucky if we're strong in one or two such areas, much less passionate about staying abreast of the changing face of our medium.

Continue reading...

Happy New Year!

It's about 50 minutes shy of 2005 here, and Maeve has finally succumbed to sleep, I'm almost done with my stout, and we're in West Bolton without TV for the second year running (yay!).

I hope the new year brings peace and happiness to one and all! Happy coding!

Continue reading...

Smarty $_SERVER vars

I don't know why I never bothered to look this up, but I didn't. One thing I typically do in my parent Cgiapp classes is to pass $_SERVER['SCRIPT_NAME'] to the template. I just found out — through the pear-general newsgroup — that this is unnecessary: use $smarty.server.KEY_NAME to access any $_SERVER vars your template might need.

Continue reading...

Sign of a Geek

It's now been confirmed: I'm a geek.

Okay, so that probably comes as no shocker to those of you who know me, but it's the little things that make me realize it myself.

I've been frequenting Perl Monks for a couple of years now, mainly to garner ideas and code to help me with my personal or work projects. I rarely post comments, and I've only once submitted a question to the site. However, I do frequent the site regularly, and the few comments I've put in — generally regarding usage of CGI::Application — have been typically well-moderated.

Well, yesterday I made a comment to a user asking about editors to use with perl. I was incensed by a remark he made about VIM not having the features he needed. Now, as I said in my comment, I've used VIM on a daily basis for over two years, and I'm still discovering new features — and I've used all of the features he was looking for.

This is where I discovered I'm a geek: my comment made it into the Daily Best for today, peaking around number 5. The fact that that made my day indicates to me that I must be a geek.

Oh — and VIM rules!

Continue reading...

Cgiapp mentioned in php|architect!

A new Cgiapp user reported they had stumbled across the project in php|architect! It's in the current, October 2004 issue, in the News section, prominently displayed in the upper right corner of the page. The announcement blurb is straight from my freshmeat project page for version 1.4. Cgiapp is carving a name for itself!

Continue reading...

Cgiapp 1.5.1 released

At work this week, I discovered a bug with how I was calling set_error_handler() in Cgiapp's run() method. Evidently passing a reference in a PHP callback causes issues! So, I corrected that.

I also made a minor, one-character change to query() to make it explicitly return a reference to the $_CGIAPP_REQUEST property array.

You can see full details at the Cgiapp download page.

Continue reading...

Cgiapp 1.5 released

Cgiapp 1.5 has been released; you may now download it.

This release fixes a subtle bug I hadn't encountered before; namely, when a method name or function name is passed as an argument to mode_param(), run() was receiving the requested run mode… and then attempting to process that as the mode param. The behaviour is now fixed, and is actually simpler than the previous (non-working) behaviour.

Also, on reading Chris Shiflet's paper on PHP security, I decided to reinstate the query() method. I had been using $_REQUEST to check for a run mode parameter; because this combines the $_GET, $_POST, and $_COOKIE arrays, it's considered a bit of a security risk. query() now creates a combined array of $_GET and $_POST variable ($_POST taking precedence over $_GET) and stores them in the property $_CGIAPP_REQUEST; it returns a reference to that property. run() uses that property to determine the run mode now.


Continue reading...

When array_key_exists just doesn't work

I've been playing with parameter testing in my various Cgiapp classes, and one test that seemed pretty slick was the following:

if (!array_key_exists('some_string', $_REQUEST)) {
    // some error

Seems pretty straight-forward: $_REQUEST is an associative array, and I want to test for the existence of a key in it. Sure, I could use isset(), but it seemed… ugly, and verbose, and a waste of keystrokes, particularly when I'm using the param() method:

if (!isset($_REQUEST[$this->param('some_param')])) {
    // some error

However, I ran into a pitfall: when it comes to array_key_exists(), $_REQUEST isn't exactly an array. I think what's going on is that $_REQUEST is actually a superset of several other arrays — $_POST, $_GET, and $_COOKIE — and isset() has some logic to descend amongst the various keys, while array_key_exists() can only work on a single level.

Whatever the explanation, I ended up reverting a bunch of code. :-(

Continue reading...

MySQL Miscellanae

Inspired by a Slashdot book review of High Performance MySQL.

I've often suspected that I'm not a SQL guru… little things like being self taught and having virtually no resources for learning it. This has been confirmed to a large degree at work, where our DBA has taught me many tricks about databases: indexing, when to use DISTINCT, how and when to do JOINs, and the magic of TEMPORARY TABLEs. I now feel fairly competent, though far from being an expert — I certainly don't know much about how to tune a server for MySQL, or tuning MySQL for performance.

Last year around this time, we needed to replace our MySQL server, and I got handed the job of getting the data from the old one onto the new. At the time, I looked into replication, and from there discovered about binary copies of a data store. I started using this as a way to backup data, instead of periodic mysqldumps.

One thing I've often wondered since: would replication be a good way to do backups? It seems like it would, but I haven't investigated. One post on the aforementioned Slashdot article addressed this, with the following summary:

  1. Set up replication
  2. Do a locked table backup on the slave

Concise and to the point. I only wish I had a spare server on which to implement it!

Continue reading...