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

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>Johannes Schlüter</title>
    <link>http://schlueters.de/blog/</link>
    <description>Always searching for Life, the Universe and Everything</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.5.3 - http://www.s9y.org/</generator>
    <pubDate>Thu, 02 Sep 2010 10:58:17 GMT</pubDate>

    <image>
        <url>http://schlueters.de/blog/templates/schluetersde/img/s9y_banner_small.png</url>
        <title>RSS: Johannes Schlüter - Always searching for Life, the Universe and Everything</title>
        <link>http://schlueters.de/blog/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>iSCSI devices in VirtualBox</title>
    <link>http://schlueters.de/blog/archives/144-iSCSI-devices-in-VirtualBox.html</link>
            <category>Software</category>
    
    <comments>http://schlueters.de/blog/archives/144-iSCSI-devices-in-VirtualBox.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=144</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=144</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;While playing with my disc-less environment, booting via &lt;a href=&quot;http://etherboot.org/&quot;&gt;gPXE&lt;/a&gt; from an &lt;a href=&quot;http://en.wikipedia.org/wiki/iSCSI&quot;&gt;iSCSI&lt;/a&gt; device, I found out that &lt;a href=&quot;http://www.virtualbox.org&quot;&gt;VirtualBox&lt;/a&gt; has direct support for iSCSI while this isn&#039;t shown in the GUI. To register an iSCSI device as virtual disc one has to use &lt;em&gt;VBoxManage&lt;/em&gt; on the command line:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;$ VBoxManage addiscsidisk \
       --server iscsi.home.schlueters.de \
       --target iqn.1986-03.com.sun:02:f4635770-f010-61be-e8f7-83403206bec5
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;The result can be checked:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;$ VBoxManage list hdds
[...]
UUID:        292b93ef-0fef-41c4-ad9c-700c38d5537e
Parent UUID: base
Format:      iSCSI
Location:    iscsi.home.schlueters.de|iqn.1986-03.com.sun:02:f4635770-f010-61be-e8f7-83403206bec5
State:       created
Type:        normal
Usage:       test (UUID: 0e9dac71-1a33-42f3-8320-1f157582e931) 
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Once the disc is registered it can be selected in the GUI (or from command line) while configuring a VM. In my test I once lost the network connection to the iSCSI target, VBox handled that in a safe way by pausing the VM. Quite handy.&lt;br /&gt;&lt;/p&gt; 
&lt;blockquote&gt; &lt;/blockquote&gt; 
    </content:encoded>

    <pubDate>Thu, 02 Sep 2010 12:40:18 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/144-guid.html</guid>
    <category>discless</category>
<category>etherboot</category>
<category>gpxe</category>
<category>iscsi</category>
<category>storage</category>
<category>virtualbox</category>

</item>
<item>
    <title>HashTables</title>
    <link>http://schlueters.de/blog/archives/142-HashTables.html</link>
            <category>PHP</category>
    
    <comments>http://schlueters.de/blog/archives/142-HashTables.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=142</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=142</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;In case you ever heard me talking about PHP internals I certainly mentioned something along the lines of &amp;quot;Everything in PHP is a HashTable&amp;quot; that&#039;s not true, but next to a zval the HashTable is one of the most important structures in PHP. While preparing my &amp;quot;&lt;a href=&quot;http://phpconference.nl/schedule/talks#phphood&quot;&gt;PHP Under The Hood&lt;/a&gt;&amp;quot; talk for the Dutch PHP Conference there was a question on IRC about &lt;a href=&quot;http://php.net/extension_loaded&quot;&gt;extension_loaded&lt;/a&gt;() being faster than &lt;a href=&quot;http://php.net/function_exists&quot;&gt;function_exists&lt;/a&gt;(), which might be strange as both of them are simple hash lookups and a hash lookup is said to be O(1). I started to write some slides for it but figured out that I won&#039;t have the time to go through it during that presentation, so I&#039;m doing this now, here:&lt;/p&gt; 
&lt;p&gt;You all should know &lt;a href=&quot;http://php.net/array&quot;&gt;PHP arrays&lt;/a&gt;. They allow you to create a list of elements where every element may be identified by a key. This key may either be an integer or a string. Now we need a way to store this association in an effective way in memory. An efficient way to store a collection of data in memory is a &amp;quot;real&amp;quot; array, an array of elements indexed by a sequence of numbers, starting at 0, up to &lt;em&gt;n&lt;/em&gt;. As memory is essentially a sequence of numbered storage blocks (this obviously is simplified, there might be segments and offsets, there might be virtual pages, etc.) we can efficiently access an element by knowing the address of the first element, the size of the elements (we assume all have the same size, which is the case here), and the index: The address of the n-th element is &lt;em&gt;start_address + (n * size_of_element)&lt;/em&gt;. That&#039;s basically what C arrays are.&lt;/p&gt; 
&lt;p&gt;Now we&#039;re not dealing with C and C arrays but also want to use string offsets so we need a function to calculate a numeric value, a hash, for each key. An hash function you most likely know is &lt;a href=&quot;http://php.net/md5&quot;&gt;MD5&lt;/a&gt;, MD5 is creating a 128 bit numeric value which is often represented using 32 hexadecimal characters. For our purpose 128 bit is a bit much and MD5 is too slow so the PHP developers have chosen the &amp;quot;&lt;a href=&quot;http://lxr.php.net/xref/PHP_5_3/Zend/zend_hash.h#228&quot;&gt;DJBX33A (Daniel J. Bernstein, Times 33 with Addition)&lt;/a&gt;&amp;quot; algorithm. This hash function is relatively fast and gives us an integer of the value, the trouble with this algorithm is that it is more likely to produce conflicts, that means to string values which create the same numeric value.&lt;/p&gt; 
&lt;p&gt;Now back to our C array: For being able to safely read any element, to see whether it is used, we need to pre-allocate the entire array with space for all possible elements. Given our hash function returning a system dependent (32 bit or 64 bit) integer this is quite a lot (size of an element multiplied wit the max int value), so PHP does another trick: It throws some digits away. For this a table mask is calculated. The a table mask is a number which is a power of two and then one subtracted and ideally higher than the number elements in the hash table. If one looks at this in binary representation this is a number where all bits are set. Doing a binary AND operation of our hash value and the table this gives us a number which is smaller than our table mask. Let&#039;s look at an example: The hash value of &amp;quot;foobar&amp;quot; equals, in decimal digits, to 3127933054. We assume a table mask of 2047 (2¹¹-1).&lt;br /&gt;&lt;br /&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;  3127933054    101110100111000001111&lt;strong&gt;00001111110&lt;/strong&gt;
&lt;u&gt;&amp;amp;       2047    &lt;/u&gt;&lt;u&gt;&lt;u&gt;000000000000000000000&lt;/u&gt;&lt;/u&gt;&lt;u&gt;11111111111&lt;/u&gt;
=        126    000000000000000000000&lt;strong&gt;00001111110&lt;/strong&gt;
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Wonderful - we have an array Index, 126, for this string and can set the value in memory!&lt;/p&gt; 
&lt;p&gt;If life were that easy. Remember: We used a hashing function which is by far not collision free and then dropped almost two thirds of the binary digits by using the table mask. This makes it rather likely that some collisions appear. These collisions are handled by storing values with the same hash in a linked list. So for accessing the an element one has to&lt;/p&gt; 
&lt;ol&gt; 
&lt;li&gt;Calculate the hash&lt;/li&gt; 
&lt;li&gt;Apply the table mask&lt;/li&gt; 
&lt;li&gt;locate the memory offset&lt;/li&gt; 
&lt;li&gt;check whether this is the element we need, traverse the linked list.&lt;/li&gt; 
&lt;/ol&gt; 
&lt;p&gt;Now the question initially asked was why extension_loaded() might be faster than function_exists() and we can tell: For many random reasons and since you have chosen a value which probably conflicts in the first, not in the second. So now the question is how often such collisions happen for this I did a quick analysis: Given the function table of a random PHP build of mine with 1106 functions listed I have 634 unique hash values and 210 hash values calculated from different functions. Worst is the value of 471 which represents 6 functions.&lt;/p&gt; 
&lt;p&gt;Full results are &lt;a href=&quot;/~johannes/php/collisions.txt&quot;&gt;online&lt;/a&gt; but please mind: These results are very specific to my environment. Also mind that the code actually works on a copy of my function table so the table mask might be different, which changes results. Also note that the given PHP code won&#039;t work for you as I added special functions exporting the table mask and hash function to mz version of PHP. And then yet another note: doing performance optimizations on this level is the by far worst place as to many unknown factors go in. And you don&#039;t have any measurable performance win. Mind readability. Clear code is worth way more than the 2 CPU cycles you probably gain! But you may have learned how hash tables work.&lt;br /&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sun, 22 Aug 2010 23:52:00 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/142-guid.html</guid>
    <category>computer science 101</category>
<category>hashtable</category>
<category>php</category>
<category>php internals</category>

</item>
<item>
    <title>References and foreach</title>
    <link>http://schlueters.de/blog/archives/141-References-and-foreach.html</link>
            <category>PHP</category>
    
    <comments>http://schlueters.de/blog/archives/141-References-and-foreach.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=141</wfw:comment>

    <slash:comments>8</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=141</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;References in PHP are bad, &lt;a href=&quot;http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html&quot;&gt;as I mentioned before&lt;/a&gt;, and you certainly should avoid using them. Now there is one use case which leads to an, at first, unexpected behavior which I didn&#039;t see as a real live issue when I stumbled over it at first, but then there were a few bug reports about it and recently a friend asked me about it ... so here it goes:&lt;/p&gt; 
&lt;p&gt;What is the output of this code:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
$a = array(&#039;a&#039;, &#039;b&#039;, &#039;c&#039;, &#039;d&#039;);

foreach ($a as &amp;amp;$v) { }
foreach ($a as $v) { }

print_r($a);
?&amp;gt;
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;We are iterating two times over an array without doing anything. So the result should be no change. Right? - Wrong! The actual result looks like this:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;Array
(
    [0] =&amp;gt; a
    [1] =&amp;gt; b
    [2] =&amp;gt; c
    [3] =&amp;gt; c
)
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;For understanding why this happens let&#039;s take a step back and look at the way PHP variables are implemented and what references are:&lt;/p&gt; 
&lt;p&gt;A PHP variable basically consists out of two things: A &amp;quot;label&amp;quot; and a &amp;quot;container.&amp;quot; The label is the entry in a hash table (there are a few optimizations in the engine so it is not always in a hashtable but well) which may represents a symbol table of a function, and array or an object&#039;s property table. So we have a name and a pointer to the container. The container, internally called &amp;quot;zval&amp;quot;, stores the value and some meta information, this container can also be a new hashtable with a set of labels pointing to other containers if we now create an reference this will cause a second label to point to the same container as another label. Both label from then on have the same powers of the container.&lt;/p&gt; 
&lt;p&gt;Now let&#039;s look at the situation from above. In&amp;#160; a picture it looks like this:&lt;/p&gt; 
&lt;p&gt;&lt;!-- s9ymdb:53 --&gt;&lt;img width=&quot;816&quot; height=&quot;490&quot; src=&quot;http://schlueters.de/blog/uploads/code/references_foreach/refe1.png&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;So we have six containers (the global symbol table on the top, a container holding the array called $a on the left and one container for each element on the right) Now we start the first iteration. So the global symbol gets a new entry for $v and v is made a reference to the container of the first array element.&lt;/p&gt; 
&lt;p&gt; &lt;!-- s9ymdb:54 --&gt;&lt;img width=&quot;816&quot; height=&quot;490&quot; class=&quot;serendipity_image_center&quot; src=&quot;http://schlueters.de/blog/uploads/code/references_foreach/refe2.png&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;So an change to either $a[0] or $v goes to the same container and therefore has an effect to the other. When the iteration continues the reference is broken and $v is made a reference to the different elements. So after the iteration ends $v is a reference to the last element.&lt;/p&gt; 
&lt;p&gt; &lt;!-- s9ymdb:55 --&gt;&lt;img width=&quot;816&quot; height=&quot;490&quot; class=&quot;serendipity_image_center&quot; src=&quot;http://schlueters.de/blog/uploads/code/references_foreach/refe3.png&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;Remember: $v being a reference means that any change to $v effects the other references, in this situation $a[3]. Up till now nothing special happened. but now the second iteration begins. This one assigns the value of the current element to $v for each step. Now $v is a reference to the same element as $a[3] so by assigning a value to $v $a[3] is changed, too:&lt;/p&gt; 
&lt;p&gt;&lt;!-- s9ymdb:56 --&gt;&lt;img width=&quot;816&quot; height=&quot;490&quot; class=&quot;serendipity_image_center&quot; src=&quot;http://schlueters.de/blog/uploads/code/references_foreach/refe4.png&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;This continues for he next steps, too.&lt;/p&gt; 
&lt;p&gt;&lt;!-- s9ymdb:57 --&gt;&lt;img width=&quot;816&quot; height=&quot;490&quot; src=&quot;http://schlueters.de/blog/uploads/code/references_foreach/refe5.png&quot; class=&quot;serendipity_image_center&quot; /&gt;&lt;!-- s9ymdb:58 --&gt;&lt;img width=&quot;816&quot; height=&quot;490&quot; src=&quot;http://schlueters.de/blog/uploads/code/references_foreach/refe6.png&quot; class=&quot;serendipity_image_center&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;And now we can easily guess what will happen at the last step: $v is being assigned the value of the last element, $a[3], and as $a[3] is a reference to $v it therefore assignees itself to itself so effectively nothing happens.&lt;/p&gt; 
&lt;p&gt;&lt;!-- s9ymdb:59 --&gt;&lt;img width=&quot;816&quot; height=&quot;490&quot; src=&quot;http://schlueters.de/blog/uploads/code/references_foreach/refe7.png&quot; class=&quot;serendipity_image_center&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;And this is the result we saw above.&lt;/p&gt; 
&lt;p&gt;So to make this story full of pictures short: Be careful about references! They can have really strange effects.&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 20 Aug 2010 13:21:05 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/141-guid.html</guid>
    <category>coding</category>
<category>php</category>
<category>php internals</category>
<category>php references</category>

</item>
<item>
    <title>MySQL at FrOSCon</title>
    <link>http://schlueters.de/blog/archives/140-MySQL-at-FrOSCon.html</link>
            <category>PHP</category>
    
    <comments>http://schlueters.de/blog/archives/140-MySQL-at-FrOSCon.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=140</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=140</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;Oh time is flying! - This weekend it is already time for &lt;a href=&quot;http://www.froscon.de&quot;&gt;FrOSCon&lt;/a&gt;, the Free and Open source Conference in St. Augustin close to Western Germany&#039;s former capitol Bonn. The conference consists out of a main track and different side tracks, like the PHP developer room and the OpenSQL sub-conference.&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;In the &lt;a href=&quot;http://programm.froscon.org/2010/track/PHP(C118)/index.en.html&quot;&gt;PHP developer room&lt;/a&gt; I will give an overview over things that happened at MySQL, especially in regards to PHP in recent times. My colleague Ulf Wendel will then go and talk about plugins to mysqlnd - the MySQL native driver for PHP -&amp;#160; in detail.&lt;/p&gt; 
&lt;p&gt;In the &lt;a href=&quot;http://programm.froscon.org/2010/track/OpenSQLCamp/index.en.html&quot;&gt;OpenSQL Camp&lt;/a&gt; track you can find other interesting MySQL related talks which will, unfortunately, not leave you with enough time to watch all the interesting talks of the &lt;a href=&quot;http://programm.froscon.org/2010/index.en.html&quot;&gt;other tracks&lt;/a&gt;. And that all for an entrance fee of just 5€! So if you have a chance: Go there and say hi!&lt;br /&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Thu, 19 Aug 2010 00:19:39 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/140-guid.html</guid>
    <category>conferences</category>
<category>froscon</category>
<category>froscon10</category>
<category>mysql</category>
<category>php</category>
<category>php conferences</category>

</item>
<item>
    <title>Scalar type hints in PHP trunk</title>
    <link>http://schlueters.de/blog/archives/139-Scalar-type-hints-in-PHP-trunk.html</link>
            <category>PHP</category>
    
    <comments>http://schlueters.de/blog/archives/139-Scalar-type-hints-in-PHP-trunk.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=139</wfw:comment>

    <slash:comments>19</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=139</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;So in my &lt;a href=&quot;http://schlueters.de/blog/plugin/tag/php%FFnext&quot;&gt;blog series&lt;/a&gt; I try to cover all additions to PHP trunk so I have to mention scalar type hints.&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
function print_float(&lt;strong&gt;float&lt;/strong&gt; $f) {
    echo $f.&quot;\n&quot;;
}

for ($i = 1; $i &amp;lt; 5; $i++) {
    print_float( $i / 3 );
}
?&amp;gt;
	&lt;/pre&gt;

	0.33333333333333&lt;br /&gt;
	0.66666666666667&lt;br /&gt; &lt;br /&gt; &lt;strong&gt;Catchable fatal error:&lt;/strong&gt; Argument 1 passed to print_float() must be of the type double, integer given, called in typehints.php on line 7 and defined in typehints.php on line 2






&lt;/blockquote&gt; 
&lt;p&gt;Is expected behavior in PHP&#039;s trunk. If you want such
a thing to work please use the &lt;em&gt;numeric&lt;/em&gt; type hint.&lt;/p&gt; 
&lt;p&gt;In case that wasn&#039;t enought fun: There&#039;s more!&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
function handle_result(&lt;strong&gt;int&lt;/strong&gt; $i) {
    echo $i.&quot;\n&quot;;
}

$pdo = new PDO(&quot;mysql:host=localhost;dbname=test&quot;, &quot;user&quot;, &quot;pass&quot;);
$pdo-&amp;gt;setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, &lt;strong&gt;false&lt;/strong&gt;);
$result = $pdo-&amp;gt;query(&quot;SELECT 42 AS id&quot;);
$row = $result-&amp;gt;fetch();
handle_result($row[&#039;id&#039;]);

$pdo = new PDO(&quot;mysql:host=localhost;dbname=test&quot;, &quot;user&quot;, &quot;pass&quot;);
$pdo-&amp;gt;setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, &lt;strong&gt;true&lt;/strong&gt;);
$result = $pdo-&amp;gt;query(&quot;SELECT 42 AS id&quot;);
$row = $result-&amp;gt;fetch();
handle_result($row[&#039;id&#039;]);
?&amp;gt;
	&lt;/pre&gt;
	42&lt;br /&gt; &lt;br /&gt; &lt;strong&gt;Catchable fatal error:&lt;/strong&gt; Argument 1 passed to handle_result() must be of the type integer, string given, called in typehints.php on line 16 and defined in typehints.php on line 2






&lt;/blockquote&gt; 
&lt;p&gt;So what happens here? - Depending on the &lt;a href=&quot;http://php.net/pdo_mysql#pdo-mysql.constants&quot;&gt;PDO::MYSQL_ATTR_DIRECT_QUERY&lt;/a&gt; option PDO will either
emulate prepared statements (which would be irrelevant here, but that&#039;s another story)
or use native prepared statements. When using prepared statements MySQL switches over to its
&amp;quot;binary&amp;quot; protocol which returns the native types, else it always returns strings. When using
PDO_mysql linked against &lt;a href=&quot;http://php.net/mysqlnd&quot;&gt;mysqlnd&lt;/a&gt; the native type is returned to PHP. If I would use
libmysql both times a string would be returned. In other words: The behavior is system dependent.
The default behavior for other drivers
isn&#039;t defined either. As PHP is a dynamically typed language this shouldn&#039;t matter, so
depending on your driver the results vary. Great. Oh and did I mention that the
types aren&#039;t specified, so a later version of a driver might change it. And PDO
is just a simple example for this ...&lt;/p&gt; 
&lt;p&gt;The key point of this all is that as soon as you mix strong typing - by using
type hints - with PHP&#039;s weak type system you open a can of worms.&lt;/p&gt; 
&lt;p&gt;And to be overly clear: I can understand the need for strict type systems and
see where such a thing helps. But adding a strong type system, stricter
than most other languages (hey, you can&#039;t pass an integer where a float is expected!),
makes little sense to me. But that&#039;s just me.&lt;/p&gt; 
&lt;p&gt;As in my &lt;a href=&quot;http://schlueters.de/blog/plugin/tag/php%FFnext&quot;&gt;previous posts&lt;/a&gt; in the series of blog posts about features in PHP trunk.
Please try the &lt;a href=&quot;http://snaps.php.net&quot;&gt;snapshots&lt;/a&gt;. Mind that these features might (not) end up in the next release of PHP, &lt;a href=&quot;http://bugs.php.net&quot;&gt;feedback&lt;/a&gt; is welcome.&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sat, 07 Aug 2010 23:00:00 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/139-guid.html</guid>
    <category>pdo</category>
<category>php</category>
<category>php.next</category>
<category>type hints</category>

</item>
<item>
    <title>Features in PHP trunk: Array dereferencing</title>
    <link>http://schlueters.de/blog/archives/138-Features-in-PHP-trunk-Array-dereferencing.html</link>
            <category>PHP</category>
    
    <comments>http://schlueters.de/blog/archives/138-Features-in-PHP-trunk-Array-dereferencing.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=138</wfw:comment>

    <slash:comments>22</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=138</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;I was writing about &lt;a href=&quot;http://schlueters.de/blog/plugin/tag/php%FFnext&quot;&gt;new features in the upcoming PHP version&lt;/a&gt; (5.4, 6.0?) before. Today&#039;s topic reads like this in the &lt;a href=&quot;http://svn.php.net/viewvc/php/php-src/trunk/NEWS?revision=HEAD&amp;amp;view=markup&quot;&gt;NEWS&lt;/a&gt; file:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;p&gt;- Added array dereferencing support. (Felipe)&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Now you might wonder what this typical short entry means. when doing OO-style PHP you might make use of a sntax feature which one might call &amp;quot;object dereferencing&amp;quot; which looks like this:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
class Foo {
    public function bar() { }
}

function func() {
    return new Foo();
}

&lt;strong&gt;func()-&amp;gt;bar();&lt;/strong&gt;
?&amp;gt;
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;So one can chain method calls or property access. Now for a long time people requested the same thing for array offset access. This was often rejected due to uncertainties about memory issues, as we don&#039;t like memory leaks. But after proper evaluation Felipe committed the patch which allows you to do things like&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
function foo() {
    return array(1, 2, 3);
}
echo &lt;strong&gt;foo()[2]&lt;/strong&gt;; // prints 3
?&amp;gt;
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Of course this also works with closures:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
$func = function() { return array(&#039;a&#039;, &#039;b&#039;, &#039;c&#039;); };
echo &lt;strong&gt;$func()[0]&lt;/strong&gt;; // prints a
?&amp;gt;
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;And even though the following example is stupid I might accept this feature as one of the few places where it is &lt;a href=&quot;http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html&quot;&gt;ok to use references in PHP&lt;/a&gt;:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
$data = array(&#039;me&#039;, &#039;myself&#039;, &#039;you&#039;);
function &lt;strong&gt;&amp;amp;&lt;/strong&gt;get_data() {
    return $GLOBALS[&#039;data&#039;];
}
&lt;strong&gt;get_data()[2] = &#039;I&#039;;&lt;/strong&gt; // $data will now contain &#039;me&#039;, &#039;myself&#039; and &#039;I&#039;
?&amp;gt;

&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Wonderful, isn&#039;t it? If you want to test it please take a look at the recent &lt;a href=&quot;http://snaps.php.net&quot;&gt;snapshots for PHP trunk&lt;/a&gt; and send us your feedback! Please mind that all features in PHP trunk may or may not appear in the next major PHP release.&lt;br /&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sat, 31 Jul 2010 13:11:39 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/138-guid.html</guid>
    <category>array</category>
<category>coding</category>
<category>oop</category>
<category>php</category>
<category>php qa</category>
<category>php.next</category>

</item>
<item>
    <title>ZFS and VirtualBox</title>
    <link>http://schlueters.de/blog/archives/137-ZFS-and-VirtualBox.html</link>
            <category>Software</category>
    
    <comments>http://schlueters.de/blog/archives/137-ZFS-and-VirtualBox.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=137</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=137</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;With ZFS you may not only do &amp;quot;file system&amp;quot; stuff but ZFS may also provide raw block devices (&amp;quot;zvol&amp;quot;) which benefit from ZFS space accounting, snapshotting, checksumming, etc. A purpose of these is to use these zvols and exporting them via iSCSI or give them to applications which can store data on them. One application for this I&#039;m using s VirtualBox and as I always forget the exact commands needed to create a zvol and making it available to VBox I decided to write it down.&lt;/p&gt; 
&lt;p&gt;Reasons for me for using zvols instead of regular VBox disks are that I can easily snapshot them (every 15 minutes a snapshot ...) individually and can easily clone them (around one second and barely any disk space needed to get a clone of a VM to do some experimental stuff...) and incremental backups using snapshots and zfs send. That said there&#039;s at least one - possibly - negative factor: A regular virtual disk file can be shared with other people and other operating systems, a zvol has to be dumped into a regular vmdk first.&lt;/p&gt; 
&lt;p&gt;Anyways here are the steps needed:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;# zfs create -V 10G tank/some_name
# chown johannes /dev/zvol/rdsk/tank/some_name
# VBoxManage internalcommands createrawvmdk \
   -filename /home/johannes/VBoxdisks/some_name.vmdk \
   -rawdisk /dev/zvol/rdsk/tank/some_name
# VBoxManage registerimage disk /home/johannes/VBoxdisks/some_name.vmdk
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;So first we create the zvol with a size of 10G. This won&#039;t be allocated but everybody asking for the size of the device will get this information back and this is the maximum size that will be used - as one can use compression and dedup there this often might be way less usage. Then, as I&#039;m running VBox under my user account, I give my user all the rights needed by making the regular user the owner. The third step creates a vmdk file pointing to the raw device location which is then registered with VirtualBox so a VM can be configured for using it.&lt;/p&gt; 
&lt;p&gt;Works nicely.&lt;br /&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sun, 25 Jul 2010 15:34:05 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/137-guid.html</guid>
    <category>oracle</category>
<category>storage</category>
<category>virtualbox</category>
<category>virtualization</category>
<category>vmdk</category>
<category>zfs</category>
<category>zvol</category>

</item>
<item>
    <title>15 years of PHP</title>
    <link>http://schlueters.de/blog/archives/136-15-years-of-PHP.html</link>
    
    <comments>http://schlueters.de/blog/archives/136-15-years-of-PHP.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=136</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=136</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;Wow, 15 years ago, on June 8th 1995, &lt;a href=&quot;http://groups.google.com/group/comp.infosystems.www.authoring.cgi/msg/cc7d43454d64d133?dmode=source&amp;amp;hl=en&quot;&gt;Rasmus announced PHP 1.0&lt;/a&gt;. Time for a personal look back:&lt;/p&gt; 
&lt;p&gt;I can&#039;t remember when I first went online. Out from the local BBS systems into the wide open net. It must have been around the same time. But soon I figured out that I needed my own homepage, so I created one, using black fonts on a green (#00ff00) background. I was proud. The only issue: I had no idea how to make it accessible to others, I had the HTML file local on the PC, but well, I still was proud. I was proud since the effect of this HTML with a little bit of JavaScript was way stronger than most of my BASIC stuff I did before.&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;A bit later, in 1998, a cousin brought a magazine about writing Perl CGI applications which caught my attention so I started learning about CGI and Perl and all the related stuff. Back then I always used my own,custom data formats for storing data. But my brother had mercy and introduced me to MySQL. I knew Paradox (and BerkeleyDB) from my Delphi programming but the powers of SQL were amazing. So I was happily building my stuff Perl+MySQL till ... yeah till the server broke down. CGI didn&#039;t work anymore for some reason.&lt;/p&gt; 
&lt;p&gt;My brother, who setup our Linux box at home but didn&#039;t know much about Apache, had the pragmatic solution: PHP worked. So what did I do? - Learn PHP. And I loved it. That was in 1999. After that many tings happened. PHP evolved and became a strong player in the web market. I worked for companies like &lt;a href=&quot;http://www.mayflower.de&quot;&gt;Mayflower&lt;/a&gt;, &lt;a href=&quot;http://www.mysql.com&quot;&gt;MySQL&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/Sun_Microsystems&quot;&gt;Sun Microsystems&lt;/a&gt; and, most likely, soon &lt;a href=&quot;http://www.oracle.com&quot;&gt;Oracle&lt;/a&gt;. And even though I&#039;m using way more C and C++ these days most of it is still directly related to PHP and this all due to some Greenlandic guy who published hist Personal Home Page Tools and my brother who couldn&#039;t configure CGI.&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;15 years and still strong. Congratulations PHP!&lt;br /&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Tue, 08 Jun 2010 00:00:00 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/136-guid.html</guid>
    <category>anniversary</category>
<category>birthday</category>
<category>coding</category>
<category>php</category>

</item>
<item>
    <title>Jason, let me help you!</title>
    <link>http://schlueters.de/blog/archives/135-Jason,-let-me-help-you!.html</link>
            <category>PHP</category>
    
    <comments>http://schlueters.de/blog/archives/135-Jason,-let-me-help-you!.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=135</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=135</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;In a few previous blog posts I was already &lt;a href=&quot;http://schlueters.de/blog/plugin/tag/php%FFnext&quot;&gt;talking about changes&lt;/a&gt; in &lt;a href=&quot;http://schlueters.de/blog/archives/128-Future-of-PHP-6.html&quot;&gt;PHP&#039;s trunk&lt;/a&gt;, like &lt;a href=&quot;http://schlueters.de/blog/archives/129-Mind-the-encodings!.html&quot;&gt;some BC break&lt;/a&gt; or &lt;a href=&quot;http://schlueters.de/blog/archives/133-Now-in-trunk-Improved-interactive-shell.html&quot;&gt;some new features&lt;/a&gt;, time to continue:&lt;/p&gt; 
&lt;p&gt;JSON is the modern data format used in &amp;quot;AJAX&amp;quot; applications. As &lt;strong&gt;the&lt;/strong&gt; leading language for the Web PHP course has support for handling JSON data: You can pass any data to &lt;a href=&quot;http://php.net/json_encode&quot;&gt;json_encode()&lt;/a&gt; and the function will create a JSON representation of this data:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
echo json_encode(array(1,2,3,4));
?&amp;gt;

[1,2,3,4]

&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;This also works for objects:&lt;br /&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
$o = new stdclass;
$o-&amp;gt;a = 42;
echo json_encode($o);
?&amp;gt;

{&quot;a&quot;:42}
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Wonderful. But the world isn&#039;t that easy. For many PHP objects the JSON-representation of the data is a bit more complex.for instance what about private properties or maybe you want to calculate some inner values? - In PHP 5.3 you were on your own. but thanks to Sara there&#039;s hope in sight: the new interface &lt;em&gt;JsonSerializable&lt;/em&gt;. Classes implementing this interface have to provide a method &lt;em&gt;jsonSerialize()&lt;/em&gt; which will be called by &lt;em&gt;json_encode()&lt;/em&gt; and has to return a JSON-compatible representation of the data by doing whatever you want. So let&#039;s take a look:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
class JsonTest implements JsonSerializable {
    private $a, $b;

    public function __construct($a, $b) {
        $this-&amp;gt;a = $a;
        $this-&amp;gt;b = $b;
    }

    public function jsonSerialize() {
        return $this-&amp;gt;a + $this-&amp;gt;b;
    }
}

echo json_encode(new JsonTest(23, 42));
?&amp;gt;

65
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Now this example in itself is of course useless, but let&#039;s create a bigger structure, which includes a few of these objects:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
$data = array(
    new stdClass();
    new JsonTest(1,2),
    new JsonTest(3,4),
    array(5,6)
);
echo json_encode($data);
?&amp;gt;

[{},3,7,[5,6]]
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Of course you&#039;d usually have more complex serialization logic, but that&#039;s left to you.&lt;/p&gt; 
&lt;p&gt;Now almost certainly somebody will ask &amp;quot;and what about the other way round?&amp;quot; - The only answer there is: Sorry there we can&#039;t do much. JSON doesn&#039;t encode and meta-information so our generic parser in &lt;a href=&quot;http://php.net/json_decode&quot;&gt;json_decode()&lt;/a&gt; can&#039;t do anything special. But anyways: The new interface will certainly be useful.&lt;/p&gt; 
&lt;p&gt;At last a short disclaimer: PHP trunk is a development tree. Features in their may be changed at anytime and might not be released. Feedback is welcome.&lt;br /&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Thu, 03 Jun 2010 19:01:00 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/135-guid.html</guid>
    <category>ajax</category>
<category>coding</category>
<category>json</category>
<category>php</category>
<category>php oo</category>
<category>php.next</category>

</item>
<item>
    <title>Berkeley DB 5 and PHP</title>
    <link>http://schlueters.de/blog/archives/134-Berkeley-DB-5-and-PHP.html</link>
            <category>PHP</category>
    
    <comments>http://schlueters.de/blog/archives/134-Berkeley-DB-5-and-PHP.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=134</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=134</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;Everybody working on Unix or in the database world stumbles over &lt;a href=&quot;http://www.oracle.com/database/berkeley-db/db/index.html&quot;&gt;Oracle Berkeley DB&lt;/a&gt; every now and then. DB is an Open Source embedded database used by applications like OpenLDAP or Postfix. Traditionally it followed mostly a key-value access pattern. Now what caught my attention was the fact that the recently released DB 5.0 provides an &lt;a href=&quot;http://www.oracle.com/technology/documentation/berkeley-db/db/bdb-sql/index.html&quot;&gt;SQLite-like C API&lt;/a&gt; with the promise of providing better concurrency and performance than regular SQLite. Time to give it a shot.&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;So I grabbed the &lt;a href=&quot;http://www.oracle.com/technology/software/products/berkeley-db/index.html&quot;&gt;source distribution&lt;/a&gt;, checked the documentation and saw that I shall use the &lt;a href=&quot;http://www.oracle.com/technology/documentation/berkeley-db/db/bdb-sql/buildinstall.html#onunix&quot;&gt;&lt;em&gt;--enable-sql_compat&lt;/em&gt;&lt;/a&gt; configure option so DB creates a libsqlite3.so which can be used by PHP&#039;s build system. On my system compiling this worked like a charm and after linking PHP against it the SQLite3 extension as well as th SQLite PDO driver worked as before. I didn&#039;t do any benchmarks, yet, but I would be interested to read some results. Oh and yes, according to the documentation there are a &lt;a href=&quot;http://www.oracle.com/technology/documentation/berkeley-db/db/bdb-sql/miscdiff.html&quot;&gt;few minor changes in behavior&lt;/a&gt;, this should only affect very few PHP users though.&lt;/p&gt; 
&lt;p&gt;So the whole process after extracting DB and PHP sources looked like this:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;$ cd db-5.0.21/build_unix
$ ../dist/configure --prefix=/opt/db-5.0.21 --enable-sql_compat --enable-cxx
$ make
# make install
$ cd ../..
$ cd php-src
$ ./configure --with-sqlite3=/opt/db-5.0.21 --with-pdo-sqlite=/opt/db-5.0.21 --with-other-php-options
$ make
# make install&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Now you don&#039;t have to use the SQLite interface for using DB but can also use &lt;a href=&quot;http://php.net/dba&quot;&gt;PHP&#039;s dba extension&lt;/a&gt;. In current releases of PHP PHP expects at most DB version number 4 for the DBA driver, but a patch was &lt;a href=&quot;http://news.php.net/php.cvs/62805&quot;&gt;committed&lt;/a&gt; to PHP&#039;s svn repository so upcoming PHP releases can be build using the latest DB version by adding &lt;em&gt;--with-db4=/opt/db-5.0.21&lt;/em&gt; to PHP&#039;s configure line.&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;Now I can hear you complain: &amp;quot;three ways to access a database isn&#039;t enough!&amp;quot; - which is true as the SQLite3 extension as well as the PDO SQLite driver are limited to SQLite capabilities and DBA, as an abstraction layer for Berkeley DB-like databases, only offers some basic operations, too. But there&#039;s hope:&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;While browsing through the DB source distribution I stumbled over a directory called php_db4 which obviously caught my further attention, so the DB developers are bundling a DB-specific PHP extension wrapping DB&#039;s native C++ API in an PHP OO API. To try it simply follow the &lt;a href=&quot;http://php.net/manual/en/install.pecl.phpize.php&quot;&gt;steps from the PHP manual&lt;/a&gt; for compiling custom extensions:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;$ cd db-5.0.21/php_db4
$ phpize
$ ./configure --with-db4=/opt/db-5.0.21
$ make
# make install&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;And then a quick check using reflection to see what functionality is provided by this extension:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;$ php -dextension=db4.so --re db4
Extension [ &lt;persistent&gt; extension #45 db4 version 0.9 ] {

  - Constants [210] {
    Constant [ integer DB_VERSION_MAJOR ] { 5 }
    Constant [ integer DB_VERSION_MINOR ] { 0 }
    Constant [ integer DB_VERSION_PATCH ] { 21 }
    Constant [ string DB_VERSION_STRING ] { Berkeley DB 5.0.21: (March 30, 2010) }
    Constant [ integer DB_MAX_PAGES ] { 4294967295 }
    Constant [ integer DB_MAX_RECORDS ] { 4294967295 }
    Constant [ integer DB_DBT_APPMALLOC ] { 1 }
    Constant [ integer DB_DBT_ISSET ] { 8 }
    Constant [ integer DB_DBT_MALLOC ] { 16 }
    Constant [ integer DB_DBT_PARTIAL ] { 64 }
    Constant [ integer DB_DBT_REALLOC ] { 128 }
    Constant [ integer DB_DBT_USERMEM ] { 1024 }
    Constant [ integer DB_DBT_DUPOK ] { 4 }
    Constant [ integer DB_CREATE ] { 1 }
    Constant [ integer DB_CXX_NO_EXCEPTIONS ] { 2 }
    Constant [ integer DB_FORCE ] { 1 }
    Constant [ integer DB_NOMMAP ] { 8 }
    Constant [ integer DB_RDONLY ] { 1024 }
    Constant [ integer DB_RECOVER ] { 2 }
    Constant [ integer DB_MULTIVERSION ] { 4 }
    Constant [ integer DB_TXN_SNAPSHOT ] { 2 }
    Constant [ integer DB_THREAD ] { 16 }
    Constant [ integer DB_TRUNCATE ] { 32768 }
    Constant [ integer DB_TXN_NOSYNC ] { 1 }
    Constant [ integer DB_TXN_NOT_DURABLE ] { 2 }
    Constant [ integer DB_USE_ENVIRON ] { 4 }
    Constant [ integer DB_USE_ENVIRON_ROOT ] { 8 }
    Constant [ integer DB_AUTO_COMMIT ] { 256 }
    Constant [ integer DB_DIRTY_READ ] { 512 }
    Constant [ integer DB_DEGREE_2 ] { 1024 }
    Constant [ integer DB_READ_COMMITTED ] { 1024 }
    Constant [ integer DB_READ_UNCOMMITTED ] { 512 }
    Constant [ integer DB_NO_AUTO_COMMIT ] { 8192 }
    Constant [ integer DB_RPCCLIENT ] { 1 }
    Constant [ integer DB_INIT_CDB ] { 64 }
    Constant [ integer DB_INIT_LOCK ] { 128 }
    Constant [ integer DB_INIT_LOG ] { 256 }
    Constant [ integer DB_INIT_MPOOL ] { 512 }
    Constant [ integer DB_INIT_REP ] { 1024 }
    Constant [ integer DB_INIT_TXN ] { 2048 }
    Constant [ integer DB_JOINENV ] { 0 }
    Constant [ integer DB_LOCKDOWN ] { 4096 }
    Constant [ integer DB_PRIVATE ] { 8192 }
    Constant [ integer DB_RECOVER_FATAL ] { 16384 }
    Constant [ integer DB_SYSTEM_MEM ] { 65536 }
    Constant [ integer DB_EXCL ] { 64 }
    Constant [ integer DB_FCNTL_LOCKING ] { 2048 }
    Constant [ integer DB_RDWRMASTER ] { 16384 }
    Constant [ integer DB_WRITEOPEN ] { 65536 }
    Constant [ integer DB_TXN_NOWAIT ] { 16 }
    Constant [ integer DB_TXN_SYNC ] { 4 }
    Constant [ integer DB_ENCRYPT_AES ] { 1 }
    Constant [ integer DB_CDB_ALLDB ] { 64 }
    Constant [ integer DB_DIRECT_DB ] { 128 }
    Constant [ integer DB_NOLOCKING ] { 1024 }
    Constant [ integer DB_NOPANIC ] { 2048 }
    Constant [ integer DB_OVERWRITE ] { 4096 }
    Constant [ integer DB_PANIC_ENVIRONMENT ] { 8192 }
    Constant [ integer DB_REGION_INIT ] { 16384 }
    Constant [ integer DB_TIME_NOTGRANTED ] { 32768 }
    Constant [ integer DB_TXN_WRITE_NOSYNC ] { 32 }
    Constant [ integer DB_YIELDCPU ] { 65536 }
    Constant [ integer DB_UPGRADE ] { 1 }
    Constant [ integer DB_VERIFY ] { 2 }
    Constant [ integer DB_DIRECT ] { 16 }
    Constant [ integer DB_EXTENT ] { 64 }
    Constant [ integer DB_ODDFILESIZE ] { 128 }
    Constant [ integer DB_CHKSUM ] { 8 }
    Constant [ integer DB_DUP ] { 16 }
    Constant [ integer DB_DUPSORT ] { 4 }
    Constant [ integer DB_ENCRYPT ] { 1 }
    Constant [ integer DB_RECNUM ] { 64 }
    Constant [ integer DB_RENUMBER ] { 128 }
    Constant [ integer DB_REVSPLITOFF ] { 256 }
    Constant [ integer DB_SNAPSHOT ] { 512 }
    Constant [ integer DB_STAT_CLEAR ] { 1 }
    Constant [ integer DB_JOIN_NOSORT ] { 1 }
    Constant [ integer DB_AGGRESSIVE ] { 1 }
    Constant [ integer DB_NOORDERCHK ] { 2 }
    Constant [ integer DB_ORDERCHKONLY ] { 4 }
    Constant [ integer DB_PR_PAGE ] { 16 }
    Constant [ integer DB_PR_RECOVERYTEST ] { 32 }
    Constant [ integer DB_PRINTABLE ] { 8 }
    Constant [ integer DB_SALVAGE ] { 64 }
    Constant [ integer DB_REP_NOBUFFER ] { 2 }
    Constant [ integer DB_REP_PERMANENT ] { 4 }
    Constant [ integer DB_LOCKVERSION ] { 1 }
    Constant [ integer DB_FILE_ID_LEN ] { 20 }
    Constant [ integer DB_LOCK_NORUN ] { 0 }
    Constant [ integer DB_LOCK_DEFAULT ] { 1 }
    Constant [ integer DB_LOCK_EXPIRE ] { 2 }
    Constant [ integer DB_LOCK_MAXLOCKS ] { 3 }
    Constant [ integer DB_LOCK_MINLOCKS ] { 5 }
    Constant [ integer DB_LOCK_MINWRITE ] { 6 }
    Constant [ integer DB_LOCK_OLDEST ] { 7 }
    Constant [ integer DB_LOCK_RANDOM ] { 8 }
    Constant [ integer DB_LOCK_YOUNGEST ] { 9 }
    Constant [ integer DB_LOCK_NOWAIT ] { 1 }
    Constant [ integer DB_LOCK_RECORD ] { 2 }
    Constant [ integer DB_LOCK_SET_TIMEOUT ] { 4 }
    Constant [ integer DB_LOCK_SWITCH ] { 8 }
    Constant [ integer DB_LOCK_UPGRADE ] { 16 }
    Constant [ integer DB_HANDLE_LOCK ] { 1 }
    Constant [ integer DB_RECORD_LOCK ] { 2 }
    Constant [ integer DB_PAGE_LOCK ] { 3 }
    Constant [ integer DB_LOGVERSION ] { 17 }
    Constant [ integer DB_LOGOLDVER ] { 8 }
    Constant [ integer DB_LOGMAGIC ] { 264584 }
    Constant [ integer DB_ARCH_ABS ] { 1 }
    Constant [ integer DB_ARCH_DATA ] { 2 }
    Constant [ integer DB_ARCH_LOG ] { 4 }
    Constant [ integer DB_ARCH_REMOVE ] { 8 }
    Constant [ integer DB_FLUSH ] { 1 }
    Constant [ integer DB_LOG_CHKPNT ] { 2 }
    Constant [ integer DB_LOG_COMMIT ] { 4 }
    Constant [ integer DB_LOG_NOCOPY ] { 8 }
    Constant [ integer DB_LOG_NOT_DURABLE ] { 16 }
    Constant [ integer DB_LOG_WRNOSYNC ] { 32 }
    Constant [ integer DB_user_BEGIN ] { 10000 }
    Constant [ integer DB_debug_FLAG ] { 2147483648 }
    Constant [ integer DB_LOG_DISK ] { 1 }
    Constant [ integer DB_LOG_LOCKED ] { 2 }
    Constant [ integer DB_LOG_SILENT_ERR ] { 4 }
    Constant [ integer DB_MPOOL_CREATE ] { 1 }
    Constant [ integer DB_MPOOL_LAST ] { 16 }
    Constant [ integer DB_MPOOL_NEW ] { 32 }
    Constant [ integer DB_MPOOL_DIRTY ] { 2 }
    Constant [ integer DB_MPOOL_DISCARD ] { 1 }
    Constant [ integer DB_MPOOL_NOFILE ] { 1 }
    Constant [ integer DB_MPOOL_UNLINK ] { 2 }
    Constant [ integer DB_TXNVERSION ] { 1 }
    Constant [ integer DB_GID_SIZE ] { 128 }
    Constant [ integer DB_EID_BROADCAST ] { -1 }
    Constant [ integer DB_EID_INVALID ] { -2 }
    Constant [ integer DB_REP_CLIENT ] { 1 }
    Constant [ integer DB_REP_MASTER ] { 2 }
    Constant [ integer DB_RENAMEMAGIC ] { 198656 }
    Constant [ integer DB_BTREEVERSION ] { 9 }
    Constant [ integer DB_BTREEOLDVER ] { 8 }
    Constant [ integer DB_BTREEMAGIC ] { 340322 }
    Constant [ integer DB_HASHVERSION ] { 9 }
    Constant [ integer DB_HASHOLDVER ] { 7 }
    Constant [ integer DB_HASHMAGIC ] { 398689 }
    Constant [ integer DB_QAMVERSION ] { 4 }
    Constant [ integer DB_QAMOLDVER ] { 3 }
    Constant [ integer DB_QAMMAGIC ] { 270931 }
    Constant [ integer DB_AFTER ] { 1 }
    Constant [ integer DB_APPEND ] { 2 }
    Constant [ integer DB_BEFORE ] { 3 }
    Constant [ integer DB_CONSUME ] { 4 }
    Constant [ integer DB_CONSUME_WAIT ] { 5 }
    Constant [ integer DB_CURRENT ] { 6 }
    Constant [ integer DB_FAST_STAT ] { 1 }
    Constant [ integer DB_FIRST ] { 7 }
    Constant [ integer DB_GET_BOTH ] { 8 }
    Constant [ integer DB_GET_BOTHC ] { 9 }
    Constant [ integer DB_GET_BOTH_RANGE ] { 10 }
    Constant [ integer DB_GET_RECNO ] { 11 }
    Constant [ integer DB_JOIN_ITEM ] { 12 }
    Constant [ integer DB_KEYFIRST ] { 13 }
    Constant [ integer DB_KEYLAST ] { 14 }
    Constant [ integer DB_LAST ] { 15 }
    Constant [ integer DB_NEXT ] { 16 }
    Constant [ integer DB_NEXT_DUP ] { 17 }
    Constant [ integer DB_NEXT_NODUP ] { 18 }
    Constant [ integer DB_NODUPDATA ] { 19 }
    Constant [ integer DB_NOOVERWRITE ] { 20 }
    Constant [ integer DB_NOSYNC ] { 21 }
    Constant [ integer DB_POSITION ] { 23 }
    Constant [ integer DB_PREV ] { 24 }
    Constant [ integer DB_PREV_NODUP ] { 26 }
    Constant [ integer DB_SET ] { 27 }
    Constant [ integer DB_SET_LOCK_TIMEOUT ] { 1 }
    Constant [ integer DB_SET_RANGE ] { 28 }
    Constant [ integer DB_SET_RECNO ] { 29 }
    Constant [ integer DB_SET_TXN_NOW ] { 8 }
    Constant [ integer DB_SET_TXN_TIMEOUT ] { 2 }
    Constant [ integer DB_UPDATE_SECONDARY ] { 30 }
    Constant [ integer DB_WRITECURSOR ] { 8 }
    Constant [ integer DB_WRITELOCK ] { 16 }
    Constant [ integer DB_OPFLAGS_MASK ] { 255 }
    Constant [ integer DB_MULTIPLE ] { 2048 }
    Constant [ integer DB_MULTIPLE_KEY ] { 16384 }
    Constant [ integer DB_RMW ] { 8192 }
    Constant [ integer DB_DONOTINDEX ] { -30998 }
    Constant [ integer DB_KEYEMPTY ] { -30996 }
    Constant [ integer DB_KEYEXIST ] { -30995 }
    Constant [ integer DB_LOCK_DEADLOCK ] { -30994 }
    Constant [ integer DB_LOCK_NOTGRANTED ] { -30993 }
    Constant [ integer DB_NOSERVER ] { -30990 }
    Constant [ integer DB_NOSERVER_HOME ] { -30989 }
    Constant [ integer DB_NOSERVER_ID ] { -30988 }
    Constant [ integer DB_NOTFOUND ] { -30987 }
    Constant [ integer DB_OLD_VERSION ] { -30986 }
    Constant [ integer DB_PAGE_NOTFOUND ] { -30985 }
    Constant [ integer DB_REP_DUPMASTER ] { -30984 }
    Constant [ integer DB_REP_HANDLE_DEAD ] { -30983 }
    Constant [ integer DB_REP_HOLDELECTION ] { -30982 }
    Constant [ integer DB_REP_ISPERM ] { -30980 }
    Constant [ integer DB_REP_NEWMASTER ] { -30893 }
    Constant [ integer DB_REP_NEWSITE ] { -30976 }
    Constant [ integer DB_REP_NOTPERM ] { -30975 }
    Constant [ integer DB_REP_UNAVAIL ] { -30974 }
    Constant [ integer DB_RUNRECOVERY ] { -30973 }
    Constant [ integer DB_SECONDARY_BAD ] { -30972 }
    Constant [ integer DB_VERIFY_BAD ] { -30970 }
    Constant [ integer DB_VERB_DEADLOCK ] { 1 }
    Constant [ integer DB_VERB_RECOVERY ] { 8 }
    Constant [ integer DB_VERB_REPLICATION ] { 32 }
    Constant [ integer DB_VERB_WAITSFOR ] { 32768 }
  }

  - Classes [4] {
    Class [ &lt;internal:db4&gt; class db4txn ] {

      - Constants [0] {
      }

      - Static properties [0] {
      }

      - Static methods [0] {
      }

      - Properties [0] {
      }

      - Methods [8] {
        Method [ &lt;internal:db4&gt; public method abort ] {
        }

        Method [ &lt;internal:db4&gt; public method commit ] {
        }

        Method [ &lt;internal:db4&gt; public method discard ] {
        }

        Method [ &lt;internal:db4&gt; public method id ] {
        }

        Method [ &lt;internal:db4&gt; public method set_timeout ] {
        }

        Method [ &lt;internal:db4&gt; public method set_name ] {
        }

        Method [ &lt;internal:db4&gt; public method get_name ] {
        }

        Method [ &lt;internal:db4, ctor=&quot;&quot;&gt; public method db4txn ] {
        }
      }
    }

    Class [ &lt;internal:db4&gt; class db4cursor ] {

      - Constants [0] {
      }

      - Static properties [0] {
      }

      - Static methods [0] {
      }

      - Properties [0] {
      }

      - Methods [7] {
        Method [ &lt;internal:db4&gt; public method close ] {
        }

        Method [ &lt;internal:db4&gt; public method count ] {
        }

        Method [ &lt;internal:db4&gt; public method del ] {
        }

        Method [ &lt;internal:db4&gt; public method dup ] {
        }

        Method [ &lt;internal:db4&gt; public method get ] {

          - Parameters [2] {
            Parameter #0 [ &lt;required&gt; &amp;amp;$param0 ]
            Parameter #1 [ &lt;required&gt; &amp;amp;$param1 ]
          }
        }

        Method [ &lt;internal:db4&gt; public method put ] {
        }

        Method [ &lt;internal:db4&gt; public method pget ] {

          - Parameters [2] {
            Parameter #0 [ &lt;required&gt; &amp;amp;$param0 ]
            Parameter #1 [ &lt;required&gt; &amp;amp;$param1 ]
          }
        }
      }
    }

    Class [ &lt;internal:db4&gt; class db4 ] {

      - Constants [0] {
      }

      - Static properties [0] {
      }

      - Static methods [0] {
      }

      - Properties [0] {
      }

      - Methods [15] {
        Method [ &lt;internal:db4, ctor=&quot;&quot;&gt; public method db4 ] {
        }

        Method [ &lt;internal:db4&gt; public method open ] {
        }

        Method [ &lt;internal:db4&gt; public method close ] {
        }

        Method [ &lt;internal:db4&gt; public method cursor ] {
        }

        Method [ &lt;internal:db4&gt; public method del ] {
        }

        Method [ &lt;internal:db4&gt; public method get ] {
        }

        Method [ &lt;internal:db4&gt; public method get_encrypt_flags ] {
        }

        Method [ &lt;internal:db4&gt; public method pget ] {
        }

        Method [ &lt;internal:db4&gt; public method get_type ] {
        }

        Method [ &lt;internal:db4&gt; public method join ] {
        }

        Method [ &lt;internal:db4&gt; public method put ] {
        }

        Method [ &lt;internal:db4&gt; public method set_encrypt ] {
        }

        Method [ &lt;internal:db4&gt; public method stat ] {
        }

        Method [ &lt;internal:db4&gt; public method sync ] {
        }

        Method [ &lt;internal:db4&gt; public method truncate ] {
        }
      }
    }

    Class [ &lt;internal:db4&gt; class db4env ] {

      - Constants [0] {
      }

      - Static properties [0] {
      }

      - Static methods [0] {
      }

      - Properties [0] {
      }

      - Methods [11] {
        Method [ &lt;internal:db4, ctor=&quot;&quot;&gt; public method db4env ] {
        }

        Method [ &lt;internal:db4&gt; public method close ] {
        }

        Method [ &lt;internal:db4&gt; public method dbremove ] {
        }

        Method [ &lt;internal:db4&gt; public method dbrename ] {
        }

        Method [ &lt;internal:db4&gt; public method get_encrypt ] {
        }

        Method [ &lt;internal:db4&gt; public method open ] {
        }

        Method [ &lt;internal:db4&gt; public method remove ] {
        }

        Method [ &lt;internal:db4&gt; public method set_data_dir ] {
        }

        Method [ &lt;internal:db4&gt; public method set_encrypt ] {
        }

        Method [ &lt;internal:db4&gt; public method txn_begin ] {
        }

        Method [ &lt;internal:db4&gt; public method txn_checkpoint ] {
        }
      }
    }
  }
}&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4,&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4,&gt;&lt;/internal:db4&gt;&lt;/required&gt;&lt;/required&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/required&gt;&lt;/required&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4,&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/internal:db4&gt;&lt;/persistent&gt;
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;The extension bundles some examples to get you started with Berkeley DB.&lt;/p&gt; 
&lt;p&gt;Even though I&#039;d prefer a &lt;a href=&quot;http://www.mysql.com&quot;&gt;relational client-server database&lt;/a&gt; for most use cases I can image situations where a simple embedded solutions has its benefits, especially if combined with other Oracle Berkeley DB based applications.&lt;br /&gt;&lt;/p&gt; 
&lt;blockquote&gt; &lt;/blockquote&gt; 
    </content:encoded>

    <pubDate>Thu, 03 Jun 2010 15:54:00 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/134-guid.html</guid>
    <category>berkeley db</category>
<category>coding</category>
<category>database</category>
<category>db</category>
<category>oracle</category>
<category>php</category>
<category>php extensions</category>
<category>sqlite</category>
<category>sqlite3</category>

</item>
<item>
    <title>Now in trunk: Improved interactive shell</title>
    <link>http://schlueters.de/blog/archives/133-Now-in-trunk-Improved-interactive-shell.html</link>
            <category>PHP</category>
    
    <comments>http://schlueters.de/blog/archives/133-Now-in-trunk-Improved-interactive-shell.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=133</wfw:comment>

    <slash:comments>7</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=133</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;A few years ago I used another blog to write about &amp;quot;&lt;a href=&quot;http://blog.mayflower.de/archives/44-More-PHP-power-on-the-command-line.html&quot;&gt;More PHP power on the command line&lt;/a&gt;&amp;quot; almost 5 years later the PHP interactive shell got a major update which went in PHP&#039;s trunk. The &lt;a href=&quot;http://news.php.net/php.cvs/62675&quot;&gt;commit message&lt;/a&gt; tells a lot about the improvements:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;- Improved CLI Interactive readline shell (Johannes)
  . Added cli.pager ini setting to set a pager for output.
  . Added cli.prompt ini settingto configure the shell prompt.
  . Added shortcut #inisetting=value to change ini settings at run-time.
  . Don&#039;t terminate shell on fatal errors.

A pager can be a an shell command which will receive the command output on its
STDIN channel

php &amp;gt; #cli.pager=less
php &amp;gt; phpinfo();
(output will appear in the pager)
php &amp;gt; #cli.pager=grep -i readline
php &amp;gt; phpcredits();
Readline =&amp;gt; Thies C. Arntzen
php &amp;gt; #cli.pager=
(output appears again direct on the terminal)

A prompt can contain a few escape sequences like

php &amp;gt; #cli.prompt=\e[032m\v \e[031m\b \e[34m\&amp;gt; \e[0m
5.3.99-dev php &amp;gt; //Colorful prompt with version number

A prompt can also contaian PHP code in backticks

php &amp;gt; #cli.prompt=`echo gethostname();` \b \&amp;gt;
guybrush php &amp;gt;
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;But I assume a screenshot is quite useful, so here it goes:&lt;/p&gt; 
&lt;p&gt;&lt;!-- s9ymdb:52 --&gt;&lt;img width=&quot;667&quot; height=&quot;221&quot; src=&quot;http://schlueters.de/blog/uploads/screenshots/Screenshot-johannesguybrush-src-php-build-6.0-debug-notsrm-gcc.png&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;
So what doyou need to use this feature? - &lt;a href=&quot;http://schlueters.de/blog/archives/128-Future-of-PHP-6.html&quot;&gt;PHP trunk&lt;/a&gt; compiled using &lt;em&gt;--with-readline&lt;/em&gt; or &lt;em&gt;--with-libedit&lt;/em&gt;.The PHP Documentation &lt;a href=&quot;http://php.net/manual/en/features.commandline.interactive.php&quot;&gt;has information&lt;/a&gt; about the interactive mode, the new features will be added once trunk is closer to a release and it&#039;s clear in what release this will appear.&lt;br /&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 28 May 2010 20:55:00 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/133-guid.html</guid>
    <category>command line</category>
<category>php interactive</category>
<category>php shell</category>
<category>php.next</category>

</item>
<item>
    <title>ZFS</title>
    <link>http://schlueters.de/blog/archives/130-ZFS.html</link>
            <category>Software</category>
    
    <comments>http://schlueters.de/blog/archives/130-ZFS.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=130</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=130</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;So, I use OpenSolaris on most of my boxes as native operating system. VMs run other OSs. My choice for OpenSolaris was driven by the availability of DTrace. One of the greatest tools for system/program analysis ever created. By running OpenSolaris I&#039;ve also got ZFS which is Oracle&#039;s über file system. I never really cared about ZFS, at least not until I missed it. So ZFS integrates all the different storage layers in one system - RAID-controller, logical volume manager, POSIX file system layer, ... Really nice to have that integrated, eases management. Now I don&#039;t change my disks that often and the file system silently runs underneath. From time to time I looked into my auto snapshot to restore some stuff and got used to snapshot my VMs (running on ZFS-powered &amp;quot;virtual&amp;quot; zvol devices) before updating them which over time became a habit about which I didn&#039;t really think.&lt;/p&gt; 
&lt;p&gt;Then I&#039;ve got myself a netbook. Some cheap up to date ASUS EeePC. On that system I choose to install Ubuntu - which was troublesome enough (had to compile my owned manually patched wireless driver) so I didn&#039;t bother to try OpenSolaris. Works like a charm, even without ZFS. Some time after I configured the netbook a new Ubuntu release came out and since then I&#039;m in trouble. I read on too many sites that things broke with this release so I dare to update the system. On my OpenSolaris boxes updating to a update, even to a dev build, is a no-brainer: The packaging system automatically creates a ZFS snapshot and configures the boot loader in a way that the old as well as the new system can be booted. So I can click the update button, reboot and either it works (typical case) or I can revert. Really nice.&lt;/p&gt; 
&lt;p&gt;Now back to Ubuntu: If I press the button and something goes wrong I have to reinstall the system (or use a backup) which I don&#039;t want. I just want to use the netbook as a mobile browser, presentation system etc. There are other systems I use to play/experiment with... &lt;/p&gt; 
&lt;p&gt;At the recent PHP Barcamp Salzburg we got to a discussion about ZFS, too. In the discussion there was talk about the auto snapshotting and a claim was &amp;quot;well, I won&#039;t need it, I have everything in a version control software and I know what I delete&amp;quot; that might be true but once you have ZFS you change your way to operate and you don&#039;t have the whole system in a version control thing. It&#039;s so great to be able to clone a VM in less than a second to play with some stuff. It is cool to be able to enable compression with one short shell command. It&#039;s fantastic to have a fully checksummed filesystem with RAID-Z. Man how did we live in the old days? Nice to e aware of the luxury I&#039;m used to &lt;img src=&quot;http://schlueters.de/blog/templates/schluetersde/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;P.S. This blog is running on ZFS, too - of course, gave a good feeling to be able to revert during today&#039;s update, too.&lt;br /&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Mon, 10 May 2010 20:10:00 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/130-guid.html</guid>
    <category>dtrace</category>
<category>netbook</category>
<category>opensolaris</category>
<category>phpbcat</category>
<category>ubuntu</category>
<category>zfs</category>

</item>
<item>
    <title>Mind the encodings!</title>
    <link>http://schlueters.de/blog/archives/129-Mind-the-encodings!.html</link>
            <category>PHP</category>
    
    <comments>http://schlueters.de/blog/archives/129-Mind-the-encodings!.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=129</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=129</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;Dealing with character sets and encodings is tough. As long as you&#039;re dealing only with English texts you in a luxury situation and can mix utf-8 and iso-8859-1 encoded texts and most (all?) of your tests will work. Some of your users, like me, with strange names (&amp;quot;Schlüter&amp;quot;) will be annoyed as your application breaks them (&amp;quot;SchlÃ¼ter&amp;quot;), but these will be edge cases. There are bigger issues with mixing encodings but that&#039;s not what I wanted to tell now.&lt;/p&gt;
&lt;p&gt;Handling these encodings in PHP correctly is tough. PHP, currently, has a quite simple approach to the problem in general: PHP doesn&#039;t care about encodings. A string is simply a sequence of bytes. Well in general. The details are difficult. Core features like JSON-handling or XML processing expect that your PHP strings are encoded using utf-8, which is a sane choice, for JSON it is part of the JSON specification, for XML it&#039;s the only way to be able to work with all documents without additional information from you along every XML operation.&lt;/p&gt;
&lt;p&gt; On the other side we have browsers. A browser has to read documents from all over the world which can be encoded in any encoding you like. For whatever reason browser developers decided that iso-8859-1 would make a great default encoding, which means that if a response to a browser&#039;s request doesn&#039;t specify anything else the browser assumes the document is encoded using iso-8859-1. The document&#039;s encoding will also be used when sending form data back to the server. To handle this, PHP has a php.ini setting default_charset which, if set, will set the selected encoding in the HTTP header. The default value of this is setting is empty - so browsers fall back on their default, iso-8859-1.&lt;/p&gt;
&lt;p&gt;Recently Rasmus made a &lt;a href=&quot;http://news.php.net/php.cvs/62101&quot;&gt;commit&lt;/a&gt; to PHP trunk which changes the default to utf-8.&lt;/p&gt;
&lt;p&gt;In the long-run this changes is good as it works for all languages, iso-8859-1 only works for a limited set of European languages, and works better with the outside environment, where utf-8 adoption is growing (JSON and XML were examples).&lt;/p&gt;
&lt;p&gt;In the short-term this might cause trouble for applications depending on the default.The good thing is that the development in trunk has just started and the release of PHP.next is &lt;a href=&quot;http://schlueters.de/blog/archives/128-Future-of-PHP-6.html&quot;&gt;still sometime away&lt;/a&gt; and you can easily prepare your application - which is a good thing anyways to protect from administrators making mistakes with current versions already.&lt;/p&gt;
&lt;p&gt;To set the encoding from within your application you can for example call &lt;em&gt;ini_set(&#039;default_charset&#039;, $enc);&lt;/em&gt; or &lt;em&gt;header(&amp;quot;Content-type: text/html; charset=$enc&amp;quot;);&lt;/em&gt; at the beginning of your script, where &lt;em&gt;$enc&lt;/em&gt; is your preferred encoding. Please mind that this has no effect on the script itself, which, for instance, means you have to configure your database connection accordingly, too!&lt;/p&gt;&lt;br /&gt; 
    </content:encoded>

    <pubDate>Sun, 28 Mar 2010 03:31:00 +0200</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/129-guid.html</guid>
    <category>charsets</category>
<category>commits</category>
<category>encoding</category>
<category>php</category>
<category>php.next</category>

</item>
<item>
    <title>Future of PHP 6</title>
    <link>http://schlueters.de/blog/archives/128-Future-of-PHP-6.html</link>
            <category>PHP</category>
    
    <comments>http://schlueters.de/blog/archives/128-Future-of-PHP-6.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=128</wfw:comment>

    <slash:comments>8</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=128</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    &lt;p&gt;Yesterday was a quite thrilling day for the PHP development team and led to some imprecise news articles so let&#039;s take a look at what happened: Over the last months many of the core contributors agreed that the current approach to bring Unicode into PHP&#039;s engine wasn&#039;t the right approach and a good thing would be to rethink it from the start. By a provocative move of one contributor the stalled situation got some more movement and &lt;a href=&quot;http://news.php.net/php.internals/47120&quot;&gt;Rasmus declared&lt;/a&gt; the current implementation to be discontinued to restart.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;The past&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;When the foundation of what should have become PHP 6 was created a decision was made to use UTF-16 as internal encoding for &amp;quot;everything&amp;quot; inside the engine. The choice for UTF-16 was made due to the fact that PHP 6 would use the ICU library which is focused on offering UTF-16 string functions. By using UTF-16 as default encoding we&#039;d have to convert the script code and all data passed from or to the script (request data, database results, output, ...) from another encoding, usually UTF-8, to UTF-16 or back. The need for conversion doesn&#039;t only require CPU time and more memory (a UTF-16 string takes double memory of a UTF-8 string in many cases) but makes the implementation rather complex as we always have to figure out which encoding was the right one for a given situation. From the userspace point of view the implementation brought some backwards compatibility breaks which would require manual review of the code. These all are pains for a very small gain for many users where many would be happy about a tighter integration of some mbstring-like functionality. This all led to a situation for many contributors not willing to use &amp;quot;trunk&amp;quot; as their main development tree but either develop using the stable 5.2/5.3 trees or refuse to do development at all.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;The present&lt;/strong&gt;&lt;/p&gt;

Yesterday the stagnation created by the situation has been resolved and it was decided that our trunk in svn will be based on 5.3 and we&#039;ll merge features from the old trunk and new features there so that 5.3 will be a true stable branch. The EOL for 5.2 has not yet been defined but I suggest you to really migrate over to 5.3, which &lt;a href=&quot;http://php.net/migration53&quot;&gt;usually can be done with very little work&lt;/a&gt;, as soon as possible.


&lt;p&gt;&lt;strong&gt;The future&lt;/strong&gt;&lt;/p&gt;

Right now we&#039;re starting different discussions to see what kind of Unicode support we really want. Many contributors react positive on a proposed &amp;quot;string class&amp;quot; which wraps string operations in Unicode and binary forms without going deep in the engine. In my opinion such an approach might also be a way to solve some of the often criticized inconsistencies in PHP&#039;s string APIs without the need to break old code. (new code uses the new class, old code the old functions) But that idea is far from a proper proposal or even the implementation, current status is about refocusing the development and get the requirement and design discussions going. By that it&#039;s a bit early to decide whether the next version of PHP will be called PHP 5.4, PHP 6 or maybe even PHP 7.


&lt;p&gt;&lt;strong&gt;PHP is alive and kicking!&lt;/strong&gt;&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 12 Mar 2010 13:15:23 +0100</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/128-guid.html</guid>
    <category>development</category>
<category>opensource</category>
<category>php</category>
<category>php 5</category>
<category>php 5.4</category>
<category>php 6</category>
<category>php releases</category>
<category>php.next</category>
<category>php53</category>
<category>processes</category>
<category>unicode</category>

</item>
<item>
    <title>Ob ich es je verstehen werde?</title>
    <link>http://schlueters.de/blog/archives/127-Ob-ich-es-je-verstehen-werde.html</link>
            <category>Gesellschaft</category>
    
    <comments>http://schlueters.de/blog/archives/127-Ob-ich-es-je-verstehen-werde.html#comments</comments>
    <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=127</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://schlueters.de/blog/rss.php?version=2.0&amp;type=comments&amp;cid=127</wfw:commentRss>
    

    <author>nospam@example.com (Johannes Schlüter)</author>
    <content:encoded>
    
&lt;p&gt;Heute feiert &lt;i title=&quot;Als ob es da nur eine einelne zentrale Community gÃ¤be....&quot;&gt;die&lt;/i&gt; deutsche &lt;i&gt;Internet-Community&lt;/i&gt; und ja das Urteil des BVerG ist zu begrÃ¼ÃŸen. Aber noch immer frage ich mich warum man einem Privatunternehmen deutlich mehr Daten freiwillig gibt.&lt;/p&gt;

&lt;p&gt;Ich schrieb es ja &lt;a href=&quot;http://schlueters.de/blog/archives/126-Dinge,-die-ich-nicht-verstehe-....html&quot;&gt;zuvor&lt;/a&gt; schon: Ich verstehe nicht wie Leute all Ihre Daten einem Unternehmen kÃ¶nnen und zugleich dagegen sind wenn der Staat ein &lt;b&gt;Bruchteil&lt;/b&gt; der Daten per Gesetz bekommt. Ich weiÃŸ nicht ob Google heute selber irgendwas bÃ¶ses mit den Daten macht, nach allem was man so hÃ¶rt wohl nicht, aber zum einen haben staatliche Stellen schon heute Zugang zu den Daten bei Google zum anderen weiÃŸ man nicht was Google macht, wenn das WerbegeschÃ¤ft mal was schlechter lÃ¤uft, inzwischen haben die nen groÃŸen Stapel Mitarbeiter zu fÃ¼ttern und AktionÃ¤re zufrieden zustellen.&lt;/p&gt;

&lt;p&gt;Ja, Google gibt Daten an BehÃ¶rden raus. In den USA ist das im Rahmen des &lt;a href=&quot;http://de.wikipedia.org/wiki/USA_Patriot_Act&quot;&gt;USA PATRIOT Act&lt;/a&gt;  von 2001 geregelt und Eric Schmidt, CEO von Google, hat das ja unlÃ¤ngst in einem &lt;a href=&quot;http://www.youtube.com/watch?v=A6e7wfDHzew&quot;&gt;Interview betont&lt;/a&gt;. In Deutschland haben wir zum GlÃ¼ck (noch?) kein vergleichbares Gesetz, dass Geheimdiensten und PolizeibehÃ¶rden derart umfangreiche Rechte einrÃ¤umt, wie dies im Patriot Act der Fall ist aber auch hier gibt  es MÃ¶glichkeiten, die zur Beschlagnahme von Daten von Google fÃ¼hren kÃ¶nnen .. oder auch sowas wie Geheimdienstliche Zusammenarbeit, die einen Zugriff deutscher BehÃ¶rden nicht unmÃ¶glich machen (obei dann die Frage ist ob die CIA oder das BKA schlimmer ist &lt;img src=&quot;http://schlueters.de/blog/templates/schluetersde/img/emoticons/wink.png&quot; alt=&quot;;-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;)&lt;/p&gt;

&lt;p&gt;Aber nur um nochmal zu erinnern was fÃ¼r Daten Google hat, dass sind ja nicht nur die Suchanfragen, die man mal so stellt sondern auch die Information welche Websites man so aufruft (Danke Google Ads und Google Analytics Ã¼berall) das sind Mails die man so schreibt (und sei es nur weil der EmpfÃ¤nger GMail nutzt) das sind Informationen mit wem man wann so telefoniert (Android des angerufenen is ja an GMail&amp;amp;Co. angebunden) In den USA sind das auch Inhalte von Mailboxnachrichten (die per Spracherkennung als Mail verschickt werden). Dank Picassa und Photoerkennung kennen die auch das Gesicht und Aufenthaltsorte (das is eigentlich der spannende Teil bei der Streetview-Diskussion - Google hat die unzensierten Bilder und automatische Gesichtserkennung ...) und noch viel mehr an Daten. Das kombiniert mit den Suchanfragen bei der Google Suche, der Produktsuche, Google Maps, .... gibt ein extrem detailliertes PersÃ¶nlichkeitsbild. Nein. Ich verstehe nicht warum man sowas in einer einzigen Datenbank, die man nicht kontrolliert, haben wollen kÃ¶nnte. &lt;/p&gt; 
    </content:encoded>

    <pubDate>Tue, 02 Mar 2010 14:03:00 +0100</pubDate>
    <guid isPermaLink="false">http://schlueters.de/blog/archives/127-guid.html</guid>
    <category>bundesverfassungsgericht</category>
<category>daten frei</category>
<category>datenschutz</category>
<category>gmail</category>
<category>google</category>
<category>patriot act</category>
<category>privacy</category>
<category>recht und ordnung</category>
<category>urteilvorratsdatenspeicherung</category>

</item>

</channel>
</rss>