简体   繁体   中英

Inject DB adapter in mapper

I am quite confused about how to inject (Zend/Apigility) in a mapper class a specific db adapter (here named music) concerning following mapper:

AlbumMapper.php

<?php
namespace music\V1\Rest\Album;

use Zend\Db\Sql\Select;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Paginator\Adapter\DbSelect;

class AlbumMapper
{
    protected $adapter;
    public function __construct(AdapterInterface $adapter)
    {
        $this->adapter = $adapter;
    }

    public function fetchAll()
    {
        $select = new Select('album');
        $paginatorAdapter = new DbSelect($select, $this->adapter);
        $collection = new AlbumCollection($paginatorAdapter);
        return $collection;
    }

    public function fetchOne($id)
    {
        $sql = 'SELECT * FROM album WHERE id = ?';
        $resultset = $this->adapter->query($sql, array($id));
        $data = $resultset->toArray();
        if (!$data) {
            return false;
        }

        $entity = new AlbumEntity();
        $entity->exchangeArray($data[0]);
        return $entity;
    }
}

Module.php

public function getServiceConfig()
{
    return array(
        'factories' => array(
            'music\V1\Rest\Album\AlbumMapper' =>  function ($sm) {
                $adapter = $sm->get('Zend\Db\Adapter\Adapter');
                return new \music\V1\Rest\Album\AlbumMapper($adapter);
            },
        ),
    );
}

AlbumResourceFactory.php

<?php
namespace music\V1\Rest\Album;

class AlbumResourceFactory
{
    public function __invoke($services)
    {
        $mapper = $services->get('music\V1\Rest\Album\AlbumMapper');
        return new AlbumResource($mapper);
    }
}

This will fetch the db adapter credentials from config/autoload/user.global.php file which is according to this file comment not an appropriate way when it comes to productive mode.

The solution that I think is the correct one, involves the editing of the Module.php file:

public function getServiceConfig()
{
    $dbParams = array(
        'database'  => 'music',
        'username'  => 'root',
        'password'  => 'myPassword',
        'hostname'  => 'localhost',
    );

    return array(
        'factories' => array(
            'music\V1\Rest\Album\AlbumMapper' =>  function ($sm) use ($dbParams) {
                $adapter = new \Zend\Db\Adapter\Adapter(array(
                    'driver'    => 'pdo',
                    'dsn'       => 'mysql:dbname='.$dbParams['database'].';host='.$dbParams['hostname'],
                    'database'  => $dbParams['database'],
                    'username'  => $dbParams['username'],
                    'password'  => $dbParams['password'],
                    'hostname'  => $dbParams['hostname'],
                ));
                return new \music\V1\Rest\Album\AlbumMapper($adapter);
            },
        ),
    );
}

If there is a better solution I am open for suggestions, but this works.

You could do it another (recommended) way with Zend\\Db\\Adapter\\AdapterServiceFactory .

First configure your global DB settings in config/autoload/global.php and configure the usage of AdapterServiceFactory

return array(
     'db' => array(
         'driver'         => 'Pdo',
         'dsn'            => 'mysql:dbname=music;host=localhost',
         'driver_options' => array(
             PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
         ),
     ),
     'service_manager' => array(
         'factories' => array(
             'Zend\Db\Adapter\Adapter'
                     => 'Zend\Db\Adapter\AdapterServiceFactory',
         ),
     ),
 );

Then you could override some of settings (for example DB credentials) in config/autoload/local.php

return array(
     'db' => array(
         'username' => 'root',
         'password' => 'myPassword',
     ),
);

After that in your Module.php you could just get 'Zend\\Db\\Adapter\\Adapter' from ServiceManager :

public function getServiceConfig()
{    
    return array(
        'factories' => array(
            'music\V1\Rest\Album\AlbumMapper' =>  function ($sm) {
                $adapter = $sm->get('Zend\Db\Adapter\Adapter');
                return new \music\V1\Rest\Album\AlbumMapper($adapter);
            },
        ),
    );
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM