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

<rss version="0.91" >
<channel>
<title>Johannes Schlüter</title>
<link>http://schlueters.de/blog/</link>
<description>Always searching for Life, the Universe and Everything</description>
<language>en</language>
<image>
        <url>http://schlueters.de/blog/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: Johannes Schlüter - Always searching for Life, the Universe and Everything</title>
        <link>http://schlueters.de/blog/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Making use of PHP mysqlnd statistics</title>
    <link>http://schlueters.de/blog/archives/172-Making-use-of-PHP-mysqlnd-statistics.html</link>

    <description>
        &lt;p&gt;&lt;!-- s9ymdb:72 --&gt;&lt;img width=&quot;110&quot; height=&quot;69&quot; class=&quot;serendipity_image_right&quot; src=&quot;http://schlueters.de/blog/uploads/screenshots/mysqlndanalytics.serendipityThumb.png&quot; /&gt;One of the great things of mysqlnd as a base library for PHP&#039;s MySQL support are the collected statistics. mysqlnd collects &lt;a href=&quot;http://www.php.net/mysqlnd.stats&quot;&gt;about 160 different statistical values&lt;/a&gt; about all the things going on. When having such an amount of raw data it, obviously, is quite hard to draw conclusions out of it. Therefore I recently created a PHP library sitting on top of this feature to collect all data, run some analysis and then provide some guidance and made it available from the &lt;a href=&quot;https://github.com/johannes/JSMysqlndAnalytics&quot;&gt;JSMysqlndAnalytics GitHub repo&lt;/a&gt; (see there also for instructions for using Composer).&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;Using the library is relatively simple as the short instructions show. The library consists of two main parts. On the one side the &amp;quot;Collector&amp;quot;&amp;#160; this is a wrapper around &lt;a href=&quot;http://php.net/mysqli_get_client_stats&quot;&gt;mysqli_get_client_stats()&lt;/a&gt; (even though this function is part of mysqli it will also work for applications using ext/mysql or PDO_mysql) which is creating the raw statistics which could be stored away or such and then the actual Analytics engine comparing the values to predefined rules. The &lt;a href=&quot;https://github.com/johannes/JSMysqlndAnalytics/blob/master/src/JS/Mysqlnd/Analytics/analytics.xml&quot;&gt;current set of rules&lt;/a&gt; is a bit limited so I&#039;m looking for input for ideas.&lt;/p&gt; 
&lt;p&gt;In case you&#039;re a Symfony user live is quite easy: &lt;a href=&quot;http://schlueters.de/blog/archives/161-Symfony-2-and-mysqlnd.html&quot;&gt;Some time ago&lt;/a&gt; I already provided an Symfony bundle providing a Symfony Profiling Toolbar plugin showing the statistics. This &lt;a href=&quot;https://github.com/johannes/JSMysqlndBundle&quot;&gt;JSMysqlndBundle&lt;/a&gt; has been extended&amp;#160; to make use of these Analytics. The &lt;a href=&quot;http://schlueters.de/blog/uploads/screenshots/mysqlndanalytics.png&quot;&gt;screenshot &lt;/a&gt;might give a rough idea on how this looks.&lt;/p&gt; 
&lt;p&gt;Hope this helps creating better applications! Happy hacking!&lt;/p&gt; 
    </description>
</item>
<item>
    <title>Analysing WHER-clauses in INFORMATION_SCHEMA table implemtations</title>
    <link>http://schlueters.de/blog/archives/171-Analysing-WHER-clauses-in-INFORMATION_SCHEMA-table-implemtations.html</link>

    <description>
        &lt;p&gt;The MySQL Server has a quite simple interface for plugins to create tables inside INFORMATION_SCHEMA. A minimal plugin for creating a table with nothing but a counter might look like this:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;static int counter_fill_table(THD *thd, TABLE_LIST *tables, Item *cond)
{
  ulonglong value= 0;
  
  while (1)
  {
    table-&amp;gt;field[0]-&amp;gt;store(value++, true);
  }
  
  return 0;
}

static ST_FIELD_INFO counter_table_fields[]=
{
  {&quot;COUNT&quot;, 20, MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0, 0},
  {0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0}
};

static int counter_table_init(void *ptr)
{
  ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE*)ptr;

  schema_table-&amp;gt;fields_info= counter_table_fields;
  schema_table-&amp;gt;fill_table= counter_fill_table;
  return 0;
}

static struct st_mysql_information_schema counter_table_info =
{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };

mysql_declare_plugin(counter)
{
  MYSQL_INFORMATION_SCHEMA_PLUGIN,
  &amp;amp;counter_table_info,          /* type-specific descriptor */
  &quot;COUNTER&quot;,                    /* plugin and table name */
  &quot;My Name&quot;,                    /* author */
  &quot;An I_S table with a counter&quot;,/* description */
  PLUGIN_LICENSE_GPL,           /* license type */
  counter_table_init,           /* init function */
  NULL,                         /* deinit function */
  0x10,                         /* version */
  NULL,                         /* no status variables */
  NULL,                         /* no system variables */
  NULL,                         /* no reserved information */
  0                             /* no flags */
}
mysql_declare_plugin_end;
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;This is quite straight forward and &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.6/en/writing-information-schema-plugins.html&quot;&gt;documented&lt;/a&gt; inside the MySQL documentation. It also has an obvious issue: It will run forever (at least if we assume we don&#039;t run in an out of memory situation). Luckily we might have a user who foresees this issue and added a WHERE clause like here:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;SELECT COUNT FROM INFORMATION_SCHEMA.COUNTER WHERE COUNT &amp;lt; 10&lt;/pre&gt; 
&lt;/blockquote&gt; &lt;br /&gt;&lt;a href=&quot;http://schlueters.de/blog/archives/171-Analysing-WHER-clauses-in-INFORMATION_SCHEMA-table-implemtations.html#extended&quot;&gt;Continue reading &quot;Analysing WHER-clauses in INFORMATION_SCHEMA table implemtations&quot;&lt;/a&gt;
    </description>
</item>
<item>
    <title>MySQL, Memcache, PHP revised</title>
    <link>http://schlueters.de/blog/archives/169-MySQL,-Memcache,-PHP-revised.html</link>

    <description>
        &lt;p&gt;Some time ago &lt;a href=&quot;http://schlueters.de/blog/archives/152-Not-only-SQL-memcache-and-MySQL-5.6.html&quot;&gt;I was writing&lt;/a&gt; about the
InnoDB Memcache Daemon plugin already for the MySQL server. Back then we had a labs release with a little preview
only. Meanwhile quite some time passed and new developments
were made - just in time for the &lt;a href=&quot;http://dev.mysql.com/tech-resources/articles/mysql-5.6-rc.html&quot;&gt;MySQL 5.6 RC announced&lt;/a&gt;
this weekend &lt;a href=&quot;http://www.oracle.com/mysqlconnect&quot;&gt;by Tomas&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;The innodb_memcache daemon plugin is a plugin for the MySQL Server end contains an
embedded memcached. This embedded memcached is configured to use MySQL&#039;s InnoDB engine
as storage backend. By using this data stored inside an InnoDB table can be accessed
using memcache&#039;s key-value protocol. Back in the times of the previous blog post this 
was limited to data from a single table, which maps easily to the key-value nature 
of memcache but is a clear limitation. The InnoDB obviously knows that and improvd it:&lt;/p&gt; 
&lt;p&gt;A user may now define multiple configurations at the same time and therefore
access different tables at the same time - or the same table using different
key-columns as memcache key, for accessing the data the memcache key names will
then be prefixed by specially formatted configuration names.

&lt;/p&gt; 
&lt;p&gt;Let&#039;s take a look at an simple example. Assume we have this configuration inside
innodb_memcache.containers:&lt;/p&gt; 
&lt;pre&gt;      Name: prefix_test
      schema: test
      table: test
      key column: id
      key name: PRIMARY KEY
      value columns: lastname
&lt;/pre&gt; 
&lt;p&gt;We can then use the memcache configuration using a key like this:&lt;/p&gt; 
&lt;pre&gt;      set @@prefix_test.1 Schlüter
      get @@prefix_test.1
&lt;/pre&gt; 
&lt;p&gt;The first call will store my last name with id=1 in the test.test table.
For accessing multiple configurtions we simply add entries to the
containers list.&lt;/p&gt; 
&lt;p&gt;Of course we can still access miltiple columns, as in the previous version:&lt;/p&gt; 
&lt;pre&gt;   
      Name: test_first_last
      schema: test
      table: test
      key columns: id
      key name: PRIMARY
      value columns: firstname,lastname
&lt;/pre&gt; 
&lt;p&gt;And then we add my firstname:&lt;/p&gt; 
&lt;pre&gt; 
      set @@test_first_last.1 Johannes,Schlüter
      get @@test_first_last.1
&lt;/pre&gt; 
&lt;p&gt;The configurations above are, obviously, just a short introduction. For full
information please check the documentation.&lt;/p&gt; 
&lt;p&gt;Now this blog entry is tagged a	s PHP. Hs is that coming into play? - Well,
on the one side we have this fast memcache interface, which allows to 
access almost arbitrarry data from the database. On the other side we 
have  our PHP mysqlnd plugin interface where we can add special features,
like query caching or load balancing, transparently to any PHP application.
Why not combine those two things? - Good question. That&#039;s what we have done 
in the &lt;a href=&quot;http://pecl.php.net/mysqlnd_memcache&quot;&gt;PECL mysqlnd_memcache&lt;/a&gt;
PHP extension. This PHP extension is a plugin to mysqlnd intercepting queries 
sent to the server. In a quick analysis it tries to identfy whether an SQL 
statement can - transparently - be converted into memcache requests. We 
therefore exchange some computing power on the PHP server and gain more 
performance from the MySQL server. As SQL is a rather complex language and 
memcache is a quite limited key-value protocol this will only work for a 
limited subset of common queries though.&lt;/p&gt; 
&lt;p&gt;So let&#039;s take a look at some PHP code:&lt;/p&gt; 
&lt;pre&gt; 
      &amp;lt;?php
      $mysqli = new mysqli(&quot;localhost&quot;, &quot;usr&quot;, &quot;pass&quot;, &quot;test&quot;);
      $memcache = new memcached();
      $memcache-&amp;gt;addServer(&quot;localhost&quot;, 11211);
     
      mysqlnd_memcache_set($mysqli, $memcache);
      ?&amp;gt;
&lt;/pre&gt; 
&lt;p&gt;Here we ceate a MySQL connection using mysqli as well as a memcache connection
using the pecl/memcached extension. Instead of mysqli we could, as with any
mysqlnd plugin, use ext/mysql or the MySQL PDO driver. We then associate
the MySQL connection with the memcache connection. As a consequence of this
code the mysqlnd_memcache plugin will query the MySQL server for the current
memcache configuration. Subsequently it will analyse SQL queries sent to the
server:&lt;/p&gt; 
&lt;pre&gt;  
      &amp;lt;?php
      $q1 = $mysqli-&amp;gt;query(&quot;SELECT firstname, lastname FROM test WHERE id = 1&quot;);
      
      $q2 = $mysqli-&amp;gt;query(&quot;SELECT * FROM test&quot;);
      ?&amp;gt;
&lt;/pre&gt; 
&lt;p&gt;These are two normal queries and nothing special on first sight. In case
there&#039;s no error $q1 and $q2 will hold mysqli_result instances where
rows can be read using fetch_row() or in other provided ways. But there
are things going on in the back: The PHP extension will see that the first
one can be translated to a memcche request and then fetch the data using
this shortcut. The second call tries to read all data from the table. The
memcache protocol provides no way for doing that so this query will use the
&amp;quot;classic&amp;quot; way of sending the SQL to the MySQL server.&lt;/p&gt; 
&lt;p&gt;In order to be fast and limit the overhead - mind: we have to check any
query - we didn&#039;t add a full SQL parser to this plugin but the check is done
using a regular expression which will be enriched using data collected
from the MySQL Server. In case this reguar expression causes trouble 
it can be overriden when the inital association is established. There
are a few other caveats in the initial 1.0.0-beta reease available from
PECL therefore we&#039;d love to hear from you to see what you need and how
we can improve your MySQL experience!&lt;/p&gt; 
    </description>
</item>
<item>
    <title>Quick setup for PHP development trees</title>
    <link>http://schlueters.de/blog/archives/168-Quick-setup-for-PHP-development-trees.html</link>

    <description>
        &lt;p&gt;As PHP has moved to git recently everybody who works on the PHP source has to recreate his work environment. When working on PHP I have a few &lt;em&gt;requirements&lt;/em&gt; for my working dirs. For one I want to be able to use different branches (like 5.3, 5.4 and master) at the same time and I want to quickly test different PHP configurations, like builds using thread-safety or debug mode on or off.&lt;/p&gt; 
&lt;p&gt;A simple approach for this is to use out-of-tree builds, something like that:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;p&gt;$ git clone ....php-src.git&lt;br /&gt;$ (cd php-src &amp;amp;&amp;amp; ./buildconf)&lt;br /&gt;$ mkdir build-master-minimal&lt;br /&gt;$ cd build-master-minimal&lt;br /&gt;$ ../php-src/configure --disable-all&lt;br /&gt;$ make&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;This allows having both requirements full-filled as you can have build dirs for each branch and each configuration. Nice, but in the long run quite confusing as you always have to make sure php-src has the correct branch checked out, matching the build dir you&#039;re currently building in, else you will create a mess.&lt;/p&gt; 
&lt;p&gt;Thankfully there is a nice solution to &lt;a href=&quot;https://wiki.php.net/vcs/gitfaq#multiple_working_copies_workflow&quot;&gt;have multiple checkouts using git-new-workdir&lt;/a&gt;. So one can easily setup the branches and build dirs. Now it&#039;s still quite some repetitive work to create a structure using different branches and a set of different build dirs for each branch. Therefore I&#039;ve created a simple shell script to do this quickly on my different machines and &lt;a href=&quot;https://github.com/johannes/create-php-workdir&quot;&gt;pushed the script to github&lt;/a&gt; in case anybody wants to have a similar structure, and maybe improve the script. But be warned: The script is really an ad hoc thing for me to get started.&lt;br /&gt;&lt;/p&gt; 
    </description>
</item>
<item>
    <title>Some videos</title>
    <link>http://schlueters.de/blog/archives/167-Some-videos.html</link>

    <description>
        &lt;p&gt;Over the years a few videos of my presentations and some interviews were published. I&#039;ve collected the ones I found and put them on &lt;a href=&quot;/yt/?piwik_campaign=blogvideos&quot;&gt;a single web page&lt;/a&gt;. The oldest is from 2009 the latests just from February this year. Enjoy.&lt;/p&gt; 
&lt;p&gt; If you have another video which I missed: Please let me know!&lt;br /&gt;&lt;/p&gt; 
    </description>
</item>
<item>
    <title>Testing persistent connection and thread-safety features in PHP</title>
    <link>http://schlueters.de/blog/archives/166-Testing-persistent-connection-and-thread-safety-features-in-PHP.html</link>

    <description>
        &lt;p&gt;
By default PHP provides shared-nothing environments to ensure that whatever happens to PHP&#039;s state in one request has no effect on other requests, so all function tables are cleaned up, all file handles are closed etc. In a few rare cases this is not what people like, for that PHP introduced &amp;quot;&lt;a href=&quot;http://php.net/features.persistent-connections&quot;&gt;persistent connections&lt;/a&gt;&amp;quot; of different kinds. Testing those is a bit annoying as you have to configure a webserver and ensure to hit the same instance over the course of a test and then use a load generator, probably one which can detect a failure. Additionally by having a webserver in the game there is more code being executed, which might mean an additional source for trouble while debugging. An alternative might be using FastCGI, while that adds it&#039;s own issues for such a test.&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;To solve this for myself I, some time ago, wrote a PHP SAPI module called &lt;a href=&quot;https://github.com/johannes/pconn-sapi&quot;&gt;pconn&lt;/a&gt; and pushed it to github. (A SAPI is the component in PHP which implements the communication with the web server or whatever triggers PHP requests) The general idea was to have a lightweight SAPI which does nothing but emulate a bunch of requests. I had it some where on my list of things to blog about, but well, low prio.&lt;/p&gt; 
&lt;p&gt;Now some time later it seems like Derick was doing some stuff with persistent connections, too, and figured that the new embedded web server is a good thing for such tests, too. While he didn&#039;t know about my solution, as one could see in a short discussion on twitter we had:&lt;br /&gt;&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;p&gt;In other news, the new CLI web server in PHP 5.4 is brilliant for debugging issues with extensions that span more than one request.&lt;/p&gt;— Derick Rethans (@derickr) &lt;a data-datetime=&quot;2012-03-15T10:50:49+00:00&quot; href=&quot;https://twitter.com/derickr/status/180244655743565824&quot;&gt;March 15, 2012&lt;/a&gt; 
&lt;/blockquote&gt; 
&lt;blockquote&gt; 
&lt;p&gt;@&lt;a href=&quot;https://twitter.com/derickr&quot;&gt;derickr&lt;/a&gt; for that you could also use &lt;a href=&quot;https://t.co/CehrUb8K&quot; title=&quot;https://github.com/johannes/pconn-sapi&quot;&gt;github.com/johannes/pconn…&lt;/a&gt; which also does multithreading &lt;img src=&quot;http://schlueters.de/blog/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;&lt;/p&gt;— Johannes Schlüter (@phperror) &lt;a href=&quot;https://twitter.com/phperror/status/180299729903697921&quot; data-datetime=&quot;2012-03-15T14:29:40+00:00&quot;&gt;March 15, 2012&lt;/a&gt; 
&lt;/blockquote&gt; 
&lt;blockquote&gt; 
&lt;p&gt;@&lt;a href=&quot;https://twitter.com/phperror&quot;&gt;phperror&lt;/a&gt;: You need to write about that stuff :-þ&lt;/p&gt;— Derick Rethans (@derickr) &lt;a data-datetime=&quot;2012-03-15T14:35:34+00:00&quot; href=&quot;https://twitter.com/derickr/status/180301217052901376&quot;&gt;March 15, 2012&lt;/a&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Now I&#039;ve contradicted myself: Above I was proudly writing about this being lightweight and easy to debug, but in the tweet I mentioned threading. And well threading always includes lots of trouble to code. But yeah, over time I figured out that this was a good foundation to solve a second issue which has has to be done for PHP: PHP can be run in threaded environments, which in general is not advised. When doing that the old party rule applies: What happens in a thread stays in thread. Different threads should not impact the requests handled in other threads. Now testing for race conditions is even harder than testing persistent connections and additional web server code hurts even more. So my little SAPI became a lot bigger and can now be compiled in two modes. Either simple and short in non threaded mode or with all the extra stuff in threaded-mode which will allow running PHP requests in parallel threads in loops.&lt;/p&gt;
&lt;p&gt;In case you find yourself working on some PHP extensions where this might help: Check the github repository and the &lt;a href=&quot;https://github.com/johannes/pconn-sapi/blob/master/README&quot;&gt;README&lt;/a&gt; and drop me a line if anything is unclear.&lt;/p&gt; 
    </description>
</item>
<item>
    <title>Upcoming talks</title>
    <link>http://schlueters.de/blog/archives/165-Upcoming-talks.html</link>

    <description>
        &lt;p&gt;Over the last few weeks I had been quite silent, but that&#039;s about to change: Over the next few weeks I&#039;ll give a few presentations. Feel free to join any of those.&lt;/p&gt; 
&lt;ul&gt; 
&lt;li&gt;January, 18th: &lt;a href=&quot;http://www.mysql.com/news-and-events/web-seminars/display-680.html&quot;&gt;Erstellung hochperformanter PHP-Anwendungen mit MySQL&lt;/a&gt; (German)&lt;br /&gt;MySQL Webinar, Online&lt;/li&gt; 
&lt;li&gt;February, 9th: &lt;a href=&quot;http://www.oracle.com/webapps/events/ns/EventsDetail.jsp?p_eventId=148478&amp;amp;src=7314534&amp;amp;src=7314534&amp;amp;Act=240&quot;&gt;MySQL Konnectoren&lt;/a&gt; (German)&lt;br /&gt;OTN Developer Day: MySQL, Frankfurt, Germany&lt;/li&gt; 
&lt;li&gt;February 24th/25th: &lt;a href=&quot;http://www.phpconference.co.uk/talk/php-under-hood&quot;&gt;PHP under the hood&lt;/a&gt; (English)&lt;br /&gt;PHP UK Conference, London, UK&lt;/li&gt; 
&lt;/ul&gt; 
    </description>
</item>
<item>
    <title>High Performance PHP Session Storage on Scale</title>
    <link>http://schlueters.de/blog/archives/164-High-Performance-PHP-Session-Storage-on-Scale.html</link>

    <description>
        &lt;p&gt;One of the great things about the HTTP protocol, besides &lt;a href=&quot;http://tools.ietf.org/html/rfc2324&quot;&gt;status code 418&lt;/a&gt;, is that it&#039;s stateless. A web server therefore is not required to store any information on the user or allocate resources for a user after the individual request is done. By that a single web server can handle many many many different users easily, and well if it can&#039;t anymore one can add a new server, put a simple load balancer in front and scale out. Each of those web servers then handles its requests without the need for communication which leads to linear scaling (assuming network provides enough bandwidth etc.).&lt;/p&gt; 
&lt;p&gt;Now the Web isn&#039;t used for serving static documents only anymore but we have all these fancy web apps. And those applications often have the need for a state. The most trivial information they need is the current user. HTTP is a great protocol and provides a way to do authentication which works well with its stateless nature - unfortunately this authentication is implemented badly in current clients. Ugly popups, no logout button, ... I don&#039;t have to tell more I think. For having nicer login systems people want web forms. Now the stateless nature of HTTP is a problem: The user may login and then browse around. On later requests it should still be known who that user is - with a custom HTML form based login alone this is not possible. A solution might be cookies. At least one might think so for a second. But setting a cookie &amp;quot;this is an authorized user&amp;quot; alone doesn&#039;t make sense as it could easily be faked. Better is to simply store a random identifier in a cookie and then keep a state information on the server. Then all session data is protected and only the user who knows this random identifier is authenticated. If this identifier is wisely chosen and hard to guess this works quite well. Luckily this is a mostly PHP- and MySQL-focused blog and as PHP is a system for building web applications this functionality is part of the core language: The &lt;a href=&quot;http://php.net/session&quot;&gt;PHP session module&lt;/a&gt;.&lt;/p&gt; 
&lt;p&gt;The session module, which was introduced in PHP 4, partly based on work on the famous phplib library, is quite a fascinating piece of code. It is open and extendable in so many directions but still so simple to use that everybody uses it, often newcomers learn about it on their first day in PHP land. Of course you can not only store the information whether the user is logged in but cache some user-specific data or keep the state on some transactions by the user, like multi-page forms or such.&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;In its default configuration session state will be stored on the web server&#039;s file system. Each session&#039;s data in its own file in serialized form. If the filesystem does some caching or one uses a ramdisk or something this can be quite efficient. But as we suddenly have a state on the web server we can&#039;t scale as easily as before anymore: If we add a new server and then route a user with an existing session to the new server all the session data won&#039;t be there. That is bad. This is often solved by a configuration of the load balancer to route all requests from the same user to the same web server. In some cases this works quite ok, but it is often seen that this might cause problems. Let&#039;s assume you want to take a machine down for maintenance. All sessions there will die. Or imagine there&#039;s a bunch of users who do complex and expensive tasks - then one of your servers will have a hard time, giving these users bad response times which feels like bad service, even though your other systems are mostly idle.&lt;/p&gt; 
&lt;p&gt;A nice solution for this would be to store the sessions in a central repository which can be accessed from all web servers.&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://schlueters.de/blog/archives/164-High-Performance-PHP-Session-Storage-on-Scale.html#extended&quot;&gt;Continue reading &quot;High Performance PHP Session Storage on Scale&quot;&lt;/a&gt;
    </description>
</item>
<item>
    <title>mysqli_result iterations</title>
    <link>http://schlueters.de/blog/archives/163-mysqli_result-iterations.html</link>

    <description>
        &lt;p&gt;For the last few months I had quite a few MySQL blog posts and didn&#039;t have anything from my &amp;quot;&lt;a href=&quot;http://schlueters.de/blog/plugin/tag/php%FFnext&quot;&gt;new features in PHP [trunk|5.4]&lt;/a&gt;&amp;quot; series. This article is a bridge between those two. The &lt;a href=&quot;http://svn.php.net/viewvc/php/php-src/branches/PHP_5_4/NEWS?revision=HEAD&amp;amp;view=markup&quot;&gt;PHP 5.4 NEWS&lt;/a&gt; file has a small entry:&lt;/p&gt; 
&lt;p&gt; &lt;/p&gt; 
&lt;blockquote&gt;MySQLi: Added iterator support in MySQLi. mysqli_result implements Traversable. (Andrey, Johannes)&lt;br /&gt;&lt;/blockquote&gt; 
&lt;p&gt;From the outside it is a really small change and easy to miss. The mentioned class, mysqli_result, implements an interface which adds no new methods. What once can&#039;t see is that this relates to some internal C-level functions which can be called by the engine for doing a foreach iteration on objects of this class. So with PHP 5.4 you don&#039;t have to use an &amp;quot;ugly&amp;quot; while construct anymore to fetch rows from a mysqli result but can simply do a foreach:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&lt;a title=&quot;&quot; target=&quot;&quot; href=&quot;http://php.net/mysqli_report&quot;&gt;mysqli_report&lt;/a&gt;(MYSQLI_REPORT_STRICT);
try {
    $mysqli = new mysqli(/* ... */);
    foreach ($myslqi-&amp;gt;&lt;a title=&quot;&quot; target=&quot;&quot; href=&quot;http://php.net/mysqli.query&quot;&gt;query&lt;/a&gt;(&quot;SELECT a, b, c FROM t&quot;) as $row) {
        /* Process $row which is an associative array */
    }
} catch (mysqli_sql_exception $e) {
    /* an error happened ... */
}
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;I&#039;m configuring mysqli in a way to throw exceptions on error. This is useful in this case as mysqli::query() might return false in the case of an error. Passing false to a foreach will give a fatal error, so I&#039;d need a temporary variable and a check in front of the foreach loop, with exceptions I simply do the error handling in the catch block.&lt;/p&gt; 
&lt;p&gt;One thing to note is that mysqli is using buffered results (&amp;quot;store result&amp;quot;) by default. If you want to use unbuffered result sets (&amp;quot;use result&amp;quot;) you can easily do that by setting the flag accordingly:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;foreach ($myslqi-&amp;gt;query(&quot;SELECT a, b, c FROM t&quot;, MYSQLI_USE_RESULT) as $row) {
    /* ... */
}
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;People who are advanced with iterators in PHP might ask &amp;quot;Why did you implement Traversable only, not &lt;a href=&quot;http://php.net/iterator&quot;&gt;Iterator&lt;/a&gt;?&amp;quot; - the main reason is that we simply didn&#039;t want to. The mysqli_result class already has quite a few methods and we didn&#039;t want to make the interface confusing. If you need an Iterator class for some purpose you can simply wrap mysqli_result in an &lt;a href=&quot;http://php.net/IteratorIterator&quot;&gt;IteratoIterator&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt; 
    </description>
</item>
<item>
    <title>mysqlnd_qc and Symfony2</title>
    <link>http://schlueters.de/blog/archives/162-mysqlnd_qc-and-Symfony2.html</link>

    <description>
        &lt;p&gt;Previously I was writing about combining &lt;a href=&quot;http://schlueters.de/blog/archives/161-Symfony-2-and-mysqlnd.html&quot;&gt;Symfony2 and mysqlnd&lt;/a&gt; to get more statistics on what is going on below the surface in the database communication when using a Symfony2 application via the Symfony2 profiler. Now that&#039;s not all that can be done and I gave some ideas for extending this. One idea was adding mysqlnd_qc support. mysqlnd_qc is the client side query cache plugin for mysqlnd. This provides a client-side cache for query results transparently without changing the application.&lt;/p&gt; 
&lt;p&gt; 
&lt;iframe width=&quot;670&quot; height=&quot;550&quot; src=&quot;/presentations/#p=20101030_barcelona_MySQL_Caching&quot;&gt;&amp;amp;amp;amp;lt;span id=&amp;amp;amp;amp;quot;XinhaEditingPostion&amp;amp;amp;amp;quot;&amp;amp;amp;amp;gt;&amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;lt;span id=&amp;amp;amp;amp;amp;amp;quot;XinhaEditingPostion&amp;amp;amp;amp;amp;amp;quot;&amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;lt;/span&amp;amp;amp;amp;amp;amp;gt;&lt;/iframe&gt; 
&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://schlueters.de/blog/uploads/screenshots/symfony2_mysqlnd_qc.png&quot; class=&quot;serendipity_image_link&quot;&gt;&lt;!-- s9ymdb:70 --&gt;&lt;img style=&quot;width: 162px; height: 62px;&quot; src=&quot;http://schlueters.de/blog/uploads/screenshots/symfony2_mysqlnd_qc.serendipityThumb.png&quot; class=&quot;serendipity_image_right&quot; /&gt;&lt;/a&gt;A nice thing about this plugin, for this context here, is the function &lt;a href=&quot;http://php.net/mysqlnd_qc_get_query_trace_log&quot;&gt;mysqlnd_qc_get_query_trace_log()&lt;/a&gt; which provides information about each query being executed. Not only the query string but also some timing (execution time, result storage time) and a stack trace so you can see where in the code a query was executed. I&#039;ve added this functionality to the &lt;a href=&quot;https://github.com/johannes/JSMysqlndBundle&quot;&gt;JSMysqlndBundle&lt;/a&gt; as you can see in the &lt;a href=&quot;http://schlueters.de/blog/uploads/screenshots/symfony2_mysqlnd_qc.png&quot; class=&quot;serendipity_image_link&quot;&gt;screenshot&lt;/a&gt;. I won&#039;t show a screenshot about what happens if you click the stacktrace link as this currently breaks the layout a bit, but maybe somebody wants to make this nicer? - Or maybe even feels motivated to make it even better using &lt;a href=&quot;http://docs.php.net/manual/en/book.mysqlnd-uh.php&quot;&gt;mysqlnd_uh&lt;/a&gt; (which, as of today, has docs, thanks to Ulf) Feel free to contact me to talk about ideas! &lt;img src=&quot;http://schlueters.de/blog/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;&lt;br /&gt;&lt;/p&gt; 
    </description>
</item>
<item>
    <title>Symfony 2 and mysqlnd</title>
    <link>http://schlueters.de/blog/archives/161-Symfony-2-and-mysqlnd.html</link>

    <description>
        &lt;p&gt;In a &lt;a href=&quot;http://schlueters.de/blog/archives/159-mysqlnd-plugins-and-json.html&quot;&gt;previous blog posting&lt;/a&gt; I was mentioning that I&#039;m working on a small hobby PHP project. As I&#039;m using this project to update myself to current frameworks I&#039;ve decided to use Symfony2. Symfony provides a nice feature, which is the Symfony Profilier, an extensive logging and reporting system for Symfony2 developers to understand what&#039;s going on. A part of it is the Doctrine query logger which lists all database queries executed by Doctrine and their execution time.&lt;/p&gt; 
&lt;p&gt;&lt;a href=&quot;http://schlueters.de/blog/uploads/screenshots/symfony_mysqlnd.png&quot; class=&quot;serendipity_image_link&quot;&gt;&lt;!-- s9ymdb:69 --&gt;&lt;img width=&quot;110&quot; height=&quot;109&quot; src=&quot;http://schlueters.de/blog/uploads/screenshots/symfony_mysqlnd.serendipityThumb.png&quot; class=&quot;serendipity_image_left&quot; /&gt;&lt;/a&gt;This is nice but when we&#039;re using mysqlnd in our PHP build we have more information available. &amp;quot;So why not use that information,&amp;quot; I thought and built a new bundle for Symfony2 doing exactly that. The &lt;a href=&quot;http://github.com/johannes/JSMysqlndBundle&quot;&gt;JSMysqlndBundle&lt;/a&gt; will take all the &lt;a href=&quot;http://php.net/mysqlnd.stats&quot;&gt;150 or so statistic values&lt;/a&gt; collected, so they can be seen in the profiler (click screenshot for a larger view).&lt;/p&gt; 
&lt;p&gt;As this is the initial value, a quick Sunday morning hack, it has not all features I can imagine. Things one could do include&lt;/p&gt; 
&lt;ul&gt; 
&lt;li&gt;Provide information on caching decisions and behavior when &lt;a href=&quot;http://php.net/mysqlnd_qc&quot;&gt;mysqlnd_qc&lt;/a&gt; is used&lt;/li&gt; 
&lt;li&gt;Provide replication-related decisions when the new &lt;a href=&quot;http://php.net/mysqlnd_ms&quot;&gt;mysqlnd replication and load balancing plugin&lt;/a&gt; is used&lt;/li&gt; 
&lt;li&gt;Take David&#039;s &lt;a href=&quot;http://blog.mayflower.de/archives/578-MySQLnd-Plugins-Writing-a-MySQL-Query-Logger-in-PHP.html&quot;&gt;mysqlnd_uh-based query logging&lt;/a&gt; ideas and provide more information on any executed query&lt;/li&gt; 
&lt;li&gt;....&lt;/li&gt; 
&lt;/ul&gt;Any takers? - Code away!&lt;br /&gt; 
    </description>
</item>
<item>
    <title>MySQL Query Analyzer and PHP</title>
    <link>http://schlueters.de/blog/archives/150-MySQL-Query-Analyzer-and-PHP.html</link>

    <description>
        &lt;p&gt;Today we&#039;ve released a few things for PHP and MySQL users: One is the first (and probably only) beta of the &lt;a href=&quot;http://pecl.php.net/mysqlnd_ms&quot;&gt;mysqlnd_ms plugin&lt;/a&gt; for MySQL Replication and Load Balancing support and the first GA version of a PHP plugin for the Query Analyzer of the MySQL Enterprise Monitor.&lt;/p&gt; 
&lt;p&gt;Ulf &lt;a href=&quot;http://blog.ulf-wendel.de/&quot;&gt;blogged a lot&lt;/a&gt; about mysqlnd_ms, so I don&#039;t have to repeat him here. what I want to talk about is the other one. So what is that about?&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;When running a PHP-based application with MySQL it is often quite interesting to see what actually happens on the database sever. Besides monitoring of the system load etc. it is often interesting to see what queries are actually executed and which of them are expensive. A part of MySQL Enterprise Monitor is the &lt;a href=&quot;http://mysql.com/products/enterprise/query.html&quot;&gt;MySQL Query Analyzer&lt;/a&gt; which helps answering these questions.&lt;/p&gt; 
&lt;p&gt;Traditionally the MySQL Query Analyzer&amp;#160; was based on MySQL Proxy which is configured to sit between the application and the MySQL server and collects all relevant data.&lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;Now in the new &lt;a href=&quot;http://blogs.oracle.com/mysqlenterprise/entry/mysql_enterprise_monitor_2_33&quot;&gt;2.3.7 release&lt;/a&gt; of the MySQL Enterprise Monitor we have enhanced this for PHP users: We now provide a plugin which can be loaded in PHP and which will provide data for the Query Analyzer directly from within PHP.&lt;/p&gt; 
&lt;p&gt; &lt;!-- s9ymdb:67 --&gt;&lt;img width=&quot;1053&quot; height=&quot;690&quot; src=&quot;http://schlueters.de/blog/uploads/screenshots/mem_quan_php1.png&quot; class=&quot;serendipity_image_center&quot; style=&quot;max-width:100%&quot; /&gt;&lt;/p&gt; 
&lt;p&gt;By that we don&#039;t only reduce the latency for the data collection but we can provide more information about the current environment.&lt;/p&gt; 
&lt;p&gt;&lt;!-- s9ymdb:68 --&gt;&lt;img width=&quot;837&quot; height=&quot;694&quot; src=&quot;http://schlueters.de/blog/uploads/screenshots/mem_quan_php2.png&quot; class=&quot;serendipity_image_center&quot; /&gt; &lt;/p&gt; 
&lt;p&gt;In the query detail window you now don&#039;t only see general query statistics but also a stack trace from the application, so you can immediately identify the part of the application which should be improved. So above you can see a few screenshots I made from this server showing some insights of this blog where I was testing the plugin.&lt;/p&gt; 
&lt;p&gt;If you want to learn more checkout the &lt;a href=&quot;http://dev.mysql.com/doc/mysql-monitor/2.3/en/mem-qanal-using-cphp.html&quot;&gt;documentation&lt;/a&gt; and &lt;a href=&quot;http://mysql.com/products/enterprise/monitor.html&quot;&gt;product pages&lt;/a&gt;. Hope you like it!&lt;br /&gt;&lt;/p&gt; 
    </description>
</item>
<item>
    <title>Direct MySQL Stream Access - Revised</title>
    <link>http://schlueters.de/blog/archives/160-Direct-MySQL-Stream-Access-Revised.html</link>

    <description>
        &lt;p&gt;Roughly three years ago I was writing about &lt;a href=&quot;http://schlueters.de/blog/archives/86-Direct-MySQL-Stream-Access.html&quot;&gt;Direct MySQL Stream Access&lt;/a&gt; - a way to access the low-level stream PHP&#039;s mysqlnd library is using. Back then this had been a patch against PHP&#039;s mysqli extension. As such a feature is quite dangerous (you can easily mess with the connection state which confuses mysqlnd and/or the MySQL server) we didn&#039;t push it into the main PHP tree. Now three years later it&#039;s time to look at this again as we don&#039;t need to patch PHP anymore.&lt;/p&gt; 
&lt;p&gt;Since the mentioned patch was written mysqlnd got a plugin interface about which &lt;a href=&quot;http://schlueters.de/blog/plugin/tag/mysqlnd+plugins&quot;&gt;I was talking before&lt;/a&gt;. This plugin-interface, especially in the version of PHP 5.4, makes it trivial to implement this feature.&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;PHP_FUNCTION(mysqlnd_to_stream)
{
&amp;#160;&amp;#160;&amp;#160; zval *conn_zv;
&amp;#160;&amp;#160;&amp;#160; MYSQLND *conn;

&amp;#160;&amp;#160;&amp;#160; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, &quot;z&quot;, &amp;amp;conn_zv) == FAILURE) {
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; return;
&amp;#160;&amp;#160;&amp;#160; }

&amp;#160;&amp;#160;&amp;#160; if (!(conn = zval_to_mysqlnd(conn_zv))) {
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; php_error_docref(NULL TSRMLS_CC, E_WARNING,
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &quot;Passed variable is no mysqlnd based connection&quot;);
&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; RETURN_FALSE;
&amp;#160;&amp;#160;&amp;#160; }

&amp;#160;&amp;#160;&amp;#160; php_stream_to_zval(conn-&amp;gt;net-&amp;gt;stream, return_value);
}
&amp;#160;&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;If you take a function like the one shown above and add some general PHP infrastructure you are done. The key function here is the function &lt;em&gt;MYSQLND* zval_to_mysqlnd(zval *connection)&lt;/em&gt; which takes a PHP variable as parameter and in case it is a MySQL connection (ext/mysql, mysqli or pdo_mysql) will return the corresponding MYSQLND pointer which gives access to the stream which then has to be packed into a PHP variable, again. The nice thing, compared to the old version is not only that it is a plugin which can be loaded into PHP as shared extension via php.ini but also that it works with all MySQL extensions, not only mysqli as the one before.&lt;/p&gt; 
&lt;p&gt;You can &lt;a href=&quot;http://schlueters.de/blog/uploads/code/mysqlnd_to_stream.tar.bz2&quot;&gt;download the complete source&lt;/a&gt;, but be warned: This is experimental stuff and not supported in any way, but I hope good enough to get a feeling what&#039;s possible with mysqlnd.&lt;br /&gt;&lt;/p&gt; 
    </description>
</item>
<item>
    <title>mysqlnd plugins and json</title>
    <link>http://schlueters.de/blog/archives/159-mysqlnd-plugins-and-json.html</link>

    <description>
        &lt;p&gt;Some time ago I was already writing about the &lt;a href=&quot;http://schlueters.de/blog/archives/146-mysqlnd-plugins-for-PHP-in-practice.html&quot;&gt;power included with mysqlnd plugins&lt;/a&gt; and how they can they can be used transparently to help you with your requirements without changing your code. But well, as mysqlnd plugins in fact are regular PHP extensions they can export functions to the PHP userland and providing complete new functionality.&lt;/p&gt; 
&lt;p&gt;In my spare time I&#039;m currently writing a shiny Web 2.0 application where I&#039;m heavily using AJAX-like things, so what I do quite often in this application is, basically this: Check some pre-conditions (permissions etc.) then select some data from the database, do a fetch_all to get the complete result set as an array and run it through json_encode; or to have it in code:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
$m = new MySQLi(/*...*/);
check_whether_the_user_is_checked_in_and_allowed_to_see_this();
$result = $m-&amp;gt;query(&quot;SELECT a,b,c,d FROM t WHERE e=23&quot;);
echo json_encode($result-&amp;gt;fetch_all());
?&amp;gt;
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Of course that example is simplified as I&#039;m using the Symfony 2 framework for this project. When writing a similar function for the 5th time I wondered whether I really need to create the temporary array and all these temporary elements in it.&lt;/p&gt; 
&lt;p&gt;So I wrote a mysqlnd plugin.&lt;/p&gt; 
&lt;p&gt;The mysqlnd_query_to_json plugin (hey what a name!) provides a single function, mysqlnd_query_to_json(), which takes two parameters, a connection identifier and an SQL query, and returns a JSON string containing the result set. The connection identifier can be a mysql resource, a mysqli object or even a PDO object. The resulting JSON string will be created directly from the network buffer without the need of temporary complex structures. Using the above example would create code like this:&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;pre&gt;&amp;lt;?php
$m = new MySQLi(/*...*/);
check_whether_the_user_is_checked_in_and_allowed_to_see_this();
echo mysqlnd_query_to_json($m, &quot;SELECT a,b,c,d FROM t WHERE e=23&quot;);
?&amp;gt;
&lt;/pre&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;The plugin, which you can &lt;a href=&quot;http://schlueters.de/blog/uploads/code/mysqlnd_query_to_json.tar.bz2&quot;&gt;find here&lt;/a&gt;, requires PHP 5.4 and has a few limitations as it knows nothing about MySQL bitfields or escaping of unicode characters for creating fully valid JSON data and Andrey called it, for good reasons, a hack. Neither did I benchmark it, yet as I merely share it to show what&#039;s possible and maybe start some discussion on what is actually needed.&lt;/p&gt; 
&lt;p&gt;If you want to learn more on these topics I also suggest to check the &lt;a href=&quot;http://www.mysql.com/news-and-events/web-seminars/&quot;&gt;MySQL Webinar page&lt;/a&gt; frequently as Ulf is going to hold a Webinar on myslqnd plugins in October!&lt;br /&gt;&lt;/p&gt; 
    </description>
</item>
<item>
    <title>Improvements for PHP application portability in PHP.next</title>
    <link>http://schlueters.de/blog/archives/156-Improvements-for-PHP-application-portability-in-PHP.next.html</link>

    <description>
        &lt;p&gt;I was writing about &lt;a href=&quot;http://schlueters.de/blog/plugin/tag/php%FFnext&quot;&gt;PHP.next before&lt;/a&gt;, many things improved there meanwhile. Most notably we have a committed version number: The next PHP release will be called PHP 5.4. The topic I want to talk about today is &amp;quot;Improved application portability&amp;quot; which covers multiple small changes which aim at making it simpler for developers to write applications working on any PHP setup.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Separating &lt;em&gt;&amp;lt;?=&lt;/em&gt; from &lt;em&gt;short_open_tags&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;PHP knows quite a few ways to separate PHP code from surrounding text (usually HTML), most applications use &lt;em&gt;&amp;lt;?php&lt;/em&gt; as that works on every system. There is a short form of this, &lt;em&gt;&amp;lt;?&lt;/em&gt;, which can be disabled using php.ini&#039;s short_open_tags setting. Being able to disable this is important when embedding PHP code into XML documents containing XML processing instructions. Now we also have &lt;em&gt;&amp;lt;?=&lt;/em&gt; which, basically, is a shortcut for &lt;em&gt;&amp;lt;?php echo&lt;/em&gt;. This tag is useful when using PHP as templating language as it prevents cluttered code. The issue in current version of PHP is that this is bound to short_open_tags, so portable applications can&#039;t rely on it. But PHP 5.4 will bring the solution: &lt;em&gt;&amp;lt;?=&lt;/em&gt; will always be there, independently from short_open_tags. Yay!&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;No more magic_quotes&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;In the old times it was easy to write code using PHP.&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;p&gt;&amp;lt;?php&lt;br /&gt;$q = mysql_query(&amp;quot;SELECT * FROM t WHERE name = &#039;$name&#039; &amp;quot;);&lt;br /&gt;?&amp;gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;And you had, thanks to register_globals, some data to work on and this was mostly secure as PHP automatically escaped request data. But well this escaping worked only in a few cases acceptable good. Besides not knowing anything about other encodings or DBMS-specific escape sequences it also failed for non-string values as in&lt;/p&gt; 
&lt;blockquote&gt; 
&lt;p&gt;&amp;lt;?php&lt;br /&gt;
$q = mysql_query(&amp;quot;SELECT * FROM t WHERE id = $id &amp;quot;);&lt;br /&gt;
?&amp;gt;&lt;/p&gt; 
&lt;/blockquote&gt; 
&lt;p&gt;Where the external value wasn&#039;t escaped. So portable applications, which aim at being secure nowadays have to check whether magic_quote_gpc is enabled, then remove the &amp;quot;bad&amp;quot; quotes and then finally escape again using the appropriate way. That&#039;s quite&amp;#160; an annoyance and doing this the wrong way can cause bad bugs (like forcing such a replacement logic in an endless recursion by providing arrays) So nobody really likes magic_quotes. So with PHP 5.4 they are gone. No more need to worry about them. Use the proper escaping and you&#039;re done. Wonderful. Only issue: Legacy applications might rely on magic_quotes so when upgrading PHP make sure the application does the required escaping itself so almost-secure applications won&#039;t become insecure.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Dropped explicit --enable-zend-multibyte compile-time option&lt;/strong&gt;&lt;/p&gt; 
&lt;p&gt;Especially in Asia people use multi-byte encodings which aren&#039;t ASCII-compatible so mixing them with PHP code might be hard. In current versions of PHP there is a compile-time option to enable a special multibyte mode for the engine which will handle this in the engine so PHP code can be provided using these encodings. By this portable applications had a hard time due to this conversion (not) being done. Thanks to the work by Dmitry and Moriyoshi this mode is now always enabled whithout penalty for people not depending on it and the extended functionality from mbstring can be provided as a shared module. By this distributors can provide a single build which will work for everybody.&lt;/p&gt; 
&lt;p&gt;&lt;strong&gt;Closing remarks&lt;/strong&gt; &lt;br /&gt;&lt;/p&gt; 
&lt;p&gt;As always in this series: Be aware that things discussed here might change. Please try out the current snapshot of PHP 5.4 and test it with your applications. No we can still fix backwards compatibility breaks. fixing them after a release will possibly break it for people depending on the new behavior. Happy coding!&lt;br /&gt;&lt;/p&gt; 
    </description>
</item>

</channel>
</rss>
