<?xml version="1.0"?>
<?xml-stylesheet 
 href="http://www.w3.org/2000/08/w3c-synd/style.css" type="text/css"
?>
<rss version="0.91"><channel><title>Planet PEAR</title><link>http://planet.pear.php.net</link><description>People blogging about PEAR</description><language>en</language><item><title>Mitigating the risk of license changes - Lukas Kahwe Smith</title><link>http://www.pooteeweet.org/blog/0/1084</link><pubDate>Wed, 14 May 2008 08:29:08 +0000</pubDate><description><![CDATA[<p>This is just a very short note about the recent <a href="http://extjs.com/forum/showthread.php?t=33096" >license change</a> from LGPL to GPL made by the author of extJS. When choosing an open source product make sure that the contributors are fragmented across enough organizations to prevent any chance of being able to do a license change. If that is not the case make sure that the community is large enough so that you have a good chance at succeeding with a fork if the need arises. In the case of extJS the later seems to be the <a href="http://www.akbkhome.com/blog.php/View/164/ExtJs__talking_forking.html" >case</a>. As such the license change itself is not soooo big an issue, since a lot of people do not consider their frontend code to be proprietary anyways. The source is there for all to see. So for the most part people are fine considering their frontend to be licensed under the GPL. That being said, extJS guys are trying to <a href="http://extjs.com/products/license.php" >make people believe</a> that using extJS on the frontend has any effect on the backend licensing. Kinda reminds me of the MySQL client license stunt and the days when MySQL sales reps intentionally confused people about the GPL .. good that those days are over.</p>

]]></description></item><item><title>Prepared statement gotchas - Lukas Kahwe Smith</title><link>http://www.pooteeweet.org/blog/0/1083</link><pubDate>Wed, 14 May 2008 06:19:04 +0000</pubDate><description><![CDATA[<p>I spotted an interesting blog post over on <a href="http://www.planetosdb.org/" >Planet OSDB</a> about <a href="http://www.depesz.com/index.php/2008/05/10/prepared-statements-gotcha/" >prepared statements gotchas</a>. It illustrates very well the issue that prepared statements have been plagued with since their inception: namely that they can severely hurt performance (even though they are considered to improve performance by most people).</p>

<p>Just briefly: Why do we even care for prepared statements? For stateless web applications the benefits are mainly protection against SQL injection and better readability. In some rare cases in theory also better performance if the same statement is executed multiple times in the same request. The disadvantage is that for most web applications queries are rarely executed more than once and therefore the separation of parsing/planning and execution just means that there is an additional roundtrip to the database. Also in very long running database sessions the prepared query plan could get outdated, which could also spell disaster for performance. or in other words: prepared statements are no silver bullet.</p>

<p>The problem described in the above blog post is of course since the idea behind prepared statements is to separate the parsing and planning stage from the actual data that is to be used in the WHERE clause of the query. Modern cost based optimizers keep detailed statistics about data distribution, which is difficult to leverage if there is no data available during the planning stage. This blog post however focuses on another aspect that is not yet relevant to MySQL, since there is no support for partial indexes in MySQL just yet. However RDBMS like PostgreSQL do support partial indexes. Again since the data is missing during the planning stage, the database is unable to determine if an existing partial index matches.</p>

<p>So what can be done to fix this if we do want to stick with prepared statements? On the user side one thing one can do is move the relevant filtering data into the prepared statement itself. This of course means that you loose the benefit of the prepared statement for the relevant pieces of data, but it might be an acceptable balance. Of course if this data contains user supplied data, you now need to manually make sure that the data is safe.</p>

<p>The other approach is simply switching to emulated prepared statements, which most database layers support (like PDO). This also fixes the issue of adding a second round trip to the database for every execution. However it means you put yourself at the mercy of the parser embedded in the database layer you are using. Actually in the case of PDO there is little chance to get around that anyways. Worse yet, the PDO parser is known to be <a href="http://pecl.php.net/bugs/bug.php?id=7033" >buggy</a> by design.</p>

<p>On the database one approach that has been taken by Oracle since I think 9i is to delay the planning stage until the first execution. The query plan is then optimized for the first data set. I do not know how this works in detail, as I presume that if the plan uses a partial index as a covering index and the next data set is not contained in the partial index, that this approach would fail. However it gets the job done for people that just want to use prepared statements for one shot execution to get SQL injection protection and better readability.</p>

<p>Another approach that I do not think any RDBMS has taken (probably because its either hard or not feasible .. or both) is to keep multiple query plans around. In this scenario in the initial planning phase the database would also store some simple parameters that define if an existing query plan will match or not. If the plan does not, then a new plan is generated, while the old plan is kept around. This way a single prepared statement could eventually keep multiple query plans around. This would also solve the issue with partial indexes being used as covering indexes.</p>

<p>Yet another approach, which would be less interesting for short running sessions as are common in PHP applications, would be that if the query is executed and the performance is slower than expected, that this then triggers a replanning. Potentially also keeping the old plan for old data sets. This would also solve the issue of long running sessions having out of date plans.</p>

<p>Overall it seems for stateless web applications the best approach is using a database layer with good prepared statement emulation support. I hope that PDO, will <a href="http://wiki.php.net/rfc/pdov1" >one day</a> fit this criteria. Until then the <a href="http://pear.php.net/package/MDB2/" >MDB2</a> parser seems to do a much better job. Though MDB2 is of course implemented in PHP, which carries its own performance overhead and is not E_STRICT compliant due to the PHP4 compatibility.</p>

]]></description></item><item><title>MySQL enjoying its new home - Lukas Kahwe Smith</title><link>http://www.pooteeweet.org/blog/0/1081</link><pubDate>Fri, 09 May 2008 06:16:51 +0000</pubDate><description><![CDATA[<p>So it seems that Sun has made it <a href="http://blogs.mysql.com/kaj/2008/05/06/mysql-server-is-open-source-even-backup-extensions/" >clear</a> that the core product will remain open source. Of course the definition of what is core and what isn't is up to Sun/MySQL to decide, but it seems that overall more things will be released as open source than if MySQL would have gone through with its planned IPO. So this is a good thing. Speaking of non core products, I really like what Mike and his team are doing in the GUI department with the <a href="http://dev.mysql.com/workbench/" >workbench</a> and their other <a href="http://dev.mysql.com/downloads/gui-tools/5.0.html" >GUI tools</a>. However since Sun is friendly to <a href="http://www.sun.com/software/products/postgresql/index.jsp" >PostgreSQL</a> and actually also distributes SQLite (its <a href="http://asdf.blogs.com/asdf/2005/06/sqlite_use_incr.html" >bundled</a> with Solaris after all), I wonder if they are considering making their tools more and more portable across other RDBMS?</p>

]]></description></item><item><title>The Date_Holidays package, a pack of splitters and a pear tree. - Ken Guest</title><link>http://blogs.linux.ie/kenguest/2008/05/09/the-date_holidays-package-a-pack-of-splitters-and-a-pear-tree/</link><pubDate>Fri, 09 May 2008 01:15:10 +0000</pubDate><description><![CDATA[
Some of you may know that I am a lead developer of the pear Date_Holidays package.

Date_Holidays helps you calculate the dates and titles of holidays and other special celebrations. This is all driver-based so it is easy to add new drivers that calculate a country's holidays. 
Until recently all of ...]]></description></item><item><title>Signup for the TestFest@Webtuesday - Lukas Kahwe Smith</title><link>http://www.pooteeweet.org/blog/0/1079</link><pubDate>Wed, 07 May 2008 11:34:16 +0000</pubDate><description><![CDATA[<p>As I already noted on the <a href="http://blog.liip.ch/archive/2008/04/29/testfest-at-webtuesday-hackfest.html" >Liip</a> blog, there will be a TestFest as part of the <a href="http://webtuesday.ch/hackdays/20080524" >Webtuesday Hackday</a>. So in order to better prepare things for the event I would appreciate it if people interested in joining the TestFest drop me a note via email or in a comment. See you there!</p>

]]></description></item><item><title>PEPR, XML_GRDDL and Digg's RDFa - Daniel O'Connor</title><link>http://clockwerx.blogspot.com/2008/05/pepr-xmlgrddl-and-diggs-rdfa.html</link><pubDate>Sun, 04 May 2008 04:15:13 +0000</pubDate><description><![CDATA[So, <a href="http://blog.digg.com/?p=120">Digg got RDFa</a> all over the place.<br /><br />That's pretty handy since I've just moved <a href="http://pear.php.net/pepr/pepr-proposal-show.php?id=533">XML_GRDDL</a> to a call for votes.<br /><br />Why, you ask? Because you can have <a href="http://code.google.com/p/xmlgrddl/source/browse/trunk/docs/digg-rdfa.php">instant RDF from digg</a> in a few lines of code (tip: you want to grab xml_grddl from SVN at the moment).]]></description></item><item><title>PHP_Debug V2.1.3 released - Strangebuzz...?</title><link>http://www.strangebuzz.com/index.php/2008/05/02/33-php_debug-v213-released</link><pubDate>Fri, 02 May 2008 11:32:55 +0000</pubDate><description><![CDATA[This is just a small update to correct and close minor bugs that were on the Pear bug tracker.  I have also finally added the sources on the php csv server. The last step will be to do the end user documentation in the DocBook format so it can be available in the official pear documentation.


Pear...]]></description></item><item><title>Finding the right place for a join condition - Lukas Kahwe Smith</title><link>http://www.pooteeweet.org/blog/0/1076</link><pubDate>Wed, 30 Apr 2008 10:03:20 +0000</pubDate><description><![CDATA[<p>In a little app where users can create tabs and portlets in those tabs I ran into some issues with my ordered list implementation. It turns out I just misplaced a filtering expression in the WHERE clause instead of the JOIN condition. The basic idea was that I wanted to add new portlets in the left hand column at the top. The positions from the portlets actually start at 0, but what I am doing is to insert them at 1 below the current minimum or -1 if the table is empty. Then in a second query I push everything up by one. Seemed like the most efficient way to deal with concurrency. I guess in theory I could even skip pushing things up by one, but oh well.</p>

<p>Here is the original query (note that I am using PDO which supports Oracle style named placeholders for all drivers including MySQL):</p>


<pre><code>INSERT INTO user_tab_portlets (tab_id, portlet_id, pos, col, is_open, config)
            (SELECT :tab_id, :portlet_id, COALESCE(MIN(utp.pos)-1, -1), :col, :is_open, :config
                FROM user_tabs ut LEFT JOIN user_tab_portlets utp ON (ut.id = utp.tab_id)
                WHERE ut.id = :tab_id AND (utp.col IS NULL OR utp.col = :col)
                GROUP BY utp.tab_id, utp.col)</code></pre>

<p>I sort of expected the "utp.col IS NULL OR utp.col = :col" to work out fine for the case when there are no portlets yet in the left column on the given tab, since due to the LEFT JOIN the "IS NULL" part should fire (the col is not nullable). As it turns out a more readable and actually working version of my query would look like this:</p>


<pre><code>INSERT INTO user_tab_portlets (tab_id, portlet_id, pos, col, is_open, config)
            (SELECT :tab_id, :portlet_id, COALESCE(MIN(utp.pos)-1, -1), :col, :is_open, :config
                FROM user_tabs ut LEFT JOIN user_tab_portlets utp ON (ut.id = utp.tab_id AND utp.col = :col)
                WHERE ut.id = :tab_id
                GROUP BY utp.tab_id, utp.col)</code></pre>

<p>Anyways, if anyone has some pointers on how to better do an ordered list in SQL please let me know. I felt quite good when I figured this one out :)</p>

]]></description></item><item><title>PHP Unconference 2008 in Hamburg - Christian Weiske</title><link>http://cweiske.de/tagebuch/PHP%20Unconference%202008%20in%20Hamburg.htm</link><pubDate>Mon, 28 Apr 2008 08:15:09 +0000</pubDate><description><![CDATA[<div >
  <p >
   Dieses Wochenende (26./27. April) war ich in Hamburg auf der
   <a href="http://php-unconference.de/">PHP Unconference 2008</a>,
   organisiert von der PHP Usergroup Hamburg. Tobias Struckmeier war so lieb
   mich und mindestens 6 andere Leute für das Wochenende bei sich
   aufzunehmen, wodurch mir dir nervige Hotelsuche oder das Übernachten in
   der Uni erspart blieb. Außerdem wurde der Abend etwas länger; nachts um 1
   saßen wir nach der Heimfahrt von der <em >Recycel Bar</em> vor den Laptops
   und informierten uns gegenseitig über coole selbstgebaute Software :)
  </p>
  <p >
   Sonnabend in der Eröffnungssession wurden die Sessions festgelegt -
   schön basisdemokratisch nach Anzahl der Wünsche der Teilnehmer.
   Meinen Vortrag über PEAR2 wollten nicht genug Leute (<8) hören, das
   Angebort für den <acronym title="SPARQL Protocol And Query    Language">SPARQL</acronym> bekam volle 9 Punkte und wurde als auf den
   Sonntag 16:00 in den letzten Slot gesetzt.
  </p>
  <p >
   Den so "gewonnen" Freiraum konnte ich sehr schön mit dem Beisitzen in den
   anderen Sessions füllen und hier und da was Neues aufschnappen. Das tolle
   an der Unconf sind eigentlich - wie überall - die Gespräche zwischen den
   Vorträgen, von denen es reichlich interessante gab.
  </p>
  <p >
   Ich wurde allerdings immer mehr in dem Gefühl bestärkt, auf den falschen
   Gebieten tätig zu sein: Der PEAR-Talk wurde nicht genommen, das
   PEAR-Installerbuch in der Verlosung als zweitletztes genommen und mein
   SPARQL-Vortrag am Sonntagnachmittag wollten ganze drei Leute hören...
   Nach der Vorstellung von <a href="http://dbpedia.org">DBpedia</a>
   entwickelte sich aber doch ein interessantes Gespräch über die
   Verfügbarkeit von Daten über die Menschen. Sie existieren sowieso im
   Netz, allerdings haben nur ... Organisationen die Mittel, sie
   zusammenzuführen. Ergebnis: Damit alle die gleichen Chancen haben, müssen
   Informationen für alle verfügbar und frei sein. Denn irgendjemand hat
   immer Zugriff darauf - warum also nicht alle?
  </p>
  <p >
   Zusammenfassend war es ein sehr interessantes und schönes Wochenende. Als
   zum Schluß darum gebeten wurde, Kritik und Verbesserungsvorschläge
   einzureichen fiel mir absolut nichts ein - perfekt!
  </p>
 </div>]]></description></item><item><title>PHP_CodeSniffer code taken and rebadged as Zend Framework code - Greg Sherwood</title><link>http://gregsherwood.blogspot.com/2008/04/phpcodesniffer-code-taken-and-rebadged.html</link><pubDate>Sat, 26 Apr 2008 00:15:12 +0000</pubDate><description><![CDATA[A new <a href="http://pear.php.net/bugs/bug.php?id=13774">feature request</a> for PHP_CodeSniffer alerted me to the effort of a couple of Zend Framework developers to create a PHP_CodeSniffer standard that can be used by all Zend Framework developers. The feature request mentioned that the name they had chosen (Zend) conflicts with the existing standard that is distributed with PHP_CodeSniffer.<br /><br />I immediately thought this was a bit strange because I've already had someone from Zend <a href="http://gregsherwood.blogspot.com/2007/08/getting-zend-coding-standard-into.html">contribute some code</a> for the Zend Framework coding standard, and I've written a fair few sniffs for it myself.<br /><br />I took a look at <a href="http://framework.zend.com/svn/framework/trunk/incubator/tools/codingstandard/">the code</a> and noticed that almost all of the sniffs that have been committed to the Zend Framework SVN repository are just copies of the sniffs I have written for the existing PHP_CodeSniffer standards. The troubling part is that all the copyright notices and author tags have been switched to indicate that the code was written by and copyright Zend. Worse still, the licence had been changed to the Zend Framework's New BSD licence.<br /><br />This is a pretty clear violation of the <a href="http://matrix.squiz.net/developer/tools/php_cs/licence">BSD licence</a> under which PHP_CodeSniffer is distributed, so I've left a comment on the <a href="http://framework.zend.com/wiki/display/ZFDEV/ZF+Coding+Standards+(RC)">Coding Standard RC</a> page in the Zend Framework wiki. I tried locating an email address, submitting an issue and even commenting on an existing issue, but it appears the Zend Framework doesn't have any scope for non-approved developer comments besides the wiki.<br /><br />I did get a little angry when I saw this, but I also see this as an opportunity to complete the PHP_CodeSniffer Zend standard and get PHP_CodeSniffer our there to a new developer community. The Zend Framework obviously has a couple of developers dedicated to automating their coding standard checks using PHP_CodeSniffer, so I've provided them with an invitation to contact me and work together. I will hopefully be taken up on that offer.<br /><br /><strong>Update:</strong> Thought it might be easier to see the problem if you can focus on one file. Take a look at <a href="http://framework.zend.com/fisheye/browse/~raw,r=9304/Zend_Framework/trunk/incubator/tools/codingstandard/Zend/Sniffs/Functions/FunctionDeclarationArgumentSpacingSniff.php">Zend's FunctionDeclarationArgumentSpacingSniff</a> (from the ZF SVN repo) and <a href="http://cvs.php.net/viewvc.cgi/pear/PHP_CodeSniffer/CodeSniffer/Standards/Squiz/Sniffs/Functions/FunctionDeclarationArgumentSpacingSniff.php?revision=1.10&content-type=text%2Fplain&pathrev=1.10">Squiz's FunctionDeclarationArgumentSpacingSniff</a> (from the PEAR CVS repo). Only very minor changes have been made. Even with these changes, it would be best to extend the Squiz sniff and do some minor refactoring rather than copy/paste, which I'm happy to help with.<br /><br /><strong>Update:</strong> <a href="http://www.thomasweidner.com/flatpress/index.php">Thomas Weidner</a> has contacted me to let me know the files have been removed from the Zend Framework SVN repo.]]></description></item></channel></rss>
