Gerrymandered Code: Extending Zend_Registry to globalize session vars

In my most recent post I talked about putting my toes in the Zend Framework water with stand-alone usage of Zend_Cache. This has been a great experience, and since writing the post I’ve been updating my main application with more caching anywhere I can see a benefit.

In the past couple of days I waded a little deeper into ZF, installing Zend_Registry (also stand-alone) and using it to globalize configuration variables that I was previously loading into $_SESSION in order to access throughout my scripts and inside classes without having to pass them explicitly.

I’ve been using $_SESSION like this for a couple of years, and I’ve known the whole time it was a band-aid approach to solve the problem. Such an approach is not an ideal “design pattern.” Though it passes my baseline rule–it works–there are downsides. The two most obvious are that 1) there’s nothing to stop me from accidentally overwriting a session var inside some script or method, and 2) there’s no sense loading up the session handler with stuff that really shouldn’t be in there.

Zend_Registry is a very lightweight module (one file), that is actually an extension to the native ArrayObject PHP5 class. Any variable, object, or scalar you load into Zend_Registry instantly becomes available globally throughout your script. Let me prevent confusion by saying there is no persistence across page loads–this is just for within each request–but the upside is any scope issues are swept away in a very elegant manner. Hint: Combine Zend_Registry with Zend_Cache to achieve persistence.

The Registry design pattern is not unique to ZF, you can even write your own Registry class if you care to.  I’m still not fluent in OOP-speak, but I understand Zend_Registry is implemented by default as a Singleton.  I know there’s a lot of trashing of the Singleton pattern out there in programmer land.  However, I don’t get too hung up on such metaphysical debates…not to say there isn’t merit in the argument, but for me and my work it is not a practical concern.

I refactoring my main app with Zend_Registry in place of my rat’s nest of $_SESSION[‘config’][‘foo’] and such…which is mostly just things like email addresses for the system admin (me) and other global variables that may come in handy in any script or method.

As with my previous ZF article, I’ll leave the details to the fine folks at Zend (see Zend_Registry documentation here), but the implementation of Zend_Registry in this fashion can be exactly this simple:

Zend_Registry::set('admin_email', 'chris.renner@company.net ' );

And then later in your script (or function or object method or wherever) you return the value by calling:

Zend_Registry::get('admin_email' );

Wow, how elegant! You can also access the registry as an object or as an array. For my needs, the static setter/getter methods are perfect.

Netbeans’ Find and Replace features made it relatively simple to update my code with the new Zend_Registry calls.  I guess the “web developer” jargon for that would be “I refactored my code base.”

Problem solved, right?  Well yes and no.  The pesky need for globalized config vars has been solved, but there is a related problem.  How did I ever get the idea to store config variables in $_SESSION?  Probably the same way most of you reading this did in your newbie days:  I was already using $_SESSION to store actual, legitimate session variables at user login, and then access those variables through my code.

gerrymanderIn addition to being a code jockey, I am a politics junkee and also the owner of a second major in Political Science (I know, its so rare to find someone working in a field that is wholly unrelated to their degree…).  It occurred to me there is an analogy to be made between a  Gerrymandered congressional district and what the pros call “spaghetti code.”  I think my amateur-ish use of $_SESSION as a global band-aid amounts to what one might call “Gerrymandered code.”  I am hereby coining the phrase!

The obvious solution to replace all the $_SESSION tags littered throughout my code is to simply load $_SESSION into Zend Registry like so:

Zend_Registry::set('session', $_SESSION);

This works, but retrieving session vars proves to be a bit clunky. My reading of the ZF documentation suggests there isn’t a way to access the value of an array element in the Registry in a direct fashion. You therefore have to instantiate Zend_Registry every time you need access to a session var. For example…

$registry = new Zend_Registry();
echo $registry['session']['userID'];

I find this a bit clunky to do every time I need to access my session. I also don’t care for all the extra overhead caused by generating an object for each one of these cases.

My solution was to extend Zend_Registry with another class that can access an array element inside the registry and return it directly. Here’s what I came up with:

/**
 * A simple extension to Zend_Registry to allow direct access to array objects
 * and object properties inside the registry
 * @author Chris Renner http://www.chrisrenner.com
 */
class App_Registry extends Zend_Registry {
 
    /**
     * Constructs a parent Zend_Registry with default
     * ARRAY_AS_PROPS to allow access as an object
     *
     * @param array $array data array
     * @param integer $flags ArrayObject flags
     */
    public function __construct($array = array(), $flags = parent::ARRAY_AS_PROPS) {
        parent::__construct($array, $flags);
    }
 
    /**
     * getter method for directly accessing value of an array element stored in a registry index
     *
     * @param string $index - the array we're accessing
     * @param string $key - the element we want to access
     * @return mixed
     */
    public static function getFromArray($index, $key) {
 
        $array = self::get($index);
 
        if(is_object($array)) {
            $var = $array->$key;
        } elseif(is_array($array)) {
            $var = $array[$key];
        }
 
        return $var;
    }
 
    /**
     * setter method for directly modifying value of an array element stored in a registry index
     *
     * @param string $index - the array we're accessing
     * @param string $key - the element we want to access
     * @param string $val - the value we want to assign
     * @return mixed
     */
    public static function setInArray($index, $key, $val) {
 
        $registry = self::getInstance();
 
        if(is_object($registry[$index])) {
            $registry[$index]->$key = $val;
        } elseif(is_array($registry[$index])) {
            $registry[$index][$key] = $val;
        }
 
    }
 
}

As you can see, there are just two methods. getFromArray returns the value of an array element or object property from the registry. You just need to supply the Zend_Registry index and the key/property name you want back.

setInArray is used to update an existing property or array element. Supply the Zend_Registry index, the property/key name, and the value you want to assign.

So now, if I want to get the userID from the session (We still set the session array into the registry using Zend_Registry::set() as above), I can call a new static method like this:

echo App_Registry::getFromArray('session', 'userID');

…and to change the value I simply call this:

App_Registry::setInArray('session', 'userID', $newValue);

Obviously this is a very rough class.  It could use more polish, like error handling in case we’re trying to access something that is neither an object or an array.  This can be used to access elements/properties for any array or object you might pass into the registry (not just session vars).

You might ask why not just use constants to globalize config vars?  You certainly could in a simple application.  If you want to change those vars in the script or store an array, you’re out of luck.

I’m curious to see what readers of this post might think, if you have suggestions for improvements or better ways of doing the same thing.  Thanks for reading!

Enhance performance with Zend_Cache

1/7/10 Update:  I submitted this post to Zend Developer Zone and they published it! Short Link: http://dz.zend.com/a/11582

So I finally took the Zend Framework plunge a few weeks ago.  No, I didn’t start building an application with the framework, but I did start investigating some of the ZF classes for stand-alone implementation in my existing projects.

The first ZF class to catch my eye was Zend_Cache, for its obvious performance implications.  The applications I develop and manage are very heavy with database transactions.  Hitting the db every time you need an object is a serious performance bottleneck, and on a shared environment can be troubling to other applications living in the same environment.

I’m going to describe my experiences with Zend_Cache here, but I am not going to bore you with lots of code detail and specifics. The above-linked reference page on the ZF site has more than adequate documentation.

Zend_Cache is incredibly flexible, and allows you to use any one of a number of back end caching methods…i.e. the place you want to store your cached data.  Each of these methods is implemented with an adapter class.  Your choices include file-based caching, sqlite, APC, memcached, Xcache, and ZendPlatform.  There are additional adapters to permit caching in two different methods (TwoLevels) and for methods specific to Zend Server.

The enterprise-shared hosting environment my apps live on includes APC, so I went with that adapter.  My dev environment runs Zend Server CE, which includes an APC-compatible Zend caching extension, so I enabled it through the Zend Server config pane.

There are also a few front end adapters to use, which operate the caching machinery.  Zend_Cache_Core is the base adapter and is, in Zend’s words, generic and flexible.  However, for more exotic solutions are available: File, Function, Output and File.

You can cache just about any kind of data that you can store in a variable:  intergers, strings, arrays, serialized stuff, and even objects.  Think about the possible implementations and their performance benefits for just a moment: Object persistence across sessions, recordset caching for speedier searches and paged results, I suppose one could even use this for an alternative session manager.

I already use a vastly simpler file-based caching method for storing serialized arrays for use in various select boxes that occurr frequently across my apps (e.g. “select your department” type stuff).  I may port these over to Zend_Cache later.  Instead, I have implemented Zend_Cache to store objects built from database queries. I am able to manipulate objects across multiple page requests and reduce database requests to only when the object is being modified and saved.

The implementation is extremely simple.  Let me demonstrate how to create a cached object. I will assume we already have an instance of the object we want to cache ($this), and I am not providing a complete class below (so don’t try to cut and paste the code literally).

// we need a method create a unique ID for the object
// this will be used to identify the cached object when created or when retrieving
// I would suggest using a hash that includes your db unique id
public function create_cache_id($id) {
    $cache_id = md5('myRecord_' . $id);
    return $cache_id;
}
 
// this method will retrieve the object
// $id should be unique id of your database record
public function fetch($id) {
 
    $cache_id = $this->create_cache_id($id);
 
    $frontendOptions = array(
        'lifetime' => 300 ,                 // cached object will expire after this many seconds
        /* this ROCKS because you don't spend time writing code to check if the cache is expired */
        'automatic_serialization' => true   // we'll need this on to store the object, also for an array
    );
 
    // note that for the APC adapter there are no back end options to configure
    // instantiate instance of Zend_Cache
 
    $cache = Zend_Cache::factory('Core', 'APC', $frontendOptions);
 
    if(!($obj = $cache->load($this->cache_id)) ) {
 
        /* if a cache with this ID doesn't exist, then execute your db query and build your object, then we'll add it to cache: */
 
        $this->myQuery($id); // this is just a generic method meant to represent your db transation
 
        $cache->save($this); // adds the object to cache
 
        echo 'this is not from cache'; // diagnostic, comment out later
 
    } else {
 
        /* if the cached object does exist, then we need to re-populate our object properties */
 
	// loop through each element of $obj and add as a property to $this
        foreach($obj as $key => $val) {
            $this->$key = $val;
        }
 
        echo 'this is from cache';  // diagnostic, comment out later
 
    }
 
}

I’ve grossly oversimplified the external parts of the process such as the parent object class and the db interactions, but this should still give you the idea. Any time you generate your object, you’ll automatically check the cache first before querying the database.

You’re also going to want a method to clear the cache if your object changes. For example, if your user edits a record using an input form, you’re going to want to update the db and the cache. Rather than immediately re-loading the object into cache, I prefer to simply clear it out of cache and wait for the next fetch request to add back into cache. This way you don’t have a bunch of objects stored in cache that aren’t being used.

Anyway, the approach to clearing the cache is extremely simple. Let’s assume you already have a method for processing an update to a database record that underlies your object. To clear the old version of the object from cache, simply call a method like this:

public function clear_cached($id) {
 
       $cache_id = $this->create_cache_id($id);
       $cache = Zend_Cache::factory('Core', 'APC');
       $cache->remove($cache_id);
 
}

It is truly not much more complicated than the above examples, particularly if you already have an existing application structure you want to add Zend_Cache to. I’ve been pleased with my first experiments into Zend Framework and intend to explore some other components for use in my projects. Hopefully this tutorial will help someone else out there who’s been hesitant to buy into the framework craze.

UPDATE: Just thought I’d link to a couple of other great resources on Zend_Cache:

Zend Framework Hidden Gems: Zend_Cache (Zend Developer Zone)

Joey Rivera: Caching using PHP/Zend_Cache and MySQL

Brandon Savage: He knows what he’s talking about…

Via PHPdeveloper.org, I’ve been following Brandon Savage’s blog for a few months.  Most recently, he’s posted a pair of excellent articles on productive and useless micro-optimizations.  These are code “enhancements” such as “change all print() statements to echo statements because echo is faster”.  Brandon takes a look at several popular micro-enhancements and offers his professional opinion on whether they are truly worth your time or not.

I find Brandon’s knowledge of PHP a great resource, and his practical approach is appreciated and it is very evident he develops in the real world rather than in abstract-land. Many of his recent posts have been focused on the beginning php developer.  So if you are a newbie or an intermediate (I consider myself the latter), Brandon’s stuff is very much worth your time.

Fabien Potencier: PHP does need a template engine

Fabien Potencier’s latest blog post is yet another entry in the popular debate in the PHP community over templating. Recently, conventional wisdom has swung back to the use of PHP itself for templating, rather than one of the popular but resource intensive template engines like Smarty.

I discussed this myself here. At the time Brian Lozier wrote his article, his approach was probably in the minority. Other than the use of short tags, however, PHP for templating has seen a renaissance.

Fabien’s angle on this, however, is anti-popular sentiment. He argues that PHP is too verbose to be a good template language, its syntax is not concise enough for templating, and it lacks sufficient reusability in a template context. I find the first two of these positions pretty subjective, and you’ll find from the blog comments there are plenty of opposing opinions on this.

I posted my own comments over there, and re-print them here for your consideration. I think I made some valid points, but then again I have no perspective but my own, so I could be way off.

I’ve been templating directly with PHP for some time now using Brian Lozier’s. I’ve since ditched the short tags, but for me, working in a solo environment, I’d rather have simplicity (don’t have to learn a template engine syntax), control, and save the performance to spend later on things like actual application features.

Further, I’m not sure what all the heartburn over escaping variables in the template is about? IMO you should never be doing real work in the template anyway, any variables should be prepared in your controller class/script BEFORE being sent to the template. You’re violating your own rule of separation of concerns by doing that much PHP work in the template. Likewise, making a function call in the template would violate the same principle. I’ve yet to encounter anything in two large scale enterprise apps that I couldn’t template with PHP.

I also agree with the comments above that its not going to hurt the designer to learn a bit of PHP. Its really not that hard and it is a translatable skill. The en-vogue template engine of the day may or may not be in use in 5 years, but PHP will be.

I would argue that a very small percentage of total PHP developers are working in an environment where there is a separate templater that ONLY does the template work and has no knowledge of or role in application coding.

In the end, Fabien announces he’s built upon some prior work by another developer to create yet another “magic bullet” template language. I had to re-think the intent of the article in its entirety once I realized at least part of his motivation must be to encourage folks to try out his new template engine. I do not fault Fabien for this (we all want to promote and share our work), but it causes me to reach the conclusion that his critique of PHP for templating is perhaps not 100% impartial.

Update: Eli White has also posted a response to Fabien.

Update 2: Padriac Brady has now posted a rather brutal response to Fabien:

Fabien’s article triggered the urge once again to challenge the status quo, the continued view of something in PHP being necessary when in truth it simply isn’t. The article takes that view to extremes, going to some effort arguing against the recent slide towards templating with PHP with arguments which are so biased as to misinform readers. [trackback]

And, now Fabien has posted a follow up to his original post:

Before I try to answer some questions, I’d like to reinstate that I like PHP templates. And you should remember that symfony has only used plain old PHP templates since the beginning. As a matter of fact, I’m been advocating about using PHP templates since my first PHP project, and I have never used any other PHP template engines. So, I’m not against PHP templates; I just find that some PHP limitations as a template language are more and more irritating for me.

Basic AJAX with PHP and jQuery

I gave a live tutorial/demo at work today for room full of folks. I’ve posted the source code and powerpoint below. The title is pretty self explanatory…just a very simple demonstration of AJAX techniques using jQuery JavaScript and PHP on the server side in a very crude Twitter-like mini-posting app.

Basic AJAX with PHP and jQuery – Source Code

Powerpoint Presentation

The problem with Database Abstraction Layers…

Let me preface this post by saying I reserve the right to be entirely mistaken, and I invite comments with opposing opinions…hey, maybe I’ll learn something by mouthing off! I know I’m painting with very broad brush-strokes and I expect to be corrected where my statements may be overly generalized.

Now, as to the topic at hand:  The problem with DALs, PDOs, ORMs, data access objects, etc. (such as Propel) is that they are only “clean” solutions for relatively simple, single table queries and/or small result sets.

Larger databases will see huge hits on performance if you try to return only primary keys for a result set, and then loop through the keys, creating an object for each (thereby firing a query for each). For displaying result sets, a single query is vastly superior.

Further, the DAL pattern appears to break down when your query includes multiple joins and aliases. Properly normalized relational databases require joins in order to return relevant data about a record to the user, i.e. you don’t store the user’s full name in every sales order record, only the id reference to his record in the customer table. I’ve yet to see a DAL that can effectively deal with multiple joins and aliasing without asking the coder to write explicit SQL.

Let’s look at an example of a “simple” query to demonstrate the power of DALs.  Here’s the standard way to write a simple MySQL query with PHP.

$sql = "SELECT name FROM users WHERE id = '100' LIMIT 1 ";
 
$result = mysql_query($sql);
 
$row = mysql_fetch_object($result);
 
$name = $row->name;

Now, lets see how a theoretical DAL class might handle the same query:

$name = $db->Fetch_Var('users', 'name', 'id', '100');

Wow.  You can see what took us four lines of code before now takes only one.  The second example uses an actual method I’ve written for a simple DAL class I use at work.  If I can ever get permission from the licensing dept, I’ll share it here.

For retrieving a single result or even an entire row (or rows) from a single table, such DALs can be effective and incredible powerful. However, for large scale paged result sets requiring joins, etc, I find it is most efficient to write custom SQL. In my opinion, these DALs are wishful thinking if the goal is to remove the need for the PHP developer to be able to write effective SQL. These tools should, rather, be treated exactly as such. Each is a tool to speed your coding and abstract away routine query building. But for any complex application, you are never going to get fully away from writing your own SQL queries. And due to the nature of these DALs/ORMs, the only SQL queries left to write are always going to be the most complex.

Propel actually does manage to provide some support for joins. I do not like Propel’s reliance on the “*” wildcard in the linked example, but perhaps that is just for simplicity in the documentation. Good SQL explicity names the columns to retrieve, and except for in-development testing, you should rarely if ever use “*” …its lazy coding and wastes resources (see Rudy Limeback’s Simply SQL for a more detailed argument against “*”). I’d like to see Propel, or any other ORM/DAL class deal, however, with a query such as this:

SELECT SQL_CALC_FOUND_ROWS
          projects.id
          , faculty
          , author
          , author2
          , author3
          , date_created
          , users.last_name     as faculty_last
          , users.first_name    as faculty_first
          , users2.last_name    as author_last
          , users2.first_name    as author_first
          , dept.dept_name
          , project_title
          , project_type
          , staff_no
          , project_status
          , organization.org_name
          , project_date
FROM projects
LEFT OUTER JOIN users as faculty  ON projects.faculty = users.id
LEFT OUTER JOIN users as users2  ON projects.author = users2.id
LEFT OUTER JOIN dept ON projects.dept = dept.id
LEFT OUTER JOIN organization ON project.org = organization.id
LEFT OUTER JOIN staff ON project.staff_no = staff.id
WHERE (users.last_name LIKE '%smith%' OR users.first_name LIKE '%smith%')
AND project.title LIKE '%Material Composition of Unobtanium%'
ORDER BY Items.Entry_Date DESC 
LIMIT 0, 15

The above example is a sanitized (names anonymized to protect the innocent) version of a real query I use to return paginated results in one of our web apps. Some of the joins are included dynamically based on search criteria, others are always included. The WHERE clause is likewise generated dynamically, as well as the ORDER BY, which is used for column-based sorting.

Show me a DAL/ORM class that can deal with this example and I’ll be your best friend forever.

Let’s now look, for example, at Propel’s approach to a multi-join query, taken from the above link.

Here’s the standard SQL way:

SELECT * 
FROM author 
  INNER JOIN book ON book.author_id = author.id 
  INNER JOIN publisher ON publisher.id = book.publisher_id
WHERE publisher.name = 'Some Name'

Here’s the Propel way:

$c = new Criteria(AuthorPeer::DATABASE_NAME);
 
$c->addJoin(AuthorPeer::ID, BookPeer::AUTHOR_ID, Criteria::INNER_JOIN);
$c->addJoin(BookPeer::PUBLISHER_ID, PublisherPeer::ID, Criteria::INNER_JOIN);
 
$c->add(PublisherPeer::NAME, 'Some Name');
 
$authors = AuthorPeer::doSelect($c);

If you are absolutely hell bent on returning your result set as objects, then I suppose the Propel approach is appealing, but it is more code in the end and there is an unavoidable learning curve (though admittedly not that daunting) to writing it.

If you’re considering yourself a professional PHP application developer and not just a “coder” or “website designer”, rather than avoiding SQL at all costs, you should be learning how to write good SQL.  I’m not sure where we got the idea that we needed a more succinct way to write queries without using SQL, since Structured Query Language is already succinct by design.

This is much the same argument as voiced against the myraid template engines out there…why build a template engine with its own simple syntax when PHP already is essentially a template engine?  Further, a similar argument has been made by Rasmus Lerdorf (also here), the father of PHP, with respect to the proliferation of frameworks.

Rather than use these drawbacks as an excuse to reject DALs (and template engines and frameworks for that matter), I am merely suggesting that the professional PHP developer recognize the limitations of these tools, and to know when it is more efficient to bang out an SQL statement than trying to contort your code and DAL class to deal with very complex queries.

One caveat I’d like to insert here at the end is ADOdb, perhaps the most popular DAL for PHP. I’ve used ADOdb in the past and like it. Rather than trying to abstract away all your SQL worries, ADOdb deals with the differences in connections and the PHP query functions across different database types, so that instead of obsessing about “mysql_query($sql)” versus “oci_execute($sql)”, you focus only on your SQL. The advantage is that your apps become more portable/scalable across various relational db products.

Further reading:
Propel Object-Relational Mapping Framework
ADOdb Database Abstraction Layer
Wikipedia entry on Object-Relational Mapping

Samuel Folkes: 17 PHP Practices That Should Be Banished Forever

stop-150x150Samuel Folkes has posted a great article about bad PHP programming habits.  In his article, titled 17 PHP Practices That Should Be Banned Forever, Folkes describes 17 specific behaviors which can lead to bad code, security holes, or both.

Not all of the 17 items are PHP-specific. Not properly commenting your code is of course a problem in any programming language.  This is also one I am ashamed to say is a problem for me.  Particularly when you are a one-man shop and you don’t have anyone else working in or maintaining your code, commenting doesn’t seem that necessary.  Having said that, I have always commented complex sections of code for my own benefit.  I’ve gotten better at more generalized commenting lately, particularly with writing Doc Block comments in my classes.  However, I would like to think that most of my code–at least the more recent stuff–is well written and logical enough that it is fairly self-explanatory to an experienced developer.

Other notable bad PHP habits include reliance on the ubiquitous Register Globals, failure to sanitize user input, not closing database connections, overuse of error supression, and using functions inside loop declarations.

One habit Folkes describes hit home with me in a very direct way.  He suggests reliance on short PHP tags (<?, <?=) is a no-no, principally because not all hosts have short tags enabled in php.ini, and also that potential conflicts can come up when working with XML, since XML documents begin with <?xml, the PHP parser may try to parse the XML open tag.

These are both valid concerns, particularly so if you are working extensively with XML, and/or if you are developing code to be distributed widely to server environments you have no control over.

I use the <?= tag extensively, since becoming a convert to Brian Lozier’s PHP Templating Class.  Further, I develop in an enterprise environment, on a project which we do not intend to distribute, on a server where we (meaning the institution) do indeed control configuration.

I have developed a small number of XML documents generated from PHP scripts, but to this point my XML open tags have been encapsulated in strings (‘<?xml’) and would therefore never be parsed as PHP to begin with.  Perhaps due to my limited exposure to XML with PHP, I’ve not run into a scenario in which this compatibility problem would arise.

Finally, I’ve read recently on one site that short tags will be deprecated in PHP 6, then on another site I’ve read that <?= is about to make a comeback, since Zend Framework is pushing a Brian Lozier-esque PHP-as-template-engine approach.

We’ll see.  Until I see more obvious handwriting on the wall regarding short tags, I’m sticking to my current approach.  As for the rest of Folkes’ recommendations, they are well worth a read for any newbie or seasoned PHP developer.

How to get started creating PHP web applications

By some accounts there are at least 5 million PHP developers in the world, each with a different skill level. But how did we all become PHP developers? Almost every PHPer has an interesting background story, and it is worth your time to investigate the back-stories of other PHPers you meet.

So lets say you want to become a PHPer and don’t know where to start. I’m here to help! Read on…

The first thing I’ll say is this: if you are coming to web development from a completely different background, even a non-technical background, hooray for you. I’m in the same boat. I’ve always loved computers and technology but I’m currently in my first and only true tech job in my career, and I’m in my mid 30s. What I’ve found is that the experiences you’ve had before give you context in terms of business processes and how the world of work works. That’s not to say a career programmer can’t gain that knowledge, but I think its harder.

I’ve always said this: I can learn the programming..there’s books and web articles out the wazoo to do so. Interpersonal and oral/written communications skills, business process knowledge, and policy level awareness aren’t so easy to learn, particularly if you’ve never been in the trenches of an organization doing the actual work that a web app is built to support. A web developer spends a lot of time translating client wants into actionable tasks, and you can’t do that with an abstract knowledge of what you can do with code.

PHP can be as simple or complex as you want it to be. To learn the language, you’re going to need a text editor of some kind (something better than NotePad), a PHP-enabled web server somewhere, and some time. Everything else you can get for free on the web. Oh, you’ll need time, of course.

When I started writing PHP, I already knew the basics of HTML. This is an essential piece, because HTML is the presentation language that results from your PHP scripts. So, if you lack basic HTML, you need to go back and pick that up first. There’s a billion HTML tutorials on the web to help you out. Learning HTML doesn’t require a PHP server, so you can write HTML files on your own computer and open them in your browser to view your work.

If you work for an organization that already has web servers that are PHP enabled, then you just need to get access so that you can place your PHP script files on the server in order to run/test them. If you’re learning on your own, you’re going to want to “rent” some web space. The host I recommend most highly is Asmallorange.com, they have personal hosting plans as cheap as $25/year, which would be fine for a small PHP beginner site.

You’re also going to need a text editor, preferrably one with syntax highlighting so you can understand your code better. I coded for nearly a year with plain old Notepad, and let me tell you that tracking down mistakes is a nightmare without syntax highlighting.

overview_thumb

Trellian CodePad

There are several good free IDEs (integrated development evnvironment) out there, but the simplest for beginners is probably CodePad by Trellian. Once you get good, you’re going to want something with more features, like Zend Studio, NetBeans or Komodo, but for beginners, Codepad has all that you need. For Mac users, I really love Coda by Panic, but the lack of inline error checking keeps me from using it as my primary IDE.

The next thing you’re going to need are some tutorials. I highly recommend this PHP/MySQL tutorial at freewebmasterhelp.com. This is the same tutorial I got started with, and will give you a basic understanding of how to use PHP with a MySQL database to create, edit and delete records.

The other thing I would recommend are books. Get lots of books on programming, even if you rarely use them. They are excellent reference materials and I find myself referring back to them over and over again.

51pqjvc7p5l_sl75_

Beginning PHP & MySQL

The best beginner’s PHP guide I found, and the one that helped launch my still-new career, is Beginning PHP and MySQL: From Novice to Professional, by W. Jason Gilmore. The book starts you out with the basic principles such as proper syntax, strings, arrays, etc. and works you up slowly. Even after you’ve mastered the concepts, the book is an excellent desk reference.

Hopefully there’s a newbie out there reading this that has benefited from my suggestions. Feel free to leave me a comment with your favorite beginner’s resources.

PHP “market” demographics

Wonder how many PHP developers there are in your country? Are you curious as to the most popular browser among PHP developers? Manuel Lemos has a new blog post up at PHPclasses.org entitled “How Large Is the PHP Market?”, in which he delves into these questions and more.

Manuel uses a Zend estimate of 5 million for the total worldwide number of developers.  There is no documentation or methodology provided by Zend as to how that number was determined, but Manuel seems to think it is a reasonable estimate.  I disagree only to the extent I am not so quick to discard the notion this number could have been just pulled out of thin air.  For the sake of discussion, however, it is an adequate figure.

Also provided is a methodology you can use to extrapolate the number of PHP developers in your country.  In the U.S., for example, he estimates 637,000.  If you now feel much less unique and more easily replaceable, just remember that quality of work varies greatly and is your ticket to separating yourself from the herd.

In terms of development environments, the most suprising news is that 68% of PHP developers use Firefox as their development browser (myself included).  This is compared to a similar percentage of IE users in the general population.  Clearly this is due to Firefox’s superior developer tools and plugins, and probably to a somewhat lesser extent to Firefox’s standards compliance.  Why bang your head against the wall at the start of a project when you can wait until the end to do your IE validation?

There’s considerably more discussion in the article, so I encourage you to check it out if you’re interested in things like the percentage of web servers running Apache, or the number of Linux desktop users among PHP developers.

PHP templating with… well… PHP itself!

Have you avoided adopting a templating engine for your web applications because you are afraid of the learning curve? You’re not alone. I was in the same boat about a year ago.

But, as applications evolve and grow more complex over their lifecycle, separating presentation HTML and “presentation logic” from application logic becomes essential to being able to manage your code.

The hot template engine out there right now is Smarty. Although it is fairly simple to adopt and use, it does require the use of a Smarty-specific syntax for implementing logic (such as if statements, which are essential if you are going to show/hide content and/or controls based on user roles) in the template files themselves.

And although Smarty’s website touts the performance benefits, lets not kid ourselves. Smarty consumes server resources and even if its the fastest engine out there, its still going to slow down your application.

The alternative is to simply use PHP itself as your templating engine.

What’s that? You don’t understand what I mean? Do you remember back when you first starting coding PHP, and you jumbled up your PHP and HTML together into the same files? Remember embedding the good ole “” ? That’s the basic principle at work in templating with PHP.

Brian Lozier’s excellent Sitepoint.com article, Beyond the Template Engine, which is from way back in 2003 (I know, an eternity in web terms) discusses these issues in more detail. He also includes a detailed tutorial in the use of a PHP4 class he wrote for PHP-based templating.

I have used this class in my own applications and have found it to be excellent. The class is extremely simple and can be easily updated to PHP5 standards. He’s even included a caching method in the class, which can significantly boost application performance and reduce database calls (which is what generates most of your application’s server load).

Just for kicks, I added a method to Brian’s class to pull the templates from a database table (see below). If you’re building an application for mass distribution (like vBulletin or WordPress, etc.), this is how you would build a user-editable template system.

public function fetch_from_db($file) {
 
     extract($this->vars);  // extract vars to the local namespace
 
     $sql = " SELECT * FROM content WHERE Name = '$file' LIMIT 1 ";
     $result = mysql_query($sql) or die (mysql_error());
 
     if(mysql_num_rows($result) == 0) {
          $sql = " SELECT * FROM content WHERE Name = 'pagenotfound' LIMIT 1 "; 
          $result = mysql_query($sql) or die (mysql_error());
     } 
 
     $row = mysql_fetch_object($result);
 
     ob_start();
     eval("*>" . $row->Content . "<*"); // replace * with ? in your code
     $contents = ob_get_contents();
     ob_end_clean();
 
     return $contents;
 
}