1

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

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

<?php

use Project\Bundle\Metadata\AbstractMetadata;

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

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

4

1 回答 1

0

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

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

我制作了一个可以从代码中的任何位置调用的管理器类。此类包含一个方法,该方法在缓存文件夹中返回该类的实例。

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类,仅仅是因为它处理文件写入和文件权限。此外,如果文件不存在,它将调用闭包。在这种情况下,闭包调用处理数据加载并将其转换为 PHP 代码的类。然后加载缓存文件require_once并返回 的实例LocalizedMetadata,它是缓存的类名。

上面的方法可以修改为也将资源文件传递给 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();
    }
}

我还想指出,可以在缓存文件中使用命名空间。

于 2016-02-05T16:49:46.973 回答