<?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>alex.moskalyuk &#187; PHP</title>
	<atom:link href="http://www.moskalyuk.com/blog/category/programming/php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.moskalyuk.com/blog</link>
	<description></description>
	<lastBuildDate>Mon, 30 Nov 2009 19:37:42 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Top scalability&#160;mistakes</title>
		<link>http://www.moskalyuk.com/blog/top-scalability-mistakes/1563</link>
		<comments>http://www.moskalyuk.com/blog/top-scalability-mistakes/1563#comments</comments>
		<pubDate>Tue, 29 Jul 2008 06:13:59 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Security]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/top-scalability-mistakes/1563</guid>
		<description><![CDATA[John Coggeshall, CTO of Automotive Computer Services, and author of Zend PHP Certification Practice Book and PHP5 Unleashed, gave a talk at OSCON 2008 on top 10 scalability mistakes. I wasn&#8217;t there, but he posted the slides for everybody to follow. Here&#8217;re some lessons learned. Define the scalability goals for your application. If you don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.coggeshall.org/">John Coggeshall</a>, CTO of Automotive Computer Services, and author of <a href="http://www.amazon.com/gp/product/0973589884/002-0161606-1322478?ie=UTF8&amp;tag=moskalyukcom-20&amp;linkCode=xm2&amp;camp=1789&amp;creativeASIN=0973589884">Zend PHP Certification Practice Book</a> and <a href="http://www.amazon.com/gp/product/067232511X/002-0161606-1322478?ie=UTF8&amp;tag=moskalyukcom-20&amp;linkCode=xm2&amp;camp=1789&amp;creativeASIN=067232511X">PHP5 Unleashed</a>, <a href="http://www.coggeshall.org/resources/slideshow/id/530124">gave a talk</a> at <strong>OSCON 2008</strong> on top 10 scalability mistakes. I wasn&#8217;t there, but he posted the slides for everybody to follow. Here&#8217;re some lessons learned.</p>
<ol>
<li><strong>Define the scalability goals for your application</strong>. If you don&#8217;t know how many requests you&#8217;re shooting for, you don&#8217;t know whether you&#8217;ve built something that works, and how long it&#8217;s going to last you. </li>
<li><strong>Measure everything</strong>. CPU usage, memory usage, disk I/O, network I/O, requests per second, with the last one being the most important. If you don&#8217;t know the baseline, you don&#8217;t know whether you&#8217;ve improved. </li>
<li><strong>Design your database with scalability in mind</strong>. Assume you&#8217;ll have to implement replication. </li>
<li><strong>Do not rely on NFS for code sharing on a server farm</strong>. It&#8217;s slow and it&#8217;s got locking issues. While the idea of keeping one copy of code, and letting the rest of the servers load them via NFS might seem very convenient, it doesn&#8217;t work in practice. Stick to some tried practices like <a href="http://www.moskalyuk.com/blog/rsync-overview">rsync</a>. Keep the code local to the machine serving it, even if it means a longer push process. </li>
<li><strong>Play around with I/O buffers</strong>. If you&#8217;ve got tons of memory, play with TCP buffer size &#8211; your defaults are likely to be set conservatively. See your tax dollars at work and use this <a href="http://acs.lbl.gov/TCP-tuning/linux.html">Linux TCP Tuning guide</a>. If your site is written in PHP, use <a href="http://www.php.net/outcontrol">output buffering functions</a>. </li>
<li><strong>Use Ram Disks for any data that&#8217;s disposable</strong>. But you do need a lot of available RAM lying around. </li>
<li><strong>Optimize bandwidth consumption</strong> by enabling compression via mod_deflate, setting zlib.put_compression value to true for PHP sites, or Tidy content reduction for PHP+Tidy sites. </li>
<li><strong>Confugure PHP for speed</strong>. Turn off the following: register_globals, auto_globals_jit, magic_quotes_gpc, expose_php, register_argc_argv, always_populate_raw_post_data, session.use_trans_sid, session.auto_start. Set session.gc_divisor to 10,000, output_buffering to 4096, in John&#8217;s example. </li>
<li><strong>Do not use blocking I/O, such as reading another remote page via curl</strong>. Make all the calls non-blocking, otherwise the wait is something you can&#8217;t really optimize against. Rely on background scripts to pull down the data necessary for processing the request. </li>
<li><strong>Don&#8217;t underestimate caching</strong>. If a page is cached for 5 minutes, and you get even 10 requests per second for a given page, that&#8217;s 3,000 requests your database doesn&#8217;t have to process. </li>
<li><strong>Consider PHP op-code cache</strong>. This will be available to you off-the-shelf with PHP6. </li>
<li><strong>For content sites consider taking static stuff out of dynamic context</strong>. Let&#8217;s say you run a content site, where the article content remains the same, while the rest of the page is personalized for each user, as it has My Articles section, and so on. Instead of getting everything dynamically from the DB, consider generating yet another PHP file on the first request, where the article text would be stored in raw HTML, and dynamic data pulled for logged-in users. This way the generated PHP file will only pull out the data that&#8217;s actually dynamic. </li>
<li><strong>Pay great attention to database design</strong>. Learn indexes and know how to use them properly. InnoDB outperforms MyISAM in almost all contexts, but doesn&#8217;t do full-text searching. (Use <a href="http://www.sphinxsearch.com/">sphinx</a> if your search needs get out of control.) </li>
<li><strong>Design PHP applications in an abstract way</strong>, so that the app never needs to know the IP address of the MySQL server. Something like &#8216;mysql-writer-db&#8217;, and &#8216;mysql-reader-db&#8217; will be perfectly ok for a PHP app. </li>
<li><strong>Run external scripts monitoring the system health</strong>. Have the scripts change the HOSTS if things get out of control. </li>
<li><strong>Do not do database connectivity decision-making in PHP</strong>. Don&#8217;t spend time doing fallbacks if your primary DB is down. Consider running <a href="http://dev.mysql.com/tech-resources/articles/proxy-gettingstarted.html">MySQL Proxy</a> for simplifying DB connectivity issues. </li>
<li><strong>For super-fast reads consider SQLite</strong>.&#160; But don&#8217;t forget that it&#8217;s horrible with writes. </li>
<li><strong>Use Keepalive properly</strong>. Use it when both static and dynamic files are served off the same server, and you can control the timeouts, so that a bunch of Keep-alive requests don&#8217;t overwhelm your system. John&#8217;s rule? No Keep-alive request should last more than 10 seconds. </li>
<li><strong>Monitor via familiar Linux commands</strong>. Such as <a href="http://linux.die.net/man/1/iostat">iostat</a> and <a href="http://linuxcommand.org/man_pages/vmstat8.html">vmstat</a>. The iostat command is used for monitoring system input/output device loading by observing the time the devices are active in relation to their average transfer rates. The iostat command generates reports that can be used to change system configuration to better balance the input/output load between physical disks. vmstat&#160; reports&#160; information about processes, memory, paging, block IO, traps, and cpu activity. </li>
<li><strong>Make sure you&#8217;re logging relevant information right away</strong>. Otherwise debugging issues is going to get tricky. </li>
<li><strong>Prioritize your optimizations</strong>. Optimization by 50% of the code that runs on 2% of the pages will result in 1% total improvement. Optimizing 10% of the code that runs on 80% of the pages results in 8% overall improvement. </li>
<li><strong>Use profilers</strong>. They draw pretty graphs, they&#8217;re generally easy to use. </li>
<li><strong>Keep track of your system performance</strong>. Keep a spreadsheet of some common stats you&#8217;re tracking, so that you can authoritatively say how much of performance gain you got by getting a faster CPU, installing extra RAM, or upgrading your Linux kernel. </li>
</ol>
<p>Complete presentation is down below:</p>
</p>
<div id="__ss_530124" style="width: 425px; text-align: left"><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=top-10-scalability-mistakes-oscon-1217182496499410-8" width="425" height="355" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" />
<div style="font-size: 11px; padding-top: 2px; font-family: tahoma,arial; height: 26px"><a href="http://www.slideshare.net/?src=embed"><img style="border-right: 0px; border-top: 0px; margin-bottom: -5px; border-left: 0px; border-bottom: 0px" alt="SlideShare" src="http://static.slideshare.net/swf/logo_embd.png" /></a> | <a title="View this slideshow on SlideShare" href="undefined">View</a> | <a href="http://www.slideshare.net/upload">Upload your own</a></div>
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/top-scalability-mistakes/1563/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>24 Web site performance&#160;tips</title>
		<link>http://www.moskalyuk.com/blog/24-web-site-performance-tips/1535</link>
		<comments>http://www.moskalyuk.com/blog/24-web-site-performance-tips/1535#comments</comments>
		<pubDate>Sun, 30 Mar 2008 07:17:03 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/?p=1535</guid>
		<description><![CDATA[Yahoo! Developer Network blog had an entry by Stoyan Stefanov and presentation from PHP Quebec conference. A few points to take away, in case you don&#8217;t feel like going through 76-slide presentation: A drop of 100ms in page rendering time leads to 10% in sales on Amazon. A drop of 500 ms leads to 20% [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Yahoo! Developer Network</strong> blog had <a href="http://developer.yahoo.net/blog/archives/2008/03/yahoos_latest_p.html">an entry by Stoyan Stefanov</a> and presentation from PHP Quebec conference. A few points to take away, in case you don&#8217;t feel like going through 76-slide presentation:</p>
<ol>
<li>A drop of 100ms in page rendering time leads to 10% in sales on Amazon. A drop of 500 ms leads to 20% less traffic to Google.</li>
<li>Make fewer HTTP requests &#8211; combine CSS and JS files into single downloads. Minify both JS and CSS.</li>
<li>Combine images into <a href="http://www.csssprites.com/">CSS sprites</a>.</li>
<li>Bring static content closer to the users. That usually means CDNs like Akamai or Limelight, but sometimes a co-location facility or data center in a foreign country is the only option.</li>
<li>Static content should have Expires: headers way into the future, so that they&#8217;re never re-requested.</li>
<li>Dynamic content should have Cache Control: header.</li>
<li>Offer content gzip&#8217;ed.</li>
<li>Stoyan claims nothing will be rendered in the browser till the last piece of CSS has been served, and therefore it&#8217;s critical to send CSS as early in the process as possible. I happen to have <a href="http://www.moskalyuk.com/">a document</a> with CSS declared at the very end, and disagree with this statement &#8211; at least the content <em>seems</em> to render OK without CSS, and then self-corrects when CSS finally loads.</li>
<li>Move the scripts all the way to the bottom to avoid the download block &#8211; Stoyan&#8217;s example shows placing the javascript includes right before &lt;/body&gt; and &lt;/html&gt;, although it&#8217;s possible to place them even further down (well, you&#8217;d break XHTML purity, I suppose, if you declare your documents to be XHTML).</li>
<li>Avoid CSS expressions.</li>
<li>Consider placing the minified CSS and JS files on separate servers to fight browser&#8217;s default pipelining settings &#8211; not everybody has <a href="http://fasterfox.mozdev.org/">FasterFox</a> or tweaked pipeline settings.</li>
<li>For super-popular pages consider inlining JS for fewer HTTP requests.</li>
<li>Even though placing content on external servers with different domains will help you with HTTP pipelining, don&#8217;t go crazy with various domains &#8211; they all require DNS lookups.</li>
<li>Every 301 redirect is a wasted HTTP request.</li>
<li>For busy backend servers consider PHP&#8217;s <a href="http://us2.php.net/flush">flush()</a>.</li>
<li>Use GET over POST any time you have a choice.</li>
<li>Analyze your cookies &#8211; large number of them could substantially increase the number of TCP packets.</li>
<li>For faster JavaScript and DOM parsing, reduce the number of DOM elements.</li>
<li>document.getElementByTagName(&#8216;*&#8217;).length will give you the number of total elements. Look at those abusive &lt;div&gt;s.</li>
<li>Any missing JS file is a significant performance penalty &#8211; the browser will browse the 404 page you generate, trying to see if it has valid &lt;script&gt;s.</li>
<li>Optimize your PNGs &#8211; check out <a href="http://pmt.sourceforge.net/pngcrush/">pngcrush</a>, <a href="http://psydk.org/PngOptimizer.php">pngoptimizer</a></li>
<li>Optimize JPEGs &#8211; <a href="http://www.gsp.com/cgi-bin/man.cgi?section=1&amp;topic=jpegtran">jpegtran</a></li>
<li>Make sure you have favicon.ico &#8211; generating those 404s will be expensive, plus once you have it, it&#8217;s cache-able.</li>
<li>Toolkits for measuring page loads: <a href="http://pagetest.wiki.sourceforge.net/">AOL PageTest</a>, <a href="http://www.fiddlertool.com/fiddler/">FiddlerTool</a> HTTP debugging proxy, <a href="http://www.research.ibm.com/pagedetailer/">IBM Page Detailer</a> instrumentation tool, YSlow, and Firebug are suggested in the presentation. My personal addition to the list is <a href="http://www.xk72.com/charles/">Charles</a> that has been recommended by a colleague.</li>
</ol>
<p>And here&#8217;s the whole presentation, although it&#8217;s not possible to follow links from Slideshare slides.
<div style="width:425px;text-align:left" id="__ss_319798"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=high-performance-web-pages-20-new-best-practices-1206389190195598-3"/><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slideshare.net/swf/ssplayer2.swf?doc=high-performance-web-pages-20-new-best-practices-1206389190195598-3" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;"><a href="http://www.slideshare.net/?src=embed"><img src="http://static.slideshare.net/swf/logo_embd.png" style="border:0px none;margin-bottom:-5px" alt="SlideShare"/></a></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/24-web-site-performance-tips/1535/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP + MySQL links of the&#160;day</title>
		<link>http://www.moskalyuk.com/blog/php-mysql-links-of-the-day/1379</link>
		<comments>http://www.moskalyuk.com/blog/php-mysql-links-of-the-day/1379#comments</comments>
		<pubDate>Sun, 25 Feb 2007 00:57:55 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/php-mysql-links-of-the-day/1379</guid>
		<description><![CDATA[Patrick Galbraith from Grazr is describing MySQL multi-master replication, where two nodes replicate each other&#8217;s updates. Useful for the case when you&#8217;re running the product out of multiple data centers, and there is no predictability on where the writes will occur, i.e. both are hot MySQL servers. IBM DeveloperWorks introduces us to XCache on PHP: [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Patrick Galbraith</strong> from <a href="http://grazr.com/">Grazr</a> is <a href="http://capttofu.livejournal.com/1752.html">describing MySQL multi-master replication</a>, where two nodes replicate each other&#8217;s updates. Useful for the case when you&#8217;re running the product out of multiple data centers, and there is no predictability on where the writes will occur, i.e. both are hot MySQL servers.</p>
<p><strong>IBM DeveloperWorks</strong> <a href="http://www-128.ibm.com/developerworks/library/os-php-fastapps1/index.html?ca=drs-">introduces us to XCache on PHP</a>:<br />
<blockquote>XCache is a relative newcomer, but many sites are reporting good results with it. In addition, it is easy to build, install, and configure because it&#8217;s implemented as a PHP extension. Recompiling Apache and PHP isn&#8217;t required. This article is based on XCache V1.2.0. It reliably supports PHP V4.3.11 to V4.4.4, PHP V5.1.x to V5.2.x, and early versions of PHP V6. (XCache doesn&#8217;t support PHP V5.0.x.) XCache works with mod_php and FastCGI, but not with the Common Gateway Interface (CGI) or the command-line PHP interpreter. The XCache source code builds on a variety of systems, including FreeBSD, Sun Solaris, Linux®, and (as shown here) on Mac OS X. XCache can be built on Microsoft® Windows®, as well, using the Cygwin UNIX® emulation environment or Visual C. You can build XCache for Cygwin or for native Win32. The latter target is compatible with the official Win32 release of PHP.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/php-mysql-links-of-the-day/1379/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VIM tips for PHP&#160;developers</title>
		<link>http://www.moskalyuk.com/blog/vim-tips-for-php-developers/1373</link>
		<comments>http://www.moskalyuk.com/blog/vim-tips-for-php-developers/1373#comments</comments>
		<pubDate>Fri, 16 Feb 2007 18:51:10 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/vim-tips-for-php-developers/1373</guid>
		<description><![CDATA[Fresh from VIM talk, I was curious to see Andrei Zmievski post VIM script files from his VIM for PHP programmers presentation. It&#8217;s not one of those 3 page presentations ending with &#8220;Read the VIM manual&#8221; either, it&#8217;s a 77-page guide to optimizing one&#8217;s VIM experience when writing PHP.]]></description>
			<content:encoded><![CDATA[<p>Fresh from <a href="http://www.moskalyuk.com/blog/bram-moolenaar-on-increasing-everyday-efficiency/1369">VIM talk</a>, I was curious to see <strong>Andrei Zmievski</strong> <a href="http://www.gravitonic.com/blog/archives/000357.html">post</a> <a href="http://www.gravitonic.com/do_download.php?download_file=other/andrei-vim-files.tar.gz">VIM script files</a> from his <a href="http://www.gravitonic.com/do_download.php?download_file=talks/vancouver-2007/vim-for-php-programmers.pdf">VIM for PHP programmers</a> presentation. It&#8217;s not one of those 3 page presentations ending with &#8220;Read the VIM manual&#8221; either, it&#8217;s a 77-page guide to optimizing one&#8217;s VIM experience when writing PHP.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/vim-tips-for-php-developers/1373/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some PHP links for the&#160;day</title>
		<link>http://www.moskalyuk.com/blog/some-php-links-for-the-day-2/1346</link>
		<comments>http://www.moskalyuk.com/blog/some-php-links-for-the-day-2/1346#comments</comments>
		<pubDate>Mon, 29 Jan 2007 02:17:13 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/some-php-links-for-the-day-2/1346</guid>
		<description><![CDATA[PHPBuilder runs a chapter from an APress book on PEAR. The chapter is dedicated to using PEAR authentication modules. Pretty much any site you build nowadays allows the users to register, choose a password, validate a password, send a password out when it&#8217;s forgotten, etc. You use the Auth package to authenticate users in your [...]]]></description>
			<content:encoded><![CDATA[<p><strong>PHPBuilder</strong> runs a chapter from an APress book on PEAR. The chapter is dedicated to <a href="http://www.phpbuilder.com/columns/foundations_of_pear20070125.php3">using PEAR authentication modules</a>. Pretty much any site you build nowadays allows the users to register, choose a password, validate a password, send a password out when it&#8217;s forgotten, etc.<br />
<blockquote>You use the Auth package to authenticate users in your site. Out of the box, it supports many different ways of authenticating users, including storage in a database, in files, or even by using SOAP calls. You can even write a custom container object that allows you to write your own method to authenticate users.</p></blockquote>
<p>Donald McArthur over at <strong>NewsForge</strong> <a href="http://programming.newsforge.com/programming/07/01/15/1420219.shtml">creates a generic reusable PHP calendar template</a> that could be used on any site requiring inputting dates:<br />
<blockquote>My design goals were to create a PHP page that would take as input a querystring value in the form of a Unix epoch number that would represent the beginning moment of a particular date. (I chose the Unix epoch number, which represents the number of seconds that have transpired since the start of January 1, 1970, as that was the data my database SQL statement used as a SELECT criteria.) The script would determine the month and year of that value, and create an array holding a Unix epoch number for the beginning moment for each day in that month. The script would then output HTML to display a calendar, with each date a hyperlink back to the original PHP page, with the associated querystring value for that date.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/some-php-links-for-the-day-2/1346/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP&#160;debugging</title>
		<link>http://www.moskalyuk.com/blog/php-debugging/1315</link>
		<comments>http://www.moskalyuk.com/blog/php-debugging/1315#comments</comments>
		<pubDate>Thu, 07 Dec 2006 05:54:40 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/php-debugging/1315</guid>
		<description><![CDATA[Jaime Wong posted a pretty good list of PHP debugging techniques: PHP has two functions which should be your best friends: var_dump and print_r. Both do the same thing: they print out information about a variable in a human-readable form. Some people prefer var_dump, others print_r. Try both and see which one makes more sense [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Jaime Wong</strong> posted <a href="http://adc.jgwong.org/index.php/2006/11/23/effective-bugfixing-techniques-for-php/">a pretty good list of PHP debugging techniques</a>:<br />
<blockquote>PHP has two functions which should be your best friends: var_dump and print_r. Both do the same thing: they print out information about a variable in a human-readable form. Some people prefer var_dump, others print_r. Try both and see which one makes more sense to you, it’s more a personal taste.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/php-debugging/1315/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP class graph&#160;generator</title>
		<link>http://www.moskalyuk.com/blog/php-class-graph-generator/1297</link>
		<comments>http://www.moskalyuk.com/blog/php-class-graph-generator/1297#comments</comments>
		<pubDate>Fri, 17 Nov 2006 18:55:08 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/php-class-graph-generator/1297</guid>
		<description><![CDATA[Ever found yourself with too many PHP classes and not too much understanding of how they all tie together? PHP class graph generator parses your source code directory and produces the dependency graph. Here&#8217;s the bash source file from Jacob Westhoff.]]></description>
			<content:encoded><![CDATA[<p>Ever found yourself with too many PHP classes and not too much understanding of how they all tie together? <a href="http://westhoffswelt.de/blog/index.php?/archives/12-Class-dependency-graph-generation.html">PHP class graph generator</a> parses your source code directory and produces the dependency graph. Here&#8217;s <a href="http://westhoffswelt.de/data/blog/classgraph/generate_class_graph.sh">the bash source file from Jacob Westhoff</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/php-class-graph-generator/1297/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTTP POST without&#160;cURL</title>
		<link>http://www.moskalyuk.com/blog/http-post-without-curl/1293</link>
		<comments>http://www.moskalyuk.com/blog/http-post-without-curl/1293#comments</comments>
		<pubDate>Wed, 15 Nov 2006 19:27:03 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/http-post-without-curl/1293</guid>
		<description><![CDATA[Need to do a HTTP POST, but your PHP for whatever reason does not have access to Curl? Wez Furlong wrote a simple function that does HTTP POST via stream_context_create, which should work out to be faster than Curl-based HTTP POST, since stream functions do not have the overhead.]]></description>
			<content:encoded><![CDATA[<p>Need to do a HTTP POST, but your PHP for whatever reason does not have access to <a href="http://us2.php.net/curl">Curl</a>? <strong>Wez Furlong</strong> wrote <a href="http://netevil.org/node.php?nid=937">a simple function that does HTTP POST</a> via <a href="http://us2.php.net/stream_context_create">stream_context_create</a>, which should work out to be faster than Curl-based HTTP POST, since stream functions do not have the overhead.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/http-post-without-curl/1293/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>More PHP&#160;presentations</title>
		<link>http://www.moskalyuk.com/blog/more-php-presentations/1287</link>
		<comments>http://www.moskalyuk.com/blog/more-php-presentations/1287#comments</comments>
		<pubDate>Mon, 13 Nov 2006 19:48:19 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/more-php-presentations/1287</guid>
		<description><![CDATA[Aaron Wormus put up the slides for his presentations on PHP: * Moving to PHP5 with Style * Planning a PHP4 -> PHP5 platform Rewrite * Advanced PHP Tools (tutorial) All .zip files.]]></description>
			<content:encoded><![CDATA[<p><strong>Aaron Wormus</strong> <a href="http://www.wormus.com/aaron/stories/2006/11/13/zendcon-php-conference-slides-up.html">put up the slides</a> for his presentations on PHP:<br />
 * Moving to PHP5 with Style<br />
 * Planning a PHP4 -> PHP5 platform Rewrite<br />
 * Advanced PHP Tools (tutorial)<br />
All .zip files.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/more-php-presentations/1287/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Avoiding persistent connection with&#160;MySQL</title>
		<link>http://www.moskalyuk.com/blog/avoiding-persistent-connection-with-mysql/1283</link>
		<comments>http://www.moskalyuk.com/blog/avoiding-persistent-connection-with-mysql/1283#comments</comments>
		<pubDate>Mon, 13 Nov 2006 03:16:49 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/avoiding-persistent-connection-with-mysql/1283</guid>
		<description><![CDATA[Over on MySQL performance blog a question of whether the persistent connections are evil is discussed: Not only connects are expensive but you also may run into the trouble establishing number of connections you need. The problem is there can be only so many connections active between Host “Apache” and Host “MySQL”: Port 3306 as [...]]]></description>
			<content:encoded><![CDATA[<p>Over on <strong>MySQL performance blog</strong> a question of <a href="http://www.mysqlperformanceblog.com/2006/11/12/are-php-persistent-connections-evil/">whether the persistent connections are evil</a> is discussed:<br />
<blockquote>Not only connects are expensive but you also may run into the trouble establishing number of connections you need. The problem is there can be only so many connections active between Host “Apache” and Host “MySQL”: Port 3306 as connection in TCP/IP protocol is identified by pair of IP addresses and pair of ports (local port and remote port). Yes if you’re establishing thousands of connections per second you normally do not keep it open for long time, but Operation System does. According to TCP/IP protocol Ports can’t be recycled instantly and have to spend some time in “FIN” stage waiting before they can be recycled.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/avoiding-persistent-connection-with-mysql/1283/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>84 MySQL performance&#160;tips</title>
		<link>http://www.moskalyuk.com/blog/84-mysql-performance-tips/1281</link>
		<comments>http://www.moskalyuk.com/blog/84-mysql-performance-tips/1281#comments</comments>
		<pubDate>Sun, 12 Nov 2006 07:12:51 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/84-mysql-performance-tips/1281</guid>
		<description><![CDATA[There&#8217;s a list of 84 MySQL performance tips optimistically titled Top 10 MySQL performance tips from today&#8217;s MySQL Camp at Google headquarters. The session was pretty interesting, as a lot of people got into argument when yet another tip was introduced, and shared their experience on the cases when the suggested tip would not work. [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s a list of <a href="http://forge.mysql.com/wiki/Top10SQLPerformanceTips">84 MySQL performance tips</a> optimistically titled Top 10 MySQL performance tips from today&#8217;s <a href="http://mysqlcamp.org/">MySQL Camp</a> at Google headquarters. The session was pretty interesting, as a lot of people got into argument when yet another tip was introduced, and shared their experience on the cases when the suggested tip would not work. If you decided to dedicate some time to MySQL reading, there&#8217;s plenty of presentations on <a href="http://dev.mysql.com/usingmysql/php/">MySQL+PHP development</a> on MySQL Developers site as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/84-mysql-performance-tips/1281/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Is the era of cloudware&#160;here?</title>
		<link>http://www.moskalyuk.com/blog/is-the-era-of-cloudware-here/1276</link>
		<comments>http://www.moskalyuk.com/blog/is-the-era-of-cloudware-here/1276#comments</comments>
		<pubDate>Thu, 09 Nov 2006 22:11:25 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Silicon Valley]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Yahoo!]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/is-the-era-of-cloudware-here/1276</guid>
		<description><![CDATA[Wired magazine has coined a new term for the massive data centers built in Pacific Northwest by Google, Microsoft and Yahoo! Cloudware is, ironically, a return of the centralized data and bandwidth power houses caused by decentralized and distributed nature of the Internet. George Gilder thinks we&#8217;re witnessing something monumental: According to Bell&#8217;s law, every [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Wired magazine</strong> has coined a new term for the massive data centers built in Pacific Northwest by Google, Microsoft and Yahoo! <a href="http://www.wired.com/wired/archive/14.10/cloudware.html">Cloudware</a> is, ironically, a return of the centralized data and bandwidth power houses caused by decentralized and distributed nature of the Internet. George Gilder thinks we&#8217;re witnessing something monumental:<br />
<blockquote>According to Bell&#8217;s law, every decade a new class of computer emerges from a hundredfold drop in the price of processing power. As we approach a billionth of a cent per byte of storage, and pennies per gigabit per second of bandwidth, what kind of machine labors to be born? How will we feed it? How will it be tamed? And how soon will it, in its inevitable turn, become a dinosaur?</p></blockquote>
<p><strong>Nicholas Carr</strong> <a href="http://www.roughtype.com/archives/2006/11/welcome_back_to_1.php">published a lengthy entry</a> contemplating the consequences of this turn in computing:<br />
<blockquote>In arguing that computing is &#8220;almost free,&#8221; while at the same time describing how costly it actually is, Gilder overlooks the paradox of abundance: that providing a resource in the quantities required to make it seem &#8220;free&#8221; can be a very expensive undertaking.</p></blockquote>
<p>Now on to my feelings about this:</p>
<p>The fascination with the large data centers seems to come and go away every few years. You can just look at the <a href="http://finance.yahoo.com/q/bc?s=LVLT&#038;t=my">Level 3 Communications</a> chart to differentiate the period of enamourment with the technology followed by the period of disappointment. Server farms and giant data centers are cool to talk about, but in reality they provide only <strong>marginal advantage</strong> &#8211; you save on new server racks, when the data center companies are charging extra due to the boom times. With enough capital and commitment anyone can replicate a large data center, and if the business required, it wouldn&#8217;t take too much for someone decidedly uncool like Time Warner or News Corp. to invest another billion in a data center of their own, where &#8220;thousands and thousands&#8221; of servers would provide for a great background for executive photo shoots.</p>
<p>The argument on owning the vital piece of the architecture is important, as your growth shouldn&#8217;t be potentially bound by what Hurricane Electric or Equinox decide to charge. However, such architecture, as the aforementioned Level 3 stock chart displays, can be <strong>a liability</strong> at times when the market is undergoing a downturn, and a Web company finds itself in the business of renting out the server racks to justify the costs of building a data center.</p>
<p>Glider&#8217;s Wired article seems to glorify the fact that Google, Yahoo! and Microsoft are all building in Pacific Northwest. That&#8217;s Dalles, OR, Wenatchee, WA and Quincy, WA. All located relatively closely to one another and in proximity to major dams, which allow for cheap electricity. So the &#8220;cloudware&#8221; will work great when I launch a YouTube clone, which will happen to hit big in <a href="http://blogs.zdnet.com/ITFacts/?p=11384">broadband-wealthy</a> Korea, right? Eeh, so that&#8217;s a problem as well. International traffic accounts for huge portions of growth at Google, Yahoo! and Microsoft. In fact, when you look at Comscore numbers for <a href="http://blogs.zdnet.com/ITFacts/?p=12027">US traffic in September 2006</a> and Comscore <a href="http://blogs.zdnet.com/ITFacts/?p=11897">numbers for August 2006 in the United States</a>, you will notice an interesting trend as far as total Internet users &#8211; the number of unique US Internet users fell from August 2006 to September 2006. Granted, there&#8217;re a few statistical issues here and there, and who knows how ComScore arrives at the exact numbers, so the US traffic might have even grown, but the fact is &#8211; US Internet usage growth is pretty much <strong>at its plateau</strong> right now. The growth for Internet&#8217;s top tier is going to come from China, India, Brazil and other emerging markets, and surprisingly the ping times to those places are not too great from either one of Pacific Northwest data centers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/is-the-era-of-cloudware-here/1276/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>10 PHP&#160;tips</title>
		<link>http://www.moskalyuk.com/blog/10-php-tips/1264</link>
		<comments>http://www.moskalyuk.com/blog/10-php-tips/1264#comments</comments>
		<pubDate>Fri, 27 Oct 2006 18:40:08 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Optimization]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/10-php-tips/1264</guid>
		<description><![CDATA[There&#8217;s a pretty good quick list of 10 PHP tips from yet another Web development blog.]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s a pretty good <a href="http://blog.rightbrainnetworks.com/2006/09/18/10-things-you-probably-didnt-know-about-php/">quick list of 10 PHP tips</a> from yet another Web development blog.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/10-php-tips/1264/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Checking for the presence of the arrays in&#160;PHP</title>
		<link>http://www.moskalyuk.com/blog/checking-for-the-presence-of-the-arrays-in-php/1235</link>
		<comments>http://www.moskalyuk.com/blog/checking-for-the-presence-of-the-arrays-in-php/1235#comments</comments>
		<pubDate>Fri, 22 Sep 2006 08:24:49 +0000</pubDate>
		<dc:creator>Alex</dc:creator>
				<category><![CDATA[Optimization]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.moskalyuk.com/blog/checking-for-the-presence-of-the-arrays-in-php/1235</guid>
		<description><![CDATA[Recently during a casual conversation someone asked me what would be the fastest way to check for array presence in PHP. Normally you don&#8217;t tend to think of the empty array as anything special, but they do occur a lot &#8211; a query from the database can return 0 rows, the object that has been [...]]]></description>
			<content:encoded><![CDATA[<p>Recently during a casual conversation someone asked me what would be the fastest way to check for array presence in PHP. Normally you don&#8217;t tend to think of the empty array as anything special, but they do occur a lot &#8211; a query from the database can return 0 rows, the object that has been in cache has expired, or the Web page has 0 inbound links pointing to it. Pretty usual way to go about it i to use <strong>count</strong> or its twin brother <strong>sizeof</strong> to find out the length of the array and behave accordingly depending on whether the if statement returns true or not.</p>
<p>It was pointed out to me, however, that both count and sizeof always need to conduct the pointer arithmetics, even if the array in question is of zero size. Checking for the existence of the first element of the array, however, would involve no pointer arithmetics, since referencing <strong>$array[0]</strong> is the same as referencing <strong>$array</strong> pointer. But how much faster is it? I set out to test it with a pretty simple script that would run both comparisons a million times. Since accessing the first element of an empty array would generate a PHP notice (note that it&#8217;s not an error, the pointer is still valid), I had to revert to <strong>error_reporting(0)</strong> at the beginning of the file to exclude the time spent on printing out PHP notices.</p>
<p>It&#8217;s also useful to know that whenever the if statement contains a clause that doesn&#8217;t have executable code, it will be optimized by the interpreter, and therefore something should be done inside the if() clause once we&#8217;re there. So how about running a counter from 1 to a million, checking for the same array over and over, and printing the counter value on each run?</p>
<p><code>
<pre>
error_reporting(0);

$array1 = array();
$time1 = time();

for ($x=0; $x&lt;1000000; $x++)
{
	if (count($array1)==0)
	{echo $x;
	}
}

$time2 = time();

for ($x=0; $x&lt;1000000;$x++)
{
	if(!$array1[0])
	{echo $x;
	}
}

$time3 = time();

echo ($time2-$time1)."\n";
echo ($time3-$time2)."\n";
</pre>
<p></code></p>
<p>The results?<br />
<strong>99937<br />
36</strong></p>
<p>More than 2,500x difference.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.moskalyuk.com/blog/checking-for-the-presence-of-the-arrays-in-php/1235/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

