当我扩展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
我认为有些事情是错的。或者我做错了。
如何正确设置路径?
答案 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路径中要求任何文件。