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:

Why Apple Needs to Reinvent the TV

Personally I can’t wait for Apple to come in and reinvent the television. I envisage they’ll raise the bar like they did with the iPhone and make the market several times more competitive.

Televisions were invented in the late 1920s and colour came in 1940s. Since then we’ve been subject to a business model pioneered by the television networks. They serve us content, they serve us advertising and we have the ability to pay for premium subscription services (such as Foxtel or Cable) and connect peripheral devices.

At the moment the price point for TV’s is amazing. You can purchase a 40-inch Full-HD LED LCD for around $600 (AUD). Compare that to 4 years ago when I paid over $5000 (AUD) for 43-inch Semi-HD Plasma screen. Both the industrial design and the hardware is great, but this is not the issue. The issue with TVs is the experience.

The experience with TV’s is appalling. Every user interface varies between brand and model. There is no consistency in terms of design and frankly it’s pathetic. Let’s talk about a common task such as changing the channel. You pick up a remote and try to hit the impossible bulls-eye. Occasionally you do and then the television takes it’s merry time trying to fulfill your request.

With the UI aside have you forgotten about the plethora of boxes sitting within your cabinet? Let’s go back to 1993 when TV’s only supported one external device; now we have boxes for just about everything - cable networks, gaming consoles, network media devices, premium subscription services, convertors, boxes to connect more boxes and DVD & Blu-Ray players. It’s ridiculous!

The Apple TV was important for Apple, because it was their entry into the market. Steve Jobs always claimed it was a ‘hobby’ and they ‘weren’t very serious about it’, but it was a lot more than that. The Apple TV was a market tester. Are consumer’s prepared to pay for content? Do people actually listen to music on their TV’s? Or how about viewing photos? Finally how long do people spend watching TV? The latter question is very relevant. I think we all know the answer and the potential market size.

Now for the big unknowns. Has Apple thought extremely big? Does what their trying to do require commitment from networks all around the world? It’s quite possible. For example a feature such as trying to replay a TV program straight after it’s broadcast would require permission from the copyright holder.

Will the Apple Television disrupt the model where content is restricted by markets? At the moment networks purchase programs from content providers after they’ve had widespread success in their local markets. But lets not forget the internet exists today and consumers aren’t prepared to wait 12 months to see what the trending topics on Twitter are all about. They want it now and technologies such as BitTorrent enable this. Could we see a global change to this model across the spectrum? One day they might even go as far as allowing you to determine your own programming. Talk about a total change. All of a sudden you will be dictating your own programming instead of the networks. Going out for dinner later tonight? Then watch the news now instead of at 7:00pm. Video on demand already exists, but not in this capacity.

Last but not least I’m sure there is another billion dollar App market just waiting to be untapped in the living room. The problem Apple has here though is people aren’t going to get off the couch to touch their TV screens, they’ll have to use an iPad or a new category of device (remote on steroids). TheVerge ( claims people will use their voice which makes sense given the successful launch of Siri. I would love to check the weather, watch those videos I’d saved for later, play a few games or catchup on the news. There is definitely room for an App market here.

For Apple, reinventing the television makes sense. It extends their walled garden into your living room. They already control your phone, tablet and computer and now they want the 10-foot experience. I hope they have solved all of the problems including creating a universal product that works around the world. I look forward to a product debut in 2012.