Wednesday, February 03, 2010

PHPBenelux conference 2010 wrapup

This past weekend, Belgium was buzzing PHP all the way. PHPBenelux organized the first annual international PHP conference in Belgium and it can be called a true success. Attendees and speakers coming from all parts of the world made this event a true international conference and I was truly happy to be a part of it, this time as member of the organization.

Preparation
The months, weeks and certainly the days prior to the conference were hectic, stressful and sometimes energy draining. With lots of things that still needed to be done last minute, we have learned that we still have lots of room to improve ourselves for future events. But, as it is common to PHP development, we met our deadlines and saw everything was running smoothly.

Airport and train station runs
The conference had a few international speakers on the list, for who we had to ensure a smooth ride to the conference hotel. Stefan Koopmanschap picked up Cal Evans at Schiphol. Thijs Feryn went down to Antwerp Central Station to pick up Fabien Potencier, and had to do this 3 times returning each time without Fabien (read his blog article about what happend). I myself went to Brussels International Airport to pick up David Zülke and Rowan Merewood traveling together with Ben Waine.


Speaker's dinner and pre-conference social
As is custom to events like this, we organized as speaker's dinner where we invited our speakers and sponsors to participate in this socializing event where everyone has the opportunity to get to know each other, discuss topics and exchange ideas. We headed out to Da Giovanni, an Italian restaurant in the center of Antwerp that is known for it's overwhelming tacky design. Red-white blocked cloths everywhere: the shirts of the waiters, the tables and lamps. We had a decent meal and a very good laugh.
Following the dinner we also organized a pre-conference social in De Vagant, one of Antwerp's most known Jenever locations. This was open for everyone that was in the area and could make it to the place. But tiredness and pre-conference jitters had this social ended well before midnight.

The conference
Saturday was the big day, and what a day it was ! Sponsors arrived well in time to set up their booths and at about 8:30am the first attendees were coming in. Since it had snowed during the night, most attendees were a bit late so we started the sessions with a delay of 30 minutes (by lunch time we were already back on schedule).
After a short introduction by Stefan Koopmanschap, Derick Rethans officially opened the conference with his keynote talk "The PHP Universe", which was well accepted by the audience (See reviews on http://joind.in/1240). The following talks followed right after and filled the most of the conference.

Remote presentation
Due to bad weather, Zend's speaker Eric Ritchie couldn't make it to the conference, but by using WebEx we were able to have him present his talk "Generating dynamic PDFs using Zend Framework and JavaBridge" (http://joind.in/1268) from his office as though he was standing in the room. Although it was a bit tough to set up, I have to say it was successful fix for Zend, WebEx and us.

One downside of this approach is that Eric didn't had the chance to interact with the attendees himself during or after his keynote and as shown in the comments on joind.in there were still a few questions that the attendees wanted to clarify with Eric. So, in a technical perspective it can be called a success, but for the conference spirit it has a downside.

Closing Keynote
My personal mentor and dear friend Cal Evans was given the floor to present his closing keynote "Open Teams" (http://joind.in/1251) which was unlike the other talks not a technical subject, but non-the-less a very valuable view on how managers and developers can improve the way they operate. Unfortunately I missed this talk, but I'm looking forward seeing it on an other occasion. You can contact Cal and invite him to give this talk for the managers in your company, so your company can become "Company Awesome" everyone wants to work for.

Ibuildings Conference Social
The people of Ibuildings were really kind to sponsor the after-social event, held in the exhibition hall. Besides drinks and very delicious food, our other sponsors had some goodies to give away and so people walked away with an iPhone and Zend Studio licenses, a ticket for PHPBenelux Conference 2011, a ticket for PHPUK 2010, Windows 7 licenses, a netbook (provided by Nocus) and of course elePHPants. So a big applause to the winners and of course our sponsors for providing these awesome prizes.

Sponsors
This great conference wasn't possible without the help of our sponsors, and we all thank them for making this first conference the best start of 2010. Thank you !!!


PHP is hot !
Apparently PHP is hot, hotter then ever. At the conference, a lot of people not only attended the great sessions, but they were also looking for new PHP developers to join their teams. And they were not just giving you a great job, they even offered some real nice goodies when you signed up:
If you're a company and you're looking for PHP Rock stars, see how you can persuade them to at least talk to you. Make sure you have seen the slides of Cal Evans's talk about "Open Teams", cause if you can offer this, you do have the advantage !

PHPBenelux Team
This conference succeeded because of the never-failing, passionate help and support by the whole PHPBenelux team. I have worked in many teams already, but I have to say that working with these guys on a remote basis (all using Skype, Google docs and e-mail as main communication and collaboration tools) worked very well (as to emphasize what Cal Evans stated in his "Open Teams" talk) and everyone was there to see the result.

Teamies, thanks a lot for this wonderful experience and I'm looking forward doing the things we do best: community relations, meetings and events ! You guys rock !!!

PHPBenelux team by @phpcodemonkey

Conclusion
This was the first conference that I not only attended, but was actually involved behind the scenes. It was a great experience and I have now more respect to organizers of bigger conferences now that we know what kind of challenges they have to overcome.

Read what others had to say about our conference:
I had a blast and I hope you all enjoyed it. See you all next year at the PHPBenelux Conference 2011, and let us know how to improve ourselves for next years' conference at joind.in !!!

Thursday, January 07, 2010

Zend Framework data models

I was struggling getting my data models (as described in the Zend Framework Quickstart) to work with relations. My first solution was to create a database view that merged that data using joins to collect this data in a format that I could use in my data models. This was going great until I looked at my database where it contained over 20 views (along with 20 data models, mappers and db table gateways) ! So I said to myself there had to be another way.

Fortunately there was a solution, hinted by Felix De Vliegher on IRC. He pointed me to the Zend Framework Zend_Db_Table Relationships page on the Zend Framework online manual. And although it's clearly specified how things work, I struggled a bit to see how each component was linked to the other and when I should use what.

So, I decided to work out a small application to test and support this relationship modeling.

Step 1: Preparation
Let's start with creating a new Zend Framework project that we call "datamodels".

zf create project datamodels

This creates a new Zend Framework project that we can use to showcase these examples. We add a few directories to the application structure to store our documentation, our database and our schemas.


These are four tables all related to each other that we use to base our tutorial and test upon.


Translated into SQLite3 this looks like this:
-- filename: schema.sqlite.sql -- 
create table `user` (
    `id` integer primary key autoincrement,
    `username` text not null,
    `password` text not null
);

create table `contact` (
    `id` integer primary key autoincrement,
    `user_id` integer not null,
    `email` text not null,
    `phone` text null,
    `fax` text null
);

create table `address` (
    `id` integer primary key autoincrement,
    `type_id` integer not null default 1,
    `user_id` integer not null,
    `address1` text not null,
    `address2` text null,
    `city` text not null,
    `state` text null,
    `zip` text not null,
    `country` text not null
);

create table `address_type` (
    `id` integer primary key autoincrement,
    `type` text not null
);
Creating the SQLite3 database is now easy as 1,2,3. Just from command line execute sqlite3 ./data/db/datamodels.db < schema.sqlite.sql and see the magic happen. Our database is set and ready to use.

Our test data is also stored in a file, it's contents can be found here:
-- filename: data.sqlite.sql --

-- Data for user table --
INSERT INTO `user` 
    VALUES (1, 'testuser1', 'test123');
INSERT INTO `user` 
    VALUES (2, 'testuser2', 'test234');

-- Data for contact table --
INSERT INTO `contact` 
    VALUES (1, 1, 'test1@example.com', '1-800-555-1234', '1-800-555-1230');
INSERT INTO `contact` 
    VALUES (2, 2, 'test2@example.com', '1-800-555-2234', '1-800-555-2230');

-- Data for address table --
INSERT INTO `address`
    VALUES (1, 1, 1, '1 Test Home', '', 'Testtown', 'ZF', '1234', 'PHP');
INSERT INTO `address`
    VALUES (2, 1, 2, '2 Test Home', '', 'Testtown', 'ZF', '1234', 'PHP');
INSERT INTO `address`
    VALUES (3, 2, 2, 'Test Corp, LTD', '4 Test Ave', 'Testtown', 'ZF', '1234', 'PHP');
    
-- Data for address_type table --
INSERT INTO `address_type`
    VALUES (1, 'Home address');
INSERT INTO `address_type`
    VALUES (2, 'Billing address');


In application/configs/application.ini we need to add the following lines in order to use our newly generated database:

[production]
...
resources.db.adapter = "Pdo_SQLite"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/datamodels.db"

You also need to define our "Default" namespace in the application bootstrap file Bootstrap.php. This is done by adding the following lines there.

protected function _initAutoload()
    {
        $autoloader = new Zend_Application_Module_Autoloader(array (
            'namespace' => 'Default',
            'basePath' => APPLICATION_PATH,
        ));
        return $autoloader;
    }

Creating the four data models along with their mappers and table gateways is a bit of work so I've provided the application as-is on a public SVN repository (https://svn2.hosted-projects.com/in2it/datamodels/tags/step_1). You can export it and start from there.

Step 2: Displaying a user listing
We want to display a listing of users with their contact details and the number of addresses they have, more or less like the following table:

Username
E-mail
Phone
Fax
# addresses
testuser1
test1@example.com
1-800-555-1234
1-800-555-1230
1
testuser2
test2@example.com
1-800-555-2234
1-800-555-2230
2

As you can see now, with this listing we have 3 tables combined and without some relational information between the models it's hard to get this kind of listing.

Let's set up our dbTable classes to work with relationships.
class Default_Model_DbTable_User extends Zend_Db_Table_Abstract
{
    protected $_name = 'user'; 
    protected $_dependentTables = array (
        'Default_Model_DbTable_Contact',
        'Default_Model_DbTable_Address',
    );
}

class Default_Model_DbTable_AddressType extends Zend_Db_Table_Abstract
{
    protected $_name = 'address_type'; 
    protected $_dependentTables = array ('Default_Model_DbTable_Address');
}

class Default_Model_DbTable_Contact extends Zend_Db_Table_Abstract
{
    protected $_name = 'contact';
    protected $_referenceMap = array (
        'User' => array (
            'columns' => array ('user_id'),
            'refTableClass' => 'Default_Model_DbTable_User',
            'refColumns' => array ('id'),
        ),
    );
}

class Default_Model_DbTable_Address extends Zend_Db_Table_Abstract
{
    protected $_name = 'address'; 
    protected $_referenceMap = array (
        'User' => array (
            'columns' => array ('user_id'),
            'refTableClass' => 'Default_Model_DbTable_User',
            'refColumns' => array ('id'),
        ),
        'Type' => array (
            'columns' => array ('type_id'),
            'refTableClass' => 'Default_Model_DbTable_AddressType',
            'refColumns' => array ('id'),
        ),
    );
}

In order to use these relations, we create a new model and mapper for listing these accounts.

class Default_Model_Accounts extends Default_Model_Abstract
{
    protected $_username;
    protected $_email;
    protected $_phone;
    protected $_fax;
    protected $_addressCount;
    
    public function getUsername ()
    {
        return $this->_username;
    }

    public function setUsername ($username)
    {
        $this->_username = (string) $username;
        return $this;
    }

    public function getEmail ()
    {
        return $this->_email;
    }

    public function setEmail ($email)
    {
        $this->_email = (string) $email;
        return $this;
    }

    public function getPhone ()
    {
        return $this->_phone;
    }

    public function setPhone ($phone)
    {
        $this->_phone = (string) $phone;
        return $this;
    }

    public function getFax ()
    {
        return $this->_fax;
    }

    public function setFax ($fax)
    {
        $this->_fax = (string) $fax;
        return $this;
    }

    public function getAddressCount ()
    {
        return $this->_addressCount;
    }

    public function setAddressCount ($addressCount)
    {
        $this->_addressCount = (int) $addressCount;
        return $this;
    }

    public function getMapper()
    {
        if (null === $this->_mapper) {
            $this->setMapper('Default_Model_Mapper_Accounts');
        }
        return $this->_mapper;
    }
    public function populate($row)
    {
        if (is_array($row)) {
            $row = new ArrayObject($row, ArrayObject::ARRAY_AS_PROPS);
        }
        if (isset ($row->id)) {
            $this->setId($row->id);
        }
        if (isset ($row->username)) {
            $this->setUsername($row->username);
        }
        if (isset ($row->email)) {
            $this->setEmail($row->email);
        }
        if (isset ($row->phone)) {
            $this->setPhone($row->phone);
        }
        if (isset ($row->fax)) {
            $this->setFax($row->fax);
        }
    }
    public function toArray()
    {
        return array (
            'id' => $this->getId(),
            'username' => $this->getUsername(),
            'email' => $this->getEmail(),
            'phone' => $this->getPhone(),
            'fax' => $this->getFax(),
            'address_count' => $this->getAddressCount(),
        );
    }
}

class Default_Model_Mapper_Accounts extends Default_Model_Mapper_Abstract
{
    public function getDbTable()
    {
        if (null === $this->_dbTable) {
            $this->setDbTable('Default_Model_DbTable_User');
        }
        return $this->_dbTable;
    }
    
    public function fetchAll($className, $where = null, $order = null, $count = null, $offset = null)
    {
        $entries = array ();
        $model = null;
        if (!is_string($className)) {
            require_once 'Zend/Exception.php';
            throw new Zend_Exception('Model class name should be a string');
        }
        if (is_string($className)) {
            if (!class_exists($className)) {
                require_once 'Zend/Exception.php';
                throw new Zend_Exception('Non-existing model class name provided');
            }
        }
        if (null !== ($resultSet = $this->getDbTable()->fetchAll($where, $order, $count, $offset))) {
            foreach ($resultSet as $row) {
                $model = new $className;
                if (!$model instanceof Default_Model_Abstract) {
                    require_once 'Zend/Exception.php';
                    throw new Zend_Exception('Invalid model class provided');
                }
                
                // let's get contact details first
                $contacts = $row->findDependentRowset(
                    'Default_Model_DbTable_Contact',
                    'User'
                );
                $contact = $contacts->current();
                $model->populate($contact);
                unset ($contacts, $contact);
                
                // let's see how many addresses this contact has
                $addresses = $row->findDependentRowset(
                    'Default_Model_DbTable_Address',
                    'User'
                );
                $addressCount = count($addresses);
                $model->setAddressCount($addressCount);
                unset ($addresses, $addressCount);
                
                // now it's time to add our user details to the model
                $model->populate($row);
                $entries[] = $model;
                unset ($model);
            }
        }
        return $entries;
    }
}

And to view our completed table, we need to modify our view partial userlisting.phtml:

<tr>
  <td><?php echo $this->escape($this->username) ?></td>
  <td><?php echo $this->escape($this->email) ?></td>
  <td><?php echo $this->escape($this->phone) ?></td>
  <td><?php echo $this->escape($this->fax) ?></td>
  <td><?php echo $this->escape($this->address_count) ?></td>
</tr>

Now we have our table set as we want it:



You can download this step from the repo to see the changes yourself: https://svn2.hosted-projects.com/in2it/datamodels/tags/step_2.

Conclusion
Once you have figured out how these relationships work, you can extends your model capabilities without resorting to other solutions (like using database views) or maintaining crappy code.

On the other hand, It would be nice if I could use my already created models with their functionality in one go, so I can link my datamodels instead of my data sources. Need to figure this one out.

Tuesday, December 29, 2009

A great 2009 !

It's that time of year again where one looks back to all the things that have happened in the past 12 months. 2009 has to be the most thrilling, fastest ride ever and I'm really surprised to see it's nearly the end of this year.

PHP
The most thrilling part of 2009 was the release of PHP 5.3 on June 30. With this release, PHP has risen to a new level of development implementing some long awaited features like DateTime, namespaces, closures, gotos (who wants to use that ?!?), late static binding and an improved garbage collection. Also new extensions were added to this release like ext/phar, ext/fileinfo and ext/intl.
I want to express my gratitude to all those developers who have made this release possible and to all the participants of PHP Test Fest for making their contributions worth the while.

Zend Framework
It's also worth mentioning that Supreme Allied Commander Matthew Weier O' Phinney, his team and all developers around the world have done a great job improving Zend Framework. With the release of Zend Framework 1.8, lot's of things changed within the way applications are being bootstrapped and provided a more flexible way to deploy feature rich applications with a very modular structure.

PHP Conferences
For me personal it was a very exciting year where I was speaking at some great conferences on stage and in uncon sessions (thank you Keith!). If budget allows it, I'll be attending these conferences again in 2010.
One conference will be added to this list in 2010 since I'll be co-organizing it: PHPBenelux Conference.
If you ever want to catch up on the hottest game in PHP, be sure to check out these and other great PHP conferences on the PHP website. You'll learn so much from the conference itself, the speakers and the audience itself, it's really worth the money.


Macq Electronique
Since March of this year I've been working as a PHP/Zend Framework consultant for Macq Electronique, a hardware manufacturer in Brussels that provides hardware solutions for governments (like automated traffic panels, speed enforcement cameras, tunnel control and pump installation monitors). I would like to thank the company for giving me inside view of these infrastructures and I'm excited to work with them again in 2010.


Thank you !
I would like to express my gratitude to the following people who have thought me a few valuable lessons that I can use in my personal and professional life:
  • Cal Evans:
    Cal, to you we now have our own PHP conference in January. Without your support, advise and never ending belief in us, we weren't able to pull it off. Thank you !
  • Matthew Weier O'Phinney:
    Matthew, although we never had the chance to sit down and discuss things I do want to thank you for all the good work you have done for Zend Framework and the PHP Community. If it wasn't for you, I'd still be stuck writing crappy code with code replication and re-inventing the wheel all over again. Thank you !
  • Keith Casey:
    Keith, thanks to you I was able to talk about stuff that matters to me and being able to inspire people to become interested in things like SPL and Unit Testing. Thank you !
  • Stefan Koopmanschap:
    Stefan, although it seems I've been giving you lots of advice this year, you have shown me what a true spirit means. With your enormous passion for PHP and your ideas to promote PHP in ways that I never could think possible, I owe you so much. Thank you my friend !
  • Chris Cornut:
    Chris, I would like to thank you for giving us Joind.in. With it's simple interface and it's purpose it has given me so much feedback on how to improve my skills as a speaker. Without it, I would never known what areas I could improve myself. So thank you very much for your efforts !
Conclusion
2009 was a great year and I'm sorry to see it end. But a new year is around the corner and who knows, it might bring even more excitement and fulfillment. Anyways, I wish you all a very happy new year and I hope to see you again at a conference somewhere in the world.

Sunday, November 01, 2009

Unit testing with Zend Framework 1.8+

I recently gave a presentation at ZendCon 2009 Uncon about "php unit with Zend Framework", which many people liked a lot (see comments on http://joind.in/638). But since then I got a lot of questions how to set up a testing environment for Zend Framework applications that uses version Zend Framework 1.8 or newer.

We start off by setting our environment best fitted for our unit testing. I use a virtual linux system for this, using VMWare, but with some extra background research these global settings can be applied for your own (test) environment as well.

I'm not going to explain how to install PHP here, but I can tell you I'm using PHP 5.3.0 (build from source). With this build, I've installed PHPUnit 3.4.2 and Xdebug 2.0.5. The example application was made using Zend Framework 1.9.5.

First we're creating a new Zend Framework project using Zend_Tool on command line, by issuing the command zf create project zfunit in the workspace directory I use to share my VMWare instance with my workstation.

Ok, we now have a default Zend Framework application running.




We're not going to build a complete application here, but just showing how you can start unit testing your Zend Framework project, so you can implement unit tests on your own applications.

First we need to modify the phpunit.xml file so we can use it as our unit testing configuration.


<phpunit bootstrap="./TestHelper.php" colors="true">
    <testsuite name="Zend Framework Unit Testing">
        <directory>./directory>
    testsuite>

    <filter>
        <whitelist>
            <directory suffix=".php">../library/directory>
            <directory suffix=".php">../application/directory>
            <exclude>
                <directory suffix=".phtml">../application/directory>
            exclude>
        whitelist>
    filter>

    <logging>
        <log type="coverage-html" target="./log/report" charset="UTF-8" yui="true" 
         highlight="true" lowUpperBound="50" highLowerBound="80"/>
        <log type="testdox-html" target="./log/testdox.html" />
    logging>
phpunit>


As you see in the root node of our phpunit.xml file, we include the TestHelper script to aid us setting up the right testing environment. Of course, you can modify this file to fit your own application setup. This is my TestHelper script to set up my test environment, include paths and setting timezones.



// start output buffering
ob_start();

// set our app paths and environments
define('BASE_PATH', realpath(dirname(__FILE__) . '/../'));
define('APPLICATION_PATH', BASE_PATH . '/application');
define('APPLICATION_ENV', 'testing');

// Include path
set_include_path(
    '.'
    . PATH_SEPARATOR . BASE_PATH . '/library'
    . PATH_SEPARATOR . get_include_path()
);

// Set the default timezone !!!
date_default_timezone_set('Europe/Brussels');

// We wanna catch all errors en strict warnings
error_reporting(E_ALL|E_STRICT);

require_once 'ControllerTestCase.php';



We create a custom ControllerTestCase that we can extend in all our controller test cases. This proves to be the most convenient way to handle the setup and teardown of the Zend Framework architecture.



require_once 'Zend/Application.php';
require_once 'Zend/Test/PHPUnit/ControllerTestCase.php';

abstract class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase
{
    public $application;

    public function setUp()
    {
        $this->application = new Zend_Application(
            APPLICATION_ENV,
            APPLICATION_PATH . '/configs/application.ini'
        );

        $this->bootstrap = array($this, 'appBootstrap');
        parent::setUp();
    }

    public function appBootstrap()
    {
        $this->application->bootstrap();
    }
}



And finally we create our first test on the default IndexController.



require_once realpath(dirname(__FILE__) . '/../../ControllerTestCase.php');

class IndexControllerTest extends ControllerTestCase
{
    public function testCallingRootTriggersIndex()
    {
        $this->dispatch('/');
        $this->assertController('index');
        $this->assertAction('index');
    }
  
    public function testCallingBogusTriggersError()
    {
        $this->dispatch('/bogus');
        $this->assertController('error');
        $this->assertAction('error');
        $this->assertResponseCode(404);
    }
}



Running phpunit from commandline will tell you that your assertions succeeded and all is a go.



All green, assertions succeeded and report is generated.

I've setup my test environment that directory log/report is aliased by /report, so I can view the code coverage reports (requires XDebug).
The following code coverage report is the result.


As you can see, with just a minimal effort you've set up your Zend Framework application to be unit tested. So now you don't have any more excuses to leave your applications untested.

Since I don't have all the knowledge, I would like to thank Matthew Weier O' Phinney and Mathias Geat for sharing their knowledge on the subject. Thanks guys !

Sunday, October 25, 2009

ZendCon 2009 Review

If you're involved with PHP and you haven't heard of ZendCon before, you have been around the wrong croud!

The past week was reserved for the biggest PHP event of the year bringing you the best of the best the open-source and commercial world have to offer developers and businesses. And it rocked, big time!

With a full day of tutorials and three days of top-notch presentations given by people that make things happen in the PHP ecosystem, you got a real bargain for your money.

Besides these brain overloading sessions, Keith Casey, king of the uncon sessions, hand-picked the best sessions rated and presented by the audience itself. And even though the main conference was mindblowing, Keith made sure that people had a hard time choosing between main tracks and uncon sessions. Job well done Keith !!!

I was scheduled for three uncon sessions myself.

On Monday I talked about unit testing with PHPUnit and Zend Framework.

On Tuesday Anna Filina, Bradley Holt and I talked about the role of PHP user groups and provided tips on (re)starting a user group, how to get involved with open-sourse projects and how to get sponsorships from local businesses and big enterprises. I made a recording of the session, but sound quality is poor, so I need more work on it to improve it. Stay tuned for more.

On the third day I was scheduled for my "SPL, not a bridge too far" session but I (and others) were a bit too late for such an early schedule due to the fact that Microsoft was giving an awesome party downtown San Francisco to celebrate the release of Windows 7.
Because we parked our rental car in a car park that closed around midnight, we were happy we could join other conference attendees and speakers on a party bus bringing us back to the hotel where we arrived at about 4am.

Conversations on community stuff with Keith Casey and Anna Filina kept us out of bed until way passed 5am leading up to the fact that I arrived late at my own session scheduled for 8am.
Luckily no one was there to miss me, but still… ariving late at your own gig is so 80's.

For those that couldn't make it to San Jose, you could follow along on IRC channel #zendcon, Twitter and Flickr. Even some Google Waves and Youtube movies were spotted here and there.

A few good things were braught to the attention of all attendees.
  • people and businesses should get more involved in contributing back to the open source projects they use themselves
  • there is no best framework out there so look for the one that best fit your needs
  • there's a lot of talent out there that's not supported enough by the company they work for to become educated on advanced topics or even get certified
  • beware of the weierophinney !!!

Conclusion

ZendCon proved to be the top-notch PHP conference of this year, seeing lots of old and new friends giving the best of themselves. Like the German PHPcc who gave an awesome amount of tutorial, main and uncon sessions, my dear friend and genius Matthew Weier O' Phinney who was more on stage then amongst the audience and of course Keith Casey, who ruled the uncon sessions in a magnificent way.
But to be honnest, ZendCon would not exist without the community that gave us PHP, Zend along with S&S for organizing this event and the sponors that pushed the ticket prizes down to an affordable level. Thank you all and see you next year at ZendCon10.

Saturday, October 10, 2009

Spl Not A Bridge Too Far phpNW09

This morning I had the honor to speak at the PHP North West (phpNW09) conference in Manchester (UK) about SPL. It was almost a full room and it was wonderful to see and hear people being impressed what SPL can mean for them, so I believe it was a good session.

For those who attended my talk, you can leave your comments and feedback at http://joind.in/613 and be sure to rate the conference itself at http://joind.in/event/view/70.

Thursday, September 24, 2009

Bughuntday: yes, you can!


Last week Thursday the start was given to Zend Framework's Bughuntday and it turned out to be a huge success, as mentioned by Chief Architect Matthew Weier O' Phinney on Zend's DevZone website.

Over a hunderd bugs were squashed leading up to the release of Zend Framework 1.9.3.

What is Bughuntday ?
Bughuntday is actually a term to indicate that on a specific day (or days), lots of developers are focussing their attention to fix bugs, often reported by users in a bug tracking tool (like Jira, Mantis or Bugzilla).

Since lots of users have submitted issues and only a few developers have time to investigate them, extra help is always welcome to clear a backlog of reported issues.

So, each year a "Bughuntday" is scheduled to have many developers fix issues in a relative short timeframe.

You can help !
Fixing bugs for Zend Framework is a very good way to learn best coding practices or parts of the framework you're not familiar with.

Go over to the Zend Framework Issue Tracker and look for bugs that are still open.

If you already signed the Zend CLA, you're good to go. If you haven't done this, now is a good time to do so.

Get the latest revision from http://framework.zend.com/svn/framework/standard/trunk/, which includes the library, unit tests, external libraries and documentation.

In case of emergency
If you're stuck, or you have created a patch to fix an issue, head over to #zftalk.dev on IRC (freenode) where you can ask for help.

The Zend Framework Bughuntday is held each third Thursday and Friday of the month and each month prizes are given to the top 3 fixers.

If your company uses Zend Framework, see if you cannot make it a company thing. The quality improvement of Zend Framework will be a great benefit for your company as well.