如何解决 Symfony3 中自动生成的 类

How to resolve auto generated classes in Symfony3

在使用 psr 4 的 Symfony3 项目中,我通过在 'var/cache/dev' 文件夹中自动生成 php class 来存储配置数据。

这是生成文件的简化副本:

<?php

use Project\Bundle\Metadata\AbstractMetadata;

class LocalizedMetadata extends AbstractMetadata
{
    protected function populate ()
    {
    }
}

我知道我可以 includerequire 文件,但是 'dev' 目录在开发和生产之间变化,我在几个地方使用 class。另外,我希望在其他项目中使用这个包,所以我不想在包之外硬编码任何东西。这些文件通常是如何加载的? Symfony 核心中有什么可以提供帮助的吗?

在 'dev' 目录中创建的任何 classes 都不能自动加载,至少在没有配置包外部文件的情况下不能自动加载(例如 composer.yml)。

我研究了 Symfony 如何管理它的路由器文件,解决方案实际上非常简单。

我做了一个管理器 class 可以从代码中的任何地方调用它。此 class 包含一个方法,该方法 returns 缓存文件夹中 class 的一个实例。

public function getLocalizedRoutes ()
{
    if ( null !== $this->localizedRoutes ) {
        return $this->localizedRoutes;
    }

    $cache = $this->getConfigCacheFactory()->cache(
        $this->options['cache_dir'].'/'.CachingMetadata::CACHE_FILE,
        function (ConfigCacheInterface $cache) {
            $content = CachingMetadata::getInstance()->dump();
            $cache->write($content);
        }
    );

    require_once $cache->getPath();

    return $this->localizedRoutes = LocalizedMetadata::getInstance();
}

它使用 Symfony 的内置 ConfigCache class,只是因为它处理文件写入和文件权限。此外,如果文件不存在,它将调用闭包。在这种情况下,闭包调用 class 处理数据加载并将其转换为 PHP 代码。然后用 require_once 加载缓存文件并返回 LocalizedMetadata 的实例,这是缓存的 class 名称。

上面的方法可以修改为也将资源文件传递给ConfigCache,这样如果你的文件之一被修改,缓存将被重写。就我而言,这不是必需的。

使用缓存预热器使其工作只需要调用上述方法:

class RouteCacheWarmer implements CacheWarmerInterface
{
    private $_manager;

    public function __construct ( LocaleManager $manager )
    {
        $this->_manager = $manager;
    }

    public function isOptional ()
    {
        return true;
    }

    public function warmUp ( $cacheDir )
    {
        $this->_manager->getLocalizedRoutes();
    }
}

我还要注意,可以在缓存文件中使用命名空间。