<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="/blog/templates/schluetersde/atom.css" type="text/css" ?>

<feed 
   xmlns="http://www.w3.org/2005/Atom"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/">
    <link href="http://schlueters.de/blog/feeds/atom10.xml" rel="self" title="Johannes Schlüter" type="application/atom+xml" />
    <link href="http://schlueters.de/blog/"                        rel="alternate"    title="Johannes Schlüter" type="text/html" />
    <link href="http://schlueters.de/blog/rss.php?version=2.0"     rel="alternate"    title="Johannes Schlüter" type="application/rss+xml" />
    <title type="html">Johannes Schlüter</title>
    <subtitle type="html">Always searching for Life, the Universe and Everything</subtitle>
    <icon>http://schlueters.de/blog/templates/schluetersde/img/s9y_banner_small.png</icon>
    <id>http://schlueters.de/blog/</id>
    <updated>2010-09-02T11:00:45Z</updated>
    <generator uri="http://www.s9y.org/" version="1.5.3">Serendipity 1.5.3 - http://www.s9y.org/</generator>
    <dc:language>en</dc:language>

    <entry>
        <link href="http://schlueters.de/blog/archives/137-ZFS-and-VirtualBox.html" rel="alternate" title="ZFS and VirtualBox" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-07-25T13:34:05Z</published>
        <updated>2010-09-02T11:00:45Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=137</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/2-Software" label="Software" term="Software" />
    
        <id>http://schlueters.de/blog/archives/137-guid.html</id>
        <title type="html">ZFS and VirtualBox</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>With ZFS you may not only do &quot;file system&quot; stuff but ZFS may also provide raw block devices (&quot;zvol&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'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.</p> 
<p>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'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.</p> 
<p>Anyways here are the steps needed:</p> 
<blockquote> 
<pre># 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
</pre> 
</blockquote> 
<p>So first we create the zvol with a size of 10G. This won'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'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.</p> 
<p>Works nicely.<br /></p> 
            </div>
        </content>
        <dc:subject>oracle</dc:subject>
<dc:subject>storage</dc:subject>
<dc:subject>virtualbox</dc:subject>
<dc:subject>virtualization</dc:subject>
<dc:subject>vmdk</dc:subject>
<dc:subject>zfs</dc:subject>
<dc:subject>zvol</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/144-iSCSI-devices-in-VirtualBox.html" rel="alternate" title="iSCSI devices in VirtualBox" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-09-02T10:40:18Z</published>
        <updated>2010-09-02T10:58:17Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=144</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/2-Software" label="Software" term="Software" />
    
        <id>http://schlueters.de/blog/archives/144-guid.html</id>
        <title type="html">iSCSI devices in VirtualBox</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>While playing with my disc-less environment, booting via <a href="http://etherboot.org/">gPXE</a> from an <a href="http://en.wikipedia.org/wiki/iSCSI">iSCSI</a> device, I found out that <a href="http://www.virtualbox.org">VirtualBox</a> has direct support for iSCSI while this isn't shown in the GUI. To register an iSCSI device as virtual disc one has to use <em>VBoxManage</em> on the command line:</p> 
<blockquote> 
<pre>$ VBoxManage addiscsidisk \
       --server iscsi.home.schlueters.de \
       --target iqn.1986-03.com.sun:02:f4635770-f010-61be-e8f7-83403206bec5
</pre> 
</blockquote> 
<p>The result can be checked:</p> 
<blockquote> 
<pre>$ 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) 
</pre> 
</blockquote> 
<p>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.<br /></p> 
<blockquote> </blockquote> 
            </div>
        </content>
        <dc:subject>discless</dc:subject>
<dc:subject>etherboot</dc:subject>
<dc:subject>gpxe</dc:subject>
<dc:subject>iscsi</dc:subject>
<dc:subject>storage</dc:subject>
<dc:subject>virtualbox</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/142-HashTables.html" rel="alternate" title="HashTables" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-08-22T21:52:00Z</published>
        <updated>2010-08-23T22:48:59Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=142</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/3-PHP" label="PHP" term="PHP" />
    
        <id>http://schlueters.de/blog/archives/142-guid.html</id>
        <title type="html">HashTables</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>In case you ever heard me talking about PHP internals I certainly mentioned something along the lines of &quot;Everything in PHP is a HashTable&quot; that's not true, but next to a zval the HashTable is one of the most important structures in PHP. While preparing my &quot;<a href="http://phpconference.nl/schedule/talks#phphood">PHP Under The Hood</a>&quot; talk for the Dutch PHP Conference there was a question on IRC about <a href="http://php.net/extension_loaded">extension_loaded</a>() being faster than <a href="http://php.net/function_exists">function_exists</a>(), 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't have the time to go through it during that presentation, so I'm doing this now, here:</p> 
<p>You all should know <a href="http://php.net/array">PHP arrays</a>. 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 &quot;real&quot; array, an array of elements indexed by a sequence of numbers, starting at 0, up to <em>n</em>. 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 <em>start_address + (n * size_of_element)</em>. That's basically what C arrays are.</p> 
<p>Now we'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 <a href="http://php.net/md5">MD5</a>, 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 &quot;<a href="http://lxr.php.net/xref/PHP_5_3/Zend/zend_hash.h#228">DJBX33A (Daniel J. Bernstein, Times 33 with Addition)</a>&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.</p> 
<p>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's look at an example: The hash value of &quot;foobar&quot; equals, in decimal digits, to 3127933054. We assume a table mask of 2047 (2¹¹-1).<br /><br /></p> 
<blockquote> 
<pre>  3127933054    101110100111000001111<strong>00001111110</strong>
<u>&amp;       2047    </u><u><u>000000000000000000000</u></u><u>11111111111</u>
=        126    000000000000000000000<strong>00001111110</strong>
</pre> 
</blockquote> 
<p>Wonderful - we have an array Index, 126, for this string and can set the value in memory!</p> 
<p>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</p> 
<ol> 
<li>Calculate the hash</li> 
<li>Apply the table mask</li> 
<li>locate the memory offset</li> 
<li>check whether this is the element we need, traverse the linked list.</li> 
</ol> 
<p>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.</p> 
<p>Full results are <a href="/~johannes/php/collisions.txt">online</a> 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'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'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.<br /></p> 
            </div>
        </content>
        <dc:subject>computer science 101</dc:subject>
<dc:subject>hashtable</dc:subject>
<dc:subject>php</dc:subject>
<dc:subject>php internals</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html" rel="alternate" title="Do not use PHP references" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-01-10T14:19:00Z</published>
        <updated>2010-08-22T21:38:15Z</updated>
        <wfw:comment>http://schlueters.de/blog/wfwcomment.php?cid=125</wfw:comment>
    
        <slash:comments>19</slash:comments>
        <wfw:commentRss>http://schlueters.de/blog/rss.php?version=atom1.0&amp;type=comments&amp;cid=125</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/3-PHP" label="PHP" term="PHP" />
    
        <id>http://schlueters.de/blog/archives/125-guid.html</id>
        <title type="html">Do not use PHP references</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Last year I spoke at eight conferences and attended a few more multiple times at most of them I found myself in discussions about references and PHP as many users seem to have wrong understandings about them. Before going to deep into the subject let's start with a quick reminder what references are and clear some confusion about objects which are &quot;passed by reference.&quot;</p> 
<p>References are a way to have multiple variables referencing the same variable container using different names -- so whatever name you're using an operation on that variable will always have an effect on the others.</p> 
<p>Let's look into it with some code to make this all clearer. For a start we simply do a regular assignment from one variable to the other and change it:</p> 
<blockquote> 
<pre>&lt;?php
$a = 23;
$b = $a;
$b = 42;
var_dump($a);
var_dump($b);
?&gt;
</pre> 
</blockquote> 
<p>This script will tell us that <em>$a</em> still is <em>23</em> and <em>$b</em> equals <em>42</em>. So what happened here is that we got a copy (more on what actually happened later...) now let's do the same with a reference:</p> 
<blockquote> 
<pre>&lt;?php
$a = 23;
$b = &amp;$a;
$b = 42;
var_dump($a);
var_dump($b);
?&gt;
</pre> 
</blockquote> 
<p>Now suddenly <em>$a</em> changes to <em>42</em>, too. In fact there is no difference between <em>$a</em> and <em>$b</em> and both are using the same internal variable container (aka. <em>zval</em>). The only way to separate these two is by invalidating one of the variables using <em>unset()</em>.</p> 
<p>References in PHP can't only be created in regular assignments but also for function parameters or return values:</p> 
<blockquote> 
<pre>&lt;?php
function &amp;foo(&amp;$param) {
    $param = 42;
    return $param;
}

$a = 23;
echo "\$a before calling foo(): $a\n";
$b = foo($a);
echo "\$a after the call to foo(): $a\n";
$b = 23;
echo "\$a after touching the returned variable: $a\n";
?&gt;
</pre> 
</blockquote> 
<p>The result from this is, well what do you expect? Right - it looks like this:</p> 
<blockquote> 
<pre>$a before calling foo(): 23
$a after the call to foo(): 42
$a after touching the returned variable: 42
</pre> 
</blockquote> 
<p>So we initialize a variable, pass it to a function as referenced parameter. The function changes it and it has the new value. The function returns the same variable, we change the returned variable and the original value ... wait it didn't change!? - Yes references are mean. What happened is the following: The function returned a reference, referencing the same <em>zval</em> as <em>$a</em> and the <em>=</em> assignment operator creates a copy of it.</p> 
<p>To fix this we have to add one <em>&amp;</em> more:</p> 
<blockquote> 
<pre>$b = &amp;foo($a);
</pre> 
</blockquote> 
<p>Then the result is what one would expect:</p> 
<blockquote> 
<pre>$a before calling foo(): 23
$a after the call to foo(): 42
$a after touching the returned value: 23
</pre> 
</blockquote> 
<p>Summary so far: PHP references are alias to the same variable and properly using them can be hard. For details on the reference counting, which is the base for this, check the <a href="http://php.net/features.gc.refcounting-basics">according section in the manual</a>.</p> 
<p>When PHP 5 came to live one of the big changes was how objects were handled. The general explanation is something like this:</p> 
<blockquote>
  In PHP 4 objects are treated like other variables so when using them
  as function parameters or doing assignments they are copied. In PHP 5
  they are always passed by reference.
</blockquote> 
<p>Which isn't entirely correct. The issue to solve was about object oriented patterns: Objects are passed as parameters to some function or method, this function sends a signal to the object (aka calls a method) which then might change the object's state (aka. its properties). For this to work the object has to be the same. PHP 4 OO users now always passed explicit references, which is, as we saw above, tricky to do correctly. To make this nicer in PHP 5 an object storage which is independent from the variable container was introduced. So inside the variable we don't store the whole object anymore (which basically means the properties table plus class information) but a reference to an object inside an object storage - so if we create a copy of the variable we don't copy the object but this reference (or: handle) so it feels like an reference, but be aware it is no reference but a different concept. The difference can be seen by directly changing the variable:</p> 
<blockquote> 
<pre>&lt;?php
// create an object and a copy as well as a reference to the variable
$a = new stdclass;
$b = $a;
$c = &amp;$a;

// Do something with the object
$a-&gt;foo = 42;
var_dump($a-&gt;foo);
var_dump($b-&gt;foo);
var_dump($c-&gt;foo);

// Now change the variable itself
$a = 42;
var_dump($a);
var_dump($b);
var_dump($c);
?&gt;
</pre> 
</blockquote> 
<p>When running this you can see that the access to the property really affects the <em>copy</em>, too but in the last assignment you can see the difference to an reference as <em>$b</em> is not affected by it. This is the behavior most (all?) people with OO experience expect.</p> 
<p>So OO was one valid reason for using references, but as PHP 4 is dead for over one year now old code using this should really cleaned up!</p> 
<p>Another reason people use reference is since they think it makes the code faster. But this is wrong. It is even worse: References mostly make the code slower!</p> 
<p>Yes, references often make the code slower - Sorry, I just had to repeat this to make it clear.</p> 
<p>When coming from other languages from other languages people read in style guides that passing copies of large structures or strings should be avoided as creating a copy takes time. In some environments complex structures have to be passed as pointers, which is a fundamentally different model from references, and people take this to PHP references. But PHP is not that other language but PHP with PHP's runtime and in PHP we do copy-on-write.</p> 
<p>With copy-on-write we don't copy on an assignment or function call but just note that there are multiple independent variables pointing at one and the same variable container and only if there is a write operation we separate the variable, which is written to, from the others. This means that even so a variable looks like a copy it's in fact no copy and the function call takes no penalty do to big parameters. The problem with references now is that they disable the copy-on-write mechanism so any following non-reference assignment using this variable will create an immediate copy. This in itself won't be bad - you could simply use references everywhere, well not really: PHP is built around the copy-on-write availability so most internal functions expect copies.</p> 
<p>Somewhere I found code which something looks like this:</p> 
<blockquote> 
<pre>&lt;?php
function foo(&amp;$data) {
    for ($i = 0; $i &lt; strlen($data); $i++) {
        do_something($data{$i});
    }
}

$string = "... looooong string with lots of data .....";
foo(string);
?&gt;
</pre> 
</blockquote> 
<p>Now the first issue with this code is obvious: It is calling <em>strlen()</em> in a loop for each iteration while the length is calculated. So that's <em>strlen($data)</em> function calls while a single one would be enough. Now with <em>strlen()</em> it won't be too bad as, unlike in a language like C, strings in PHP directly carry the length so no calculation is needed, in general. But now in this case the developer tried to be smart and save time by passing a reference. But well, <em>strlen()</em> expects a copy. copy-on-write can't be done on references so <em>$data</em> will be copied for calling <em>strlen()</em>, <em>strlen()</em> will do an absolutely simple operation - in fact <em>strlen()</em> is one of the most trivial functions in PHP - and the copy will be destroyed immediately.</p> 
<p>If no reference is being used no copy is needed which makes the code way faster and even if <em>strlen()</em> would take the reference you wouldn't have won anything.</p> 
<p>Summary so far: </p> 
<ul> 
<li>Do not use references for OO but get ridof PHP 4 legacy.</li> 
<li>Do not use references for performance.</li> 
</ul> 
<p>Now a third thing which is done with references is bad API design by returning via reference parameters. The issue here is, again, that people forget that PHP is PHP and not another language.</p> 
<p>In PHP you can return multiple types from the same function - so if the function was successful you could return a string and a boolean <em>false</em> in case of an error. PHP also allows to return complex structures like arrays and objects, so if multiple things are to be returned they can be packed together. Additionally there are exceptions as a way to return from a function.</p> 
<p>Using referenced parameters is a bad thing, additionally to the fact that references are bad and cause performance penalties using references in this way makes code hard to maintain. Having such a function call:</p> 
<blockquote> 
<pre>  do_something($var);
</pre> 
</blockquote> 
<p>Would you expect that $var will change? - No. But if <em>do_something()</em> takes it as a reference it could happen.</p> 
<p>Another problem with such APIs is that function calls can't be nested but you always have to use a temporary variable, now nesting function calls can also reduce readability, but there are enough situations where nesting makes the code clearer.</p> 
<p>My personal favorite example for a bad design decision in regards to references is PHP's own <em>sort()</em> function. <em>sort()</em> takes an array as reference parameter which will be returned in sorted order by reference. It would be way nicer to return the sorted array as regular return value. The reason for this is history: <em>sort()</em> is older than copy-on-write. Copy-on write was introduced with PHP 4, while sort() is way older and from times before PHP really was its own language but a shortcut to do some things in the Web.</p> 
<p>To sum it up: References in PHP are bad. Do not use them. They hurt and will just mess with things and do not expect to be able to outsmart the engine with references!</p> 
            </div>
        </content>
        <dc:subject>api design</dc:subject>
<dc:subject>best practice</dc:subject>
<dc:subject>guidlines</dc:subject>
<dc:subject>oop</dc:subject>
<dc:subject>performance</dc:subject>
<dc:subject>php</dc:subject>
<dc:subject>php 4</dc:subject>
<dc:subject>php coding</dc:subject>
<dc:subject>php oo</dc:subject>
<dc:subject>php references</dc:subject>
<dc:subject>planet php</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/141-References-and-foreach.html" rel="alternate" title="References and foreach" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-08-20T11:21:05Z</published>
        <updated>2010-08-22T12:13:44Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=141</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/3-PHP" label="PHP" term="PHP" />
    
        <id>http://schlueters.de/blog/archives/141-guid.html</id>
        <title type="html">References and foreach</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>References in PHP are bad, <a href="http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html">as I mentioned before</a>, and you certainly should avoid using them. Now there is one use case which leads to an, at first, unexpected behavior which I didn'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:</p> 
<p>What is the output of this code:</p> 
<blockquote> 
<pre>&lt;?php
$a = array('a', 'b', 'c', 'd');

foreach ($a as &amp;$v) { }
foreach ($a as $v) { }

print_r($a);
?&gt;
</pre> 
</blockquote> 
<p>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:</p> 
<blockquote> 
<pre>Array
(
    [0] =&gt; a
    [1] =&gt; b
    [2] =&gt; c
    [3] =&gt; c
)
</pre> 
</blockquote> 
<p>For understanding why this happens let's take a step back and look at the way PHP variables are implemented and what references are:</p> 
<p>A PHP variable basically consists out of two things: A &quot;label&quot; and a &quot;container.&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's property table. So we have a name and a pointer to the container. The container, internally called &quot;zval&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.</p> 
<p>Now let's look at the situation from above. In&#160; a picture it looks like this:</p> 
<p><!-- s9ymdb:53 --><img width="816" height="490" src="http://schlueters.de/blog/uploads/code/references_foreach/refe1.png" /></p> 
<p>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.</p> 
<p> <!-- s9ymdb:54 --><img width="816" height="490" class="serendipity_image_center" src="http://schlueters.de/blog/uploads/code/references_foreach/refe2.png" /></p> 
<p>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.</p> 
<p> <!-- s9ymdb:55 --><img width="816" height="490" class="serendipity_image_center" src="http://schlueters.de/blog/uploads/code/references_foreach/refe3.png" /></p> 
<p>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:</p> 
<p><!-- s9ymdb:56 --><img width="816" height="490" class="serendipity_image_center" src="http://schlueters.de/blog/uploads/code/references_foreach/refe4.png" /></p> 
<p>This continues for he next steps, too.</p> 
<p><!-- s9ymdb:57 --><img width="816" height="490" src="http://schlueters.de/blog/uploads/code/references_foreach/refe5.png" class="serendipity_image_center" /><!-- s9ymdb:58 --><img width="816" height="490" src="http://schlueters.de/blog/uploads/code/references_foreach/refe6.png" class="serendipity_image_center" /></p> 
<p>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.</p> 
<p><!-- s9ymdb:59 --><img width="816" height="490" src="http://schlueters.de/blog/uploads/code/references_foreach/refe7.png" class="serendipity_image_center" /></p> 
<p>And this is the result we saw above.</p> 
<p>So to make this story full of pictures short: Be careful about references! They can have really strange effects.</p> 
            </div>
        </content>
        <dc:subject>coding</dc:subject>
<dc:subject>php</dc:subject>
<dc:subject>php internals</dc:subject>
<dc:subject>php references</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/140-MySQL-at-FrOSCon.html" rel="alternate" title="MySQL at FrOSCon" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-08-18T22:19:39Z</published>
        <updated>2010-08-19T07:24:14Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=140</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/3-PHP" label="PHP" term="PHP" />
    
        <id>http://schlueters.de/blog/archives/140-guid.html</id>
        <title type="html">MySQL at FrOSCon</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Oh time is flying! - This weekend it is already time for <a href="http://www.froscon.de">FrOSCon</a>, the Free and Open source Conference in St. Augustin close to Western Germany'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.<br /></p> 
<p>In the <a href="http://programm.froscon.org/2010/track/PHP(C118)/index.en.html">PHP developer room</a> 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 -&#160; in detail.</p> 
<p>In the <a href="http://programm.froscon.org/2010/track/OpenSQLCamp/index.en.html">OpenSQL Camp</a> 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 <a href="http://programm.froscon.org/2010/index.en.html">other tracks</a>. And that all for an entrance fee of just 5€! So if you have a chance: Go there and say hi!<br /></p> 
            </div>
        </content>
        <dc:subject>conferences</dc:subject>
<dc:subject>froscon</dc:subject>
<dc:subject>froscon10</dc:subject>
<dc:subject>mysql</dc:subject>
<dc:subject>php</dc:subject>
<dc:subject>php conferences</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/139-Scalar-type-hints-in-PHP-trunk.html" rel="alternate" title="Scalar type hints in PHP trunk" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-08-07T21:00:00Z</published>
        <updated>2010-08-14T15:10:28Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=139</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/3-PHP" label="PHP" term="PHP" />
    
        <id>http://schlueters.de/blog/archives/139-guid.html</id>
        <title type="html">Scalar type hints in PHP trunk</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>So in my <a href="http://schlueters.de/blog/plugin/tag/php%FFnext">blog series</a> I try to cover all additions to PHP trunk so I have to mention scalar type hints.</p> 
<blockquote> 
<pre>&lt;?php
function print_float(<strong>float</strong> $f) {
    echo $f."\n";
}

for ($i = 1; $i &lt; 5; $i++) {
    print_float( $i / 3 );
}
?&gt;
	</pre>

	0.33333333333333<br />
	0.66666666666667<br /> <br /> <strong>Catchable fatal error:</strong> 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






</blockquote> 
<p>Is expected behavior in PHP's trunk. If you want such
a thing to work please use the <em>numeric</em> type hint.</p> 
<p>In case that wasn't enought fun: There's more!</p> 
<blockquote> 
<pre>&lt;?php
function handle_result(<strong>int</strong> $i) {
    echo $i."\n";
}

$pdo = new PDO("mysql:host=localhost;dbname=test", "user", "pass");
$pdo-&gt;setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, <strong>false</strong>);
$result = $pdo-&gt;query("SELECT 42 AS id");
$row = $result-&gt;fetch();
handle_result($row['id']);

$pdo = new PDO("mysql:host=localhost;dbname=test", "user", "pass");
$pdo-&gt;setAttribute(PDO::MYSQL_ATTR_DIRECT_QUERY, <strong>true</strong>);
$result = $pdo-&gt;query("SELECT 42 AS id");
$row = $result-&gt;fetch();
handle_result($row['id']);
?&gt;
	</pre>
	42<br /> <br /> <strong>Catchable fatal error:</strong> 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






</blockquote> 
<p>So what happens here? - Depending on the <a href="http://php.net/pdo_mysql#pdo-mysql.constants">PDO::MYSQL_ATTR_DIRECT_QUERY</a> option PDO will either
emulate prepared statements (which would be irrelevant here, but that's another story)
or use native prepared statements. When using prepared statements MySQL switches over to its
&quot;binary&quot; protocol which returns the native types, else it always returns strings. When using
PDO_mysql linked against <a href="http://php.net/mysqlnd">mysqlnd</a> 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't defined either. As PHP is a dynamically typed language this shouldn't matter, so
depending on your driver the results vary. Great. Oh and did I mention that the
types aren't specified, so a later version of a driver might change it. And PDO
is just a simple example for this ...</p> 
<p>The key point of this all is that as soon as you mix strong typing - by using
type hints - with PHP's weak type system you open a can of worms.</p> 
<p>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't pass an integer where a float is expected!),
makes little sense to me. But that's just me.</p> 
<p>As in my <a href="http://schlueters.de/blog/plugin/tag/php%FFnext">previous posts</a> in the series of blog posts about features in PHP trunk.
Please try the <a href="http://snaps.php.net">snapshots</a>. Mind that these features might (not) end up in the next release of PHP, <a href="http://bugs.php.net">feedback</a> is welcome.</p> 
            </div>
        </content>
        <dc:subject>pdo</dc:subject>
<dc:subject>php</dc:subject>
<dc:subject>php.next</dc:subject>
<dc:subject>type hints</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/138-Features-in-PHP-trunk-Array-dereferencing.html" rel="alternate" title="Features in PHP trunk: Array dereferencing" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-07-31T11:11:39Z</published>
        <updated>2010-08-03T23:12:35Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=138</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/3-PHP" label="PHP" term="PHP" />
    
        <id>http://schlueters.de/blog/archives/138-guid.html</id>
        <title type="html">Features in PHP trunk: Array dereferencing</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>I was writing about <a href="http://schlueters.de/blog/plugin/tag/php%FFnext">new features in the upcoming PHP version</a> (5.4, 6.0?) before. Today's topic reads like this in the <a href="http://svn.php.net/viewvc/php/php-src/trunk/NEWS?revision=HEAD&amp;view=markup">NEWS</a> file:</p> 
<blockquote> 
<p>- Added array dereferencing support. (Felipe)</p> 
</blockquote> 
<p>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 &quot;object dereferencing&quot; which looks like this:</p> 
<blockquote> 
<pre>&lt;?php
class Foo {
    public function bar() { }
}

function func() {
    return new Foo();
}

<strong>func()-&gt;bar();</strong>
?&gt;
</pre> 
</blockquote> 
<p>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't like memory leaks. But after proper evaluation Felipe committed the patch which allows you to do things like</p> 
<blockquote> 
<pre>&lt;?php
function foo() {
    return array(1, 2, 3);
}
echo <strong>foo()[2]</strong>; // prints 3
?&gt;
</pre> 
</blockquote> 
<p>Of course this also works with closures:</p> 
<blockquote> 
<pre>&lt;?php
$func = function() { return array('a', 'b', 'c'); };
echo <strong>$func()[0]</strong>; // prints a
?&gt;
</pre> 
</blockquote> 
<p>And even though the following example is stupid I might accept this feature as one of the few places where it is <a href="http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html">ok to use references in PHP</a>:</p> 
<blockquote> 
<pre>&lt;?php
$data = array('me', 'myself', 'you');
function <strong>&amp;</strong>get_data() {
    return $GLOBALS['data'];
}
<strong>get_data()[2] = 'I';</strong> // $data will now contain 'me', 'myself' and 'I'
?&gt;

</pre> 
</blockquote> 
<p>Wonderful, isn't it? If you want to test it please take a look at the recent <a href="http://snaps.php.net">snapshots for PHP trunk</a> and send us your feedback! Please mind that all features in PHP trunk may or may not appear in the next major PHP release.<br /></p> 
            </div>
        </content>
        <dc:subject>array</dc:subject>
<dc:subject>coding</dc:subject>
<dc:subject>oop</dc:subject>
<dc:subject>php</dc:subject>
<dc:subject>php qa</dc:subject>
<dc:subject>php.next</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/136-15-years-of-PHP.html" rel="alternate" title="15 years of PHP" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-06-07T22:00:00Z</published>
        <updated>2010-06-08T10:24:35Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=136</wfw:commentRss>
    
    
        <id>http://schlueters.de/blog/archives/136-guid.html</id>
        <title type="html">15 years of PHP</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Wow, 15 years ago, on June 8th 1995, <a href="http://groups.google.com/group/comp.infosystems.www.authoring.cgi/msg/cc7d43454d64d133?dmode=source&amp;hl=en">Rasmus announced PHP 1.0</a>. Time for a personal look back:</p> 
<p>I can'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.<br /></p> 
<p>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't work anymore for some reason.</p> 
<p>My brother, who setup our Linux box at home but didn'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 <a href="http://www.mayflower.de">Mayflower</a>, <a href="http://www.mysql.com">MySQL</a>, <a href="http://en.wikipedia.org/wiki/Sun_Microsystems">Sun Microsystems</a> and, most likely, soon <a href="http://www.oracle.com">Oracle</a>. And even though I'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't configure CGI.<br /></p> 
<p>15 years and still strong. Congratulations PHP!<br /></p> 
            </div>
        </content>
        <dc:subject>anniversary</dc:subject>
<dc:subject>birthday</dc:subject>
<dc:subject>coding</dc:subject>
<dc:subject>php</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/134-Berkeley-DB-5-and-PHP.html" rel="alternate" title="Berkeley DB 5 and PHP" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-06-03T13:54:00Z</published>
        <updated>2010-06-05T13:44:38Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=134</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/3-PHP" label="PHP" term="PHP" />
    
        <id>http://schlueters.de/blog/archives/134-guid.html</id>
        <title type="html">Berkeley DB 5 and PHP</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Everybody working on Unix or in the database world stumbles over <a href="http://www.oracle.com/database/berkeley-db/db/index.html">Oracle Berkeley DB</a> 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 <a href="http://www.oracle.com/technology/documentation/berkeley-db/db/bdb-sql/index.html">SQLite-like C API</a> with the promise of providing better concurrency and performance than regular SQLite. Time to give it a shot.<br /></p> 
<p>So I grabbed the <a href="http://www.oracle.com/technology/software/products/berkeley-db/index.html">source distribution</a>, checked the documentation and saw that I shall use the <a href="http://www.oracle.com/technology/documentation/berkeley-db/db/bdb-sql/buildinstall.html#onunix"><em>--enable-sql_compat</em></a> configure option so DB creates a libsqlite3.so which can be used by PHP'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't do any benchmarks, yet, but I would be interested to read some results. Oh and yes, according to the documentation there are a <a href="http://www.oracle.com/technology/documentation/berkeley-db/db/bdb-sql/miscdiff.html">few minor changes in behavior</a>, this should only affect very few PHP users though.</p> 
<p>So the whole process after extracting DB and PHP sources looked like this:</p> 
<blockquote> 
<pre>$ 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</pre> 
</blockquote> 
<p>Now you don't have to use the SQLite interface for using DB but can also use <a href="http://php.net/dba">PHP's dba extension</a>. In current releases of PHP PHP expects at most DB version number 4 for the DBA driver, but a patch was <a href="http://news.php.net/php.cvs/62805">committed</a> to PHP's svn repository so upcoming PHP releases can be build using the latest DB version by adding <em>--with-db4=/opt/db-5.0.21</em> to PHP's configure line.<br /></p> 
<p>Now I can hear you complain: &quot;three ways to access a database isn't enough!&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's hope:<br /></p> 
<p>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's native C++ API in an PHP OO API. To try it simply follow the <a href="http://php.net/manual/en/install.pecl.phpize.php">steps from the PHP manual</a> for compiling custom extensions:</p> 
<blockquote> 
<pre>$ cd db-5.0.21/php_db4
$ phpize
$ ./configure --with-db4=/opt/db-5.0.21
$ make
# make install</pre> 
</blockquote> 
<p>And then a quick check using reflection to see what functionality is provided by this extension:</p> 
<blockquote> 
<pre>$ php -dextension=db4.so --re db4
Extension [ <persistent> 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 [ <internal:db4> class db4txn ] {

      - Constants [0] {
      }

      - Static properties [0] {
      }

      - Static methods [0] {
      }

      - Properties [0] {
      }

      - Methods [8] {
        Method [ <internal:db4> public method abort ] {
        }

        Method [ <internal:db4> public method commit ] {
        }

        Method [ <internal:db4> public method discard ] {
        }

        Method [ <internal:db4> public method id ] {
        }

        Method [ <internal:db4> public method set_timeout ] {
        }

        Method [ <internal:db4> public method set_name ] {
        }

        Method [ <internal:db4> public method get_name ] {
        }

        Method [ <internal:db4, ctor=""> public method db4txn ] {
        }
      }
    }

    Class [ <internal:db4> class db4cursor ] {

      - Constants [0] {
      }

      - Static properties [0] {
      }

      - Static methods [0] {
      }

      - Properties [0] {
      }

      - Methods [7] {
        Method [ <internal:db4> public method close ] {
        }

        Method [ <internal:db4> public method count ] {
        }

        Method [ <internal:db4> public method del ] {
        }

        Method [ <internal:db4> public method dup ] {
        }

        Method [ <internal:db4> public method get ] {

          - Parameters [2] {
            Parameter #0 [ <required> &amp;$param0 ]
            Parameter #1 [ <required> &amp;$param1 ]
          }
        }

        Method [ <internal:db4> public method put ] {
        }

        Method [ <internal:db4> public method pget ] {

          - Parameters [2] {
            Parameter #0 [ <required> &amp;$param0 ]
            Parameter #1 [ <required> &amp;$param1 ]
          }
        }
      }
    }

    Class [ <internal:db4> class db4 ] {

      - Constants [0] {
      }

      - Static properties [0] {
      }

      - Static methods [0] {
      }

      - Properties [0] {
      }

      - Methods [15] {
        Method [ <internal:db4, ctor=""> public method db4 ] {
        }

        Method [ <internal:db4> public method open ] {
        }

        Method [ <internal:db4> public method close ] {
        }

        Method [ <internal:db4> public method cursor ] {
        }

        Method [ <internal:db4> public method del ] {
        }

        Method [ <internal:db4> public method get ] {
        }

        Method [ <internal:db4> public method get_encrypt_flags ] {
        }

        Method [ <internal:db4> public method pget ] {
        }

        Method [ <internal:db4> public method get_type ] {
        }

        Method [ <internal:db4> public method join ] {
        }

        Method [ <internal:db4> public method put ] {
        }

        Method [ <internal:db4> public method set_encrypt ] {
        }

        Method [ <internal:db4> public method stat ] {
        }

        Method [ <internal:db4> public method sync ] {
        }

        Method [ <internal:db4> public method truncate ] {
        }
      }
    }

    Class [ <internal:db4> class db4env ] {

      - Constants [0] {
      }

      - Static properties [0] {
      }

      - Static methods [0] {
      }

      - Properties [0] {
      }

      - Methods [11] {
        Method [ <internal:db4, ctor=""> public method db4env ] {
        }

        Method [ <internal:db4> public method close ] {
        }

        Method [ <internal:db4> public method dbremove ] {
        }

        Method [ <internal:db4> public method dbrename ] {
        }

        Method [ <internal:db4> public method get_encrypt ] {
        }

        Method [ <internal:db4> public method open ] {
        }

        Method [ <internal:db4> public method remove ] {
        }

        Method [ <internal:db4> public method set_data_dir ] {
        }

        Method [ <internal:db4> public method set_encrypt ] {
        }

        Method [ <internal:db4> public method txn_begin ] {
        }

        Method [ <internal:db4> public method txn_checkpoint ] {
        }
      }
    }
  }
}</internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4,></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4,></internal:db4></required></required></internal:db4></internal:db4></required></required></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4,></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></internal:db4></persistent>
</pre> 
</blockquote> 
<p>The extension bundles some examples to get you started with Berkeley DB.</p> 
<p>Even though I'd prefer a <a href="http://www.mysql.com">relational client-server database</a> 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.<br /></p> 
<blockquote> </blockquote> 
            </div>
        </content>
        <dc:subject>berkeley db</dc:subject>
<dc:subject>coding</dc:subject>
<dc:subject>database</dc:subject>
<dc:subject>db</dc:subject>
<dc:subject>oracle</dc:subject>
<dc:subject>php</dc:subject>
<dc:subject>php extensions</dc:subject>
<dc:subject>sqlite</dc:subject>
<dc:subject>sqlite3</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/135-Jason,-let-me-help-you!.html" rel="alternate" title="Jason, let me help you!" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-06-03T17:01:00Z</published>
        <updated>2010-06-04T12:23:25Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=135</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/3-PHP" label="PHP" term="PHP" />
    
        <id>http://schlueters.de/blog/archives/135-guid.html</id>
        <title type="html">Jason, let me help you!</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>In a few previous blog posts I was already <a href="http://schlueters.de/blog/plugin/tag/php%FFnext">talking about changes</a> in <a href="http://schlueters.de/blog/archives/128-Future-of-PHP-6.html">PHP's trunk</a>, like <a href="http://schlueters.de/blog/archives/129-Mind-the-encodings!.html">some BC break</a> or <a href="http://schlueters.de/blog/archives/133-Now-in-trunk-Improved-interactive-shell.html">some new features</a>, time to continue:</p> 
<p>JSON is the modern data format used in &quot;AJAX&quot; applications. As <strong>the</strong> leading language for the Web PHP course has support for handling JSON data: You can pass any data to <a href="http://php.net/json_encode">json_encode()</a> and the function will create a JSON representation of this data:</p> 
<blockquote> 
<pre>&lt;?php
echo json_encode(array(1,2,3,4));
?&gt;

[1,2,3,4]

</pre> 
</blockquote> 
<p>This also works for objects:<br /></p> 
<blockquote> 
<pre>&lt;?php
$o = new stdclass;
$o-&gt;a = 42;
echo json_encode($o);
?&gt;

{"a":42}
</pre> 
</blockquote> 
<p>Wonderful. But the world isn'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's hope in sight: the new interface <em>JsonSerializable</em>. Classes implementing this interface have to provide a method <em>jsonSerialize()</em> which will be called by <em>json_encode()</em> and has to return a JSON-compatible representation of the data by doing whatever you want. So let's take a look:</p> 
<blockquote> 
<pre>&lt;?php
class JsonTest implements JsonSerializable {
    private $a, $b;

    public function __construct($a, $b) {
        $this-&gt;a = $a;
        $this-&gt;b = $b;
    }

    public function jsonSerialize() {
        return $this-&gt;a + $this-&gt;b;
    }
}

echo json_encode(new JsonTest(23, 42));
?&gt;

65
</pre> 
</blockquote> 
<p>Now this example in itself is of course useless, but let's create a bigger structure, which includes a few of these objects:</p> 
<blockquote> 
<pre>&lt;?php
$data = array(
    new stdClass();
    new JsonTest(1,2),
    new JsonTest(3,4),
    array(5,6)
);
echo json_encode($data);
?&gt;

[{},3,7,[5,6]]
</pre> 
</blockquote> 
<p>Of course you'd usually have more complex serialization logic, but that's left to you.</p> 
<p>Now almost certainly somebody will ask &quot;and what about the other way round?&quot; - The only answer there is: Sorry there we can't do much. JSON doesn't encode and meta-information so our generic parser in <a href="http://php.net/json_decode">json_decode()</a> can't do anything special. But anyways: The new interface will certainly be useful.</p> 
<p>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.<br /></p> 
            </div>
        </content>
        <dc:subject>ajax</dc:subject>
<dc:subject>coding</dc:subject>
<dc:subject>json</dc:subject>
<dc:subject>php</dc:subject>
<dc:subject>php oo</dc:subject>
<dc:subject>php.next</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/133-Now-in-trunk-Improved-interactive-shell.html" rel="alternate" title="Now in trunk: Improved interactive shell" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-05-28T18:55:00Z</published>
        <updated>2010-06-03T17:04:44Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=133</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/3-PHP" label="PHP" term="PHP" />
    
        <id>http://schlueters.de/blog/archives/133-guid.html</id>
        <title type="html">Now in trunk: Improved interactive shell</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>A few years ago I used another blog to write about &quot;<a href="http://blog.mayflower.de/archives/44-More-PHP-power-on-the-command-line.html">More PHP power on the command line</a>&quot; almost 5 years later the PHP interactive shell got a major update which went in PHP's trunk. The <a href="http://news.php.net/php.cvs/62675">commit message</a> tells a lot about the improvements:</p> 
<blockquote> 
<pre>- 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'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 &gt; #cli.pager=less
php &gt; phpinfo();
(output will appear in the pager)
php &gt; #cli.pager=grep -i readline
php &gt; phpcredits();
Readline =&gt; Thies C. Arntzen
php &gt; #cli.pager=
(output appears again direct on the terminal)

A prompt can contain a few escape sequences like

php &gt; #cli.prompt=\e[032m\v \e[031m\b \e[34m\&gt; \e[0m
5.3.99-dev php &gt; //Colorful prompt with version number

A prompt can also contaian PHP code in backticks

php &gt; #cli.prompt=`echo gethostname();` \b \&gt;
guybrush php &gt;
</pre> 
</blockquote> 
<p>But I assume a screenshot is quite useful, so here it goes:</p> 
<p><!-- s9ymdb:52 --><img width="667" height="221" src="http://schlueters.de/blog/uploads/screenshots/Screenshot-johannesguybrush-src-php-build-6.0-debug-notsrm-gcc.png" /></p> 
<p>
So what doyou need to use this feature? - <a href="http://schlueters.de/blog/archives/128-Future-of-PHP-6.html">PHP trunk</a> compiled using <em>--with-readline</em> or <em>--with-libedit</em>.The PHP Documentation <a href="http://php.net/manual/en/features.commandline.interactive.php">has information</a> about the interactive mode, the new features will be added once trunk is closer to a release and it's clear in what release this will appear.<br /></p> 
            </div>
        </content>
        <dc:subject>command line</dc:subject>
<dc:subject>php interactive</dc:subject>
<dc:subject>php shell</dc:subject>
<dc:subject>php.next</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/128-Future-of-PHP-6.html" rel="alternate" title="Future of PHP 6" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-03-12T12:15:23Z</published>
        <updated>2010-05-11T08:45:19Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=128</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/3-PHP" label="PHP" term="PHP" />
    
        <id>http://schlueters.de/blog/archives/128-guid.html</id>
        <title type="html">Future of PHP 6</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Yesterday was a quite thrilling day for the PHP development team and led to some imprecise news articles so let'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's engine wasn'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 <a href="http://news.php.net/php.internals/47120">Rasmus declared</a> the current implementation to be discontinued to restart.</p> 
<p><strong>The past</strong></p> 
<p>When the foundation of what should have become PHP 6 was created a decision was made to use UTF-16 as internal encoding for &quot;everything&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'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'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 &quot;trunk&quot; as their main development tree but either develop using the stable 5.2/5.3 trees or refuse to do development at all.</p> 
<p><strong>The present</strong></p>

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'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 <a href="http://php.net/migration53">usually can be done with very little work</a>, as soon as possible.


<p><strong>The future</strong></p>

Right now we're starting different discussions to see what kind of Unicode support we really want. Many contributors react positive on a proposed &quot;string class&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'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'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.


<p><strong>PHP is alive and kicking!</strong></p> 
            </div>
        </content>
        <dc:subject>development</dc:subject>
<dc:subject>opensource</dc:subject>
<dc:subject>php</dc:subject>
<dc:subject>php 5</dc:subject>
<dc:subject>php 5.4</dc:subject>
<dc:subject>php 6</dc:subject>
<dc:subject>php releases</dc:subject>
<dc:subject>php.next</dc:subject>
<dc:subject>php53</dc:subject>
<dc:subject>processes</dc:subject>
<dc:subject>unicode</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/129-Mind-the-encodings!.html" rel="alternate" title="Mind the encodings!" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-03-28T01:31:00Z</published>
        <updated>2010-05-11T08:44:58Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=129</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/3-PHP" label="PHP" term="PHP" />
    
        <id>http://schlueters.de/blog/archives/129-guid.html</id>
        <title type="html">Mind the encodings!</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Dealing with character sets and encodings is tough. As long as you'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 (&quot;Schlüter&quot;) will be annoyed as your application breaks them (&quot;SchlÃ¼ter&quot;), but these will be edge cases. There are bigger issues with mixing encodings but that's not what I wanted to tell now.</p>
<p>Handling these encodings in PHP correctly is tough. PHP, currently, has a quite simple approach to the problem in general: PHP doesn'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's the only way to be able to work with all documents without additional information from you along every XML operation.</p>
<p> 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's request doesn't specify anything else the browser assumes the document is encoded using iso-8859-1. The document'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.</p>
<p>Recently Rasmus made a <a href="http://news.php.net/php.cvs/62101">commit</a> to PHP trunk which changes the default to utf-8.</p>
<p>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).</p>
<p>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 <a href="http://schlueters.de/blog/archives/128-Future-of-PHP-6.html">still sometime away</a> and you can easily prepare your application - which is a good thing anyways to protect from administrators making mistakes with current versions already.</p>
<p>To set the encoding from within your application you can for example call <em>ini_set('default_charset', $enc);</em> or <em>header(&quot;Content-type: text/html; charset=$enc&quot;);</em> at the beginning of your script, where <em>$enc</em> 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!</p><br /> 
            </div>
        </content>
        <dc:subject>charsets</dc:subject>
<dc:subject>commits</dc:subject>
<dc:subject>encoding</dc:subject>
<dc:subject>php</dc:subject>
<dc:subject>php.next</dc:subject>

    </entry>
    <entry>
        <link href="http://schlueters.de/blog/archives/130-ZFS.html" rel="alternate" title="ZFS" />
        <author>
            <name>Johannes Schlüter</name>
            <email>nospam@example.com</email>
        </author>
    
        <published>2010-05-10T18:10:00Z</published>
        <updated>2010-05-10T19:27:55Z</updated>
        <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=atom1.0&amp;type=comments&amp;cid=130</wfw:commentRss>
    
            <category scheme="http://schlueters.de/blog/categories/2-Software" label="Software" term="Software" />
    
        <id>http://schlueters.de/blog/archives/130-guid.html</id>
        <title type="html">ZFS</title>
        <content type="xhtml" xml:base="http://schlueters.de/blog/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>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've also got ZFS which is Oracle'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'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 &quot;virtual&quot; zvol devices) before updating them which over time became a habit about which I didn't really think.</p> 
<p>Then I'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'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'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.</p> 
<p>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'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... </p> 
<p>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 &quot;well, I won't need it, I have everything in a version control software and I know what I delete&quot; that might be true but once you have ZFS you change your way to operate and you don't have the whole system in a version control thing. It'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'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'm used to <img src="http://schlueters.de/blog/templates/schluetersde/img/emoticons/smile.png" alt=":-)" style="display: inline; vertical-align: bottom;" class="emoticon" /></p> 
<p>P.S. This blog is running on ZFS, too - of course, gave a good feeling to be able to revert during today's update, too.<br /></p> 
            </div>
        </content>
        <dc:subject>dtrace</dc:subject>
<dc:subject>netbook</dc:subject>
<dc:subject>opensolaris</dc:subject>
<dc:subject>phpbcat</dc:subject>
<dc:subject>ubuntu</dc:subject>
<dc:subject>zfs</dc:subject>

    </entry>

</feed>