[GH-ISSUE #472] semver and PHP version_compare() #7320

Closed
opened 2026-06-20 17:18:35 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @phil-davis on GitHub (Oct 29, 2018).
Original GitHub issue: https://github.com/semver/semver/issues/472

I didn't see anyone mention or ask about this, so I think it is worth asking the question and getting the answer.

http://php.net/manual/en/function.version-compare.php has specific text parts of its version scheme that sort in the order dev->alpha->beta->rc->#->pl (whatever pl is)

and semver:

  1. sorts in strictly ASCII order for text, e.g. alpha->beta->dev->rc (if you happen to use those 4 strings in your development/release process)

  2. sorts numeric first, followed by text, so if you do put numbers at position 4 then the order would be like 2.0.0.1->2.0.0.2->2.0.0.alpha->2.0.0.beta->2.0.0.rc->2.0.0

So PHP version_compare() is a different ordering than semver, across the full range of version strings that are valid in both systems.

By restricting your project to using, for example, numeric at position 1,2,3 then just alpha->beta->rc at position 4 and some numeric after that "alpha.1" etc, then such a chosen subset of possible semver strings can have the same ordering by PHP version_compare() and by semver.

Yes?

Originally created by @phil-davis on GitHub (Oct 29, 2018). Original GitHub issue: https://github.com/semver/semver/issues/472 I didn't see anyone mention or ask about this, so I think it is worth asking the question and getting the answer. http://php.net/manual/en/function.version-compare.php has specific text parts of its version scheme that sort in the order dev->alpha->beta->rc->#->pl (whatever pl is) and semver: 1) sorts in strictly ASCII order for text, e.g. alpha->beta->dev->rc (if you happen to use those 4 strings in your development/release process) 2) sorts numeric first, followed by text, so if you do put numbers at position 4 then the order would be like 2.0.0.1->2.0.0.2->2.0.0.alpha->2.0.0.beta->2.0.0.rc->2.0.0 So PHP ``version_compare()`` is a different ordering than semver, across the full range of version strings that are valid in both systems. By restricting your project to using, for example, numeric at position 1,2,3 then just alpha->beta->rc at position 4 and some numeric after that "alpha.1" etc, then such a chosen subset of possible semver strings can have the same ordering by PHP ``version_compare()`` and by semver. Yes?
Author
Owner

@klehelley commented on GitHub (Oct 30, 2018):

First, all of the versions you list in point 2, with the exception of 2.0.0, are not valid SemVer strings. But if you replace the last dot with an hyphen in the invalid version strings (2.0.0.1 -> 2.0.0-1) they become compliant with SemVer and the order you've put them in is indeed how the precedence works as described in rule 11 of the specification.

Reading the behaviour of the version_compare() function of PHP, to be able to use it with SemVer strings you have to work with a subset of the valid versions according to the SemVer specification :

  • If one of the two versions to compare is 1.0.0+20181030, the part that should be compared according to SemVer is 1.0.0 (build metadata is not used for precedence), but version_compare() interprets it as 1.0.0.20181030 => build metadata cannot be used
  • Versions 1.0.0-a and 1.0.0-alpha are different according to Semver, but equivalent according to version_compare() => for the few equivalent strings documented, only one of them must used and the other should never appear
  • According to SemVer, you have 1.0.0-a2 < 1.0.0-a.1, but for version_compare() it is the opposite as 1.0.0-a2 is equivalent to 1.0.0-a.2 => you cannot mix digits with the alphabetical and symbol characters
  • With SemVer pure numeric pre-release parts have lower precedence than alphanumeric parts, thus 1.0.0-1 < 1.0.0-b, but with version_compare() a pure numeric part has higher precedence unless it is compared with pl or p, so here it considers that 1.0.0-1 > 1.0.0-b => pure numeric and alphanumeric parts should not happen in the same place in two version numbers

I may not have covered all the differences, but this seems to be kind of a hassle, as you have additional rules to remember to apply to your versioning strategy. If you really want to compare SemVer strings, I'd advise using one of the available PHP libraries instead of relying on version_compare().

<!-- gh-comment-id:434219908 --> @klehelley commented on GitHub (Oct 30, 2018): First, all of the versions you list in point 2, with the exception of `2.0.0`, are _not_ valid SemVer strings. But if you replace the last dot with an hyphen in the invalid version strings (`2.0.0.1` -> `2.0.0-1`) they become compliant with SemVer and the order you've put them in is indeed how the precedence works as described in rule 11 of the specification. Reading the behaviour of the `version_compare()` function of PHP, to be able to use it with SemVer strings you have to work with a subset of the valid versions according to the SemVer specification : * If one of the two versions to compare is `1.0.0+20181030`, the part that should be compared according to SemVer is `1.0.0` (build metadata is not used for precedence), but `version_compare()` interprets it as `1.0.0.20181030` => build metadata cannot be used * Versions `1.0.0-a` and `1.0.0-alpha` are different according to Semver, but equivalent according to `version_compare()` => for the few equivalent strings documented, only one of them must used and the other should never appear * According to SemVer, you have `1.0.0-a2` < `1.0.0-a.1`, but for `version_compare()` it is the opposite as `1.0.0-a2` is equivalent to `1.0.0-a.2` => you cannot mix digits with the alphabetical and symbol characters * With SemVer pure numeric pre-release parts have lower precedence than alphanumeric parts, thus `1.0.0-1` < `1.0.0-b`, but with `version_compare()` a pure numeric part has higher precedence unless it is compared with `pl` or `p`, so here it considers that `1.0.0-1` > `1.0.0-b` => pure numeric and alphanumeric parts should not happen in the same place in two version numbers I may not have covered all the differences, but this seems to be kind of a hassle, as you have additional rules to remember to apply to your versioning strategy. If you really want to compare SemVer strings, I'd advise using one of the available PHP libraries instead of relying on `version_compare()`.
Author
Owner

@phil-davis commented on GitHub (Oct 30, 2018):

Thanks for the response, I wanted to confirm what I was thinking and maybe also help others in future who look at PHP version_compare() and are trying to think through the differences.

And I missed the detail about 1.2.3.alpha not valid and 1.2.3-alpha is valid.

<!-- gh-comment-id:434222361 --> @phil-davis commented on GitHub (Oct 30, 2018): Thanks for the response, I wanted to confirm what I was thinking and maybe also help others in future who look at PHP ``version_compare()`` and are trying to think through the differences. And I missed the detail about 1.2.3.alpha not valid and 1.2.3-alpha is valid.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/semver#7320