<?xml version="1.0" encoding="utf-8" ?>

<rss version="0.91" >
<channel>
<title>iBlog - Ilia Alshanetsky</title>
<link>http://ilia.ws/</link>
<description>Here be dragons.</description>
<language>en</language>
<image>
        <url>http://ilia.ws/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: iBlog - Ilia Alshanetsky - Here be dragons.</title>
        <link>http://ilia.ws/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Performance Analysis of isset() vs array_key_exists() </title>
    <link>http://ilia.ws/archives/247-Performance-Analysis-of-isset-vs-array_key_exists.html</link>

    <description>
        &lt;p&gt;
At Confoo I had an interesting conversation with Guilherme Blanco regarding the fact that in Doctrine 2 they had a performance issue due to usage of array_key_exists() and how it was significantly slower than isset(). His anecdotal example was that doing isset() took 0.5 seconds, while array_key_exists() for the same operation took 5 seconds!
&lt;/p&gt;
&lt;p&gt;
That seemed wrong, given that array_key_exists() simply does a hash table look-up, to determine if the array key exists and the only speed difference would be due to the fact that isset() is a language construct and does not have the overhead of function &amp;amp; parameter processing. So, I&#039;ve decided to do a quick benchmark using a 5,000 element array.
&lt;/p&gt;
&lt;div class=&quot;bb-php-title&quot;&gt;PHP:&lt;/div&gt;&lt;div class=&quot;bb-php&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php

$arr&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;#160;array();
&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$fp&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;fopen&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;/usr/share/dict/words&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;r&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);
while&amp;#160;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$i&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;&amp;lt;&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;5000&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;&amp;amp;&amp;amp;&amp;#160;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$w&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;fgets&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$fp&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)))&amp;#160;{
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$arr&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;trim&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$w&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;)]&amp;#160;=&amp;#160;++&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$i&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;
}

&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$s&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;microtime&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);
for&amp;#160;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$i&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$i&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;&amp;lt;&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;100000&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$i&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;++)&amp;#160;{
&amp;#160;&amp;#160;&amp;#160;&amp;#160;isset(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$arr&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;abracadabra&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;]);
}
&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$e&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;microtime&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);

echo&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;Isset:&amp;#160;&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$e&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$s&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;\n&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;

&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$s&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;microtime&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);
for&amp;#160;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$i&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$i&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;&amp;lt;&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;100000&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$i&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;++)&amp;#160;{
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;array_key_exists&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&#039;abracadabra&#039;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$arr&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);
}
&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$e&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;=&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;microtime&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);

echo&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;array_key_exists:&amp;#160;&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;.(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$e&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;-&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;$s&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;\n&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;;

&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;&lt;/div&gt;
&lt;p&gt;
The above benchmark executed on PHP 5.4 shows that while isset() is 2.5 times faster taking a mere 0.0219 seconds vs 0.0549 seconds taken by array_key_exists(), both operations are extremely quick and take a fraction of a second even when doing 100k operations. Any &quot;optimization&quot; between the calls is purely within the super-micro-micro optimization realm and is not going to make any application measurably faster. 
&lt;/p&gt;

&lt;p&gt;
The bottom line is that if your application does not need to distinguish between an array key that does not exist and one whose value happens to be NULL you should use isset() because it happens to be a little faster. However, if a NULL array key value and a non-existant array key are something you need to differentiate between, use array_key_exists() and you don&#039;t need to worry about the performance, the function is extremely fast, even in the case of Doctrine 2 that apparently may do as many as 50,000 calls to the function per-request in some cases.
&lt;/p&gt; 
    </description>
</item>
<item>
    <title>Introduction to PHP 5.4 Slides</title>
    <link>http://ilia.ws/archives/246-Introduction-to-PHP-5.4-Slides.html</link>

    <description>
        My slides from the &lt;a href=&quot;http://confoo.ca/en&quot;&gt;Confoo&lt;/a&gt; presentation on PHP 5.4 are up and can be viewed/downloaded from here:&lt;br /&gt;
&lt;a href=&quot;http://ilia.ws/files/confoo_php54.pdf&quot;&gt;http://ilia.ws/files/confoo_php54.pdf&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I look forward to everyone&#039;s feedback either on this blog or via &lt;a href=&quot;http://joind.in/talk/view/6063&quot;&gt;Joind.in&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
And in case you didn&#039;t know, &lt;a href=&quot;http://www.php.net/archive/2012.php#id2012-03-01-1&quot;&gt;PHP 5.4 was released &lt;/a&gt;yesterday! &lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;[Update March 3, 2012]&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Based on great suggestion from Rasmus, I&#039;ve updated the charset slide to clarify that the change introduced in 5.4 relates to the default charset used by internal entities functions (htmlspecialchars, htmlentities, etc...) and updating the default_charset INI is one of the changes you may need to do to account for this change. 
    </description>
</item>
<item>
    <title>Introduction to PostgreSQL</title>
    <link>http://ilia.ws/archives/245-Introduction-to-PostgreSQL.html</link>

    <description>
        The slides from my &quot;Introduction to PostgreSQL&quot; talk at &lt;a href=&quot;http://confoo.ca/en&quot;&gt;Confoo&lt;/a&gt;are now available for view/download &lt;br /&gt;
and can found here: &lt;a href=&quot;http://ilia.ws/files/confoo_pgsql.pdf&quot;&gt;http://ilia.ws/files/confoo_pgsql.pdf&lt;/a&gt;. Hopefully it will make people more interested in PostgreSQL, which is a great database system and take it into consideration when making their database platform decisions.&lt;br /&gt;
&lt;br /&gt;
For me personally, it was quite interesting, as it is one of the rare chances I get to speak about something that is not directly related to PHP, although I did sneak-in a few PHP specific slides &lt;img src=&quot;http://ilia.ws/templates/default/img/emoticons/wink.png&quot; alt=&quot;;-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
I would very much appreciate feedback from all who had attended the talk and any suggestions on how to make it better are always welcome. Please send me your comments via this blog or via &lt;a href=&quot;http://joind.in/talk/view/6001&quot;&gt;Joind.in&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
A big thanks for to Bruce Momjian from Enterprise DB who gave me some really good suggestions on improving the slides (already reflected in the PDF) and Christophe Pettus from PostgreSQL Experts, Inc. whose original PostgreSQL Intro talk had inspired mine. &lt;br /&gt;
 
    </description>
</item>
<item>
    <title>PHP's Output Buffering</title>
    <link>http://ilia.ws/archives/244-PHPs-Output-Buffering.html</link>

    <description>
        &lt;p&gt;
While profiling our application I came across a a rather strange memory usage by the ob_start() function. We do use ob_start() quite a bit to defer output of data, which is a common thing in many applications. What was unusual is that 16 calls to ob_start() up chewing through almost 700kb of memory, given that the data being buffered rarely exceeds 1-2kb, this was quite unusual.
&lt;/p&gt;
&lt;p&gt;
I started looking at the C code of the ob_start() function and found this interesting bit of code inside &lt;strong&gt;php_start_ob_buffer()&lt;/strong&gt;
&lt;em&gt;initial_size = 40*1024;
block_size = 10*1024;&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Which directs PHP to pre-allocate 40kb of data for each ob_start() call and when this proves to be insufficient, increase by 10kb each time. Ouch!
&lt;/p&gt;
&lt;p&gt;
PHP does allow you to say how much memory ob_start() can use, via 2nd parameter to the function. However, if you exceed that size, PHP will promptly flush the captured data to screen, which means that unless you are really good at predicting your buffer sizes or vastly overestimate, there is a risk that the data will be dumped to screen by PHP if you use this option.
&lt;/p&gt;
&lt;p&gt;
Since I am not really good at guessing, I&#039;ve decided to make a small, backwards compatible tweak to PHP&#039;s code that allow specification of custom buffer sizes, but allow the buffer size to be increased if the initial buffer size proves to be insufficient, ensuring that the data can be safely buffered. This functionality is implemented through a change (see patch below) to the 1st parameter of the ob_start() function, which normally is used to provide the callback function. With the patch in place the parameter, can be a number, which defines the desired buffer size.  With the patch, ob_start(1024) means that the 1kb buffer should be used and when it is exceed keep allocating 1kb at a time to allow for additional data to be stored. This solution does mean you cannot use custom, resizable buffer sizes with a callback function, however it does provider a backwards (PHP API wise) compatible way of implementing the functionality in PHP 5.2 and 5.3.
&lt;/p&gt;
Here is a simple before &amp;amp; after example:
&lt;div class=&quot;bb-php-title&quot;&gt;PHP:&lt;/div&gt;&lt;div class=&quot;bb-php&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php

&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;ob_start&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;echo&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;str_repeat&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;1500&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;var_dump&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;strlen&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;ob_get_clean&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()));

&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;&lt;/div&gt;
will print 0, since buffer is exceeded and is flushed to screen

&lt;div class=&quot;bb-php-title&quot;&gt;PHP:&lt;/div&gt;&lt;div class=&quot;bb-php&quot;&gt;&lt;code&gt;&lt;span style=&quot;color: #000000&quot;&gt;
&lt;span style=&quot;color: #0000BB&quot;&gt;&amp;lt;?php

&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;ob_start&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;echo&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;str_repeat&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #DD0000&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;,&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;1500&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;);
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;var_dump&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;strlen&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;ob_get_clean&lt;/span&gt;&lt;span style=&quot;color: #007700&quot;&gt;()));

&lt;/span&gt;&lt;span style=&quot;color: #0000BB&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/span&gt;
&lt;/code&gt;&lt;/div&gt;
will print 1500, buffer was exceeded and subsequently increased, allowing data to remain in the buffer

&lt;div class=&quot;bb-code-title&quot;&gt;CODE:&lt;/div&gt;&lt;div class=&quot;bb-code&quot;&gt;Index&amp;#58;&amp;#160;main/output.c
===================================================================
---&amp;#160;main/output.c	&amp;#40;revision&amp;#160;320624&amp;#41;
+++&amp;#160;main/output.c	&amp;#40;working&amp;#160;copy&amp;#41;
@@&amp;#160;-155,10&amp;#160;+155,14&amp;#160;@@
&amp;#160;		initial_size&amp;#160;=&amp;#160;&amp;#40;chunk_size&amp;#42;3/2&amp;#41;;
&amp;#160;		block_size&amp;#160;=&amp;#160;chunk_size/2;
&amp;#160;	}&amp;#160;else&amp;#160;{
-		initial_size&amp;#160;=&amp;#160;40&amp;#42;1024;
-		block_size&amp;#160;=&amp;#160;10&amp;#42;1024;
+		if&amp;#160;&amp;#40;output_handler&amp;#160;&amp;amp;&amp;amp;&amp;#160;Z_TYPE_P&amp;#40;output_handler&amp;#41;&amp;#160;==&amp;#160;IS_LONG&amp;#160;&amp;amp;&amp;amp;&amp;#160;!chunk_size&amp;#41;&amp;#160;{
+			initial_size&amp;#160;=&amp;#160;block_size&amp;#160;=&amp;#160;Z_LVAL_P&amp;#40;output_handler&amp;#41;;
+		}&amp;#160;else&amp;#160;{
+			initial_size&amp;#160;=&amp;#160;40&amp;#42;1024;
+			block_size&amp;#160;=&amp;#160;10&amp;#42;1024;
+		}
&amp;#160;	}
-	return&amp;#160;php_ob_init&amp;#40;initial_size,&amp;#160;block_size,&amp;#160;output_handler,&amp;#160;chunk_size,&amp;#160;erase&amp;#160;TSRMLS_CC&amp;#41;;
+	return&amp;#160;php_ob_init&amp;#40;initial_size,&amp;#160;block_size,&amp;#160;
+&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#40;output_handler&amp;#160;&amp;amp;&amp;amp;&amp;#160;Z_TYPE_P&amp;#40;output_handler&amp;#41;&amp;#160;!=&amp;#160;IS_LONG&amp;#160;?&amp;#160;output_handler&amp;#160;&amp;#58;&amp;#160;NULL&amp;#41;,
+&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;chunk_size,&amp;#160;erase&amp;#160;TSRMLS_CC&amp;#41;;
&amp;#160;}
&amp;#160;/&amp;#42;&amp;#160;}}}&amp;#160;&amp;#42;/&lt;/div&gt; 
    </description>
</item>
<item>
    <title>&quot;Under the Hood&quot; Slides</title>
    <link>http://ilia.ws/archives/243-Under-the-Hood-Slides.html</link>

    <description>
        My slides for my &quot;Under the Hood&quot; talk at ZendCon are now online and can be downloaded &lt;a href=&quot;http://ilia.ws/files/zendcon_2011_under_the_hood.pdf&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Thanks to all the attendees, especially those who left feedback at &lt;a href=&quot;http://joind.in/3789&quot;&gt;Joind.In&lt;/a&gt;.&lt;br /&gt;
 
    </description>
</item>
<item>
    <title>New PHP-Excel (0.9.5) was just released! </title>
    <link>http://ilia.ws/archives/242-New-PHP-Excel-0.9.5-was-just-released!.html</link>

    <description>
        I&#039;ve just released a new version of php-excel extension that exposes the new functionality offered by libxl 3.2.0.&lt;br /&gt;
The new functionality in this release includes the following:&lt;br /&gt;
&lt;br /&gt;
        - ExcelSheet::setPrintFit(int wPages, int hPages) that fits sheet width and sheet height to wPages and hPages respectively&lt;br /&gt;
        - ExcelSheet::getPrintFit() that returns whether fit to page option is enabled, and if so to what width &amp;amp; height&lt;br /&gt;
        - ExcelSheet::getNamedRange(string name) that gets the named range coordianates by name, returns false if range is not found&lt;br /&gt;
        - ExcelSheet::getIndexRange(int index) that gets the named range coordianates by index, returns false if range is not found&lt;br /&gt;
        - ExcelSheet::namedRangeSize() that returns the number of named ranges in the sheet&lt;br /&gt;
        - ExcelSheet::getVerPageBreak(int index) that returns column with vertical page break at position index&lt;br /&gt;
        - ExcelSheet::getVerPageBreakSize() that returns a number of vertical page breaks in the sheet&lt;br /&gt;
        - ExcelSheet::getHorPageBreak(int index) that eturns column with horizontal page break at position index&lt;br /&gt;
        - ExcelSheet::getHorPageBreakSize() that returns a number of horizontal page breaks in the sheet&lt;br /&gt;
        - ExcelSheet::getPictureInfo(int index) that returns a information about a workbook picture at position index in worksheet&lt;br /&gt;
        - ExcelSheet::getNumPictures() that returns a number of pictures in this worksheet&lt;br /&gt;
        - ExcelBook::biffVersion() that returns BIFF version of binary file. (Used for xls format only)&lt;br /&gt;
        - ExcelBook::getRefR1C1() that returns whether the R1C1 reference mode is active&lt;br /&gt;
        - ExcelBook::setRefR1C1(bool active) that sets the R1C1 reference mode&lt;br /&gt;
        - ExcelBook::getPicture(int picture_index) that returns a picture at position index&lt;br /&gt;
        - ExcelBook::getNumPictures() that returns a number of pictures in this workbook&lt;br /&gt;
        - ExcelSheet ExcelBook::insertSheet(int index, string name [, ExcelSheet sh]) that inserts a new sheet to this book at position index,&lt;br /&gt;
          returns the sheet handle. If ExcelSheet parameter is missing a new sheet will be created.&lt;br /&gt;
&lt;br /&gt;
The source code &amp;amp; tar balls can be found at &lt;a href=&quot;https://github.com/iliaal/php_excel&quot;&gt;https://github.com/iliaal/php_excel&lt;/a&gt; 
    </description>
</item>
<item>
    <title>IPC: Hidden Features of PHP Slides</title>
    <link>http://ilia.ws/archives/241-IPC-Hidden-Features-of-PHP-Slides.html</link>

    <description>
        The slides from my talk on the Hidden Features of PHP are now available and can be downloaded from here:&lt;br /&gt;
&lt;a href=&quot;http://ilia.ws/files/ipc_2011_hidden_features.pdf&quot;&gt;ipc_2011_hidden_features.pdf&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Thanks to all the people who attended the talk and I really am looking for your feedback via &lt;a href=&quot;http://joind.in/talk/view/3512&quot;&gt;Joind.in&lt;/a&gt;. 
    </description>
</item>
<item>
    <title>Memcached, the Better Memcache Interface Slides</title>
    <link>http://ilia.ws/archives/240-Memcached,-the-Better-Memcache-Interface-Slides.html</link>

    <description>
        The slides from my talk on the Memcached extension are now available and can be downloaded from here:&lt;br /&gt;
&lt;a href=&quot;http://ilia.ws/files/ipc_Memcached_2011.pdf&quot;&gt;ipc_Memcached_2011.pdf&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Thanks to all the people who attended the talk and I really am looking for your feedback via &lt;a href=&quot;http://joind.in/talk/view/3509&quot;&gt;Joind.in&lt;/a&gt;.&lt;br /&gt;
 
    </description>
</item>
<item>
    <title>ConFoo - Hidden PHP Features</title>
    <link>http://ilia.ws/archives/239-ConFoo-Hidden-PHP-Features.html</link>

    <description>
        My slides for the &quot;Hidden PHP Features&quot; talk at ConFoo are now available at &lt;a href=&quot;http://ilia.ws/files/confoo_2011_hidden_features.pdf&quot;&gt;http://ilia.ws/files/confoo_2011_hidden_features.pdf&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
If you were at the talk, please give me your feedback/suggestions at: &lt;a href=&quot;http://joind.in/2905&quot;&gt;http://joind.in/2905&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
 
    </description>
</item>
<item>
    <title>Confoo - APC &amp; Memcached Talk</title>
    <link>http://ilia.ws/archives/238-Confoo-APC-Memcached-Talk.html</link>

    <description>
        Thanks to all the people who attended my talk on the APC and Memcached yesterday at Confoo. The slides are now available to download at: &lt;a href=&quot;http://ilia.ws/files/confoo_APC_MEM2011.pdf&quot;&gt;http://ilia.ws/files/confoo_APC_MEM2011.pdf&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
If you have any feedback, or comments they would be much appreciated via Joind.In (&lt;a href=&quot;http://joind.in/2806&quot;&gt;http://joind.in/2806&lt;/a&gt;)  
    </description>
</item>
<item>
    <title>PHP Excel Extension 0.9.1</title>
    <link>http://ilia.ws/archives/237-PHP-Excel-Extension-0.9.1.html</link>

    <description>
        The 0.9.1 version of the Excel extension was released and is now available for download. This is mostly a bug fix release, with a number of contributions by Rob Gagnon. The 2 main fixes are related to detection of custom formatted numeric fields, that were incorrectly detected as dates and readRow()/readCol() methods that had a bug when 2 and 3rd parameters are supplied, causing the last row/column not to be read. Additionally a getSheetByName() method was introduced that allows locating a sheet by it&#039;s name in either case sensitive or insensitive form.&lt;br /&gt;
&lt;br /&gt;
GitHub: &lt;a href=&quot;http://github.com/iliaal/php_excel/&quot;&gt;http://github.com/iliaal/php_excel/&lt;/a&gt;&lt;br /&gt;
Source: &lt;a href=&quot;http://github.com/downloads/iliaal/php_excel/php-excel-0.9.1.tar.bz2&quot;&gt;http://github.com/downloads/iliaal/php_excel/php-excel-0.9.1.tar.bz2&lt;/a&gt; 
    </description>
</item>
<item>
    <title>ISP Popularity by Domain Count</title>
    <link>http://ilia.ws/archives/236-ISP-Popularity-by-Domain-Count.html</link>

    <description>
        The past two information gathering runs showed that GoDaddy is the world largest ISP, but I was curious who else falls into the Top ISP category as determined by consumer shopping habits.  To do this Ive used my resolved IP database of 124 million domains and an ISP database from MaxMind.&lt;br /&gt;
&lt;br /&gt;
The results are pretty interesting, and it clearly shows that a small number of ISPs are definitely doing something right, which is causing many consumers to vote with their dollars in those ISPs favor. &lt;br /&gt;
&lt;br /&gt;
As usual the information is shown in graph form, to filter down the data to just the large providers Ive set a minimum at 100,000 domains, leaving me with just 122 ISPs. The image below shows the break-down of the Top 25. If you click on it, you will be able expand the chart to 50,100 or the entire list in a form of a bar chart, or explore the pie chart that includes %s.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://ilia.ws/stats/top_isps.php&quot;&gt;&lt;!-- s9ymdb:26 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;841&quot; height=&quot;664&quot; style=&quot;border: 0px; padding-left: 5px; padding-right: 5px;&quot; src=&quot;http://ilia.ws/uploads/images/isp.png&quot; alt=&quot;&quot; /&gt;&lt;img /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Since we already know GoDaddy is #1, I will skip them over them and focus on the next largest 3. At #2, we have The Planet, a Texas based data-center provider with 6.1 million domains (4.91% of total). It should mention that The Planet had recently merged with Softlayer Technologies, #8 on our list, which would further expand their prominence by another 1.8 million domains. At #3 we have 1&amp;1 Internet, a German ISP with 5 million domains (4.04%). And finally at #4 we have Internap, an Atlanta based ISP with 2.88 million domains (2.32%).&lt;br /&gt;
&lt;br /&gt;
In total, the 25 largest ISPs represent 52.3% of all the domains, which quite impressive since overall there are 31,173 distinct ISPs. Even within the top 25 things are not entirely even, only the first 15 can claim over 1 million domains. Expanding the ISP list to Top-50, expands the domain coverage to 59.67%, not a whole lot. However once the entire list of ISPs with &gt;100k domains is considered we are looking at 68.9% representation. This means that 2/3 of the entire internet is effectively managed by only 122 companies. Kinda scary, actually.&lt;br /&gt;
&lt;br /&gt;
In an effort to validate the popularity of the ISPs, Ive also decided to look at the IP address breakdown (how many IPs per domain) and which ISPs the Top-IPs belong to. This should identify the ISPs whose business is predominantly the result of parked domains. The results for Top 25 IP addresses are shown in the table below&lt;br /&gt;
&lt;br /&gt;
&lt;!-- s9ymdb:27 --&gt;&lt;img class=&quot;serendipity_image_center&quot; width=&quot;993&quot; height=&quot;595&quot; style=&quot;border: 0px; padding-left: 5px; padding-right: 5px;&quot; src=&quot;http://ilia.ws/uploads/images/ip.png&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
When it comes to IP addresses, GoDaddy is by far the most frugal, which probably relates to the fact that they do a lot of domain parking. Both #1 and #2 on the list belong to GoDaddy, representing 12.9 million and 6 million domains respectively. I should mention that #4 with 1.9 million domains and #6 with another 1.1 million domains also belong to GoDaddy. Based on this information it would seem that GoDaddys prominence in the ISP space is predominantly based on parked domains, which take up 22 million of the 26.4 million being hosted with them. This can probably be attributed to GoDaddys extremely aggressive pricing when it comes to buying domains. The 3rd most popular IP address belong to Oversee.net, with just over 2 million IPs. Given that Oversee.net only has 2.57 million domain under management, it would seem that most of them are parked domains, same situation as with GoDaddy.&lt;br /&gt;
&lt;br /&gt;
Couple of other big IPs worth noting are 64.95.64.197, which belongs to Internap, with 1.31 million domains resolving to it. Given that Internap hosts 2.88 million domains, it seems just shy of 1/2 of their domain base is parked. Another winner is 216.21.239.197 which belongs to Register.com with 669k domains, which represents nearly the entirety of of the 703k domains at that ISP. Unsurprisingly Network Solutions is in the same boat, of the 1.32 million domains under management, 1.15 are parked on 3 IP addresses.&lt;br /&gt;
&lt;br /&gt;
On a general note, the 124 million domains are hosted on just 5.39 million IP addresses, which raises interesting questions about IPv4 exhaustion, clearly domain hosting is not the reason. So what the heck are people using those public IPs for? If they are being used by Internet Providers to provide internet to consumers, one would think that more extensive use of NAT would certainly alleviate the IPv4 shortage for quite some time.&lt;br /&gt;
&lt;br /&gt;
There are some 81,164 IPs that have over 100 domains resolve to them, if combined, their total domain count reached 87.4 million, 70% of all registered domains. Since It is safe to assume that in most cases virtual hosting wont have more then 200 sites per IP, than based on the gathered data,  81.4 million domains are parked on 37,865 IPs. This in turn means that 2/3 (65.4%) of all domains are not actually in-use. A number very similar to the % of domains hosted the worlds Top ISPs, so perhaps the things are not so bad after-all and the non-parked domains are more evenly distributed than the initial numbers might suggest. 
    </description>
</item>
<item>
    <title>Domain Distribution by City</title>
    <link>http://ilia.ws/archives/235-Domain-Distribution-by-City.html</link>

    <description>
        As part of my on-going domain informatics coverage, I am now publishing some additional information that Ive been able to gather in the last few days.&lt;br /&gt;
&lt;br /&gt;
I am making available two additional geographic chats that breakdown the domain distribution by top world cities. The first chart a preview of which can been below (click to see full, browse-able/zoomable version) shows the Top 150 cities, by domain distribution. These cities represent a total 91.3% of some 102 million domains that could be resolved to a city level.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://ilia.ws/stats/cities.php&quot;&gt;&lt;img src=&quot;http://ilia.ws/uploads/images/cities.png&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The most popular city in the world, with 26.4 million domains calling it home is Scottsdale, Arizona in United States. Which is not entirely surprising, given that it is the hometown on GoDaddy, worlds largest domain provider/hosting company. This coincidentally means that Arizona, which had &lt;a href=&quot;http://ilia.ws/stats/us_states.php&quot;&gt;won the US state domain count&lt;/a&gt; contest with 26.7 million domains in our previous round of statistics, is entirely due to GoDaddy. The 2nd largest city is San Francisco, with a respectable 14.3 million domains, which represents over 1/2 of the 24.3 million domains hosted in California. And the 3rd place goes to Houston, Texas with just shy of 6.1 million domains.&lt;br /&gt;
&lt;br /&gt;
Overall there are only 15 cities in the world that can claim to host over a 1 million domains and all of them are found in the US. The first non-US city is actually Toronto, Canada at #19 with 850 thousand domains, shortly followed by Beijing China with 845 thousand domains. The smallest city on the Top 150 list is Oklahoma (Capital of Oklahoma, US) with just 43.4 thousand domains. Seems tiny compared to the beginning of the list, but on global country scale it would actually make it into Top 50 at 49, with almost twice as many domains as Iran (23.4 thousand domains) that would now be displaced to 50th place.&lt;br /&gt;
&lt;br /&gt;
To give a slightly better domain concentration view, I am publishing a dynamic cluster map that groups cities together by geographic proximities. Zooming in on the map will breakdown the larger clusters into smaller eventually, eventually resolving all the way to the individual cities. Due to better visualization of markers on this map, Ive expanded the city list to the Top 400 cities. Which takes us down to as little as 8,600 domains and provides a slightly more worldly view. Click on the map below to see the dynamic version.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://ilia.ws/stats/cities_group.php&quot;&gt;&lt;img src=&quot;http://ilia.ws/uploads/images/cities_group.png&quot; /&gt;&lt;/a&gt; 
    </description>
</item>
<item>
    <title>Domain Location Statistics</title>
    <link>http://ilia.ws/archives/234-Domain-Location-Statistics.html</link>

    <description>
        I recently re-started the process or aggregating PHP usage data and first sample of small dataset (about 10 million domains) has been the subject of my &lt;a href=&quot;http://phpadvent.org/2010/usage-statistics-by-ilia-alshanetsky&quot;&gt;PHP Advent article&lt;/a&gt;. Now, I&#039;ve started the process of collecting the data on the full data set which comprises of 124 million domains that represent the entirety of .com, .net, .biz, .info, .us, .sk and .org  &lt;a href=&quot;http://en.wikipedia.org/wiki/Top-level_domain&quot;&gt;TLD&lt;/a&gt;s.&lt;br /&gt;
&lt;br /&gt;
The first step of the process has been resolving all of these domains, which is now complete. The next step is fetching the server information, which began, but will take some time to finish. However, even from the domain revolving data there is a lot of useful data to be gleamed, which is what I am now publishing. My first focus was on the world-wide distribution on these TLDs, which at least for me held a few surprises.&lt;br /&gt;
&lt;br /&gt;
First of all, unsurprisingly US has the most domains hosted on its soil, however its sheer overwhelming of other countries is quite impressive, and stands at just over 89 million domains, 71% of all domains!. In 2nd place is Germany (which was actually a surprise, my guess that it would be Canada or Japan) with 7.5 million domains and the bronze goes to United Kingdom with 3 million domains. Canada was actually 4th with 2.7 million domains and Japan all the way in 9th place with 1.86 million domains. Below is a graph representing the top 50 Countries according to the domain distribution. To see more detail, click on the image which will bring up a zoomable &lt;a href=&quot;http://www.highcharts.com/&quot;&gt;HighChart&lt;/a&gt; graph.&lt;br /&gt;
&lt;a href=&quot;http://ilia.ws/stats/top_50_tlds.php&quot;&gt;&lt;img src=&quot;http://ilia.ws/uploads/images/worlstats2.png&quot; alt=&quot;Domain Distribution, Top 50 Countries (US Excluded)&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Note that the US excluded, due to the high number of domains it made the graph not usable and unfortunately HighCharts library does not supposer logarithmic scale. What I did instead is a create a separate chart, which breaks down the domain distribution by US states, which can be found further in the article. As you can tell from the World chart, the domain distribution is highly un-even, the top entry starts with Germany at 7.5 million and by the time hit Spain at #12, we are down to 1 million domains. By the time we get to Bulgaria that is in 37th place were are down to just 100k domains. By the time last entry in our chart appears, which happens to be Panama, we are down to a mere 21,709 domains. &lt;br /&gt;
&lt;br /&gt;
As with the world data, US domain distribution also had a surprise in store for me. I would&#039;ve guessed that the majority of domains would find their home in California, being itself the home of Silicon Valley. However, California actually came in second, behind Arizona of all states. Arizona is home to 26.7 million domains, while California can only lay claim to 24,.3 million, Texas came in 3rd with a mere 9.99 million domains. Below is the chart showing all the states, click on the image which will bring up a zoomable &lt;a href=&quot;http://www.highcharts.com/&quot;&gt;HighChart&lt;/a&gt; graph.&lt;br /&gt;
&lt;a href=&quot;http://ilia.ws/stats/us_states.php&quot;&gt;&lt;img src=&quot;http://ilia.ws/uploads/images/usstates.png&quot; alt=&quot;Domain Distribution, by US States&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
As with the world stats, the US domain distribution is also extremely uneven, only 12 states can lay claim to being home to over a million domains. The 12th being state, being New York with 1.56 million domains. By the the time we reach Indiana at #27, we are down to just 100k domains.  Alaska trails the list at a mere 4729 domains, which seems tiny, however it still more more then 130 countries, which on a world scale would place at at #71, ahead of Iceland an Saudi Arabia, that both have just over 4100 domains.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve also created a &lt;a href=&quot;http://ilia.ws/stats/world_map.php&quot;&gt;clickable world-map&lt;/a&gt; that will let you explore all 222 countries, US and Canada are clickable and will give you breakdown of the individual states/provinces. While the sever information script is gathering data, which should take about 2 weeks I am hoping to generate more data based on the IPs, which should give ISP popularity, avg. # of domains per single IP with info on the &quot;top IPs&quot; and other curious bits of info I can gleam from free/public &lt;a href=&quot;http://www.maxmind.com/&quot;&gt;MaxMind&lt;/a&gt; I am using.&lt;br /&gt;
&lt;br /&gt;
P.S. If you have access to TLDs other then the ones I listed, I would be grateful if you would be willing to provide domain lists for those TLDs on a one-time or monthly basis. 
    </description>
</item>
<item>
    <title>PHP Excel Extension 0.9</title>
    <link>http://ilia.ws/archives/233-PHP-Excel-Extension-0.9.html</link>

    <description>
        The 0.9 version of the Excel extension was released and is now available for download. This version was updated with support for LibXL 3.1.0, and introduces a number of new methods that can be used to manage repeating of printable rows, creation of named rages, and summary positioning.&lt;br /&gt;
&lt;br /&gt;
GitHub: &lt;a href=&quot;http://github.com/iliaal/php_excel/&quot;&gt;http://github.com/iliaal/php_excel/&lt;/a&gt;&lt;br /&gt;
Source: &lt;a href=&quot;http://github.com/downloads/iliaal/php_excel/php-excel-0.9.0.tar.bz2&quot;&gt;http://github.com/downloads/iliaal/php_excel/php-excel-0.9.0.tar.bz2&lt;/a&gt; 
    </description>
</item>

</channel>
</rss>

