mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-05 10:54:27 +02:00
- use output buffers for better performance and less memory usage
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
- load seldom used Smarty API methods dynamically to reduce memory footprint
|
||||
- cache template object of {include} if same template is included several times
|
||||
- convert debug console processing to object
|
||||
- use output buffers for better performance and less memory usage
|
||||
|
||||
06.08.2015
|
||||
- avoid possible circular object references caused by parser/lexer objects
|
||||
|
@@ -817,7 +817,22 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
// set caching in template object
|
||||
$_template->caching = $this->caching;
|
||||
// fetch template content
|
||||
return $_template->render(true, false, $display);
|
||||
$level = ob_get_level();
|
||||
try {
|
||||
$_smarty_old_error_level = isset($this->error_reporting) ? error_reporting($this->error_reporting) : null;
|
||||
ob_start();
|
||||
$result = $_template->render(true, false, $display);
|
||||
if (isset($_smarty_old_error_level)) {
|
||||
error_reporting($_smarty_old_error_level);
|
||||
}
|
||||
return $result === null ? ob_get_clean() : $result;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
while (ob_get_level() > $level) {
|
||||
ob_end_clean();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -282,9 +282,11 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||
//$compiler->suppressNocacheProcessing = true;
|
||||
}
|
||||
if (isset($_assign)) {
|
||||
$_output .= " \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_Variable(\$_smarty_tpl->getInlineSubTemplate({$include_file}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, {$_cache_tpl}, '{$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['func']}'));\n";
|
||||
$_output .= "ob_start();\n";
|
||||
$_output .= "\$_smarty_tpl->getInlineSubTemplate({$include_file}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, {$_cache_tpl}, '{$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['func']}');\n";
|
||||
$_output .= "\$_smarty_tpl->tpl_vars[$_assign] = new Smarty_Variable(ob_get_clean());\n";
|
||||
} else {
|
||||
$_output .= "echo \$_smarty_tpl->getInlineSubTemplate({$include_file}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, {$_cache_tpl}, '{$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['func']}');\n";
|
||||
$_output .= "\$_smarty_tpl->getInlineSubTemplate({$include_file}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, {$_cache_tpl}, '{$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['func']}');\n";
|
||||
}
|
||||
if ($update_compile_id) {
|
||||
$_output .= $compiler->makeNocacheCode("\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n");
|
||||
@@ -303,9 +305,11 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||
}
|
||||
// was there an assign attribute
|
||||
if (isset($_assign)) {
|
||||
$_output .= "\$_smarty_tpl->tpl_vars[$_assign] = new Smarty_Variable(\$_smarty_tpl->getSubTemplate ($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, {$_cache_tpl}));\n";
|
||||
$_output .= "ob_start();\n";
|
||||
$_output .= "\$_smarty_tpl->getSubTemplate($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, {$_cache_tpl});\n";
|
||||
$_output .= "\$_smarty_tpl->tpl_vars[$_assign] = new Smarty_Variable(ob_get_clean());\n";
|
||||
} else {
|
||||
$_output .= "echo \$_smarty_tpl->getSubTemplate ($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, {$_cache_tpl});\n";
|
||||
$_output .= "\$_smarty_tpl->getSubTemplate($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, {$_cache_tpl});\n";
|
||||
}
|
||||
if ($update_compile_id) {
|
||||
$_output .= "\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n";
|
||||
|
@@ -151,14 +151,34 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
* @param mixed $cache_id cache id to be used with this template
|
||||
* @param mixed $compile_id compile id to be used with this template
|
||||
* @param object $parent next higher level of Smarty variables
|
||||
* @param bool $_display true: display, false: fetch
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws SmartyException
|
||||
* @return string rendered template output
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null)
|
||||
public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $_display = false)
|
||||
{
|
||||
return isset($template) ? $this->smarty->fetch($template, $cache_id, $compile_id, $parent) : $this->render(true, false, false);
|
||||
if (isset($template)) {
|
||||
return $this->smarty->fetch($template, $cache_id, $compile_id, $parent, $_display);
|
||||
} else {
|
||||
// fetch template content
|
||||
$level = ob_get_level();
|
||||
try {
|
||||
$_smarty_old_error_level = isset($this->smarty->error_reporting) ? error_reporting($this->smarty->error_reporting) : null;
|
||||
ob_start();
|
||||
$result = $this->render(true, false, $_display);
|
||||
if (isset($_smarty_old_error_level)) {
|
||||
error_reporting($_smarty_old_error_level);
|
||||
}
|
||||
return $result === null ? ob_get_clean() : $result;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
while (ob_get_level() > $level) {
|
||||
ob_end_clean();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,7 +252,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
$this->tpl_vars = $tpl_vars;
|
||||
$this->config_vars = $config_vars;
|
||||
}
|
||||
$_smarty_old_error_level = isset($this->smarty->error_reporting) ? error_reporting($this->smarty->error_reporting) : null;
|
||||
// check URL debugging control
|
||||
if (!$this->smarty->debugging && $this->smarty->debugging_ctrl == 'URL') {
|
||||
$this->smarty->_debug->debugUrl($this);
|
||||
@@ -260,9 +279,9 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
if (!isset($this->compiled)) {
|
||||
$this->loadCompiled();
|
||||
}
|
||||
$content = $this->compiled->render($this);
|
||||
$this->compiled->render($this);
|
||||
} else {
|
||||
$content = $this->source->renderUncompiled($this);
|
||||
$this->source->renderUncompiled($this);
|
||||
}
|
||||
if ($parentIsTpl && !empty($this->tpl_function)) {
|
||||
$this->parent->tpl_function = array_merge($this->parent->tpl_function, $this->tpl_function);
|
||||
@@ -275,7 +294,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
if ($this->smarty->debugging) {
|
||||
$this->smarty->_debug->start_cache($this);
|
||||
}
|
||||
$this->cached->updateCache($this, $content, $no_output_filter);
|
||||
$this->cached->updateCache($this, $no_output_filter);
|
||||
$compile_check = $this->smarty->compile_check;
|
||||
$this->smarty->compile_check = false;
|
||||
if ($parentIsTpl) {
|
||||
@@ -285,7 +304,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
$this->cached->process($this, true);
|
||||
}
|
||||
$this->smarty->compile_check = $compile_check;
|
||||
$content = $this->getRenderedTemplateCode($this->cached->unifunc);
|
||||
$this->getRenderedTemplateCode($this->cached->unifunc);
|
||||
if ($this->smarty->debugging) {
|
||||
$this->smarty->_debug->end_cache($this);
|
||||
}
|
||||
@@ -303,25 +322,23 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
if ($this->smarty->debugging) {
|
||||
$this->smarty->_debug->start_cache($this);
|
||||
}
|
||||
$content = $this->cached->render($this);
|
||||
$this->cached->render($this);
|
||||
if ($this->smarty->debugging) {
|
||||
$this->smarty->_debug->end_cache($this);
|
||||
}
|
||||
}
|
||||
$content = null;
|
||||
if ((!$this->caching || $this->cached->has_nocache_code || $this->source->recompiled) && !$no_output_filter &&
|
||||
(isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))
|
||||
) {
|
||||
$content = Smarty_Internal_Filter_Handler::runFilter('output', $content, $this);
|
||||
}
|
||||
if (isset($_smarty_old_error_level)) {
|
||||
error_reporting($_smarty_old_error_level);
|
||||
$content = Smarty_Internal_Filter_Handler::runFilter('output', ob_get_clean(), $this);
|
||||
}
|
||||
// display or fetch
|
||||
if ($display) {
|
||||
if ($this->caching && $this->smarty->cache_modified_check) {
|
||||
$this->cached->cacheModifiedCheck($this, $content);
|
||||
$this->cached->cacheModifiedCheck($this, isset($content) ? $content : ob_get_clean());
|
||||
} else {
|
||||
echo $content;
|
||||
echo isset($content) ? $content : ob_get_clean();
|
||||
}
|
||||
if ($this->smarty->debugging) {
|
||||
$this->smarty->_debug->end_template($this);
|
||||
@@ -361,7 +378,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
}
|
||||
}
|
||||
// return cache content
|
||||
return $content;
|
||||
return $content === null ? null: $content;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +394,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
{
|
||||
$level = ob_get_level();
|
||||
try {
|
||||
ob_start();
|
||||
if (empty($unifunc) || !is_callable($unifunc)) {
|
||||
throw new SmartyException("Invalid compiled template for '{$this->template_resource}'");
|
||||
}
|
||||
@@ -397,12 +413,16 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
if (isset($this->smarty->security_policy)) {
|
||||
$this->smarty->security_policy->exitTemplate();
|
||||
}
|
||||
return ob_get_clean();
|
||||
return null;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
while (ob_get_level() > $level) {
|
||||
ob_end_clean();
|
||||
}
|
||||
array_shift($this->_capture_stack);
|
||||
if (isset($this->smarty->security_policy)) {
|
||||
$this->smarty->security_policy->exitTemplate();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
@@ -470,7 +490,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
public function getSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $cache_tpl_obj)
|
||||
{
|
||||
$tpl = $this->setupSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $cache_tpl_obj);
|
||||
return $tpl->render();
|
||||
$tpl->render();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -563,7 +583,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
$this->smarty->_debug->start_template($tpl);
|
||||
$this->smarty->_debug->start_render($tpl);
|
||||
}
|
||||
$output = $tpl->getRenderedTemplateCode($content_func);
|
||||
$tpl->getRenderedTemplateCode($content_func);
|
||||
if ($this->smarty->debugging) {
|
||||
$this->smarty->_debug->end_template($tpl);
|
||||
$this->smarty->_debug->end_render($tpl);
|
||||
|
@@ -208,7 +208,7 @@ class Smarty_Template_Cached extends Smarty_Template_Resource_Base
|
||||
if (!$this->processed) {
|
||||
$this->process($_template);
|
||||
}
|
||||
return $_template->getRenderedTemplateCode($this->unifunc);
|
||||
$_template->getRenderedTemplateCode($this->unifunc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -269,31 +269,33 @@ class Smarty_Template_Cached extends Smarty_Template_Resource_Base
|
||||
*
|
||||
* @throws SmartyException
|
||||
*/
|
||||
public function updateCache(Smarty_Internal_Template $_template, $content, $no_output_filter)
|
||||
public function updateCache(Smarty_Internal_Template $_template, $no_output_filter)
|
||||
{
|
||||
$content = ob_get_clean();
|
||||
$_template->cached->has_nocache_code = false;
|
||||
// get text between non-cached items
|
||||
$cache_split = preg_split("!/\*%%SmartyNocache:{$_template->compiled->nocache_hash}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->compiled->nocache_hash}%%\*/!s", $content);
|
||||
// get non-cached items
|
||||
preg_match_all("!/\*%%SmartyNocache:{$_template->compiled->nocache_hash}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->compiled->nocache_hash}%%\*/!s", $content, $cache_parts);
|
||||
$output = '';
|
||||
$content = '';
|
||||
// loop over items, stitch back together
|
||||
foreach ($cache_split as $curr_idx => $curr_split) {
|
||||
// escape PHP tags in template content
|
||||
$output .= preg_replace('/(<%|%>|<\?php|<\?|\?>|<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>)/', "<?php echo '\$1'; ?>\n", $curr_split);
|
||||
$content .= preg_replace('/(<%|%>|<\?php|<\?|\?>|<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>)/', "<?php echo '\$1'; ?>\n", $curr_split);
|
||||
if (isset($cache_parts[0][$curr_idx])) {
|
||||
$_template->cached->has_nocache_code = true;
|
||||
$output .= $cache_parts[1][$curr_idx];
|
||||
$content .= $cache_parts[1][$curr_idx];
|
||||
}
|
||||
}
|
||||
if (!$no_output_filter && !$_template->compiled->has_nocache_code &&
|
||||
(isset($_template->smarty->autoload_filters['output']) ||
|
||||
isset($_template->smarty->registered_filters['output']))
|
||||
) {
|
||||
$output = Smarty_Internal_Filter_Handler::runFilter('output', $output, $_template);
|
||||
$content = Smarty_Internal_Filter_Handler::runFilter('output', $content, $_template);
|
||||
}
|
||||
// write cache file content
|
||||
$this->writeCachedContent($_template, $output);
|
||||
$this->writeCachedContent($_template, $content);
|
||||
ob_start();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -206,7 +206,7 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
|
||||
if (isset($_template->cached)) {
|
||||
$_template->cached->file_dependency = array_merge($_template->cached->file_dependency, $this->file_dependency);
|
||||
}
|
||||
return $_template->getRenderedTemplateCode($this->unifunc);
|
||||
$_template->getRenderedTemplateCode($this->unifunc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,6 +222,7 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
|
||||
$_template->source->compileds = array();
|
||||
$this->file_dependency = array();
|
||||
$this->tpl_function = array();
|
||||
$this->includes = array();
|
||||
$this->nocache_hash = null;
|
||||
$this->unifunc = null;
|
||||
// compile locking
|
||||
|
@@ -202,7 +202,9 @@ class Smarty_Template_Source
|
||||
list($name, $type) = Smarty_Resource::parseResourceName($template_resource, $smarty->default_resource_type);
|
||||
$resource = Smarty_Resource::load($smarty, $type);
|
||||
// if resource is not recompiling and resource name is not dotted we can check the source cache
|
||||
if (($smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON) && !$resource->recompiled && !(isset($name[1]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/'))) {
|
||||
if (($smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON) && !$resource->recompiled &&
|
||||
!(isset($name[1]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/'))
|
||||
) {
|
||||
$unique_resource = $resource->buildUniqueResourceName($smarty, $name);
|
||||
if (isset($smarty->source_objects[$unique_resource])) {
|
||||
return $smarty->source_objects[$unique_resource];
|
||||
@@ -221,8 +223,11 @@ class Smarty_Template_Source
|
||||
// may by we have already $unique_resource
|
||||
$is_relative = false;
|
||||
if (!isset($unique_resource)) {
|
||||
$is_relative = isset($name[1]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/') && ($type == 'file' || (isset($_template->parent->source) && $_template->parent->source->type == 'extends'));
|
||||
$unique_resource = $resource->buildUniqueResourceName($smarty, $is_relative ? $source->filepath . $name : $name);
|
||||
$is_relative = isset($name[1]) && $name[0] == '.' && ($name[1] == '.' || $name[1] == '/') &&
|
||||
($type == 'file' ||
|
||||
(isset($_template->parent->source) && $_template->parent->source->type == 'extends'));
|
||||
$unique_resource = $resource->buildUniqueResourceName($smarty, $is_relative ? $source->filepath .
|
||||
$name : $name);
|
||||
}
|
||||
$source->unique_resource = $unique_resource;
|
||||
// save in runtime cache if not relative
|
||||
@@ -243,18 +248,7 @@ class Smarty_Template_Source
|
||||
*/
|
||||
public function renderUncompiled(Smarty_Internal_Template $_template)
|
||||
{
|
||||
$level = ob_get_level();
|
||||
ob_start();
|
||||
try {
|
||||
$this->handler->renderUncompiled($_template->source, $_template);
|
||||
return ob_get_clean();
|
||||
}
|
||||
catch (Exception $e) {
|
||||
while (ob_get_level() > $level) {
|
||||
ob_end_clean();
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user