From 6615fd156be9f25e1b48853e63963b359b5c586d Mon Sep 17 00:00:00 2001 From: Marjo Wenzel van Lier Date: Sat, 27 Jun 2026 05:59:54 +0200 Subject: [PATCH] build(php): Raise minimum version to 8.4 Move the supported PHP floor from 8.3 to 8.4 across the toolchain. Drop 8.3 from the CI matrix (now 8.4 and 8.5), bump the Docker image, phpstan and rector targets, and align every version reference in the README, docs site, and contributor guides. Revert an experimental 8.5 pipe operator in nameFix back to the typed one-liner so the code runs on the 8.4 floor. Also tighten the removeAccents benchmark surfaced by static analysis: guard the str_repeat count as a non-negative int and fold each result into a printed checksum so the pure calls cannot be optimised away. Signed-off-by: Marjo Wenzel van Lier --- .coderabbit.yaml | 8 ++++---- .github/workflows/codecov.yml | 4 ++-- .github/workflows/php.yml | 2 +- CLAUDE.md | 6 +++--- CONTRIBUTING.md | 2 +- Dockerfile | 2 +- README.md | 8 ++++---- composer.json | 6 +++--- docs/_config.yml | 2 +- docs/contributing.md | 4 ++-- docs/getting-started.md | 2 +- docs/index.md | 8 ++++---- phpstan.neon | 2 +- rector.php | 4 ++-- src/StringManipulation.php | 2 +- .../Benchmark/RemoveAccentsComplexityBenchmark.php | 13 ++++++++++--- 16 files changed, 41 insertions(+), 34 deletions(-) diff --git a/.coderabbit.yaml b/.coderabbit.yaml index a0c31b3..0309059 100644 --- a/.coderabbit.yaml +++ b/.coderabbit.yaml @@ -2,7 +2,7 @@ # yaml-language-server: $schema=https://docs.coderabbit.ai/schema/schema.v2.json # CodeRabbit Configuration -# StringManipulation PHP 8.3+ Library +# StringManipulation PHP 8.4+ Library # Enforces strict quality standards: PHPStan MAX, SOLID principles, PER-CS2.0 # Language and Tone @@ -54,8 +54,8 @@ reviews: Review PHP code for adherence to PER Coding Style 2.0 guidelines. Ensure proper namespace usage, code organisation, and separation of concerns. Verify that SOLID principles are followed and - encourage FOOP techniques—such as immutable data, pure functions, - and functional composition—to improve maintainability, + encourage FOOP techniques (such as immutable data, pure functions, + and functional composition) to improve maintainability, testability, and performance. Specific checks: @@ -64,7 +64,7 @@ reviews: - Final classes with static methods where appropriate - Comprehensive docblocks with @param, @return, and @example tags - No methods exceeding 100 lines (PHPMD rule) - - PHP 8.3+ features and patterns + - PHP 8.4+ features and patterns - Proper error handling and null safety - path: "tests/**/*.php" diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index ca27eed..b81df5a 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -9,10 +9,10 @@ jobs: with: fetch-depth: 0 - - name: Set up php 8.3 + - name: Set up php 8.4 uses: shivammathur/setup-php@v2 with: - php-version: "8.3" + php-version: "8.4" extensions: mbstring, xml, zip, pdo_mysql, xhprof - name: Install dependencies diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 8e764b6..498931c 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -15,7 +15,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ["8.3", "8.4", "8.5"] + php-versions: ["8.4", "8.5"] steps: # This step checks out a copy of your repository. diff --git a/CLAUDE.md b/CLAUDE.md index 73c476d..d21f266 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,11 +4,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -High-performance PHP 8.3+ string manipulation library with zero production dependencies. Single final class (`StringManipulation`) exposing static methods optimised with pre-computed character mappings for O(1) lookups via `strtr()`. +High-performance PHP 8.4+ string manipulation library with zero production dependencies. Single final class (`StringManipulation`) exposing static methods optimised with pre-computed character mappings for O(1) lookups via `strtr()`. ## Build & Test Commands -**Always use Docker** to ensure consistent PHP 8.3 + AST extension environment. +**Always use Docker** to ensure consistent PHP 8.4 + AST extension environment. | Task | Docker | Local | |------|--------|-------| @@ -82,4 +82,4 @@ Mutation testing target MSI: 88%. ## CI -GitHub Actions runs the test matrix against PHP 8.3, 8.4, and 8.5 with vulnerability scanning (osv-scanner + Enlightn). +GitHub Actions runs the test matrix against PHP 8.4 and 8.5 with vulnerability scanning (osv-scanner + Enlightn). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 42ada95..beeb275 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ Thank you for your interest in contributing to StringManipulation! This document - Docker and Docker Compose - Git -- PHP 8.3+ (optional, only for local development without Docker) +- PHP 8.4+ (optional, only for local development without Docker) ### Setting Up Pre-commit Hooks diff --git a/Dockerfile b/Dockerfile index 06ffa80..e09e3fd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.3-cli-alpine +FROM php:8.4-cli-alpine # Install system dependencies RUN apk add --no-cache \ diff --git a/README.md b/README.md index 99a11a3..1881949 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ ## Introduction -Welcome to the `StringManipulation` library, a high-performance PHP 8.3+ toolkit designed for complex and efficient +Welcome to the `StringManipulation` library, a high-performance PHP 8.4+ toolkit designed for complex and efficient string handling. Following a recent suite of O(n) optimisations, the library is now **2-5x faster**, making it one of the most powerful and reliable solutions for developers who require speed and precision in their PHP applications. @@ -201,7 +201,7 @@ of tools to ensure stability and correctness. ### Docker-Based Testing (Recommended) -For a consistent and reliable testing environment, we recommend using Docker. Our Docker setup includes PHP 8.3 with all +For a consistent and reliable testing environment, we recommend using Docker. Our Docker setup includes PHP 8.4 with all required extensions: ```bash @@ -217,7 +217,7 @@ docker-compose run --rm test-infection # Mutation testing ### Local Testing -If you have a local PHP 8.3+ environment configured: +If you have a local PHP 8.4+ environment configured: ```bash # Complete test suite @@ -243,7 +243,7 @@ composer tests ## System Requirements -- **PHP 8.3 or later** (strict typing enabled) +- **PHP 8.4 or later** (strict typing enabled) - **`mbstring` extension** for multi-byte string operations - **`intl` extension** for internationalisation and advanced Unicode support - **Enabled `declare(strict_types=1);`** for robust type safety diff --git a/composer.json b/composer.json index 261e6da..a7b3b96 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "marjovanlier/stringmanipulation", - "description": "High-performance PHP 8.3+ string manipulation library featuring O(n) algorithms with up to 5x speed improvements. Provides Unicode-aware operations including searchWords(), nameFix(), utf8Ansi(), removeAccents(), and isValidDate() with comprehensive testing infrastructure.", + "description": "High-performance PHP 8.4+ string manipulation library featuring O(n) algorithms with up to 5x speed improvements. Provides Unicode-aware operations including searchWords(), nameFix(), utf8Ansi(), removeAccents(), and isValidDate() with comprehensive testing infrastructure.", "keywords": [ "string manipulation", "performance", @@ -43,7 +43,7 @@ }, "minimum-stability": "stable", "require": { - "php": "^8.3" + "php": "^8.4" }, "require-dev": { "enlightn/security-checker": ">=2.0", @@ -72,7 +72,7 @@ "test:phpstan": "Perform advanced static analysis with PHPStan for type checking, null safety, and logic validation", "test:pest": "Run comprehensive Pest test suite with mutation testing, strict type checking and edge case coverage", "test:psalm": "Execute Psalm static analysis for advanced type inference, purity checking, and security validation", - "test:rector": "Analyse code for modernisation opportunities and PHP 8.3+ feature adoption using Rector rules", + "test:rector": "Analyse code for modernisation opportunities and PHP 8.4+ feature adoption using Rector rules", "test:vulnerabilities-check": "Scan all dependencies for known CVE vulnerabilities and security advisories using Enlightn Security Checker", "fix:code-style": "Automatically fix code style issues with Pint", "fix:rector": "Apply Rector refactorings to improve code quality", diff --git a/docs/_config.yml b/docs/_config.yml index 24015a4..e37fedf 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,6 +1,6 @@ # Site settings title: StringManipulation -description: High-performance PHP 8.3+ string manipulation library featuring O(n) algorithms with up to 5x speed improvements +description: High-performance PHP 8.4+ string manipulation library featuring O(n) algorithms with up to 5x speed improvements baseurl: "/StringManipulation" url: "https://marjovanlier.github.io" diff --git a/docs/contributing.md b/docs/contributing.md index e128948..871c37d 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -24,7 +24,7 @@ We welcome contributions to the StringManipulation library! Whether you're fixin ### Prerequisites -- PHP 8.3 or later +- PHP 8.4 or later - Docker and Docker Compose (recommended for testing) - Git - Composer @@ -84,7 +84,7 @@ Use descriptive branch names: ### PHP Standards - **Strict typing**: All files must include `declare(strict_types=1);` -- **PHP 8.3+**: Use modern PHP features +- **PHP 8.4+**: Use modern PHP features - **PSR-4 autoloading**: Follow namespace conventions - **Final classes**: Prefer final classes with static methods - **Typed parameters**: Always use explicit type declarations diff --git a/docs/getting-started.md b/docs/getting-started.md index dd6fb92..15ac826 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -28,7 +28,7 @@ composer require marjovanlier/stringmanipulation ### Requirements -- **PHP 8.3+** with strict typing +- **PHP 8.4+** with strict typing - **mbstring extension** for multi-byte string operations - **intl extension** for internationalisation support diff --git a/docs/index.md b/docs/index.md index 0185f18..dcf44bd 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,14 +2,14 @@ layout: default title: Home nav_order: 1 -description: "High-performance PHP 8.3+ string manipulation library featuring O(n) algorithms with up to 5x speed improvements" +description: "High-performance PHP 8.4+ string manipulation library featuring O(n) algorithms with up to 5x speed improvements" permalink: / --- # StringManipulation {: .fs-9 } -High-performance PHP 8.3+ string manipulation library featuring O(n) algorithms with up to 5x speed improvements. +High-performance PHP 8.4+ string manipulation library featuring O(n) algorithms with up to 5x speed improvements. {: .fs-6 .fw-300 } [Get Started]({{ site.baseurl }}/getting-started){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 } @@ -19,7 +19,7 @@ High-performance PHP 8.3+ string manipulation library featuring O(n) algorithms ## Overview -The **StringManipulation** library is a toolkit designed for complex and efficient string handling in PHP 8.3+. Following a recent suite of O(n) optimisations, the library delivers **2-5x faster performance**, making it one of the most powerful and reliable solutions for developers who require speed and precision. +The **StringManipulation** library is a toolkit designed for complex and efficient string handling in PHP 8.4+. Following a recent suite of O(n) optimisations, the library delivers **2-5x faster performance**, making it one of the most powerful and reliable solutions for developers who require speed and precision. ### Key Features @@ -92,7 +92,7 @@ Methods like `searchWords()` perform all transformations in a single pass, minim ## System Requirements -- PHP 8.3 or later (strict typing enabled) +- PHP 8.4 or later (strict typing enabled) - `mbstring` extension for multi-byte string operations - `intl` extension for internationalisation and advanced Unicode support diff --git a/phpstan.neon b/phpstan.neon index 72fcab1..e80344f 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,7 +3,7 @@ parameters: paths: - src/ tmpDir: .phpstan - phpVersion: 80300 + phpVersion: 80400 treatPhpDocTypesAsCertain: false tipsOfTheDay: false reportWrongPhpDocTypeInVarTag: true diff --git a/rector.php b/rector.php index 94cafe8..3b123b3 100644 --- a/rector.php +++ b/rector.php @@ -20,9 +20,9 @@ TypedPropertyFromAssignsRector::class, AddVoidReturnTypeWhereNoReturnRector::class, ]) - ->withPhpVersion(PhpVersion::PHP_83) + ->withPhpVersion(PhpVersion::PHP_84) ->withSets([ - LevelSetList::UP_TO_PHP_83, + LevelSetList::UP_TO_PHP_84, SetList::CODING_STYLE, SetList::EARLY_RETURN, SetList::INSTANCEOF, diff --git a/src/StringManipulation.php b/src/StringManipulation.php index d93f750..8d847de 100644 --- a/src/StringManipulation.php +++ b/src/StringManipulation.php @@ -228,7 +228,7 @@ public static function strReplace(array|string $search, array|string $replace, s } // Optimize single character replacements using strtr which is faster for this case - if (is_string($search) && is_string($replace) && strlen($search) === 1) { + if (\is_string($search) && \is_string($replace) && \strlen($search) === 1) { return strtr($subject, [$search => $replace]); } diff --git a/tests/Benchmark/RemoveAccentsComplexityBenchmark.php b/tests/Benchmark/RemoveAccentsComplexityBenchmark.php index b3b4050..9d2a10d 100644 --- a/tests/Benchmark/RemoveAccentsComplexityBenchmark.php +++ b/tests/Benchmark/RemoveAccentsComplexityBenchmark.php @@ -40,22 +40,27 @@ public static function run(): void $previousTime = null; $previousLength = null; + $checksum = 0; foreach (self::LENGTHS as $length) { $testString = self::makeString($length); + $result = ''; // Warmup for ($i = 0; $i < self::WARMUP; ++$i) { - StringManipulation::removeAccents($testString); + $result = StringManipulation::removeAccents($testString); } $start = microtime(true); for ($i = 0; $i < self::ITERATIONS; ++$i) { - StringManipulation::removeAccents($testString); + $result = StringManipulation::removeAccents($testString); } $duration = microtime(true) - $start; + // Consume the result so the pure calls cannot be optimised away. + $checksum += strlen($result); + $durationMs = $duration * 1000.0; $opsPerSec = (float) self::ITERATIONS / $duration; $usPerOp = ($duration * 1_000_000.0) / (float) self::ITERATIONS; @@ -80,6 +85,8 @@ public static function run(): void $previousLength = $length; } + echo "\nChecksum (prevents dead-code elimination): " . (string) $checksum . "\n"; + echo "\nInterpretation:\n"; echo "- If complexity is O(n), time should scale linearly with input size\n"; echo "- Actual ratio should be close to expected ratio\n"; @@ -92,7 +99,7 @@ public static function run(): void */ private static function makeString(int $length): string { - $string = str_repeat(self::BASE, (int) ceil($length / strlen(self::BASE))); + $string = str_repeat(self::BASE, max(0, (int) ceil($length / strlen(self::BASE)))); return substr($string, 0, $length); } }