Lesson 1 - Database abstractionLesson 2 - Routing and templatingLesson 2.5 - CleanupLesson 3 - Exceptions and logging
There are a great number of PHP tutorials out there, and a great deal of them are out of date -- often wildly -- and full of outdated or outright bad practices. More recently, we're seeing a number of better tutorials pop up, focusing on modern frameworks and better practices. There does not appear to be much to help you get from A to B, however. What if you have a legacy application in production? Rewriting it isn't always an option, especially for bigger applications. That's the void I'm hoping this tutorial series will help fill. I have written up a demo app incorporating a number of outdated practices commonly seen both in tutorials online and in code snippets posted here. Take a look at the codebase. Look familiar? If you're maintaining apps written like this, or if you're still writing apps like this, let's walk through cleaning up and modernizing this code together. Hopefully this will help you give your existing code a face lift, implement some more modern practices and, ultimately, make it easier to extend and maintain.
The sample app is available on GitHub and can be downloaded from https://github.com/jdhmtl/squeaker/archive/lesson-0.zip
or, preferably, cloned at firstname.lastname@example.org:jdhmtl/squeaker.git. This will be a multi-lesson series, and each lesson will have a corresponding tag in the repository to help you follow along. Ideally, you'll be making these same (or similar) changes yourself.
This being a PHP tutorial, you're obviously going to need PHP and MySQL. As we'll be working with password_hash, you will need either PHP 5.5 or newer, or the password_compat package. We'll be using namespaces and autoloading, so PHP 5.3 is an absolute hard minimum requirement. Additionally, we'll be using Git
, so if you aren't already familiar with those, it might be worth taking a half hour to read up on them. Both are absolutely essential to modern PHP development.
So what's wrong with this app? What will we be covering in this tutorial?
- page-based scripts with no separation of concerns
- includes in every file
- mysql_ functions, with bonus SQL injection vulnerabilities
- die() as an error handling mechanism
- global state
- duplication of code
The aim of this tutorial isn't to finish with a 'perfect' app, but we will address all of the above concerns. We'll move from procedural page scripts to a more OO approach with proper routing. mysql will give way to PDO and possibly an ORM. We will introduce some proper logging mechanisms that will aid us in debugging while showing the user friendly error pages that expose nothing of the inner workings of the app. I will try to explain each change step by step, and will create a new thread for each lesson, to allow for questions and discussion. Let's get started.
The sample app uses public/ as its webroot, has a sample database in db.sql, and all of the users have a default password of 'password'. Couldn't be easier. The app itself is a very quickly thrown together Twitter-esque app. Not all the functionality of Twitter is there, of course, because that really isn't the point. Get the app up and running, play around a little, look through the code, and we're ready to dig in.