PHP PDO class and XAMPP/”exotic” MySQL configurations

Last night I was trying to setup a @mail server but the installer kept choking when attempting to connect to my local database.

I am posting here my quick workaround in case you too, dear reader, get a dreaded “PDO” error message complaining about your attempt to “connect to unix://

Here is I how I solved the issue for @mail: I opened library/Zend/Db/Adapter/Pdo/Abstract.php, found the line that creates the PDO object (”new PDO(…“) and, in this example, the first argument passed to the constructor was $dsn.

The problem is that PDO sees that this variables references “localhost” and decides that, since the database is local, it is going to use mysql.sock (hence the unix:// scheme)

This works as long as the file is found in its default location. If it is elsewhere, you are out of luck. This happens, for instance, if you use XAMPP.

Here is my quick fix, inserted right before the creation of the PDO object:

$dsn = str_replace(’host=localhost’, ‘unix_socket=/opt/lampp/var/mysql/mysql.sock’, $dsn);

All done.

Note: I have not investigated enough to know whether this is something missing in the Zend Framework or in @mail itself.

If you enjoyed this post, make sure you subscribe to my RSS feed!


How I added real ActiveRecord support to adodb

Dead hard driveFor my new projects, I have decided to use PHP5, mostly because at least a couple projects will be worked on by a team and the learning curve is fairly forgiving.
I decided, however, to follow the model offered by Rails. I looked into a few PHP frameworks, such as Akelos, but realized that they were too constraining for our purpose. That’s when I decided to develop my own thin layer framework.

An excellent productivity tool is the ActiveRecord pattern. After all, it doesn’t matter what it is, that’s being mapped; whether it’s database tables or web services should not be relevant to the controller.
I have, in the past, used adodb successfully and I was happy when I realized that it comes with a ADOdb_Active_Record class.

Unfortunately, that class does a very basic job of mapping one class to a database table and that’s it. Therefore, support for has_many or belongs_to clauses.
I know that AR offers more features that those but I thought that these fit the very minimum requirement for them to be useful.
And that’s how I ended up modifying ADOdb_Active_Record to support these.

This article is mostly a series of listings that show the modifications-a bit-and how to use them-a bit more. First, here is how I am using them in my framework:
Let’s imagine a database that contains songs, artists and genres. Let’s look at the definition of a Song object:

<?php
class Song extends ActiveRecord
{
        function __construct()
        {
                parent::__construct('song');
                $this->belongsTo('artist');
                $this->belongsTo('genre');
        }
}
?>

and an Artist object:

<?php
class Artist extends ActiveRecord
{
        function __construct()
        {
                parent::__construct('artist');
                $this->hasMany('songs');
        }
}
?>

let’s have a look at a very basic controller that will allow us to retrieve our artists. Their songs will also be retrieved, since artists are defined as having many songs:

<?php
 
class ArtistController extends ApplicationController
{
        function index()
        {
                $artist = new Artist();
                $this->artists = &$artist->find(ALL, "artists.id=1", array('loading'=>ADODB_LAZY_AR));
        }
}
?>

Through the magic of my framework, which is outside the scope of this post, we will then be able to display our artists with their respective songs like so:

    <div id="colOne">
 
        <?php
        foreach($artists as $artist)
        {
                print "<h1>{$artist->name}</h1>";
                foreach($artist->songs as $song)
                {
                        print "&nbsp;&nbsp;&nbsp;&nbsp;TITLE:{$song->title}<br />";
                }
        }
        ?>
 
   </div>

Note that, for this example, I removed as many irrelevant pieces of code as possible. For instance, we are always retrieving artist #1. The array that we are passing to the find() statement allows us to configure some of AR’s behaviours. In this example, we are passing ADODB_LAZY_AR, which is a hint that we do not wish to perform massive joins, but retrieve related objects on demand. If we wished to retrieve everything upfront, we could have used ADODB_JOIN_AR instead.

Now, our model classes are subclasses of ActiveRecord, which is another one of my framework classes, which provides a light abstraction on top of ADOdb_Active_Record. The relevant piece, for you, would be this one since we invoke it:

        function find($mode, $condition=null, $extra=array(), $bindArr=false, $pKeyArr=false)
        {
                // id?
                if(ctype_digit($mode))
                        return $this->load($mode);
 
                // return one row
                if(FIRST == $mode)
                        return parent::load($condition);
 
                // Assumption: ALL == $mode - return multiple rows
                return parent::find($condition, $bindArr, $pKeyArr, $extra);
        }

It is interesting because the last line contains the actual call to ADOdb_Active_Record’s find() method.

In adodb itself, two files were modified: adodb-active-record.php and adodb.inc.php.

The former now contains two new structures: _hasMany and _belongsTo. ARs are now aware of the concept of foreign name, which is the name by which this object will be known to another object if a relationship is defined. This allows us, among other things, to naturally inflect tables names.

The latter was modified so that it accepts extra parameters, for instance in GetActiveRecordsClass(), and handle massive joins. Note that joins can be deferred through the use of ADODB_LAZY_AR. In which case I will use the model objects’ __get() method to load missing properties on-demand.

“Buyer Beware”
I hope to publish my full PHP framework in the near future; in the meantime, this hacked version of adodb has been very helpful in my work. I hope you too find it helpful. Beware, though: this is an early work and I would rather offer it to John Lim and let him integrate it in adodb-or can it if he’s too horrified!
I am aware of at least one bug, which may happen when using the join method on belongs_to objects. It could also do more things for you. Definitely not the cat’s meow.
But if you like it and need help, drop me a line.

Download

If you enjoyed this post, make sure you subscribe to my RSS feed!