Best Practices for Magento 2 Programming
Programming in Magento 2 means dealing with varying pieces of software, and when they are all combined, they make up an intricate software platform. Because there are so many different pieces involved, it’s important to have a set of processes in place to keep your codebase nice and tidy. Implementing formal procedures to standardize repeatable tasks helps ensure the reliability of your store and prevent unwieldy situations from occurring in the first place.
Not all best practices are created equal. Easy to implement code formatting tools may not affect the functionality of your store, but they may speed up the code review process. Other code sniffing tools may make your entire codebase easier to maintain, so instead of tracking down small issues, you can work on developing new features. Then there are those large, confusing problems that may occur after implementing a complicated feature. These may be extremely difficult to diagnose and may require an entire architectural overhaul. Thinking through design patterns and having a plan beforehand could prevent these large issues from occurring in the first place.
It’s not a requirement to implement all of the following recommended best practices, and this is by no means an exhaustive list. However, by consciously choosing to implement one or more of these ideas, you are streamlining your development process and helping your team work toward confidently shipping a quality product.
Automated Code Tooling
PHP_CodeSniffer has long been a staple in the PHP world to check your code against a set of rules to detect coding violations and automatically fix them. It’s best used both during development to correct issues as they are being coded, as well as within a deployment pipeline. By using either standardized rulesets or creating your own ruleset specific to either your company or client projects, you are confirming your code follows an approved list of standards and that your code formatting is in a consistent state.
An added benefit of using rulesets with PHP_CodeSniffer is it speeds up the amount of time that is spent in a code review process (you do also have a formal code review process, correct?). Rather than having your architects waste time on mundane tasks such as invalid code formatting or naming conventions, they can be more focused on reviewing the larger architectural details that are more important.
PHP Mess Detector
Another staple in the PHP world is PHPMD. The PHP Mess Detector takes an automated review process much farther than PHP_CodeSniffer by detecting architectural problems with code automatically. This tool analyzes code to automatically detect bugs and complicated code (which I like to call “spaghetti” code). It also keeps your codebase clean by detecting “dead” code, which is code that exists in your codebase but isn’t used or executed at any point.
Magento Coding Standard
The Magento Coding Standard is the official coding standard built for and recommended by Magento. It works in tandem with PHP_CodeSniffer and implements not only standard PHP recommendations such as PSR compliance, basic security rules and syntax checks, but also updates specific to Magento’s codebase such as certain naming conventions and other coding standards.
Another great reason to follow the Magento Coding Standard is that it is used for automated reviews for Magento Marketplace modules, as well as for compatibility with Magento instances running on the Magento Cloud. By following these guidelines, your code not only has a much higher rate of quality but also higher compatibility with the extended Magento ecosystem.
Design Patterns and Principles
This practice isn’t specific to Magento or PHP; it’s for all programming projects and languages. There are sets of design patterns and principles to follow that, for the most part, are accepted methods of best practices for coding.
The Sourcemaking Design Patterns page has a great reference of various design patterns. Wikipedia also has a good Software design pattern page to reference. These are tried-and-true patterns of solid programming concepts to apply to just about any programming project. Over time, best practices for design patterns may change, but they generally stay the same.
If your programmers don’t currently have a wide range of knowledge of design patterns, set up some time to focus on learning them with study groups. Peer-to-peer interaction for learning these patterns is a great way to inspire confidence in your programmers as well as build some camaraderie within your team.
Peer-to-peer interaction for learning these patterns is a great way to inspire confidence in your programmers as well as build some camaraderie within your team.
In specific regards to Object-Oriented Programming, one should become intricately familiar with the concept of SOLID design principles. It’s easy to get into trouble with object-orient programming (especially Magento!), so following these design principles within your Magento code helps keep your app avoid a spaghetti mess in the future. In times when something is coded and it just doesn’t quite look right, it’s most likely not adhering to one of these design principles. Learning the concepts, and why they were created, will help your entire team stay on a solid footing and help you deliver clean code.
Speaking of clean code, Bob Martin, the creator of the foundations of SOLID design principles, authored a book called “Clean Code: A Handbook of Agile Software Craftsmanship.” This book, along with the other related books in the series, are great reads for your team to learn more about writing maintainable and agile code.
The main difference between Magento 1 and Magento 2 is the addition of the dependency injection layer. The extension of the implementation of this DI layer is the heavy use of interfaces. These interfaces make up what is known in Magento 2 as service contracts.
A service contract is a fancy word of saying “implement these interfaces” to build out the desired features and functionality. By extending the core interfaces, your code becomes compatible with a specific internal API. By using this API, it guarantees the code is compatible with core code, upgrades and third-party code.
Classes that implement interfaces are called concrete classes. By using service contracts and implementing these interfaces, one creates their own concrete classes. Magento’s creation of these concrete classes in the core code is a good example of this.
The usage of service contracts is great; however, some developers of custom or third-party code are creating their own classes and extending Magento’s core classes, rather than implementing the service contracts. This is not good coding practice, as custom code now depends on the concrete implementation of the class rather than implementing the suggested interfaces. This creates a hard dependency on the concrete class and leads to very bad inheritance problems, making it hard to update to a new version of Magento or work well with third-party code.
Whenever a lass you wish to extend implements an interface, consider implementing that interface rather than extending the core concrete class. In your own custom code, create your own service contracts to allow third parties to implement your service contracts, which will, in turn, help create portable and updateable code.
Strict Data Types
Defining and using strict data types are also another very direct way to help write bug-free code. The advent and popularity of TypeScript show us just how important getting the data type correct is, and PHP is no different. The language is considered a loosely or weakly typed language, and the ability to define strict types in our code will make it more predictable.
PHP 7 introduced the concept of strict types. Using a strict type declaration makes sure your types cannot be juggled or changed during the execution of the software. If the wrong type is passed around or modified during runtime, the script will immediately fail. This is actually desired, rather than an unexpected error happening in a production environment.
Since declaring strict types is done on a file-by-file basis, you can start implementing strict types today by just adding it to new files in your code. Over time, you can eventually transition to all of your PHP files having this declaration. This gives you the ability to slowly implement strict types on a time frame that is good for you and your clients. To learn more about this, read up on how strict types work.
Along the same lines, you can declare a variable type in a comment. This is part of the DocBlock Standard, so it can also be checked for proper implementation by using PHP_CodeSniffer. By declaring var types in comments, you are making code drastically easier to debug in development environments, especially within PHTML template files when defining a block variable or when using ViewModels.
Other Best Practices
There are many other best practices you can use, and you or your team can even create your own. I’ve documented and taught many other Magento-specific concepts such as applying patches from GitHub with the cweagens module, how to properly save Magento data objects, as well as how to write good unit tests to ensure code predictability in production environments.
Whichever best practices you implement, you don’t need to do it all at once. Your best course of action is to pick some low-hanging fruit to implement to immediately see a change in your development practice. Then, slowly introduce other concepts over a period of time. If you keep doing this, you can become confident that, with time, your code will become more predictable, maintainable and easier to work with in the future.