<?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>Juozas devBlog &#187; optimization</title>
	<atom:link href="http://dev.juokaz.com/tag/optimization/feed" rel="self" type="application/rss+xml" />
	<link>http://dev.juokaz.com</link>
	<description>Random ideas, scripts and facts</description>
	<lastBuildDate>Mon, 22 Mar 2010 10:48:42 +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>Zend Framework is NOT bloated</title>
		<link>http://dev.juokaz.com/php/zend-framework-is-not-bloated</link>
		<comments>http://dev.juokaz.com/php/zend-framework-is-not-bloated#comments</comments>
		<pubDate>Fri, 12 Mar 2010 17:14:21 +0000</pubDate>
		<dc:creator>Juozas</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[apc]]></category>
		<category><![CDATA[bloated]]></category>
		<category><![CDATA[features]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[padraic]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[slow]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://dev.juokaz.com/?p=993</guid>
		<description><![CDATA[ Zend Framework is always considered as being the slow/bloated one. I don&#8217;t think this is right, so I decided to prove that it&#8217;s not correct and in fact ZF is as good as other frameworks are. This post doesn&#8217;t cover any benchmarks though; this is more like a architecture review and some misconceptions disproof. [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignnone size-full wp-image-460" title="Zend Framework" src="http://dev.juokaz.com/wp-content/uploads/2009/04/logo-zend-framework.jpg" alt="Zend Framework" width="169" height="114" /> Zend Framework is always considered as being the slow/bloated one. I don&#8217;t think this is right, so I decided to prove that it&#8217;s not correct and in fact ZF is as good as other frameworks are. This post doesn&#8217;t cover any benchmarks though; this is more like a architecture review and some misconceptions disproof.  </p>
<p>Before we go any further, let&#8217;s check with <a href="http://en.wikipedia.org/wiki/Software_bloat">Wikipedia</a>:</p>
<blockquote><p>Software bloat is a term used to describe the tendency of newer computer programs to have a <strong>larger installation footprint</strong>, or have many <strong>unnecessary features</strong> that are not used by end users, or just generally <strong>use more system resources</strong> than necessary, while offering little or <strong>no benefit</strong> to its users.
</p></blockquote>
<p>So what I need to provide is <em>contra</em> arguments that Zend Framework doesn&#8217;t do those.</p>
<h5>&#8220;Large installation footprint&#8221;</h5>
<p>25.8 MB and 2338 files. This is how much ZF <em>weights</em> and this is usually quoted as the main factor of bloatedness. First of all, 25.8 MB is a joke &#8211; full application takes maximum 50 MB. So unless you want to squeeze in 100&#8217;s of projects into a shared hosting, size of ZF shouldn&#8217;t matter at all. Price of hard-drive and RAM (for APC caches) is so low nowadays, that I don&#8217;t even remember last time I checked how much space my project takes up.</p>
<p>Same applies with files count &#8211; why would anyone even care how much files it has? As you probably know, PHP doesn&#8217;t compile your project into one binary, thus making it a big file. What it does, is it loads external code using include/require statements. Hence, from those 2338 you usually going to use around 300 (based on my tests). One can argue that this is still a lot of files, but this <em>big </em>number of files comes from ZF extensibility. A lot of functionality is separated into plugins, adapters etc. </p>
<h5>&#8220;Unnecessary features&#8221;</h5>
<p>ZF has massive amount of functionality: starting from web framework components and finishing up with services classes (I have written more about this <a href="http://dev.juokaz.com/php/why-zend-framework">here</a>). There is a big chance that you are not going to use all of them, but because all components are decoupled (as much as possible) and as mentioned above, you don&#8217;t even notice them if you don&#8217;t include those files. </p>
<p>I&#8217;m one of those people who think that ZF has too much components, but this is rather my own personal preference rather than a problem. Nevertheless, I haven&#8217;t used only a few of available components as once you need something, it&#8217;s always very quick to just <em>use</em> it. No need to download anything more or look for available components. For serious components like <a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-1">Doctrine</a>, you probably want to look around, but just for some regular code Zend provides all required features.</p>
<h5>&#8220;Use more system resources&#8221;</h5>
<p>This one is <strong>hot</strong> topic in ZF world. But the point here is that &#8220;features = slow&#8221;, especially in PHP. This happens because PHP as a language is not <em>that</em> fast and as you start adding more features and code, you get slower code. This where framework&#8217;s benchmarks are born, but as Pádraic mentions in his <a href="http://blog.astrumfutura.com/archives/421-PHP-Framework-Benchmarks-Entertaining-But-Ultimately-Useless.html">post</a> about benchmarks: </p>
<blockquote><p>To create a positive benchmark, you need to understand that all frameworks were born as festering piles of unoptimised stinking crap. They were all born bad and get worse with age. This sounds quite sad, but actually it&#8217;s an inevitable compromise between performance and features. It&#8217;s also a compromise between performance and ease-of-use</p></blockquote>
<p>It&#8217;s inevitable to provide those features that ZF provides and still work faster than other frameworks. So considering the speed of development you need to know how much performance you actually need. Maybe rapid development is much more important? At least it&#8217;s for me, and by sacrificing some tenths of a second I can roll out projects in a few days. And as &#8220;bloated&#8221; definition states, something is not bloated if it provides benefits while using more system resources.</p>
<h5>How to make it not bloated?</h5>
<p>If you still consider ZF as bloated framework, let me give you some ideas how to make it work for you. First of all &#8211; <a href="http://en.wikipedia.org/wiki/Software_performance_analysis">profile</a>, profile, profile! I keep mentioning this every time I talk about performance, but don&#8217;t judge performance of something without actually knowing <em>why</em> it&#8217;s not performing well. <a href="http://xdebug.org/">Xdebug</a> helps here as it can provide profiling data, which you then can use to detect slow parts of code. From my experience this is usually I/O &#8211; DB calls, file reads etc. Get rid of those and you have some decent performance increase. </p>
<p>A lot of other performance factors come from knowing how framework works internally or <em>really</em> reading manual. For example <a href="http://framework.zend.com/manual/en/zend.application.html">Zend_Application</a> is kind of slow, but it can be easily optimized by just getting rid of it. But this is only needed if you are running very big application, where every millisecond of execution matters, for normal application you&#8217;d hardly get any benefit. This is very ZF&#8217;s decoupled components start to shine, as you can just use those which work well and add some special sauce for other parts.  </p>
<h5>Conclusion</h5>
<p>I use Zend Framework extensively, so I&#8217;m biased a lot here, but having this much of experience, I can at least judge it objectively (up to some degree). And what I can say is that ZF is not bloated, it can be slower than some other available frameworks, but widely popular method to judge its performance by the number of files it has is just wrong. Of course it&#8217;s not the easiest framework to get working with (and get it to perform efficiently), but don&#8217;t get put off just by archive size it comes in. </p>
]]></content:encoded>
			<wfw:commentRss>http://dev.juokaz.com/php/zend-framework-is-not-bloated/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Zend Framework and Doctrine. Part 3</title>
		<link>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-3</link>
		<comments>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-3#comments</comments>
		<pubDate>Mon, 30 Nov 2009 11:57:53 +0000</pubDate>
		<dc:creator>Juozas</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[speed]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://dev.juokaz.com/?p=909</guid>
		<description><![CDATA[ During last two months I spent massive amount of time tweaking Doctrine ORM framework and making it to perform as fast as possible (as you might have noticed from my never ending tweets). This post is devoted to performance and efficiency, with practical tips &#038; tricks how to reduce memory usage, make it work [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://dev.juokaz.com/wp-content/uploads/2009/11/doctrine-orm-php5.png" alt="doctrine-orm-php5" title="doctrine-orm-php5" width="191" height="53" class="alignnone size-full wp-image-847" style="margin-right: 5px;" /> During last two months I spent massive amount of time tweaking Doctrine ORM framework and making it to perform as fast as possible (as you might have noticed from my never ending <a href="http://twitter.com/juokaz">tweets</a>). This post is devoted to performance and efficiency, with practical tips &#038; tricks how to reduce memory usage, make it work faster and save resources.</p>
<p>Doctrine is a very powerful framework, however you should study its behavior a little bit to get it working properly. As it turns out &#8211; it&#8217;s not that hard. </p>
<h5>Speed</h5>
<p>One of the first things I recommend looking at is <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/caching:query-cache-&#038;-result-cache">query cache</a>. Because there is quite a lot happening in turning <a href="http://www.doctrine-project.org/documentation/manual/1_2/nl/dql-doctrine-query-language">DQL</a> statement into the SQL query, <strong>caching</strong> that process can increase performance by a big margin. Best choice &#8211; <a href="http://en.wikipedia.org/wiki/PHP_accelerator">APC</a>, although robo47.net has an <a href="http://www.robo47.net/codeschnipsel/32-Adapter-fuer-Doctrine_Cache-zu-Zend_Cache">example</a> code for use of Zend_Cache adapters, just don&#8217;t forget that file back-end is probably not the best pick.</p>
<p><strong>Hydrators</strong> are probably the easiest thing to misuse. Hydration in Doctrine language is turning SQL query results into data graph. It can be an array, object or single value. It&#8217;s very nice to get results as PHP objects (in this case &#8211; models), however it&#8217;s slow. Slower than hydrating like array, and much slower than getting raw result from <a href="http://uk2.php.net/manual/en/book.pdo.php">PDO</a>. That&#8217;s why I always recommend answering one simple question: &#8220;will you be updating/deleting records?&#8221;. If the answer is no &#8211; hydrate as array, because you are not going to need an actual model (usually).</p>
<p>For this reason I always try to use array notation to access properties rather than like-object-vars one. Basically instead of <em>$product->name</em> I tend to write <em>$product['name']</em>, which returns the same result, but makes <strong>switching to array hydration very easy</strong>. You can find more tips and tricks at Doctrine manual <a href="http://www.doctrine-project.org/documentation/manual/1_2/en/data-hydrators">here</a>, but the key moment is to remember that the faster data structure in PHP is array (I believe so), so if application is not performing well &#8211; start playing with hydrations first.</p>
<p>Doctrine has a very nice support for relations, where they work like proxies and data can be retrieved when it&#8217;s needed (lazy-loading). However, this is wrong:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$user</span> <span style="color: #339933;">=</span> Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'User'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">find</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$user</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Comments</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$comment</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #b1b100;">print</span> <span style="color: #000088;">$comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">NewsItem</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;br /&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>This code is bad, because for each <em>comment</em> you will load <em>news item</em> using a <strong>separate query</strong>, hence you are wasting db server resources and making code slower. Optimization is pretty straightforward:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> Doctrine_Query<span style="color: #339933;">::</span><span style="color: #004000;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">from</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Comments C'</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">-&gt;</span><span style="color: #004000;">innerJoin</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'C.NewsItem N'</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">-&gt;</span><span style="color: #004000;">where</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'C.user_id = ?'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$comment</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #b1b100;">print</span> <span style="color: #000088;">$comment</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">NewsItem</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">title</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;br /&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Here all the data is loaded in <strong>one query</strong> and everything happens much faster (and in this case making it to hydrate as array would also improve the performance).</p>
<p>However, make sure you <strong>know what you are joining</strong>. For example imagine that in previous example <em>news item</em> is also one-to-many (comment has many news items) relation and user <em>1</em> has written 1000 comments where each comment is attached to average <em>news items</em>. Query above will return 50&#8242;000 records (<a href="http://en.wikipedia.org/wiki/Cross_product">50 * 1000</a>) which Doctrine will need to hydrate then. This will be very slow and probably going to kill your web server after some time. One day I had a query which was returning 2GB of data, server admins where probably not very happy about it&#8230;</p>
<h5>Memory</h5>
<p>One of my favorite parts of software development is playing with memory usage and making it efficient. Even though it sounds really simple, debugging it and finding it where the memory is <a href="http://en.wikipedia.org/wiki/Memory_leak">leaking</a> is not an easy task. Recently I was using Doctrine to work with quite big datasets (on average 50&#8242;000 of records) and probably have tried all the possible tricks to make Doctrine memory efficient. My code looked really simple:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$data</span> <span style="color: #339933;">=</span> Doctrine_Query<span style="color: #339933;">::</span><span style="color: #004000;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$item</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// do some work here</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>You might expect that memory usage would be steady, however it is not. Doctrine uses <a href="http://martinfowler.com/eaaCatalog/identityMap.html">identity map</a> and objects also have a lot of references which makes <strong>freeing up memory</strong> a tricky job. As my experience showed, even though records have a method <em>free()</em> which is supposed to de-reference it, sometimes it doesn&#8217;t help.</p>
<p>So to make memory management work, make sure to try these:</p>
<ul>
<li><strong>$record->free(true)</strong> &#8211; deep free-up, calls <em>free()</em> on all relations too</li>
<li><strong>$collection->free()</strong> &#8211; free all collection references</li>
<li><strong>Doctrine_Manager::connection()->clean()</strong> &#8211; cleanup connection (and remove identity map entries)</li>
</ul>
<p>With some debugging and profiling (and these methods) you hopefully can make memory usage to be low. I&#8217;m also using some custom iterators (available <a href="http://github.com/juokaz/php-examples/tree/master/doctrine-iterators/">here</a>) to <strong>divide query into chunks</strong>, because loading 50&#8242;000 of objects in one go is not going to work, so you might want to look at it too. </p>
<p>Another recommended tip: make sure to <strong>free queries</strong> too. As collections hold references to all records, query object also has some references to parsed sub-parts of query. For this I use auto-free setting enabled by (available in my first part post also <a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-1">here</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// enable automatic queries resource freeing</span>
<span style="color: #000088;">$manager</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setAttribute</span><span style="color: #009900;">&#40;</span>
	Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">ATTR_AUTO_FREE_QUERY_OBJECTS</span><span style="color: #339933;">,</span>
	<span style="color: #009900; font-weight: bold;">true</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>It&#8217;s very easy to forget to free a query and it&#8217;s again creating these references which makes <a href="http://php.net/manual/en/function.gc-enable.php">garbage collector</a>&#8217;s work hard. Nevertheless, after enabling this one I don&#8217;t know any other place where the memory can start to leak.</p>
<p>Last step &#8211; <strong>PHP 5.3</strong>. I&#8217;ve been working with this version for a few months and it works great, so if it&#8217;s possible &#8211; I recommend using it (you will also help with testing frameworks, but both Zend Framework and Doctrine already should work fine). One important function here is <a href="http://php.net/releases/5_3_0.php">improved</a> garbage collector, so the actual script takes less memory to execute. I haven&#8217;t recorded benchmarks on this one, but what I&#8217;ve noticed during development is that 5.3 does in fact has a lower peak memory usage. </p>
<h5>Conclusion</h5>
<p>I think I haven&#8217;t missed anything here, or at least these are the tips which made applications work fast (if I have &#8211; let me know). To finish with &#8211; good optimizations are done by comprehensive benchmarking and profiling, so the fact that Doctrine is a big framework doesn&#8217;t necessary mean it&#8217;s slow too. At the end of the day, it&#8217;s usually only a matter of reading a manual. </p>
<p><strong>All parts</strong>:</p>
<ol>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-1">Zend Framework and Doctrine. Part 1</a></li>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-2">Zend Framework and Doctrine. Part 2</a></li>
<li><a href="http://dev.juokaz.com/php/zend-framework-and-doctrine-part-3">Zend Framework and Doctrine. Part 3</a></li>
</ol>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.juokaz.com/php/zend-framework-and-doctrine-part-3/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>E-commerce sales tracking with Google Analytics</title>
		<link>http://dev.juokaz.com/google/e-commerce-sales-tracking-with-google-analytics</link>
		<comments>http://dev.juokaz.com/google/e-commerce-sales-tracking-with-google-analytics#comments</comments>
		<pubDate>Wed, 25 Feb 2009 14:56:10 +0000</pubDate>
		<dc:creator>Juozas</dc:creator>
				<category><![CDATA[Google]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[e-commerce]]></category>
		<category><![CDATA[e-shop]]></category>
		<category><![CDATA[free]]></category>
		<category><![CDATA[google analytics]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[orders]]></category>
		<category><![CDATA[profit]]></category>
		<category><![CDATA[sales]]></category>
		<category><![CDATA[shop]]></category>
		<category><![CDATA[tracker]]></category>

		<guid isPermaLink="false">http://dev.juokaz.com/?p=267</guid>
		<description><![CDATA[Google Analytics is default choice for visitors tracking, but it can be also used for sales statistics. I have been working with e-commerce projects for a while, and have implemented very powerful back-end statistics tools, but I always try to search for easier to use (and functional enough) tools. Today I&#8217;m going to talk about [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.google.com/analytics">Google Analytics</a> is default choice for visitors tracking, but it can be also used for sales statistics. I have been working with e-commerce projects for a while, and have implemented very powerful back-end statistics tools, but I always try to search for easier to use (and functional enough) tools. Today I&#8217;m going to talk about E-commerce functionality in Google Analytics &#8211; free and easy to use online tool.</p>
<p><img class="size-full wp-image-277" style="float: right;" title="E-commerce" src="http://dev.juokaz.com/wp-content/uploads/2009/02/ecommerce-overview-google-analytics_1235571575598.png" alt="E-commerce" width="284" height="248" />E-commerce tracker works like normal Google analytics code, it&#8217;s simply part of it. Your job is to decide when to supply Google with transaction information, but I see only one logical time &#8211; right after confirmed payment.</p>
<p>To track your transactions you <strong>need</strong> to have &#8220;Success page&#8221;, a page, where users will be redirected after successful payment. If you don&#8217;t have such, you probably won&#8217;t be able to track transactions &#8211; it&#8217;s possible to submit transactions in other pages, but only submitting them in success page would give correct results (further details below). If you have tried Goals in analytics, you know what I&#8217;m talking about.</p>
<p>In your success page you need to slightly modify current Analytics tracker code. Google has very good API documentation available at <a href="http://code.google.com/apis">code.google.com/apis</a>, and all required information for transactions tracking is <a href="http://code.google.com/apis/analytics/docs/gaJSApiEcommerce.html">here</a> (yes, only 3 functions). Sample transaction code is this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #003366; font-weight: bold;">var</span> gaJsHost <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;https:&quot;</span> <span style="color: #339933;">==</span> document.<span style="color: #660066;">location</span>.<span style="color: #660066;">protocol</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> 
<span style="color: #3366CC;">&quot;https://ssl.&quot;</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;http://www.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
document.<span style="color: #000066; font-weight: bold;">write</span><span style="color: #009900;">&#40;</span>unescape<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;%3Cscript src='&quot;</span> <span style="color: #339933;">+</span> gaJsHost <span style="color: #339933;">+</span> 
<span style="color: #3366CC;">&quot;google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>script type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
  <span style="color: #003366; font-weight: bold;">var</span> pageTracker <span style="color: #339933;">=</span> _gat._getTracker<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;UA-ANALYTICS-ID&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  pageTracker._trackPageview<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// Track pageview</span>
&nbsp;
  pageTracker._addTrans<span style="color: #009900;">&#40;</span>
    <span style="color: #3366CC;">&quot;1234&quot;</span><span style="color: #339933;">,</span>                    <span style="color: #006600; font-style: italic;">// Order ID</span>
    <span style="color: #3366CC;">&quot;Mountain View&quot;</span><span style="color: #339933;">,</span>           <span style="color: #006600; font-style: italic;">// Store name</span>
    <span style="color: #3366CC;">&quot;11.99&quot;</span><span style="color: #339933;">,</span>                   <span style="color: #006600; font-style: italic;">// Total</span>
    <span style="color: #3366CC;">&quot;1.29&quot;</span><span style="color: #339933;">,</span>                    <span style="color: #006600; font-style: italic;">// Tax</span>
    <span style="color: #3366CC;">&quot;5&quot;</span><span style="color: #339933;">,</span>                       <span style="color: #006600; font-style: italic;">// Shipping</span>
    <span style="color: #3366CC;">&quot;San Jose&quot;</span><span style="color: #339933;">,</span>                <span style="color: #006600; font-style: italic;">// City</span>
    <span style="color: #3366CC;">&quot;California&quot;</span><span style="color: #339933;">,</span>              <span style="color: #006600; font-style: italic;">// State</span>
    <span style="color: #3366CC;">&quot;USA&quot;</span>                      <span style="color: #006600; font-style: italic;">// Country</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  pageTracker._addItem<span style="color: #009900;">&#40;</span>
    <span style="color: #3366CC;">&quot;1234&quot;</span><span style="color: #339933;">,</span>                    <span style="color: #006600; font-style: italic;">// Order ID</span>
    <span style="color: #3366CC;">&quot;DD44&quot;</span><span style="color: #339933;">,</span>                    <span style="color: #006600; font-style: italic;">// Product code</span>
    <span style="color: #3366CC;">&quot;T-Shirt&quot;</span><span style="color: #339933;">,</span>                 <span style="color: #006600; font-style: italic;">// Product Name </span>
    <span style="color: #3366CC;">&quot;Green Medium&quot;</span><span style="color: #339933;">,</span>            <span style="color: #006600; font-style: italic;">// Category</span>
    <span style="color: #3366CC;">&quot;11.99&quot;</span><span style="color: #339933;">,</span>                   <span style="color: #006600; font-style: italic;">// Price</span>
    <span style="color: #3366CC;">&quot;1&quot;</span>                        <span style="color: #006600; font-style: italic;">// Quantity</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  pageTracker._addItem<span style="color: #009900;">&#40;</span>..<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>    <span style="color: #006600; font-style: italic;">// Another Item</span>
&nbsp;
  pageTracker._trackTrans<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>   <span style="color: #006600; font-style: italic;">// Track transaction</span>
&nbsp;
<span style="color: #339933;">&lt;/</span>script<span style="color: #339933;">&gt;</span></pre></div></div>

<p>What you do, is tell Google unique order ID, prices, shipping location and items information. All these parameters will later be used to analyse your sales and give information about popular products, customers habits, etc. Basically, Google analytics is easy way to merge your traffic and sales statistics.</p>
<p>E-commerce tracking has problems too. Most problems arise from success page requirement. For example, in PayPal customer can choose not to go back to shop. PayPal will send payment notification, but because user doesn&#8217;t visit your website, you&#8217;ve <em>lost</em> one transaction. It&#8217;s possible to supply transaction information as soon as user visits website again, but statistics won&#8217;t be accurate &#8211; user will probably come again from different source, different keywords, or even different month.</p>
<p>However, I recommend trying Google E-commerce tracking for all shops, especially small ones, because they probably don&#8217;t have good inside statistics. Statistics in back-end are always much more accurate and informative, but they require much more time and are really harder to implement than adding 20 lines of code. I&#8217;d vote for good back-end statistics and Google analytics for visitors vs. buyers analysis.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.juokaz.com/google/e-commerce-sales-tracking-with-google-analytics/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Server &#8211; complete PHP environment in minutes</title>
		<link>http://dev.juokaz.com/php/zend-server-complete-php-environment-in-minutes</link>
		<comments>http://dev.juokaz.com/php/zend-server-complete-php-environment-in-minutes#comments</comments>
		<pubDate>Thu, 19 Feb 2009 17:06:59 +0000</pubDate>
		<dc:creator>Juozas</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Servers]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[environment]]></category>
		<category><![CDATA[installation]]></category>
		<category><![CDATA[localhost]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[tests]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend server]]></category>

		<guid isPermaLink="false">http://dev.juokaz.com/?p=189</guid>
		<description><![CDATA[I believe that everyone who develops in PHP knows Zend (I know them from certification which I&#8217;ve done some time ago), especially now, when Zend Framework is more and more popular. Zend also makes (and probably specializes) software for web servers &#8211; Zend Guard, Zend Optimizer, etc. Recently Zend introduced new product &#8211; Zend Server. [...]]]></description>
			<content:encoded><![CDATA[<p>I believe that everyone who develops in <a href="http://www.php.net">PHP</a> knows <a href="http://www.zend.com">Zend</a> (I know them from certification which I&#8217;ve done some time ago), especially now, when <a href="http://framework.zend.com/">Zend Framework</a> is more and more popular. Zend also makes (and probably specializes) software for web servers &#8211; Zend Guard, Zend Optimizer, etc. Recently Zend introduced new product &#8211; <a href="http://www.zend.com/en/products/server/">Zend Server</a>. They introduce it by:</p>
<blockquote><p>Zend Server is a complete, enterprise-ready Web Application Server for running and managing PHP applications that require a high level of reliability, performance and security.</p></blockquote>
<p>I haven&#8217;t tried it &#8211; probably it will be commercial solution (Zend Studio == <a href="http://www.zend.com/en/products/platform/">Zend Platform</a>?) and I&#8217;m not looking for one right one. So I jumped over to <a href="http://www.zend.com/en/community/zend-server-ce">Zend Server CE</a> (Community Edition) which is:</p>
<blockquote><p>The free community edition of Zend Server enables you to set up a complete PHP environment in minutes, and run non-critical PHP applications in development, testing and production</p></blockquote>
<p>Main <a href="http://www.zend.com/en/products/server/editions">differences</a> lie deep inside PHP configuration &#8211; not-community version is much more tweaked for performance and production servers, where community edition is for development environments.</p>
<p>To start with, installing Zend Server is a joke and can be done in no-time. Download one file from <a href="http://www.zend.com/en/products/server/downloads-all">here</a>, extract it and run in terminal. Thats it! After installation web server was accessible on localhost:10088 and web-based configuration on localhost:10082/ZendServer. Everything worked smoothly and without any errors.</p>
<p><a href="http://dev.juokaz.com/wp-content/uploads/2009/02/screenshot-juokazthinkpad-desktop-zendserver-400beta1ms16rc8-linux-glibc23-i386.png"><img class="alignnone size-full wp-image-190" title="Zend Server installation" src="http://dev.juokaz.com/wp-content/uploads/2009/02/screenshot-juokazthinkpad-desktop-zendserver-400beta1ms16rc8-linux-glibc23-i386.png" alt="Zend Server installation" width="500" height="376" /></a></p>
<p>Web interface gives access to server logs, PHP parameters (allows  you to change them, restart server), extensions, debugger, Zend products configuration (Optimizer, Java Bridge, etc.) and some more. If they just add Apache VirtualHosts configuration it would be perfect for me, because I&#8217;m still doing it by hand.</p>
<p>Performance is subjective and can&#8217;t be judged fast, so I&#8217;m not going to compare this package to standalone servers. Probably it will run faster or at least as fast as default configuration Apache+PHP. I do believe that Zend made some configuration improvements, but you only need them if you can&#8217;t (or are to lazy) do them yourself.</p>
<p>I have been using standard <a href="http://httpd.apache.org/">Apache</a>, PHP, MySQL servers for ages, and haven&#8217;t really ever tried anything like this. It&#8217;s really user friendly, gives a lot of power through simple interface, and what&#8217;s most important is very easy to setup. Probably Xampp (or just running <em>sudo apt-get install apache2 php5</em>) can be installable as fast as Zend Server, but in my belief, Zend Server is much more production-like environment. Depends what you need.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.juokaz.com/php/zend-server-complete-php-environment-in-minutes/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Correct headers for dynamically generated content</title>
		<link>http://dev.juokaz.com/php/correct-headers-for-dynamically-generated-content</link>
		<comments>http://dev.juokaz.com/php/correct-headers-for-dynamically-generated-content#comments</comments>
		<pubDate>Sun, 15 Feb 2009 19:00:39 +0000</pubDate>
		<dc:creator>Juozas</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Websites]]></category>
		<category><![CDATA[headers]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[load time]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[speed]]></category>
		<category><![CDATA[tips]]></category>
		<category><![CDATA[uahoo]]></category>
		<category><![CDATA[yahoo]]></category>
		<category><![CDATA[yslow]]></category>

		<guid isPermaLink="false">http://dev.juokaz.com/?p=155</guid>
		<description><![CDATA[Static images have correct headers &#8211; Apache sends them by default. Different story is with all dynamic generating content &#8211; if you don&#8217;t send correct headers user&#8217;s browser will load it every time. It&#8217;s not always good, because generated thumbnails doesn&#8217;t change every time and should be cached in browser&#8217;s cache. If you want to [...]]]></description>
			<content:encoded><![CDATA[<p>Static images have correct headers &#8211; Apache sends them by default. Different story is with all dynamic generating content &#8211; if you don&#8217;t send correct headers user&#8217;s browser will load it every time. It&#8217;s not always good, because generated thumbnails doesn&#8217;t change every time and should be cached in browser&#8217;s cache. If you want to reduce server load and increase loading speed you definitely need to send correct headers.</p>
<p>Our task is to give browser enough information to identify content, which later can be used to decided if content has changed, and if not &#8211; say it to browser without sending content again. Bigger picture is explained <a href="http://thoughtpad.net/alan-dean/http-headers-status.jpg">here</a>, I really recommend analysing it a little bit &#8211; it gives better understanding how headers work and what they mean.</p>
<p>As you saw in <a href="http://thoughtpad.net/alan-dean/http-headers-status.jpg">headers map</a>, there are many possible headers to send, but we can focus on three of them:</p>
<ol>
<li>Etag. Unique identified for output data (maybe hash)</li>
<li>Last-Modified. Date of last data modification</li>
<li>Expires. When to expire content</li>
</ol>
<p>Constructing algorithm is pretty simple, it can be explained in pseudo-code:</p>
<pre>get request headers
   is content expired
      send content, new headers
   else is content different (Etag)
      send content, new headers
   else
      304 header, no content</pre>
<p>I&#8217;ve created <em>outputCacheHeaders(&#8230;)</em> function which (available <a href="http://dev.juokaz.com/examples/expires-etag/headers.phps">here</a>) outputs all required headers and returns true if you need to output content or false if not. All you need to do is pass modification time, live time and data (two last ones are not required). Live time says how long should cache be kept and data is used to generate Etag. Very simple!</p>
<p>After enabling correct headers sending, my websites started to feel much faster, because HTTP requests takes much less time. Also, <a href="http://developer.yahoo.com/performance/rules.html">Yahoo performance tips</a> are really worth reading, really. There are many great tips and I have been using many of them for a long time. These tricks are much much more significant than 0.1 s. faster PHP rendering time.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.juokaz.com/php/correct-headers-for-dynamically-generated-content/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Easy javascript packing with PHP</title>
		<link>http://dev.juokaz.com/php/easy-javascript-packing-with-php</link>
		<comments>http://dev.juokaz.com/php/easy-javascript-packing-with-php#comments</comments>
		<pubDate>Thu, 05 Feb 2009 00:14:00 +0000</pubDate>
		<dc:creator>Juozas</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Websites]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[firebug]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[packed]]></category>
		<category><![CDATA[requests]]></category>
		<category><![CDATA[website speed]]></category>

		<guid isPermaLink="false">http://dev.juokaz.com/?p=24</guid>
		<description><![CDATA[&#8220;JavaScript packing&#8221; is method for reducing JavaScript files size by removing all unnecessary data (obfuscating) and compressing it&#8217;s contents. Most popular is Dean Edward&#8217;s packer, which transforms JavaScripts into something like this:

eval&#40;function&#40;p,a,c,k,e,r&#41;&#123;...

To start with, it&#8217;s very easy to have dynamically packed files (no one wants to pack them by hand, packed versions are only useful [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;JavaScript packing&#8221; is method for reducing JavaScript files size by removing all unnecessary data (<em>obfuscating</em>) and compressing it&#8217;s contents. Most popular is <a href="http://dean.edwards.name/packer/">Dean Edward&#8217;s packer</a>, which transforms JavaScripts into something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>p<span style="color: #339933;">,</span>a<span style="color: #339933;">,</span>c<span style="color: #339933;">,</span>k<span style="color: #339933;">,</span>e<span style="color: #339933;">,</span>r<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>...</pre></div></div>

<p>To start with, it&#8217;s very easy to have dynamically packed files (no one wants to pack them by hand, packed versions are only useful for production, debugging them is harder) with PHP. One of many PHP packers is available on-line at <a href="http://joliclic.free.fr/php/javascript-packer/en/">http://joliclic.free.fr/php/javascript-packer/en/</a>. It&#8217;s simple one-file script which works really well.</p>
<p>JavaScript packing is as simple as:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require</span> <span style="color: #0000ff;">'class.JavaScriptPacker.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$src</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'my_script.js'</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Script file</span>
<span style="color: #000088;">$script</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$src</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$packer</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> JavaScriptPacker<span style="color: #009900;">&#40;</span><span style="color: #000088;">$script</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'Normal'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$packed</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$packer</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">pack</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">header</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-type: text/javascript; charset=utf-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">header</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-Length: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$packed</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$packed</span><span style="color: #339933;">;</span></pre></div></div>

<p><em>* Parameters for JavaScriptPacker object can be easily tested in project <a href="http://joliclic.free.fr/php/javascript-packer/en/">website</a>. </em><em>Sometimes packed javascripts don&#8217;t work because of missing &#8220;;&#8221; symbols. I used <a href="http://www.getfirebug.com">FireBug</a> extension for Firefox to find actual problematic lines in unpacked version and correct them. </em></p>
<p>Using this class I created controller for all my JavaScripts, which gets JavaScript name from GET call, checks for cached version and if packed version is not cached &#8211; creates <em>1 day</em> cache and outputs it. Also, I pass JavaScript name in special form: &#8220;filename1-filename2-&#8230; .js&#8221; what let&#8217;s me merge multiple files into one packed version. (<em>it can be optimized even more by storing cached versions as static files and accessing them directly</em>)</p>
<p>Packer alone cannot make a big difference, but by combining it with:</p>
<ul>
<li>multiple files merging</li>
<li>caching (correct headers)</li>
<li>then packing</li>
<li>putting JavaScripts at the bottom of document</li>
</ul>
<p>gives very good results, not only decreasing HTTP calls count, but also time required to render whole website. Still, it&#8217;s very easy to implement whole system since all required libraries (packer, caching, etc.) are available on-line for free.</p>
]]></content:encoded>
			<wfw:commentRss>http://dev.juokaz.com/php/easy-javascript-packing-with-php/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
