【问题标题】:php class not found while in (zend-based) include_path在(基于zend的)include_path中找不到php类
【发布时间】:2012-07-11 12:30:16
【问题描述】:

我有一个类,它位于 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());
    }
}

这给出了:-

[2012 年 7 月 11 日星期三 14:07:41] [错误] [客户端 127.0.0.1] PHP 致命错误:在线 /Library/WebServer/Foo/library/Form/Register.php 中找不到类“MyValidator_Usernameunique” 14、推荐人:http://foo/

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

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

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

【问题讨论】:

  • 抱歉,您是否正在寻找关于为什么您的类无法加载的答案或 Zend Framework 中自动加载的解释?您的帖子有点不清楚。
  • 确实,知道你是否自动加载也很重要

标签: php zend-framework zend-autoloader


【解决方案1】:

出于此答案的目的,我将忽略路径中“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());

它会自动加载。

请参阅manual 了解更多信息。

自动加载对你的表单起作用的原因是'Forms'目录被框架自动添加到自动加载器的包含路径中,所以它知道在哪里找到它。

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

【讨论】:

  • 感谢您的回答和时间,但我更喜欢下面的那个(对不起)。老实说,像“这将告诉 Zend Framework 在哪里寻找你的类”这样的句子。增加了混乱,因为他们根本没有解释命名空间是什么以及为什么它是必要的。对于我放入 php 的 include_path 中的文件夹,我可以说完全相同,那么命名空间是否等同于 include_path?不要这么想。当您事后似乎忽略了我的问题时,“请参阅手册”也有点奇怪,为什么这对 Form 有效,而对 MyValidator 无效。我在手册中没有找到相关内容。
  • @Herbert 我添加了一个小句子来回应您的评论。公平地说,我确实在对您的问题的评论中要求您澄清,但您没有回复。
  • 您给了我大约 15 分钟的时间来澄清,然后才从您的答案中的 zend-framework-documentation 重复。但是,您确实澄清了我需要注册名称空间,这是我以前不知道的。到目前为止,我仍然不清楚为什么它适用于表单但不适用于验证器:S 我想我将不得不忍受它:) 无论如何,谢谢你的努力。
【解决方案2】:

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

我有点期待关注 在您的 web 应用程序的路径中 (/Library/WebServer/Foo/)

  • 申请
    • 配置
    • 控制器
  • 图书馆
  • 公开

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

图书馆

  • 我的应用程序
    • 验证
      • Validator.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());

    }
}

【讨论】:

  • 那么,你说的是 zends 不是搜索类的所有 include_paths,而是先搜索命名空间,然后再搜索类?可能在“启动”时跟踪所有命名空间。然后你能说明为什么它适用于 Forms 吗?我自己在库文件夹中创建了这个文件夹,我没有在我的命名空间中配置它,但它确实有效:S 顺便说一句,我尝试了你的建议,它有效,因此我喜欢你的回答。我肯定会接受它,但最好在你解释为什么这对表格有效之后。 :) 谢谢!
  • Zend 在类路径中查找已注册的命名空间。
  • 类路径等于include_path?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-10
  • 2015-10-02
  • 2011-11-08
  • 1970-01-01
  • 2012-02-07
  • 2015-04-22
相关资源
最近更新 更多