编辑: 我应该解释这是一个必须使用\ authenticate到多个dbs的应用程序。我在自动加载配置中定义了所有数据库适配器,如下所示:
return array(
'db' => array(
//Default adapter retrieved with $sm->get('Zend\Db\Adapter\Adapter')
'driver' => 'Pdo_Mysql',
'dsn' => 'mysql:dbname=db1;host=myserver',
'username' => $DBuser,
'password' => $DBpass,
//'driver_options' => array(
// PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES \'UTF8\''
//),
'adapters' => array(
'someDB' => array(
'driver' => 'Pdo_Mysql',
'dsn' => 'mysql:dbname=someDB;host=myserver',
'username' => $DBuser,
'password' => $DBpass,
),
'someOtherDB' => array(
'driver' => 'Pdo_Mysql',
'dsn' => 'mysql:dbname=someOtherDB;host=myserver',
'username' => $DBuser,
'password' => $DBpass,
'AppType' => 'myCustomProperty',
...
我有以下功能我试图转移到服务管理器:
public function getAuthService($db) {
if (! $this->authService) {
//All DBs using authentication must have a view_users view
$dbAdapter = $this->getServiceLocator()->get($db);
$authAdapter = new AuthAdapter($dbAdapter);
$authAdapter
->setTableName('view_users')
->setIdentityColumn('username')
->setCredentialColumn('password')
->setCredentialTreatment('MD5(?)');
;
$authService = new AuthenticationService();
$authService->setAdapter($authAdapter);
$this->authService = $authService;
}
return $this->authService;
}
我在服务管理器中有这个,但是如何修改它以便$ myParam在检索时可以传递?
public function getServiceConfig() {
return array(
'factories' => array(
'AuthService' => function($sm) {
$dbAdapter = $this->getServiceLocator()->get($myParam);
$authAdapter = new AuthAdapter($dbAdapter);
$authAdapter
->setTableName('view_users')
->setIdentityColumn('username')
->setCredentialColumn('password')
->setCredentialTreatment('MD5(?)');
;
$authService = new AuthenticationService();
$authService->setAdapter($authAdapter);
return $authService;
}
)
);
}
问题是我希望能够在从服务管理器检索它时将$ db param传递给工厂。
要明确这个问题并不是专门针对如何对多个数据库进行身份验证,因为这对我来说已经很好了,我只想将我的功能移到服务管理器中。
编辑:crisp回答了我的实际问题,但我发现我的真正问题是对如何使用Authentication类的误解。
长话短说,我有一个登录控制器,提示输入用户信用,然后检查用户对所有数据库的访问权限,并将此信息存储在Zend \ Authentication \ Storage \ Session中。然后从各种其他模块,只需调用Session上的read()并检索用户的授权信息。
答案 0 :(得分:2)
您正在寻找的是AbstractFactory
,它本身能够从服务名称确定要返回的服务。
来自抽象工厂的服务命名必须有一种模式,我建议您的用例使用AuthService\DbAdapterName
模式。
考虑到这一点,你可以为它写一个工厂,比如这个......
<?php
namespace Application\Service;
use Zend\Authentication\AuthenticationService;
use Zend\Authentication\Adapter\DbTable as AuthAdapter;
use Zend\ServiceManager\AbstractFactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class AbstractAuthenticationServiceFactory implements AbstractFactoryInterface
{
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
// the name must begin with authservice ($name is the lowercase canonical name)
if (0 !== strpos($name, 'authservice')) {
return false;
}
// remove authservice from the name, leaving just the db name
$dbName = str_replace('authservice', '', $name);
// we can create the service only if the service manager has the db
return $serviceLocator->has($dbName);
}
public function createServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
$dbName = str_replace('authservice', '', $name);
$dbAdapter = $serviceLocator->get($dbName);
$authAdapter = new AuthAdapter($dbAdapter);
$authAdapter
->setTableName('view_users')
->setIdentityColumn('username')
->setCredentialColumn('password')
->setCredentialTreatment('MD5(?)');
$authService = new AuthenticationService();
$authService->setAdapter($authAdapter);
return $authService;
}
}
出厂后,您需要将其添加到service_manager
键下的abstract_factories
配置中...
// module.config.php
return array(
'service_manager' => array(
'abstract_factories' => array(
'authservice' => 'Application\Service\AbstractAuthenticationServiceFactory',
),
),
);
然后,您可以使用servicelocator通过使用前面描述的模式获取AuthService
个实例
$someDbAuth = $this->getServiceLocator()->get('AuthService\someDB');
$otherDbAuth = $this->getServiceLocator()->get('AuthService\someOtherDB');