rc3.org

Strong opinions, weakly held

The PHP encapsulation problem

I was working on a small project this week that reminded me again of PHP’s fatal flaw, which is that it is nearly impossible to maintain encapsulation to prevent components of a system from screwing each other up. We have a Web site that uses a big, popular, open source PHP application. The home page of the site loads up some components of the system and displays some information. I had written a tiny application to enable users to maintain one small section of the home page. My application’s involvement with the home page consisted of one function and one callout to the function to display its return value. The function was basically this:

function getQuote() { $my_db = mysql_connect(“host”, “user”, “password”); mysql_select_db(“my_db”, $my_db);

// Query the database, grab a value, and return it. }

My code worked fine, but the mysql_select_db call blew up the other application. As far as I can tell, everything I did should live within the local namespace of my function and shouldn’t affect anything else on the page. To fix the problem, I wound up writing my function using mysqli. I’m not sure if that worked because mysqli provides better encapsulation or because the rest of the application uses the old style MySQL functions and the newer mysqli stuff doesn’t conflict with it.

Aside from the pain in dealing with problems like this, I think that PHP’s lack of clean encapsulation is probably what makes many PHP applications tend toward chaos as they grow.

5 Comments

  1. Asbjørn Ulsberg

    June 5, 2007 at 4:10 pm

    The worst thing is that we have to live with these problems for years, since PHP5 (which corrects many of these scope problems by introducing proper object orientation) uptake in hosting environments is stunningly slow. My host (DreamHost) provides PHP5, but the last survey I saw (not sure where) showed less than 10% deployment of PHP5, 3 or so years after its release.

    We probably need to wait 10 or more years for PHP5 deployment to surpass that of PHP4 and then some more years for developers to stop grinding out PHP4 code and move over to cleaner PHP5 code. Perhaps then, and only then, will it be possible to extend on existing frameworks and libraries without breaking absolutely everything with every iteration.

  2. Check out the docs on mysql_select_db, and the notes about connecting to multiple databases:

    http://us2.php.net/mysql_select_db

    Wow, that’s nasty. Especially this:

    http://us2.php.net/manual/en/function.mysql-select-db.php#39095

    On another note, Zend and the PHP group really mucked up the release of PHP5. From what I understand, the slow adoption rates were initually due to the fact that apps like Plesk and Cpanel broke under PHP5. So all those cheapy VPS hosts couldn’t make the switch. Years later, I’m guessing that’s changed — but damn. Zend should have worked with this people in some way to make sure that didn’t happen.

  3. Did you try it with the new_link parameter set to true?

    http://us2.php.net/manual/en/function.mysql-connect.php

  4. While I’d love PHP5 to become universal, too, this has been fixed since PHP 4.2 for anyone suffering with sloppy code (the new_link parameter allows you to force mysql_connect to return a new handle) – security reasons alone mean you should already have that available.

    Also, while it wasn’t complete PHP4’s object support was more than sufficient for database encapsulation and ORM – I’ve been doing both for years using code I wrote in 2001 and the idea was hardly revolutionary then (I just liked being able to make the syntax much cleaner and avoiding the wizard-like boilerplate code which the existing classes required).

    The only real problem you’ll run into is the impossibility of implementing singletons without using the global namespace. I was content living with that restriction until PHP5 came around since not having to worry about connection IDs and being able to do things like foreach($db->query(“…”) as $user) more than made up for the inability to have poor data models be more memory-efficient.

  5. Your encapsulation is just at the wrong level.

    You need a do_query($db, $sql) method that handles connecting and selecting db.

    Ruby ruins your instincts for PHP. (and alas PHP5 does not solve this one)

Leave a Reply

Your email address will not be published.

*

© 2024 rc3.org

Theme by Anders NorenUp ↑