<?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>Zenphoto - simpler web gallery management &#187; optimization</title>
	<atom:link href="http://www.zenphoto.org/tag/optimization/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.zenphoto.org</link>
	<description>Blog for news about Zenphoto and its development.</description>
	<lastBuildDate>Fri, 30 Jul 2010 16:45:17 +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>Refresh the Database</title>
		<link>http://www.zenphoto.org/2010/05/refresh-the-database/</link>
		<comments>http://www.zenphoto.org/2010/05/refresh-the-database/#comments</comments>
		<pubDate>Thu, 06 May 2010 17:16:54 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[Admin utilities]]></category>
		<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Officially supported]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=1569</guid>
		<description><![CDATA[Cleans the database and removes any orphan entries for comments, images, and albums.
This is a button interface for the admin backend&#8217;s overview page.
]]></description>
			<content:encoded><![CDATA[<p>Cleans the database and removes any orphan entries for comments, images, and albums.</p>
<p><em>This is a button interface for the admin backend&#8217;s overview page.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2010/05/refresh-the-database/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>eAccelerator caching</title>
		<link>http://www.zenphoto.org/2009/11/eaccelerator-caching/</link>
		<comments>http://www.zenphoto.org/2009/11/eaccelerator-caching/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 20:07:58 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[Addons & Utilities]]></category>
		<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Unsupported]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[eAccelerator]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=946</guid>
		<description><![CDATA[
a. Reduce load on the DB server
b Bypassing directory traversal

a. Reduce load on the DB server
Developed by invarbrass
This is based on the caching technique described on http://www.zenphoto.org/2008/01/hacks/ We&#8217;ll use eAccelerator shm cache instead of storing the query results on disk.
1. Edit the functions-db.php under zp-core directory.
2. Search function query_single_row, change it to:
function query_single_row($sql, $noerrmsg=false) {
if [...]]]></description>
			<content:encoded><![CDATA[<ol>
<li><a href="#reduce-load-db">a. Reduce load on the DB server</a></li>
<li><a href="#bypassing-directory">b Bypassing directory traversal</a></li>
</ol>
<h4>a. Reduce load on the DB server</h4>
<p>Developed by invarbrass</p>
<p>This is based on the caching technique described on http://www.zenphoto.org/2008/01/hacks/ We&#8217;ll use eAccelerator shm cache instead of storing the query results on disk.<br />
1. Edit the functions-db.php under zp-core directory.<br />
2. Search function query_single_row, change it to:<br />
<code>function query_single_row($sql, $noerrmsg=false) {<br />
if ($cache = get_cache($sql))<br />
return $cache;<br />
$result = query($sql, $noerrmsg);<br />
if ($result) {<br />
$data = mysql_fetch_assoc($result);<br />
store_cache($sql, $data);<br />
return $data;<br />
}<br />
else {<br />
return false;<br />
}<br />
}</code><br />
3. Search <tt>function query_full_array</tt>, change it to:<br />
<code>function query_full_array($sql, $noerrmsg = false) {<br />
if ($cache = get_cache($sql))<br />
return $cache;<br />
$result = query($sql, $noerrmsg);<br />
if ($result) {<br />
$allrows = array();<br />
while ($row = mysql_fetch_assoc($result))<br />
$allrows[] = $row;<br />
store_cache($sql, $allrows);<br />
return $allrows;<br />
}<br />
else {<br />
return false;<br />
}<br />
}</code><br />
4. Last thing, add two functions in <tt>functions-db.php</tt>. You could change “cachedirectory” to your cache directory, and change <tt>$cache_time_out</tt> to the expire time you want.<br />
<code>function store_cache($query, $result_cache) {<br />
$cache_time_out = 600;<br />
if (preg_match("/^(insert|delete|update|replace)\s+/i",$query))<br />
return;<br />
if (stristr($query, "ORDER BY RAND"))<br />
return;<br />
$key = 'sql_' . md5($query);<br />
$val = serialize($result_cache);<br />
eaccelerator_put($key, $val, $cache_time_out);<br />
}</code><br />
<code><br />
function get_cache($query) {<br />
if (preg_match("/^(insert|delete|update|replace)\s+/i",$query))<br />
return;<br />
if (stristr($query, "ORDER BY RAND"))<br />
return;<br />
$key = 'sql_' . md5($query);<br />
$val = eaccelerator_get($key);<br />
if ( $val != NULL )<br />
return unserialize($val);<br />
}</code></p>
<h4><a title="bypassing-directory" name="bypassing-directory"></a>b. Bypassing directory traversal</h4>
<p>Developed by invarbrass<br />
ZP scans the albums directory every time the script is executed. Since disk operations are expensive, we can try to limit disk-based I/O to make it load faster. We&#8217;ll be using eAccelerator to cache our stuff, but you can easily adopt this code for APC, XCache, memcached or even a disk-file.<br />
1. Open <tt>class-album.php</tt> in <tt>zp-core</tt> directory.<br />
2. Put the following code at the beginning of the script:<br />
<code>function store_filenames_cache($dir, $has_dir, $pic_cache, $vid_cache) {<br />
$cache_time_out = 600;<br />
if ($has_dir) {<br />
$pic_key = 'dp_' . md5($dir);<br />
$vid_key = 'dv_' . md5($dir);<br />
}<br />
else {<br />
$pic_key = 'fp_' . md5($dir);<br />
$vid_key = 'fv_' . md5($dir);<br />
}<br />
$pic_val = serialize($pic_cache);<br />
$vid_val = serialize($vid_cache);<br />
eaccelerator_put($pic_key, $pic_val, $cache_time_out);<br />
eaccelerator_put($vid_key, $vid_val, $cache_time_out);<br />
}<br />
function get_filenames_cache($dir, $has_dir, &amp;$pic_cache, &amp;$vid_cache) {<br />
if ($has_dir) {<br />
$pic_key = 'dp_' . md5($dir);<br />
$vid_key = 'dv_' . md5($dir);<br />
}<br />
else {<br />
$pic_key = 'fp_' . md5($dir);<br />
$vid_key = 'fv_' . md5($dir);<br />
}<br />
$pic_cache = eaccelerator_get($pic_key);<br />
$vid_cache = eaccelerator_get($vid_key);<br />
if ( $pic_cache != NULL ) {<br />
$pic_cache = unserialize($pic_cache);<br />
}<br />
else {<br />
return FALSE;<br />
}<br />
if ( $vid_cache != NULL ) {<br />
$vid_cache = unserialize($vid_cache);<br />
}<br />
else {<br />
return FALSE;<br />
}<br />
return TRUE;<br />
}</code><br />
3. Locate the <tt>loadFileNames()</tt> function, and replace it with this:<br />
<code>function loadFileNames($dirs=false) {<br />
if ($this-&gt;isDynamic()) { // there are no 'real' files<br />
return array();<br />
}<br />
$albumdir = getAlbumFolder() . $this-&gt;name . "/";<br />
if (!is_dir($albumdir) || !is_readable($albumdir)) {<br />
$msg = gettext("Error: The 'albums' directory")." (" . $this-&gt;albumdir . ") ";<br />
if (!is_dir($this-&gt;albumdir)) {<br />
$msg .= gettext("cannot be found.");<br />
} else {<br />
$msg .= gettext("is not readable.");<br />
}<br />
die($msg);<br />
}<br />
//masroore - cache these results<br />
if (get_filenames_cache($albumdir, $dirs, $files, $videos) === FALSE) {<br />
$dir = opendir($albumdir);<br />
$files = array();<br />
$videos = array();<br />
while (false !== ($file = readdir($dir))) {<br />
if ($dirs &amp;&amp; (is_dir($albumdir.$file) &amp;&amp; (substr($file, 0, 1) != '.') || hasDyanmicAlbumSuffix($file))) {<br />
$files[] = $file;<br />
} else if (!$dirs &amp;&amp; is_file($albumdir.$file)) {<br />
if (is_valid_video($file)) {<br />
$files[] = $file;<br />
$videos[] = $file;<br />
} else if (is_valid_image($file)) {<br />
$files[] = $file;<br />
}<br />
}<br />
}<br />
closedir($dir);<br />
store_filenames_cache($albumdir, $dirs, $files, $videos);<br />
}<br />
if (count($videos) &gt; 0) {<br />
$video_thumbs = array();<br />
foreach($videos as $video) {<br />
$video_root = substr($video, 0, strrpos($video,"."));<br />
foreach($files as $image) {<br />
$image_root = substr($image, 0, strrpos($image,"."));<br />
if ($image_root == $video_root &amp;&amp; $image != $video) {<br />
$video_thumbs[] = $image;<br />
}<br />
}<br />
}<br />
$files = array_diff($files, $video_thumbs);<br />
}<br />
return $files;<br />
}</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2009/11/eaccelerator-caching/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Server side optimization</title>
		<link>http://www.zenphoto.org/2009/11/server-side-optimization/</link>
		<comments>http://www.zenphoto.org/2009/11/server-side-optimization/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 20:05:29 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[Addons & Utilities]]></category>
		<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Unsupported]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[PHP cache libary]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=944</guid>
		<description><![CDATA[Developed by sagasw
Database result cache
As we know, the database will use many resource and time to query the information of Image. If we want to save time, we could do optimization with cache the result.
What I use is two functions, you could use other PHP cache library too. The code I use is version 1.13.
!! [...]]]></description>
			<content:encoded><![CDATA[<p>Developed by <a title="http://henku.info/" href="http://henku.info/">sagasw</a></p>
<p>Database result cache</p>
<p>As we know, the database will use many resource and time to query the information of Image. If we want to save time, we could do optimization with cache the result.<br />
What I use is two functions, you could use other PHP cache library too. The code I use is version 1.13.<br />
!! Please note: because I don&#8217;t open the comment function, so it may have problem with comment.</p>
<p>You could go to site <tt><a href="http://henku.info/"><span>http://henku.info</span></a></tt> to see the cache result.</p>
<p>1. Edit the functions-db.php under zp-core directory.</p>
<p>2. Search function query_single_row, change it to:<br />
<code>function query_single_row($sql){<br />
if ($cache = get_cache($sql))<br />
return $cache; $result = query($sql);<br />
if ($result) {<br />
$singlerow = mysql_fetch_assoc($result);<br />
store_cache($sql, $singlerow);<br />
return $singlerow;<br />
} else {<br />
return false;<br />
}<br />
}</code><br />
3. Search function query_full_array, change it to:<br />
<code>function query_full_array($sql){<br />
if ($cache = get_cache($sql))<br />
return $cache; $result = query($sql);<br />
if ($result) {<br />
$allrows = array();<br />
while ($row = mysql_fetch_assoc($result))<br />
$allrows[] = $row;<br />
store_cache($sql, $allrows);<br />
return $allrows;<br />
} else {<br />
return false;<br />
}<br />
}</code><br />
4. Last thing, add two functions in functions-db.php. You could change &#8220;cachedirectory&#8221; to your cache directory, and change $cache_time_out to the expire time you want. 30* 24 * 3600 is 30 days.<br />
<code>function store_cache($query, $result_cache){<br />
if (preg_match("/^(insert|delete|update|replace)\s+/i",$query))<br />
return;<br />
if (stristr($query, "ORDER BY RAND"))<br />
return; $cache_file = 'cachedirectory/'. md5($query);<br />
error_log (serialize($result_cache), 3, $cache_file);<br />
}</code><br />
<code><br />
function get_cache($query)<br />
{<br />
$cache_time_out = 30* 24 * 3600;<br />
if (preg_match("/^(insert|delete|update|replace)\s+/i",$query))<br />
return;<br />
if (stristr($query, "ORDER BY RAND"))<br />
return;<br />
$cache_file = 'cachedirectory/'. md5($query);<br />
if ( file_exists($cache_file) )<br />
{<br />
if ( (time() - filemtime($cache_file)) &gt; $cache_time_out )<br />
{<br />
unlink($cache_file);<br />
}<br />
else<br />
{<br />
$result_cache = unserialize(file_get_contents($cache_file));<br />
return $result_cache;<br />
}<br />
}<br />
}</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2009/11/server-side-optimization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Client side optimization</title>
		<link>http://www.zenphoto.org/2009/11/client-side-optimization/</link>
		<comments>http://www.zenphoto.org/2009/11/client-side-optimization/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 20:03:57 +0000</pubDate>
		<dc:creator>acrylian</dc:creator>
				<category><![CDATA[Addons & Utilities]]></category>
		<category><![CDATA[Extensions]]></category>
		<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Unsupported]]></category>
		<category><![CDATA[client]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://www.zenphoto.org/?p=942</guid>
		<description><![CDATA[Developed by vikaskbh
AS per yahoo! optimization guidelines http://developer.yahoo.com/yslow/
for making Zenphoto faster at client-side, here are some hacks.
FIRST: Edit .htaccsss file and add the following lines.
&#60;ifmodule mod_expires.c&#62;&#60;filesmatch "\.(jpg&#124;gif&#124;png&#124;css&#124;js)$"&#62;
ExpiresActive on
ExpiresDefault "access plus 1 year"
&#60;/filesmatch&#62;
&#60;/ifmodule&#62;FileETag None
That will make your image, javascript,css files cache lifetime 1 year+ and Removes Etags, If Apache WebServer?has attached any. So that webpage header [...]]]></description>
			<content:encoded><![CDATA[<p>Developed by <a title="http://actress.bollysite.com" href="http://actress.bollysite.com">vikaskbh</a></p>
<p>AS per yahoo! optimization guidelines <a href="http://developer.yahoo.com/yslow/"><span>http://developer.yahoo.com/yslow/</span></a><br />
for making Zenphoto faster at client-side, here are some hacks.</p>
<p><strong>FIRST:</strong> Edit .htaccsss file and add the following lines.<br />
<code>&lt;ifmodule mod_expires.c&gt;&lt;filesmatch "\.(jpg|gif|png|css|js)$"&gt;<br />
ExpiresActive on<br />
ExpiresDefault "access plus 1 year"<br />
&lt;/filesmatch&gt;<br />
&lt;/ifmodule&gt;FileETag None<code><br />
That will make your image, javascript,css files cache lifetime 1 year+ and Removes Etags, If Apache <tt><a rel="nofollow" href="http://www.zenphoto.org/trac/wiki/WebServer">WebServer?</a></tt>has attached any. So that webpage header size can be reduced.</code></code></p>
<p><strong>SECOND:</strong> If your web server is supporting gzip compression, edit index.php and add following line at Top of the page.<br />
<code>header("Vary: Accept-Encoding");if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'))<br />
ob_start("ob_gzhandler");<br />
else ob_start();</code><br />
So, Web server will deliver entire webpage as gzip compression format to the browser. So, network bandwidth can be reduced.</p>
<p><strong>THIRD:</strong> Convert your all <tt><a rel="nofollow" href="http://www.zenphoto.org/trac/wiki/JavaScript">JavaScript?</a></tt>, CSS files into PHP code (Make simple echo statement) and follow SECOND step for them. Finally, load them in templates. That will make your <tt><a rel="nofollow" href="http://www.zenphoto.org/trac/wiki/JavaScript">JavaScript?</a></tt>, css gzip-compressed &amp; faster deliverable.<br />
<code>SampleJavaScript.js.php<br />
if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'],<br />
'gzip'))<br />
ob_start("ob_gzhandler");<br />
else ob_start();<br />
header("content-type: application/x-javascript; charset: UTF-8");<br />
$gd = "Expires: Monday, January 18, 2038 12:44:06 AM";<br />
header($gd);<br />
zen.css.php<br />
&lt;?phpif (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip'))<br />
ob_start("ob_gzhandler");<br />
else ob_start();<br />
header("Content-type: text/css; charset: UTF-8");<br />
$gd = "Expires: Sun, 1 Jan 2017 05:00:00 GMT";<br />
header($gd);<br />
?&gt;</code><br />
image.php</p>
<p><tt>&lt;link rel="stylesheet" href="/themes/sterile/zen.css.php"&gt;&lt;/link&gt;</tt></p>
<p>try to put javascript before <tt>&lt;/body&gt;</tt><br />
image.php</p>
<p><tt>&lt;script src="/themes/sterile/SampleJavaScript.js.php"&gt;&lt;/script&gt;<br />
</tt><br />
So, The loading of web-page won&#8217;t blocked untill javascript is loaded.</p>
<p>You can check the performance of the site <tt><a href="http://actress.bollysite.com/"><span>http://actress.bollysite.com</span></a></tt> and test It with Firefox firebug-Yslow plug-in.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.zenphoto.org/2009/11/client-side-optimization/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
