{"id":16266143,"url":"https://github.com/z4kn4fein/php-semver","last_synced_at":"2025-03-15T11:31:47.520Z","repository":{"id":57088980,"uuid":"230145275","full_name":"z4kn4fein/php-semver","owner":"z4kn4fein","description":"Semantic Versioning library for PHP.","archived":false,"fork":false,"pushed_at":"2024-04-25T18:01:11.000Z","size":170,"stargazers_count":15,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-04-25T19:24:40.824Z","etag":null,"topics":["php","php-library","semantic-versioning","semver","semver-convention","semver-parser"],"latest_commit_sha":null,"homepage":"https://z4kn4fein.github.io/php-semver","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/z4kn4fein.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-12-25T19:31:10.000Z","updated_at":"2024-04-25T19:24:42.708Z","dependencies_parsed_at":"2023-01-22T15:15:27.964Z","dependency_job_id":"77cd2f37-8bcc-420d-80d6-1d4dd81c4109","html_url":"https://github.com/z4kn4fein/php-semver","commit_stats":{"total_commits":53,"total_committers":3,"mean_commits":"17.666666666666668","dds":0.07547169811320753,"last_synced_commit":"ac804a2b4b9664bb83e3009870ac7a97b3df5f32"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z4kn4fein%2Fphp-semver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z4kn4fein%2Fphp-semver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z4kn4fein%2Fphp-semver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/z4kn4fein%2Fphp-semver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/z4kn4fein","download_url":"https://codeload.github.com/z4kn4fein/php-semver/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243724966,"owners_count":20337655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["php","php-library","semantic-versioning","semver","semver-convention","semver-parser"],"created_at":"2024-10-10T17:22:00.747Z","updated_at":"2025-03-15T11:31:47.238Z","avatar_url":"https://github.com/z4kn4fein.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# php-semver\n[![Build Status](https://github.com/z4kn4fein/php-semver/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/z4kn4fein/php-semver/actions/workflows/ci.yml)\n[![Latest Stable Version](https://poser.pugx.org/z4kn4fein/php-semver/version)](https://packagist.org/packages/z4kn4fein/php-semver)\n[![Total Downloads](https://poser.pugx.org/z4kn4fein/php-semver/downloads)](https://packagist.org/packages/z4kn4fein/php-semver)\n[![Sonar Quality Gate](https://img.shields.io/sonar/quality_gate/z4kn4fein_php-semver?logo=sonarcloud\u0026server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/project/overview?id=z4kn4fein_php-semver)\n[![Sonar Coverage](https://img.shields.io/sonar/coverage/z4kn4fein_php-semver?logo=SonarCloud\u0026server=https%3A%2F%2Fsonarcloud.io)](https://sonarcloud.io/project/overview?id=z4kn4fein_php-semver)\n\nSemantic Versioning library for PHP. It implements the full [semantic version 2.0.0](https://semver.org/spec/v2.0.0.html) specification and\nprovides ability to **parse**, **compare**, and **increment** semantic versions along with validation against **constraints**.\n\n## Requirements\n| Version       | PHP Version |\n|---------------|-------------|\n| `\u003e=1.0, \u003c1.2` | \u003e=5.5       |\n| `\u003e=1.2, \u003c3.0` | \u003e=7.1       |\n| `\u003e=3.0`       | \u003e=8.1       |\n\n\n## Install with [Composer](https://getcomposer.org/)\n```shell\ncomposer require z4kn4fein/php-semver\n```\n\n## Usage\nThe following options are supported to construct a `Version`:\n1. Building part by part with `Version::create()`.\n\n   ```php\n   Version::create(3, 5, 2, \"alpha\", \"build\");\n   ```\n\n2. Parsing from a string with `Version::parse()` or `Version::parseOrNull()`.\n\n   ```php\n   Version::parse(\"3.5.2-alpha+build\");\n   ```\n\nThe following information is accessible on a constructed `Version` object:\n```php\n\u003c?php\n\nuse z4kn4fein\\SemVer\\Version;\n\n$version = Version::parse(\"2.5.6-alpha.12+build.34\");\n\necho $version-\u003egetMajor();         // 2\necho $version-\u003egetMinor();         // 5\necho $version-\u003egetPatch();         // 6\necho $version-\u003egetPreRelease();    // alpha.12\necho $version-\u003egetBuildMeta();     // build.34\necho $version-\u003eisPreRelease();     // true\necho $version-\u003eisStable();         // false\necho $version-\u003ewithoutSuffixes();  // 2.5.6\necho $version;                     // 2.5.6-alpha.12+build.34\n```\n\n### Strict vs. Loose Parsing\nBy default, the version parser considers partial versions like `1.0` and versions starting with the `v` prefix invalid.\nThis behaviour can be turned off by setting the `strict` parameter to `false`.\n```php\necho Version::parse(\"v2.3-alpha\");             // exception\necho Version::parse(\"2.1\");                    // exception\necho Version::parse(\"v3\");                     // exception\n\necho Version::parse(\"v2.3-alpha\", false);      // 2.3.0-alpha\necho Version::parse(\"2.1\", false);             // 2.1.0\necho Version::parse(\"v3\", false);              // 3.0.0\n```\n\n## Compare\nIt is possible to compare two `Version` objects with the following comparison methods.\n```php\n\u003c?php\n\nuse z4kn4fein\\SemVer\\Version;\n\n// with static methods\necho Version::lessThan(\"2.3.4\", \"2.4.1\");                            // true\necho Version::lessThanOrEqual(\"2.4.1\", \"2.4.1\");                     // true\necho Version::greaterThan(\"2.3.1-alpha.5\", \"2.3.1-alpha.3\");         // true\necho Version::greaterThanOrEqual(\"3.2.3\",\"3.2.2\");                   // true\necho Version::equal(\"3.2.3\",\"3.2.3+build.3\");                        // true\necho Version::notEqual(\"3.2.3\",\"2.2.4\");                             // true\n\n// compare() or compareString()\necho Version::compare(Version::parse(\"2.3.4\"), Version::parse(\"2.4.1\"));  // -1\necho Version::compare(Version::parse(\"2.3.4\"), Version::parse(\"2.3.4\"));  // 0\necho Version::compare(Version::parse(\"2.3.4\"), Version::parse(\"2.2.0\"));  // 1\n\necho Version::compareString(\"2.3.4\", \"2.4.1\");                            // -1\necho Version::compareString(\"2.3.4\", \"2.3.4\");                            // 0\necho Version::compareString(\"2.3.4\", \"2.2.0\");                            // 1\n\n\n// with instance methods\n$version = Version::parse(\"2.5.6-alpha.12+build.34\");\n\necho $version-\u003eisLessThan(Version::parse(\"2.3.1\"));                  // false\necho $version-\u003eisLessThanOrEqual(Version::parse(\"2.5.6-alpha.15\"));  // true\necho $version-\u003eisGreaterThan(Version::parse(\"2.5.6\"));               // false\necho $version-\u003eisLessThanOrEqual(Version::parse(\"2.5.6-alpha.12\"));  // true\necho $version-\u003eisEqual(Version::parse(\"2.5.6-alpha.12+build.56\"));   // true\necho $version-\u003eisNotEqual(Version::parse(\"2.2.4\"));                  // true\n```\n\n### Sort\n\n`Version::sort()` and `Version::sortString()` are available to sort an array of versions.\n```php\n\u003c?php\n\nuse z4kn4fein\\SemVer\\Version;\n\n$versions = array_map(function(string $version) {\n    return Version::parse($version);\n}, [\n    \"1.0.1\",\n    \"1.0.1-alpha\",\n    \"1.0.1-alpha.beta\",\n    \"1.0.1-alpha.3\",\n    \"1.0.1-alpha.2\",\n    \"1.1.0\",\n    \"1.1.0+build\",\n]);\n\n$sorted = Version::sort($versions);\n\n// The result:\n//   \"1.0.1-alpha\"\n//   \"1.0.1-alpha.2\"\n//   \"1.0.1-alpha.3\"\n//   \"1.0.1-alpha.beta\"\n//   \"1.0.1\"\n//   \"1.1.0\"\n//   \"1.1.0+build\"\n```\n\nYou might want to sort in reverse order, then you can use `Version::rsort()` or `Version::rsortString()`.\n```php\n\u003c?php\n\nuse z4kn4fein\\SemVer\\Version;\n\n$versions = array_map(function(string $version) {\n    return Version::parse($version);\n}, [\n    \"1.0.1\",\n    \"1.0.1-alpha\",\n    \"1.0.1-alpha.beta\",\n    \"1.0.1-alpha.3\",\n    \"1.0.1-alpha.2\",\n    \"1.1.0\",\n    \"1.1.0+build\",\n]);\n\n$sorted = Version::rsort($versions);\n\n// The result:\n//   \"1.1.0\"\n//   \"1.1.0+build\"\n//   \"1.0.1\"\n//   \"1.0.1-alpha.beta\"\n//   \"1.0.1-alpha.3\"\n//   \"1.0.1-alpha.2\"\n//   \"1.0.1-alpha\"\n```\n\n`Version::compare()` and `Version::compareString()` methods also can be used as callback for `usort()` to sort an array of versions.\n```php\n\u003c?php\n\nuse z4kn4fein\\SemVer\\Version;\n\n$versions = array_map(function(string $version) {\n    return Version::parse($version);\n}, [\n    \"1.0.1\",\n    \"1.0.1-alpha\",\n    \"1.0.1-alpha.beta\",\n    \"1.0.1-alpha.3\",\n    \"1.0.1-alpha.2\",\n    \"1.1.0\",\n    \"1.1.0+build\",\n]);\n\nusort($versions, [\"z4kn4fein\\SemVer\\Version\", \"compare\"]);\n\n// The result:\n//   \"1.0.1-alpha\"\n//   \"1.0.1-alpha.2\"\n//   \"1.0.1-alpha.3\"\n//   \"1.0.1-alpha.beta\"\n//   \"1.0.1\"\n//   \"1.1.0\"\n//   \"1.1.0+build\"\n```\n\n## Constraints\nWith constraints, it's possible to validate whether a version satisfies a set of rules or not.\nA constraint can be described as one or more conditions combined with logical `OR` and `AND` operators.\n\n### Conditions\nConditions are usually composed of a comparison operator and a version like `\u003e=1.2.0`.\nThe condition `\u003e=1.2.0` would be met by any version that greater than or equal to `1.2.0`.\n\nSupported comparison operators:\n- `=` Equal (equivalent to no operator: `1.2.0` means `=1.2.0`)\n- `!=` Not equal\n- `\u003c` Less than\n- `\u003c=` Less than or equal\n- `\u003e` Greater than\n- `\u003e=` Greater than or equal\n\nConditions can be joined together with whitespace, representing the `AND` logical operator between them.\nThe `OR` operator can be expressed with `||` or `|` between condition sets.\n\nFor example, the constraint `\u003e=1.2.0 \u003c3.0.0 || \u003e4.0.0` translates to: *Only those versions are allowed that are either greater than or\nequal to `1.2.0` {**AND**} less than `3.0.0` {**OR**} greater than `4.0.0`*.\n\nWe can notice that the first part of the previous constraint (`\u003e=1.2.0 \u003c3.0.0`) is a simple semantic version range.\nThere are more ways to express version ranges; the following section will go through all the available options.\n\n### Range Conditions\nThere are particular range indicators which are sugars for more extended range expressions.\n\n- **X-Range**: The `x`, `X`, and `*` characters can be used as a wildcard for the numeric parts of a version.\n   - `1.2.x` translates to `\u003e=1.2.0 \u003c1.3.0-0`\n   - `1.x` translates to `\u003e=1.0.0 \u003c2.0.0-0`\n   - `*` translates to `\u003e=0.0.0`\n\n  In partial version expressions, the missing numbers are treated as wildcards.\n   - `1.2` means `1.2.x` which finally translates to `\u003e=1.2.0 \u003c1.3.0-0`\n   - `1` means `1.x` or `1.x.x` which finally translates to `\u003e=1.0.0 \u003c2.0.0-0`\n\n- **Hyphen Range**: Describes an inclusive version range. Wildcards are evaluated and taken into account in the final range.\n   - `1.0.0 - 1.2.0` translates to `\u003e=1.0.0 \u003c=1.2.0`\n   - `1.1 - 1.4.0` means `\u003e=(\u003e=1.1.0 \u003c1.2.0-0) \u003c=1.4.0` which finally translates to `\u003e=1.1.0 \u003c=1.4.0`\n   - `1.1.0 - 2` means `\u003e=1.1.0 \u003c=(\u003e=2.0.0 \u003c3.0.0-0)` which finally translates to `\u003e=1.1.0 \u003c3.0.0-0`\n\n- **Tilde Range (`~`)**: Describes a patch level range when the minor version is specified or a minor level range when it's not.\n   - `~1.0.1` translates to `\u003e=1.0.1 \u003c1.1.0-0`\n   - `~1.0` translates to `\u003e=1.0.0 \u003c1.1.0-0`\n   - `~1` translates to `\u003e=1.0.0 \u003c2.0.0-0`\n   - `~1.0.0-alpha.1` translates to `\u003e=1.0.1-alpha.1 \u003c1.1.0-0`\n\n- **Caret Range (`^`)**: Describes a range with regard to the most left non-zero part of the version.\n   - `^1.1.2` translates to `\u003e=1.1.2 \u003c2.0.0-0`\n   - `^0.1.2` translates to `\u003e=0.1.2 \u003c0.2.0-0`\n   - `^0.0.2` translates to `\u003e=0.0.2 \u003c0.0.3-0`\n   - `^1.2` translates to `\u003e=1.2.0 \u003c2.0.0-0`\n   - `^1` translates to `\u003e=1.0.0 \u003c2.0.0-0`\n   - `^0.1.2-alpha.1` translates to `\u003e=0.1.2-alpha.1 \u003c0.2.0-0`\n\n### Validation\nLet's see how we can determine whether a version satisfies a constraint or not.\n```php\n\u003c?php\n\nuse z4kn4fein\\SemVer\\Version;\nuse z4kn4fein\\SemVer\\Constraints\\Constraint;\n\n$constraint = Constraint::parse(\"\u003e=1.2.0\");\n$version = Version::parse(\"1.2.1\");\n\necho $version-\u003eisSatisfying($constraint);     // true\necho $constraint-\u003eisSatisfiedBy($version);    // true\n\n// Or using the static satisfies() method with strings:\necho Version::satisfies(\"1.2.1\", \"\u003e=1.2.0\");  // true\n```\n\n## Increment\n`Version` objects can produce incremented versions of themselves with the `getNext{Major|Minor|Patch|PreRelease}Version` methods.\nThese methods can be used to determine the next version in order incremented by the according part.\n`Version` objects are **immutable**, so each incrementing function creates a new `Version`.\n\nThis example shows how the incrementation works on a stable version:\n```php\n\u003c?php\n\nuse z4kn4fein\\SemVer\\Version;\nuse z4kn4fein\\SemVer\\Inc;\n\n$stableVersion = Version::create(1, 0, 0);\n\necho $stableVersion-\u003egetNextMajorVersion();        // 2.0.0\necho $stableVersion-\u003egetNextMinorVersion();        // 1.1.0\necho $stableVersion-\u003egetNextPatchVersion();        // 1.0.1\necho $stableVersion-\u003egetNextPreReleaseVersion();   // 1.0.1-0\n\n// or with the inc() method:\necho $stableVersion-\u003einc(Inc::MAJOR);              // 2.0.0\necho $stableVersion-\u003einc(Inc::MINOR);              // 1.1.0\necho $stableVersion-\u003einc(Inc::PATCH);              // 1.0.1\necho $stableVersion-\u003einc(Inc::PRE_RELEASE);        // 1.0.1-0\n```\n\nIn case of an unstable version:\n```php\n\u003c?php\n\nuse z4kn4fein\\SemVer\\Version;\nuse z4kn4fein\\SemVer\\Inc;\n\n$unstableVersion = Version::parce(\"1.0.0-alpha.2+build.1\");\n\necho $unstableVersion-\u003egetNextMajorVersion();        // 2.0.0\necho $unstableVersion-\u003egetNextMinorVersion();        // 1.1.0\necho $unstableVersion-\u003egetNextPatchVersion();        // 1.0.0\necho $unstableVersion-\u003egetNextPreReleaseVersion();   // 1.0.0-alpha.3\n\n// or with the inc() method:\necho $unstableVersion-\u003einc(Inc::MAJOR);              // 2.0.0\necho $unstableVersion-\u003einc(Inc::MINOR);              // 1.1.0\necho $unstableVersion-\u003einc(Inc::PATCH);              // 1.0.0\necho $unstableVersion-\u003einc(Inc::PRE_RELEASE);        // 1.0.0-alpha.3\n```\n\nEach incrementing function provides the option to set a pre-release identity on the incremented version.\n```php\n\u003c?php\n\nuse z4kn4fein\\SemVer\\Version;\nuse z4kn4fein\\SemVer\\Inc;\n\n$version = Version::parce(\"1.0.0-alpha.1\");\n\necho $version-\u003egetNextMajorVersion(\"beta\");         // 2.0.0-beta\necho $version-\u003egetNextMinorVersion(\"\");             // 1.1.0-0\necho $version-\u003egetNextPatchVersion(\"alpha\");        // 1.0.1-alpha\necho $version-\u003egetNextPreReleaseVersion(\"alpha\");   // 1.0.0-alpha.2\n\n// or with the inc() method:\necho $version-\u003einc(Inc::MAJOR, \"beta\");             // 2.0.0-beta\necho $version-\u003einc(Inc::MINOR, \"\");                 // 1.1.0-0\necho $version-\u003einc(Inc::PATCH, \"alpha\");            // 1.0.1-alpha\necho $version-\u003einc(Inc::PRE_RELEASE, \"alpha\");      // 1.0.0-alpha.2\n```\n\n## Copy\nIt's possible to make a copy of a particular version with the `copy()` method.\nIt allows altering the copied version's properties with optional parameters.\n```php\n$version = Version::parse(\"1.0.0-alpha.2+build.1\");\n\necho $version-\u003ecopy();                                        // 1.0.0-alpha.2+build.1\necho $version-\u003ecopy(3);                                       // 3.0.0-alpha.2+build.1\necho $version-\u003ecopy(null, 4);                                 // 1.4.0-alpha.2+build.1\necho $version-\u003ecopy(null, null, 5);                           // 1.0.5-alpha.2+build.1\necho $version-\u003ecopy(null, null, null, \"alpha.4\");             // 1.0.0-alpha.4+build.1\necho $version-\u003ecopy(null, null, null, null, \"build.3\");       // 1.0.0-alpha.2+build.3\necho $version-\u003ecopy(3, 4, 5);                                 // 3.4.5-alpha.2+build.1\n```\n\u003e [!NOTE]\\\n\u003e Without setting any optional parameter, the `copy()` method will produce an exact copy of the original version.\n\n## Invalid version handling\nWhen the version or constraint parsing fails due to an invalid format, the library throws a specific `SemverException`.\n\u003e [!NOTE]\\\n\u003e The `Version::parseOrNull()` and `Constraint::parseOrNull()` methods can be used for exception-less conversions as they return `null` when the parsing fails.\n\n## Contact \u0026 Support\n- Create an [issue](https://github.com/z4kn4fein/php-semver/issues) for bug reports and feature requests.\n- Start a [discussion](https://github.com/z4kn4fein/php-semver/discussions) for your questions and ideas.\n- Add a ⭐️ to support the project!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fz4kn4fein%2Fphp-semver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fz4kn4fein%2Fphp-semver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fz4kn4fein%2Fphp-semver/lists"}