Breathing New Life into Legacy PHP Applications

PHP 5.4 to 8.3

Nix

Nix is a powerful package manager and system configuration tool:

  • Declarative and reproducible builds
  • Multiple versions of packages side-by-side
  • Supports multiple programming languages, including PHP

Benefits for PHP development:

  • Easily switch between PHP versions
  • Manage dependencies consistently
  • Create isolated development environments
  • Simplify deployment processes

Nix can be particularly useful for maintaining and upgrading legacy PHP applications.

Loophp/nix-shell:

nix shell github:loophp/nix-shell#env-php81

Nix

Sample flake.nix file:

{
  description = "PHP development environment";
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    flake-utils.url = "github:numtide/flake-utils";
    phps.url = "github:loophp/nix-shell";
  };
  outputs = { self, nixpkgs, flake-utils, phps }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs {
          inherit system;
          overlays = [ phps.overlays.default ];
        };
      in
      {
        devShells.default = pkgs.mkShell {
          buildInputs = [
            pkgs.env-php82
          ];
        };
      });
}

Node.js

  • JavaScript runtime
  • Large ecosystem (npm)
  • Released in 2009.
  • Commonly used alongside PHP projects.

jQuery

  • Still the number #3 most used web technology in 2024 according to Stack Overflow.
  • Common in older PHP applications.
  • Upgrade, replace, or rewrite.

Example:

$(document).ready(function() {
    $(".button").click(function() {
        $.ajax({
            url: "process.php",
            method: "POST",
            data: { id: $(this).data("id") },
            success: function(response) {
                $("#result").html(response);
            },
            error: function(xhr, status, error) {
                console.error("Error:", error);
            }
        });
    });
});

CSS Frameworks

Common in legacy PHP applications:

  • Bootstrap 3/4
  • Foundation
  • DIY
  • No framework

Newer alternatives:

  • Tailwind CSS
  • Bulma
  • Materialize
  • UnoCSS

Consider:

  • Upgrading existing framework
  • Gradually adopting a new framework
  • Creating a custom design system

PHP Extensions

$ php -m

[PHP Modules]
bcmath
calendar
Core
ctype
curl
date
dom
exif
fileinfo
filter
ftp
gd
gettext
gmp
hash
iconv
imap
intl
json
ldap
libxml

CSS Bundling

Benefits of modern bundling:

  • Better organization (modules, variables)
  • Easier maintenance
  • Automated optimizations
  • Faster load times

Example upgrade path:

  1. Introduce Sass for variables and nesting
  2. Add PostCSS for autoprefixing and minimization
  3. Implement Webpack or Vite for full asset pipeline

Docker

Containerization for PHP applications:

  • Consistent development environments
  • Easy deployment
  • Isolation of services

Benefits:

  • Reproducible environments
  • Easier onboarding for new developers
  • Simplified CI/CD pipelines

Example PHP 7.4 dockerfile:

FROM php:7.4-fpm
# Install system dependencies
RUN apt-get update && apt-get install -y git curl libpng-dev \
                            libonig-dev libxml2-dev zip unzip
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Set working directory
WORKDIR /var/www
# Copy existing application directory contents
COPY . /var/www
# Copy existing application directory permissions
COPY --chown=www-data:www-data . /var/www
# Install dependencies
RUN composer install
# Change current user to www
USER www-data
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]

Docker Compose

Example docker-compose.yml for a PHP application:

version: '3'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: myapp
    volumes:
      - ./www:/var/www
      - ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
    networks:
      - app-network

… Part 1.

This docker-compose file defines a multi-container setup for a PHP application.

Docker Compose

Example docker-compose.yml for a PHP application:

  webserver:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./www:/var/www
      - ./docker/nginx/conf.d/:/etc/nginx/conf.d/
    networks:
      - app-network

… Part 2.

Docker Compose

Example docker-compose.yml for a PHP application:

  db:
    image: mysql:8.4
    ports:
      - "3307:3306"
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: your_mysql_root_password
    volumes:
      - ./docker/mysql:/var/lib/mysql/
      - ./mysql/my.cnf:/etc/mysql/my.cnf
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  dbdata:
    driver: local

… Part 3.