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

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule">
<channel>
    
    <title>Uncreative - PHP</title>
    <link>http://blog.wolff-hamburg.de/</link>
    <description>The blog with no witty title...</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.5.5 - http://www.s9y.org/</generator>
    <pubDate>Sun, 03 Oct 2010 15:49:59 GMT</pubDate>

    <image>
        <url>http://blog.wolff-hamburg.de/templates/competition/img/s9y_banner_small.png</url>
        <title>RSS: Uncreative - PHP - The blog with no witty title...</title>
        <link>http://blog.wolff-hamburg.de/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>PHP Unconference Europe announced</title>
    <link>http://blog.wolff-hamburg.de/archives/29-PHP-Unconference-Europe-announced.html</link>
            <category>PHP</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/29-PHP-Unconference-Europe-announced.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=29</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    &lt;p&gt;What is it with me? Haven&#039;t blogged in over a year and whenever I do blog, it always seems to be about those darn unconferences. There really must be something to them, right? Right?&lt;/p&gt;

&lt;p&gt;Well, if you&#039;ve always been intruiged by the raving reviews the &lt;a href=&quot;http://www.php-unconference.de&quot; title=&quot;Official website of the PHP Unconference Hamburg&quot;&gt;PHP Unconference in Hamburg, Germany&lt;/a&gt; is getting (which took place again just last weekend, and, again, was a blast), but were put off by the fact that it&#039;s in Germany, which is far, far away and people might not speak English and eat only Sauerkraut, wear Lederhosen and are overall silly (hint: only the last part is true), then now is your chance to experience the unconfence spirit in a more international setting:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://www.phpuceu.org/2010/10/03/save-the-date-feb-19-20-2011/&quot; title=&quot;PHP Unconference Europe 2011&quot;&gt;The PHP Unconference Europe is scheduled to take place in Manchester on February 19/20, 2011&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These unconferences are entirely community-driven, noncommercial events and have become kind of a family meeting of the PHP development scene in Germany. I hope the same can be achieved Europe-wide. Mind you, the number of tickets will be limited, though!&lt;/p&gt;

&lt;p&gt;Jakob Westhoff was kind enough to &lt;a href=&quot;http://westhoffswelt.de/blog/0052_another_php_unconference_is_over.html&quot; title=&quot;Another PHP Unconference is over - A wrap up by Jakob Westhoff&quot;&gt;provide a small write-up&lt;/a&gt; of his impressions of last weekend&#039;s unconference in Hamburg. If you&#039;ve ever wondered how an unconference works or why you should go, this will give you a great overview.&lt;/p&gt;

&lt;p&gt;I&#039;m really looking forward to the Manchester unconference and meeting a lot of new folks!&lt;/p&gt; 
    </content:encoded>

    <pubDate>Sun, 03 Oct 2010 15:10:30 +0200</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/29-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>Finding a date for the next Unconference</title>
    <link>http://blog.wolff-hamburg.de/archives/27-Finding-a-date-for-the-next-Unconference.html</link>
            <category>PHP</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/27-Finding-a-date-for-the-next-Unconference.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=27</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    &lt;p&gt;Ladies and gentlemen, I am proud to announce... nothing quite yet &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/wink.png&quot; alt=&quot;;-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;&lt;/p&gt;
&lt;p&gt;
The last two &lt;a href=&quot;http://www.php-unconference.de/&quot;&gt;unconferences in Hamburg&lt;/a&gt; have been a huge success, which has become somewhat problematic. The first unconference saw about 60-80 attendees, while the second one already clocked in at around 120 - and that&#039;s just because that was the number where we pulled the plug and couldn&#039;t accept any more registrations.&lt;/p&gt;
&lt;p&gt;That in itself is, of course, a Good Thing(tm), as we&#039;ve reached our goal to make the whole thing into an enjoyable experience. Unfortunately, it also showed us the limits of our current venue: More than 120 people would be hard to accomodate at the local University&#039;s Informatikum.&lt;/p&gt;
&lt;h3&gt;The good news&lt;/h3&gt;
&lt;p&gt;So the good news is: There will be another unconference in Hamburg in 2009! This time we&#039;ll try to organize a venue that will allow us to get a few more people in, so we don&#039;t have to leave too many people standing outside in the street, right in the pouring rain, crying, freezing, bumping their bloody fists against the door... yeah, okay, I may be exaggerating. A little. Ahem. Anyway...&lt;/p&gt;
&lt;h3&gt;The bad news (and question for the audience)&lt;/h3&gt;
&lt;p&gt;
The bad news is: We&#039;re highly unlikely (okay, now I&#039;m understating &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/tongue.png&quot; alt=&quot;:-P&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;) to make it for the usual April/May date this time. Sorry, folks. Thus, we&#039;re now aiming for mid-September, and we&#039;ve pre-picked two possible dates we&#039;d like to hear your opinion on:
&lt;ul&gt;
&lt;li&gt;September 12th/13th, 2009&lt;/li&gt;
&lt;li&gt;September 19th/20th, 2009&lt;/li&gt;
&lt;/ul&gt;
As all who already attended one of the past unconferences know, the event is all about you guys and it&#039;s your input that makes it the success it has become! So here&#039;s the first thing you can do to make this year&#039;s unconference a sure-fire hit - leave a comment and tell us which date you&#039;d prefer. Well, that and any other ideas that you might have for the unconference &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/wink.png&quot; alt=&quot;;-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;
&lt;/p&gt; 
    </content:encoded>

    <pubDate>Thu, 05 Feb 2009 22:16:49 +0100</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/27-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>A pragmatic approach to rights management</title>
    <link>http://blog.wolff-hamburg.de/archives/25-A-pragmatic-approach-to-rights-management.html</link>
            <category>PHP</category>
            <category>Programming</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/25-A-pragmatic-approach-to-rights-management.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=25</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    &lt;h2&gt;The part &lt;s&gt;where I complain&lt;/s&gt; you can ignore&lt;/h2&gt;
&lt;p&gt;While most of you have been sitting under the Christmas tree and happily unpacking presents surrounded by your loved ones, I was reading &lt;a href=&quot;http://weierophinney.net/matthew/archives/201-Applying-ACLs-to-Models.html&quot; title=&quot;Applying ACLs to Models by Matthew Weier O&#039;Phinney&quot;&gt;Matthew&#039;s blog post about Zend_ACL&lt;/a&gt;. What? I finally got time to to these kinds of things now &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/laugh.png&quot; alt=&quot;:-D&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In the comments, Lukas already mentioned the good ol&#039; PEAR package &lt;a href=&quot;http://pear.php.net/package/LiveUser&quot;&gt;LiveUser&lt;/a&gt;, of which I was the original author and that has been accused of being over-engineered and way too complex to grasp. Looking back I&#039;d have to say people were right. It was too complex and it was over-engineered. And now I&#039;m seeing similar problems again with Zend_ACL.&lt;/p&gt;
&lt;p&gt;I haven&#039;t used LiveUser myself in many, many years because all of the projects I&#039;ve been involved with ever since either did not require any really sophisticated rights management, or when they did there already was an existing system in place. Also, coworkers needed a really long time to grasp its concepts and it was a real pain to initially set up and quite hard to debug at times.&lt;/p&gt;
&lt;p&gt;While Zend_ACL at first sight is less complex, as it supports only one style of rights management and does not even define any specific persistance mechanism for the storage of resources, roles and their relationships, it deals with a whole different level of complexity: A gazillion of small classes with next to no functionality, a single one for every tiny little aspect involved in the management of rights throughout your application. This sounds like an awful lot of overhead and an extreme case of Javaism (Java-style architecture ported 1:1 to PHP without questioning whether or not it&#039;s the right way to do it in the context of PHP).&lt;/p&gt;
&lt;p&gt;
&lt;h2&gt;The idea&lt;/h2&gt;
Rewind a few years to a previous programming gig, my former Boss Thies came up with a very simplistic way of managing user rights that is a lot more suited to the PHP way of doing things. Basically, you define a list of rights, following a naming scheme that implies a hierarchical structure - like this:&lt;br /&gt;
&lt;blockquote&gt;ApplicationName.ModuleName.FunctionName.ActionName&lt;/blockquote&gt;
&lt;/p&gt;
&lt;p&gt;
An example of a list of rights for a real-life application could look like this:
&lt;ul&gt;
&lt;li&gt;MyGuestbook.FrontPage.ItemList.Show
&lt;/li&gt;&lt;li&gt;MyGuestbook.FrontPage.EntryForm.Show
&lt;/li&gt;&lt;li&gt;MyGuestbook.FrontPage.EntryForm.Post
&lt;/li&gt;&lt;li&gt;MyGuestbook.Admin.ItemList.Show
&lt;/li&gt;&lt;li&gt;MyGuestbook.Admin.ItemList.Delete
&lt;/li&gt;&lt;li&gt;MyGuestbook.Admin.ItemList.Edit
&lt;/li&gt;&lt;li&gt;MyGuestbook.Admin.General.Delete
&lt;/li&gt;&lt;li&gt;MyGuestbook.Admin.General.Activate
&lt;/li&gt;&lt;li&gt;MyGuestbook.Admin.General.Deactivate
&lt;/li&gt;&lt;/ul&gt;
...I guess you can see where this is going. A list like this is very easily maintainable and it&#039;s so straightforward, you don&#039;t even need to think about your rights structure in advance, you can just make it up as you go while you&#039;re happily coding away and suddenly feel the need to ask for a user right at some point.
&lt;/p&gt;
&lt;p&gt;I&#039;ve written my own implementation of this style of rights management that defines only two methods:
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;setRights(Array $rightList)&lt;/i&gt;&lt;br /&gt;
Sets a list of rights for a given user. This list could come from a database, a file, anywhere you&#039;d like. Example will follow later on. Invoked only once after a user has logged in.
&lt;/li&gt;
&lt;li&gt;&lt;i&gt;checkRight(String $rightName)&lt;/i&gt;&lt;br /&gt;
Checks whether the given rights list contains the right with the given name. Invoked at any time a right has to be checked.
&lt;/li&gt;&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
Until now, the approach may have sounded a bit too simplistic. What if I have hundreds of rights throughout my application? I&#039;d need to assign every right to every user manually! Not so, because as a shortcut, you can use wildcards to give a user all rights in a given area. In the example above, to give a user access to the front page, but only the item list in the admin section, you could have a rights list like this:
&lt;ul&gt;
&lt;li&gt;MyGuestbook.FrontPage.*
&lt;/li&gt;&lt;li&gt;MyGuestbook.Admin.ItemList.*
&lt;/li&gt;&lt;/ul&gt;
It&#039;s also possible to negate a right by prefixing it with a minus sign. If, for example, I&#039;d like the user to have access to the aforementioned modules, but I don&#039;t want him to be able to delete entries, the list could look like this:
&lt;ul&gt;
&lt;li&gt;MyGuestbook.FrontPage.*
&lt;/li&gt;&lt;li&gt;MyGuestbook.Admin.ItemList.*
&lt;/li&gt;&lt;li&gt;-MyGuestbook.Admin.ItemList.Delete
&lt;/li&gt;&lt;/ul&gt;
Notice the minus sign: It means although the user would have all the rights for the ItemList action because of the wildcard assignment, the Delete function is specifically revoked. You could also use wildcards for revoking a whole bunch of rights, but if you needed to do that, you&#039;d probably have made a mistake with your rights assignments anyway &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/wink.png&quot; alt=&quot;;-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;h2&gt;Groups and roles&lt;/h2&gt;
I can already hear the outcry: &quot;But I need groups! And roles!&quot;. Yeah - about that... there has been a lot of discussion on this topic on the LiveUser mailinglist many moons ago. The general consensus was: Groups and roles are practically the same thing, they&#039;re just named differently depending on context. Let me illustrate: A group represents a number of entities (say, &quot;users&quot;) sharing the same set of rights. A role represents a set of actions which entities that are assigned to this role are supposed to be able to perform. Such actions can in turn be represented as rights, and there you go - we&#039;re back where we were with the group thingy.&lt;/p&gt;
&lt;p&gt;Groups (and hence, roles) are easily implemented using the above approach: The simplest method would be to keep a separate rights object for each group the user belongs to, and whenever a right is checked, iterate through the group rights array and do a check on each of the objects it contains. After all groups have been checked, you can then check the individual user rights (non-group rights) that could potentially override group rights. After 10-15 minutes of light coding and the use of only very few brain cycles you&#039;ll have your enhanced group rights capable version of the system illustrated above. A more advanced method would be to first merge all rights into one array and do lookups only on the merged structure - the only challenge here would be to think of a system that decides the order in which groups that define the same rights would be able to override each other... but the system is simple enough that nearly anyone could come up with at least something that works.&lt;/p&gt;
&lt;p&gt;&quot;Okay&quot;, you say, &quot;but if the rights are not defined centrally, but made up as-I-go when I code stuff, how do I find out which rights are actually used?&quot;. There are multiple valid approaches to tackle that issue. One possibility would be to do a lookup in some database table and insert the right name if it is not already present. It&#039;s an approach I&#039;ve used myself in the (far) past - it works, but it&#039;s quite expensive, especially as right checks are common. You could cache the results, but the caching mechanism results in more code, so we trade in slow database lookups with more logic overhead. A better method is what &lt;i&gt;gettext&lt;/i&gt; does - just scan the source for calls to the checkRight() method and write the found right names into some datastore that can be used for writing graphical user interfaces for the administration of user rights. To scan your code you can either use grep or write a really small PHP script.&lt;/p&gt;
&lt;p&gt;
&lt;h2&gt;Examples&lt;/h2&gt;
I have some example code up that I wrote back in 2006. Be warned that this code has never been tested in production, it is merely the result of a pissing contest with someone who claimed that this would be very complicated to implement - the code was only used to prove him wrong. It should work, but may contain bugs that bite you in places where it really hurts:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ssl.limbourg.com/svn/CWAC/trunk/library/CWAC/User/Rights.php&quot;&gt;Basic class to check against an array of rights&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ssl.limbourg.com/svn/CWAC/trunk/tests/CWAC/User/RightsTest.php&quot;&gt;A very small and very incomplete unit test.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ssl.limbourg.com/svn/CWAC/trunk/scripts/scan_rights.php&quot;&gt;Script to scan a directory for right names used in your code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;h2&gt;Limitations&lt;/h2&gt;
What this approach solves (and, I think, solves very well) is the problem of static user rights that are defined for specific actions on the application level. Where it fails is when you have user-generated content for which you want to maintain object-specific ACLs - e.g., user A uploads a document that is supposed to be viewable by everyone, but editable only for users B and C, which are members of user-defined group FooBar. Rights specific to this document would have to be created at runtime. While certainly doable with the above approach, the handling would be a real nightmare, as you&#039;d have to deal with potentially millions of dynamically generated rights. This scenario may be one where Zend_ACL is better suited, although a simpler approach might be to just define four basic rights (create, insert, update, delete) that are dynamically mixed into the user rights array depending on object context - that way, the above approach could even be used in these situations (although it would smell a bit like rape).
&lt;/p&gt;
&lt;p&gt;
&lt;h2&gt;Conclusion? Input?&lt;/h2&gt;
Okay, alright - I haven&#039;t really given you the ultimate ready-to-use solution for easy rights management, but hey, Christmas is over &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/tongue.png&quot; alt=&quot;:-P&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;&lt;br /&gt;
What I meant to illustrate is that rights management can be done in an easy way, a way that IMO suits &quot;the PHP way&quot; much better than all those overly complicated packages like Zend_ACL, phpGACL or, yes, LiveUser. PHP is not about purity, it&#039;s about getting things done. People sometimes seem to forget that (including me), so I think a little reminder every now and then can&#039;t hurt &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/wink.png&quot; alt=&quot;;-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;
&lt;/p&gt;
&lt;p&gt;What I&#039;d like to know now is what other people (yes, that means you) think about this approach and how would you apply it (or something similar) to user-generated content without abandoning the simplicity illustrated above?&lt;/p&gt;
&lt;p style=&quot;font-weight: bold&quot;&gt;Happy new year to all of the PHP community!&lt;/p&gt; 
    </content:encoded>

    <pubDate>Fri, 02 Jan 2009 18:41:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/25-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>See you at the International PHP Conference 2008</title>
    <link>http://blog.wolff-hamburg.de/archives/24-See-you-at-the-International-PHP-Conference-2008.html</link>
            <category>Javascript</category>
            <category>PHP</category>
            <category>Programming</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/24-See-you-at-the-International-PHP-Conference-2008.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=24</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    Yes, it is true - I am not dead &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/wink.png&quot; alt=&quot;;-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

Just wanted to chime in on the IPC&#039;2008 cheering, as I will be going to Mainz as well and I&#039;m very excited to meet the rest of the crowd once again!

I will hold a session titled &quot;Search as a service&quot; in which I will show off &lt;a href=&quot;http://code.google.com/p/marjory/&quot; title=&quot;Marjory at Google Code&quot;&gt;my little side-project Marjory&lt;/a&gt;. Additionally, you&#039;ll be able to find me at the Mayflower booth, &lt;a href=&quot;http://blog.thinkphp.de/archives/367-Meet-the-PHP-Experts-at-the-Mayflower-Coffee-Lounge.html&quot; title=&quot;Meet the experts at the Mayflower Coffee Lounge!&quot;&gt;which will serve as a Coffee Lounge&lt;/a&gt; this year - I&#039;m at the source, Luke!

Regarding Marjory, I&#039;ve just started to port the code to Zend Framework 1.6 (the old version still used some post-1.0/pre-1.5-checkout). I&#039;ll also add some new features, two of them having already made it into SVN: JSON-RPC as an alternative to ReST, and Dojo.Data-compatible JSON as alternative to the XML output for search queries, so the service can be used directly with Dojo widgets. Thanks to the latest Zend Framework additions, these features took only about 15 minutes to implement, including looking up the API examples in the manual &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/wink.png&quot; alt=&quot;;-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

 
    </content:encoded>

    <pubDate>Fri, 24 Oct 2008 22:26:39 +0200</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/24-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>Fulltext search as a webservice</title>
    <link>http://blog.wolff-hamburg.de/archives/22-Fulltext-search-as-a-webservice.html</link>
            <category>PHP</category>
            <category>Programming</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/22-Fulltext-search-as-a-webservice.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=22</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    Once again, a long time has passed since the last blog post. Why is that? Well, I&#039;ve been a bit busy with work, the PHP Unconference in Hamburg, getting married, going to Helsinki for our honeymoon and all that kind of stuff, you know - the usual &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

On the PHP-related side of this post, I&#039;ve created yet another open source project which has already proven useful for the company I&#039;ve been working with for the last year - namely &lt;a href=&quot;http://www.northclick.de/&quot;&gt;NorthClick&lt;/a&gt;, which are the same guys who are behind &lt;a href=&quot;http://jimdo.com/&quot;&gt;Jimdo.com&lt;/a&gt; (the free website creator that will undoubtedly one day swallow up Weebly and MySpace, ahem &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;).

While working at some really old code that provided a fulltext search feature, I was at one point &lt;s&gt;incredibly pissed &lt;/s&gt;rather unsatisfied due to the fact that said code resisted all attempts to debug it. This lead to the decision to sit down on a rainy weekend to try if I couldn&#039;t come up with something more useful, and most importantly, scalable. After about three hours of trial and error with Zend_Service_REST and Zend_Search_Lucene, I came up with a working prototype of a service-oriented fulltext index.

The basic idea was to decouple the indexing logic from the application logic, making the fulltext feature completely independent of the main application. The solution for this is a simple XML-based webservice that you throw your documents at, and that will allow querying the index later on.

At first I had no idea that a solution like this had already existed until I had a talk with Peter Petermann at last fall&#039;s International PHP Conference in Frankfurt, who pointed me to the &lt;a href=&quot;http://lucene.apache.org/solr/&quot;&gt;Apache Solr&lt;/a&gt; project, which does pretty much the same thing, but is implemented in Java. Since I wasn&#039;t yet happy with the auto-generated XML response syntax and the webservice API of my own project, I then decided to just &lt;s&gt;steal&lt;/s&gt;borrow Solr&#039;s ideas and make my API and XML syntax somewhat compatible to theirs, so switching between the two projects should be easy (in theory, didn&#039;t try it yet).

As a result of all this, &lt;a href=&quot;http://code.google.com/p/marjory/&quot;&gt;Marjory&lt;/a&gt; was born and can now be found at Google Code.

Here&#039;s a quick example of how easily a document can be added to Marjory:
&lt;div class=&quot;php&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$data&lt;/span&gt; = &amp;lt;&amp;lt;&amp;lt;EOD&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;lt;add catalog=&lt;span style=&quot;color: #ff0000;&quot;&gt;&quot;default&quot;&lt;/span&gt;&amp;gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;lt;doc src=&lt;span style=&quot;color: #ff0000;&quot;&gt;&quot;http://my.website.tld/my/document.html&quot;&lt;/span&gt; /&amp;gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;lt;/add&amp;gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;EOD;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$context&lt;/span&gt;&amp;#160; = &lt;a href=&quot;http://www.php.net/stream_context_create&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;stream_context_create&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;http&#039;&lt;/span&gt; =&amp;gt; &lt;a href=&quot;http://www.php.net/array&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;array&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;method&#039;&lt;/span&gt;&amp;#160; =&amp;gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;POST&#039;&lt;/span&gt;,&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&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; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;header&#039;&lt;/span&gt;&amp;#160; =&amp;gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;Content-type: text/xml&#039;&lt;/span&gt;,&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&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; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;content&#039;&lt;/span&gt; =&amp;gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$data&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$result&lt;/span&gt; = &lt;a href=&quot;http://www.php.net/file_get_contents&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;file_get_contents&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;http://marjory.example.com/rest/add&#039;&lt;/span&gt;, &lt;span style=&quot;color: #000000; font-weight: bold;&quot;&gt;false&lt;/span&gt;, &lt;span style=&quot;color: #0000ff;&quot;&gt;$context&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;

Well, okay, this will only work for HTML documents located on a webserver. What if your application reads, say, a PDF, extracts text from it and wants to store that in the fulltext index? Just alter the XML:
&lt;div class=&quot;xml&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;lt;add&lt;/span&gt; &lt;span style=&quot;color: #000066;&quot;&gt;catalog&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;lt;doc&lt;/span&gt; &lt;span style=&quot;color: #000066;&quot;&gt;uri&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&quot;MyUniqueDocumentId&quot;&lt;/span&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;lt;field&lt;/span&gt; &lt;span style=&quot;color: #000066;&quot;&gt;name&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Marjory: Search as a service&lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;lt;/field&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;lt;field&lt;/span&gt; &lt;span style=&quot;color: #000066;&quot;&gt;name&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&quot;abstract&quot;&lt;/span&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;An epic novel about full-text indexing in an SOA environment&lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;lt;/field&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;lt;field&lt;/span&gt; &lt;span style=&quot;color: #000066;&quot;&gt;name&lt;/span&gt;=&lt;span style=&quot;color: #ff0000;&quot;&gt;&quot;content&quot;&lt;/span&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Lorem ipsum dolor sit amet... (to be continued)&lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;lt;/field&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;lt;/doc&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #009900;&quot;&gt;&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;lt;/add&lt;span style=&quot;font-weight: bold; color: black;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;

People having experience with Solr will find the above syntax a lot more familiar. The previously shown example is just a nice shortcut for indexing documents located on the web, which was a requirement for the NorthClick CMS.

And this is how documents can be searched once they&#039;ve been indexed:
&lt;div class=&quot;php&quot; style=&quot;text-align: left&quot;&gt;&lt;ol&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$xml&lt;/span&gt; = simplexml_load_file&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;http://marjory.example.com/rest/select?q=Marjory&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #b1b100;&quot;&gt;foreach&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$xml&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;xpath&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;//doc&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$document&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &lt;a href=&quot;http://www.php.net/printf&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;printf&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&quot;&lt;span style=&quot;color: #000099; font-weight: bold;&quot;&gt;\n&lt;/span&gt;Found document: %s&lt;span style=&quot;color: #000099; font-weight: bold;&quot;&gt;\n&lt;/span&gt;&quot;&lt;/span&gt;, &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;string&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$document&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;uri&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #b1b100;&quot;&gt;foreach&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$document&lt;/span&gt;-&amp;gt;&lt;span style=&quot;color: #006600;&quot;&gt;str&lt;/span&gt; &lt;span style=&quot;color: #b1b100;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: #0000ff;&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &amp;#160; &amp;#160; &lt;a href=&quot;http://www.php.net/printf&quot;&gt;&lt;span style=&quot;color: #000066;&quot;&gt;printf&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&quot;Field %s contains value: %s&lt;span style=&quot;color: #000099; font-weight: bold;&quot;&gt;\n&lt;/span&gt;&quot;&lt;/span&gt;, &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;string&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;&#039;name&#039;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#93;&lt;/span&gt;, &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;string&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #0000ff;&quot;&gt;$field&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160; &amp;#160; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; color: black; font-weight: normal; font-style: normal;&quot;&gt;&lt;div style=&quot;font-family: &#039;Courier New&#039;, Courier, monospace; font-weight: normal;&quot;&gt;&amp;#160;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;

Easy, right? There&#039;s more that can be done, like limiting the number of results from a query, specifying the fields returned or specifying the catalog to search in. Marjory also allows to write your own document parsers or adaptors for search engines other than Zend_Search_Lucene.

The repository also contains code that shows how to use Marjory with &lt;a href=&quot;https://www.dropr.org/&quot;&gt;Dropr&lt;/a&gt;, the message queueing system developed by fellow Jimdoers Sönke Rümpler and Boris Erdmann. Using a message queue instead of firing the requests against the webservice will further improve your application performance (no more waiting for the indexer to finish processing your document) and make the indexing process more fail-safe (should something go wrong during processing, Dropr will simply try again). If you didn&#039;t hear about Dropr yet, &lt;a href=&quot;http://blog.northclick.de/archives/35&quot;&gt;have a look&lt;/a&gt; - it has proven incredibly useful for distributed architectures like Jimdo.com.

If you&#039;re interested in how exactly Marjory works and what it can do for you, look at the &lt;a href=&quot;http://code.google.com/p/marjory/wiki/DocBasics&quot;&gt;&quot;basics&quot; section of the documentation&lt;/a&gt; or download the &lt;a href=&quot;http://wiki.php-unconference.de/images/2/25/Marjory_slides.pdf&quot;&gt;slides of the presentation I gave&lt;/a&gt; at the recent Unconference in Hamburg.

 
    </content:encoded>

    <pubDate>Sun, 04 May 2008 18:15:49 +0200</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/22-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>Announcing the next unconference in Hamburg</title>
    <link>http://blog.wolff-hamburg.de/archives/21-Announcing-the-next-unconference-in-Hamburg.html</link>
            <category>Databases</category>
            <category>Events</category>
            <category>PHP</category>
            <category>Programming</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/21-Announcing-the-next-unconference-in-Hamburg.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=21</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    Hello fellow readers of PHP-Planet (at least the remaining ones who did not yet go on vacation &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;).

After the &lt;a href=&quot;http://blog.wolff-hamburg.de/archives/19-Looking-back-at-the-Hamburg-unconference....html&quot;&gt;success of this year&#039;s PHP Unconference&lt;/a&gt; in Hamburg, Germany, there was little doubt that the event would not remain a single incident. The remaining question was not if, but when should we do the next one?

This question can now be answered: On the weekend of April 26th / 27th, the PHP Unconference 2008 will once again take place in our beautiful city. We want to stick to the proven concept of some pre-announced sessions combined with a spontaneus program that is being proposed and voted for on-site by the attendees, as this has worked tremendously well during the first installment.

The unconference will most probably once again be held at the premises of the local University - we don&#039;t have a 100% official confirmation yet, but things are looking bright (also, the University officials seemed to have enjoyed this year&#039;s unconference just as much as the rest of us &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;).

The only downside is that at the same weekend, there&#039;s a huge sports event, the Hanse-Marathon, taking place in Hamburg, which is likely to block some of the traffic on Sunday and will also have an effect on available hotels - so if you&#039;re planning on coming (and you should &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/laugh.png&quot; alt=&quot;:-D&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;), and wish to stay in a hotel, you should book well in advance.

I will announce more details as they&#039;re being fleshed out - all information will become available on the unconference blog first, though, so head over there and subscribe to the RSS feed &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

&lt;a href=&quot;http://www.php-unconference.de/&quot;&gt;To the official unconference blog (sorry, German only for now)&lt;/a&gt; 
    </content:encoded>

    <pubDate>Tue, 18 Dec 2007 22:49:11 +0100</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/21-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>Migrating to PDT</title>
    <link>http://blog.wolff-hamburg.de/archives/20-Migrating-to-PDT.html</link>
            <category>PHP</category>
            <category>Programming</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/20-Migrating-to-PDT.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=20</wfw:comment>

    <slash:comments>6</slash:comments>
    <wfw:commentRss>http://blog.wolff-hamburg.de/rss.php?version=2.0&amp;type=comments&amp;cid=20</wfw:commentRss>
    

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    In case you haven&#039;t noticed, &lt;a href=&quot;http://www.zend.com/pdt/&quot;&gt;PDT 1.0 has been released&lt;/a&gt;. PDT, a.k.a. PHP Development Tools, is the shiny new PHP editor based on Eclipse, on which the successor to the current Zend Studio will be based. Being based on Eclipse, it is very, very powerful.

It took a little while for me to get acquainted with the little oddities of the Eclipse platform. One can clearly see that it was originally tailored to fit Java development, and although PHP integration is now pretty good, things sometimes still feel a bit bloated and overly complicated. Having said that, I&#039;m using PDT full-time for all my PHP development now and have kissed the old Zend Studio goodbye. Eclipse brings too many goodies to the table to ignore.

For those of you who want to try, here&#039;s the major drawbacks that can put you off:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Piss-poor network performance&lt;/strong&gt;&lt;br /&gt;
When you open a project, many many things happen in Eclipse. The project builder starts. The validators unleash their wild dogs on the files, checking for stupid things you will seldomly care about in PHP development. A lot of files will be opened and closed in very short time. When you have a really large project with thousands of files, and your project workspace is on a network share, don&#039;t expect your server to cope with the load. At best, expect things to become slow. Very slow.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Frequent slowdowns and out of memory exceptions&lt;/strong&gt;&lt;br /&gt;
Especially when the project builder runs on a very large project, or if you have Subversive installed to update your source files from the repository, or, even worse, if both happens at the same time, things can get ugly. It&#039;s bad enough when Eclipse is getting so slow at times that it becomes totally unresponsive, but it gets worse when Eclipse starts throwing Exceptions because there&#039;s not enough heap space left.&lt;/li&gt;
&lt;/ul&gt;

Note that this goes for Eclipse running with Sun Java 6 on Ubuntu 7.04, on a workstation with 2GB of RAM.

And here&#039;s what can be done about it:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;If you can, use NFS instead of Samba&lt;/strong&gt;&lt;br /&gt;
Hosting the project on NFS shares instead of SMB ones dramatically improved network performance for me. That&#039;s not to say that it is really fast now, just a lot faster than with NFS. I wonder if this is due to a borked Samba version on my current Ubuntu, because the Windows clients at the office seem to have fewer problems with network performance (although not what I&#039;d call mindblowingly fast either).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Adjust Java heap space&lt;/strong&gt;&lt;br /&gt;
Regarding the out of memory errors, I have found &lt;a href=&quot;http://forum.java.sun.com/thread.jspa?threadID=587273&amp;tstart=0&quot;&gt;a forum post&lt;/a&gt; that pointed me in the right direction. Using the settings described there, Eclipse no longer runs out of heap space and seems overall more responsive. The wait times for most operations have visibly increased. In case you don&#039;t have write permissions to your eclipse.ini, you could also just start Eclipse with the following options (adjust values if have fewer memory): &lt;pre&gt;eclipse -vmargs -Xms40m -Xmx1024m&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UPDATE: Turn off unneccessary validators&lt;/strong&gt;&lt;br /&gt;
Ah, I totally forgot: In the Window/Preferences menu you will find a section called &quot;Validation&quot;. There are a lot of validators in here that are activated by default but that you won&#039;t ever need for PHP development - such as EJB Validator, JSP Syntax Validator and so on... just turn them off.
&lt;/li&gt;
&lt;/ul&gt;

Now, where in my directory tree was that class again? Let&#039;s just press CRTL-SHIFT-R and find out &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt; 
    </content:encoded>

    <pubDate>Mon, 01 Oct 2007 22:09:42 +0200</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/20-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>Looking back at the Hamburg unconference...</title>
    <link>http://blog.wolff-hamburg.de/archives/19-Looking-back-at-the-Hamburg-unconference....html</link>
            <category>Events</category>
            <category>PHP</category>
            <category>Programming</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/19-Looking-back-at-the-Hamburg-unconference....html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=19</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    It&#039;s been a whopping four weeks since the PHP Unconference Hamburg 2007, which I head the pleasure of co-organizing together with a bunch of really cool people from the local usergroup - namely Judith Andreesen, Florian Blasel, Ekkehard Doerre and Hinrich Sager (order is strictly alphabetically &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;).

Just now, after a week of vacation (involving waking up each day to the sound of chainsaws, hammers and nailguns - &lt;strong&gt;don&#039;t ask&lt;/strong&gt;) I can finally breathe again and blog about it. It was a blast! I never would have dreamed how successful it came out. We were able to use the facilities of our local university, which sponsored three rooms including beamers and internet access (which was more difficult to set up, but in the end far better than at some commercial conferences I&#039;ve attended &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;) and the mensa provided us with lunch (solid, but overpriced). For the smaller in-between snacks, Hinrich&#039;s son along with a few friends provided the catering, which turned out to be a really good idea.

We didn&#039;t just sit, eat and drink, though - the weekend was packed with lots of interesting sessions, and unlike commercial conferences, the attendees were able to suggest and vote for topics they wanted to hear about. In the end, we had one track of pre-planned sessions and two parallel tracks of sessions that were planned just at the beginning of the day. Although this was precisely what we intended, we were a bit sceptical at first how well this would work out - we Germans are notorious for not being spontaneus and needing a plan even for going to the bathroom &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt; But all went well nonetheless. Ekke and especially Judith did a very great job moderating the voting sessions.

Of course, due to the spontaneous nature of the program, there was not always pre-made material available, so in some cases the speakers had to make the session up as they went along, and reactivate their skills in the long-forgotten art of writing on a blackboard (yes, with actual chalk!) instead of just flipping through Powerpoint slides. I was one of them, hosting a session about form frameworks together with Soenke Ruempler.

At one day, we even decided that the lunch break was too long and so a session that could otherwise not fit in the regular timetable anymore was spontaneously squeezed into the lunch break - and it was even pretty well attended &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

I don&#039;t even know right now how many people were actually attending, but it must have been way over 50. We could&#039;ve coped with up to 120, but the fewer people gave the event an athmosphere not unlike a family meeting, just with far more interesting conversations &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/laugh.png&quot; alt=&quot;:-D&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

Many prominent people from the PHP, MySQL and PostgreSQL communities attended. In fact, you could have the impression that the event was co-sponsered by eZ systems and MySQL, as there were so many of their employees there &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

From what I&#039;ve heard, the event was also well-received by the university people, who are keen on getting some more exposure to people working &quot;in the field&quot;, as opposed to purely theoretical work. If we did another unconference, the university will without a doubt jump in as a room sponsor again. 

A few days ago there was a wrapup-meeting, which I was unfortunately unable to attend to, but Judith was kind enough to &lt;a href=&quot;http://www.andresen.de/projekte/unconference/&quot;&gt;post a complete checklist of what we did&lt;/a&gt; and what we&#039;d need to do if we organized another unconference - should you have similar plans in your area, go and have a look, the post is called &lt;a href=&quot;http://www.andresen.de/projekte/unconference/&quot;&gt;How to organize a PHP unconference&lt;/a&gt;. I&#039;m sure you&#039;ll find the information most helpful.

After the huge success of our first unconference, personally, I think that it&#039;s not a question of &lt;strong&gt;if&lt;/strong&gt; we&#039;re gonna do it again, just &lt;strong&gt;when&lt;/strong&gt;. &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;
 
    </content:encoded>

    <pubDate>Sun, 03 Jun 2007 23:36:25 +0200</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/19-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>PHPUG Frankfurt celebrates its 5th anniversary</title>
    <link>http://blog.wolff-hamburg.de/archives/18-PHPUG-Frankfurt-celebrates-its-5th-anniversary.html</link>
            <category>PHP</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/18-PHPUG-Frankfurt-celebrates-its-5th-anniversary.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=18</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    
&lt;p&gt;The PHP User Group Frankfurt am Main (PHPUGFFM) will be celebrating its 5th anniversary tomorrow and is planning for a big party, so if you&#039;re in the area, be sure to drop by! Well, of course it&#039;s a geek party (they&#039;re developers, what did you expect? &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;) so there&#039;ll be plenty of talks before the actual socializing will start.&lt;/p&gt;&lt;p&gt;Session topics will be Unobtrusive Javascript, $YAJQ ++ (who the hell came up with &lt;b&gt;that&lt;/b&gt; one?? &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/wink.png&quot; alt=&quot;;-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;), PHP Homebanking (the sequel), PHP Dos, Don’t and maybes, juicy Joost and ION parser - sounds like a very interesting mix to me.&lt;/p&gt;&lt;p&gt;&lt;a title=&quot;PHPUGFFM Homepage&quot; href=&quot;http://phpugffm.de/index.php/archives/148&quot;&gt;Go to their website to get all the info on the event&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I won&#039;t be there, as I live in Hamburg (a.k.a. up north), not in Frankfurt (a.k.a. down there &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;) and only got word of it today - but I wish all of you guys down there a lot of fun, have a great party &lt;img src=&quot;http://blog.wolff-hamburg.de/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; &lt;br /&gt;&lt;a href=&quot;http://blog.wolff-hamburg.de/archives/18-PHPUG-Frankfurt-celebrates-its-5th-anniversary.html#extended&quot;&gt;Continue reading &quot;PHPUG Frankfurt celebrates its 5th anniversary&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Wed, 09 May 2007 21:54:32 +0200</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/18-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>Thanks, O'Reilly :-D</title>
    <link>http://blog.wolff-hamburg.de/archives/17-Thanks,-OReilly-D.html</link>
            <category>Events</category>
            <category>PHP</category>
            <category>Programming</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/17-Thanks,-OReilly-D.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=17</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    One week left until the &lt;a href=&quot;http://www.php-unconference.de/&quot;&gt;PHP Unconference in Hamburg&lt;/a&gt;, and finally the goodies have arrived &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

O&#039;Reilly was kind enough to sponsor a care package with lots of cool PHP and MySQL related books, writing blocks, pens and key-holding band thingies (what are they called again?). Among the books are timeless classics like PHP in a Nutshell, PHP Design Patterns, PHP Hacks or MySQL Internals... really great stuff!

Here&#039;s what I got from them:

&lt;img src=&quot;http://blog.wolff-hamburg.de/uploads/oreillycarepackage.jpg&quot; /&gt;

The books will be given away to the unconference attendees in a raffle on day two... now all I have to come up with is some fun way to raffle them out &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/laugh.png&quot; alt=&quot;:-D&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

Thanks a lot to Darren Cooper for contacting O&#039;Reilly and making it happen, and of course to O&#039;Reilly for being a cool company and supporting the Open Source community so much. On a side note, I bought a book from Tim O&#039;Reilly himself once, who was helping out at an O&#039;Reilly booth at FOSDEM in Brussels a few years back. It was really cool to see a Multi-Gazillionaire selling books at a rather improvised table that had a bit of a flea-market vibe to it. One can only like the guy &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

Too bad there isn&#039;t a PHP book in my current favourite series of O&#039;Reilly books yet, the &quot;Head First&quot;-series. Kathy Sierra, if you ever read this: Hint, hint &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/laugh.png&quot; alt=&quot;:-D&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt; 
    </content:encoded>

    <pubDate>Sat, 28 Apr 2007 19:49:26 +0200</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/17-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>Is it me or does the Zend website suck?</title>
    <link>http://blog.wolff-hamburg.de/archives/16-Is-it-me-or-does-the-Zend-website-suck.html</link>
            <category>PHP</category>
            <category>Programming</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/16-Is-it-me-or-does-the-Zend-website-suck.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=16</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    Well, as you may have read in my last post, the company I&#039;m working at is currently looking for a PHP developer. To speed up the process of finding one, I had this really bright idea - well, I &lt;strong&gt;thought&lt;/strong&gt; it was bright - to not just wait until people come to us, but actively search for people on the web. So, where to look?

Of course! It&#039;s so obvious - the Zend website has a &lt;a href=&quot;http://www.zend.com/jobs/&quot;&gt;job page&lt;/a&gt; where people can post their resumés. Great! Soo, let&#039;s search for some talent!

I should have known there&#039;d be &lt;strong&gt;no way&lt;/strong&gt; it would be that easy.
 &lt;br /&gt;&lt;a href=&quot;http://blog.wolff-hamburg.de/archives/16-Is-it-me-or-does-the-Zend-website-suck.html#extended&quot;&gt;Continue reading &quot;Is it me or does the Zend website suck?&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Thu, 12 Apr 2007 23:16:26 +0200</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/16-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>Job Offer in Hamburg, Germany</title>
    <link>http://blog.wolff-hamburg.de/archives/15-Job-Offer-in-Hamburg,-Germany.html</link>
            <category>Databases</category>
            <category>Javascript</category>
            <category>PHP</category>
            <category>Programming</category>
            <category>XUL</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/15-Job-Offer-in-Hamburg,-Germany.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=15</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    Another one of the &quot;rather different&quot; blog entries today: My current employer, &lt;a href&quot;http://www.presswatch.de/&quot;&gt;PressWatch&lt;/a&gt;, is searching for a full-time PHP developer. We&#039;re in the media monitoring business - which means, we&#039;re basically searching newspapers, magazines, websites and even TV and radio shows for information relevant to our customers. You may extrapolate from the previous sentence that we&#039;re dealing with quite a lot of data &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

Thus, we&#039;re not searching for someone who can barely code a guestbook. Requirements are:
&lt;ul&gt;&lt;li&gt;Good understanding of OOP in PHP5 (can you say &quot;SPL&quot;?)&lt;/li&gt;
&lt;li&gt;A few years of experience in real-life projects
&lt;/li&gt;&lt;li&gt;Basic knowledge of the Linux/Unix shell (we&#039;re using Linux, FreeBSD and Solaris) 
&lt;ul&gt;&lt;li&gt; Optional: Bash-Scripting basics&lt;/li&gt;&lt;/ul&gt; 
&lt;/li&gt;&lt;li&gt;Some knowledge of regular expressions (no need to be an expert, 
  but if your regex knowledge is very limited you should be willing 
  to learn this) 
&lt;/li&gt;&lt;li&gt;XML-processing with SimpleXML and PHP5-DOM
&lt;/li&gt;&lt;li&gt;Good knowledge in relational databases&lt;ul&gt; 
&lt;li&gt;you know about subqueries, views and triggers 
&lt;/li&gt;&lt;li&gt;you know about normalization and denormalization 
&lt;/li&gt;&lt;li&gt;Optional: PostgreSQL experience 
&lt;/li&gt;&lt;li&gt;Optional: Experience in database optimization (setting indexes, index-clustering, partitioning...)&lt;/li&gt;&lt;/ul&gt; 
&lt;/li&gt;&lt;li&gt;the ability (and willingness &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/laugh.png&quot; alt=&quot;:-D&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;) to quickly grasp complex concepts 
&lt;/li&gt;&lt;li&gt;you have no fear of legacy code &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/laugh.png&quot; alt=&quot;:-D&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt; 
&lt;/li&gt;&lt;/ul&gt;

You should also be able to read (and maybe write) English - I suppose if you can read this, this won&#039;t be a problem &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/laugh.png&quot; alt=&quot;:-D&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;. Spoken English is only a requirement if you don&#039;t speak German (and if you don&#039;t, you should be willing to learn &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;).

This is a job where you can learn a lot, have nice colleagues, an interesting environment, and lots of extremely delicious restaurants nearby (yes, this is &lt;strong&gt;vitally important&lt;/strong&gt; &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/laugh.png&quot; alt=&quot;:-D&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;). Oh, and also very important: Free choice of your desktop operating system!

If you&#039;re interested, please send your application directly to my employer via &lt;a href=&quot;jobs@presswatch.de&quot;&gt;jobs@presswatch.de&lt;/a&gt;. If you&#039;re not, but know someone who is, please spread the word &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt; 
    </content:encoded>

    <pubDate>Tue, 10 Apr 2007 18:00:58 +0200</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/15-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>Announcing the PHP Unconference Hamburg</title>
    <link>http://blog.wolff-hamburg.de/archives/14-Announcing-the-PHP-Unconference-Hamburg.html</link>
            <category>Databases</category>
            <category>Javascript</category>
            <category>PHP</category>
            <category>Programming</category>
            <category>XUL</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/14-Announcing-the-PHP-Unconference-Hamburg.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=14</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    Today I have a little different blog entry for you: On behalf of the PHP Usergroup Hamburg I&#039;m announcing the first PHP Unconference in Hamburg, Germany! The event will take place on May 5th and 6th, at the facilities of the local University (which kindly acts as a co-organizer of the event).

As you may know, we Germans are some strange folks who tend to over-organize everything. Thus, even though it kind of defies the spirit of a true unconference, we&#039;re going to have one slot with pre-planned sessions (topics to be announced shortly before the conference). The University sponsors three rooms though, so even when there&#039;s a session going on, there&#039;ll be plenty opportunity to spontaneously organize two more sessions for all the folks who think the other stuff is completely lame &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

Anyway, to cover the costs there&#039;s going to be a small fee of 20€. The University will provide an optional lunch on both days for an additional 20€. Students of the University of Hamburg rejoice: You&#039;re going to get in for free (lunch excluded &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;). Visitors from outside Hamburg will have to find some place to spend the night, though (alternatively, Hamburg&#039;s Night-Life offers plenty opportunity to get through the night without sleeping, although I think you&#039;d miss out on the second day of the event, then &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;).

We&#039;ve already sent out invitations to a few of the more prominent members of the PHP communities and got several &lt;strong&gt;yes&lt;/strong&gt; and some definite *maybes*, so we&#039;re off to a promising start &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

Get more information at:
&lt;a href=&quot;http://www.php-unconference.de/&quot;&gt;http://www.php-unconference.de/&lt;/a&gt;

Oh, yeah, sorry - the site is in German only. I don&#039;t think I&#039;ll manage to fire up a fully translated site in my limited spare time, but if there&#039;s enough interest from non-German-speakers, I&#039;m sure I can manage to at least translate the registration form. Just drop your comments here or at the Unconference blog.

Hope to see many of you guys in a few weeks! &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/laugh.png&quot; alt=&quot;:-D&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt; 
    </content:encoded>

    <pubDate>Mon, 02 Apr 2007 22:30:46 +0200</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/14-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>Poker-Face</title>
    <link>http://blog.wolff-hamburg.de/archives/12-Poker-Face.html</link>
            <category>Misc</category>
            <category>PHP</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/12-Poker-Face.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=12</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    Well, well... so &lt;a href=&quot;http://www.flickr.com/photos/calevans/285999135/in/set-72157594355906012/&quot;&gt;this is what Cal wanted that photo for&lt;/a&gt;. I am officially something to play with now &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

Reminds me of Disney&#039;s Hercules movie where he found out he&#039;s an action figure (now, that would be some nice idea for the PHP community, right? &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/wink.png&quot; alt=&quot;;-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;). Unfortunately though, unlike Hercules, I&#039;ve got no super-powers... &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/sad.png&quot; alt=&quot;:-(&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

On a totally different topic: The bug that I&#039;ve banged into with APC and PDO a while ago &lt;a href=&quot;http://pecl.php.net/bugs/bug.php?id=8526&quot;&gt;seems to be fixed now&lt;/a&gt; - thanks to Gopal Vijayaraghavan for providing the patch! Now all that&#039;s missing is a new APC release, or alternatively a PDO release fixing that side of the bug &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/laugh.png&quot; alt=&quot;:-D&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt; 
    </content:encoded>

    <pubDate>Thu, 02 Nov 2006 11:58:00 +0100</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/12-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>
<item>
    <title>ActiveRecord enhancements</title>
    <link>http://blog.wolff-hamburg.de/archives/10-ActiveRecord-enhancements.html</link>
            <category>Databases</category>
            <category>PHP</category>
            <category>Programming</category>
    
    <comments>http://blog.wolff-hamburg.de/archives/10-ActiveRecord-enhancements.html#comments</comments>
    <wfw:comment>http://blog.wolff-hamburg.de/wfwcomment.php?cid=10</wfw:comment>

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

    <author>nospam@example.com (Markus)</author>
    <content:encoded>
    After two weeks I finally managed to find a bit of time to continue working on CWAC_ActiveRecord - mainly thanks to the German PHP portal PHP-Center having some kind of server trouble (otherwise, I&#039;d probably have been writing some news posts for them &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/smile.png&quot; alt=&quot;:-)&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;).

Requested by my friend Arnaud was the setConnection() method, that allows to reuse existing PDO objects with CWAC_ActiveRecord. Before this, you could only pass a DSN with the config array and a new connection would always be created.

I&#039;ve also added the limit() and orderBy() methods, whose purposes should be fairly obvious &lt;img src=&quot;http://blog.wolff-hamburg.de/templates/default/img/emoticons/laugh.png&quot; alt=&quot;:-D&quot; style=&quot;display: inline; vertical-align: bottom;&quot; class=&quot;emoticon&quot; /&gt;

Speaking of Arnaud, this friendly dude has recently installed &lt;a href=&quot;https://ssl.limbourg.com/websvn/listing.php?repname=CWAC&amp;path=%2F&amp;sc=0&quot;&gt;WebSVN on our machine&lt;/a&gt; (we&#039;re actually sharing the same server), so viewing the changes to CWAC is not only prettier, but also much more comfortable now, as you can now subscribe to RSS feeds for Subversion changesets.
 
    </content:encoded>

    <pubDate>Mon, 11 Sep 2006 00:03:58 +0200</pubDate>
    <guid isPermaLink="false">http://blog.wolff-hamburg.de/archives/10-guid.html</guid>
    <creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license>
</item>

</channel>
</rss>
