Zend Framework& PHPunit路径问题?

时间:2011-01-25 14:15:09

标签: php zend-framework path phpunit extend

当我扩展ZF类时,我得到路径错误。这是我的测试:

<?php
require_once ('Zend/Acl.php'); // gives error w/o
require_once ('../application/models/Acl.php');

class Model_AclTest extends ControllerTestCase
{

    /**
        * @var Model_Acl
        */
    protected $acl;

    public function setUp()
    {
        parent::setUp();
        $this->acl = new Model_Acl(2, 'sims');
    }

    public function testHasUsername()
    {
        echo $this->acl->username;
        $this->assert($this->acl->username);
    }
}

这是Model_Acl类:

class Model_Acl extends Zend_Acl
{
    private $username;
    private $userid;
    private $userroles;
    private $allroles;

    public function __construct($userid, $username)
    {
        if (method_exists(parent, '__construct')) parent::__construct();
        $this->username = $username;
        $this->userid = $userid;
        $this->setRoles();
        $this->setResources();
        $this->setPrivilages();
        return $this;
    }
...
}

我收到此错误,除非我需要'Zend / Acl.php'。

PHP Fatal error:  Class 'Zend_Acl' not found in /mnt/dev/mragent/application/models/Acl.php on line 6

所以我觉得可能还有一些东西还不太适合鼻烟,并继续这种轻微的不便。然后我从phpunit本身得到以下错误:

1) Model_AclTest::testHasUsername
Use of undefined constant parent - assumed 'parent'

/mnt/dev/mragent/application/models/Acl.php:14
/mnt/dev/mragent/tests/application/models/AclTest.php:18

我认为有些事情是错的。或者我做错了。

如何正确设置路径?

3 个答案:

答案 0 :(得分:2)

首先,您需要查看以下内容:

class Model_Acl extends Zend_Acl

这就是您需要以下内容的原因:

require_once ('Zend/Acl.php'); // gives error w/o

为了在不添加上述行的情况下工作,您需要设置包含路径,以便自动装带器可以找到直接位于“Zend”目录下的Acl.php文件。包含路径只需要包含作为“Zend”目录的父目录的目录。通常这将是您的“库”目录。

至于“父母”问题:

Use of undefined constant parent - assumed 'parent'

您看到这个是因为您有以下代码:

if (method_exists(parent, '__construct')) parent::__construct();

实际应该是:

if (method_exists(get_parent_class($this), '__construct')) parent::__construct();

您也可以写下以下内容:

method_exists(get_parent_class($this), '__construct') && parent::__construct();

这一点稍微简洁一点(尽可能用PHP获得)并且噪音稍微少一些。

原因是什么?

该行(最左边)的第一件事是“method_exists”,这是一个快速指示,这是我们关心的。线的最末端(最左边,除了分号)是最终结果。此外,&amp;&amp;通常是一个很好的指标,它应该只有一个声明。如果这发生了变化,很容易看出整个语句可能需要重新计算而不是在parent :: __ construct()之后附加另一个语句;

编辑:有关自动加载的更多信息:

在项目根目录中创建一个autoload.php.dist文件(替换'/ PATH / TO / YOUR / PHP5 / LIB / DIR'):

<?php /* autoload.php.dist */

$includePaths = array( realpath('/PATH/TO/YOUR/PHP5/LIB/DIR'), get_include_path());
set_include_path( join(\PATH_SEPARATOR, $includePaths) );

spl_autoload_register(function($className) {
    $className = ltrim($className, '\\');
    $fileName  = '';
    $namespace = '';
    if ($lastNsPos = strripos($className, '\\')) {
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    }
    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
    require $fileName;
}, true, true);

创建一个可以重复使用的引导程序(bootstrap.php)

<?php /* bootstrap.php */
if (file_exists($file = __DIR__.'/autoload.php')) {
    require_once $file;
} elseif (file_exists($file = __DIR__.'/autoload.php.dist')) {
    require_once $file;
}

创建一个phpunit.xml.dist文件,该文件使用你的bootstrap.php(替换'./your/test/directory/here'):

<?xml version="1.0" encoding="UTF-8"?>
<!-- phpunit.xml.dist -->
<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         colors="false"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false"
         syntaxCheck="false"
         bootstrap="./bootstrap.php"
>
    <testsuites>
        <testsuite name="Test Suite">
            <directory>./your/test/directory/here</directory>
        </testsuite>
    </testsuites>
</phpunit>

现在您可以从根项目目录运行phpunit。

答案 1 :(得分:1)

您必须使用自动加载器将类名Zend_Acl转换为文件路径Zend / Acl.php。这应该放在你的PHPUnit bootstrap.php文件中。 Zend Framework提供了一个易于使用的自动加载器。

require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();

Zend和ZendX“名称空间”会自动注册。如果您想注册自己的“命名空间”,请使用:

$loader->registerNamespace('MyNamespace_');

如果您愿意,您当然可以使用自己的自动加载功能,但由于您已经在使用Zend Framework,因此它似乎是一条好路线。

BTW,“命名空间”周围的引号是表示这些不是真正的PHP名称空间,而是表示将下划线之间的部分转换为目录名称的类命名约定。

答案 2 :(得分:0)

我只是张贴这个,所以其他人会找到答案:

我不得不升级到PHPunit 3.4。 PHPunit 3.2忽略xml文件中指定的引导程序文件。也许这个功能当时没有实现。之后,所有按预期工作,在Zend_Application被引导后,我不需要从我的项目或php路径中要求任何文件。