如果模板存储在数据库中,则大量查询,或者从缓存中删除时出错

时间:2014-07-03 14:23:34

标签: templates symfony twig

通过在this answer中找到的数据库中存储一些模板,数据库查询的数量会大大增加。例如,分析器显示页面上20个查询中的12个与搜索模板有关,尽管没有一个存储在数据库中。我的印象是只有在文件结构中没有模板时才进行搜索。是否有方法仅在所需模板不在文件结构中时才查询数据库?

更新1:

实验表明,注释tags服务的vol.volbundle.twig_database_loader部分可以消除不必要的查询,但仍然可以在数据库中找到模板。如果没有tags块,则会发生以下错误

  

InvalidArgumentException:模板名称" new_opp"无效(格式   是" bundle:section:template.format.engine"

编辑模板时,持久化并尝试使用以下代码从缓存中删除其前任。 [当存在tags块时,将删除缓存的模板!]这似乎是这种情况,因为tags块允许在缓存删除期间找到数据库加载器。

    $fileCache = $this->container->get('twig')->getCacheFilename($name);
    if (is_file($fileCache)) {
        @unlink($fileCache);
    } 

因此,奇怪的是,当块不存在时,控制器会使用数据库加载器。

services.yml

vol.volbundle.twig_database_loader:
    class: Vol\VolBundle\Tools\TwigDatabaseLoader
    arguments: [@doctrine.orm.entity_manager]
    tags:
        - { name: twig.loader }

TwigDatabaseLoader

namespace Vol\VolBundle\Tools;
use \Twig_Error_Loader;
/**
 * Description of DatabaseTwigLoader
 *
 */
class TwigDatabaseLoader implements \Twig_LoaderInterface
{

    private $entityManager;

    public function __construct($entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function getSource($name)
    {
        if (false === $source = $this->getValue('source', $name)) {
            throw new Twig_Error_Loader(sprintf('Template "%s" does not exist.', $name));
        }

        return $source;
    }

    public function isFresh($name, $time)
    {
        if (false === $lastModified = $this->getValue('last_modified', $name)) {
            return false;
        }

        return $lastModified <= $time;
    }

    public function getCacheKey($name)
    {
// check if exists
        return 'db:' . $name;
    }
    protected function getValue($column, $name)
    {
        $conn = $this->entityManager->getConnection();
        $sth = $conn->prepare('SELECT '.$column.' FROM template WHERE name = :name');
        $sth->execute(array(':name' => (string) $name));

        return $sth->fetchColumn();
    }
}

编译器

namespace Vol\VolBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;

/**
 * Description of TwigDatabaseLoaderPass
 *
 */
class TwigDatabaseLoaderPass implements CompilerPassInterface
{

    public function process(ContainerBuilder $container)
    {
        $definition = $container->getDefinition('twig');
        $definition->addMethodCall('setLoader', array(new Reference('vol.volbundle.twig_database_loader')));
    }
}

1 个答案:

答案 0 :(得分:0)

事实证明,大量查询仅在开发模式下发生!这是通过在MySQL中启用查询日志来确定的。执行模板编辑然后渲染然后查看日志表明只有存储的模板调用模板查询。查询日志中没有出现其他模板。结案!