PSR-4代码库中的理论生成器的解决方法 [英] Workaround for doctrine generator in PSR-4 codebase

查看:89
本文介绍了PSR-4代码库中的理论生成器的解决方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Symfony 2&我正在尝试在Windows机器上的学说

With Symfony 2 & Doctrine on a Windows machine I'm trying to


  1. 从现有架构生成实体:

  1. generate entities from an existing schema:

php应用程序/控制台原则:mapping:import --force CoreBundle批注

为其生成getter / setter:

generate getters/setters on them:

php应用程序/控制台学说:generate:entities --path = / path / to / codebase / src / MyProject / CoreBundle / Entities CoreBundle

使用在其上生成REST CRUD控制器.com / voryx / restgeneratorbundle rel = nofollow> Voryx

php应用/控制台voryx:generate:rest- -entity = CoreBundle:User

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

The first steps works fine and I can find the entities in my CoreBundle/Entity folder with the correct namespace:

MyVendor\MyProject\CoreBundle\Entity

到目前为止很好。
但是,运行其他2条命令将失败:

Good so far. However, running the other 2 commands will fail:

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

composer.json中的自动加载看起来像这样:

The autoload in my composer.json looks like this:

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

我发现 Doctrine无法处理PSR-4名称空间,这可能是使其失败的原因。

I found out that Doctrine can't deal with PSR-4 namespaces, that's probably what makes it fail.

我真的希望这些实体住在PSR-4 CoreBundle中-有解决方法吗?

I would really like the entities to live in the PSR-4 CoreBundle though - is there a workaround for it?

我尝试了此方法,但是没有t工作,或者:

I tried this, but it doesn't work, either:

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

谢谢。

推荐答案

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

User janvennemann on GitHub fixed Doctrine for PSR-4. You can find the patch on Gist, or linked here below


  1. mkdir -p app / VendorOverride ;

  2. cp vendor / doctrine / doctrine-bundle / Mapping / DisconnectedMetadataFactory.php app / VendorOverride / DisconnectedMetadataFactory.php ;
  3. 应用DisconnectedMetadataFactory补丁;

  4. app / VendorOverride 添加到 composer.json 中的classmap 部分;

  5. 运行 composer dump-autoload

  1. mkdir -p app/VendorOverride;
  2. cp vendor/doctrine/doctrine-bundle/Mapping/DisconnectedMetadataFactory.php app/VendorOverride/DisconnectedMetadataFactory.php;
  3. apply the DisconnectedMetadataFactory patch;
  4. add app/VendorOverride to the classmap section in composer.json;
  5. run composer dump-autoload.

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

Then almost all scaffolding command works.

/**
 * 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();
}

这篇关于PSR-4代码库中的理论生成器的解决方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆