Zend Framework 2 Library Paths

2019-02-25 03:33发布

问题:

Trying to get my feet wet on ZF2 and I've stumbled on my first problem. Say on a module I want to use Shanty_Mongo (an external library to connect to MongoDb)

So I've copied the entire Shanty directory on the library and created a new Model class:

namespace Dummy\Model;

use Shanty\Mongo\Document;

class Dummy extends Shanty_Mongo_Document {
  public function setConnections( $connections ) {
    Shanty_Mongo::addConnections($connections);
  }
}

(The setConnections() is to be used by DI, if I've understood it well)

This seems to fail to find Shanty_Mongo_Document. Should I add something to the application.config.php to point to the extra library?

回答1:

The library Shanty_Mongo is an "old" underscore separated library without using namespaces. In ZF2, the style is the same PSR-0 standard but with namespaces (so Shanty_Mongo will be Shanty\Mongo). However, you are able to load these old style fine with a classmap for example. Then you can use underscore separated classes inside your ZF2 project.

I'd suggest you create a module for this library and put that module under ./vendor (for "modules providing 3rd party features"). In this module, you can create the following directory structure (I assume the name of the module is ShantyMongo):

./vendor/ShantyMongo/
    library/
    Module.php
    autoload_classmap.php
    autoload_function.php
    autoload_register.php

The library is a submodule to the Shanty-Mongo git repository. The file autoload_classmap.php is a classmap created by the php script classmap_generator.php inside the bin directory of the ZF2 repository. Then the autoload_function.php can be something simple as this:

<?php
return function ($class) {
    static $map;
    if (!$map) {
        $map = include __DIR__ . '/autoload_classmap.php';
    }

    if (!isset($map[$class])) {
        return false;
    }
    return include $map[$class];
};

And autoload_register.php something like this:

<?php
spl_autoload_register(include __DIR__ . '/autoload_function.php');

To let the ZF2 application know you have this module, you need to fill the module.php with a ShantyMongo\Module class. Something like this should be sufficient:

<?php

namespace ShantyMongo;

use Zend\Module\Consumer\AutoloaderProvider;

class Module implements AutoloaderProvider
{
    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\ClassMapAutoloader' => array(
                __DIR__ . '/autoload_classmap.php',
            )
        );
    }
}

If you add "ShantyMongo" to your modules array in application.config.php you now have set up the autoloader for this 3rd party library inside ZF2. You can then use your model as follows:

<?php

namespace Dummy\Model;

class Dummy extends Shanty_Mongo_Document {
  public function setConnections ($connections) {
    Shanty_Mongo::addConnections($connections);
  }
}

Because ShantyMongo doesn't use namespaces, you don't have that use statement anymore.