3

在 Windows 机器上使用 Symfony 2 & Doctrine 我正在尝试

  1. 从现有模式生成实体:

    php app/console doctrine:mapping:import --force CoreBundle annotation

  2. 在它们上生成 getter/setter:

    php app/console doctrine:generate:entities --path=/path/to/codebase/src/MyProject/CoreBundle/Entities CoreBundle

  3. 使用Voryx在它们上生成 REST CRUD 控制器:

    php app/console voryx:generate:rest --entity="CoreBundle:User"

第一步工作正常,我可以在我的 CoreBundle/Entity 文件夹中找到具有正确命名空间的实体:

MyVendor\MyProject\CoreBundle\Entity

目前很好。但是,运行其他 2 个命令将失败:

[RuntimeException]
Can't find base path for "CoreBundle" (path: 
"\path\to\codebase\src\MyProject\CoreBundle", destination: 
"/path/to/codebase/src/MyProject/CoreBundle").  

我的 composer.json 中的自动加载如下所示:

"autoload": {
    "psr-4": {
        "MyVendor\\": "src/"
    }
},

我发现Doctrine 无法处理 PSR-4 namespaces,这可能是它失败的原因。

不过,我真的很希望实体生活在 PSR-4 CoreBundle 中 - 是否有解决方法?

我试过这个,但它也不起作用:

"autoload": {
    "psr-0": {
        "MyVendor\\MyProject\\CoreBundle\\Entity": "src/MyProject/CoreBundle/Entity/"
    },
    "psr-4": {
        "MyVendor\\": "src/"
    }
},

谢谢你。

4

2 回答 2

5

GitHub 上的用户 janvennemann 为 PSR-4 修复了 Doctrine。您可以在 Gist 上找到补丁,或在下面链接

修复它的步骤

  1. mkdir -p app/VendorOverride;
  2. cp vendor/doctrine/doctrine-bundle/Mapping/DisconnectedMetadataFactory.php app/VendorOverride/DisconnectedMetadataFactory.php;
  3. 应用 DisconnectedMetadataFactory 补丁;
  4. 添加app/VendorOverride到中的classmap部分composer.json
  5. 运行composer dump-autoload

然后几乎所有的脚手架命令都有效。

DisconnectedMetadataFactory PSR-4 补丁

/**
 * Get a base path for a class
 *
 * @param string $name      class name
 * @param string $namespace class namespace
 * @param string $path      class path
 *
 * @return string
 * @throws \RuntimeException When base path not found
 */
private function getBasePathForClass($name, $namespace, $path)
{
    $composerClassLoader = $this->getComposerClassLoader();
    if ($composerClassLoader !== NULL) {
        $psr4Paths = $this->findPathsByPsr4Prefix($namespace, $composerClassLoader);
        if ($psr4Paths !== array()) {
            // We just use the first path for now
            return $psr4Paths[0];
        }
    }

    $namespace = str_replace('\\', '/', $namespace);
    $search = str_replace('\\', '/', $path);
    $destination = str_replace('/'.$namespace, '', $search, $c);

    if ($c != 1) {
        throw new \RuntimeException(sprintf('Can\'t find base path for "%s" (path: "%s", destination: "%s").', $name, $path, $destination));
    }

    return $destination;
}

/**
 * Gets the composer class loader from the list of registered autoloaders
 *
 * @return \Composer\Autoload\ClassLoader
 */
private function getComposerClassLoader() {
    $activeAutloaders = spl_autoload_functions();
    foreach($activeAutloaders as $autoloaderFunction) {
        if (!is_array($autoloaderFunction)) {
            continue;
        }

        $classLoader = $autoloaderFunction[0];
        if ($classLoader instanceof \Symfony\Component\Debug\DebugClassLoader) {
            $classLoader = $classLoader->getClassLoader()[0];
        }

        if (!is_object($classLoader)) {
            continue;
        }

        if ($classLoader instanceof \Composer\Autoload\ClassLoader) {
            return $classLoader;
        }
    }

    return NULL;
}

/**
 * Matches the namespace against all registered psr4 prefixes and
 * returns their mapped paths if found
 *
 * @param string $namespace The full namespace to search for
 * @param \Composer\Autoload\ClassLoader $composerClassLoader A composer class loader instance to get the list of psr4 preixes from
 * @return array The found paths for the namespace or an empty array if none matched
 */
private function findPathsByPsr4Prefix($namespace, $composerClassLoader) {
    foreach ($composerClassLoader->getPrefixesPsr4() as $prefix => $paths) {
        if (strpos($namespace, $prefix) === 0) {
            return $paths;
        }
    }

    return array();
}
于 2016-02-09T16:34:52.687 回答
1

如果有人遇到这个问题..我终于成功了。我不太确定到底是什么修复了它,所以这里是我所做的所有步骤:

  1. 当我运行 Symfony 2.3 时,首先我升级到 2.7
  2. 我从头开始重新生成包...我将包的位置更改MyProject\CoreBundle为并将包类重命名为 MyProjectCoreBundle。

我现在可以成功运行所有这些命令:

php app/console doctrine:mapping:import --force MyProjectCoreBundle annotation
php app/console doctrine:generate:entities MyProjectCoreBundle
php app/console doctrine:generate:form MyProjectCoreBundle:User
php app/console voryx:generate:rest --entity=MyProjectCoreBundle:User       

(请注意,调用doctrine:generate:form不在 OP 中。)

我最好的猜测是升级的一个步骤是更改作曲家自动加载——这个,或者 2.7 自动加载器,似乎已经修复了它:

"autoload": {
    "psr-4": { "": "src/", "SymfonyStandard\\": "app/" }
},
于 2015-07-13T04:01:35.583 回答