Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

template changes take some seconds to recompile with PHP5 opcache enabled. #72

Closed
calguy1000 opened this issue Jul 16, 2015 · 3 comments

Comments

@calguy1000
Copy link

Problem:

With Smarty opcache enabled (PHP 5.5+) template changes take some seconds to be recompiled.  This can cause problems when using caching of varying sorts to cache the rendered output from a compiled page

Severity: MAJOR

Symptoms:

Making a small change to a smarty template, and then browsing to the page has no effect.  You must wait for a few seconds or continuously reload in order to see the change.

How to reproduce:

1.  Ensure that the PHP 5.5+ opcache is enabled in the php.ini (default settings otherwise)
    opcache.enable=1

2.  Browse to the supplied testcase script with a browser, and see the rendered page

3.  Save a small change in the templates/index.tpl file

4.  Immediately reload the browser page.

Problem Area:

sysplugins/smarty_template_compiled.php smarty_template_compiled::process()
on line 174 the compiled template is 'included' to check for validity and wether it must be 'recompiled'
if it must be recompiled it is recompiled and 'included' again (line 179)
because this is within the opcache revalidate frequency, even though the timestamp on the php file has changed
the include has no effect (the opcache optimizes this out).

Sample code

<?php
include_once('smarty-3.1.27/libs/Smarty.class.php');
define('SMARTY_COMPILE_DIR',getcwd().'/tmp/templates_c');
define('SMARTY_CACHE_DIR',getcwd().'/tmp/cache');

ini_set('opcache.revalidate_freq',10); // by default this is 2

$smarty = new Smarty();
$smarty->setCompileDir(SMARTY_COMPILE_DIR);
$smarty->setCacheDir(SMARTY_CACHE_DIR);
$smarty->addTemplateDir(getcwd().'/templates');
$smarty->addConfigDir(getcwd().'/configs');

$data = [];
$data['title'] = 'Test Smarty and PHP 5.5 opcache';
$data['subtitle'] = 'Template changes have no effect for some seconds.';
$smarty->assign('data',$data);
$conf = opcache_get_configuration();
$smarty->assign('conf',$conf['directives']);
$smarty->display('index.tpl');

Test template

<html>
<head>
  <title>{$data.title}</title>
</head>
<body>
  <h1 style="text-align: center;">{$data.title}</h1>
  <h2 style="text-align: center;">{$data.subtitle}</h2>
  <h3 style="color: orange; text-align: center;">Make a small change to {$smarty.template} and immediately reload this page.</h3>
  <p>some text aa</p>
  <p>some text bb</p>
  <p>some text cc</p>
  <p>some text</p>
  <p>some text</p>
  <p>some text</p>
  <p>some text</p>
  <fieldset>
    <legend>Opcache configuration</legend>
    <table style="width: 100%;">
    {foreach $conf as $key => $val}
      <tr>
        <td>{$key}</td>
    <td>{$val}</td>
      </tr>
    {/foreach}
    </table>
  </fieldset>
</body>
</html>
@uwetews
Copy link
Contributor

uwetews commented Jul 19, 2015

I think the problem is the opcache.revalidate_freq parameter which controls how often opcache does check for modifications. It should be

opcache.revalidate_freq=0

which means always revalidate.

@uwetews uwetews closed this as completed Jul 19, 2015
@calguy1000
Copy link
Author

I think that your solution is short sighted. The factory default setting of php 5.5 for the opcache is
opcache.revalidate_freq=2. changing it to 0 would result in a sub-optimal use of the opcode cache. Infact for sites that don't change often increasing this value is probably a good performance boost.

Which means that every person using smarty with PHP5 would need to adjust their php settings. This is not good for publicly distributed software applications using smarty.

A better solution would be to change the code such that this file does not get included twice.

A fallback solution would be to call opcache_invalidate on the file before including it.
something like: if( function_exists('opcache_invalidate') ) opcache_invalidate($filename);

Which should solve the problem without making every smarty user using PHP 5.5 adjust their PHP settings and would still take advantage of the opcode cache for repeated requests when the template does not need to be recompiled.

@uwetews
Copy link
Contributor

uwetews commented Jul 20, 2015

The patch is now in dev-master

think-mcunanan pushed a commit to think-mcunanan/smarty that referenced this issue Mar 22, 2023
…e-php5-to-php7-diagnostic-code-for-note-42

Redmine-#5313:[レスポンス改善] サーバーサイドをPHP5→PHP7にアップグレードする
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants