Php 使用Zend Framework使用多个数据源
我正在启动一个基于zend框架的应用程序;该应用程序应该能够使用数据库以外的多个数据源;例如,Web服务 我一直在阅读如何构建我的模型以适应这种情况。我遇到了各种各样的概念,它们似乎为这个DataMapper模式、服务模式、适配器层等提供了解决方案。但是,我仍然不知道如何将这些结合到一个可重用和可伸缩的代码库中 我以前使用过zend framework,通常会使用mysql表。例如,若我有一个Users表……我的模型中有一个Users类,它包含用户域的业务逻辑和一个扩展Zend_Db_table_Row_Abstract(表示用户表中的一行)的用户类Php 使用Zend Framework使用多个数据源,php,oop,zend-framework,zend-db,Php,Oop,Zend Framework,Zend Db,我正在启动一个基于zend框架的应用程序;该应用程序应该能够使用数据库以外的多个数据源;例如,Web服务 我一直在阅读如何构建我的模型以适应这种情况。我遇到了各种各样的概念,它们似乎为这个DataMapper模式、服务模式、适配器层等提供了解决方案。但是,我仍然不知道如何将这些结合到一个可重用和可伸缩的代码库中 我以前使用过zend framework,通常会使用mysql表。例如,若我有一个Users表……我的模型中有一个Users类,它包含用户域的业务逻辑和一个扩展Zend_Db_table
如何最好地组织我的模型和代码库,以便无论我的数据源是什么,我仍然可以调用$users->fetchAll并获取用户对象的集合?它的工作原理基本上与您以前的工作原理相同,只是您使用的不是Zend_Db_Table_Gateway,而是my_UserGateway_,例如,首先创建一个界面:
interface UserGateway
{
/**
* @return array
* @throws UserGatewayException
*/
public function findAll();
}
我们不希望来自具体网关的异常出现在消费代码中,因此我们将UserGatewayException添加为一个包罗万象:
class UserGatewayException extends RuntimeException
{}
然后添加一个实现该接口的类:
class My_UserGateway_Webservice implements UserGateway
{
public function findAll()
{
try {
// insert logic to fetch from the webservice
return $userData;
} catch (Exception $e) {
throw new UserGatewayException($e->getMessage(), $e->getCode, $e);
}
}
// … more code
}
同样,如果要使用数据库源,可以为Zend_Db_*类编写适配器,例如
class My_UserGateway_Database implements UserGateway
{
private $tableDataGateway;
public function __construct(Zend_Db_Table_Abstract $tableDataGateway)
{
$this->tableDataGateway = $tableDataGateway;
}
public function findAll()
{
try {
return $this->tableDataGateway->select()->blah();
} catch (Exception $e) {
throw new UserGatewayException($e->getMessage(), $e->getCode, $e);
}
}
// … more code
}
如果您需要另一个数据提供者,请确保他们实现了该接口,这样您就可以依赖findAll方法。使您的消费类依赖于接口,例如
class SomethingUsingUsers
{
private $userGateway;
public function __construct(UserGateway $userGateway)
{
$this->userGateway = $userGateway;
}
public function something()
{
try {
$users = $this->userGateway->findAll();
// do something with array of user data from gateway
} catch (UserGatewayException $e) {
// handle Exception
}
}
// … more code
}
现在,当您创建一些ThingusingUsers时,您可以轻松地将一个或另一个网关注入构造函数,并且无论使用哪个网关,您的代码都可以工作:
$foo = SomethingUsingUsers(
new My_UserGateway_Database(
new Zend_Db_Table('User')
)
)
或者,对于Web服务:
$foo = SomethingUsingUsers(
new My_UserGateway_Webservice(
// any additional dependencies
)
)
它的工作原理与之前基本相同,只是使用My_UserGateway(我的用户网关)而不是Zend_Db_Table_网关,例如,首先创建一个接口:
interface UserGateway
{
/**
* @return array
* @throws UserGatewayException
*/
public function findAll();
}
我们不希望来自具体网关的异常出现在消费代码中,因此我们将UserGatewayException添加为一个包罗万象:
class UserGatewayException extends RuntimeException
{}
然后添加一个实现该接口的类:
class My_UserGateway_Webservice implements UserGateway
{
public function findAll()
{
try {
// insert logic to fetch from the webservice
return $userData;
} catch (Exception $e) {
throw new UserGatewayException($e->getMessage(), $e->getCode, $e);
}
}
// … more code
}
同样,如果要使用数据库源,可以为Zend_Db_*类编写适配器,例如
class My_UserGateway_Database implements UserGateway
{
private $tableDataGateway;
public function __construct(Zend_Db_Table_Abstract $tableDataGateway)
{
$this->tableDataGateway = $tableDataGateway;
}
public function findAll()
{
try {
return $this->tableDataGateway->select()->blah();
} catch (Exception $e) {
throw new UserGatewayException($e->getMessage(), $e->getCode, $e);
}
}
// … more code
}
如果您需要另一个数据提供者,请确保他们实现了该接口,这样您就可以依赖findAll方法。使您的消费类依赖于接口,例如
class SomethingUsingUsers
{
private $userGateway;
public function __construct(UserGateway $userGateway)
{
$this->userGateway = $userGateway;
}
public function something()
{
try {
$users = $this->userGateway->findAll();
// do something with array of user data from gateway
} catch (UserGatewayException $e) {
// handle Exception
}
}
// … more code
}
现在,当您创建一些ThingusingUsers时,您可以轻松地将一个或另一个网关注入构造函数,并且无论使用哪个网关,您的代码都可以工作:
$foo = SomethingUsingUsers(
new My_UserGateway_Database(
new Zend_Db_Table('User')
)
)
或者,对于Web服务:
$foo = SomethingUsingUsers(
new My_UserGateway_Webservice(
// any additional dependencies
)
)