2. Getting Started
2.1 Common Directory structure
A common question among those starting out with writing programs for the web is, “where do I put my stuff?” Over the years, this answer has consistently been “where the DocumentRoot is.” Although this answer is not complete, it’s a great place to start.
For security reasons, configuration files should not be accessible by a site’s visitors; therefore, public scripts are kept in a public directory and private configurations and data are kept outside of that directory.
For each team, CMS, or framework one works in, a standard directory structure is used by each of those entities. However, if one is starting a project alone, knowing which filesystem structure to use can be daunting.
Paul M. Jones has done some fantastic research into common practices of tens of thousands of github projects in the realm of PHP. He has compiled a standard file and directory structure, the Standard PHP Package Skeleton, based on this research. In this directory structure, DocumentRoot should point to public/, unit tests should be in the tests/ directory, and third party libraries, as installed by composer, belong in the vendor/ directory. For other files and directories, abiding by the Standard PHP Package Skeleton will make the most sense to contributors of a project.
2.2 Use the Current Stable Version (8.4)
If you are getting started with PHP, start with the current stable release of PHP 8.4. PHP 8.x adds many new features over the older 7.x and 5.x versions. The engine has been largely re-written, and PHP is now even quicker than older versions. PHP 8 is a major update of the language and contains many new features and optimizations.
You should try to upgrade to the latest stable version quickly - PHP 7.4 is already End of Life. Upgrading is easy, as there are not many backwards compatibility breaks PHP 8.0, PHP 8.1, PHP 8.2, PHP 8.3, PHP 8.4. If you are not sure which version a function or feature is in, you can check the PHP documentation on the php.net website.
2.3 Built-in web server
With PHP 5.4 or newer, you can start learning PHP without installing and configuring a full-fledged web server. To start the server, run the following command from your terminal in your project’s web root:
1 > php -S localhost:8000
2.4 Complementary Testing Tools
Besides individual testing and behavior driven frameworks, there are also a number of generic frameworks and helper libraries useful for any preferred approach taken.
Tool Links
- Selenium is a browser automation tool which can be integrated with PHPUnit
- Mockery is a Mock Object Framework which can be integrated with PHPUnit or PHPSpec
- Prophecy is a highly opinionated yet very powerful and flexible PHP object mocking framework. It’s integrated with PHPSpec and can be used with PHPUnit.
- php-mock is a library to help to mock PHP native functions.
- Infection is a PHP implementation of Mutation Testing to help to measure the effectiveness of your tests.
- PHPUnit Polyfills is a library that allows for creating PHPUnit cross-version compatible tests when a test suite needs to run against a range of PHPUnit versions.
2.5 Test Driven Development
From Wikipedia:
Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle: first the developer writes a failing automated test case that defines a desired improvement or new function, then produces code to pass that test and finally refactors the new code to acceptable standards. Kent Beck, who is credited with having developed or ‘rediscovered’ the technique, stated in 2003 that TDD encourages simple designs and inspires confidence.
There are several different types of testing that you can do for your application:
Unit Testing
Unit Testing is a programming approach to ensure functions, classes and methods are working as expected, from the point you build them all the way through the development cycle. By checking values going in and out of various functions and methods, you can make sure the internal logic is working correctly. By using Dependency Injection and building “mock” classes and stubs you can verify that dependencies are correctly used for even better test coverage.
When you create a class or function you should create a unit test for each behavior it must have. At a very basic level
you should make sure it errors if you send it bad arguments and make sure it works if you send it valid arguments. This
will help ensure that when you make changes to this class or function later on in the development cycle that the old
functionality continues to work as expected. The only alternative to this would be var_dump() in a test.php, which is
no way to build an application - large or small.
The other use for unit tests is contributing to open source. If you can write a test that shows broken functionality (i.e. fails), then fix it, and show the test passing, patches are much more likely to be accepted. If you run a project which accepts pull requests then you should suggest this as a requirement.
PHPUnit is the de-facto testing framework for writing unit tests for PHP applications, but there are several alternatives:
Integration Testing
From Wikipedia:
Integration testing (sometimes called Integration and Testing, abbreviated “I&T”) is the phase in software testing in which individual software modules are combined and tested as a group. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.
Many of the same tools that can be used for unit testing can be used for integration testing as many of the same principles are used.
Functional Testing
Sometimes also known as acceptance testing, functional testing consists of using tools to create automated tests that actually use your application instead of just verifying that individual units of code are behaving correctly and that individual units can speak to each other correctly. These tools typically work using real data and simulating actual users of the application.
Functional Testing Tools
- Codeception is a full-stack testing framework that includes acceptance testing tools
- Cyress
- Mink
- Selenium
- Storyplayer is a full-stack testing framework that includes support for creating and destroying test environments on demand