Learning PHP Data Objects

October 20th, 2007

Popel, D. (2007) Learning PHP Data Objects, Packt Pub

Commendably the book keeps a tight focus, providing the minimum context in which to show PDO features: in this case a basic library program with simple PHP methods providing HTML. However in a later chapter it provides a useful example that shows the advantage of the model, updating previous code accordingly.

It saves time by assuming you have your environment set up correctly. Considering the ease of which you can install an environment such as WAMP or LAMP, this is a good decision. PDO itself is now distributed as a shared extension, so you just need to enable it by adding the so or dll to the relevant configuration file. Using Ubuntu, this is at /etc/php5/conf.d/pdo.ini

Design patterns vary, I believe the idea is that the reader should research MVC separation and other patterns, decide how to use them, then incorporate the PDO features from the book; it doesn’t enforce a particular methodology you may not want to use. It implies that you make or acquire a system to separate the view and model, perhaps by using extract and compact. Conversely this is a disadvantage to less experienced PHP programmers, as they won’t be served by the least-common-denominator code examples, which don’t enforce separation of HTML and PHP.

I would recommend the book on the subjects of security and database correctness. Using prepared statements the book provides you with a robust way to avoid SQL injection. Many people still rely on the ad hoc use of addslashes and friends, but even these have been attacked, with exploits taking advantage of incorrect character sets. As PDO can emulate prepared statements, now you really have no excuse to not use them.

When something goes wrong, the book explains how to handle the error correctly with exceptions, without exposing potentially harmful information. For mission-critical database operations it elaborates on transactions, which weren’t a feature of the PHP 4 extensions, and are either handled natively or emulated with PDO. Again it doesn’t let focus drift into validation, which isn’t provided by PDO, so only cursory hard-coded examples are given.

The best time to implement PDO is when starting a new project, as you can use it exclusively, hopefully easing the pain if you need to transfer to a different database down the line. The book keeps this well in mind and emphasises that PDO is for connection abstraction not database abstraction; it won’t write your SQL for you. Helpfully it highlights various situations when you might be tempted to use non-portable SQL, notably when counting rows and inserting data. Also if you want to prototype a new system, you can take advantage of the configuration-less SQlite database, indeed if you want to use version three of SQlite, then you have to use PDO, as the old functions operate on version two.

If you prefer the task-oriented approach to learning, you’ll like this book. It provides code and screen-shots to guide you through each step. If you’re an advanced PHP programmer, there are a few things you may find interesting, such as the lesser known PDO configuration options, and BLOB support, but really I find this book aimed more at the intermediate procedural programmer. Indicative of this is the succinct “Introduction to OOP in PHP 5″ appendix.

If you supplement this with other application design literature and integrate the PDO techniques in the book, you’ll certainly be another step towards making your systems more flexible and maintainable.

Code Igniter: Active Record and Private Class Variables

October 6th, 2007

In the Code Igniter Models documentation it details the Active Record insert, which builds the insert around your class variables, allowing you to do this:

$this->title   = $_POST['title'];
$this->content = $_POST['content'];
$this->date    = time();
$this->db->insert('entries', $this);

However there’s a bug: it doesn’t distinguish against private class variables, leaving you with errors like this:

error, no fields in database named ‘_parent_name’ ,’_ci_scaffolding’ , and ‘_ci_scaff_table’

These private class variables (denoted by the underscore) are inherited from the base Model class, but can be stripped out by editing system/database/DB_active_rec.php function _object_to_array:

if ( ! is_object($val) AND ! is_array($val) AND substr($key, 0, 1) != '_');

Code Igniter: Model Constructor Arguments?

October 1st, 2007

After a month of use, I’m still a big fan of Code Igniter; it’s a lightweight PHP framework that hasn’t got in my way, which is a big factor regarding how long things last. I particular like its flexibility regarding handling URLs, as it doesn’t force you to use its default segment-based approach, providing direct regex URL / Object mapping, or if you so wish, an option to revert back to plain HTTP GET. Other frameworks can do similar things, but they don’t all work on PHP 4, and don’t all have the same quality of documentation.

Nevertheless there was something I found confusing to begin with: the use of the Active Record pattern in the model. Not knowing about Active Record, I was left asking: where are my model constructor arguments? To demonstrate, you can’t do something like this:

$this->load->model("foo", array("id" => 1));

To do so you have to implement your code in terms of a library. For models, think of your class as a representation of a table, which provides standard CRUD functionality, with member variables instead of constructor arguments:

$this->load->model("table_name");
$this->table_name->id = 1;
$this->table_name->text = "Example";
$this->table_name->update();