在(基于zend的)include_path中找不到php类


php class not found while in (zend-based) include_path

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

<?php echo get_include_path(); ?>

/Library/WebServer/Foo/application//库:/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致命错误:在第14行的/Library/WebServer/Foo/Library/Form/Register.PHP中找不到类"MyValidator_Usernameunique",referr:http://foo/

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

当然,这是很自然的,因为/Library/WebServer/Foo/Library/MyValidator/不在我的php include_path中,并且我没有"要求"、"包括"或"要求一次"文件。然而,据我所知,zend框架应该通过将_替换为/并搜索include_path来自动加载文件。这对于注册表单来说似乎很好,但对于验证器来说却失败了。为什么会这样?情况几乎相同。此外,当我尝试直接在控制器类中创建MyValidator_Usernameunique并返回相同的错误消息时,它也会失败。

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

为了这个答案的目的,我将忽略您路径中‘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());

它将自动加载。

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

自动加载适用于表单的原因是"Forms"目录由框架自动添加到自动加载程序包含路径中,因此它知道在哪里可以找到它。

正如您所猜测的,自动加载的方法是用"_"代替"/",然后从生成的路径加载类。但是,默认路径以外的路径需要在application.ini中"注册",如我的示例所示。看看Zend/Loader/Autoloader.php中的代码,了解实际情况。

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

我有点期待跟随在您的网络应用程序(/Library/WebServer/Foo/)的路径中

  • 应用程序
    • configs
    • 控制器
    • 等等
  • 图书馆
  • 公众

现在你想把验证器添加到你的库中,我会像一样做

  • MyApp
    • 验证
      • 验证器.php

内部验证器.php

class MyApp_Validate_Validator extends Zend_Validate_Abstract
{
    //Do stuff here
}

既然我们在库中有了这个额外的部分,我们需要告诉zend,我们有一个额外的名称空间,里面有我们自己的代码

所以在application.ini中,您可以像这样配置

autoloaderNamespaces.0 = MyApp_

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

所以你现在可以做下面的

创建一个表单(最好将其放在应用程序/表单中/但这当然取决于您)

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