1

我有一个类,它位于 zend 项目中我的库文件夹的子目录中。所以假设我的应用程序在 /Library/WebServer/Foo/ 中,那么 php 的包含路径是:

<?php echo get_include_path(); ?>

/Library/WebServer/Foo/application/../library:/Library/WebServer/Foo/library:/usr/share/zend-framework/library/

所以现在我想创建这个类,忽略随机逻辑,我应该能够通过说“new MyValidator_Usernameunique()”或类似的话来达到它:

/Library/WebServer/Foo/library/MyValidator/Usernameunique.php

class MyValidator_Usernameunique extends Zend_Validate_Abstract
{
     const USERNAME_ALREADY_EXISTS = 'usernameAlreadyUsed';
     const DATABASE_FAILED = 'userDatabaseFailure';

     protected $_messageTemplates = array(
         self::USERNAME_ALREADY_EXISTS => "De gebruikersnaam '%value%' is al in gebruik, gebruik een andere."
         self::DATABASE_FAILED => "Er ging iets mis bij het verbinden met de database."
     );

    public function isValid($value)
    {
        $magic = rand(0,3)
        if($magic==0) {
            $this->_error(self::USERNAME_ALREADY_EXISTS);
            return false;
        }
        if($magic==1) {
            $this->_error(self::DATABASE_FAILED);
            return false;
        }
        return true;
    }
}

所以我就是这样做的:

/Library/WebServer/Foo/library/Form/Register.php

class Form_Register extends Form_FooForm 
{
    public function __construct() 
    {
        parent::__construct();
        $username = $this->createText('username', 'Gebruikersnaam')->setRequired(true);
        $username->addValidator(new MyValidator_Usernameunique());
    }
}

这使:-

[Wed Jul 11​​ 14:07:41 2012] [error] [client 127.0.0.1] PHP Fatal error: Class 'MyValidator_Usernameunique' not found in /Library/WebServer/Foo/library/Form/Register.php on line 14, referer :http://foo/

忽略行号,因为我稍微简化了代码。

当然,这很自然,因为 /Library/WebServer/Foo/library/MyValidator/ 不在我的 php include_path 中,而且我没有“要求”或“包含”或“要求一次”文件。然而,据我了解,zend 框架应该通过将 _ 替换为 / 并搜索 include_path 来自动加载文件。这似乎适用于注册表单,但对于验证器失败。现在,这是为什么呢?这几乎是相同的场景。此外,当我尝试直接在具有相同错误消息的控制器类中创建 MyValidator_Usernameunique 时,它​​也会失败。

任何关于为什么会发生这种情况的想法或指示都非常感谢。此外,请注意,我并不是要修复这个错误,而是要更好地理解 zend 中的自动加载。所以请不要提出使用我的验证器多余的解决方案。

4

2 回答 2

3

出于此答案的目的,我将忽略您路径中“Foo”之上的所有内容,因为它无关紧要。

为了让您的验证器自动加载,您需要做几件事。

首先,您需要创建一个文件夹“Foo/library/My”,然后将以下行添加到您的 application.ini 文件中:-

autoloadernamespaces[] = "My_"

这将告诉 Zend Framework 在哪里寻找您的类。

接下来创建文件夹“Foo/library/My/Validator”,然后在该文件夹中创建“Usernameunique.php”,它应该如下所示:-

class My_Validator_Usernameunique extends  Zend_Validate_Abstract
{
    //All your class stuff goes here.
}

然后当你这样做时: -

$username->addValidator(new My_Validator_Usernameunique());

它会自动加载。

有关详细信息,请参阅手册

自动加载适用于您的表单的原因是“表单”目录被框架自动添加到自动加载器包含路径中,因此它知道在哪里可以找到它。

如您所料,自动加载的工作原理是将 '_' 替换为 '/',然后从生成的路径加载类。但是,默认路径以外的路径需要在 application.ini 中“注册”,如我的示例所示。查看 Zend/Loader/Autoloader.php 中的代码以了解实际发生的情况。

于 2012-07-11T12:47:36.210 回答
1

查看您的代码,我可能会错过它,但这并不是真正的“标准”zend 布局

我有点期待跟随你的 webapp (/Library/WebServer/Foo/)

  • 应用
    • 配置
    • 控制器
    • ETC
  • 图书馆
  • 上市

现在您想将验证器添加到您的库中,我会这样做

图书馆

  • 我的应用
    • 证实
      • 验证器.php

Validator.php 内部

class MyApp_Validate_Validator extends Zend_Validate_Abstract
{
    //Do stuff here
}

现在我们在库中有这个额外的部分,我们需要告诉 zend 我们有一个额外的命名空间,其中包含我们自己的代码

所以在 application.ini 你像这样配置它

autoloaderNamespaces.0 = MyApp_

现在应用程序(zend)应该知道在哪里寻找你的验证器

所以您现在可以执行以下操作

创建一个表单(最好将其放在 application/forms/ 中,但当然取决于您)

class Form_Register extends Zend_Form {

    public function __construct() {
        parent::__construct();

        $username = $this->createText('username', 'Gebruikersnaam')
        ->setRequired(true)
        ->addValidator(new MyApp_Validate_Validator());

    }
}
于 2012-07-11T13:02:22.863 回答