CakePHP 3.0.0 + Phinx

I’ve always followed CakePHP development pretty closely. In fact, before I became a contributor to Zend Framework v1.x I wrote the bulk of my web applications using Cake. It was one of the earliest PHP MVC frameworks that followed the popular design patterns exploding in other languages.

That’s why I was very excited to learn that CakePHP 3.0.0 has chosen to use Phinx for it’s database migrations. They developed a plugin to integrate the two projects here:

You can read more on the CakePHP blog:

I’m pleased to welcome the CakePHP community to Phinx!




I had pleasure of visiting Norway for 4 days at the beginning of this month. It’s a very clean and structured country and very Scandinavian - much like Stockholm. Straight after landing we were caught a train to Oslo then waited at the station to catch a bigger train to Bergen (1758 NOK for 2 people).


It’s a 7-hour journey, however the train has free WiFI and a restaurant car (with a fairly limited menu, but they do have beer). I’d highly recommend the train ride. You get excellent views of the country-side and the best part was we hit snow towards the end.



After 7 hours we finally arrived in Bergen. Whilst Bergen was small and intimate I’d say probably 2-3 days is enough to see this city. We only stayed for one night and managed to squeeze quite a lot in. Undoubtedly the best thing to do is to visit Fløyen. A spot up the mountain roughly 320m above sea level. From here you get the best view of Bergen city (170 NOK for two people).


After having a few meals in Bergen and checking out the fairly limited nightlife it was time to leave. We caught a bus to the airport. It is roughly 30 minutes and SAS Airlines have a convenient shuttle. From memory you pay about 180 NOK for two people. A quick 50 minute flight (with WiFi!) and we had arrived in Oslo again.

It had been a long time since my friend and I had eaten dumplings so we found a good restaurant on Trip Advisor which I can now highly recommend - (560 NOK for 2 people inc wine) Then we went out for drinks at some place I forgot ;(, but you can mingle with the locals and they have a heated beer garden!

For breakfast the next day we went to an American diner ( in the hip suburb of Grünerløkka - which reminded me a lot like Surry Hills in Sydney. The best part is they serve an all day breakfast which is a must after a late night out. Afterwards we were able to wander around and check out the local markets that happen on Saturday.

The best place we found for beers and a snack on Saturday afternoon was the Lektern Water Bar. It’s a nice open-air restaurant apparently only open in the summer. The Akershus fortress looms in the background.


For dinner on Saturday night we ate steak at a steak house. I’m a big steak connoisseur and this one was pretty average. I won’t recommend the restaurant. However the cocktails afterwards at Sudøst definitely made up for it. If you go here make sure you get the bartender named Tommy. For once I wasn’t drinking sugared water shaken by a student and actually got something decent.

That was it for Oslo apart from a quick walk around the opera house. It opened in 2008 and is definitely a feat of modern architecture. Time to head back to the airport. Buying a train ticket here is the most convient thing I’ve ever done. You simply swipe your credit card and the gates open. Again the same thing is required at the other end. Your credit card becomes your ticket. It was a beautiful day for flying and I managed to snap some pics of the Norwegian country side.


Introducing Phinx 0.3.0

TLDR: This is a big release.

Today I’m excited to announce Phinx 0.3.0. This release has been in the making for quite a few months. Last October Phinx broke 10,000 downloads and just four months later will see Phinx topping 30,000. This has been incredible momentum for the project.

The 0.3.0 release also includes an overhauled website at: and documentation at For beginners I’m also planning to release a screencast that covers the most popular features of Phinx. Stay tuned!

Phinx now supports MySQL, Postgres & SQLite out of the box. I’m interested to bring better support to Windows and obviously support Microsoft SQL Server. This cannot happen without financial support including a Windows server with MSSQL to test the builds. If anyone knows or has a contact at Microsoft or if a partner is willing to sponsor this then get in touch with me directly.

On the roadmap for Phinx in the future is better test coverage, documentation and database support. We want to integrate with Doctrine and add DBAL support.

Last but not least I’m finding less and less time to develop Phinx these days. It’s hard to juggle two startups, private life and a project growing at this pace. I’m looking to create a “core team” with GitHub commit rights to shape the future of this project. If you’ve been contributing regularly and are interested then please get in touch with me.

Thank you for supporting and using Phinx!



Getting a Residence Permit to Work in Germany

So you want to come and work in Germany? In particular the thriving startup scene in Berlin? A lot of people ask me about the process so I decided to write my notes here. In short - the process is not difficult if you follow the steps correctly and have secured a job offer. This is the money shot. There are other options like the Freelancer / Artist Visa (very popular in Berlin), but I do not know much about this. Apparently they are a lot easier though and give you the freedom to work for anyone. Disclaimer: I’m not a legal expert so proceed at your own risk.

The first step is to book your plane ticket and make your way to Europe. As a citizen from Australia, Canada, Israel, Japan, New Zealand, Korea or the USA you are able to enter Germany start the process of applying for a residence permit. This is very beneficial if you want to meet with companies before you choose a job. You don’t have to apply for everything remotely, but having a job of course will really help your situation.

After arriving in Germany this is the basic process:

1. Find a place to live and receive a rental contract (popular sites include, & for shared accommodation)
2. Take your Rental Contract and your passport to your local Bürgeramt and register yourself. It is compulsory to always be registered whilst living in Germany. This applies to Germans too. They will issue you with an Anmeldebescheinigung (registration card). You will need this for all sorts of things - your visa, mobile phone & insurance contracts.
3. Find a job and obtain a German Working Contract. Your employer will need to complete several forms in order to prove they have looked for Germans to fulfil the same job or you are qualified/super special to take the position. The forms include: “Antrag auf Erlaubnis einer Beschäftigung” (Request permission for your employment from the authorities) and an “Stellenbeschreibung” (Job Description about the role, not about you personally). Contrary to many other country requirements for foreign visas, you do not need a University Degree for a German Residence Permit. This is a big difference to the USA. However, you should be qualified enough to perform your specific line of work. E.g: You won’t be able to practise as a heart surgeon with only a high-school education.
4. You should then select an insurance provider (more on that below).
5. Visit the Finanzamt with your Anmeldebescheinigung & Passport. They will issue you with a tax identification number which you need to provide to your employer.
6. Final step: visit the Ausländerbehörde (Office for Aliens) with all of the documents from above (plus your passport, 2 x passport photos and any documentation including qualifications to support your visa) to apply for your Residence Permit. This is the hardest step and most likely the one where you can encounter problems.

I’ll explain some of the steps now in more detail:

Choosing a place to live can be very difficult depending on the suburb and number of people looking. I’ve noticed it’s very affected by seasonal changes as well. e.g. University breaks and Summer. It was definitely crazy when I was first looking in July compared with January and the winter months. There are both unfurnished and furnished places. Generally you’ll pay a tiny bit more for furnished places, but obviously you can save a few thousand in furniture costs upfront. I’d do this step first so you can register yourself, relax and start on the more important steps. Once you’ve found a place be sure to stick your name on the letter boxes and master door so you receive all the important mail from the authorities.

My advice for anything ending with ‘amt’ would be to take a friend who can speak German. It makes the whole process much easier and less stressful. On the other hand if you learn things by trial & error and want to do it the hard way then try to do it all yourself. I did the latter and often created a lot of confusion, not to mention looking like an idiot and annoying the authorities (probably not the smartest option).

When it comes to insurance in Germany be prepared for a massive reality check. In Australia I paid somewhere around $40/month for private health insurance. In Germany I pay over 15x times that amount (your employer will pay half, but obviously it will still cost you more). I’ve been told they changed the laws a few years ago and its now compulsory to have health insurance. The steep premiums are to protect the insurance companies in case you lose your job (they still have to insure you regardless of your income situation) and also to support the large percentage of unemployed people who can no longer afford to pay their premiums. To obtain a Residence Permit you must choose between either Private or Public Health Insurance from a German provider. Travel and Expat insurance is not acceptable. I’ve been told the latter can be used in the Freelancer arrangement. Public health insurance is based on what you earn. If you earn less than 50k a year it probably makes sense financially. If you earn over 50k a year then you also have the option to use private health insurance. Private health insurance generally provides a better service, but it is based on your healthiness and well-being. My advice would be the “less you say, the less you’ll pay”.

Insurance info is all in German so most expats use an Insurance Broker. They help you to choose between a number of different options. Be aware that they earn a commission based on the plan you sign up for so be careful of adding on extra options or you’ll pay a fortune. If you want a great English speaking insurance broker then I can highly recommend John Gunn ( . He is based in Hamburg, but is able to sort you out over the phone & internet. He was the best by far out of the 3-4 I worked with.

By this stage you probably should of opened a German Bank Account. There are a couple of “online-only” banks where you’ll save a lot in fees, but they rejected my application for reasons unknown (probably due to having just arrived and having zero credit history). In the end I went to one of the big names in person and had no trouble opening account (the bloke spoke good English). The same problem applies to credit cards and post-paid mobile phone plans. Most banks won’t issue cards without at least 3 years positive history. This makes it extremely hard to purchase online. Fortunately Germany has a great solution called “Sofort überweisung” which is like direct debit on steroids. Many merchants accept this or standard direct debit and ship goods immediately. I’d also recommend you open a PayPal account for the rest and link it to your German Bank Account.

Finally you need to visit the Ausländerbehörde with all of the documentation you have amassed. Before you go be sure to fill out a “Antrag auf Erteilung eines Aufenthaltstitels” (Residence Permit Application), take your passport and also 2 x passport photos. That will save you a lot time when your there. Google for it - it’s available online. I went to the Ausländerbehörde in Berlin. It’s not the nicest place and it is definitely very bureaucratic there. If you want to take a German-speaking friend to any authority, then this is the one I’d recommend. They will issue your permit on the spot or they may want to run a few more background checks including verifying the position with the Labor Authority, so be prepared to wait several more weeks before you get an answer. Legally you are not allowed to work until you receive your residence permit.

They say the Ausländerbehörde in Berlin only takes appointments (with often a month long wait). This is true, however I decided just to turn up and try my luck around 12pm as my 3 month stay was running out. My residence permit was issued for the duration of my contract (12 months). Unlike Australia, working contracts are not normally “unlimited” here and generally renew on an annual basis. In the middle of this year I will have to take my renewed working contract back to the Ausländerbehörde and ask for my residence permit to be renewed.

I did a lot of research online about each of the required steps. Theres some great stuff on toytowngermany, but I hope you find the above information useful. If you have any questions then just leave a comment or send me a message.



Phinx 0.2.3 is out with reversible migrations and much more

I am really excited to announce Phinx 0.2.3. Phinx has come a long way since it started as a tiny open-source tool I used on a few projects. It has received a stack of contributions and is used by thousands of people from all around the world.

Phinx now includes some great features including reversible migrations, a verbosity parameter, support for foreign keys and PHP configuration files. I want to talk briefly about the first two today.

Reversible Migrations

When using reversible migrations you only need to define the ‘up logic’ and Phinx is smart enough to figure out how to migrate down automatically for you. This feature was inspired by the work tenderlove introduced into Rails 3.1.

To define a reversible migration you simply add a change method to your migration file and insert the database transformations you require. If Phinx detects the change method it will automatically handle the migration both up and down for you.

Note: Not all commands can be reversed. Phinx will throw an exception if you try to use an irreversible command.

Let me demonstrate reversible migrations in an example project. First we create a new migration:

$ php vendor/bin/phinx create ExampleMigration
Phinx by Rob Morgan. version 0.2.3

using config file ./phinx.yml
using config parser yaml
using migration path /Users/robbym/Sites/webapp/scripts/migrations
created ./scripts/migrations/20130406160342_example_migration.php

And open it using our text editor. Next I’ll uncomment the change method and add some code to create a simple blog posts table. Here’s the source code for the file:

Now when combined with the new verbose parameter you can see detailed insight into exactly how long various commands take to execute. This is very handy to benchmark various operations. Let’s run the migration we created using the verbose parameter:

$ php vendor/bin/phinx migrate -e testing -v
Phinx by Rob Morgan. version 0.2.3

using config file ./phinx.yml
using config parser yaml
using migration path /Users/robbym/Sites/webapp/scripts/migrations
using environment testing
using adapter mysql
using database webapp

 == 20130406160342 ExampleMigration: migrating
 -- createTable('posts')
    -> 0.0863s
 == 20130406160342 ExampleMigration: migrated 0.0918s

All Done. Took 0.1215s

And now to showcase the power of reversible migrations we can simply roll it back:

$ php vendor/bin/phinx rollback -e testing -v
Phinx by Rob Morgan. version 0.2.3

using config file ./phinx.yml
using config parser yaml
using migration path /Users/robbym/Sites/webapp/scripts/migrations
using environment testing

 == 20130406160342 ExampleMigration: reverting
 == 20130406160342 ExampleMigration: reverted 0.0059s

There we have it. Phinx was smart enough to reverse the createTable command and drop it when migrating down. Reversible migrations save you both code and time.

Both these features bring Phinx in-line with other migration tools and platforms. More information on reversible migrations is available on the official Phinx documentation. Thanks for using my project. If your interested in contributing the GitHub project is here:

Getting Started With Phinx


Update (21st October, 2012): As Phinx 0.1.4 has now shipped, I have updated this tutorial to work with Composer instead of PEAR.

Earlier this year I decided to open-source one of my personal software projects - Phinx. Phinx is a database migration tool (think Ruby on Rails ActiveRecord migrations) where can you describe all of your database transformations in pure PHP. I have used this tool for many of my consulting projects, however it still took a lot of effort to turn it into a re-usable product. In this tutorial I’m going to explain how to install Phinx and use it with a simple guestbook application.


This tutorial assumes you have working knowledge of PHP, the Composer dependency manager, Zend Framework 1.x and the MySQL database. You should have a copy of Zend Framework 1.x available in your PHP include path. I have coded the sample application against ZF 1.11.11. It is also assumed you are able to configure your webserver to run the sample application. I have used Mac OS X to develop this tutorial.

Setup the Sample Application

I have a sample Guestbook application available on GitHub. Start by cloning the application:

$ git clone

Next setup your webserver to run the sample application.

Configure your Database

Create an empty database called guestbook and open the Guestbook configuration file (application/configs/application.ini). Change the database settings to match your system. Now we are ready to start using Phinx.


First we need to install Phinx. By far the best way is via Composer as a dependency. Create an empty file called composer.json in the root of the guestbook application. Now open this file and change it to look like the following:

Now run Composer to install Phinx as a dependency:

$ curl -s | php
$ php composer.phar install

Phinx will now be available under the vendor/bin/phinx command.

Making Phinx work with the Sample Application

Phinx uses a configuration file (phinx.yml) in the root of your project to learn about it’s migrations. The configuration file is a simple YAML-based file. More information is available on the official Phinx documentation site:

To Phinx-ify your app, simply run:

$ php vendor/bin/phinx init

Phinx will create a configuration file with a few defaults, open this file in your text editor. A great feature of Phinx is that it supports multiple environments, by default the development environment is enabled. Edit the development environment settings to match your configuration.

Next we need to create a directory to store the migrations. Unless specified otherwise Phinx expects a directory called migrations in your project root directory:

$ mkdir migrations

Now execute the status command to test your database connection.

$ php vendor/bin/phinx status

Phinx will attempt to connect to your default environment database. If a successful connection is made, then Phinx will create an empty table to store the migration history.

Creating Your First Migration

Our sample application is a guestbook. We need to create a table to store the posts. For each post I want to be able to enter a title, message and save the time that it was created. Let’s create a new migration called CreatePostsTable:

$ php vendor/bin/phinx create CreatePostsTable
Phinx by Rob Morgan. version 0.1.4

using config ./phinx.yml
using migration path /Users/robbym/Sites/guestbook/migrations
created ./migrations/20121013151612_create_posts_table.php

Phinx will create an empty migration file in the migrations directory. Open this file in your text editor. In the up method we will use the Table API to create a new database table. Next in the down method we will simply remove this table. By specifying the reverse of our transformations in the down method we are able to use Phinx’s rollback functionality. It is important to note that Phinx creates an id column by default for every table. More information about this column is available in the Phinx documentation. Your migration file should look like this:

Transforming the Database

Now it’s time to execute our newly created database migration. Run Phinx with the migrate command:

$ php vendor/bin/phinx migrate
Phinx by Rob Morgan. version 0.1.4

using config ./phinx.yml
using migration path /Users/robbym/Sites/guestbook/migrations
warning no environment specified, defaulting to: development
using adapter mysql

 == 20121013151612 CreatePostsTable migrating
 == 20121013151612 CreatePostsTable migrated 1.1352s

All Done. Took 1.1485s

Phinx will connect to your database and execute the CreatePostsTable migration. Now you have successfully migrated your database to the latest version. Therefore we can now use the Guestbook application:

And that’s it!


There we have a brief introduction to getting started with Phinx. You can find out more about the project on it’s website here: We are also looking for contributors to close bugs, add features and work on the documentation. If you’d like to help checkout the GitHub project here: