可以创建一个工厂来实例化自定义表单验证器吗? [英] Possible to create a factory to instantiate custom Form validators?
问题描述
(使用 Zend 框架 2.2.4)
(using Zend Framework 2.2.4)
我的验证器工厂在验证时似乎并不存在".如果我尝试从包含表单的控制器实例化验证器,则相反,它可以正常工作:
My validator factory, doesn't seem to "exist" at validation time. If I attempt to instantiate the validator from the controller in which the form is housed, it conversely works fine:
这有效...
$mycustomvalidator = $this->getServiceLocator()
->get('ValidatorManager')
->get('LDP_PinAvailable');
以下是代码中其他设置的方式,我似乎无法找到问题,希望避免打开 ZF2 源代码来理解.从文档来看,这似乎是正确的.
Here's how things are set up otherwise in the code, I can't seem to find the problem, and was hopeful to avoid opening up ZF2 source to understand. By way of documentation, it seems right.
模块配置
public function getValidatorConfig()
{
return array(
'abstract_factories' => array(
'\LDP\Form\Validator\ValidatorAbstractFactory',
),
);
}
工厂课堂
namespace LDP\Form\Validator;
use Zend\ServiceManager\AbstractFactoryInterface,
Zend\ServiceManager\ServiceLocatorInterface;
class ValidatorAbstractFactory implements AbstractFactoryInterface
{
public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName)
{
return stristr($requestedName, 'LDP_PinAvailable') !== false;
}
public function createServiceWithName(ServiceLocatorInterface $locator, $name, $requestedName)
{
// baked in for sake of conversation
$validator = new \LDP\Form\Validator\PinAvailable();
if( $validator instanceof DatabaseFormValidatorInterface )
$validator->setDatabase( $locator->get('mysql_slave') );
return $validator;
}
}
自定义验证器
namespace LDP\Form\Validator;
class PinAvailable extends \Zend\Validator\AbstractValidator implements DatabaseFormValidatorInterface
{
/**
* @var \Zend\Db\Sql\Sql
*/
private $database;
public function setDatabase( \Zend\Db\Sql\Sql $db )
{
$this->database = $db;
}
public function isValid( $value )
{
$DBA = $this->database->getAdapter();
// do the mixed database stuff here
return true;
}
}
最后,数组的表单字段验证器配置部分:
Lastly, the form field validator config part of the array:
'pin' => array(
'required' => true,
'filters' => array(
array('name' => 'alnum'),
array('name' => 'stringtrim'),
),
'validators' => array(
array( 'name' => 'LDP_PinAvailable' )
),
),
),
将它们拼凑在一起,加载表单,并在提交时使用下面的堆栈跟踪:
Piecing it all together, the form loads, and when submitted, it does with the stack trace below:
2013-10-28T17:09:35-04:00 ERR (3): Exception:
1: Zend\Validator\ValidatorPluginManager::get was unable to fetch or create an instance for LDP_PinAvailable
Trace:
#0 /Users/Saeven/Documents/workspace/Application/vendor/zendframework/zendframework/library/Zend/ServiceManager/AbstractPluginManager.php(103): Zend\ServiceManager\ServiceManager->get('LDP_PinAvailabl...', true)
#1 /Users/Saeven/Documents/workspace/Application/vendor/zendframework/zendframework/library/Zend/Validator/ValidatorChain.php(82): Zend\ServiceManager\AbstractPluginManager->get('LDP_PinAvailabl...', Array)
推荐答案
继续挖掘,我找到了问题所在.它在 Zend\Validator\ValidatorChain 大约第 80 行提取到这些行:
Digging some more, I've found the problem. It distilled to these lines in Zend\Validator\ValidatorChain circa line 80:
public function plugin($name, array $options = null)
{
$plugins = $this->getPluginManager();
return $plugins->get($name, $options);
}
上下文中没有可用的插件管理器.
There was no plugin manager available in context.
在控制器中准备表单时,谷歌搜索了大约三秒钟才发现必须这样做:
It took about three seconds of Googling to find that I had to do this when I prepared the form in the controller:
$validators = $this->getServiceLocator()->get('ValidatorManager');
$chain = new ValidatorChain();
$chain->setPluginManager( $validators );
$form->getFormFactory()->getInputFilterFactory()->setDefaultValidatorChain( $chain );
希望这对其他人有所帮助.以这种方式设置时,您可以使用常规的旧类名,无需扭曲类名.
Hopefully this helps someone else. You are able to use regular old classnames when setting it up this way, no need to warp the classnames.
这篇关于可以创建一个工厂来实例化自定义表单验证器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!