<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Gergely Hodicska &#187; high traffic website</title>
	<atom:link href="http://blog.felho.hu/stock/high-traffic-website/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.felho.hu</link>
	<description>Random secrets of PHP, web development</description>
	<lastBuildDate>Fri, 30 Nov 2007 10:16:33 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Fixing some problems in Template Lite</title>
		<link>http://blog.felho.hu/fixing-some-problems-in-template-lite.html</link>
		<comments>http://blog.felho.hu/fixing-some-problems-in-template-lite.html#comments</comments>
		<pubDate>Thu, 08 Nov 2007 06:49:15 +0000</pubDate>
		<dc:creator>Felho</dc:creator>
				<category><![CDATA[high traffic website]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[template lite]]></category>
		<category><![CDATA[high traffic]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://blog.felho.hu/fixing-some-problems-in-template-lite.html</guid>
		<description><![CDATA[As a PHP developer probably you are familiar with Smarty, which is maybe the de facto PHP template engine. Smarty is sometimes criticized that it has too many feature and is too big. I think that in an average development Smarty could be a good choice, it gives you a lot of potential, and its [...]]]></description>
			<content:encoded><![CDATA[<p>As a PHP developer probably you are familiar with <a href="http://smarty.php.net/" title="Smarty Template Engine">Smarty</a>, which is maybe the de facto PHP template engine. Smarty is sometimes criticized that it has too many feature and is too big. I think that in an average development Smarty could be a good choice, it gives you a lot of potential, and its speed and memory footprint has no impact on the overall performance of the application. But if you develop a really high traffic website these issues could become very important. <a href="http://templatelite.sourceforge.net/" title="Template Lite - The smaller, faster templating solution">Template Lite</a> could be a good compromise between the features of Smarty and the performance. It is a lightweight version of Smarty, it is much faster and has much lower memory footprint. It has almost the same features like Smarty, so you won&#8217;t have any problem using it after Smarty. While Template Lite works very well, it needs a few improvements.<span id="more-29"></span></p>
<h2>The name of the compiled template file</h2>
<p>By default the name of the compiled template file is the encoded version of the original template file. If turn off this behavior by setting the <code>$encode_file_name</code> variable to <code>false</code>. The problem is, that in this case Template Lite does not include into the name of the compiled file the <code>$template_dir</code> variable. Consider the following situation:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span><br />
<span style="color: #808080; font-style: italic;">/*<br />
&nbsp;* Template layout:<br />
&nbsp;* /templates<br />
&nbsp;* &nbsp; &nbsp; /domain1.com<br />
&nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; /header.tpl<br />
&nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; /index.tpl<br />
&nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; /footer.tpl<br />
&nbsp;* /templates<br />
&nbsp;* &nbsp; &nbsp; /domain2.com<br />
&nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; /header.tpl<br />
&nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; /index.tpl<br />
&nbsp;* &nbsp; &nbsp; &nbsp; &nbsp; /footer.tpl<br />
&nbsp;*/</span><br />
<br />
<span style="color: #808080; font-style: italic;">// This common code handles both domain.</span><br />
<span style="color: #0000ff;">$template</span> = <span style="color: #000000; font-weight: bold;">new</span> Template_Lite<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #0000ff;">$template</span>-&gt;<span style="color: #006600;">template_dir</span> = <span style="color: #0000ff;">$_SERVER</span><span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'SERVER_NAME'</span><span style="color: #66cc66;">&#93;</span>;<br />
<span style="color: #0000ff;">$template</span>-&gt;<span style="color: #006600;">display</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'index.tpl'</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000000; font-weight: bold;">?&gt;</span></div></td></tr></table></div>

<p>The code looks good, but there is a big problem. If you get the index page on domain1.com, and then the index page on domain2.com, the secondly generated compiled file will overwrite the first one. To solve this problem you should modify the source code in the following way:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #808080; font-style: italic;">//$name = ($this-&gt;encode_file_name) ? md5((($this-&gt;_resource_type == 1) ? $this-&gt;template_dir.$file : $this-&gt;_resource_type . &amp;qout;_&amp;qout; . $file)).'.php' : str_replace(&amp;qout;.&amp;qout;, &amp;qout;_&amp;qout;, str_replace(&amp;qout;/&amp;qout;, &amp;qout;_&amp;qout;, $this-&gt;_resource_type . &amp;qout;_&amp;qout; . $file)).'.php';</span><br />
<span style="color: #0000ff;">$name</span> = <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">encode_file_name</span><span style="color: #66cc66;">&#41;</span> ? <span style="color: #000066;">md5</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;_resource_type == <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> ? <span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">template_dir</span>.<span style="color: #0000ff;">$file</span> : <span style="color: #0000ff;">$this</span>-&gt;_resource_type . &amp;qout;_&amp;qout; . <span style="color: #0000ff;">$file</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #ff0000;">'.php'</span> : <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066;">str_replace</span><span style="color: #66cc66;">&#40;</span><span style="color: #000066;">array</span><span style="color: #66cc66;">&#40;</span>&amp;qout;:&amp;qout;, &amp;qout;.&amp;qout;, &amp;qout;/&amp;qout;, &amp;qout;\\&amp;qout;<span style="color: #66cc66;">&#41;</span>, &amp;qout;_&amp;qout;, <span style="color: #0000ff;">$this</span>-&gt;_resource_type.&amp;qout;_&amp;qout;.<span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">template_dir</span>.<span style="color: #0000ff;">$file</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #ff0000;">'.php'</span>;</div></td></tr></table></div>

<p>This modification should be done in several places in the source code. To find all the places you should search for the &#8220;encode_file_name&#8221; string.</p>
<h2>Writing out the compiled template file</h2>
<p>Template Lite by default opens a new file, and writes the compiled template content to it. This is not a good solution if the site has high traffic, because in the time of writing out the file it is not accessible for other processes which will cause error. A better solution is if you write to a temporary file, and when you finish it rename the temporary file to the final name. The name of the temporary file should be unique, you can achieve this by using a suffix like this: <code><a href="http://php.net/getmypid" title="Gets PHP's process ID">getmypid</a>()."_".<a href="http://php.net/microtime" title="Return current Unix timestamp with microseconds">microtime</a>(TRUE)</code>. Now if we have multiple request on the same time, and there isn&#8217;t a compiled version of the template, every request starts to generate the compiled version. The renames will be atomic and are ordered by the OS, so this way we can eliminate this type of error. The only drawback is that in Windows we can&#8217;t rename to an existing file, but usually you won&#8217;t serve a high traffic site on a Windows machine with PHP, so this is not a big problem.</p>
<p>To get Template Lite to work in this way, we should slightly modify its source (<code>class.template.php</code>) in the following way:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #808080; font-style: italic;">/*<br />
// Original code<br />
$f = fopen($this-&gt;compile_dir.'c_'.$name, &amp;qout;w&amp;qout;);<br />
fwrite($f, $output);<br />
fclose($f);<br />
*/</span><br />
<span style="color: #808080; font-style: italic;">// We write to a temporary file at first, and then we rename it to the final name.</span><br />
<span style="color: #808080; font-style: italic;">// Renaming is atomic so we won't have probelm on concurrent requests.</span><br />
<span style="color: #0000ff;">$compiledFile</span> = <span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">compile_dir</span>.&amp;qout;c_&amp;qout;.<span style="color: #0000ff;">$name</span>;<br />
<span style="color: #0000ff;">$tempFile</span> = <span style="color: #0000ff;">$compiledFile</span>.&amp;qout;_&amp;qout;.<span style="color: #000066;">getmypid</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.&amp;qout;_&amp;qout;.<span style="color: #000066;">microtime</span><span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">TRUE</span><span style="color: #66cc66;">&#41;</span>.&amp;qout;.tmp&amp;qout;;<br />
<span style="color: #0000ff;">$f</span> = <span style="color: #000066;">fopen</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$tempFile</span>, &amp;qout;w&amp;qout;<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000066;">fwrite</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$f</span>, <span style="color: #0000ff;">$output</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000066;">fclose</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$f</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #808080; font-style: italic;">// This won't work on Windwos, if the target file exists!!!</span><br />
<span style="color: #000066;">rename</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$tempFile</span>, <span style="color: #0000ff;">$compiledFile</span><span style="color: #66cc66;">&#41;</span>;</div></td></tr></table></div>

<h2>The value of the <code>$this->_file</code> variable</h2>
<p>The <code>Template_Lite</code> class holds in this variable the name of the currently used template file. If the currently processed template includes an other template, Template Lite stops the processing of the current template and starts to process the included one (it works like a function call). At this stage the value of the <code>$this->_file</code> will be the name of the included template. Unfortunately when the processing step back to the original template, the value of <code>$this->_file</code> won&#8217;t change back. Generally this has no effect, but I sucked a little through it when I tried to extend Template Lite (you can read about this soon).</p>
<p>To correct this issue you should modify the <code>class.template.php</code> file on two places:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>749
750
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #0000ff;">$prev_file_name</span> = <span style="color: #0000ff;">$this</span>-&gt;_file;<br />
<span style="color: #0000ff;">$this</span>-&gt;_file = <span style="color: #0000ff;">$file</span>;</div></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>796
797
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #0000ff;">$this</span>-&gt;_file = <span style="color: #0000ff;">$prev_file_name</span>;<br />
<span style="color: #b1b100;">return</span> <span style="color: #0000ff;">$output</span>;</div></td></tr></table></div>

<h2>Some other little typos</h2>
<p>The following snippet comes from the original <code>template.class.php</code> file:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #b1b100;">if</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;_resource_type == <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">$f</span> = <span style="color: #000066;">fopen</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">template_dir</span> . <span style="color: #0000ff;">$file</span>, &amp;qout;r&amp;qout;<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">$size</span> = <span style="color: #000066;">filesize</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;<span style="color: #006600;">template_dir</span> . <span style="color: #0000ff;">$file</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$size</span> &gt; <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$file_contents</span> = <span style="color: #000066;">fread</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$f</span>, <span style="color: #0000ff;">$size</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #66cc66;">&#125;</span><br />
<span style="color: #b1b100;">else</span><br />
<span style="color: #ff0000">if<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;_resource_type == &amp;qout;file&amp;qout;<span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #0000ff;">$f</span> = <span style="color: #000066;">fopen</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$file</span>, &amp;qout;r&amp;qout;<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #0000ff;">$size</span> = <span style="color: #000066;">filesize</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$file</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$size</span> &gt; <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$file_contents</span> = <span style="color: #000066;">fread</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$f</span>, <span style="color: #0000ff;">$size</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #66cc66;">&#125;</span></span><br />
<span style="color: #b1b100;">else</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000066;">call_user_func_array</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;_plugins<span style="color: #66cc66;">&#91;</span><span style="color: #ff0000;">'resource'</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#91;</span><span style="color: #0000ff;">$this</span>-&gt;_resource_type<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span>, <span style="color: #000066;">array</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$file</span>, &amp;<span style="color: #0000ff;">$file_contents</span>, &amp;<span style="color: #0000ff;">$this</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span><br />
<br />
<span style="color: #0000ff;">$this</span>-&gt;_file = <span style="color: #0000ff;">$file</span>;<br />
<span style="color: #000066;">fclose</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$f</span><span style="color: #66cc66;">&#41;</span>;</div></td></tr></table></div>

<p>Maybe you notice, that no file is opened in the else statement, but <code>fclose($f)</code> is always called. You should move this command to the <code>if</code> and <code>else if</code> statement.</p>
<p>Another little typo is here:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>257
258
259
260
261
</pre></td><td class="code"><div class="php" style="font-family: monospace;"><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #000066;">in_array</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$key</span>, <span style="color: #0000ff;">$this</span>-&gt;_vars<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
<span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// The array key should be $key.</span><br />
&nbsp; &nbsp; <span style="color: #000066;">unset</span><span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$this</span>-&gt;_vars<span style="color: #66cc66;">&#91;</span><span style="color: #0000ff;">$index</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span></div></td></tr></table></div>

<p>You can download the <a href='http://blog.felho.hu/wp-content/classtemplate.zip' title='The corrected version of the template.class.php'>corrected version</a>. The comments are in Hungarian, but after reading the article you won&#8217;t need them, and anyway it is a beautiful language. <img src='http://blog.felho.hu/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.felho.hu/fixing-some-problems-in-template-lite.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>


