This resource contains a collection of the best PHP practices and PHP tips provided by our Toptal network members. As such, this page will be updated on a regular basis to include additional information and cover emerging PHP techniques. This is a community driven project, so you are encouraged to contribute as well, and we are counting on your feedback.
PHP has evolved in a really quick and dirty way, almost as a consequence of being the favorite server language of the web. PHP now has all the things you look for in a robust language - it is flexible and dynamic. Although the older PHP versions weren’t good with OOP, newer versions of the languages support almost everything needed, and in a really smart way. The community behind PHP is the main reason of its success. PHP is used by 81.2% of all the websites out there that use a server side language, and lots of great frameworks were born and died trying to complete the missing pieces of the language. In the same, they guided the development of the needed parts to be done to get the best of a language whose main purpose is web development (although you can do a lot more).
Be aware, PHP is so easy to learn and implement that in inexpert hands it is really dangerous when you want to build a project that grows with time. Great PHP developers know how to use it to get the best out of this language, including which frameworks and tools to use, thus the project won’t become someone’s nightmare. Here are our tips and best practices to develop with this great language.
Check out the Toptal resource pages for additional information on PHP. There is a PHP hiring guide, PHP job description, common PHP mistakes, and PHP interview questions.
Manage Your Dependencies in PHP with Composer
What Is a Dependency?
PHP is a great language to create web projects. One of the things you will see when using PHP is that there is a library for almost anything you need.
A dependency in your project is a library or package that your code uses for performing tasks. For example, if you need to call a REST API you can use the curl library of PHP, or better yet, use the Guzzle library, that have all the things you need for creating the calls.
The Problem with Dependency Management
One common problem of using third party code is keeping it updated while time goes on. Also, there are libraries that depend on other libraries, that depends on other libraries, and so on. That is really a bad situation in a dynamic context as web development is. Not to mention which version of the library you’ll use, as sometimes you need a different version according to the context you’re in, for example, the PHP version your server has.
And there is another catch. Requiring libraries is a big pain, you have to write all the includes into the file that needs to use a given library. When removing that class, you have to clean all the includes and delete the library. And as we all know, that can almost never happen, and we end up with a big folder of deprecated libraries, and then we need to waste our time (or the time of your team) to clean all that mess.
Meet Composer, Your New Friend
Composer is here to solve all those problems for us. When I first started using Composer, I thought it was a package manager, like Yum or Apt. However as they state in their documentation, they are a dependency management and not a package manager, because the packages are not installed globally. Instead, the packages are installed under a vendor folder inside your project.
If you are already falling in love with Composer for this, you’ll definitely love it for what comes next.
Composer offers an autoload for your classes. All you have to do is add this line in top of your project require __DIR__ . '/vendor/autoload.php'; and then just call the constructor of your class. For example, if you’re using Guzzle, you just have to call:
$client = new GuzzleHttp\Client();
and it will work. If you don’t need it anymore, just delete the class and that’s it! Well, I lied, that’s not all but almost. Head to the next section to learn the final step.
We talk about the pain that is deleting a library, because you not only have to be aware of that library but also of the dependencies of that library, and being careful enough not to delete a dependency being use by another library.
In composer this is just as simple as deleting the dependency from the composer.json file, and run composer update. Yes, it is that simple.
Meet Packagist, the Repository for Your Projects
As if you already don’t have enough with all this, there is a common repository for finding libraries for your projects that can be used easily with Composer.
Packagist is the place you go when you need a library. There you can search for libraries, and see what version you want to use, depending on your needs. Also, you can write your own packages, and include them there for others to use.
Of course, there are other ways to include packages, like directly from Github or other sources. That is out of the scope of this article, but you can find how to do this in the documentation page of Composer.
When you go to the library website, you can see several available versions. In general, you will have one that is ready for production and one that is in development.
How the versioning numbers work? Well, they follow the semantic versioning standard, which is basically as follows:
You have 3 numbers, separated by a dot. So for example, in your composer.json file you can add something like "guzzlehttp/guzzle": "5.3.*" for requiring the Guzzle library. The first number, in this case 5, is called the major version. This number changes when big changes are made in the library. Changing this version will probably change the name of the functions, or the classes, or anything. The second number is the minor version, that is meant to be for functionality changes or additions, but having backwards compatibility with other versions. The third number is the patch number. This number is changed each time a bug is fixed, and doesn’t change the functionality of the package.
As you can notice, you can include the wildcard * for replacing that number. This means that when you run composer update, Composer will check for the latest number in that category (major, minor or patch) and update to the newer version. It is recommended to keep the last number with a wildcard only, and update the minor version according. However, if you really trust that library and you always want the latest version, you can of course make this a wildcard as well.
You can also use comparator operators to include a range. For example: "guzzlehttp/guzzle": ">=5.3,<5.4" is equivalent to "guzzlehttp/guzzle": "5.3.*", and also is equivalent to "guzzlehttp/guzzle": "~5.3" using the tilde (~) operator.
For more about versioning, go to the documentation of Composer about versioning.
Save Disk Space
As a last tip, if you use Git add the vendor folder in your ignore file. Having the Composer file is enough, because once the user downloads the project, it will just have to run a composer install command to fetch all the libraries.
In this article we explained what dependencies are, why they are important for our projects, and the problems we have when we deal with them.
After that, we explained how Composer address all those issues in a really smart way to keep your project dependencies organized.
Composer is another tool for your toolbelt that will save you a lot of time and headaches.
Using Test Driven Development In PHP with PhpUnit
In this article we will see how using Test Driven Development (TDD, explained in deep a little later in the article) helps to write good quality code that is maintainable, reusable, and easy to debug and fix when bugs happen.
PHP and Testing
PHP and testing didn’t start together as friends. We all know that other languages are more oriented from the start to create code based on testing suites, but PHP was conceived for quick development. That’s why testing wasn’t part of the day to day routine in a PHP coder.
But times are changing, and now PHP is a mature language that can be used to build great and big applications, and using a test driven development approach is the way to go if you want to save time at the end and build good quality code.
What Is TDD?
TDD stands for Test Driven Development. Basically this means: write your test cases first, and your code later. At first, your tests will fail, because the code will be empty for that case, and that’s fine. Your mission here is making the test pass by building the code to make it happen. This allows you to focus your coding process to pass well described specs, instead of having it all in your head while coding (points in favor for when you need to work under pressure or you’re tired).
So I summarize this as:
- Write your test case
- Write code for your test code
- Fix and refactor
- Move to next test case
For those out there following an agile approach, this sounds very similar. Well it is, because TDD is suited for agile development.
Of course, things could go wrong, but if you found a bug later you have to write another test case, clearly missing from your suite. The good part of this is that when writing new features, they will have to also pass the current automated tests.
Ok, we know what TDD means, but what about Unit testing? Unit testing means testing part of your code isolated from the rest. For that, you need to improve your code to be able to test each component alone, without any interference from other components.
This is why TDD is great for development, because it force developers to isolate the different pieces of information in well known methods that can be tested individually to pass the tests.
It’s not difficult to imagine that TDD will be difficult to implement with code that makes use of God objects, or include too many concerns in one function or method. For example, a function that process a XML file and imports data into a database. You could split that into several functions, one that process the XML, another one for getting the results mapped to the database, and another for saving and checking for errors. If you do it all in one method, then it’s hard to test if that method is doing the task right. As a general rule, each method should do just one thing, and do it right.
That’s how you can do unit testing, by creating small and well defined methods with a clear task to implement, test, and prove right or wrong.
My suggestion for using TDD is to do it every time you can. Most projects that you start from scratch are good for a TDD approach, because you can create them as you want.
However, projects with messy code or code that is build without considering the concepts we discussed in this article or that need to be corrected quickly to go in production are not always a good fit. What I suggest in those cases is to use TDD to refactor pieces of the code and improve the code by parts. Taking all the code and rebuilding everything is not an option in most cases.
TDD forces you to think in how to structure every function, and that’s good. With time you will find this task easier to do, and your code will be really easy to update and refactor.
How to Write Comment-Less Code?
A lot of programmers are used to adding a lot of comments to their code. They see this as a good practice, and there are some programming courses that encourage this approach.
This leads to code that has a lot of comments to each block of code, replacing what the code should say already. Toptal developers, on the other hand, recommend that code should be written to be easy to read and understand, and should express what you want to achieve.
Developers are sometimes under pressure to deliver fast, and it’s ok to put some comments here and there, to explain to yourself and others what you are doing there. But if you incorporate some simple rules for writing your code it will be better, and everybody that works with your code in the future will appreciate it.
How can you achieve this? Here are suggestions on how to avoid code overload with unnecessary comments:
- Code conventions: Use a common way to name variables, functions, indentation, classes, and the use of brackets among other things. Take a look at PHP Framework Interop Group to learn some of the recommended conventions, and try to remember and follow them in all your projects.
- Clear names for variables: Always try to put names expressing what you want to do with them.
Keep functions short: Try to write as few lines as possible when writing functions. This doesn’t mean you should be doing functional programming, but try to put small pieces of your code that do a specific task, like getting records from a database, in a separate function.
Use the keywords TODO, FIXME, NOTE for your comments. Using them forces you to write comments only when something that needs to be completed or fixed is in your code.
- Use comments at the beginning of the file: Describe what the file does, you don’t need to comment each function unless you’re writing an open API, but for internal classes try to keep descriptions only in the top of your document. The functions’ name should express what it does. If you have functions with names GetProductsByEnabledUsers() in your classes, you may need to refactor that into other classes.
- Keep a good structure of your code: For this it is recommended to use a good framework like Laravel, CakePHP, and Kohana to keep the structure of the files following a structured approach, following a model that makes sense, like MVC. In general, if you have classes depending on other classes, try to create folders to hold those and avoid long names in the files.
- Maintain good indentation: Choose a convention like 4 spaces or 1 tab of size 2, but always use the same, and indent well. Other languages like Python compile only if you use good indentation, many PHP developers see this as a disadvantage. I personally love that Python forces developers to keep good code.
- Use tools to help you out: Sometimes you’re tired, and you just want to finish. Getting to the finish line quickly often make us code poorly. Try using some tools in your code editor. Toptal developers recommend SublimeText and the plugin Phpcs that force developers to follow the standard. Also it helps to learn the standard while writing your code.
Use your comments as refactor signs: Sometimes, when part of the functionality needs to be done really quickly, creating comments to specify desired end results can be used as a refactor signs that this part of the code should be improved later, maybe by splitting the function or by creating better names for the variables.
Well, I hope you found this interesting and useful and decide embrace code readability. Everyone using your code will be thankful if you do.
This article was originally published on Toptal