Entries tagged as coding
Related tags
.net c# php security web 2.0 xss ajax amber road brendand gregg dtrace hardware json php oo php.next solaris storage sun microsystems youtube anniversary birthday fun php extensions php shell readline array java oop php qa university assembler boredom frustration stupidity banshee music BarCamp conferences debugging events macos opensolaris planet php travel wolfram bazaar launchpad netbeans phpqa phpt berkeley db database db oracle sqlite sqlite3 balcony blogging entertainment fire fire at home fire fighters home sweet home internet irc same proocedure trends tv tv series twitter video Bryan Cantrill development DTrace google MacOS exchange microsoft office outlook outlookfun vba christmas escher family games mysql mysql storage engine pony puzzle weihnachten comments english german language 23c3 acquisation berlin blogger ccc data center ego froscon froscon08 froscon10 hamburg hausdurchsuchung ipc ipc06 ipc07 ipc08 ipc09 ipc10 james gosling lawblog montreal mysqlde mysqlnd mysqlnd plugins namespaces nuremberg oscon osdc osdc.il07 osdc09 php conferences php quebec php quebec 09 php releases php53 phpbarcelona cvs dsp git parsecvs play project managment scm vcs barcamp gopal pecl releases scream delphi pascal gsoc gsoc09 improvements ms paint opensource packages paint php 5 php 5.4 php 6 php testing processes testing unicode blog crossbow linux netbook phpbcat server solaris zones ubuntu virtualization exams beer garden munich php bbq firefox add-ins desktop gecko mozilla xul javafx badeente barcelona catalonia concert dancehall daten frei dendemann earth god google maps hiphop history job kaffee kaunas kinderzimmer productions linkblog lithuania live php git beate merk br alpha bundesdatenschutzbeauftragter bundestrojaner bundesverfassungsgericht cdu csu Daten frei datenschutz gmail gsoc08 movies onlinedursuchung patriot act politik privacy recht und ordnung regierung schäuble sicherheitsstaat terroristen urteilvorratsdatenspeicherung goto closures php testfest easter gsoc2008 qa testfest bc mysql proxy phpmysqlproxy ulf work iterator mysqli resultset stored procedures grades jee xenjoMar 24: Google Summer of Code 2009
Dec 30: MySQL Storage Engine based on PHP
Sometimes one has weird ideas, or am I the only one? - This specific one is at least a year old, now, during the Christmas days, waiting for New Year's Eve I had the time and mood to finally try it out: MySQL 5.1 has a plugin interface to easily add storage engines. PHP can easily embedded into other applications. So why not combine these two things? - Writing a MySQL Storage Engine which reads data by calling a PHP script.
Let's start with a simple example first:
<?phpfunction create_table($table, $data) {
    return true;
}
function open_table($table) {
    return new ArrayIterator(array(
        array('id' => 1, 'dat' => 'foo'),
        array('id' => 2, 'a' => 'bar')
    ));
}
?>
This is the bare minimum storage engine my plugin supports. create_table() is called for creating the table, open_table() to access it, the later one then returns an iterator which is used for a full table scan. This example uses an ArrayIterator, which implements the SeekableIterator and the Countable interfaces, the first one provides a seek() method, which is called to read specific rows after sorting for instance, the later provides a method count() which gives the optimizer a hint.
Let's use this table:
mysql> CREATE TABLE php_test (id int, val CHAR(3)) ENGINE=PHP;
Query OK, 0 rows affected (0.04 sec)
mysql> SELECT * FROM php_test;
+------+------+
| id | val |
+------+------+
| 1 | foo |
| 2 | bar |
+------+------+
2 rows in set (0.00 sec)
Ok, of course that's nice and shiny but well, it's read only. To solve that you can implement a few interfaces provided by the plugin to handle writes:
<?php
class Test extends ArrayIteratorÂ
implements MySQLStorage_Writable, MySQLStorage_Updatable, MySQLStorage_Deletable {
    public function write($data) {
        $this[] = $data;
    }
    public function update($data) {
        $this[$this->key()] = $data;
    }
    public function delete() {
        unset($this[$this->key()]);
    }
}
function create_table($table, $data) {
    return true;
}
function open_table($table) {
    return new Test(array(
        array('id' => 1, 'dat' => 'foo'),
        array('id' => 2, 'a' => 'bar')
    ));
}
?>
Again, we can test it:
mysql> UPDATE php_test SET val = 'baz' WHERE id = 1;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> DELETE FROM php_test WHERE id = 2;
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO php_test VALUES(3, 'bar');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM php_write;
+------+------+
| id | val |
+------+------+
| 1 | baz |
| 3 | bar |
+------+------+
2 rows in set (0.00 sec)
As a reminder: This is calling PHP for all these operations.
So what might real life use cases be, once the major issues in the code are fixed? I have a few ideas like
- A live-logfile query tool, not sure that's really need, see the primitive Apache httpd access_log parser which is provided with the code as an example
- Combine it with the embedded MySQL server and use this storage engine for your unit tests, "mock tables" ...
Any other ideas? - Leave a comment ![]()
Oh, and like most MySQL stuff nowadays: There's a launchpad project for this plugin.
Dec 25: Goto your Christmas presents with PHP 5.3
Over the last few days I already mentioned a few hidden gems from PHP 5.3. Now at Christmas I wanted to take a look at some new language feature of the upcoming PHP version:
Added "jump label" operator (limited "goto"). (Dmitry, Sara)
The entry is a imprecise on purpose, since it's not to be advertised too much to not be abused too much, but well, you're reading this on Christmas instead of spending time with your family, so I guess you're a geek and know already: PHP 5.3 introduces not only namespaces but also goto. Yes it's a "goto label;" the limitations i, mentioned in the NEWS entry, are: You can only jump within the same execution unit (function or global part of the same file file) and you can't jump into loops.
When you know about goto I'm sure you know it's bad, so why did we added? - Well there's a very limited set of problems where it's ok. One is generated code, a code generator using goto can be written way better than without goto and nobody is supposed to read that code anyways. The second situation is when having a longer piece of code, where situations might occur where you cancel execution sin the middle of the code but want to do some cleanup nonetheless. A short pseudo-code example:
<?php
function process_file($filename) {
    $fp = fopen($filename, "r");
    if (!$fp) {
        goto cleanup;
    }
    $row = fread($fp, 1024);
    // do something with the row
    if ($error_while_processing) {
        goto cleanup;
    }
    $a_few_bytes = fread($fp, 4);
    // do something again ...
        if ($error_while_processing) {
        goto cleanup;
    }
    /* ... */cleanup:
    fclose($fp);
}?>
There are alternatives available, like wrapping this all in loops and using break or wrap it in an try {} catch block and throw exceptions, but goto can be cleaner. So have fun and use it with care!
Dec 19: Data structures in PHP 5.3
In the programming world there are quite a few well understood and explored data structures. Which are commonly used in tons of applications, still the only things PHP offered till 5.3 in regards to structuring data were arrays (more precise: hash tables) and objects. So people had to either abuse them for other structures or implement the structures themselves on top of these. Thanks to Etienne things now are changing and PHP's Standard PHP Library (SPL) extension will offer quite a few standard implementations of data structures. The implemented data structures are implemented using these classes:
- SplDoublyLinkedList
- SplStack
- SplQueue (SplPriorityQueue)
- SplHeap (SplMinHeap, SplMaxHeap)
- SplFixedArray
Except for SplFixedArray the ideas behind these classes should be clear. If not you can read about them over at Wikipedia or in basically every general introduction to software programming book. For the exact naming and details of the implementation chosen for PHP you can read the fine manual. So why should you use these instead of implementing your own? - There are a few reasons the important ones are:
- Why do work others have done before again and again? - Code used in more places is better tested and has less bugs.
- Having code implemented native in C is faster than doing this in PHP userland.
- Using default data structures makes the code more maintainable
The only question left there might be: "Ok, that's nice and cool and I could use them, but I have to support older PHP versions for at least some time. What can I do?" - The solution there is easy as well: Most stuff in SPL doesn't do any special trick that requires an implementation in C but can also be implemented in userland. In fact most stuff is tested as userland code first to design the interfaces nicely. Others are implemented in PHP after being implemented in C as kind of documentation. These implementations are distributed with PHP source releases or via CVS, so you can simply take that code and use it.
But now let's get back to the one class which might not be clear: SplFixedArray. SplFixedArray is an implementation of a data structure similar to PHP's arrays with a big limitation: It only supports numeric indexes in a predefined range (starting at 0 and going up) like the ArrayObject from 5.2 it's class based so it can't be used with all thousands of array functions PHP offers, but within it's domain and fucntionality it's very fast and uses less memory than classic PHP arrays. so if you have a big array where numeric indexing is enough: Use it!
Dec 17: NetBeans plugin for running phpt tests

One of the things I do quite often is running PHP's regression test suite which is using a custom test format called .phpt. The PHP source distribution, and CVS checkouts, include a nice script for running them called run-tests.php.
run-tests.php gives a summary of failed tests in the end. As a developer I'm now interested for the reasons for the failures. The test system therefore produces a bunch of files, a file containing the expected output, one containing the actual output and a diff between these as relevant files. The problem there is that the diff, for being portable, is using a quite simple machnism which only shows the lines which differ without any context. This makes it quite hard to read. Therefore I usually diff the .exp and .out files myself for doing that I have a few simple shell scripts which I call with the test name and then get a proper diff.
Lately I've changed my way of working and use vim less, I still use it, but I use NetBeans as an IDE more and more. So I thought a bit about that test issue and searched my brain for my Java skills and started playing around to see whether I manage to write a NetBeans plugin which can run the tests and report the results in a usable way. Over the time it looked quite promising, so I registered a launchpad project and imported the code to a repository there. Now I think I've reached a true milestone which should basically work for interested folks. And released a version 0.6.0.
The module registers an menu entry and a toolbar icon to start a wizard. This wizard asks you for the PHP binaries to use and test directory to run. It will then run the tests and open a window with the results of each test. By double clicking or using a context menu you can then get the actual test code and a diff. If you have PHP support installed in NetBeans the code will also be highlighted.
There are still a few issues most importantly you need a special version of run-tests.php, which is bundled, and not all things, like redirect tests, are supported. There are certainly other issues, but the aim is mostly to help me. If you're interested feel free to report a bug and maybe I look into it. If you're brave you can also fetch the code and start hacking it - but keep in mind I'm no Java developer and had no idea what I'm aiming at and how to write NetBeans modules when I started, you can see that in the code ![]()
This code requires Java 6 (since I make use of SwingWorker) and I didn't test older NetBeans versions than 6.5 since that version has proper PHP support and there's little sense in having older versions installed.
P.S. The screenshot is a bit faked: The inner windows don't appear exactly like that, yet, but that's the aim and you can easily use Drag'n'Drop inside the IDE to arrange them till I found out how to that from within the code.
Nov 19: Fighting JavaFX
I recently wrote a few postings about great Sun stuff. The reason for that? - Well since joining Sun I get all the information about the things Sun does and there are tons of cool things, I enjoy OpenSolaris, especially DTrace and zfs (zfs snapshots!) - these are great pieces of technology. Ok, you can feel that OpenSolaris isn't finished yet, but it's a good step from a classic Unix to a quite usable system.
Now Sun is famous for another product family: Java. For me Java has always been a synonym for ugly and annoying applets and over-engineered "enterprise" applications which are close to being unusable. Being Sun I learned about a new technology for fighting the RIA wars against Microsoft's Silverlight and Adobe's Flex: JavaFX. After browsing a while over the different sites I found out that key part of JavaFX is a declarative scripting language for creating user-interfaces. That sounds quite cool - no annoying and over-verbose XML and no procedural coding for describing a GUI, but a syntax which looks quite sane for that. So I wanted to give it a shot. And that's where the trouble began ...
Read MoreNov 3: Direct MySQL Stream Access
Ever wondered what your PHP application and MySQL actually do? An experimental mysqlnd branch will give you full access to the network communication stream. Using a custom PHP stream filter you can then intercept the communication ... but let's start at the beginning:
When talking about mysqlnd - the mysql native driver for PHP - we always mention the fact it's native in a way that we're, when possible, using PHP infrastructure. The most common example here is the memory management. By directly using PHP's memory we can avoid unnecessary copies of data from the MySQL Client Library's memory into PHP memory.
<?php
$mysqli = mysqli_connect("localhost", "root", "", "test");
$stream = mysqli_conn_to_stream($mysqli);
stream_filter_append($stream, "mysql.server", STREAM_FILTER_READ);
?>
But there's more what we're doing. We're also using PHP's stream abstraction layer. From a development perspective the benefit is that we're using a tested abstraction from different stream implementations by different operating systems instead of writing our own. But, again, there's more to it: We can export the communication stream to PHP userland. We hesitated about exporting it for some time as it can be quite dangerous and you might easily corrupt the client-server- communication.
As Ulf mentioned during his IPC talk I recently pushed a mysqlnd branch to launchpad which adds a userspace function to mysqli which returns a PHP stream for a connection. Using that stream you can now send your own requests to the server and wait for the response. That might be nice in a way, but I guess you most likely won't have use for that. PHP streams allow you to do more: PHP streams give you the possibility to add filters to a stream. These filters allow you to intercept packages which are sent or received , read them, change them or do whatever you like. A very simple filter can be found on the launchpad site, mentioned above. That filter simply prints the information after replacing unprintable (binary) characters by dots.
Once again: Just a small step, the next one is to decode the MySQL protocol. For that I've written a simple decoder for the MySQL protocol, not complete, but enough to give an idea. The script, including the decoder and some sample code using it, is, as a sample, part of the branch. When running you will get some output like
Query:
-> 0 59: QUERY: SELECT TABLE_SCHEMA FROM INFORMATION_SCHEMA.TABLES LIMIT 1
<- 1 1: DATA
<- 2 52: FIELD INFO
<- 3 5: EOF
<- 4 19: DATA
<- 5 5: EOF
Invalid Query:
-> 0 29: QUERY: ghdfjtgfdrs tztr ttgdszthtdr
<- 1 183: ERROR: 2000You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ghdfjtgfdrs tztr ttgdszthtdr' at line 1
Prepare:
-> 0 61: PREPARE: SELECT TABLE_NAME FROM INFORMATION_SCHEMA.STATISTICS LIMIT 2
<- 1 12: OK
<- 2 52: FIELD INFO
<- 3 5: EOF
Ping:
-> 0 1: PING
<- 1 7: OK
Execute:
-> 0 11: EXECUTE
<- 1 1: DATA
<- 2 52: FIELD INFO
<- 3 5: EOF
<- 4 15: OK
<- 5 15: OK
<- 6 5: EOF
EOF
-> 0 5: CLOSE_STMT
-> 0 1: QUIT
As one can see: The protocol isn't fully decoded yet so this all might be extended but for me it served the purpose well enough. For making real use out of this we're thinking about exporting the protocol decoder which exists within mysqlnd to PHP userland.
What are your ideas for such a feature? - Sending different queries to different servers? Rewriting queries? Sharding? Replication? Easy scaling of your application while refactoring your application? Let us know!
Oct 26: More on DTrace ... and MySQL
Angelo recently showed an easy way to dump SQL queries using DTrace, while reading the articles I felt that some important information is missing: The name of the user executing the query and the selected database. So I sat down a few minutes and tried to collect that data.
For the database name I found a quite simple solution: It is passed as parameter to the check_user() function to MySQL so we can easily add a thread-local variable to keep that name. Simple script for that:
#!/usr/sbin/dtrace -s
#pragma D option quiet
pid$1::*check_user*:entry
{
self->db = arg4 ? copyinstr(arg4) : "(no schema)";
}
pid$1::*dispatch_command*:entry
{
printf("%s: %s\n", self->db, copyinstr(arg2));
}
Getting the username is a bit harder, for the PID-provider we need a function where it is passed as parameter, best would be if it was passed as char*, but there's no such function reliably called. (For instance there are functions for checking max connections per user where all we need is passed in a proper way, but it's only called when a limit was set) The only way would be to take the user_connect property of the THD object which is passed to dispatch_command and then access the username (and hostname). But getting that working from within DTrace is quite some work. I prepared some scripts doing this with simple C structures for the second part of my DTrace article series, which is ready in my head and is waiting to be typed, so in theory it should be possible, anybody wants to try?
The best solution, of course, would be to add proper probes into the MySQL server code which provide all that information.Oct 12: DTraceing around
Over the past few weeks I annoyed my environment with praising DTrace whenever possible. Yesterday, during a break at the Barcamp Munich, I gave Wolfram a short introduction on his Mac and decided to put some stuff here:
DTrace is a toolkit available on Solaris (Solaris 10 or OpenSolaris), recent MacOS versions and FreeBSD for mightier than tools like truss or strace but with way less impact. DTrace allows you to "hook" (called "probes") into the system and allows to do some analysis then.
I guess all that works best by showing an example first: PHP uses a wrapper over the system's memory allocation using a function called _emalloc (which is wrapped by a CPP macro called emalloc) so it might be interesting to see how often that function is being called. For doing that we can use a D-script (D being the DTrace scripting language, not DigitalMars's D) like that:
#!/usr/sbin/dtrace -s
#pragma D option quiet
pid$target::_emalloc:entry
{
printf("_emalloc was called!\n");
}
We can now simply call that script and tell DTrace to start a PHP interpreter and run a PHP script. DTrace will then change the running program in memory so that the message is printed whenever the system for the process, with the PID $target, enters the function _emalloc. $target is a special variable referring to a process started by DTrace using -c or a PID provided using -p.
$ ./script1.d -c "php script.php" _emalloc was called! _emalloc was called! _emalloc was called! ...
That's nice but not really useful in any way, yet. As we'd like to at least know the size of the allocated memory area, which is the first parameter to _emalloc. The pid-provider helps us by providing the parameters to the functions as D-variables, so we can simply change our action to print that variable:
printf("_emalloc called, allocating %i bytes\n", arg0);
running the script now gives us the sizes:
./script2.d -c "php script.php" _emalloc was called, allocating 5 bytes _emalloc was called, allocating 6 bytes _emalloc was called, allocating 5 bytes ...
The output is quite long and still rather useless, for making use from this information we at least need some aggregation, but DTrace helps there, too, so let's create an aggregation variable collecting the data in a usable way:
#!/usr/sbin/dtrace -s
#pragma D option quiet
pid$target::_emalloc:entry
{
@mallocsize["emalloc"] = quantize(arg0);
}
mallocsize and emalloc are there freely chosen identifiers. Depending on your script the output now looks something like the following:
emalloc
value ------------- Distribution ------------- count
0 | 0
1 | 83
2 |@@ 1122
4 |@@@@@@@@ 5141
8 |@@@@@@ 4032
16 |@@@@@@@@@@@@@@@@@@ 11881
32 |@@@@@@ 3694
64 |@ 806
128 | 27
256 | 66
512 | 1
1024 | 1
2048 | 1
4096 | 1
8192 | 4
16384 | 0
32768 | 1
65536 | 0
131072 | 1
262144 | 0
This tells us that the most used allocation size is between 9 and 16 bytes and the largest space allocated is somewhere between 65536 and 131072 bytes.
For a deeper analysis we can now add a predicate to our probe so the action triggers only for that allocation. Such predicates are writing between slashes between the probe name and the action. Additionally I'm adding a ustack() call to the action, this will print the systems userspace backtrace -- which is C level, not PHP space.
#!/usr/sbin/dtrace -s
#pragma D option quiet
pid$target::_emalloc:entry
/ arg0 > 131072 /
{
printf("_emalloc(%i)\n", arg0);
ustack();
}
$ ./script4.d -c "php script.php"
emalloc(261900)
php`_emalloc
php`zend_vm_stack_new_page+0x19
php`zend_vm_stack_init+0xf
php`init_executor+0xf5
php`zend_activate+0x12
php`php_request_startup+0x7a
php`main+0xd86
php`_start+0x7d
So we see we're in the startup of PHP allocating some space on it's stack. One question now might be about the costs of an _emalloc call, one important factor there are syscalls to the operating system. As DTrace is made for utilizing the whole system that can be done quite easy using the syscall provider. Me might now use syscall:::entry as probe to be triggered on every call, but that will be quite a lot. As we're only interested in syscalls from _emalloc we'll use a thread-local variable as a flag and check that flag in the predicate condition:
#!/usr/sbin/dtrace -s
#pragma D option quiet
pid$target::_emalloc:entry
/ arg0 > 131072 /
{
self->inemalloc = 1;
}
pid$target::_emalloc:return
/ arg0 > 131072 /
{
self->inemalloc = 0;
}
syscall:::entry
/ self->inemalloc /
{
printf("%s", probefunc);
}
$ ./script4.d -c "php script.php" brk brk
So we're calling brk two times. brk is the syscall to "change the amount of space allocated for the calling process's data segment" which is exactly what we expect, but why is it called two times? Adding a ustack call to the syscall action can tell us where it happens, using the source this can then probably be optimized. That's left as an exercise to the interested reader.
In summary: No need to change the code and lots of information, I plan to write an additional article showing how to get interesting facts system-wide, not only for a specific process but all running ones, which is especially interesting when searching for a problem on production systems (DTrace is made to be used on productive systems!) or problems related to concurrent processes/threads.
Oct 5: DTrace, PID provider and rights
DTrace is a damn cool debugging tool, unfortunately only available for Solaris and different BSD flavors. If you want to learn about it watch the quite entertaining video (well, I guess you should be a true geek to be entertained, ...) from Bryan Cantrill's talk.
The reason for me writing this is that I had some problems with the PID provider and wanted to note the solution for myself:
$ dtrace -n 'pid1005:::entry { printf("Hello"); }'
probe description pid1005:::entry does not match any probes
The reason is that my user only had the dtrace_user, not the dtrace_proc right. Setting the attributes correctly solved the issue. Time for more DTrace'ing.
Aug 2: PHP 5.3 reached its first major milestone
As most of you might have seen we recently announced the first alpha of PHP 5.3.0. The major changes are listed in the announcement. Source tarballs can be found on PHP's downloads site, as it's the first release I packaged I'm especially interested in feedback, whether it works or not
. But we didn't only have changes on the source builds: A new team took over the creation of Windows builds. As they also did a major update to the Windows build architecture (supporting newer compiler versions on Windows and added experimental support for 64bit platforms) the build process got a bit delayed but builds should be available soon.
Remember: It's a release we packaged to get feedback from our users. So please test it. If you find issues please report them - the sooner we know about issues the sooner they can be addressed. Although our test coverage increased we can't cover all cases in our tests so please test it now and don't wait for the stable release, once the stable release is out your edge case might trigger a bug on a productive system, bugs reported now can be fixed before we release a final version.
If you want to give back to the PHP project - hey you probably make a living out of software you get for free - and can't fix bugs or assist in a similar way you probably could help our documentation team with improving the documentation, there are a few features without proper documentation, yet.
Mar 29: Student applicatiosn for GSoC: Send in your applications!
As others already wrote PHP participates in this year's Google Summer of Code program. If you are a student we'd welcome your application!
Some general hints:
- Feel free to propose your own ides, our list of ideas doesn't list everything possible.
- We are not interested in proposals for new frameworks or "I want to create my homepage using PHP", our ideas page should give you a good picture about the kind of stuff we are interested in
- Do some research on the subject, don't just copy&paste from our ideas page (we know that text!) but give us your opinion about the project
- Give us relevant information about you, we are, for isntance, not interested in the name of your cat.
- We are not thatm uch interested in people who take the money and leave, we prefer people who stay with the project, help with maintaining their code and maybe even other parts of PHP
Jan 7: Importing PHP into git
Oct 13: PHP 5.3 update
Since a few hours we're having, thanks to Edin, Windows snapshots for the upcoming PHP 5.3 release. In combination with the latest sources from CVS everybody should be able to test the current state.
There are quite a few new features already committed to the CVS tree, some of them are documented in the NEWS file and READMEs in CVS, most of them have been commented on Planet PHP so I suggest searching there for more information and keep this list short:
- Namespaces: A way to help you organizing your code.
- Late Static Binding: Gives you the class name used when calling a static method.
- Dynamic static calls: $c = "classname"; $c::someMetod();
- Improved ini-handling: .htaccess file like per-directory configuration and much more
- __callStatic magic method: similar to __call but for static calls
- mysqlnd: a replacement for libmysql for better PHP-MySQL-Integration
- getopt() on any platform (inclding windows)
- ...
As you can see there's lots of stuff which needs testing! The earlier bugs are found the earlier they can be fixed! In case you ever wondered how you could give back something to PHP (which you certainly should do) you might take a look at our test coverage reports to see which areas of PHP need more testing and provide additional tests. (See qa.php.net and Marcus's slides for an introduction to test writing) Having more tests is important for us - and you don't have to know much about PHP internals to write proper tests (sometimes it's even better to write black-box tests...)
But well, there's not only PHP 5.3: If you're interested in unicode you should certainly take a look at PHP 6 and if you're running older systems you should consider upgrading to the latest 5.2 release instead of waiting for PHP 5.3 - the stable release is not expected within this year and many things there can change till it's released.
And as a final note: Test the snaps as often as you can - generic tests can never cover all use-cases and - as said above - fixing regressions is harder after a release than during development. (And be warned: We won't take any complaints from people not testing in time)
Aug 18: Test the latest stuff!
Ilia recently published the probably final release candidate of the current stable tree: PHP 5.2.4RC2. The stable release can be expected soon. This release fixes quite some bugs from older versions and does a few minor adjustments. Please test the RC release so unexpected regressions can be detected and fixed before it's marked stable. If regressions and other problems aren't detected now it will take a few months till the next version will be released, so do your best to make sure it's worth being called stable! Please file found issues, after checking for other reports and the documentation, into the bug tracker. The recent trend to report bugs using blogs isn't working well!
In other news one could read that there were also some major improvements in the development of PHP 6 made: Next to all that Unicode related work which was made over the last months PHP got, due to Andrey, mysqlnd as PHP-optimized replacement for libmysql and, thanks to Dmitry's work, namespace support. So this weekend might be the perfect time for sending you're family visting other parts of the family, letting them sweat on some beach or having fun at some theme park - then you can sit down, relax, and, after testing PHP 5.2.4RC2, give that new stuff in PHP 6 a test.
For getting started with PHP 6, which you can get, as you're hopefully used to, from the snaps site, you should first read Andrei's slides about Unicode and PHP 6. The most important Unicde+PHP facts are also collected inside a README file. For namespaces there's, again, a README file, David Coallier has written a nice summary and Stanislav wrote a short FAQ. If you are curious what mysqlng is: simply read Ulf's blog postings or Andrey's slides.

