ZendFramework2でServiceLocatorを使わずにDBアクセス
今のプロジェクトではphp&ZendFramework2を使っています。
だけど、Controllerに全ての処理が書いてあるため、以下の3つにクラス分けを検討
- Controllerクラス
- Serviceクラス(ビジネスロジック処理)
- Modelクラス(DAO)
Zend3になるとControllerクラスでServiceLocator($this->getServiceLocator())が使えなくなるようなのでどうやってDBのAdapterを渡そうか悩んだ&調べた結果以下のようにしてみました。
- Serviceクラスの生成時にDB Adapter&Modelを注入
- Conrollerの生成時にServiceを注入
ModelクラスはZendのModelを使用
http://qiita.com/ngyuki/items/19143bc00187c74389db を参考に作成
<?php
namespace Application\Model;
class Test
{
public $id
public $name;
public function exchangeArray($data) {
$this->id = (isset($data['id'])) ? $data['id'] : null;
$this->name = (isset($data['name'])) ? $data['name'] : null;
}
}
<?php
namespace Application\Model;
use Zend\Db\TableGateway\TableGateway;
use Zend\Db\Adapter\AdapterAwareInterface;
use Zend\Db\Adapter\Adapter;
class TestTable implements AdapterAwareInterface
{
protected $tableGateway;
/**
* {@inheritDoc}
* @see \Zend\Db\Adapter\AdapterAwareInterface::setDbAdapter()
*/
public function setDbAdapter(Adapter $adapter) {
$resultSetPrototype = new ResultSet();
$resultSetPrototype->setArrayObjectPrototype(new Test());
$this->tableGateway = new TableGateway('test', $adapter, null, $resultSetPrototype);
}
public function insert(array $data) {
$record = array(
'id' => $data['id'],
'name' => $data['name'],
);
// データ挿入
$this->tableGateway->insert($record);
}
}
<?php
namespace Application\Db\Adapter;
use Zend\ServiceManager\InitializerInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Db\Adapter\AdapterAwareInterface;
class AdapterInitializer implements InitializerInterface
{
/**
* {@inheritDoc}
* @see \Zend\ServiceManager\InitializerInterface::initialize()
*/
public function initialize($instance, ServiceLocatorInterface $serviceLocator) {
if ($instance instanceof AdapterAwareInterface) {
$instance->setDbAdapter($serviceLocator->get('Zend\Db\Adapter\Adapter'));
}
}
}
Serviceクラスは以下のようにしてDB AdapterとModelインスタンスを持つ。
ModelにもDB Adapter持つのでなんか冗長な感じがしてますが、トランザクション張る用に保持。
あと、この書き方だと複数のテーブルにアクセスすることになるとそれだけの数のModelをコンストラクタの引数で渡すことになるので引数がどんどん増える。。
<?php
namespace Application\Service;
use Application\Model\TestTable;
use Zend\Db\Adapter\Adapter;
class TestService {
protected $adapter;
protected $testTable;
public function __construct(Adapter $adapter, TestTable $testTable) {
$this->adapter = $adapter;
$this->testTable = $testTable;
}
public function xxx() {
// ビジネスロジック処理
}
}
最後にModule.phpで注入の設定方法
getServiceConfig()でServiceクラスやModelクラスの注入を実施。
getControllerConfig()でControllerクラスの注入を実施。
public function getServiceConfig() {
return array(
'factories' => array(
// TestService生成時にDB AdapterとTestテーブルにアクセスするためのModelをDI
'Application\Service\TestService' => function ($sm) {
$adapter = $sm->get('Zend\Db\Adapter\Adapter');
$testTable = $sm->get('Application\Model\TestTable');
return new \Application\Service\TestService($adapter, $testTable);
}
}
'invokables' => array(
'Application\Model\TestTable' => 'Application\Model\TestTable',
),
'initializers' => array(
'Application\Db\Adapter\AdapterInitializer',
),
);
}
public function getControllerConfig() {
return array(
'factories' => array(
// TestController生成時にTestServiceをDI
'Application\Controller\Test' => function ($sm) {
$testService = $sm->getServiceLocator()->get('Application\Service\TestService');
return new \Application\Controller\TestController($testService);
},
)
);
}
<?php
namespace Application\Controller;
use Application\Service\TestService;
class TestController extends AbstractActionController {
protected $testService;
public function __construct(TestService $testService) {
$this->testService = $testService;
}
pubclic function xxxAction() {
// 処理
$this->testService->xxx();
}
}
Author And Source
この問題について(ZendFramework2でServiceLocatorを使わずにDBアクセス), 我々は、より多くの情報をここで見つけました https://qiita.com/zateon/items/98434e81240cdc93d41d著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .