phpzend-framework2database-abstraction

How do I load Zend Framework 2 database module only


Zend Framework 2 claims to have a "use-at-will" design that allows you to easily use any of its modules without committing to the full stack. I need a good database access layer, and from the docs and recommendations online I like the look of Zend\Db. I've placed the Zend/Db folder in my /lib directory, but I'm having trouble getting PHP to recognize the Zend\Db\Adapter\Adapter class. I keep getting a fatal error when I try to use it:

Fatal error: Class 'Zend\Db\Adapter\Adapter' not found in /home/username/public_html/test.php on line 6

I've tried setting ZF2_PATH in my .htaccess: SetEnv ZF2_PATH /home/username/public_html/lib/Zend

I've tried setting the include path in my code: set_include_path( $_SERVER['DOCUMENT_ROOT'] . '/lib' . PATH_SEPARATOR . get_include_path() );

I've tried explicitly loading and instantiating the Zend\Loader:

require_once 'lib/Zend/Loader/StandardAutoloader.php';
$zendLoader = new Zend\Loader\StandardAutoloader();
$zendLoader->register();

None of these have had any effect. I tried explicitly requiring Zend/Db/Adapter/Adapter.php, and that did fix the error I'm seeing, but then I just get the same error for one of its dependencies, so that's not a practical solution.

What am I doing wrong here? Is ZF2 just not really designed for this kind of modular usage, or am I missing something?

EDIT: I got this to work by writing my own autoload function:

function autoloader($class) {
    $path = explode('\\', $class);
    foreach ($path as $p) {
        $cp .= DIRECTORY_SEPARATOR . $p;
    }
    include __DIR__ . '/lib/' . $cp . '.php';
}
spl_autoload_register(autoloader);

This sort of makes sense -- obviously if I'm using the db module without the rest of the framework, I can't expect the framework to do autoloading for me -- except I still don't understand why manually loading Zend\Loader didn't solve the problem. Isn't handling autoloading the point of Zend\Loader? Anyway, I have a workable solution for now, but if there's a better solution I'd love to hear it.


Solution

  • I strongly recommend you check out composer. It really simplifies managing dependencies between a ton of modern PHP libraries, as well as autoloading.

    For instance, if you were starting you project, and you knew you wanted to pull in zend-db, you'd do something like this:

    $ mkdir myproject
    $ cd myproject
    $ curl -s https://getcomposer.org/installer | php   
    $ ./composer.phar require zendframework/zend-db:2.1.1
    

    That last line will cause composer to spring into action. It will create a directory called "vendor" where it keeps all the libraries it manages. It then will check out version 2.1.1 of zend-db in there, and set up an vendor/autoload.php which you'll require in your project.

    Then you can test it out. Create myproject/index.php like so:

    <?php
    require_once "vendor/autoload.php";
    
    $adapter = new Zend\Db\Adapter\Adapter(array(
       'driver' => 'Pdo_Sqlite',
       'database' => 'path/to/sqlite.db'
    ));
    

    And it just works.

    Later, if you decide you need Zend\Mail too, you just:

    $ ./composer.phar require zendframework/zend-mail:2.1.1
    

    and composer will install it, along with a couple of dependencies, and make sure it's available to the autoloader.

    Composer is not ZF-specific, either. There's a whole ecosystem of code to explore. Packagist is a good place to start.