DEV Community

Cover image for Building PHPVM: A PHP Version Manager Born from Necessity
Jerome Thayananthajothy
Jerome Thayananthajothy

Posted on

2 1 1

Building PHPVM: A PHP Version Manager Born from Necessity

As a PHP developer working across multiple projects, I found myself constantly struggling with a common problem: managing different PHP versions. Each client, each project had its own requirements. One legacy application needed PHP 7.4 for compatibility reasons, while a modern API required PHP 8.2 to leverage newer language features.

Sound familiar? If you're nodding your head, you're not alone. This is why I created phpvm, a lightweight PHP version manager inspired by the elegant simplicity of Node Version Manager (NVM).

The Problem: PHP Version Chaos

Like many developers, I work with multiple PHP applications simultaneously. Before creating phpvm, my workflow looked something like this:

  1. Check project requirements
  2. Manually uninstall current PHP version
  3. Install required PHP version
  4. Configure system to use it
  5. Repeat steps 1-4 every time I switched projects

This process was not only time-consuming but error-prone. Sometimes I'd miss a step, resulting in cryptic errors and wasted debugging time. Other times, I'd accidentally break system dependencies that relied on specific PHP versions.

"There has to be a better way," I thought. Looking around, I found several solutions, but none had the simplicity and elegance I was seeking. As a TypeScript and PHP developer who uses tools like NVM daily, I wanted something that followed similar patterns and conventions.

The Journey to Create phpvm

Building a version manager that works across different operating systems presented numerous challenges. What works on macOS might fail on Ubuntu, and what functions on Arch Linux might break on CentOS.

The first hurdle was detecting the system's package manager. Mac users typically use Homebrew, while Linux distributions vary between apt, dnf, yum, and pacman. Each has its own syntax and peculiarities.

# A snippet showing how phpvm detects the system's package manager
if [ "$(uname)" = "Darwin" ]; then
    PKG_MANAGER="brew"
    # macOS-specific logic
else
    # Detect Linux package manager
    if command -v apt-get >/dev/null 2>&1; then
        PKG_MANAGER="apt"
    elif command -v dnf >/dev/null 2>&1; then
        PKG_MANAGER="dnf"
    # More package managers...
    fi
fi
Enter fullscreen mode Exit fullscreen mode

Another significant challenge came with managing symlinks and paths. On macOS, Homebrew installs PHP in a Cellar directory, while Linux distributions typically use /usr/bin. Handling these differences while providing a consistent user experience required careful consideration.

Permissions posed yet another obstacle. Installing PHP often requires superuser privileges, but running commands as root can introduce security risks. I implemented a run_with_sudo helper function that elevates privileges only when necessary.

Testing across multiple environments was perhaps the most time-consuming part. I needed to ensure phpvm worked correctly not just on my machine but on various Linux distributions and macOS versions. This led me to create a comprehensive self-testing system:

phpvm test
Enter fullscreen mode Exit fullscreen mode

This command runs a series of tests that verify core functionality, giving users confidence that everything is working as expected.

The Solution: phpvm in Action

After several iterations, phpvm emerged as a robust solution. Here's how it transforms the PHP version management workflow:

# Install a specific PHP version
phpvm install 8.1

# Switch to that version
phpvm use 8.1

# Check the active version
php -v
# Output: PHP 8.1.13

# Switch to another version
phpvm use 7.4

# Verify the change
php -v
# Output: PHP 7.4.33
Enter fullscreen mode Exit fullscreen mode

For teams working on the same project, phpvm supports automatic version switching via a .phpvmrc file:

# Create a .phpvmrc file in your project root
echo "8.2" > .phpvmrc

# Later, when entering the project directory
phpvm auto
# Output: Auto-switching to PHP 8.2 (from /path/to/project/.phpvmrc)
Enter fullscreen mode Exit fullscreen mode

This feature ensures all team members use the correct PHP version, eliminating the "works on my machine" syndrome.

Technical Design Decisions

Several design principles guided phpvm's development:

  1. Shell Compatibility: Written in POSIX-compliant shell script to ensure maximum compatibility across systems.

  2. Minimal Dependencies: phpvm relies only on standard Unix tools and the system's package manager, avoiding additional dependencies.

  3. Informative Feedback: Every operation provides clear, timestamped output, making it easier to understand what's happening:

2025-05-12 10:15:30 [INFO] Switching to PHP 8.1...
2025-05-12 10:15:32 [INFO] Switched to PHP 8.1.
Enter fullscreen mode Exit fullscreen mode
  1. Robust Error Handling: When something goes wrong, phpvm provides detailed error messages and suggestions, rather than failing silently.

  2. Automated Testing: The built-in testing framework ensures reliability across different environments.

These decisions contribute to a tool that's not only functional but also maintainable and user-friendly.

Looking Ahead: The Future of phpvm

While phpvm successfully solves the PHP version management problem, I see several exciting possibilities for its future:

Try phpvm Today

If you're tired of the PHP version management dance, I invite you to try phpvm:

curl -o- https://raw.githubusercontent.com/Thavarshan/phpvm/main/install.sh | bash
Enter fullscreen mode Exit fullscreen mode

The project is open source and available at github.com/Thavarshan/phpvm. I welcome your feedback, bug reports, and contributions! Whether you're using phpvm daily or just trying it out, your experience helps shape its future.

The journey of creating phpvm reminded me that great developer tools often arise from personal frustrations. By solving my own PHP version management headaches, I hope to help others streamline their workflows and focus on what truly matters—building great PHP applications.

What developer tools have you created to solve your own problems? I'd love to hear about your experiences in the comments below.

Heroku

Deploy with ease. Manage efficiently. Scale faster.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (3)

Collapse
 
xwero profile image
david duymelinck • Edited

A way to solve this is to use containers. Just request the container with the right PHP version.
It does not have only the specific PHP version but also the extensions that are common for PHP frameworks.

The problem with having different PHP version on your machine, you also need different databases, different caches. And you need a tool for that to. And then you all have to connect it to the projects.
That is a problem containers solved many years ago.

I think it is a good exercise, it is only a part of a solution that already exists.

Collapse
 
thavarshan profile image
Jerome Thayananthajothy

Thanks for the suggestion! Containers are fantastic for full-stack parity, but phpvm is useful when I just need a quick, shell-native way to hop between interpreter versions without spinning up or rebuilding images.

Collapse
 
xwero profile image
david duymelinck • Edited

It probably will be tool that scratches an itch, but from the long term vision I get you want it to be much more.