smarty和PHP Google应用程序引擎的兼容性


smarty and PHP Google Application Engine compatibility

我需要在Google应用程序引擎的PHP环境中使用Smarty移植一个PHP应用程序。

审查开发指南:

"应用程序引擎应用程序不能:

写入文件系统。PHP应用程序可以使用谷歌云存储来存储持久文件。允许从文件系统读取,并且所有随应用程序上载的应用程序文件都可用。"

此限制是否适用于已编译的智能模板?因为编译会将它们写入文件系统。

我尝试在本地启动GAE,它很有效,但我无法尝试部署,因为我还没有访问生产环境的权限。

有消息吗?建议变通方法?

在smarty 3演示中,我修改了index.php,添加了以下两行:

$smarty->compile_dir="gs://achievotmp/compiled/";$smarty->cache_dir="gs://achievotmp/cache/";

smarty 3演示索引可在本地和GAE云中运行。(不要忘记创建bucket,例如:achievotmp)。

如谷歌应用程序引擎文档中所述,APC扩展已启用,因此您可以将其用作smarty的缓存管理器,如下所示:http://www.smarty.net/forums/viewtopic.php?t=16809

您可以在部署模板之前对其进行预编译-其想法是让脚本一次创建所有编译的文件-您必须每次执行它才能执行appcfg.py update .这将完全避免使用Google Storage!

以下是仅针对文件tpl资源的解决方案,但您可以对其进行修改,使其支持其他资源处理程序(例如,从数据库加载智能模板时)

Smarty模板目录必须包含相对路径,我们需要覆盖Smarty库中_realpath的行为,以便在不同的环境中具有相同的编译文件名。

这是build.php,用于构建目录app/Templates中的所有Smarty模板文件

require_once('libs/Smarty/libs/Smarty.class.php');
class SmartyCompileDir extends Smarty {
    public function _realpath($path, $realpath = null) {
        return $path;
    }
}
$smarty = new SmartyCompileDir;
$smarty->setCompileDir(__DIR__ . "/template_c");
// Template dir must be relative 
$smarty->setTemplateDir("app/Templates");
// make sure the escape html is enabled only if enabled in production!
$smarty->setEscapeHtml(false);
// empty compile directory
foreach (glob(__DIR__ . "/template_c/*.php") as $filename) {
    if (is_file($filename)) {
        unlink($filename);
    }
}
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator("app/Templates", FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS), RecursiveIteratorIterator::CHILD_FIRST) as $value) {
    if ($value->isFile()) {
        $file = (string)$value;
        $_smarty = clone $smarty;
        $_smarty->force_compile = true;
        $_tpl = new $smarty->template_class($file, $_smarty);
        $_tpl->caching = Smarty::CACHING_OFF;
        $_tpl->source = Smarty_Template_Source::load($_tpl);
        if ($_tpl->mustCompile()) {
            $_tpl->compileTemplateSource();
            echo ' compiled ' . $file . "'n";
            flush();
        } else {
            echo  ' ' . $file . ' is up to date' . "'n";
            flush();
        }
    }
}

构建完成后,您应该编译所有模板,如果您签出它们,它们应该在文件的头中有相对路径,例如7c3fc31b70e264e4d45f4ba59da830015ed4025f_0.file.index.tpl.php

/* Smarty version 3.1.29, created on 2016-07-28 13:52:49
  from "app/Templates/controls/column-tags.tpl" */

现在,在你的应用程序中初始化Smarty,就像这个

require_once(LIBS_DIR . "/Smarty/libs/Smarty.class.php");
class SmartyCompileDir extends 'Smarty {
    // this is to resolve all ../ to relative path - if you use smarty include function with relative path containing .. 
    public function _realpath($path, $realpath = null) {
        $parts = explode('/', $path);
        foreach($parts as $part) {
            if ($part == '.') {
                continue;
            } if ($part == '..') {
                array_pop($result);
            } else {
                $result[] = $part;
            }
        }
        return (implode('/', $result));
    }
}
$smarty = new SmartyCompileDir();
// relative path so we work fully from pre-compiled version
$smarty->setTemplateDir("app/Templates");
$smarty->setCompileDir(__DIR__ . "/template_c");
// do not check file modification time
$smarty->setCompileCheck(false);
// this must be set same as in the build script
$smarty->setEscapeHtml(false);
$smarty->display("index.tpl");

使用template_c目录将应用程序部署到GAE就是这样。

对于调试,您可以查看Smarty/libs/sysplugins/smarty_template_compiled.php的函数populateCompiledFilepath,了解Smarty是如何生成编译文件名的。