简体   繁体   中英

Zend Framework 3 Model class invoke to get configuration of db

I have these model-classes:

MasterModel:

namespace sf\ZfCommons\Model;

use Zend\Db\Sql\Sql;
use Zend\Db\Adapter\Adapter;

class MasterModel extends AbstractModel
{
    public $db;
    public $dbSys;
    public $dbUserClient;
    public $dbSysParams;
    public $dbUserClientParams;

    public function __construct()
    {
        $this->dbSys = new Adapter(Array(
            'driver' => 'Pdo_Mysql',
            'hostname' => 'localhost',
            'database' => 'db1',
            'username' => 'root',
            'password' => 'password',
            'charset' => 'utf8'
            ));

        $this->dbUserClient = new Adapter(Array(
            'driver' => 'Pdo_Mysql',
            'hostname' => 'localhost',
            'database' => 'db2',
            'username' => 'root',
            'password' => 'password',
            'charset' => 'utf8'
            ));

        if ($this::TBL_PLACE == 'user_client') {
            $this->db = $this->dbUserClient;
        } else {
            $this->db = $this->dbSys;
        }
        $this->sql = new Sql($this->db);
    }
}

AbstractModel:

namespace sf\ZfCommons\Model;

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\ServiceManager;

class AbstractModel
{
    /**
     * @var ServiceManager
     */
    protected $serviceManager;

    /**
     * @return ServiceManager
     */
    public function getServiceManager()
    {
        return $this->serviceManager;
    }

    /**
     * @param mixed $serviceManager
     * @return $this
     */
    public function setServiceManager(ContainerInterface $serviceManager)
    {
        $this->serviceManager = $serviceManager;
        return $this;
    }
}

ModelFactory:

namespace sf\ZfCommons\Model;

use Interop\Container\ContainerInterface;
use Zend\ServiceManager\Factory\FactoryInterface;

class ModelFactory implements FactoryInterface
{
    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
    {
        echo "############# ModelFactory #################";

        $service = (null === $options) ? new $requestedName : new $requestedName($options);

        return $service->setServiceManager($container);
    }
}

My module.config.php has the lines:

...
'service_manager' => [
        'factories' => [
            \sf\ZfCommons\Model\MasterModel::class => \sf\ZfCommons\Model\ModelFactory::class
        ],
        'invokables' => [
        ],
    ],
...

But the Factory is not called... What is wrong here? I want to read the db1 and db2 params from the configuration and set 2 adapters ( for each db one adapter )

How can I do that? Is there another way to get the configuration?

For your factory to be called, you need to use the Service Manager to get the MasterModel service where you need to use it, such as in another factory. For example:

class SomethingFactory implements FactoryInterface
{
   public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
   { 
     $masterModel = $container->get(\sf\ZfCommons\Model\MasterModel::class);
     // then do something with $masterModel, like inject it into something else
     return new Something($masterModel);
   }
}

In addition, ZF has a built-in DB adapter abstract factory that can build both adapters for you without having to create the MasterModel class and its factory. This is assuming that you are building a MVC application.

In your config/autoload/local.php or config/autoload/global.php , add the following:

'db' => [
    'adapters' => [
        'dbSys' => [
            'charset' => 'utf8',
            'database' => 'db1',
            'driver' => 'Pdo_Mysql',
            'username' => 'username',
            'password' => 'password',
            'hostname' => 'localhost',
        ],
        'dbClient' => [
            'charset' => 'utf8',
            'database' => 'db2',
            'driver' => 'Pdo_Mysql',
            'username' => 'username',
            'password' => 'password',
            'hostname' => 'localhost',
        ],
    ],
],

In your module.config.php (although it would be better to put this in the config/autoload/global.php ), your can add these lines:

...
'service_manager' => [
     'factories' => [
         'dbSys' => \Zend\Db\Adapter\AdapterAbstractServiceFactory::class,
         'dbClient' => \Zend\Db\Adapter\AdapterAbstractServiceFactory::class,
     ],
     'invokables' => [
     ],
 ],
...

But you still need to user the Service Manager at one point to get the adapters. Using the example above:

$dbSys = $container->get('dbSys);
$dbClient = $container->get('dbClient');

Hope this helps.

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