0

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

审查开发指南:

“App Engine 应用程序不能:

写入文件系统。PHP 应用程序可以使用 Google Cloud Storage 来存储持久文件。允许从文件系统读取,并且所有随应用程序上传的应用程序文件都可用。”

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

我尝试在本地启动 GAE 并且它可以工作,但我无法尝试部署,因为我还没有访问生产环境。

有人有这方面的消息吗?建议?解决方法?

4

3 回答 3

1

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

于 2013-07-22T12:28:17.343 回答
1

在 smarty 3 演示中,我修改了 index.php 添加这 2 行:

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

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

于 2013-10-17T15:55:06.057 回答
0

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

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

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

这是构建目录中所有 Smarty 模板文件的 build.phpapp/Templates

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 就是这样。

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

于 2016-07-28T12:12:35.017 回答