I'm speaking at ZenCon 2009!

1st July 2009

I'm speaking at ZendCon 2009 this year!

I'm doing a tutorial session called Zend Framework Certification Bootcamp where I'll be highlighting key sections of Zend Framework that you'll need to know in order to pass the the ZFCE exam.

I'm also presenting a standard session, Getting a website out of the door (aka Managing a website project) which will be a non-code talk about the realities of project management in a small web development company where the PM overhead has to be minimal, but effective.

ZendCon last year was a great conference and this year's is shaping up to be equally as good, if not better. I recommend that you persuade your employer to send you. It'll be money well spent - especially if you register before 28th August and get the discount.

Some notes on Zend Server CE for Mac OS X

22nd June 2009

I've installed Zend Server CE on my Mac to see where it's got to and it's looking quite usable. The installation puts everything into the usr/local/zend directory which is fairly well laid out so that you can find what you are looking for. There's also a a nice admin system at http://localhost:10081 which allows you to restart PHP, view phpinfo(), configure extensions and php.ini. There's also a phpMyAdmin to help administer the bundled MySQL server.

For Mac, this is now one of the better one stop shops for easy PHP & MySQL installation.

Obviously, some things need configuration:

Set up paths

You need access to the command line zendctl.sh and mysql tools:

  • Edit ~/.bash_profile and add:
        PATH=$PATH:/usr/local/zend/bin:/usr/local/zend/mysql/bin
        LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/zend/lib
    
  • Close Terminal and restart it so that your change takes effect.

Change to port 80

The Apache in Zend Server is configured for 10088 to avoid conflicting with Apple's Web Sharing I suppose. The choice of using port 80 would have been nice as an installation option though.

To use port 80 is easy enough:

  • Stop Apache: sudo zendctl.sh stop-apache
  • Edit /usr/local/zend/apache2/conf/httpd.conf and replace Listen 10088 with Listen 80
  • Edit /usr/local/zend/apache2/bin/apachectl and change STATUSURL="http://localhost:10088/server-status" to STATUSURL="http://localhost:80/server-status"
  • If you are using vhosts, then edit /usr/local/zend/apaches/conf/httpd.conf and replace all instances 10088 with 80
  • Restart Apache:sudo zendctl.sh start-apache

Installing PHPUnit

Update PEAR first:

    sudo pear channel-update pear.php.net
    sudo pear upgrade-all

Install PHPUnit:

    sudo pear channel-discover pear.phpunit.de
    sudo pear install phpunit/PHPUnit

Installing Xdebug

  • Install Xcode so you have a compiler!
  • Stop Apache: sudo zendctl.sh stop-apache
  • Go to http://localhost:10081/ and pick the Server Setup tab. Turn off the Zend Debugger and Zend Data Cache and restart PHP
  • sudo pecl install xdebug
  • Edit /usr/local/zend/etc/php.ini and add above the [zend] section near the bottom:
    zend_extension="/usr/local/zend/lib/php_extensions/xdebug.so" 
    
    [xdebug]
    xdebug.remote_enable=1
    xdebug.remote_host="localhost"
    xdebug.remote_port=9000
    xdebug.show_local_vars=On
    xdebug.var_display_max_data=10000
    xdebug.var_display_max_depth=20
    

    (you should set up your xdebug settings as you require!)

  • Restart Apache:sudo zendctl.sh start-apache
  • The Server Setup->Extensions section of the admin interface should now show xdebug.

All in all, it's remarkably easy to set up Zend Server using PEAR and PECL is which how it should be.

The only other gotcha I noticed is that my.cnf is in /usr/local/zend/mysql/data whereas I would have thought that /usr/local/zend/etc would have been more logical.

DPC '09

15th June 2009

The Dutch PHP Conference is over and so it's time to write a short wrap-up.

Day 1

The conference was opened by a cool animated video and then Cal Evans welcomed us, with a nice short speech. The keynote was given by Andrei Zmievski of Digg. Andrei is a core devloper and gave an interesting overview of what we can expect to see next in PHP.

Cal opens DPC 09

I then listened to Paul Reinheimer talk about some problems you can encounter in conceptually easy situations. I found the section about handling account login issues very interesting and it's an area that I now intend to improve in my code. Ben Ramsey followed with a talk on the theory of REST architectures which was interesting, though not directly relevant to anything that we're doing at the moment. Making sure that I understand it when we come to make web service APIs is important though.

After lunch Matthew Weier O'Phinney talked about contributing to open source projects. Matthew gave a great talk with useful information in it. As a contributor to Zend Framework already, I mainly used this talk to learn how to evangelise the concept of contributing to other people.

I stepped out of the next session into the hallway track where I caught up with some people and then checked my email. Then Jan Lehnardt was on to talk about CouchDB. CouchDB fascinates me as it's so different from the relational databases I'm used to. I don't see that we'll be using it soon though - the paradigm shift is significant.

The day ended with the speakers dinner followed by drinking :)

Day 2

Day 2 dawned bright and far too early and I managed to leave my power adapter at the hotel, so I had to go back for it, missing the opening keynote. I got back to see most of Eli White's talk on scaling. Eli is a good speaker and the talk was well researched. I know that if I ever need to scale a website to 20 database servers and too many web servers, then I'm going to try and head hunt him...

I was intending to see Juliette Reinders Folmer's talk on UTF-8, but Paul suffered from a video adapter failure and so I lent him my laptop and stayed to watch and make sure he didn't break it. Paul gave another interesting talk whilst looking good in his suit.

After lunch, it was my turn to talk. Although I was nervous at the beginning, I think that I got into my stride and the presentation went well with intelligent questions asked by the audience. I think it helped that I advised the people who knew more than I did to leave before we started :) If you were there and haven't yet rated it, then please leave feedback!

The final breakout session that I attended was another by Ben Ramsey about HTTP. There was more here that was directly relevant to work, but I'd have preferred more on the codes side with less emphasis on the methods.

The session was closed with a conversation between Cal Evans, Ivo Jansch, Andrei Zmievski, Lorna Mitchell and Paul Reinheimer. This took the form of an interview by Cal and Ivo with their guests. It worked quite well, but I felt that the questions for Andrei and Paul were not as well structured as the ones for Lorna. There was a slide show running above their heads with Twitter and Flickr photos from the conference playing. This was very funny :)

In the evening, I went for a meal at a Pancake house that was very enjoyable and I got to see a little bit of Central Amsterdam!

Conclusion

Overall, The 2009 version of the Dutch PHP Conference was very successful. It's clear that it is being positioned to become a major conference, not just for Europe, but for the world with a significant focus on the advanced developer.

I will certainly be submitting to talk in 2010 - assuming I can think up some advanced topics to talk about!

Cheers!

WinPHP wrap-up thoughts

1st June 2009

This post is part of a series about my experiences building a PHP app for Windows Server 2008 and IIS 7 for the European WinPHP Challenge 2009 which is sponsored by iBuildings, Microsoft and Leaseweb.

The WinPHP challenge come come to an end and I'm fairly happy with how SuccesSQL has come. I wish I had realised exactly how little time I had in May though. Somehow I managed to forget that we had three family birthdays, a Christening and a weekend holiday to fit in during the month...

I already knew that PHP worked great on Windows and SuccesSQL again proves that PHP is truly cross-platform. The areas that I wanted to explore and learn a little about were running PHP on IIS and using the SqlSrv database connector.

I learnt a lot about setting up PHP in Windows. It's amazing how much easier it was the second time when I installed it on the Leaseweb server. The Web Platform Installer is very good as long as you remember to stop the IIS service before running it! It's also very odd that the installer doesn't install PEAR or PDO_ODBC. I'm very glad that it uses the exact same installer as available at windows.php.net, as it makes correcting these oversights trivial.

Fortunately, Juozas Kaziukenas also wanted to connect to SQL Server, so we collaborated on a Zend Framework Database adapter for SqlSrv on codepex at http://zfmssql.codeplex.com/. Please download and exercise that too as all bug reports (and patches) will be gratefully received!

Like Juokaz, I also really enjoyed the community aspect of this competition too. Twitter was alive with #winphp tweets and it felt as co-operative rather than competitive as we helped each other overcome obstacles.

SuccesSQL demo online

31st May 2009

This post is part of a series about my experiences building a PHP app for Windows Server 2008 and IIS 7 for the European WinPHP Challenge 2009 which is sponsored by iBuildings, Microsoft and Leaseweb.

The WinPHP challenge comes to an end around now, so I've put up a demo installation of SuccesSQL (v0.01!) at http://test.successql.org. The test site takes a lot longer to display the first page than version running in my VM and I have no idea why!

The source code is released under the New BSD license and is available from my subversion repository.

I expect that this code isn't as secure as it should be and isn't especially well tested either. As such, I highly recommend that you don't use it on important databases or on a public facing web server!

Obligatory screen shot:

test.successful.org.01.jpg

I've still got lots to do though, but there's enough done that I'm using it for work related stuff when I need to look something up, but can't be bothered to wait for the SQL Server Management tool to get around to starting up. In that sense, it's already a success!

Metadata from Zend_Db_Table_Abstract

28th May 2009

This post is part of a series about my experiences building a PHP app for Windows Server 2008 and IIS 7 for the European WinPHP Challenge 2009 which is sponsored by iBuildings, Microsoft and Leaseweb.

I finally found some more time to work on SuccesSQL and can now display table structure information:

successql_structure-1.jpg

Zend_Db_Table provides all this information directly which is quite useful, however the intended use-case for Zend_Db_Table is that you extend Zend_Db_Table_Abstract for each table that you want to interact with. Obviously, SuccesSQL doesn't know in advance the names of the tables, so I created a stub class that allowed me to instantiate a Zend_Db_Table dynamically:


class SSQL_Db_Table extends Zend_Db_Table_Abstract
{
}

Then, for any given table, I can instantiate like this:


$table = new SSQL_Db_Table(array('name'=>$tableName));

The metadata about the table is stored in a protected member variable called _metadata. As this is protected, it's not accessible, outside of the class, so I created an accessor method to allow me to get at the data:


class SSQL_Db_Table extends Zend_Db_Table_Abstract
{

    public function getMetadata()
    {
        if (empty($this->_metadata)) {
            $this->_setupMetadata();
        }
        return $this->_metadata;
    }

}

Interestingly, Zend_Db_Table_Abstract lazily loads the _metadata variable and so I had to check if it had been loaded and if not, set it up. The data returned is an multi-dimensional array, with one sub-array per field. A dump looks like this:


array
  'id' => 
    array
      'SCHEMA_NAME' => null
      'TABLE_NAME' => string 'albums' (length=6)
      'COLUMN_NAME' => string 'id' (length=2)
      'COLUMN_POSITION' => int 1
      'DATA_TYPE' => string 'int' (length=3)
      'DEFAULT' => null
      'NULLABLE' => boolean false
      'LENGTH' => int 4
      'SCALE' => int 0
      'PRECISION' => int 10
      'UNSIGNED' => null
      'PRIMARY' => boolean true
      'PRIMARY_POSITION' => int 1
      'IDENTITY' => boolean true
  'artist' => 
    array
      'SCHEMA_NAME' => null
      [etc]

From then on, it's just a case of display formatting.

Retrieving a list of databases from SQL Server

19th May 2009

This post is part of a series about my experiences building a PHP app for Windows Server 2008 and IIS 7 for the European WinPHP Challenge 2009 which is sponsored by iBuildings, Microsoft and Leaseweb.

I need to get a list of databases from SQL Server for the currently logged in user. Initially, I found a built in function sp_databases. This looked promising, until I discovered that it didn't work for my user. I'm pretty sure that it's related to permissions. The user just has db_owner on a specific database and nothing else. (Mainly as I don't know how to set anything else!)

A bit of googling provided enabled me to develop this SQL statement:


SELECT namecollation_name
FROM sys.databases
WHERE name NOT IN ('master''tempdb''model''msdb');

This works, but gives me a list of all (non-system) databases, but doesn't tell me which ones I have permission to actually access.

I'm sure there's a better way, but I discovered that if I try to use a database, then I get an error message back, so a simple foreach loop solved my problem:


$validDatabases = array();
foreach($databases as $name) {
    $sql "USE [$name]";
    try {
        $this->_db->query($sql);
    } catch (Exception $e) {
        // failed to access the database - ignore it
        continue;
    }
    $validDatabases[] = $name;
}

Now... this is inelegant. Surely there's a better way?!

On the plus side, it works ;)

SQL Server troubles

16th May 2009

This post is part of a series about my experiences building a PHP app for Windows Server 2008 and IIS 7 for the European WinPHP Challenge 2009 which is sponsored by iBuildings, Microsoft and Leaseweb.

I'm now at the stage where I'm writing code and came across an error:

Message: 2 [Microsoft][SQL Native Client]
    Named Pipes Provider: Could not open a connection to SQL Server [2]. 

That seemed a little odd, so I fired up the Microsoft SQL Server Management Studio and logged in with the credentials that I'm using in the web app. It let me log in, so I went to click on the Databases item in the Object Explorer and got this message:

sqlmgnt_error.jpg

Any ideas? All I've found when googling is suggestions to reinstall...

Zend Framework URL Rewriting in IIS7

11th May 2009

This post is part of a series about my experiences building a PHP app for Windows Server 2008 and IIS 7 for the European WinPHP Challenge 2009 which is sponsored by iBuildings, Microsoft and Leaseweb.

To get my Zend Framework Tutorial working with my IIS7 & MS SQL server set up, I needed two things:

  1. A Sqlsrv adapter for Zend Framework.
  2. A replacement Apache's mod_rewrite module.

I've already covered the Sqlsrv adapter, so let's look at rewriting requests with IIS7's URL Rewrite module. As with everything in IIS, you get at this tool via the IIS Manager GUI. Be aware though that the Url Rewrite icon is available at server level and at the website level.

You need the website level which is accessed under the "Sites" section which is under the "Server name" section. In my case it is called "Default Web Site". You now click on "Import Rules" on the right hand action list and get this screen:
IISManager-import-rewrite-rules.jpg

Simply paste in these rules:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^.*$ /zf-tutorial/public/index.php [NC,L]

and press "Apply"

Note that this rules doesn't match the official ZF rules, but it performs essentially the same functionality and generates a much clearer rule within the IIS URL Rewrite manager.

Also, you need to put the full path to the index.php file for it to work. It's much easier to create a new website within the IIS manager and point it at the public directory.

My Zend Framework tutorial website is now working though, so it's full steam ahead on the actual application.

Zend Framework connection to SQL Server using SqlSrv

10th May 2009

This post is part of a series about my experiences building a PHP app for Windows Server 2008 and IIS 7 for the European WinPHP Challenge 2009 which is sponsored by iBuildings, Microsoft and Leaseweb.

I haven't managed to get much time on the challenge this week as I had hoped. Both my sons' birthday parties have taken place along with one son's birthday (the other's is tomorrow).

It turns out that fellow challenger Juozas Kaziukenas also needs a connection between Zend Framework and SQL Server, so we have joined forces to create App_Db_Adapter_SqlSrv and associated classes. Juozas started a project on codeplex at http://zfmssql.codeplex.com/ and has enabled me to commit to the project too.

Juozas committed an initial implementation and so far I've updated the _connect() method to allow for all the parameters supported by sqlserv_connect().

My current application.ini looks like this:

resources.db.adapter = SQLSRV
resources.db.params.adapterNamespace = "App_Db_Adapter"
resources.db.params.host = "RKAWIN2008\SQLEXPRESS"
resources.db.params.username = "rob"
resources.db.params.password = "123456"
resources.db.params.dbname = zf-tutorial
resources.db.params.driver_options.ConnectionPooling = 1
resources.db.params.driver_options.Encrypt = 0
resources.db.params.driver_options.TransactionIsolation = SQLSRV_TXN_READ_COMMITTED

The adapter correctly converts the SQLSRV_TXN_READ_COMMITTED string from the ini file into the constant value required by the sqlsrv_connect() function using the very useful constant() function.

I had a slight hiccup with detection of the table's primary key. Microsoft's documentation is quit clear once you have found what you are looking for, so that was easily fixed.

At this point the adapter is working for my ZF tutorial, though more work needs to be done on it.