<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Christer&#039;s blog o&#039; fun</title>
	<atom:link href="http://cogo.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://cogo.wordpress.com</link>
	<description>Christer Edvartsen&#039;s blog about ... stuff!</description>
	<lastBuildDate>Fri, 27 Jan 2012 10:37:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='cogo.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Christer&#039;s blog o&#039; fun</title>
		<link>http://cogo.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://cogo.wordpress.com/osd.xml" title="Christer&#039;s blog o&#039; fun" />
	<atom:link rel='hub' href='http://cogo.wordpress.com/?pushpress=hub'/>
		<item>
		<title>PHP_BitTorrent-0.2.0 released</title>
		<link>http://cogo.wordpress.com/2012/01/04/php_bittorrent-0-2-0-released/</link>
		<comments>http://cogo.wordpress.com/2012/01/04/php_bittorrent-0-2-0-released/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 18:20:36 +0000</pubDate>
		<dc:creator>christer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[bittorrent]]></category>
		<category><![CDATA[github]]></category>

		<guid isPermaLink="false">http://cogo.wordpress.com/?p=1143</guid>
		<description><![CDATA[During my Christmas vacation I received a pull request on GitHub for my PHP_BitTorrent project which added proper namespaces to the classes. I decided to merge the pull request and do some other changes as well. I removed the static &#8230; <a href="http://cogo.wordpress.com/2012/01/04/php_bittorrent-0-2-0-released/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1143&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>During my Christmas vacation I received a <a href="https://github.com/christeredvartsen/php-bittorrent/pull/1" target="_blank">pull request</a> on GitHub for my <a href="https://github.com/christeredvartsen/php-bittorrent" target="_blank">PHP_BitTorrent project</a> which added <a href="http://no.php.net/namespace" target="_blank">proper namespaces</a> to the classes. I decided to merge the pull request and do some other changes as well. I removed the static methods and added instance methods instead which, IMHO, makes the API cleaner, and more important, made the code easier to test.</p>
<p>There are some example usage and instructions on how to install PHP_BitTorrent <a href="https://github.com/christeredvartsen/php-bittorrent/blob/0.2.0/README.markdown" target="_blank">over at the project page on GitHub</a>.</p>
<p>I have also done some more work on the BitTorrent tracker part of the project which is <a href="https://github.com/christeredvartsen/php-bittorrent/tree/including-tracker" target="_blank">available in a separate branch</a> (not a part of the 0.2.0 release). Feel free to play around with it and don&#8217;t hesitate to send me a pull request if you have improvements for it.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cogo.wordpress.com/1143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cogo.wordpress.com/1143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cogo.wordpress.com/1143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cogo.wordpress.com/1143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cogo.wordpress.com/1143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cogo.wordpress.com/1143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cogo.wordpress.com/1143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cogo.wordpress.com/1143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cogo.wordpress.com/1143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cogo.wordpress.com/1143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cogo.wordpress.com/1143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cogo.wordpress.com/1143/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cogo.wordpress.com/1143/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cogo.wordpress.com/1143/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1143&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cogo.wordpress.com/2012/01/04/php_bittorrent-0-2-0-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c7f00126a1c4ba53bba8f7f37e347a3?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cogo</media:title>
		</media:content>
	</item>
		<item>
		<title>Fat Models, Chubby Routes, Super-Skinny Controllers</title>
		<link>http://cogo.wordpress.com/2011/11/08/fat-models-chubby-routes-super-skinny-controllers/</link>
		<comments>http://cogo.wordpress.com/2011/11/08/fat-models-chubby-routes-super-skinny-controllers/#comments</comments>
		<pubDate>Tue, 08 Nov 2011 13:19:17 +0000</pubDate>
		<dc:creator>christer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Work related]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://cogo.wordpress.com/?p=1133</guid>
		<description><![CDATA[We have just started a blog at work where we will be writing about some of the technologies we use daily. I just wrote a post about beefing up the routes in Zend Framework applications. Read all about it over &#8230; <a href="http://cogo.wordpress.com/2011/11/08/fat-models-chubby-routes-super-skinny-controllers/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1133&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>We have just started a blog at work where we will be writing about some of the technologies we use daily. I just wrote a post about beefing up the routes in Zend Framework applications.</p>
<p><a href="http://tech.vg.no/2011/11/08/fat-models-chubby-routes-super-skinny-controllers/" target="_blank">Read all about it over at VG Tech</a>.</p>
<p>I will continue to write on this blog, but if you are interested in web technologies be sure to checkout <a href="http://tech.vg.no/" target="_blank">VG Tech</a> as well.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cogo.wordpress.com/1133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cogo.wordpress.com/1133/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cogo.wordpress.com/1133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cogo.wordpress.com/1133/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cogo.wordpress.com/1133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cogo.wordpress.com/1133/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cogo.wordpress.com/1133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cogo.wordpress.com/1133/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cogo.wordpress.com/1133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cogo.wordpress.com/1133/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cogo.wordpress.com/1133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cogo.wordpress.com/1133/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cogo.wordpress.com/1133/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cogo.wordpress.com/1133/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1133&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cogo.wordpress.com/2011/11/08/fat-models-chubby-routes-super-skinny-controllers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c7f00126a1c4ba53bba8f7f37e347a3?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cogo</media:title>
		</media:content>
	</item>
		<item>
		<title>Playing with traits in PHP 5.4alpha1</title>
		<link>http://cogo.wordpress.com/2011/07/01/playing-with-traits-in-php-5-4alpha1/</link>
		<comments>http://cogo.wordpress.com/2011/07/01/playing-with-traits-in-php-5-4alpha1/#comments</comments>
		<pubDate>Fri, 01 Jul 2011 10:08:51 +0000</pubDate>
		<dc:creator>christer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[traits]]></category>

		<guid isPermaLink="false">http://cogo.wordpress.com/?p=1112</guid>
		<description><![CDATA[PHP 5.4alpha1 was released the other day with some cool new features. One of them is an implementation of traits. From the RFC: Traits is a mechanism for code reuse in single inheritance languages such as PHP. A Trait is &#8230; <a href="http://cogo.wordpress.com/2011/07/01/playing-with-traits-in-php-5-4alpha1/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1112&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.php.net/archive/2011.php#id2011-06-28-1" target="_blank">PHP 5.4alpha1</a> was released the other day with some cool new features. One of them is an implementation of <a href="http://en.wikipedia.org/wiki/Trait_%28computer_science%29" target="_blank">traits</a>. From the <a href="https://wiki.php.net/rfc/traits" target="_blank">RFC</a>:</p>
<blockquote cite="https://wiki.php.net/rfc/traits"><p>Traits is a mechanism for code reuse in single inheritance languages such as PHP. A Trait is intended to reduce some limitations of single inheritance by enabling a developer to reuse sets of methods freely in several independent classes living in different class hierarchies. The semantics of the combination of Traits and classes is defined in a way, which reduces complexity and avoids the typical problems associated with multiple inheritance and Mixins.</p></blockquote>
<p>There are some nice examples over at the RFC, and I will provide another example in this post.</p>
<p>But first, to be able to play with this we need to build PHP. It&#8217;s the usual <code>./configure; make; make test;</code> dance so it should not pose too many problems. The <code>make test</code> step is optional, but every time you skip that step, God creates another Perl programmer, so please, <code>make test</code>. If you run into any problems building PHP you will have to look elsewhere for answers. I won&#8217;t cover that in this post.</p>
<p>Now that you have built PHP, lets start writing some code.</p>
<p>When working on a framework (or something else for that matter), you will most likely need to introduce parameters for some of your classes, be it database adapters or a storage adapter. All these classes will most likely have the following methods:</p>
<ul>
<li>setParams(array $params)</li>
<li>getParams()</li>
<li>setParam($key, $value)</li>
<li>getParam($key)</li>
</ul>
<p>The implementation of these methods will most likely be the same. If you put the actual implementation of these methods in many classes you&#8217;re not <a href="http://en.wikipedia.org/wiki/DRY" target="_blank">DRY</a> anymore. Since PHP does not support multiple inheritance you will have to make a base class with the implementation of these methods, and have other classes ultimately extend this base class. Now you are relatively DRY, but this solution is not optimal(and sometimes not possible at all).</p>
<p>Enter traits, the newest superhero on the PHP street, or something like that.</p>
<p>Now, I&#8217;ll create two classes that needs to support parameters; <code>Cogo\Database\MySQL</code> and <code>Cogo\Storage\Filesystem</code>. They will each extend <code>Cogo\Database</code> and <code>Cogo\Storage</code> respectively that will have the parameter-related methods.</p>
<p><pre class="brush: php;">
&lt;?php
namespace Cogo;

abstract class Database {
    private $params;

    public function __construct(array $params) {
        $this-&gt;setParams($params);
    }

    private function setParams(array $params) {
        $this-&gt;params = $params;
    }

    public function getParams() {
        return $this-&gt;params;
    }

    protected function setParam($key, $value) {
        $this-&gt;params[$key] = $value;
    }

    public function getParam($key) {
        return (isset($this-&gt;params[$key]) ? $this-&gt;params[$key] : null);
    }

    protected function someDatabaseRelatedMethod() {
        // ...
    }

    abstract protected function someOtherDatabaseRelatedMethod();
}
</pre></p>
<p><pre class="brush: php;">
&lt;?php
namespace Cogo\Database;
use Cogo\Database;

class MySQL extends Database {
    protected function someOtherDatabaseRelatedMethod() {
        // ...
    }
}
</pre></p>
<p><pre class="brush: php;">
&lt;?php
namespace Cogo;

abstract class Storage {
    private $params;

    public function __construct(array $params) {
        $this-&gt;setParams($params);
    }

    public function setParams(array $params) {
        $this-&gt;params = $params;
    }

    public function getParams() {
        return $this-&gt;params;
    }

    public function setParam($key, $value) {
        $this-&gt;params[$key] = $value;
    }

    public function getParam($key) {
        return (isset($this-&gt;params[$key]) ? $this-&gt;params[$key] : null);
    }

    protected function someFilesystemRelatedMethod() {
        // ...
    }

    abstract protected function someOtherFilesystemRelatedMethod();
}
</pre></p>
<p><pre class="brush: php;">
&lt;?php
namespace Cogo\Storage;
use Cogo\Storage;

class Filesystem extends Storage {
    protected function someOtherFilesystemRelatedMethod() {
        // ...
    }
}
</pre></p>
<p>As you can see the parameter-related methods are almost the same. The difference is that the <code>Cogo\Database</code> class wants to have its <code>set</code> methods <code>private</code> and <code>protected</code>.</p>
<p>One possibility would be to create a base class for the parameter handling, and have the two abstract classes extend that one, but because multiple inheritance is not possible in PHP it&#8217;s easy to grind to a halt using this solution. In the end you might end up with a huge base class with loads of logic simply because it has some logic that you want to share across many other classes.</p>
<p>The base class would also have to have <code>private</code> on the set methods since you can&#8217;t override a method with a stricter visibility, only the other way around.</p>
<p>Using traits, this can be solved in a more elegant fashion. Traits also support changing visibility of the methods defined in the trait, so <code>Cogo\Database</code> can keep its <code>private</code> and <code>protected</code> implementations. Here is how the trait can look like:</p>
<p><pre class="brush: php;">
&lt;?php
namespace Cogo;

trait ParamsHandler {
    private $params;

    public function __construct(array $params) {
        $this-&gt;setParams($params);
    }

    public function setParams(array $params) {
        $this-&gt;params = $params;
    }

    public function getParams() {
        return $this-&gt;params;
    }

    public function setParam($key, $value) {
        $this-&gt;params[$key] = $value;
    }

    public function getParam($key) {
        return (isset($this-&gt;params[$key]) ? $this-&gt;params[$key] : null);
    }
}
</pre></p>
<p>Notice that the trait now contains all logic regarding parameters (including the <code>$params</code> property and the constructor). The RFC states that:</p>
<blockquote cite="https://wiki.php.net/rfc/traits"><p>Since Traits do not contain any state/properties &#8230;</p></blockquote>
<p>This seems to work after all. The RFC was created a while ago and it no longer matches the actual implementation 100% obviously.</p>
<p>Now that we have a trait with the logic we want in both our abstract classes, let&#8217;s <code>use</code> it:</p>
<p><pre class="brush: php;">
&lt;?php
namespace Cogo;

abstract class Database {
    use ParamsHandler {
        setParams as private;
        setParam as protected;
    }

    protected function someDatabaseRelatedMethod() {
        // ...
    }

    abstract protected function someOtherDatabaseRelatedMethod();
}
</pre></p>
<p><pre class="brush: php;">
&lt;?php
namespace Cogo;

abstract class Storage {
    use ParamsHandler;

    protected function someFilesystemRelatedMethod() {
        // ...
    }

    abstract protected function someOtherFilesystemRelatedMethod();
}
</pre></p>
<p>As you can see we have replaced the implementation of the parameter methods from both abstract classes with a couple of <code>use</code> statements. In the <code>Cogo\Storage</code> class we have used the methods from the trait as-is, which means they are all <code>public</code>. In the <code>Cogo\Database</code> class we have changed the visibility of two methods to match the initial implementation. We have now managed to keep ourselves DRY, as well as not creating a base class that the two abstract classes extends.</p>
<p>This is just a simple example of how to use traits. They can do loads more, and there are issues like for instance conflict resolution which is not mentioned in this post at all. I will probably post more examples of traits (and perhaps other 5.4 features) later on. In the meantime you should read <a href="https://wiki.php.net/rfc/traits" target="_blank">the RFC</a>, and try it out for yourself.</p>
<p>You will find all the code mentioned in this post over at <a href="https://github.com/christeredvartsen/php-traits-examples/" target="_blank">my php-traits-examples repository</a> at <a href="http://www.github.com/" target="_blank">GitHub</a>. Feel free to play around with it, and if you have other examples on how to use traits please fork the project and send me a pull request so I can include it (and learn from it).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cogo.wordpress.com/1112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cogo.wordpress.com/1112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cogo.wordpress.com/1112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cogo.wordpress.com/1112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cogo.wordpress.com/1112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cogo.wordpress.com/1112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cogo.wordpress.com/1112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cogo.wordpress.com/1112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cogo.wordpress.com/1112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cogo.wordpress.com/1112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cogo.wordpress.com/1112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cogo.wordpress.com/1112/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cogo.wordpress.com/1112/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cogo.wordpress.com/1112/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1112&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cogo.wordpress.com/2011/07/01/playing-with-traits-in-php-5-4alpha1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c7f00126a1c4ba53bba8f7f37e347a3?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cogo</media:title>
		</media:content>
	</item>
		<item>
		<title>Mocking MongoCollection with Mockery</title>
		<link>http://cogo.wordpress.com/2011/04/01/mocking-mongocollection-with-mockery/</link>
		<comments>http://cogo.wordpress.com/2011/04/01/mocking-mongocollection-with-mockery/#comments</comments>
		<pubDate>Fri, 01 Apr 2011 17:12:55 +0000</pubDate>
		<dc:creator>christer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[mockery]]></category>
		<category><![CDATA[mongo]]></category>
		<category><![CDATA[mongocollection]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[phpunit]]></category>

		<guid isPermaLink="false">http://cogo.wordpress.com/?p=1096</guid>
		<description><![CDATA[I have played around with the mongo extension to PHP lately and came across an issue when I was trying to write unit tests with PHPUnit for some methods using MongoCollection::insert(). Consider a class method looking like this: The Image &#8230; <a href="http://cogo.wordpress.com/2011/04/01/mocking-mongocollection-with-mockery/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1096&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I have played around with the <a href="http://pecl.php.net/package/mongo" target="_blank">mongo extension to PHP</a> lately and came across an issue when I was trying to write unit tests with <a href="http://phpunit.de" target="_blank">PHPUnit</a> for some methods using <code>MongoCollection::insert()</code>.</p>
<p>Consider a class method looking like this:</p>
<p><pre class="brush: php;">
class Database {
    public function insertData($hash, Image $image) {
        $data = array(
            'hash' =&gt; $hash,
            'name' =&gt; $image-&gt;getName(),
        );

        $this-&gt;getCollection()-&gt;insert($data, array('safe' =&gt; true));
        $image-&gt;setId((string) $data['_id']);

        return true;
    }

    // ...
}
</pre></p>
<p>The <code>Image</code> class is just some custom class, and the <code>getCollection()</code> method returns a property set in the class (so I can inject mocked versions of the collection and not depend on <code>MongoCollection</code>).</p>
<p>As you see from the code above the <code>insertData()</code> method changes the first parameter (it adds an <em>_id</em> element that is set to an instance of <code>MongoId</code>). The problem with testing the above method is that when mocking <code>MongoCollection</code> you can&#8217;t make it add the <em>_id</em> element to the passed array, so the test fails because of an E_NOTICE that says:</p>
<p><code>Undefined index: _id.</code></p>
<p>I tried to solve the problem by using <a href="https://github.com/padraic/mockery">Mockery</a> (a simple but flexible (and awesome) mock object framework by <a href="http://blog.astrumfutura.com/">Pádraic Brady</a>) like this:</p>
<p><pre class="brush: php;">
public function testInsertData() {
    $id = MongoId();
    $idAsString = (string) $id;
    $image = \Mockery::mock('Image');
    $image-&gt;shouldReceive('setId')
          -&gt;once()
          -&gt;with($idAsString)
          -&gt;andReturn($image);
    $image-&gt;shouldReceive('getName')
          -&gt;once()
          -&gt;andReturn('some name');

    $collection = \Mockery::mock('MongoCollection');
    $collection-&gt;shouldReceive('insert')
               -&gt;once()
               -&gt;with(\Mockery::on(
                   function(&amp;$data) use($id) {
                       $data['_id'] = $id;
                       return true;
                   }), \Mockery::type('array'));

    // The object we want to test with
    $database = new Database;
    $database-&gt;setCollection($collection);
    $database-&gt;insertData($hash, $image);
}
</pre></p>
<p>When running the above test I get the following error:</p>
<p><code>Parameter 1 to {closure}() expected to be a reference, value given</code></p>
<p>This is because Mockery uses the <a href="http://no2.php.net/call_user_func_array">call_user_func_array</a> function to call the closure given to <code>\Mockery::on()</code>, and that function does not support references. PHPUnit also uses this function internally for its mock objects.</p>
<p>The description of <code>MongoCollection::insert()</code> <a href="http://no2.php.net/manual/en/mongocollection.insert.php">in the PHP manual</a> looks like this:</p>
<p><code>public mixed MongoCollection::insert ( array $a [, array $options = array() ] )</code></p>
<p>Feeling a bit bold I tried to change the <code>insertData()</code> method above to pass an instance of <code>stdClass</code> instead of an array to <code>MongoCollection::insert()</code>. Why? Objects in PHP-5 are all references, so I might be able to get Mockery to work without having to specify <code>&amp;$data</code> in the closure. It&#8217;s not documented, but hey, you never know without trying right? Here is the new version of <code>insertData()</code>:</p>
<p><pre class="brush: php;">
public function insertData($hash, Image $image) {
    $data = new stdClass;
    $data-&gt;hash = $hash;
    $data-&gt;name = $image-&gt;getName();

    $this-&gt;getCollection()-&gt;insert($data, array('safe' =&gt; true));
    $image-&gt;setId((string) $data-&gt;_id);

    return true;
}
</pre></p>
<p>The only change I made in the test method was to change the closure I give to <code>\Mockery::on()</code> from:</p>
<p><pre class="brush: php;">
function(&amp;$data) use ($id) {
    $data['_id'] = $id;
    return true;
}
</pre></p>
<p>to</p>
<p><pre class="brush: php;">
function($data) use ($id) {
    $data-&gt;_id = $id;
    return true;
}
</pre></p>
<p>and voila, the test works! The part about giving an instance of <code>stdClass</code> to <code>MongoCollection::insert()</code> is not documented, and I&#8217;m not sure if it&#8217;s a feature that&#8217;s going to stay implemented.</p>
<p>At first I tried to solve this using the built in mock objects in PHPUnit, but since they clone the objects used in the mocks the trick above would not work anyway as the change would not be made on the correct reference.</p>
<p>And thats that!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cogo.wordpress.com/1096/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cogo.wordpress.com/1096/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cogo.wordpress.com/1096/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cogo.wordpress.com/1096/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cogo.wordpress.com/1096/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cogo.wordpress.com/1096/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cogo.wordpress.com/1096/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cogo.wordpress.com/1096/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cogo.wordpress.com/1096/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cogo.wordpress.com/1096/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cogo.wordpress.com/1096/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cogo.wordpress.com/1096/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cogo.wordpress.com/1096/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cogo.wordpress.com/1096/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1096&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cogo.wordpress.com/2011/04/01/mocking-mongocollection-with-mockery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c7f00126a1c4ba53bba8f7f37e347a3?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cogo</media:title>
		</media:content>
	</item>
		<item>
		<title>Changed blog theme</title>
		<link>http://cogo.wordpress.com/2011/04/01/changed-blog-theme/</link>
		<comments>http://cogo.wordpress.com/2011/04/01/changed-blog-theme/#comments</comments>
		<pubDate>Fri, 01 Apr 2011 15:09:05 +0000</pubDate>
		<dc:creator>christer</dc:creator>
				<category><![CDATA[Misc]]></category>

		<guid isPermaLink="false">http://cogo.wordpress.com/?p=1093</guid>
		<description><![CDATA[I just changed the theme on this blog to the default WordPress theme. Please let me know if anything looks weird.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1093&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I just changed the theme on this blog to the default WordPress theme. Please let me know if anything looks weird.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cogo.wordpress.com/1093/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cogo.wordpress.com/1093/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cogo.wordpress.com/1093/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cogo.wordpress.com/1093/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cogo.wordpress.com/1093/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cogo.wordpress.com/1093/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cogo.wordpress.com/1093/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cogo.wordpress.com/1093/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cogo.wordpress.com/1093/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cogo.wordpress.com/1093/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cogo.wordpress.com/1093/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cogo.wordpress.com/1093/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cogo.wordpress.com/1093/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cogo.wordpress.com/1093/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1093&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cogo.wordpress.com/2011/04/01/changed-blog-theme/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c7f00126a1c4ba53bba8f7f37e347a3?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cogo</media:title>
		</media:content>
	</item>
		<item>
		<title>How to set up your own PEAR channel</title>
		<link>http://cogo.wordpress.com/2011/03/09/how-to-set-up-your-own-pear-channel/</link>
		<comments>http://cogo.wordpress.com/2011/03/09/how-to-set-up-your-own-pear-channel/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 09:24:30 +0000</pubDate>
		<dc:creator>christer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[PEAR]]></category>
		<category><![CDATA[pirum]]></category>

		<guid isPermaLink="false">http://cogo.wordpress.com/?p=1070</guid>
		<description><![CDATA[If you want to make your projects available to users as PEAR packages you will most likely want a PEAR channel. This way users can install/upgrade/remove your packages by using the pear command. There are a couple of solutions available &#8230; <a href="http://cogo.wordpress.com/2011/03/09/how-to-set-up-your-own-pear-channel/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1070&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If you want to make your projects available to users as <a href="http://pear.php.net/" target="_blank">PEAR</a> packages you will most likely want a PEAR channel. This way users can install/upgrade/remove your packages by using the <em>pear</em> command. There are a couple of solutions available when setting up your own channel. One of the most popular is called <a href="http://www.pirum-project.org/" target="_blank">Pirum</a>, which I will be covering in this post.</p>
<blockquote cite="http://www.pirum-project.org/"><p>Pirum is a simple and nice looking PEAR channel server manager that lets you setup PEAR channel servers in a matter of minutes. Pirum is best suited when you want to create small PEAR channels for a few packages written by a few developers.</p></blockquote>
<p>First you will need to install Pirum. This can be done via pear:</p>
<pre>christer@aurora:~$ sudo pear channel-discover pear.pirum-project.org
Adding Channel "pear.pirum-project.org" succeeded
Discovery of channel "pear.pirum-project.org" succeeded
christer@aurora:~$ sudo pear install pirum/Pirum
downloading Pirum-1.0.0.tgz ...
Starting to download Pirum-1.0.0.tgz (11,732 bytes)
.....done: 11,732 bytes
install ok: channel://pear.pirum-project.org/Pirum-1.0.0</pre>
<p>If your PEAR environment is set up correctly you should now have an executable called <em>pirum</em>. Run the command to see what it can do:</p>
<pre>christer@aurora:~$ pirum
Pirum 1.0.0 by Fabien Potencier
Available commands:
pirum build target_dir
pirum add target_dir Pirum-1.0.0.tgz</pre>
<p>The first thing you want to do is just choose a target directory for where you want to have your channel along with the packages served by the channel. Create the target directory and add a file called <em>pirum.xml</em> inside it that will be used by pirum when building the channel. The file can look like this:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;server&gt;
  &lt;name&gt;pear.starzinger.net&lt;/name&gt;
  &lt;summary&gt;Starzinger PEAR channel&lt;/summary&gt;
  &lt;alias&gt;stz&lt;/alias&gt;
  &lt;url&gt;http://pear.starzinger.net/&lt;/url&gt;
&lt;/server&gt;</pre>
<p>This is the pirum.xml file I used when setting up <a href="http://pear.starzinger.net/" target="_blank">pear.starzinger.net</a>. Most tags are self descriptive except for the &lt;alias&gt; tag. That is the &#8220;shortcut&#8221; users can use when querying your channel. If you look at how I installed pirum above you can see that I used the &#8220;pirum&#8221; alias in the install command. The Starzinger PEAR channel uses &#8220;stz&#8221; so when querying the channel you can just do:</p>
<pre>christer@aurora:~$ pear list -c stz
Installed packages, channel pear.starzinger.net:
================================================
Package        Version State
PHP_BitTorrent 0.0.1   alpha
SqlDiff        0.0.3   beta</pre>
<p>Now that the pirum.xml file is in place, run the following command to build the channel:</p>
<pre>christer@aurora:~$ pirum build /var/www/pear
Pirum 1.0.0 by Fabien Potencier
Available commands:
pirum build target_dir
pirum add target_dir Pirum-1.0.0.tgz

Running the build command:
INFO   Building channel
INFO   Building maintainers
INFO   Building categories
INFO   Building packages
INFO   Building releases
INFO   Building index
INFO   Building feed
INFO   Updating PEAR server files
INFO   Command build run successfully</pre>
<p>Now you will need to setup apache to have a host pointing to the newly created channel. This can be done for instance via a regular VirtualHost setup:</p>
<pre>&lt;VirtualHost *:80&gt;
        ServerName pear.starzinger.net
        DocumentRoot /var/www/pear
&lt;/VirtualHost&gt;</pre>
<p>Now, when browsing pear.starzinger.net you will see something like this:</p>
<p><a href="http://cogo.files.wordpress.com/2011/03/empty-pear-channel.png"><img src="http://cogo.files.wordpress.com/2011/03/empty-pear-channel.png?w=300&#038;h=229" alt="" title="Empty PEAR channel" width="300" height="229" class="alignnone size-medium wp-image-1085" /></a></p>
<p>Now you just need to add some packages. As an example I will add a couple of packages that I have on my own PEAR channel:</p>
<pre>christer@aurora:~$ pirum add /var/www/pear SqlDiff-0.0.3.tgz
Pirum 1.0.0 by Fabien Potencier
Available commands:
pirum build target_dir
pirum add target_dir Pirum-1.0.0.tgz

Running the add command:
INFO   Parsing package 0.0.3 for SqlDiff
INFO   Building channel
INFO   Building maintainers
INFO   Building categories
INFO   Building packages
INFO   Building package SqlDiff
INFO   Building releases
INFO   Building releases for SqlDiff
INFO   Building release 0.0.3 for SqlDiff
INFO   Building index
INFO   Building feed
INFO   Updating PEAR server files
INFO   Command add run successfully</pre>
<p>And then another:</p>
<pre>christer@aurora:~$ pirum add /var/www/pear PHP_BitTorrent-0.0.1.tgz
Pirum 1.0.0 by Fabien Potencier
Available commands:
pirum build target_dir
pirum add target_dir Pirum-1.0.0.tgz

Running the add command:
INFO   Parsing package 0.0.3 for SqlDiff
INFO   Parsing package 0.0.1 for PHP_BitTorrent
INFO   Building channel
INFO   Building maintainers
INFO   Building categories
INFO   Building packages
INFO   Building package PHP_BitTorrent
INFO   Building package SqlDiff
INFO   Building releases
INFO   Building releases for PHP_BitTorrent
INFO   Building release 0.0.1 for PHP_BitTorrent
INFO   Building releases for SqlDiff
INFO   Building release 0.0.3 for SqlDiff
INFO   Building index
INFO   Building feed
INFO   Updating PEAR server files
INFO   Command add run successfully</pre>
<p>Now, take a look at the pear channel again in your browser:</p>
<p><a href="http://cogo.files.wordpress.com/2011/03/pear-channel-1.png"><img src="http://cogo.files.wordpress.com/2011/03/pear-channel-1.png?w=300&#038;h=233" alt="" title="PEAR channel with packages" width="300" height="233" class="alignnone size-medium wp-image-1086" /></a></p>
<p>The current version of Pirum (1.0.0) does not support anything other than building the channel and adding packages. If you for instance want to remove a package you added by mistake you will need to manually remove files from the <em>get</em> directory in your channel dir, and re-build using pirum. Lets try to remove the PHP_BitTorrent-0.0.1 package:</p>
<pre>christer@aurora:~$ cd /var/www/pear/get
christer@aurora:/var/www/pear/get$ rm PHP_BitTorrent-0.0.1.tar PHP_BitTorrent-0.0.1.tgz
christer@aurora:/var/www/pear/get$ pirum build /var/www/pear
Pirum 1.0.0 by Fabien Potencier
Available commands:
pirum build target_dir
pirum add target_dir Pirum-1.0.0.tgz

Running the build command:
INFO   Parsing package 0.0.3 for SqlDiff
INFO   Building channel
INFO   Building maintainers
INFO   Building categories
INFO   Building packages
INFO   Building package SqlDiff
INFO   Building releases
INFO   Building releases for SqlDiff
INFO   Building release 0.0.3 for SqlDiff
INFO   Building index
INFO   Building feed
INFO   Updating PEAR server files
INFO   Command build run successfully</pre>
<p>If you take a look at the channel in your browser now you will see that the package has been removed:</p>
<p><a href="http://cogo.files.wordpress.com/2011/03/pear-channel-2.png"><img src="http://cogo.files.wordpress.com/2011/03/pear-channel-2.png?w=300&#038;h=241" alt="" title="PEAR channel with package" width="300" height="241" class="alignnone size-medium wp-image-1087" /></a></p>
<p>The next version of pirum will support removing packages via the pirum command (contributed by yours truly).</p>
<p>And thats that!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cogo.wordpress.com/1070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cogo.wordpress.com/1070/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cogo.wordpress.com/1070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cogo.wordpress.com/1070/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cogo.wordpress.com/1070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cogo.wordpress.com/1070/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cogo.wordpress.com/1070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cogo.wordpress.com/1070/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cogo.wordpress.com/1070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cogo.wordpress.com/1070/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cogo.wordpress.com/1070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cogo.wordpress.com/1070/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cogo.wordpress.com/1070/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cogo.wordpress.com/1070/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1070&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cogo.wordpress.com/2011/03/09/how-to-set-up-your-own-pear-channel/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c7f00126a1c4ba53bba8f7f37e347a3?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cogo</media:title>
		</media:content>

		<media:content url="http://cogo.files.wordpress.com/2011/03/empty-pear-channel.png?w=300" medium="image">
			<media:title type="html">Empty PEAR channel</media:title>
		</media:content>

		<media:content url="http://cogo.files.wordpress.com/2011/03/pear-channel-1.png?w=300" medium="image">
			<media:title type="html">PEAR channel with packages</media:title>
		</media:content>

		<media:content url="http://cogo.files.wordpress.com/2011/03/pear-channel-2.png?w=300" medium="image">
			<media:title type="html">PEAR channel with package</media:title>
		</media:content>
	</item>
		<item>
		<title>SqlDiff-0.0.2 released</title>
		<link>http://cogo.wordpress.com/2011/02/16/sqldiff-0-0-2-released/</link>
		<comments>http://cogo.wordpress.com/2011/02/16/sqldiff-0-0-2-released/#comments</comments>
		<pubDate>Wed, 16 Feb 2011 08:32:26 +0000</pubDate>
		<dc:creator>christer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[sqldiff]]></category>

		<guid isPermaLink="false">http://cogo.wordpress.com/?p=1075</guid>
		<description><![CDATA[Just pushed a new version of SqlDiff. The new version supports colors in the output, and the generated statements inserts new columns at the correct positions. To install simply do: christer@aurora:~$ sudo pear channel-discover pear.starzinger.net Adding Channel "pear.starzinger.net" succeeded Discovery &#8230; <a href="http://cogo.wordpress.com/2011/02/16/sqldiff-0-0-2-released/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1075&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Just pushed a new version of SqlDiff. The new version supports colors in the output, and the generated statements inserts new columns at the correct positions.</p>
<p>To install simply do:</p>
<p><code>christer@aurora:~$ sudo pear channel-discover pear.starzinger.net<br />
Adding Channel "pear.starzinger.net" succeeded<br />
Discovery of channel "pear.starzinger.net" succeeded</code></p>
<p>if you haven&#8217;t already added the channel, and then:</p>
<p><code>christer@aurora:~$ sudo pear install stz/SqlDiff-beta<br />
downloading SqlDiff-0.0.2.tgz ...<br />
Starting to download SqlDiff-0.0.2.tgz (13,038 bytes)<br />
.....done: 13,038 bytes<br />
install ok: channel://pear.starzinger.net/SqlDiff-0.0.2</code></p>
<p>Read more about SqlDiff on the <a href="https://github.com/christeredvartsen/sqldiff" target="_blank">project page over at github.com</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cogo.wordpress.com/1075/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cogo.wordpress.com/1075/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cogo.wordpress.com/1075/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cogo.wordpress.com/1075/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cogo.wordpress.com/1075/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cogo.wordpress.com/1075/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cogo.wordpress.com/1075/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cogo.wordpress.com/1075/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cogo.wordpress.com/1075/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cogo.wordpress.com/1075/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cogo.wordpress.com/1075/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cogo.wordpress.com/1075/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cogo.wordpress.com/1075/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cogo.wordpress.com/1075/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1075&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cogo.wordpress.com/2011/02/16/sqldiff-0-0-2-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c7f00126a1c4ba53bba8f7f37e347a3?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cogo</media:title>
		</media:content>
	</item>
		<item>
		<title>SqlDiff-0.0.1 released</title>
		<link>http://cogo.wordpress.com/2011/02/13/sqldiff-0-0-1-released/</link>
		<comments>http://cogo.wordpress.com/2011/02/13/sqldiff-0-0-1-released/#comments</comments>
		<pubDate>Sun, 13 Feb 2011 16:25:58 +0000</pubDate>
		<dc:creator>christer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[diff]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://cogo.wordpress.com/?p=1071</guid>
		<description><![CDATA[Some minutes ago I created the first PEAR package of SqlDiff, a small tool that I have been playing around with some time. The tool is meant to aid people in making sql statements based on the diff of two &#8230; <a href="http://cogo.wordpress.com/2011/02/13/sqldiff-0-0-1-released/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1071&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Some minutes ago I created the first PEAR package of SqlDiff, a small tool that I have been playing around with some time. The tool is meant to aid people in making sql statements based on the diff of two schemas (for instance in an upgrade scenario where the database schema is updated).</p>
<p>Currently the tool only supports the XML format created by MySQL&#8217;s mysqldump (with the -X option). The tool is extensible so if anyone out there wants support for some other database as well, feel free to fork the project and send me a pull request.</p>
<p>More information (installation and usage) can be found on the project page at github: <a href="https://github.com/christeredvartsen/sqldiff" target="_blank">https://github.com/christeredvartsen/sqldiff</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cogo.wordpress.com/1071/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cogo.wordpress.com/1071/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cogo.wordpress.com/1071/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cogo.wordpress.com/1071/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cogo.wordpress.com/1071/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cogo.wordpress.com/1071/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cogo.wordpress.com/1071/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cogo.wordpress.com/1071/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cogo.wordpress.com/1071/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cogo.wordpress.com/1071/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cogo.wordpress.com/1071/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cogo.wordpress.com/1071/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cogo.wordpress.com/1071/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cogo.wordpress.com/1071/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1071&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cogo.wordpress.com/2011/02/13/sqldiff-0-0-1-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c7f00126a1c4ba53bba8f7f37e347a3?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cogo</media:title>
		</media:content>
	</item>
		<item>
		<title>PHP_BitTorrent-0.0.1 released</title>
		<link>http://cogo.wordpress.com/2011/01/29/php_bittorrent-0-0-1-released/</link>
		<comments>http://cogo.wordpress.com/2011/01/29/php_bittorrent-0-0-1-released/#comments</comments>
		<pubDate>Sat, 29 Jan 2011 21:08:49 +0000</pubDate>
		<dc:creator>christer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[bittorrent]]></category>
		<category><![CDATA[github]]></category>

		<guid isPermaLink="false">http://cogo.wordpress.com/?p=1068</guid>
		<description><![CDATA[Earlier tonight I created the first pear package of PHP_BitTorrent. The package currently contains an encoder, a decoder and a torrent component to work with torrent files. Feel free to download and play around with it. I&#8217;ll add the tracker &#8230; <a href="http://cogo.wordpress.com/2011/01/29/php_bittorrent-0-0-1-released/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1068&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Earlier tonight I created the first pear package of <a href="https://github.com/christeredvartsen/php-bittorrent" target="_blank">PHP_BitTorrent</a>. The package currently contains an encoder, a decoder and a torrent component to work with torrent files. Feel free to download and play around with it. I&#8217;ll add the tracker part to it as soon as I have some more work done on it.</p>
<p>The package is available from my pear channel(<a href="http://pear.starzinger.net/" target="_blank">pear.starzinger.net)</a>. Register the channel using the following command:</p>
<p><code>christer@aurora:~$ sudo pear channel-discover pear.starzinger.net<br />
Adding Channel "pear.starzinger.net" succeeded<br />
Discovery of channel "pear.starzinger.net" succeeded</code></p>
<p>And then you can install the package using:</p>
<p><code>christer@aurora:~$ sudo pear install stz/PHP_BitTorrent-alpha<br />
downloading PHP_BitTorrent-0.0.1.tgz ...<br />
Starting to download PHP_BitTorrent-0.0.1.tgz (8,037 bytes)<br />
.....done: 8,037 bytes<br />
install ok: channel://pear.starzinger.net/PHP_BitTorrent-0.0.1</code></p>
<p>The project is hosted at <a href="https://github.com/christeredvartsen/php-bittorrent" target="_blank">github</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cogo.wordpress.com/1068/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cogo.wordpress.com/1068/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cogo.wordpress.com/1068/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cogo.wordpress.com/1068/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cogo.wordpress.com/1068/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cogo.wordpress.com/1068/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cogo.wordpress.com/1068/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cogo.wordpress.com/1068/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cogo.wordpress.com/1068/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cogo.wordpress.com/1068/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cogo.wordpress.com/1068/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cogo.wordpress.com/1068/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cogo.wordpress.com/1068/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cogo.wordpress.com/1068/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1068&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cogo.wordpress.com/2011/01/29/php_bittorrent-0-0-1-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c7f00126a1c4ba53bba8f7f37e347a3?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cogo</media:title>
		</media:content>
	</item>
		<item>
		<title>ZendCon 2010 Day #1</title>
		<link>http://cogo.wordpress.com/2010/11/03/zendcon-2010-day-1/</link>
		<comments>http://cogo.wordpress.com/2010/11/03/zendcon-2010-day-1/#comments</comments>
		<pubDate>Wed, 03 Nov 2010 05:38:40 +0000</pubDate>
		<dc:creator>christer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[zendcon]]></category>

		<guid isPermaLink="false">http://cogo.wordpress.com/?p=1010</guid>
		<description><![CDATA[A new approach to object persistence in PHP by Stefan Priebsch I went to this talk hoping to get some more information about MongoDB combined with object persistence. It turned out that the system Stefan was supposed to talk about &#8230; <a href="http://cogo.wordpress.com/2010/11/03/zendcon-2010-day-1/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1010&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h3><a href="http://www.slideshare.net/spriebsch/a-new-approach-to-object-persistence-zendcon-2010" target="_blank">A new approach to object persistence in PHP</a> by <a href="http://priebsch.de/" target="_blank">Stefan Priebsch</a></h3>
<p>I went to this talk hoping to get some more information about MongoDB combined with object persistence. It turned out that the system Stefan was supposed to talk about was not yet finished, so instead he talked about generic ways of achieving object persistence. I believe parts of the code that he used in his slides is taken from the system he was supposed to talk about.</p>
<p>He also mentioned a couple of nasty tricks that should never be used in production, like creating an instance of a class without running the constructor (using <a href="http://php.net/unserialize" target="_blank">unserialize</a>) and making private and protected properties accessible using <a href="http://php.net/reflection" target="_blank">Reflection</a>.</p>
<p>Lazy loading was also mentioned which is very important when dealing with ORM systems. Most of the techniques he talked about was pretty straight forward and included nothing new.</p>
<h3><a href="http://www.slideshare.net/ralphschindler/484-days-of-php-53" target="_blank">484 Days of PHP 5.3 and What Have We Done (And Learned)?</a> by <a href="http://ralphschindler.com/" target="_blank">Ralph Schindler</a></h3>
<p>This talk was about some of the new features that came with php-5.3, like:</p>
<ul>
<li>__invoke magic method</li>
<li>late static binding</li>
<li>closures</li>
<li>namespaces</li>
</ul>
<p>Of these features I have only used late static binding and closures. While I do get the point of using namespaces I had not found a good use for the __invoke method until this talk! I use Zend Framework for some private projects and some things that have annoyed me with the view scripts is how the view helpers are invoked. Usually you just do something like:</p>
<p><pre class="brush: php;">
&lt;?= $this-&gt;someHelper( ... ) ?&gt;
</pre></p>
<p>With the __invoke magic method you can call an object directly as if it were a function, as long as it has implemented the __invoke method of course:</p>
<p><pre class="brush: php;">
&lt;?= $someHelper( ... ) ?&gt;
</pre></p>
<p>Not a big difference but this is only one example of where to use it.</p>
<p>Late static binding is especially nice when it comes to the singleton pattern. Now you can have an abstract singleton class that other singletons can extend, and you don&#8217;t have to copy&amp;paste the getInstance() method all over the place. The abstract class can be implemented like this:</p>
<p><pre class="brush: php;">
abstract class SingletonPattern {
    static protected $instance = array();
    protected function __clone() {}
    protected function __construct() {}
    static public function getInstance() {
        $className = get_called_class();
        if (!isset(static::$instance[$className])) {
            static::$instance[$className] = new static;
        }

        return static::$instance[$className];
    }
}
</pre></p>
<p>Other classes can then become singletons by just extending this class:</p>
<p><pre class="brush: php;">
class SomeClass extends SingletonPattern {}
class SomeOtherClass extends SingletonPattern {}
</pre></p>
<p>To create instances of these classes you do:</p>
<p><pre class="brush: php;">
$object = SomeClass::getInstance();
$otherObject = SomeOtherClass::getInstance();
</pre></p>
<h3><a href="http://www.slideshare.net/shahar/best-practices-inphpappdeployment" target="_blank">Best Practices in deploying PHP applications</a> by <a href="http://prematureoptimization.org/blog/" target="_blank">Shahar Evron</a></h3>
<p>This talk included some interesting ways of deploying code on production servers. From the simplest svn up on a working copy in production, to more complex techniques such as rpm packages and rsync. At work we mostly use working copies on production servers which makes it very easy to update and to roll back to older revisions if the update causes problems. We also use rsync but mostly for static content, and not PHP code. We have a pretty simple setup so no need for complex deployment routines.</p>
<p>Shahar also mentioned deployment scripts that can be created and used if many manual operations is needed to update the codebase on your production servers. The deployment script should also support rollbacks whenever possible.</p>
<h3><a href="http://www.slideshare.net/DragonBe/unit-testing-after-zf-18" target="_blank">Unit testing after Zend Framework 1.8</a> by <a href="http://www.dragonbe.com/" target="_blank">Michelangelo van Dam</a></h3>
<p>Michelangelo talked about how to organize and test Zend Framework applications. I also learned that PHPUnit-5.3.0 introduced support for using an xml formatted mysqldump file for use with the database extension. I&#8217;ll be sure to try that out pretty soon! Other important tips was some pretty obvious (but good) ones:</p>
<ul>
<li>Test the most critical parts of the application first</li>
<li>Make sure to write tests after bugs have been fixed</li>
<li>Learn about exploits against other sites and make tests for them so that your site is safe</li>
</ul>
<h3><a href="http://ilia.ws/archives/230-Memcached,-the-Better-Memcache-Interface-Slides.html" target="_blank">Memcached, the Better Memcache Interface</a> by <a href="http://ilia.ws/" target="_blank">Ilia Alshanetsky</a></h3>
<p>I did not learn much new stuff in this talk. At work we use the old <a href="http://php.net/memcache" target="_blank">Memcache</a> extension, but I have already written some components that use the new <a href="http://php.net/memcached" target="_blank">Memcached</a> extension, so hopefully we will be able to try that out pretty soon. There are some interesting features in this extension, like result and read-through cache callbacks. If you have a pool of servers you also have the opportunity to map certain keys to specific servers as opposed to just storing a key value pair on a random server in your pool.</p>
<p>Other than that the new extension behaves much like the old Memcache extension.</p>
<p>And that was that. The first day of the conference have been very good! Talked to some talented people and listened to even more talented people. Looking forward to more talks tomorrow!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cogo.wordpress.com/1010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cogo.wordpress.com/1010/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cogo.wordpress.com/1010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cogo.wordpress.com/1010/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cogo.wordpress.com/1010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cogo.wordpress.com/1010/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cogo.wordpress.com/1010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cogo.wordpress.com/1010/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cogo.wordpress.com/1010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cogo.wordpress.com/1010/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cogo.wordpress.com/1010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cogo.wordpress.com/1010/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cogo.wordpress.com/1010/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cogo.wordpress.com/1010/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cogo.wordpress.com&amp;blog=66533&amp;post=1010&amp;subd=cogo&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cogo.wordpress.com/2010/11/03/zendcon-2010-day-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6c7f00126a1c4ba53bba8f7f37e347a3?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cogo</media:title>
		</media:content>
	</item>
	</channel>
</rss>
