setup-php: A Cross-Platform PHP Provisioner for GitHub Actions
Project brief: GitHub action to set up PHP with extensions, php.ini configuration, coverage drivers, and various tools.
At a glance
- What is it?
- setup-php installs or switches PHP versions, adds extensions, configures php.ini, and pulls in tools like Composer across GitHub-hosted and self-hosted runners. It is the de facto standard for PHP CI, but its breadth comes with a few sharp edges.
- Who is it for?
- Adopt setup-php if you run PHP tests on GitHub Actions and need a single action that handles PHP versions, extensions, coverage drivers, and Composer across Ubuntu, Windows, and macOS. Avoid it if you are on a non-supported OS or need a tool that runs outside GitHub Actions; look at local scripts or other CI-specific provisioners.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The Problem: PHP Environments Are Not Reproducible in CI
PHP projects need a specific interpreter version, a set of extensions, and often a coverage driver. GitHub-hosted runners come with a default PHP, but it may not match your project's requirement. Installing PHP manually in a workflow means writing shell steps for each OS, handling package managers, and dealing with version-specific quirks. setup-php replaces that with a single action. It is aimed at PHP developers who use GitHub Actions for testing, static analysis, or code coverage. The README positions it as a cross-platform interface to set up the PHP environment you need. That covers the core pain: you declare what you want, and the action figures out how to get it on the current runner.
How It Works: From Version Request to Ready CLI
The action takes inputs like php-version, extensions, coverage, and tools. Based on the runner OS and architecture, it either switches to a pre-installed PHP or installs a new one. The README states: if the requested PHP version is pre-installed, setup-php switches to it, otherwise it installs the PHP version. That means on Ubuntu 24.04, which ships PHP 8.3, requesting 8.3 is nearly instant; requesting 8.1 triggers an install. The action also handles php.ini configuration through the ini-values input, and it can enable or disable extensions. Coverage drivers are a separate input: you can choose xdebug, pcov, or disable coverage entirely. The action outputs the PHP version and some other values, which you can use in later steps. The data flow is straightforward: your workflow YAML declares the desired state, the action resolves it against the runner's package sources or pre-installed binaries, and then modifies PATH and configuration so subsequent commands use the right PHP.
Getting It Running: Inputs, Flags, and a Basic Example
The README documents several inputs and flags. The core inputs are php-version, extensions, coverage, and tools. A basic setup step looks like this: uses: shivammathur/setup-php@v2, with php-version: '8.2', extensions: mbstring, intl, coverage: xdebug. The action also supports a matrix setup, where you loop over multiple PHP versions. There are flags for nightly builds, debug builds, thread safety (for Windows), force update, and verbose output. For self-hosted runners, there is a separate self-hosted setup section. The README also covers JIT configuration, caching extensions, and caching Composer dependencies. You can configure GitHub Composer authentication and Private Packagist authentication. There is an inline PHP script feature and problem matchers for PHP errors. The action is written in TypeScript, and the repository is under the MIT license. You run it by adding the step to your workflow; no separate installation is required.
Platform and Version Coverage: Wide but with Gaps
The README lists GitHub-hosted runners for Ubuntu 22.04, 24.04, and 26.04, Windows Server 2022 and 2025, and macOS 14, 15, and 26, with both x86_64 and aarch64 variants where applicable. Self-hosted runners include Ubuntu, Debian 11 through 13, Windows 7 and newer, and macOS 14 through 26. PHP version support ranges from 5.3 to 8.6 on most GitHub-hosted runners, except macOS ARM64 runners (macos-14) which support 5.6 to 8.6. That is a real gap: if you need PHP 5.3 or 5.4 on an Apple Silicon runner, you cannot use this action. Also, the README notes that operating systems based on the listed Ubuntu and Debian versions are supported on a best effort basis. That means a custom distro like Pop!_OS might work, but you should not rely on it. The version table marks many older PHP versions as End of life, which is fine for testing legacy code but means you are pulling from archives.
The Extension and Tooling Story: More Than Just PHP
Beyond the interpreter, setup-php handles extensions and tools. The extensions input accepts a comma-separated list, and the action installs them according to the platform. The coverage input lets you pick xdebug or pcov, or disable coverage entirely. The tools input can install Composer, which is a common need. The README also shows how to cache extensions and Composer dependencies, which can speed up repeated runs. There is a composer authentication section for GitHub and Private Packagist, so you can install private packages without hardcoding tokens. The action also provides problem matchers, which format PHP errors in the Actions log so they are easier to read. This is not just a PHP installer; it is a full CI environment setup tool. However, the README does not detail how each extension is installed under the hood. For a rare extension, you may need to check the source or the issue tracker to see if it is supported.
Limitations and Failure Modes
One clear limitation is the dependency on the runner's package sources. If a PHP version is not pre-installed, the action installs it, which means network access and package availability. On a self-hosted runner behind a firewall or with restricted package repositories, the install may fail. The README does not specify an offline mode. Another limitation is the best effort support for derived Ubuntu and Debian systems. If you use a distro that is not listed, you are on your own. Also, the action is tied to GitHub Actions. It does not work for GitLab CI, Jenkins, or local development. The README mentions local testing setup, but that is for testing the action itself, not for using it outside Actions. Finally, the action's behavior on macOS ARM64 is restricted: it supports PHP 5.6 and above, not 5.3 to 5.5. If you need those ancient versions, you must use an Intel runner or a different approach.
Alternative: Manual Installation Scripts
The main alternative is to write your own installation steps in the workflow. For example, on Ubuntu you could run sudo apt-get install php8.2-cli php8.2-mbstring, and on macOS you could use Homebrew. That gives you full control over the exact packages and versions, but it multiplies the workflow complexity. You need conditional steps for each OS, handle PATH updates, and manage coverage drivers manually. setup-php abstracts that away. Another alternative is to use a Docker container with PHP pre-installed, but that changes your test environment and may not match the runner's OS. The difference in approach is significant: setup-php is a purpose-built action that knows the runner's internals, while manual scripts are portable but verbose and error-prone. For a single OS, manual steps might be simpler; for a matrix across Ubuntu, Windows, and macOS, setup-php saves a lot of YAML.
Maintenance and Upgrade Cost
The repository is actively maintained, with a release on June 8, 2026, and several releases earlier in 2026. The README includes a versioning section, which likely explains how tags are managed. The action uses a major version tag like v2, but you can pin to a specific release like v2.37.2. Pinning to a specific tag reduces upgrade risk, but you must manually bump it to get fixes. The action has a status page at status.setup-php.com, which suggests there is an operational component, possibly for extension builds. The MIT license means you can fork and modify it if needed, but that adds your own maintenance burden. The action's dependencies are listed in the README, so you can audit them. Overall, the upgrade cost is low if you pin to a tag and test your workflow after each update. The active release cadence means you will see frequent updates, which is good for bug fixes but requires you to stay alert.
Editorial conclusion
Adopt setup-php if you run PHP tests on GitHub Actions and need a single action that handles PHP versions, extensions, coverage drivers, and Composer across Ubuntu, Windows, and macOS. Avoid it if you are on a non-supported OS or need a tool that runs outside GitHub Actions; look at local scripts or other CI-specific provisioners. Before adopting, verify that the PHP version and extensions you need are listed in the README for your runner type, and check the action's version pinning policy: use a specific tag like v2.37.2 rather than a floating major to avoid unexpected updates. The action's active release schedule (last push June 2026) suggests ongoing maintenance, but you should still test your workflow after any action update.
Community notes