从其他名称空间找不到PHP类

时间:2014-02-17 04:19:29

标签: php symfony classnotfound phpspec

我目前正在使用Phpspec开发Symfony2项目,而且我在扩展不同命名空间中描述的Spec类时遇到了问题。

例如,在我的项目中,我在spec/Acme/Model/Foo/FooSpec.php中描述了以下类:

namespace spec\Acme\Model\Foo;

use PhpSpec\ObjectBehavior;
use Prophecy\Argument;

abstract class FooSpec extends ObjectBehavior{
    //some code here
}

我在spec/Acme/Model/Bar/BarSpec.php扩展了FooSpec

namespace spec\Acme\Model\Bar;

use spec\Acme\Model\Foo\FooSpec;

class BarSpec extends FooSpec{
    //some code here
}

当我尝试运行phpspec时,出现以下错误:

PHP Fatal error: Class 'spec\Acme\Model\Foo\FooSpec' not found in /home/user/Projects/Acme/spec/Acme/Model/Bar/BarSpec.php on line 9

我发现让它发挥作用的唯一方法是在spec/Acme/Model/Bar/BarSpec.php中添加以下行:

include('./spec/Acme/Model/Foo/FooSpec.php');

我不知道为什么必须包含此特定文件才能使其运行,尤其是在正确找到其他类(如PhpSpec\ObjectBehavior)时。

你知道为什么会这样吗?


编辑:

正如@Phil和@Sheikh Heera在评论中所建议的那样,我尝试设置一个autoload来注册我的spec命名空间,但它不能正常工作。这是我到目前为止所尝试的:

require_once getcwd() . '/vendor/composer/ClassLoader.php';

$loader = new \Composer\Autoload\ClassLoader();

// register classes with namespaces
$loader->add('spec', getcwd().'/spec');

// activate the autoloader
$loader->register();

我还尝试修改文件vendor/composer/autoload_namespaces.php以添加此内容:

return array(
    //some code here

    'spec' => array(getcwd() . '/spec'),
    //some more code

);

但仍然是同样的错误。我还尝试了'spec' => array(getcwd())$loader->add('spec', getcwd());,看看会发生什么,这次我在另一个规范类上得到Cannot redeclare class


我的php版本是PHP 5.4.9-4ubuntu2.4 (cli)

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

更通用的解决方案是将spec目录放入composer.json的autoload-dev配置中:

"autoload-dev": {
    "psr-0": {
        "spec\\":""
    }
},

这样,作曲家也会为规范生成命名空间,规范应位于存储库的根目录下:

return array(
     'spec\\' => array($baseDir . '/'),
     ...
);

答案 1 :(得分:0)

最后,正如Phil和Sheikh Heera在评论中所建议的那样,我实际上“解决”我的“问题”的做法是自动加载我的命名空间,以便它被规范识别。

以下是我的工作:

     
  • 我将以下行添加到`vendor / composer / autoload_namespaces.php`文件中:
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
    //some code
    'spec\\Acme\\Behavior' => array(getcwd()),
    //some code
);
  • 然后我创建了以下文件夹结构:
    │── spec
    │  └── Acme
    │     └── Behavior
    │        └── FooBehavior.php
  • 我用这种方式在`spec / Acme / Behavior / FooBehavior.php`中声明了命名空间:
namespace spec\Acme\Behavior;
  • 在`spec / Acme / Model / Bar / BarSpec.php`中使用它如下:
use spec\Acme\Behavior\FooBehavior;

class BarSpec extends FooBehavior{
    //...
}

我知道这不是最好的做法,因为每当有人在这个项目上工作时,它必须手动重现第一步。因此,如果您有任何更好的想法,请随时发表评论或发布答案。