我尝试从ZF2迁移到ZF3,但许多 viewHelpers和验证器不起作用。但只有那些覆盖ZendFrameworks viewhelpers / 验证器的人才能工作......
我想要f.e.覆盖CSRF验证器以默认允许更高的超时。
我有以下应用程序配置:
$config = array(
// This should be an array of module namespaces used in the application.
'modules' => array(
'Zend\Cache',
'Zend\Db',
'Zend\Log',
'Zend\Mail',
'Zend\Mvc\Console',
'Zend\Mvc\I18n',
'Zend\I18n',
'Zend\Mvc\Plugin\FilePrg',
'Zend\Form',
'Zend\Hydrator',
'Zend\InputFilter',
'zend\Form',
'Zend\Filter',
'Zend\Mvc\Plugin\FlashMessenger',
'Zend\Mvc\Plugin\Identity',
'Zend\Mvc\Plugin\Prg',
'Zend\Navigation',
'Zend\Paginator',
'Zend\Serializer',
'Zend\ServiceManager\Di',
'Zend\Session',
'Zend\Router',
'Zend\Validator',
'DoctrineModule',
'DoctrineORMModule',
'TwbBundle',
'AssetManager',
#'Reliv\ElFinder',
'ZfcUser', //https://github.com/ZF-Commons/ZfcUser
'ZfcUserDoctrineORM',
'BjyAuthorize', // https://github.com/bjyoungblood/BjyAuthorize
'Base',
'Product',
'Blog',
'Admin'
),
// These are various options for the listeners attached to the ModuleManager
'module_listener_options' => array(
// This should be an array of paths in which modules reside.
// If a string key is provided, the listener will consider that a module
// namespace, the value of that key the specific path to that module's
// Module class.
'module_paths' => array(
'./module',
'./vendor',
),
// An array of paths from which to glob configuration files after
// modules are loaded. These effectively override configuration
// provided by modules themselves. Paths may use GLOB_BRACE notation.
'config_glob_paths' => array(
'config/autoload/{,*.}{global,local}.php',
),
// Whether or not to enable a configuration cache.
// If enabled, the merged configuration will be cached and used in
// subsequent requests.
// 'config_cache_enabled' => true,
// The key used to create the configuration cache file name.
//'config_cache_key' => $stringKey,
// Whether or not to enable a module class map cache.
// If enabled, creates a module class map cache which will be used
// by in future requests, to reduce the autoloading process.
// 'module_map_cache_enabled' => true,
// The key used to create the class map cache file name.
#'module_map_cache_key' => $stringKey,
// The path in which to cache merged configuration.
'cache_dir' => "data/cache/",
// Whether or not to enable modules dependency checking.
// Enabled by default, prevents usage of modules that depend on other modules
// that weren't loaded.
// 'check_dependencies' => true,
),
// Used to create an own service manager. May contain one or more child arrays.
//'service_listener_options' => array(
// array(
// 'service_manager' => $stringServiceManagerName,
// 'config_key' => $stringConfigKey,
// 'interface' => $stringOptionalInterface,
// 'method' => $stringRequiredMethodName,
// ),
// )
// Initial configuration with which to seed the ServiceManager.
// Should be compatible with Zend\ServiceManager\Config.
// 'service_manager' => array(),
);
基本模块的模块配置:
namespace Base;
...
return [
...
'validators' => array(
'invokables' => [
\Zend\Validator\Csrf::class => Validator\Csrf::class
]
)
...
]
基础\验证\ CSRF:
<?php
namespace Base\Validator;
class Csrf extends \Zend\Validator\Csrf
{
protected $timeout = 1;
public function __construct($options = [])
{
parent::__construct($options);
die("THIS DOES NOT GETTING PRINTED! NOR DOES THE BREAKPOINT HIT.");
}
}
编辑:添加了自动加载配置
composer.json:
"autoload": {
"psr-4": {
"Base\\": "module/Base/src/"
}
}
编辑2:\ Zend \ Form \ Element \ Csrf的实现可能出现错误?
有趣的是,CsrfValidator只是直接在这里实例化了......
/**
* Get CSRF validator
*
* @return CsrfValidator
*/
public function getCsrfValidator()
{
if (null === $this->csrfValidator) {
$csrfOptions = $this->getCsrfValidatorOptions();
$csrfOptions = array_merge($csrfOptions, ['name' => $this->getName()]);
$this->setCsrfValidator(new CsrfValidator($csrfOptions));
}
return $this->csrfValidator;
}
Stacktrace(\ Zend \ Validator \ Csrf __construct()中的断点)
StaticPage
是我的另一个模块。
我还使用xdebug进行了调试,并在CsrfFactory(return语句)中设置了一个断点,以查看是否使用了(但它不是)。 我想我可以在ZF3中轻松覆盖服务/验证器......我有没有想念?
答案 0 :(得分:2)
在实例化元素时,可以使用委托者更改附加到表单元素的验证器。本质上,一个委托人允许你(在这种情况下)在构造之后修改表单元素 - 这个想法得到了很好的解释here。
在您的情况下,您将创建一个类:
<?php
namespace Base\Delegator;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\DelegatorFactoryInterface;
use Zend\Validator\Csrf as CsrfValidator;
class CsrfDelegatorFactory implements DelegatorFactoryInterface
{
public function createDelegatorWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName, $callback)
{
// construct the Csrf form element
$element = call_user_func($callback);
// set the validator with chosen timeout and other options
$element->setCsrfValidator(new CsrfValidator(
[
// ...
'timeout' => 10000
]
));
return $element;
}
}
然后将委托者映射到应用程序module.config.php中的Zend\Form\Element\Csrf
:
'form_elements' => [
// ...
'delegators' => [
\Zend\Form\Element\Csrf::class => [
0 => \Base\Delegator\CsrfDelegatorFactory::class
],
]
],
请注意,这只会将默认情况下分配的验证程序更改为Zend\Form\Element\Csrf
,并且不会影响通过其他方式获得的csrf验证程序。