1

我目前正在使用 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来注册我的规范命名空间,但它也不起作用。这是我到目前为止所尝试的:

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).

预先感谢您的帮助。

4

2 回答 2

1

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

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

这样,composer 也会为规范生成命名空间,该命名空间应该位于存储库的根目录中:

return array(
     'spec\\' => array($baseDir . '/'),
     ...
);
于 2015-01-07T10:59:28.013 回答
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
);
  • 然后我创建了以下文件夹结构:
    │── 规格
    │ └── Acme
    │ └── 行为
    │ └── 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{
    //...
}

我知道这不是最佳实践,因为每次有人从事这个项目时,第一步都必须手动复制。因此,如果您有更好的想法,请随时发表评论或发布答案。

于 2014-02-19T04:31:25.327 回答