phpdata-access-layerdatabase-abstractionezsql

Simple database abstraction for PHP and MySQL


This is my very first post here, please let me know if I can improve the question.

I'm in the process of updating a website. In short: it handles user subscriptions and keeps track of sales (products I make). I want to keep my options open for adding new features to it in the near future. It is built using PHP and MySQL.

I have not seriously updated the code in 5 years and I'm trying to seize the opportunity to make the whole code easier to manage and update. Particularly, I'm trying to make interacting with the database a lot nicer.

I've played around with ezSQL which lets me interact with the db in a very concise way, such as:

$users = $db->get_results("SELECT name, email FROM users");
foreach ( $users as $user ) {
    // Access data using object syntax
    echo $user->name;
    echo $user->email;
}

I really like it: I quickly end up with an object I can use and it makes the code nicer to read, without having as many mysql_* functions, nor SQL queries all over the place, unlike how it used to be.

If it's nice for SELECT queries, it is not that much of a help for INSERT statements and I may end up with code that looks like this:

$db->query( "INSERT INTO    users    (name, email, date, hostname, cid, code, email_id, email_date, source, ebook, audiobook )
                            VALUES    ( '" . $db->escape( $user->name ) . "',
                                        '" . $db->escape( $user->email ) . "',
                                        '" . $db->escape( $user->date ) . "',
                                        '" . $db->escape( $user->hostname ) . "',
                                        '" . $db->escape( $user->cid ) . "',
                                        '" . $db->escape( $user->code ) . "',
                                        '" . $db->escape( $user->email_id ) . "',
                                        '" . $db->escape( $user->email_date ) . "',
                                        '" . $db->escape( $user->source ) . "',
                                        '" . $db->escape( $user->ebook ) . "',
                                        '" . $db->escape( $user->audiobook ) . "')"
                            );

It could be worse but it's still not so nice to go through. The worst part to me is that it is not as straight-forward at all as the previous example.

So, given the following table structure and PHP object:

$user = new User();
$user->name = 'something';
$user->email = 'something@example.com';
/// etc.

class User {
    var $name;
    var $email;
    // etc.
}

I'd like a simple library that lets me do just this:

$user->insert();

...and matches each member of the class with the column by the same name in the database for me and inserts the data accordingly.

My question is: is there such a library? If not, why is it a bad idea.

I've been reading about MVC but I think that it's overkill for this project. It would add extraneous complexity instead of simplicity. I do not need scaffolding nor anything that generates default code for me, for example. Also, I don't want to end up entangled in a framework that's too much for such a simple project.

So I've been curious about Database Abstraction Layers for PHP (eg: ADOdb, PDO) but it is not clear to me yet whether they are mainly intended to make writing code shorter (my intended usage) or to make writing code for various databases easier. I don't mind that my code only works with MySQL. I simply want to abstract it for clarity, not compatibility.

Instead of having to test-drive each DAL for PHP, could someone maybe provide feedback, based on experience and the simple intended use described above?

Thank you for the help.


Solution

  • RedBeanPHP is an excellent library for the purpose you describe. It is the most flexible ORM I have ever used. See the example on their home page for CRUD operations:

    $post = R::dispense('post');
    $post->text = 'Hello World';
    
    $id = R::store($post);      //Create or Update
    $post = R::load('post',$id); //Retrieve
    R::trash($post);            //Delete
    

    This library is flexible enough that it will generate database tables on the fly so you don't have to muck around with schema. Many people consider this a feature - I usually turn it off because I prefer to tweak my tables manually. Nonetheless a simple call to R::freeze() will disable that feature. It's essential to make sure the schema is frozen before going into production anyway.

    RedBeanPHP also handles relationships between database tables, and it has simple debugging capabilities if you want to see what queries are being executed under the hood (again, just a call to R::debug()). It's extremely powerful as a database abstraction layer, but you don't have to use all the fancy bells and whistles if you don't want to. It more-or-less works out of the box after including the library.

    Highly recommended, especially for your purpose.