Category Archives: Planet Ibuildings

  • [Devis Lucato]Anonymous objects in PHP - Composition, Mocks, Refactoring November 30, 2010

    PHP allows to define anonymous object in two different ways:

    Casting an array to object:

    $object = (object) array('date' => time());
    

    Using the internal class:

    $object = new stdClass; // == (object) array();
    $object->date = time();

    Both solutions allow to instantiate an anonymous object with properties. They are used as value objects and have no other purpose than storing values, so no logic can be included and they don't come with methods.  They can be used as function parameters instead of arrays, for instance. PHP 5.3.0 introduced anonymous functions and closures, so it is now possible to attach functions to these VOs (*).

    $object = new stdClass;
    $object->date = time();
    $object->foo = function() { echo "Hello!"; };
    

    The first thing to notice is that these properties are not methods but callable functions:

    $object->foo(); // error: Call to undefined method stdClass::foo() call_user_func($object->foo); // ok
    

    And foo() doesn't have access to date; a method that accesses $object->date needs to be a closure:

    $object->printDate = function($format) use ($object) { echo date($format, $object->date);
    }; call_user_func($object->printDate, 'Y'); // => 2010
    

    Writing call_user_func() everytime is bit annoying and prevent using the attached closures as methods, but there is a viable solution: introducing an Anonymous class:

    class Anonymous { function __call($name, $arguments) { // Note: Closure class is an implementation detail // so it might be removed or renamed in the future if (isset($this->$name) && $this->$name instanceof Closure) { return call_user_func_array($this->$name, $arguments); } }
    } $object = new Anonymous;
    $object->date = time();
    $object->printDate = function($format) use ($object) { echo date($format, $object->date);
    }; $object->printDate('Y'); // => 2010
    

    There are three possible use cases of anonymous objects: object composition, unit testing and application design/refactoring.  

    1. A similar approach can be used to attach new methods to an existing object adding additional behaviour dynamically (__call needs to support the attached closures). Attached methods however don't have access to private and protected properties/methods.

       

    2. Testing often use mock objects to inject fake elements and define a behaviour at runtime; these mocks can be defined as anonymous objects.

       

    3. Designing an application often requires to put in place new objects very quickly, without having a dedicated class defined yet. Refactoring often abstract code out of a class, an anonymous object can be used as a temporary container for the logic to move.

    (*) Attaching objects to a stdClass introduces some complexity, for example php closures are not serialisable as one would expect from a value object.

     

    read more

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Harrie Verveer]Sharing slides is a gesture November 17, 2010

    Whenever I do a talk, it always surprises me how many people ask about my slides. Some people couldn’t make it to the conference and ask for the slides instead, others want to have the slides as a reminder of the talk and some of them might even use the slides to do a slide karaoke back at the office. Great purposes, and usually I’m more than happy to share them with the world. What surprised me even more however, is that some people seem to get upset whenever a speaker decides to not share his slides – or simply forgets about uploading them, or hasn’t come round to doing it just yet. “Whenever a speaker doesn’t upload his slides to slideshare, God kills a kitten”, seems to be the general thought. I disagree for a number of reasons.

    My talk is more than just my slides

    Me, talking about pizza at the DPC

    Photo by Jeroen van Sluijs

    First of all, talks are usually more than just the slides. For example: during the most important part of my last talk, my slides showed a picture of a slice of pizza for about 3 minutes. By browsing through someones slides you might get a general idea on what the talk is about, but you’re missing out on the details – and probably the most important message the speaker is trying to get across. It gets even better when the speaker uses more “Presentation Zen”-like techniques. Thijs Feryn‘s talk “PHP through the eyes of a hoster” is a fantastic talk, but if you would download his slides you would mainly just end up with a bunch of beautiful, but meaningless photographs (and some keywords).

    That however is the way slides should look! They should confirm and strengthen what the speaker is telling, not tell the story themselves. Therefore sharing your slides then is not only pointless, but whenever somebody is going to see your slides it’s likely that the viewer will get a crooked view of what you were trying to tell in the first place.

    Sharing slides is a gesture
    I share them however, and most speakers do. My main reason is that people can browse through the slides again afterwards, and remember what I told them. If I did a good job the pizza-slide will then remind the viewer of the used metaphor and what I was trying to tell when this slide was on the screen. Even people that didn’t see my talk might still get a clue about the contents by looking at the slides. They will probably miss the main clue, but at least they will see a couple of mentioned tools that are worth giving a try – and if that makes you happy that’s just great! In such a case I’m glad you at least found some benefit in the work I’ve done.

    Sharing slides is a gesture though. Something extra the speaker does especially for you. Not sharing slides is not “evil”, it’s normal. There are plenty of reasons why a speaker wouldn’t upload his slides. Maybe he thinks the slides themselves shouldn’t be viewed because the viewer would miss out on so much background information and explanations that it makes the talk look plain and stupid. Maybe there’s a reason like copyright restrictions on used photographs, or maybe the speaker doesn’t want to share his slides because he wants to do the same talk somewhere else next month and he doesn’t like it when people in the audience are already reading his slides before he has even started the talk.

    Either way, it’s the speaker’s choice and not something that should be taken for granted. Sharing slides is a little bit extra a speaker did for you, and worth saying “thank you” for. Speakers don’t owe you anything, they usually don’t get paid (worse: they often even have to pay for their own expenses just to be at the conference) and they’ve usually put many hours into preparing their talks. All just for you! So next time, be grateful for the efforts they’ve put into it and give them a beer, instead of bitching about speakers that for whatever reason chose not to share their intellectual property with the entire world.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Harrie Verveer]Burying a talk: a year of database version control November 9, 2010

    About a year ago the idea was born to do a talk on database version control. Main reason: I didn’t really have a clue about database version control myself. What’s the right approach? What tools are out there? Am I doing database version control the right way, or is there a better way? While figuring all this out I decided to document all my steps, and finally use the results in a talk so I could share them with the rest of the world. I submitted a talk called “Database version control without pain” to the dutch conference PFCongres, and it got accepted!

    Zwolle, Amsterdam, Manchester and Barcelona

    Soon after that I got to repeat the same talk at other places in Europe. During these events I met some great people, had a lot of fun, saw cities I had never been before and I learned a lot as well. I tried to improve my talk based on the feedback I got, and sure enough most people seemed to like it!

    In total, I did the talk four times now:

    Enough!

    I think four is enough. I assume that the majority of the European PHP community has visited at least one of the events above, and had the chance to see the talk (and besides that I’m getting a bit tired of repeating the same story over and over again ;-) ). It’s time for something new! I don’t exactly know what it will be, but I have several ideas on new talks so hopefully I can make at least one of those ideas into a talk, and start submitting to the calls for papers at the different conferences really soon!

    Article on database version control

    As a last hoorah I’m planning to write an article on database version control, which will probably be published either here or on techportal. Missed the talk? Looking to refresh your memory? Or downloaded the slides and you’re still wondering what the heck I was talking about during the slide with the picture of a sunken boat? No worries! Just keep an eye on this site and you’ll be able to read all about it soon.

    But for now: Farewell database version control talk! You’ve been a great friend!

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Mark van der Velden]PHP Quiz part 4 November 9, 2010

    It has been a while, but here is part 4 of the PHP Quiz series! A few questions to crack your brain about, or perhaps you know them all? Try them and find out! Also do read the idea behind these quizzes, here: The PHP Quiz series

    As always, think of the answer before you execute the code or look it up. Codepad might help you run the examples. You can find round three here.

     

    Visibility is key

    Now you see me, now you don't

    class testClass {
        private $fubar = "rabuf";

        function test($test) {
            var_dump($test->fubar);
        }
    }

    class dummy {
        function test($test) {
            var_dump($test->fubar);
        }
    }

    $object1 = new testClass;
    $object2 = new testClass;
    $dummy = new dummy;

    $object1->test($object1); // Can $object1 see the private property of object1 ?
    $object1->test($object2); // Can $object1 see the private property of object2 ?
    $dummy->test($object1); // Can $dummy see the private property of object1 ?
     

     

    Static, sticky, icky

    class test {
      public $counter = -1;

      public function increment() {
        static $cnt = 0;
        $this->counter = ++$cnt;
        return $this;
      }
    }

    $object1 = new test;
    $object1->increment()->increment();

    $object2 = new test;

    // What will the output be
    echo $object2->increment()->counter;

     

    Getting the class

    class b {
            function getClassA() {
                    echo get_class($this);
            }
            function getClassB() {
                    echo get_class();
            }
            function getClassC() {
                    echo __CLASS__;
            }
    }

    class a extends b {
    }

    $a = new a;

    // What will be returned, 'a' or 'b' ?
    $a->getClassA();
    $a->getClassB();
    $a->getClassC();

     

    The strptime function

    $result = strptime('2010-11-28', '%Y-%m-%d');

    // What is the output?
    echo $result['tm_mday'] .'-'. $result['tm_mon'] .'-'. $result['tm_year'];
     

     

    The oldtimer

    for ($i = 0, $loop = 10, $a = 10; $i < $loop; ++$i, $a = 0) {
        ++$a;
    }

    // What is the output ?
    echo $a;

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Evert Pot]slowdeath - a simple denial of service attack for most PHP-based servers November 9, 2010

    The problem with Apache's approach to dealing with multiple clients, is that there's only ever a limited amount of Client processes available. This is usually is around a few hundred on common webservers.

    Because of this, it becomes necessary to handle HTTP requests as quickly as possible. As soon as a request is handled, it can go on serving the next. If a client happens to have a slow connection, this can have a direct effect on the scalability of your frontend server.

    A common way to fight this, is to put a caching server in front of your webserver, such as Varnish or Squid. These webservers are better suited to deal with many clients. This will allow your Apache server to send back HTTP responses quickly to the reverse proxy, and let the proxy deal with sending back the response to the client.

    However, this doesn't deal with slow requests. Generally, these proxy servers will open connections directly to the backend webserver to avoid having to buffer larger request bodies.

    Because PHP installations generally use apache 'prefork mpm', the number of possible connections is considerably low. This is also often the case with Fast-CGI based webservers, such as nginx and lighttpd. So if you were to just able to open up a few hundred connections, and drip in the bytes for the request body it would be very easy to take these servers down.

    To test this theory, I wrote a simple python script that does exactly this, you can grab it from github. To use it, try something like this:

    1. python slowdeath.py --threads 200 http://localhost/

    In my case my webserver was limited to 150 connections. It took about a second for it to stop serving requests.

    Big warning: This tool is for research purposes only. Use at your own risk, and only on servers you own.

    To take out a server, simply specify a number of threads higher than the MaxClients or whatever setting your webserver happens to use. Note that I only tested this on a few servers, so results may vary. Side effects include diarrhea, rashes, blackouts and death. Do not use while driving.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Harrie Verveer]The PHP community: not just about tree hugging geeks October 29, 2010

    The interesting people you meet at user group meetings, all the stuff you learn at conferences and the freely available open source projects that are out there. Those are just three of many things that make the PHP community into something awesome. However, every once in a while I hear some plea for the great PHP community that makes me a bit nauseous. “Sharing code, knowledge, elePHPants, it’s all so fun to share and be part of this great club of lovely people! I share my project with you and you share your project with me. And then we hug! Weeeee!!!”

    1960, era de los hippies

    Photo by Nelson Piedra

    Well f*ck that. Of course, whenever you regularly meet a group of people you will make some new friends, especially when you share a common interest. You might enjoy drinking beers with them or do some coding on their projects, because you think it’s a great project and you want to help them out. However, you will also make friends when you go out to the pub. Hell, you will probably even make friends at the weekly meeting for people with ingrown toenails – which is great, sure! But saying ingrown toenails are a great thing because “you meet such great people” just seems a bit awkward to me.

    Don’t get me wrong: I love the sharing, partying and beer drinking as well, and I wouldn’t want to miss it. The most interesting people you meet on conferences are the people you meet on the social events afterwards, but it’s all a consequence, not a cause. Saying you are part of the community because of it, is like saying to your date that you went through the whole process of “having sex and all” because you like smoking the cigarette at the end so much.

    So besides the hippy arguments, the PHP community also has some great, more down-to-earth things to offer for companies, developers and everybody else involved. Below I just listed a couple of arguments I could come up with by brainstorming for ten minutes. I’m pretty sure I might have missed one or two, but it should at least give you an idea.

    Contributing to open source projects
    On first sight, contributing to open source projects might look like charity. You and your noble steed have come to save the day, and with all your goodness you fix a bug in the project. Hooray! But contributing has some other upsides as well. First of all, it gives you a bit more renown and might make your resume look more interesting. How great would it be if you could put “regular contributor to the Zend Framework project” on there? By contributing you would probably learn a lot as well, just by looking into other people’s code and writing documentation or tests for it.

    Or if you’re using an open source product but you need to fix or extend it for your own purpose, giving back the changes you made means you can now keep updating to newer versions of the product. Your changes will be in it, so you won’t be stuck with the same version for the rest of your life because you added some custom hacks and an update would overwrite those changes.

    Open sourcing your own projects
    This one is rather simple; open sourcing your own project means that – if you do it right – people will start contributing to it. When your company has developed a somewhat useful tool, open sourcing it will probably mean that other people will start using the tool as well. Eventually, some people might come and fix some bugs in it, improve the tool and build some new features for it. Your tool gets enhanced, extended, better – for free!

    Conferences and user group meetings

    Events like conferences are a great place to learn and to get inspired, but can also be used for recruitment and networking. People might learn from the talks, or from talking to each other. Talks can also be inspirational and work as a trigger for somebody to start investigating a technique or a tool he didn’t think of before.

    If you do it right, speaking at such events will give you and the company you’re representing some great renown. Tens, maybe hundreds of potential colleagues, clients and people who might hire you see that you, and the company you’re representing, really know what it’s all about. As a company it’s a great way to show that you take software development seriously, and that your office is a great place to work. The speaker gets a bit more fame, and can add another interesting line on his resume.

    I did a little research on this subject by starting a poll about a week ago. The results were somewhat surprising, and they are probably hopelessly unreliable because of the group that answered the poll :-) Still, it gives you a bit of an idea:

    67% goes there to talk to interesting people

    58% goes there for the talks (which I had expected to be more, since that’s the main thing conferences have to offer – the stuff they’re selling)

    53% goes there for the hugging and beer drinking

    25% goes there to speak (you might see now what I meant by hopelessly unreliable ;-) )

    24% goes there to promote themselves

    16% goes there to promote their company, brand or product

    8% goes there to recruit new developers

    19% selected “other”. Answers included “I go there to convert all over to ruby” and one voter goes to PHP conferences to “be away from the missus”

    The community online
    Whether it’s on IRC or on some forum, there are some great resources out there for getting and sharing information, pretty much for the same reasons as the speaking and attending talks part: the person answering a question get a bit more renown, the person asking the question has his problem solved and can continue. Also, answering questions often forces you to do a little research yourself, how did this work again exactly? Somebody else might give an alternative answer to the question that would work just as well, but you hadn’t thought about that solution yet. You can really learn a lot from answering other people’s questions!

    The hippy thing
    And then of course, there’s the hippy thing. A great network of people that help each other out, give each other advice, do an open source project together and then drink some beer. This post is to show that it’s not the only thing that matters – but of course it is an important reason why it’s a lot of fun to be a part of the PHP community.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Evert Pot]Internationalized domain names, are you ready? October 23, 2010

    Since may 11 TLD's (top-level domainnames) have been added. In order for this to work successfully, a lot of applications will have to be fixed.

    Many email-validation scripts might use an approach like this:

    1. $ok = preg_match('/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,6}$/i', $email);

    This one is pretty simple, it matches the most common address formats, as long as the tld (.com, nl, .uk, etc) is under 6 characters. For a bit more sophistication you might want to ensure that the tld is a bit more valid:

    1. $ok = preg_match('/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)$/i',$email);

    Note: both these regexes were taken from regular-expression.info. The top google hit, and decent examples.

    The new TLD's use non-ascii characters, and they might become aliases for existing top-level domains, or new tld's altogether. Here are the currently working examples:

    At first sight these look like regular utf-8, characters, but if you look at the sourcecode of this page, you'll notice that it's actually encoded differently.

    The korean url http://실례.테스트, is actually encoded as http://xn--9n2bp8q.xn--9t4b11yi5a/. This is called Punycode.

    If you want support for these new urls (and thus domainnames in emails), you should have support for punycode. You will likely receive UTF-8 encoded domainnames for email address (example@실례.테스트), but internally you must make sure that you only deal with the punycode representation.

    This translating is also what modern browsers do. If you were to paste "http://xn--9n2bp8q.xn--9t4b11yi5a/" directly in the firefox address bar, it will show you the UTF-8 characters instead. Firefox will re-encode to punycode though and use that format for HTTP requests.

    The best way really to check for valid email addresses is to use a very liberal regex, but verify with a simple MX record lookup if a mailserver exists for the given domain. This example is an expansion on the first regex.

    1. $email = 'example@xn--9n2bp8q.xn--9t4b11yi5a';
    2.  
    3. if(preg_match('/^[A-Z0-9._%+-]+@([A-Z0-9.-]+\.[A-Z0-9-]{2,})$/i', $email,$matches)) {
    4. $hostname = $matches[1];
    5. if (!getmxrr($hostname, $hosts)) {
    6. echo "Host has an MX record\n";
    7. } else {
    8. echo "Host does not exist or does not have an MX record\n";
    9. }
    10. } else {
    11. echo "Email address did not match regular expression\n";
    12. }

    The preceeding code does not convert UTF-8 to punycode though. There's not yet an easy native way in PHP to do this, but Pear's Net_IDNA2 provides a way. The implementation seems very complex though, and leaves me wondering if there's an easier way to go about it.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Harrie Verveer]NetBeans’ PHPUnit integration October 19, 2010

    Although I’ve been using NetBeans as an IDE for a couple of months now, I’ve just recently found out about the nifty PHPUnit integration that comes with it. Once you’ve told NetBeans where your tests are, where PHPUnit is and how PHPUnit should be called to run your tests, you can run the unittests and see the test results in the IDE!

    Step 1: tell NetBeans where your tests are

    Open the project preferences and enter the directory containing your unittests in the field ‘Test folder’.

    NetBeans project properties dialog

    If you did this right, you will notice that NetBeans doesn’t show this folder anymore in the projects tree, but instead it shows a separate tree: underneath the tree “Source files” there’s now also a tree called “Test files”:

    Step 2: tell NetBeans where PHPUnit is

    Go to Netbeans’ general preferences, open the tab ‘PHP, and then the tab ‘Unit Testing’. Here, enter the path to PHPUnit:

    Netbeans Unit Testing dialog

    Step 3: tell NetBeans how to run the tests

    Finally, we need to tell NetBeans how to run our tests. This can be done by pointing it to the phpunit.xml, in the Project Properties dialog (PHPUnit menu):

    Netbeans project properties dialog (phpunit)

    That’s it! You can now run your unittests using NetBeans!

    Running unittests

    In the ‘run’ menu a new option has appeared. Just underneath ‘Run Project’ option there’s a new option, ‘Test Project’. When you select this option NetBeans will run your unit tests and show the results:

    As you can see something went wrong. It will not surprise you that clicking on the failed test will open the right unittest in your editor, showing you the line that failed so you can start figuring out what went wrong. The Test Results tab is sometimes a bit cryptic as to what went wrong, so it might help to open the Output dialog as well (menu Window -> Output -> Output), as the raw output of phpunit is captured here.

    Code coverage

    NetBeans can also capture the code coverage while you’re testing. To do this you first need to enable this by right-clicking the project and then selecting “Code Coverage” -> “Collect and Display Code Coverage”. Please note that you have to got the xdebug extension installed before you can do this, otherwise PHPUnit won’t run.

    NetBeans: collect and display code coverage

    Once enabled you can run phpunit again just as you did earlier, but when it’s done running it will show in your source files which code was tested and which code was not, by marking it either green or red:

    Upsides

    There are probably a lot more things you can do with the NetBeans – PHPUnit integration. I haven’t got time yet to investigate everything that’s possible, but I think that this already is quite nifty. Opening my iTerm and typing ‘phpunit’ usually isn’t that much of a hassle, but generating, opening and browsing the code coverage HTML can sometimes be quite time consuming. Now, I can just press ^ F6 and the tests are run and the tested/untested lines are marked green and red in my editor. Great!

    Downsides

    There are downsides. First of all, you need to be able to run PHPUnit from the OS your IDE is on – so probably that means that you need to be running your webserver locally. Personally I like to run my webserver on a vmware image that represents the production environment, and I share the folder where my project is in using a hgfs mount. This means I couldn’t use PHPUnit that I installed on my vmware image, but I had to install it again on Mac OSX. This not only means extra work, but it also means the environment I’m running my tests on it not longer representative to the production environment.

    Before updating your production environment, I think it’s a good idea to first run your tests once more on a more representative environment. Nevertheless the NetBeans – PHPUnit integration saves me quite some time when writing tests, because basically everything is happening in the same screen.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Evert Pot]SabreDAV 1.3.0 released October 16, 2010

    I just released version 1.3.0 of SabreDAV. Uptake has been very strong, especially for the CalDAV components. The biggest change is a big performance boost for most tree operations.

    To upgrade, download the new file here, or if you installed it using pear:

    1. pear upgrade sabredav/Sabre_DAV
    2. pear upgrade sabredav/Sabre_CalDAV

    To install using pear:

    1. pear channel-discover pear.sabredav.org
    2. pear install sabredav/Sabre_DAV
    3. pear install sabredav/Sabre_CalDAV

    There is a list of 4 (smallish) backwards compatibility breaks in the API. You can read about it in the migration guide.

    Full list of changes:

    • Added: Cache layer in the ObjectTree.
    • Added: childExists method to Sabre_DAV_ICollection. This is an api break, so if you implement Sabre_DAV_ICollection directly, add the method.
    • Changed: Almost all HTTP method implementations now take a uri argument, including events. This allows for internal rerouting of certain calls. If you have custom plugins, make sure they use this argument. If they don't, they will likely still work, but it might get in the way of future changes.
    • Changed: All getETag methods MUST now surround the etag with double-quotes. This was a mistake made in all previous SabreDAV versions. If you don't do this, any If-Match, If-None-Match and If: headers using Etags will work incorrectly. (Issue 85).
    • Added: Sabre_DAV_Auth_Backend_AbstractBasic class, which can be used to easily implement basic authentication.
    • Removed: Sabre_DAV_PermissionDenied class. Use Sabre_DAV_Forbidden instead.
    • Removed: Sabre_DAV_IDirectory interface, use Sabre_DAV_ICollection instead.
    • Added: Browser plugin now uses {DAV:}displayname if this property is available.
    • Added: Tree classes now have a delete and getChildren method.
    • Fixed: If-Modified-Since and If-Unmodified-Since would be incorrect if the date is an exact match.
    • Fixed: Support for multiple ETags in If-Match and If-None-Match headers.
    • Fixed: Improved baseUrl handling.
    • Fixed: Issue 67: Non-seekable stream support in ::put()/::get().
    • Fixed: Issue 65: Invalid dates are now ignored.
    • Updated: Refactoring in Sabre_CalDAV to make everything a bit more ledgable.
    • Fixed: Issue 88, Issue 89: Fixed compatibility for running SabreDAV on Windows.
    • Fixed: Issue 86: Fixed Content-Range top-boundary from 'file size' to 'file size'-1.

    I plan to fully keep supporting the 1.2.* branch, but I'll backport bugfixes strictly on an on-demand basis. So far there's been relatively little people stuck on older versions, so I'm only spending time on it in case anyone depends on it.

    Thanks to all the people reporting bugs and posting patches!

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Evert Pot]Ubuntu has a new font October 14, 2010

    Along with the release of 10.10, Ubuntu came with a new self-named font. I love it. It's quirky, yet very legible.

    The font is open-source, with a pretty straightforward license, which comes down to: 'include this license when redistributing. There's very little good free fonts out there that actually allow you to embed it on your site, but with this one you can.

    You can download the ttf's from here. Embedding it using css is easy:

    1. @font-face {
    2. font-family: "Ubuntu Sans";
    3. src: url('font/ubuntu/Ubuntu-R.ttf');
    4. }
    5. @font-face {
    6. font-family: "Ubuntu Sans";
    7. src: url('font/ubuntu/Ubuntu-B.ttf');
    8. font-weight: bold
    9. }
    10. @font-face {
    11. font-family: "Ubuntu Sans";
    12. src: url('font/ubuntu/Ubuntu-I.ttf');
    13. font-style: italic
    14. }
    15. @font-face {
    16. font-family: "Ubuntu Sans";
    17. src: url('font/ubuntu/Ubuntu-BI.ttf');
    18. font-style: italic; font-weight: bold
    19. }

    This looked immediately brilliant on Firefox, but Safari acts a bit weird, only anti-aliasing some of the text after hovering over.

    Be aware though, this will add about 1.3MB to your page. If you don't need some of the italic or bold variations, i'd recommend leaving them out.

    On font and copyrights

    On a more serious note, many people don't know that most fonts you buy for your websites are never allowed to be straight-embedded into webpages. I've seen a number of people embedding their fonts with either @font-face or the dirty (but impressive) cufon, or the worst of all worlds: sifr.

    Technically, with any of these technologies you are not just using, but redistributing the font. When you buy a font you are basically only allowed to generate static images. This might not be a big deal for your personal site, but it's not a wise thing to do for commercial sites.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Evert Pot]Killing a dead ssh connection September 27, 2010

    One feature telnet has and I always missed from ssh was the ^] shortcut, giving you a way to terminate the connection.

    ssh has a similar feature. If you setup 'escape characters', you can terminate the connection by typing '~.' Just add the following to your .ssh/config:

    1. Host *
    2. EscapeChar ~

    You can change the character here too, but ~ is the default and a sensible one.

    If you're dealing with crappy ssh connections that often terminate, you can add the following to make the client send a keep-alive package every 60 seconds:

    1. Host *
    2. ServerAliveInterval 60

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Evert Pot]Evercookie: the cookie that just won't die September 22, 2010

    Samy, famous for his worm, released evercookie this week. Evercookie stores cookies is various storage mechanisms such as Flash Local Shared Objects (also known as flookies), HTML5 storage mechanisms and even in the history and cache. When any of these are wiped by the user the script will repopulate it, making it very hard to get rid of your cookies.

    This is technique is common to circumvent a users' privacy wishes, which Clearspring recently got sued for, but it's put in overdrive.

    One good use for it is banning users. In the past I've used ips + cookies to ensure a user stays banned, but it doesn't take much to change your ip address and clear your cookies. All these techniques together make it a lot harder to get through. Because Flash stores it's flookies in a central place in the operating system, the cookies often even live in multiple browsers and private browsing sessions.

    Most of all, I think the tool is made to make a point. It's very hard for the average user to clear all the tracking information. It should be doable with a press of a button, without losing all your settings and history for every other site.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Ian Barber]October Conferences September 20, 2010

    Apologies for the lack of updates recently, but it has been a busy summer! October is looking interesting though, with a few conferences coming.

    First up is PHP Northwest, in Manchester on the 9th and 10th of October. I'll be one of the speakers, with a talk about the rules and tools you can use in debugging. There are a whole host of great people talking though, such as Lorna keynoting on coaching dev teams, Derick talking about maps, and my ShorDurPerSav Lorenzo on profiling. They also have some speakers making the transatlantic trip, like Scotty Mac talking about hip hop, and Marco on how PHP Architect runs. Rob, Mike and Rowan and a couple of others are all talking about Zend Framework, which may bias Marcus' Framework Shootout somewhat.

    Straight after on the 11th to 13th of October is the International PHP Conference in Mainz, Germany, where I'll be giving the debugging talk again, and my search talk. There's a whole lot of talks in German, but among the english content are talks by luminaries including Johannes Schlüter, Ben Ramsey, Sebastian Bergmann, Stefan Priebsch and more (including Derick again, of course).

    Next up I'll be attending (though not speaking at) Search Solutions 2010, in London on the 21st. Finally, at the end of the month on the 29th and 30th you can find me at PHP Barcelona, in Barcelona (natch), talking about search. There are a good slab of the names from above there (including Harrie who is also at PHPNW) and a bunch of new ones (including Thijs talking about The Cloud). I'm really looking forward to all of these conferences, and if you're there please come over and say hi!

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Evert Pot]New job at IBuildings September 15, 2010
    IBuildings

    Since a 2 weeks I'm now employed by IBuildings. First a couple of weeks from their office in Vlissingen, and then if all goes well, to Utrecht.

    IBuildings is actually a company I've been wanting to work for for a while, so I'm pretty happy. So far it's a bit of an adjustment to work regular hours again, but I'm having fun. It's good to be working in an office again. Working from home can definitely get to you after a while. Having lots of talented people around is a big plus.

    And: if you know a good place to live in Utrecht, drop me a line! I'm looking to rent a place not too far from downtown :)

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Evert Pot]Content Security Policy introduction September 15, 2010

    I blogged about Content Security Policy about 2 year ago when it was still called 'Site Security Policy'. It started as a specification and an add-on, and turned into a patch a bit later. Finally it made it into Firefox 4 beta 1. I think CSP is the next web security revolution, so make yourself aware of how it works and the implications.

    So what is it? The short version is that it's a very effective measure against cross-site scripting. By specifying a policy through the 'X-Content-Security-Policy', you can specify exactly from which locations you accept javascript and other content. This allows you to block scripts from any domains unknown to you, and inline scripts altogether.

    A simple example

    1. X-Content-Security-Policy: allow 'self'

    A simple PHP example to see this in action:

    1. <?php
    2.  
    3. header("X-Content-Security-Policy: allow 'self'");
    4.  
    5. ?>
    6. <html>
    7.   <head>
    8.     <title>CSP test</title>
    9.   </head>
    10.   <body>
    11.  
    12. <script type="text/javascript">
    13.  
    14. alert('XSS!');
    15.  
    16. </script>
    17.  
    18.   </body>
    19. </html>

    If the above code is opened in Firefox 4.0 beta1, the script will not execute, and a warning is added to the "Error Console" (in the Tools menu).

    Not only does this header block inline scripts, it also blocks the following:

    • eval(). This important for people using eval() to parse json responses.
    • setTimeout and setInterval if the function is provided as a string.
    • javascript: urls
    • HTML event attributes (onclick, onload, etc.).
    • All images, plugin objects (flash, quicktime etc.), audio, video, html frames and fonts not served from the same domain as the html page.
    • XMLHttpRequest to domains other than the source domain.

    Fortunately there are fine grained controls about what you want to allow from which domains. Here are some examples from the specification.

    1. X-Content-Security-Policy: allow 'self'; img-src *; \
    2.                            object-src media1.com media2.com *.cdn.com; \
    3.                            script-src trustedscripts.example.com

    This example starts with "allow 'self'", allowing only content from the same domain. The "img-src *" rule allows images from any domain. "object-src: media1.com media2.com" allows <object> tags to use files from media1.com, media1.com and the same domain as the html was served from. To learn more about these, I would recommend just taking a good look at the directives list in the specification.

    Options and reporting

    Using the 'options' directive it's possible to turn on specific measures. Valid values for options are 'eval-script' and 'inline-script'.

    1. X-Content-Security-Policy: allow 'self'; options inline-script, eval-script

    The preceding example allows inline scripts (using html event attributes, or the script tag) as well as the 'eval()' function. In general I would try to avoid this though.

    When a security rule is violated, it's possible to get the browser to send a report back to the server. For example, if an image is referenced from a blocked domain, the browser can send a simple report to a url you specify.

    1. X-Content-Security-Policy: allow 'self'; report-uri http://example.org/cspreport.php

    This allows you to detect any problems with your policy, or successful attempts by your evil users to inject code. An example of such a report is the following:

    1. {
    2.   "csp-report":
    3.     {
    4.       "request": "GET http://index.html HTTP/1.1",
    5.       "request-headers": "Host: example.com                                                        
    6.                          User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.3a5pre) Gecko/20100601 Minefield/3.7a5pre                                                        
    7.                          Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8  
    8.                          Accept-Language: en-us,en;q=0.5                                          
    9.                          Accept-Encoding: gzip,deflate                                            
    10.                          Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7                          
    11.                          Keep-Alive: 115                                                          
    12.                          Connection: keep-alive",
    13.       "blocked-uri": "http://evil.com/some_image.png",
    14.       "violated-directive": "img-src 'self'",
    15.       "original-policy": "allow 'none'; img-src *, allow 'self'; img-src 'self'"
    16.     }
    17. }

    Final notes

    Using CSP does not mean you can go easy on other security measures. At the moment a very limited amount of users will have support for CSP, so everybody else still needs to be protected. However, it's still a great idea to implement. Your Firefox users will automatically be protected better, and because of the reporting functionality, they automatically help you detect holes which benefits everybody.

    My guess is that CSP is going to be very important, and is here to stay. There are two things you can do to prepare for the future:

    1. Figure out your policy. It's a good idea for your web application to know anyway where resources are coming from. Especially advertisers tend to be bad at using many different domains and scripts using other scripts.
    2. Try to avoid any inline scripting, html event handlers and eval(). They are all avoidable, and in my opinion it is a good idea to keep your javascript out of html anyway. This is a big one, because both inline scripts and html events are still very popular. With the popularity of libraries such as jQuery, I do think it will be easier to just grab most of the inline scripts and move them to an external script.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Evert Pot]Storing encrypted session information in a cookie September 15, 2010

    cookie

    Our session system is due for an upgrade. Currently all PHP sessions are stored in the database, and some things are getting a bit slow. There have been a couple of approaches I've been considering, one of which is simply storing all the information in a browser cookie.

    First I want to make clear I don't necessarily condone this. The reason I'm writing this post, is because I'm hoping for some more community feedback. Is this a really bad idea? I would love to know.

    The benefits

    If all the session data is stored in the browser, it means that I don't need to store it on the server. I actually don't care all that much for having the data on the server (unless it's the only secure way), it's mostly a gigantic map with session tokens and user id's (along with some other info).

    I also feel it's more natural for HTTP, as it makes it a bit more stateless.

    Sample code

    1. <?php
    2.  
    3. class BrowserSession {
    4.  
    5.     public $secret = 'this will need to be a cryptographic random number';
    6.     public $currentUser = null;
    7.  
    8.     // Sessions time out after 10 minutes
    9.     public $timeout = 600;
    10.  
    11.     function init() {
    12.  
    13.         if (!isset($_COOKIE['MYSESSION'])) {
    14.             echo "No session cookie found\n";
    15.             return;
    16.         }
    17.  
    18.         list($userId, $time, $signature) = explode(':',$_COOKIE['MYSESSION']);
    19.        
    20.         // The cookie is old
    21.         if ($time> time() + $this->timeout) {
    22.             echo "The session cookie timed out\n";
    23.         }
    24.  
    25.         if ($signature !== $this->generateSignature($userId,$time)) {
    26.             echo "The secret was incorrect\n";
    27.         }
    28.  
    29.         $this->currentUser = $userId;
    30.  
    31.         echo "Logged in as user: $userId\n";
    32.  
    33.     }
    34.  
    35.     function login($userId) {
    36.  
    37.         $this->userId = $userId;
    38.  
    39.         $time = time();
    40.  
    41.         $cookie = $this->userId . ':' . time() . ':' . $this->generateSignature($userId,$time);
    42.  
    43.         setcookie('MYSESSION',$cookie,$time+$this->timeout,null,null,null,true);
    44.  
    45.         echo "Set cookie: $cookie\n";
    46.  
    47.     }
    48.  
    49.     function generateSignature($userId,$time) {
    50.  
    51.         $stringToSign =
    52.            $userId . "\n" .
    53.            $time . "\n" .
    54.            $_SERVER['HTTP_USER_AGENT'] . "\n" .
    55.            $_SERVER['REMOTE_ADDR'];
    56.  
    57.         return hash_hmac('SHA1',$stringToSign,$this->secret);
    58.  
    59.     }
    60.  
    61. }
    62.  
    63. ob_start();
    64. $session = new BrowserSession();
    65. $session->init();
    66.  
    67. if (isset($_GET['login'])) $session->login($_GET['login']);
    68. else {
    69.  
    70.     echo '<br /><a href="?login=1234">Log in as user 1234</a>';
    71.  
    72. }
    73. ?>

    A few notes:

    • The preceeding code was just intended as a proof of concept, it's missing some validation.
    • Currently the secret would be the same for every user. I was thinking of appending some per-user information to the secret. If somebody does guess or bruteforce the secret, they would only have access to a single users' information.
    • If a user changes their password, existing sessions should expire. To do this the signature should also include a sequence number that changes when the password changes.
    • Currently this only stores a user id. It could be extended to contain more data, but this is all I need.

    So, is there anything fundamentally wrong with this approach? In general the client should never be trusted, but for setups where the security requirements aren't as high (highly subjective, I know) I feel this might be strong enough. OAuth, OpenID and Amazon AWS all seem to trust HMAC+SHA1, but those applications do work differently.

    Credit where it's due

    I first asked this question on stack overflow. The users there already gave some great suggestions and pointed out some of the flaws. Thank you!

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Evert Pot]What happened to HTTP authentication? September 15, 2010

    Rant warning

    We enter our usernames and password on pretty much all the sites we commonly visit. Authentication is probably one of the first things you're being taught when starting to work with PHP. For some reason, in 99% of the cases this is done through an HTML form, with the username and password submitted as a urlencoded string.

    You probably know that HTTP also has native authentication, in the form of Basic and Digest authentication (read my older article if you want to know how). Every browser and pretty much any HTTP client does too. There's some big benefits to that, because it provides a very standardized mechanism to authenticate a client, whether you're a machine or human.

    What baffles me is that HTTP authentication hasn't been developed further. HTTP Digest is pretty secure by itself, and has some nice features (hashed password, protection against man in the middle and replay attacks, message digests) which is way more advanced than an HTML POST form with a session cookie can provide.

    What's missing?

    1. There's no way for a user to see if they are authenticated to a site. Perhaps a username in the addressbar?
    2. Pretty much everybody always wonders how they can code a logout mechanism. Because there are no session cookies that can be destroyed, there are some hacks that trick the browser to ask for credentials again. There should be no need for the server to provide this functionality. The browser knows it's logged in, and HTTP applications are stateless. We need an in-browser log-out button.
    3. Less important, some javascript hooks that allow developers to still use html forms to setup HTTP authentication.

    Mozilla is doing some interesting things with their Account Manager Add-on for firefox, but even that add-on does not support HTTP authentication. With Account Manager they are jumping through some hoops with javascript hooks so it works with regular authentication systems, but you'd think that if HTTP Authentication was used, things could be a lot more straightforward. The browser knows exactly who is logged in.

    So, does anyone know how this happened? Is there a major flaw in HTTP authentication I'm just missing?

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Evert Pot]Guidelines for generating XML September 15, 2010

    Over the last little while I've come across quite a few XML feed generators written in PHP, with varying degrees of 'correctness'. Even though generating XML should be very simple, there's still quite a bit of pitfalls I feel every PHP or (insert your language)-developer should know about.

    1. You are better off using an XML library

    This is the first and foremost rule. Most people end up generating their xml using simple string concatenation, while there are many dedicated tools out there that really help you generate your own XML.

    In PHP land the best example is XMLWriter. It is actually quite easy to use:

    1. <?php
    2.  
    3. $xmlWriter = new XMLWriter();
    4. $xmlWriter->openMemory();
    5. $xmlWriter->startDocument('1.0','UTF-8');
    6. $xmlWriter->startElement('root');
    7. $xmlWriter->text('Contents of the root tag');
    8. $xmlWriter->endElement(); // root
    9. $xmlWriter->endDocument();
    10. echo $xmlWriter->outputMemory();
    11.  
    12. ?>

    Granted, XMLWriter is verbose, but you have to worry a lot less about escaping and validating your xml documents.

    2. Understand Unicode

    Do you know the difference between a byte, a character and a codepoint? If you don't, I'd probably think twice about hiring you. It's absolutely shocking how many programmers are out there that don't understand the basics of unicode, UTF-8 and how it relates to the web.

    An often-heard excuse for not having to care for non-ascii characters, such as people in English speaking countries. However, if you need to use the euro-sign (€) or if you deal with people copy-pasting from word documents, you most definitely will come across problems.

    A simple call to utf8_encode is not actually enough. If some of your source-data was already encoded as UTF-8 you will end up losing data. Only use utf8_encode if you know your source-data is encoded as ISO-8859-1.

    The one true way to go about it, is to make sure that every step of the way in your web application is UTF-8. Including your HTTP/HTML contenttype, MySQL database and anything that basically ingests data for your application (email, csv importers, xml readers, web services). Once you are absolutely sure every part in your application is UTF-8, and converted any old data things will start to behave correctly.

    3. CDATA is never a solution

    It might be tempting to solve any encoding issues by simply surrounding it with <![CDATA[ and ]]>. This might make sure that XML parsers don't throw an error when reading, but they still have 'incorrect' characters. If your XML document has CDATA tags, or you think you need CDATA, you are probably wrong.

    More often than not using CDATA actually stems from encoding problems (see section 2). CDATA is not a method to encode binary characters, xml parsers will still throw errors if they come across certain byte sequences. If you do really need to encode binary data in XML, the best way is to use something like base64_encode instead.

    If your XML feed uses CDATA because of encoding issues you actually defer your problem to the consumer of your XML feed. So instead of seeing 'weird characters' on your side, the person that reads your xml feed now has no good way to detect which encoding was actually used. If it's for example an RSS feed you're generating, this can result in RSS readers throwing errors, or characters showing up incorrectly.

    4. Be liberal with whitespace

    An error like "unexpected character at line 1, column 176456" is much harder to debug than "line 5078, column 24". Whitespace between xml tags does usually not have any significance, so you can add as much indentation and linebreaks (\n) as you want. Note that tools such as XMLWriter will indent for you automatically.

    5. Be verbose

    Even though you might easily figure out that <ORD_NR> means 'order number', there's no reason why you shouldn't actually state it as <order-number>. Note that the following rules appear to fall in favor for most people:

    • Use lowercase for tags and attribute names.
    • Use dashes (-) to separate words, not underscores (_).
    • Minimize the use of attributes, nested tags allow more flexibility.

    6. Be careful with entities

    The only valid entities in XML are &lt; (<), &gt; (>) &amp; (&) and &quot; ("), so any other entity will simply not work and throw errors.

    HTML DTD's add many entities, so if you're mostly used to using HTML you might expect other entities to work. If your source-data already has entities, you might have to get rid of these first.

    In PHP it means you should use htmlspecialchars, instead of htmlentities.

    Feel free to discuss, disagree, or add on to this list in the comments, I'm happy to hear your experiences.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Ivo Jansch]Saying goodbye to Ibuildings to found Egeniq August 13, 2010

    Those who pay attention to my occasional seemingly random tweets may have noticed this tweet, back in March. It's the first line of the Bob Dylan song "Times they are a'changin", and it marked the start of a long thought process. I had a '10 year itch': I was at Ibuildings since january 2000, back then a 5 person web development shop in the south of the Netherlands, and over the years I had helped Ibuildings grow into a 110+ people PHP service company with 5 offices in 3 countries. Very proud of what Ibuildings had become and my own role in the company, I had a growing feeling of 'what next?'.

    In my enterprise PHP book I mentioned 5 major goals I wanted to accomplish in life: one of them is to found and build a company of my own. And although Ibuildings has always felt a bit mine, that's not the same. So I slowly started thinking about starting from scratch and building a new awesome company. Over the course of the next few months I searched for reasons to leave and reasons to stay, but eventually I knew that in my heart I had already made the decision in March, and all I was doing was finding reasons to validate that choice. There's a saying that in the end, you'll only regret the things you DIDN'T do, so finally I made the decision to go for it.

    What am I going to do? I'm going to found Egeniq, a company centered around a number of mobile products, concepts and related services. Over the course of the next few weeks it will become more clear what exactly we will be doing, but in short it's doing cool stuff with iphones, ipads and android devices (and whatever device makes sense). I've found partners in crime: Bas is going to look after the commercial side of the business, and I'm going to look after the technical side together with a person that I've known and trusted for years (but it will take a couple more weeks before this person's able to announce it).

    So far I've been a member of the PHP community; will this change when I am working with mobile devices? No, on the contrary! I'm both proud and happy to be part of this community, and you can bet that the products we will be developing will have loads of PHP in them (for backends, apis, webservices and the occasional web frontend). I'm still speaking at Zendcon in November, have a new book coming out soon and I hope that Egeniq will be able to contribute to a couple of open source projects.

    I'm very thrilled to finally have this out in the open. I have very supportive friends and family, but I'm still both excited and scared at the same time; I'm giving up a great career for a lot of unknowns, and this may very well be one of the most important decisions I've made in my life so far. So any words of wisdom, encouragement or just plain 'you are stupid for doing this' feedback is more than welcome!

    And to start plugging my new company right away: send all your ideas, project requests and CVs to ivo at egeniq dot com. ;-)

    I will be with Ibuildings until the end of September, mainly to hand over my responsibilities and make sure that we part ways smoothly. My job at Ibuildings has been amazing and I'd like to thank everybody I worked with, every client I worked for and everybody at Ibuildings for a great time. This is not the end, it's a new beginning. A beginning I'm very much looking forward to!

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Ivo Jansch]Good use of public, private and protected in OO class design July 20, 2010

    It's been a while since my last post. My blog pattern these days is that I write a blog post when I have an opinion that doesn't fit in a tweet. :)

    There's been a debate in the PHP community about the use of public, private and protected. Apparently the Symfony project has decided that private is Evil, and should not be used. I don't care much about Symfony as I'm not a user, but it turned to a discussion on OO theory when Stefan defended the position by claiming that you 'should have the right to extend a class's methods if it doesn't support the use case you have'.

    On Twitter, things got worse. Marco Tabini mentioned private has no role in open source code insinuating that it's about who can read the code and Travis Swicegood mentioned that protected code indicates code that is in the wrong place and later that it prevents unit testing because it creates un-testable units of code.

    Before I answer to those claims, let me give you an example of a class that uses public, private and protected in the way they were intended.

    The Account class

     
    class Account
    { public function depositFunds($amount) { $this->_updateBalance($this->currentBalance()+$amount); }
      protected function _updateBalance($newbalance) {
      if ($this->validate($newbalance)) {
      $this->__updateRecord($newbalance); $this->__publishAccountUpdatedEvent(); } }
      private function __updateRecord($newbalance) { $this->getModel()->store($newbalance); }
      ....
    }
     

    As the designer of this class, I have the following considerations:

    • Somebody that uses my class in an application will need to be able to withdraw and deposit funds. This is the only feature I offer to my class users; it is my class's responsibility to take care of handling the withdrawal and deposits.
    • Derived Account classes (which will follow the 'is a' scenario of inheritance and thus will probably be special types of accounts, such as savings accounts) should be able to withdraw and deposit, but can also call _updateBalance to update the balance directly. This is something I trust derived classes with.
    • The actual act of updating the underlying model is my responsibility and my responsibility alone. This method is private because I do not want other classes to call this function directly. The only way to call __updateRecord is through the protected _updateBalance call. This way I ensure that there's always validation and that notifications get send out. This makes my application more robust because the things that need to happen, will happen. I trust derived classes to update the balance, but the trust goes only so far; the actual act of updating the underlying model is my responsibility.

    This process is called 'encapsulation'.

    Looking back at the arguments

    Now let's look again at the arguments.

    • Stefan says that he needs to be able to override things if they don't support his use case. The above class is designed to support a variety of use cases, through the interface it offers to users and inheritors. Generally a use case is defined by the public methods a class offers, and that should be sufficient. If not, the class may have been designed poorly. Inheritors can change the use case slightly, but only to the extent that they do not endanger the overall robustness of the application.
    • Marco says that private has no use in open source projects. The above example could be part of an open source project. The decision to make a method private had nothing to do with the fact that others could read the code, nor did it have anything to do with the fact that the code cannot be changed. If this is an open source package and you want to change it because in your world you do want unvalidated account updates, you can simply download the code, change the code and be happy.
    • Travis claims that 'protected' signifies code that is in the wrong place. On the contrary, in my example I've used protected and private deliberately to design class responsibility.
    • Travis also says that it is a problem for unit testing because it creates an untestable unit. I would argue that in this case, the 'unit' is the account and its public interface. A unit test should use only the public interface which is sufficient to verify whether or not the class is doing the right things, and whether it's doing those things right. If the class contains so much code that you need unit tests that test the smaller internal functions of the class, you may be looking at a class that has too much responsibilities and that should be split up.

    The arguments seem to be mostly about what you can derive but the number 1 use case of access specifiers is defining what you can call. In my opinion, preventing people from using private to make deriving easier at the expense of no longer being able to specify who can call what and define class responsibilities, is wrong. In most cases where this is a problem, the actual problem is poor class design.

    There are of course numerous situations where the designer of a class has made the wrong decision and made a method private that should've been protected. In such scenario's, changing it and contributing a patch seems the right thing to do. However removing the use of private from a project entirely because some can't handle the difference, seems very wrong.

    Other languages

    PHP is not the first language to support private, public and protected. Other languages have seen similar debates, with more or less the same underlying principles. Ruby has built in ways to circumvent private/protected/public so functions can be unit tested. C++ is the most advanced when it comes to OO design. It supports 'private inheritance' and 'protected inheritance'. See here for examples. Also it supports a 'friend' feature that allows a class to define 'friends' that can access their private members. If classes befriend their unit tests, then unit tests can access private functions.

    PHP doesn't have a 'friends' feature (I nearly said 'PHP doesn't have friends' which does sound funnier but is not what I meant ;-) ) nor does it have ways to circumvent the access specifiers for unit tests. That doesn't make the concept of private and protected any less useful though.

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Lorna Mitchell]SugarCRM 6 Installation Error July 18, 2010

    I noticed that SugarCRM have just released their new version 6.0.0, and since my sugarcrm installation is madly out of date and I'm about to start using it again, I thought I'd just throw the old one away and install from scratch. I had no problems until I reached the final installation stage, when clicking the "install" button would return a 404. This is tedious because then you have to follow the instructions and change config.php so that "installer_locked" is false (but the installer does remember all the information you give it, which makes this less annoying)

    After a couple of times around the loop I looked properly at the warnings on that final page before the "install" button, and made some php.ini changes in line with what it requested - increasing the memory_limit and the upload_file_size. I also installed php5-curl (I'm an ubuntu user so this is just an aptitude package for me) and the install ran like a dream at that point. I'm disappointed that SugarCRM couldn't give me better feedback than just a 404, but it seems like it needed some settings that I didn't have - so if you see the same behaviour, don't give up but heed the warnings and it should be able to install itself absolutely fine. Hope this helps!

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Lorna Mitchell]Giving Up The Day Job July 13, 2010

    The In-A-Nutshell Version I have resigned from Ibuildings. I will complete my notice period here in a couple of weeks and then move on to a wide and interesting variety of well-paying freelance assignments covering development, consultancy, writing and speaking. Hopefully.

    The slightly longer version really is this. Two and a half years ago, I left a job at a type of company I usually describe as a yet-another-website company, where literally every new project was another CMS website. Which was fun for about the first 4 months and got old pretty quickly. Two and a half years at Ibuildings and I haven't done yet-another-anything, the projects have been technical, challenging and my colleagues are the best qualified set of people I'll probably ever work with.

    Along the way I've also done a wide variety of other things, most of which are achievements beyond my wildest dreams, some within the scope of this job and some on my own time but of course influenced by all that I've learned. I've delivered training, led projects, been published, become a regular conference speaker and travelled internationally doing so, collaborated on an open source project, edited a developer portal and hosted a major international PHP conference. I've even learned to say those things about myself in public without feeling too much of a fraud!

    At this point, there are so many things I want to be doing, writing, speaking and so on, as well as some interesting development projects, that holding down my 9-5 as well has become untenable; that's the main motivation for this change. I don't intend to take another full time job, although I don't have a lot of paying work lined up so please bear in mind that I am looking for some ;)

    Things I would like to be doing:

    • Working with development teams on skills, tools and process (think teach a man to fish, rather than sell him a fish)
    • API development
    • Technical writing
    • Meeting cool and interesting people and embarking on cool and interesting projects together

    Advice on achieving any or all of the above is appreciated - if any of you can also think of me when discussing business, write me a linked in recommendation, or retweet my announcement of my news, that would be fabulous!!

    If you're still reading, then I'll share a little something with you. I decided that with a career move, I needed a little rebrand, so here is my new angel avatar. I hope you like her :)

    Wish me luck in my new (ad)venture, I'll be keeping everyone up to date as always!

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Lorna Mitchell]Retrieving Product Attributes from Magento's V2 API July 12, 2010

    I've been working with the API for Magento in recent weeks and I had a bit of a struggle explaining to the V2 API which attributes of a product I wanted to retrieve. Actually I had issues talking to the V2 API at all, but that's a different post so I'll skate over those for now. Instead I thought I'd share (or rather, record for the next time I have the same problem!) how to specify which attributes about a product to retrieve.

    It actually wasn't complicated but without V2 API documentation, it wasn't at all clear what to feed in to get the result I was looking for. It turns out you can just pass an array of desired attributes, shown here with the info method from the product_catalog:

        // connect to soap server
        $client = new SoapClient('http://magentoinstall.local/api/v2_soap?wsdl=1');

        // log in
        $session = $client->login('user', 'pass');

        // product info
        $attributes = new stdclass();
        $attributes->attributes = array('product_title', 'description', 'short_description', 'price');
        $list = $client->catalogProductInfo($session, <sku>, NULL, $attributes);
     

    There were two tricks - one was realising that I could pass that final (undocumented) argument, and the other was understanding how to format that. Hopefully anyone doing battle with the same thing will find this post and get over this little challenge much faster than I did :)

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Lorna Mitchell]Speaking at FrOSCon July 10, 2010

    In August I'll be attending FrOSCon in Germany for the first time, and speaking there. It's a mixed technology conference, with rooms set aside for separate scheduling for various projects and technologies. I'll be speaking in the PHP room, delivering "Working With Web Services", a talk which covers how to consume all sorts of types of web service from PHP. I'm excited about that and even more excited to hear that I'll also be speaking in the main track, where I'll deliver "Open Source Your Career" - stories and advice about how involvement in open source can positively influence the career path for each of us.

    I haven't visited this part of Europe before so I'm also including a couple of days to see the area, and really looking forward to the trip. Since there are technologies other than PHP, and since I'm rarely in Germany, I know I'm going to meet a lot of new people ... and I can't wait :)

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)
  • [Ian Barber]Monte Carlo Simulations July 3, 2010

    Monte Carlo CasinoMonte Carlo simulations are a handy tool for looking at situations that have some aspect of uncertainty, by modelling them with a pseudo-random element and conducting a large number of trials. There isn’t a hard and fast Monte Carlo algorithm, but the process generally goes: start with a situation you wish to model, write a program to describe it that includes a random input, run that program many times, and look at the results.

    In each case, you’re taking a pot shot at the result, and over many iterations you should get a broad picture of the probabilities of certain outcomes. If these match observations of the real situation, your model is a good one. Alternatively, if you can achieve certain results through randomness that others put down to some other factor, perhaps there is more chance in the real situation that others have expected.

    As an example, lets imagine visiting an SEO expo, filled with 10,000 SEO experts. Now, 20% of the experts are creative copywriters and link profile experts who will help to make your site more usable, more readable, faster, and help drive traffic from disparate sources as they improve your search profile. The others are clueless keyword stuffers and link spammers, who will turn your site into an real mess.

    However, a given rank on a results page is dependent on an awful lot of things - how the site was originally, what other sites are doing, changes to google’s algorithms, temporary network and server effects and so on. Because of that, sometimes the bad SEOs get their sites onto the front page, and sometimes the good ones don’t. Let estimate that the good SEOs get their site onto the first page under a given term two thirds of the time, while for the bad SEOs it’s only one third of the time. Now, whichever SEO you ask claims to be in the good category, of course, so you ask to see the results for the last 5 sites they optimised. If they are all on the first page, can you be confident you’ve got a good one?

    We can set up a monte carlo simulation for that by simply looping over the five sites, and seeing which ones succeed each time, by chance, and which fail. Starting with our total 10,000 SEO population, how many good vs bad SEOs do we expect.

    <?php
    $tGood = $tBad = 0;
    $iterations = 10000;

    for($iters = 0; $iters < $iterations; $iters++) {
            $goodCount = 2000;
            $badCount = 8000;

            for($i = 0; $i < 5; $i++) {
                    $max = $goodCount;
                    for($j = 0; $j < $max; $j++) {
                            if(lcg_value() < 0.33) {
                                    $goodCount--;
                            }
                    }
                    $max = $badCount;
                    for($j = 0; $j < $max; $j++) {
                            if(lcg_value() < 0.66) {
                                    $badCount--;
                            }
                    }
            }
            $tGood += $goodCount;
            $tBad += $badCount;
    }

    var_dump("Good SEOs: " . $tGood/$iterations);
    var_dump("Bad SEOs: " . $tBad/$iterations);
    ?>

    After our 10,000 iterations, we see the numbers come out with a majority of good SEOs, but some bad ones have made it through:

    string(19) "Good SEOs: 270.0382"
    string(16) "Bad SEOs: 36.343"

    This is an example where we can use brute force to solve what would otherwise be an integration problem. Admittedly, this is not a very difficult problem, but the logic can be continued and refined into situations that are require more complex maths. The wikipedia Monte Carlo simulator page has a good description of how the value of Pi can be estimated by a Monte Carlo method, for example.

    Projecting The Future

    For a more complicated example, we can think about planning a development project. We’d like to take a set of estimates, and run them through a Monte Carlo simulation to see what kind of overall times we can expect. Imagine that we’ve taken a look at past projects, and concluded a few things about the estimate. Our estimates always come in a ‘best case’, ‘worst case’ variety, so we have a range of numbers. Most tasks are delivered somewhere within that range, usually well under the worst case, but there are small few that seem to go way over it.

    We decide to model this by assuming that worst case is actually 3 times that estimated originally. However, rather than assuming we have equal chance of getting any value in that range (a flat distribution), we want to model our chance of getting the lower results as being higher than getting the higher ones. This kind of distribution is called a power law, and we can use a function that models that distribution for our random function.

    <?php
    function powerLaw($min, $max, $n) {
            $max += 1;
            $val = pow(
                            ( pow($max, $n+1) - pow($min, $n+1) )
                                    * lcg_value()
                                    + pow($min, $n+1),
                            (1.0/($n+1))
                    );
            return $max - 1 - $val + $min;
    }

    function getTotalTime($estimates) {
            $totalTime = 0;
            foreach($estimates as $estimate) {
                    $totalTime += powerLaw($estimate['best'], $estimate['worst']*3, 5);
            }
            return $totalTime;
    }
    ?>

    With those functions in place, all we have to do is feed in our estimates, and for each one run them through the getTotalTime function. We can do a number of loops of this, and look at the results that we get.

    <?php
    // our estimates
    $estimates = array(
            "login form" => array("best" => 2, "worst" => 10),
            "forgotten password" => array("best" => 8, "worst" => 20),
            "profile page" => array("best" => 16, "worst" => 20),  
            "avatar upload" => array("best" => 8, "worst" => 14),  
    );

    // conduct 10,000 trials
    $results = array();
    for($i = 0; $i < 10000; $i++) {
            $res = getTotalTime($estimates);
            if(!isset($results[$res])) {
                    $results[$res] = 0;
            }
            $results[$res]++;
    }
    ksort($results);
    ?>

    This gives us an array of results, from which we can calculate some estimates. For example, although the worst case from the estimates is 64 hours, if we want to account for 80% of the runs we’d need to allocate around 68 hours - and assuming our model is correct then our project would still have a 20% chance of going over!

    We can visualise this by using the Google Charts API, which helps to show how, while the bulk of runs fit around the original hours, there is a tail to consider of unexpectedly long delivery times:

    <?php
    $url = “http://chart.apis.google.com/chart?chs=450x200&cht=bvs”;
    $url .=&chds=0,. max($results);
    $url .=&chd=t:. implode(,, $results);
    $url .=&chbh=3,1,1”;
    echo $url; // url for google
    ?>

    A plot of the estimates from google charts

    The length of time runs along the horizontal access, number of trials that resulted in that time in the vertical access. The long tail of growing times of the estimate show why to get a more certain timescale we have to go way over our original worst case, but still having the project likely to be delivered somewhere in the original range.

    The nice thing about these methods is that they are fairly easy to get a grip of. You can plug in a randomness function of your choosing based on almost anything, and try modelling situations that otherwise would be hard to understand intuitively. By plotting the result of calculating statistics you can quickly try out scenarios and get a feel for different sort of effects, as long as there's an element in the thing you are modelling that is chaotic enough to be effective random.

    Image Credit: Monte Carlo Casino by mfotinakis

    Digg This
    Reddit This
    Stumble Now!
    Buzz This
    Vote on DZone
    Share on Facebook
    Bookmark this on Delicious
    Kick It on DotNetKicks.com
    Shout it
    Share on LinkedIn
    Bookmark this on Technorati
    Post on Twitter
    Google Buzz (aka. Google Reader)