<?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 PHP</title><link>http://planet-php.net</link><description>People blogging about PHP</description><language>en</language><item><title>Composer Dependency Woes - blog.phpdeveloper.org &#xC2;&#xBB; PHP</title><link>http://blog.phpdeveloper.org/?p=491</link><pubDate>Tue, 15 May 2012 21:35:32 +0000</pubDate><description><![CDATA[<p>I spent the better part of this afternoon trying to figure out why a <a href="http://getcomposer.org">Composer</a> installation wasn’t working and <i>finally</i> figured out the problem…it wasn’t mine.</p>
<p>First, a little context – I’m currently working on a testing presentation for some folks at work and I wanted to show them how to work with the <a href="http://behat.org">Behat</a> testing tool to create some handy functional/integration tests for our framework-based apps. I threw together a little framework (yes yes, I know) and got the PHPUnit tests set up and running in no time. When it came to the Behat tests, though, no matter what I did, I was still having a problem:</p>
<pre class="brush: php;">
PHP Fatal error:  Class 'Goutte\Client' not found in /www/htdocs/testing-examples/app/vendor/behat/mink/src/Behat/Mink/Driver/Goutte/Client.php on line 13
</pre>
<p>No matter how I tried to configure the composer install, it always gave me this message. I tried everything I could think of and, finally, at the suggestion of <a href="http://www.rafaeldohms.com.br/">Rafael Dohms</a>, checked out the github repository for the Goutte client (a href=”http://github.com/fabpot/goutte”>here). As it turns out, in the past day or so, there’s been a large change where Fabien implemented composer support on the repo.</p>
<p>Apparently this was what broke things – thankfully not something obvious I was missing.</p>
<p>So, how did I solve it so I could see the lovely green of passing tests again? Well, if you’re familiar with composer, you know there’s a <b>composer.lock</b> file that’s created after you install. When you run the “composer install” and it fetches from “fabpot/goutte”:”*”, you get this latest version that has the issues. A quick modification of the composer.lock file takes care of that though:</p>
<pre class="brush: php;">
{
    "package": "fabpot/goutte",
    "version": "master-dev",
    "source-reference": "5ecceb7c28a428fb93f283982cc4f5edfd96630b"
},
</pre>
<p>See that “source-reference” setting? Well, that can either point to the branch or version you want to pull from or it can point to a specific commit. In my case, I just pulled the hash for the <a href="https://github.com/fabpot/Goutte/commit/5ecceb7c28a428fb93f283982cc4f5edfd96630b">commit before all of the changes</a> and dropped it in there. Then it’s just a matter of running a “composer install” to get the code from this commit instead. <b>Don’t run an update</b> though – that will wipe out your manual changes to the lock file and you’ll be back to square one. </p>
<p>Hope this helps someone out there who might be dealing with a similar issue regarding brokenness on an external lib!</p>
]]></description></item><item><title>Some throttling for PECL/mysqlnd_ms 1.4 - Ulf Wendel</title><link>http://blog.ulf-wendel.de/2012/some-throttling-for-peclmysqlnd_ms-14/</link><pubDate>Tue, 15 May 2012 13:11:37 +0000</pubDate><description><![CDATA[	<p>
Users of MySQL Replication sometimes throttle client requests to give slaves time to catch up to the master. <a href="http://www.php.net/mysqlnd_ms">PECL/mysqlnd_ms</a> 1.4, the current development version, features some throttling through the quality-of-service filter and global transaction identifier (GTID). Both the plugins <a href="http://de3.php.net/manual/de/mysqlnd-ms.gtid.php">client-side GTID emulation</a> and the <a href="http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html">MySQL 5.6 built-in GTID feature</a> can be used to slow down PHP MySQL requests, if wanted.
</p>
	<h3>How its done</h3>
	<p>
The replication plugin has a neat feature called <a href="http://de3.php.net/manual/de/mysqlnd-ms.qos-consistency.php">quality-of-service</a> filter. If, for example, the quality of service you need from a MySQL Replication cluster is "read your writes", you call <code><a href="http://de3.php.net/mysqlnd_ms_set_qos">mysqlnd_ms_set_qos</a>($connection, MYSQLND_MS_QOS_CONSISTENCY_SESSION)</code>. This instructs the plugin to either use a master or a slave, that has replicated your writes already, for all further reads. The plugin takes care of picking an appropriate cluster node. Once you are done with "read your writes" you can relax the service quality to make node selection faster.
</p>
	<p>
By default, <code>MYSQLND_MS_QOS_CONSISTENCY_SESSION</code> will enforce reading from the master. This is undesired as it increases the load on the master. However, before the introduction of global transaction identifiers, there was no safe way of knowing whether a slave had replicated a certain update already or not.
</p>
	<p>
Using either the plugins GTID emulation or the MySQL 5.6 build-in GTID feature, one can reliably check the up-to-date status of a slave using a SQL <code>SELECT</code> statement.  GTIDs are some kind of unique transaction sequence numbers. If you know the transaction sequence number of a write operation, you can check whether it has been replicated using a statement like, for example, <code>SELECT GTID_SUBSET('gtid_of_write', @@GLOBAL.GTID_DONE) AS trx_id FROM DUAL</code>. Please, check my previous posts for a more precise description of the GTID feature. This statement will check the replication status and return immediately.</p>
	<p/><h3>SQL_THREAD_WAIT_AFTER_GTIDS(string gtids [, timeout])</h3>
	<p>
Alternatively, a MySQL 5.6 user can issue <code>SELECT SQL_THREAD_WAIT_AFTER_GTIDS('gtid_of_write')</code> which will block until either the slave has replicated the write in question or the statement times out. This is great to throttle clients and prevent them to send new updates before the slaves have caught up. This is what <em>some</em> throttling is about. You can control which logic PECL/mysqlnd_ms shall use when searching for an up-to-date slave.
</p>
	<p><a id="more-354"/></p>
	<p>
Strictly speaking, you could do it in 1.3 already, if using MySQL 5.6, which is not GA yet. GTIDs are opaque to the plugin. The configuration contains a SQL statement to fetch <code>gtid_of_write</code> and one to check if <code>gtid_of_write</code> has been replicated already. You have been free to either use  <code>SQL_THREAD_WAIT_AFTER_GTIDS</code> or not for those config settings.
</p>
	<h3>The new bit</h3>
	<p>
New is a <code>wait_for_gtid_timeout</code> setting that can be used with the GTID emulation. If <code>wait_for_gtid_timeout</code> is set, the plugin will poll a slaves state for <code>wait_for_gtid_timeout</code> seconds regardless of the SQL statement configured. The plugin first runs the SQL statement to check if <code>gtid_of_write</code> has been replicated already. If not, it checks if there is time left for another poll attempt, sleeps for second and polls the status again.
</p>
	<p>
All this is done transparently in the background. All the application does is formulate its quality of service needs.
</p>
	<h3>Throttling makes synchronization costs visible</h3>
	<p>
Throttling client requests should not be understood as a hack. MySQL Replication happens to be a lazy primary copy system. All updates must be performed on the primary (master). Synchronization of secondaries (slaves) is lazy. Update transactions are finished once the primary has finished them.  An update transaction never waits for secondaries to catch up. This is an easy to implement, often fast and simple approach.
</p>
	<p>
The drawbacks are temporarily stale data on the secondaries and limited gains in availability over a single server.
</p>
	<p>
Clients get confirmation for update transactions as soon as they are finished on the primary. As soon as they are saved on just one server. There is no guarantee that the transaction ever makes it to a secondary. In the unlikely worst case, the primary crashes in an unrecoverable manner and transactions are lost before being replicated. Thus, little gain over a single server. If you don’t want that, you need eager synchronization. This is</p><p><i>Truncated by Planet PHP, read more at <a href="http://blog.ulf-wendel.de/2012/some-throttling-for-peclmysqlnd_ms-14/">the original</a> (another 1936 bytes)</i></p>]]></description></item><item><title>Sami: Yet another PHP API documentation generator - Fabien Potencier</title><link>http://feeds.fabien.potencier.org/~r/aidedecamp/~3/1NqPufqqSeg/sami-yet-another-php-api-documentation-generator</link><pubDate>Tue, 15 May 2012 11:58:00 +0000</pubDate><description><![CDATA[
    <p>Today is my "<em>let open source some of my private Github repositories</em>" day,
and more specifically, I'm releasing a bunch of code related to documentation.</p>

<p>Earlier today, I've released the Sphinx
<a href="https://github.com/fabpot/sphinx-php">extensions</a> I'm using to generate the
<a href="http://symfony.com/doc">Symfony</a> documentation.</p>

<p>And now, I'm releasing my API documentation
<a href="https://github.com/fabpot/Sami">generator</a>. Yes, I know that PHP already has
a bunch of such generators, but I started to work on this project several
years ago, when the only viable option was the old phpdocumentor.</p>

<p>Nowadays, <a href="http://phpdoc.org/">phpDocumentor</a> version 2 is probably the best
option out there as it has a good architecture, it works fine, it is
extensible, and quite a few big PHP projects is already using it. And that's
fine. I don't want to compete with it, I don't want to replace it, I'm just
open sourcing some code used by <a href="http://api.symfony.com/">Symfony</a>,
<a href="http://silex.sensiolabs.org/api/index.html">Twig</a>, and
<a href="http://silex.sensiolabs.org/api/index.html">Silex</a> because I'm not
comfortable with closed-source software. And to be totally honest and
transparent, I have not released the code before because it was not "good
enough".</p>

<p>With this disclaimer out of the way, let's see what makes Sami "different"
(compared to phpdocumentor)?</p>

<ul><li><p>It uses a PHP file for configuration to give a very flexible way of
tweaking the API generation;</p></li>
<li><p>It uses <a href="http://twig.sensiolabs.org/">Twig</a> for templating;</p></li>
<li><p>It uses a dependency injection container
(<a href="https://github.com/fabpot/Pimple">Pimple</a>) to let you override any
internal class;</p></li>
<li><p>It only works with PHP 5.3 (but it can generate documentation for PHP 5.2
projects);</p></li>
<li><p>It uses the excellent <a href="https://github.com/nikic/PHP-Parser">PHP Parser</a>
project for PHP code parsing;</p></li>
<li><p>It is able to manage versions of your code to generate documentation for
all of them in a single tree (without the overhead of re-parsing everything
for each version of course).</p></li>
</ul><p>Curious about what Sami generates? Have a look at the <a href="http://api.symfony.com/">Symfony
API</a>.</p>

<h2>Installation</h2>

<p>First, get Sami from <a href="https://github.com/fabpot/Sami">Github</a> (or integrate it
as a dependency in your project <a href="http://packagist.org/packages/sami/sami">Composer</a> file --
you are using <a href="http://getcomposer.org/">Composer</a>, right?):</p>

<pre class="text">https://github.com/fabpot/Sami
 </pre>

<p>You can also download an <a href="https://github.com/fabpot/Sami/downloads">archive</a>
from Github.</p>

<p>As Sami uses Composer to manage its dependencies, installing it is a matter of
running composer:</p>

<pre class="command-line"><code>$ composer.phar install
</code></pre>

<p>Check that everything worked as expected by executing the <code>sami.php</code> file
without any arguments:</p>

<pre class="command-line"><code>$ php sami.php
</code></pre>

<h2>Configuration</h2>

<p>Before generating documentation, you must create a configuration file. Here is
the simplest possible one:</p>

<pre class="php"><span class="kw2">&lt;?php</span>
 
<span class="kw1">return</span> <span class="kw2">new</span> Sami\Sami<span class="br0">(</span><span class="st0">'/path/to/symfony/src'</span><span class="br0">)</span>;
 </pre>

<p>The configuration file must return an instance of <code>Sami\Sami</code> and the first
argument of the constructor is the path to the code you want to generate
documentation for.</p>

<p>Actually, instead of a directory, you can use any valid PHP iterator (and for
that matter any instance of the Symfony
<a href="http://symfony.com/doc/current/components/finder.html">Finder</a> class):</p>

<pre class="php"><span class="kw2">&lt;?php</span>
 
use Sami\Sami;
use Symfony\Component\Finder\Finder;
 
<span class="re0">$iterator</span> = Finder::<span class="me2">create</span><span class="br0">(</span><span class="br0">)</span>
    -><span class="me1">files</span><span class="br0">(</span><span class="br0">)</span>
    -><span class="me1">name</span><span class="br0">(</span><span class="st0">'*.php'</span><span class="br0">)</span>
    -><span class="me1">exclude</span><span class="br0">(</span><span class="st0">'Resources'</span><span class="br0">)</span>
    -><span class="me1">exclude</span><span class="br0">(</span><span class="st0">'Tests'</span><span class="br0">)</span>
    -><span class="me1">in</span><span class="br0">(</span><span class="st0">'/path/to/symfony/src'</span><span class="br0">)</span>
;
 
<span class="kw1">return</span> <span class="kw2">new</span> Sami<span class="br0">(</span><span class="re0">$iterator</span></pre><p><i>Truncated by Planet PHP, read more at <a href="http://feeds.fabien.potencier.org/~r/aidedecamp/~3/1NqPufqqSeg/sami-yet-another-php-api-documentation-generator">the original</a> (another 8447 bytes)</i></p>]]></description></item><item><title>Interview with Derick Rethans - Cal Evans</title><link>http://feedproxy.google.com/~r/VoicesOfTheElephpant/~3/xGKhH3fniy4/</link><pubDate>Tue, 15 May 2012 05:00:39 +0000</pubDate><description><![CDATA[<p>Blog:<a href="http://derickrethans.nl/">http://derickrethans.nl/</a><br />
Twitter: <a href="https://twitter.com/derickr">@derickr</a></p>
<p></p>
<h3>Show Notes:</h3>
<ul>
<li><a href="http://www.phplondon.org/" target="_blank">http://www.phplondon.org/</a></li>
<li><a href="http://xdebug.com/" target="_blank">http://xdebug.com/</a></li>
</li>
</ul>
<p>Sponsored by:<br />
Engine Yard<br />
<a href="http://ey.io/ysQPLf"><img title="engineyard" src="http://voicesoftheelephpant.com/wp-content/uploads/2012/02/engineyard.png" alt="" width="300" height="101" /></a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/VoicesOfTheElephpant?a=xGKhH3fniy4:lcvwV6vCHR4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/VoicesOfTheElephpant?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/VoicesOfTheElephpant?a=xGKhH3fniy4:lcvwV6vCHR4:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/VoicesOfTheElephpant?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/VoicesOfTheElephpant/~4/xGKhH3fniy4" height="1" width="1"/>]]></description></item><item><title>Quick and Dirty REST Security (or Hashes For All!) - blog.phpdeveloper.org &#xC2;&#xBB; PHP</title><link>http://blog.phpdeveloper.org/?p=484</link><pubDate>Mon, 14 May 2012 21:44:37 +0000</pubDate><description><![CDATA[<p>So in working up a new RESTful service I’ve been tinkering with, I wanted to provide some kind of “authentication” system for it. I started to look into OAuth, but got a bit overwhelmed by everything that was involved with it. Looking for something a bit more lightweight (and simpler to implement a bit more quickly) I came across <a href="http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/">this older article</a> with a suggestion of a private key/hash combination. I figured that could do the job nicely for a first shot, so I set to implementing it.</p>
<h3>On the Server Side</h3>
<p>I’m using the <a href="http://fuelphp.com">FuelPHP</a> framework for this one, but that’s really only giving me a structure to work in and pull the request information from. This would work in most major frameworks (and even outside of one if you you’re a “do it my way” kind of developer). First off, let’s start with the controller side:</p>
<pre class="brush: php;">
&lt;?php
class Controller_User extends Controller_Rest
{
    protected function validateHash()
    {
        $request = file_get_contents('php://input');
        $requestHeaders = apache_request_headers();

        if (!isset($requestHeaders['X-Auth']) || !isset($requestHeaders['X-Auth-Hash'])) {
            $this->response('fail!',401);
        } else {
            // we have the headers - let's match!
            $user = Model_User::find()->where('public_key',$requestHeaders['X-Auth'])->get_one();

            if ($user !== null) {
                $hash = hash_hmac('sha256',$request,$user->private_key);
                return ($hash == $requestHeaders['X-Auth-Hash']) ? true : false;
            } else {
                return false;
            }
        }
    }

    public function post_index()
    {
        // return the user details here....
    }

    public function router($resource, array $arguments)
    {
        if ($this->validateHash() == false) {
            $resource = 'error';
            $arguments = array('Not Authorized',401);
        }

        parent::router($resource,$arguments);
    }
}
?>
</pre>
<p>There’s a lot going on here, so let me walk you through each of the steps:</p>
<ol><li>First off, we’re making a RESTful service, so we’re going to extend the <b>Controller_Rest</b> that Fuel comes with. It has some handy special routing. Our POST request in the example below would try to hit the “post_index” method and have its hashes checked in the process.
</li>
<li>Next up is the <b>“validateHash”</b> method – this is where the hard work happens:
<ul><li>The request and headers are read into variables for easier use ($request and $requestHeaders).
</li>
<li>It then checks to be sure that both of our required headers are set (X-Auth and X-Auth-Hash). There’s nothing magical about these header names, so they can be switched out depending on need and naming preference.
</li>
<li>If they’re there, the next step is to find the user based on the public key that was sent. This value is okay to openly share because, without the private key to correctly hash the data, your requests will fail.
</li>
<li>The <a href="http://php.net/hash_hmac">hash_hmac</a> function is then used (with the “sha256″ hash type) to regenerate the hash off of the contents of the request and the private key on the found user.
</li>
</ul></li>
<li>If all goes well, the request continues on and the “post_index” method is used. If it fails, however, the check in the “route” method of the controller makes a switch. It changes the currently requested resource to “/error/index” instead of what the user wants. This seamlessly shows the user a “Not Authorized” error message (401) if the hash checking fails.
</li>
</ol><h3>A Client Example</h3>
<p>Now, to help make it a bit clearer, here’s an example little script showing a <a href="http://php.net/curl">curl</a> request using the hashes:</p>
<pre class="brush: php;">
&lt;?php

$privateKey = 'caa68fb2160b428bd1e7d78fcf0ce2d5';
$publicKey  = '01fa456c4e2a2bc13e5c0c4977297fbb';

$data = '{"username":"happyFunBall"}';
$hash = hash_hmac('sha256',$data,$privateKey);

$headers = array(
    'X-Auth: '.$publicKey,
    'X-Auth-Hash: '.$hash
);

$ch = curl_init('http://mysite.localhost:8080/user');

curl_setopt($ch,CURLOPT_HEADER,true);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);

$result = curl_exec($ch);
curl_close($ch);

print_r($result);
echo "\n\n";
?>
</pre>
<p>You can see that both the public and private keys are specified (but on the PHP side, not visible to the user) and are sent as the “X-Auth*” headers as a part of the request. In this case, we’re POSTing to the &</p><p><i>Truncated by Planet PHP, read more at <a href="http://blog.phpdeveloper.org/?p=484">the original</a> (another 733 bytes)</i></p>]]></description></item><item><title>PHP as a templating language - Sean Coates</title><link>http://seancoates.com/blogs/php-as-a-templating-language</link><pubDate>Mon, 14 May 2012 15:06:34 +0000</pubDate><description><![CDATA[<p>There’s been quite a bit of talk, recently, in PHP-land about templates and the ramifications of enforcing “pure” PHP scripts by <a href="https://wiki.php.net/rfc/phpp">preventing scripts from entering html mode</a>. I’m not quite sure how I feel about this RFC, but it got me thinking about the whole idea of using PHP for templating in modern web apps.</p>

<p>For many years, I was a supporter of using PHP as a templating language to render html. However, I really don’t buy into the idea of adding an additional abstraction layer on top of PHP, such as <a href="http://smarty.php.net/">Smarty</a> (and many others). In the past year or so, I’ve come to the realization that even PHP itself is no longer ideally suited to function as the templating engine of current web applications — at least not as the primary templating engine for such apps.</p>

<p>The reason for this evolution is simple: modern web apps are no longer fully server-driven.</p>

<p>PHP, as you know, is a server technology. Rendering html on the server side was fine for many years, but times have changed. Apps are becoming more and more <a href="http://phpadvent.org/2010/first-class-apis-by-helgi-%C3%9Eormar-%C3%9Eorbj%C3%B6rnsson">API-driven</a>, and <a href="http://json.org/">JSON</a> is quickly becoming the de facto standard for API envelopes.</p>

<p>We can no longer assume that our data will be rendered in a browser, nor that it will be rendered exclusively in html. With <a href="https://gimmebar.com/">Gimme Bar</a>, we render html server-side (to reduce page load latency), in JavaScript (when adding or changing elements on an already-rendered page), in our <a href="https://gimmebar.com/api/v1">API</a> (upcoming in a future enhancement), in our iPhone app, and certainly in other places that I’m forgetting.</p>

<p>Asset rendering in Gimme Bar can be complicated — especially for embed assets. We definitely don’t want to maintain the render logic in more than one place (at least not for the main app). We regularly need to render elements in both html and JavaScript.</p>

<p>This is precisely why we don’t directly use PHP to render page elements anymore. We use <a href="http://mustache.github.com/">Mustache</a> (and Mustache-compatible <a href="http://handlebarsjs.com/">Handlebars</a>). This choice allows us to easily maintain one (partial) template for elements, and we can render those elements on the platform of our liking (which has been diversifying more and more lately, but is still primarily PHP and JavaScript).</p>

<p>Rendering elements to html on the server side, even if transferred through a more dynamic method such as via <a href="http://en.wikipedia.org/wiki/XMLHttpRequest">XHR</a>, really limits what can be done on the display side (where “display side” can mean many things these days — not just browsers).</p>

<p>We try hard to keep the layers our web applications separated through patterns such as Model/View/Controller, but for as long as we’ve been doing so, we’ve often put the view bits in the wrong place. This was appropriate for many years, but now it is time to leave the rendering duties up to the layer of your application that is actually performing the view. This is often your browser.</p>

<p>For me, this has become the right way to do things: avoid rendering html exclusively on the server side, and use a techonology that can push data rendering to your user’s client.</p>


]]></description></item><item><title>Speaking at OSCON 2012 - Lorna Mitchell</title><link>http://feedproxy.google.com/~r/lornajane/php/~3/R4fNAbpQdaw/speaking-at-oscon-2012</link><pubDate>Mon, 14 May 2012 07:22:53 +0000</pubDate><description><![CDATA[<p>In July, I'm speaking at OSCON.  Actually I have a few interesting speaking engagements coming up, and I haven't got around to adding upcoming dates to my blog yet but I'll be at phpDay in Verona next week with a talk on API Design and DPC in Amsterdam in June with a tutorial on Web Services and a talk on what OAuth is actually for.</p>
<p>OSCON is special because I have always wanted to go and never imagined it would actually happen.  Every year I read the list of sessions from the year before, and decide that I absolutely must submit to the call for papers, regardless of how small I think my chances of being accepted are!  I've submitted a couple of times in the past, excluding last year because I was newly freelance (OSCON does not cover any speaker expenses at all, they just give you a conference pass.  That's kind of hard going for those of us self-funding halfway across the world, and last year, I just couldn't do it.  This year I still can't really justify it but I'm going anyway!)<span id="more-1665"></span></p>
<p>I have two talks, both of them brand new, and I'm excited about them both!</p>
<h3>PHP 5.4 Features You'll Actually Use</h3>
<p>When I told one of my local user groups (how excellent to have more than one local user group!) about this talk they said "that'll be a short talk" and I am a little worried they are right!  Cool new array syntax, traits, and a web server ... am I missing anything important?  To make this even easier and more fun, Rasmus has the slot immediately before mine and his abstract includes "a detailed review of new PHP 5.4 features".  I feel like a spare part and I haven't even written the talk yet!</p>
<h3>Get Some Rest: Best RESTful API Practices</h3>
<p>This one will be lots of fun, because I firmly believe in writing services that make users, rather than textbooks, very happy.  Which means that I do break the rules and I think there are times when that's acceptable.  I suspect that there will be heckling, flaming, and foaming at the mouth involved but hey, I'm not there to be popular!  Honestly, I love REST, I think it's possible to take it too far, and I'm only a little bit scared to say that in public :)</p>
<h3>OSCON Conversations</h3>
<p>OSCON does a cool thing where it opens the comments on a talk page immediately - which means that you can already go and ask questions, make requests, or leave comments on either my <a href="http://www.oscon.com/oscon2012/public/schedule/detail/23503">PHP 5.4 talk</a> or the <a href="http://www.oscon.com/oscon2012/public/schedule/detail/23508">RESTful one</a> and let me know what you do (and perhaps do NOT) want to hear.  If you're going to OSCON or are just interested in the topics, I'm interested to hear your thoughts, either over here in the comments or over on the talks themselves!</p>
<p>Lorna is an independent web development consultant, writer and trainer, open source project lead and community evangelist.  This post was originally published at <a href="http://www.lornajane.net">LornaJane</a></p>
<img src="http://feeds.feedburner.com/~r/lornajane/php/~4/R4fNAbpQdaw" height="1" width="1"/>]]></description></item><item><title>Magento CE 1.7 forked on GitHub - Mayflower Blog - PHP</title><link>http://blog.mayflower.de/archives/868-Magento-CE-1.7-forked-on-GitHub.html</link><pubDate>Sat, 12 May 2012 15:08:17 +0000</pubDate><description><![CDATA[
    <p>
[This blog post is also available in <a href="http://blog.mayflower.de/archives/867-Magento-CE-1.7-auf-GitHub-geforkt.html">German</a>.]
</p>
<p> </p>
<p>
Yesterday, it was the news of the day: Magento CE 1.7 was forked on GitHub by some community people. After the spectacular departure of Yoav Kutner, then-CTO at Magento (<a href="http://techcrunch.com/2012/04/12/recently-departed-magento-cto-and-co-founder-ebay-doesnt-understand-the-meaning-of-open/" title="eBay doesn't understand the meaning of Open" target="_blank">TechCrunch</a> reported), it was just a matter of time until Magento was forked. Indeed, as Vinai Kopp <a href="http://twitter.com/#!/VinaiKopp/status/200956795475337218" title="Vinai Kopp mentioning another Magento Fork" target="_blank">pointed out on twitter</a>, there have been some forks of Magento already (project <a href="https://github.com/markkimsal/agent-ohm" title="GitHub repo of agent-ohm, an old Magento fork" target="_blank">agent-ohm</a>, a fork of Magento 1.3), but Mage+ seems to be another case.
</p>
<p>
What are the reasons of the <a href="https://github.com/mageplus/mageplus" title="Mage+ on GitHub" target="_blank">fork of Magento</a>? And what's in it for the Magento community?
</p> <br /><a href="http://blog.mayflower.de/archives/868-Magento-CE-1.7-forked-on-GitHub.html#extended">Continue reading "Magento CE 1.7 forked on GitHub"</a>
    ]]></description></item><item><title>Query parameter handling in Symfony2 - Lukas Smith</title><link>http://pooteeweet.org/blog/0/2096</link><pubDate>Sat, 12 May 2012 14:02:25 +0000</pubDate><description><![CDATA[<p>So this topic has been going back and forth in my head a lot over the last months: how do we best handle query parameters in Symfony2? Obviously you can already <a href="http://symfony.com/doc/master/components/http_foundation/introduction.html#accessing-request-data">access query parameters</a> today already but it could be easier. Essentially what I want is a way for developers to easily configure what query parameters they expect and what values they expect. This is useful for several things like easier reading and validating of query parameters, self documenting API both for <a href="https://github.com/nelmio/NelmioApiDocBundle"> API docs</a> for humans but also <a href="https://github.com/FriendsOfSymfony/FOSRestBundle/issues/52">for machines</a>. Now thanks to <a href="http://twitter.com/#!/iam_asm89">Alexander</a> we have a <a href="https://github.com/FriendsOfSymfony/FOSRestBundle/pull/185">solution</a> that <a href="https://github.com/liip/LiipHelloBundle/blob/query_param-proof-of-concept/Controller/RestController.php#L36">works</a>. But there is the big question if this is really the right approach. For now ignore the fact that it only works with annotations for now, because that is fixable. But it does point to the question if this shouldn't be integrated into the routing configuration itself by <a href="https://github.com/symfony/symfony/issues/3227">adding query support</a> for our implementation of uri-templates.</p>

<p>While this at first seems like the right place for this sort of configuration, it raises the questions of its own since path parameters (i.e. /{foo}) should be handled differently than query parameters (i.e. /{?bar}). For one I don't think that a mismatch on a <a href="http://symfony.com/doc/master/book/routing.html#adding-requirements">route requirement</a> of a query parameter cause the route to not match. However then it can quickly become confusing for the end user or it would require adding more and more syntax to handle all the different cases.</p>

<p>Feedback much appreciated!</p>

<p><strong>Update</strong>: I have just merged the <a href="https://github.com/FriendsOfSymfony/FOSRestBundle/pull/185">change</a> to FOSRestBundle.</p>

]]></description></item><item><title>Nelmio is coming to a conference near you - Nelmio</title><link>http://nelm.io/blog/2012/05/nelmio-is-coming-to-a-conference-near-you/</link><pubDate>Fri, 11 May 2012 10:19:08 +0000</pubDate><description><![CDATA[<p>Here is a quick update on conferences we will attend and speak at in the next couple months. If you are attending any, feel free to come and say hi!</p>

<p>Next week our entire team will be at <strong><a href="http://www.jsday.it/">jsDay</a></strong> and <strong><a href="http://2012.phpday.it/">phpDay</a></strong> in Verona, Italy. If you haven’t got tickets yet, hurry up because it is about to be sold out.</p>

<p>Pierre will talk about <a href="http://2012.jsday.it/talk/backbone-js-ftw/">Backbone.js</a>, Igor has two talks about <a href="http://2012.jsday.it/talk/realtime-web-apps-with-websockets/">realtime apps with websockets</a> and the <a href="http://2012.phpday.it/talk/silex-the-symfony2-microframework/">Silex microframework</a> and I myself will be talking about <a href="http://2012.phpday.it/talk/dependency-management-with-composer/">managing your dependencies with Composer</a>.</p>

<p>In June there are two notable events. The first is <strong><a href="http://techup.ch/646/swissjeese-2012">SwissJeese</a></strong>. A local JavaScript-oriented conference co-organized by Pierre that will be in Bern. It is free and on a Saturday so there is really no excuse not to come if you have an interest in JavaScript. <strong>Register for free</strong> on <a href="https://swissjeese.eventbrite.com/">eventbrite</a>!</p>

<p>The second a week later is <strong><a href="http://paris2012.live.symfony.com/">Symfony Live</a></strong> in Paris which we are always looking forward to.</p>

<p>If you get a chance to go to both phpDay and Symfony Live, you can follow Igor’s second talk about <a href="http://paris2012.live.symfony.com/speakers#session-593">Silex</a>, which will be more advanced given the audience is already more familiar with the Symfony Components. If you miss Verona you can catch up on my <a href="http://paris2012.live.symfony.com/speakers#session-543">Composer</a> talk in Paris as well. William will hold an <a href="http://paris2012.live.symfony.com/speakers#session-649">introduction to the Propel2 ORM</a> and even you have no interest in PHP I will present the <a href="http://paris2012.live.symfony.com/speakers#session-583">Redis key-value store</a> so you can come anyway ;)</p>

<p>We sure hope to see some old friends and make new ones there, so if you were hesitant to come, just register before it’s too late!</p>
]]></description></item></channel></rss>

