diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f0f380..54ebd13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. * Remove dependency on ramsey/collection package. +## Unreleased + +### Fixed + +* Hexadecimal is never an empty string; fixed in [#593](https://github.com/ramsey/uuid/pull/593). +* Update call to `str_getcsv()` to avoid deprecation notice in PHP 8.4; fixed in [#590](https://github.com/ramsey/uuid/pull/590). +* Update docblocks for `Uuid::fromBytes()`, `Uuid::fromString()`, `Uuid::fromDateTime()`, `Uuid::fromHexadecimal()`, and `Uuid::fromInteger()` to note that each can throw `InvalidArgumentException`, addressing PHPStan errors occurring at call sites; fixed in [#552](https://github.com/ramsey/uuid/pull/552). + +### Deprecated + +The following will be removed in ramsey/uuid 5.0.0: + +* `Ramsey\Uuid\Codec\OrderedTimeCodec` is deprecated; please migrate to [version 6 UUIDs](https://uuid.ramsey.dev/en/stable/rfc4122/version6.html). +* `Ramsey\Uuid\Codec\TimestampFirstCombCodec` is deprecated; please migrate to [version 7 UUIDs](https://uuid.ramsey.dev/en/stable/rfc4122/version7.html). +* `Ramsey\Uuid\Codec\TimestampLastCombCodec` is deprecated; please use `Ramsey\Uuid\Codec\StringCodec` instead. +* `Ramsey\Uuid\Generator\CombGenerator` is deprecated; please migrate to [version 7 UUIDs](https://uuid.ramsey.dev/en/stable/rfc4122/version7.html). + ## 4.7.6 - 2024-04-27 ### Fixed diff --git a/src/BinaryUtils.php b/src/BinaryUtils.php index e730f04..1a96985 100644 --- a/src/BinaryUtils.php +++ b/src/BinaryUtils.php @@ -27,43 +27,37 @@ use function unpack; class BinaryUtils { /** - * Applies the RFC 4122 variant field to the 16-bit clock sequence + * Applies the variant field to the 16-bit clock sequence * - * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant + * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field * - * @param int $clockSeq The 16-bit clock sequence value before the RFC 4122 - * variant is applied + * @param int $clockSeq The 16-bit clock sequence value before the variant is applied * * @return int The 16-bit clock sequence multiplexed with the UUID variant */ - public static function applyVariant(int $clockSeq, Variant $variant = Variant::Rfc4122): int + public static function applyVariant(int $clockSeq, Variant $variant = Variant::Rfc9562): int { return match ($variant) { Variant::ReservedNcs => $clockSeq & 0x7fff, - Variant::Rfc4122 => $clockSeq & 0x3fff | 0x8000, + Variant::Rfc9562 => $clockSeq & 0x3fff | 0x8000, Variant::ReservedMicrosoft => $clockSeq & 0x1fff | 0xc000, Variant::ReservedFuture => $clockSeq & 0x1fff | 0xe000, }; } /** - * Applies the RFC 4122 version number to the 16-bit `time_hi_and_version` field + * Applies the version field to the 16-bit `time_hi_and_version` field * - * @link http://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version + * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field * - * @param int $timeHi The value of the 16-bit `time_hi_and_version` field - * before the RFC 4122 version is applied - * @param Version $version The RFC 4122 version to apply to the `time_hi` field + * @param int $timeHi The value of the 16-bit `time_hi_and_version` field before the version is applied + * @param Version $version The version to apply to the `time_hi` field * - * @return int The 16-bit time_hi field of the timestamp multiplexed with - * the UUID version number + * @return int The 16-bit time_hi field of the timestamp multiplexed with the UUID version number */ public static function applyVersion(int $timeHi, Version $version): int { - $timeHi = $timeHi & 0x0fff; - $timeHi |= $version->value << 12; - - return $timeHi; + return ($timeHi & 0x0fff) | ($version->value << 12); } /** @@ -80,7 +74,7 @@ class BinaryUtils public static function applyVersionAndVariant( string $bytes, Version $version, - Variant $variant = Variant::Rfc4122 + Variant $variant = Variant::Rfc9562, ): string { /** @var int[] $unpackedTime */ $unpackedTime = unpack('n*', substr($bytes, 6, 2)); diff --git a/src/Builder/FallbackBuilder.php b/src/Builder/FallbackBuilder.php index 4496e23..8c45e42 100644 --- a/src/Builder/FallbackBuilder.php +++ b/src/Builder/FallbackBuilder.php @@ -20,8 +20,7 @@ use Ramsey\Uuid\Exception\UnableToBuildUuidException; use Ramsey\Uuid\UuidInterface; /** - * FallbackBuilder builds a UUID by stepping through a list of UUID builders - * until a UUID can be constructed without exceptions + * FallbackBuilder builds a UUID by stepping through a list of UUID builders until a UUID can be constructed without exceptions * * @immutable */ @@ -35,8 +34,7 @@ class FallbackBuilder implements UuidBuilderInterface } /** - * Builds and returns a UuidInterface instance using the first builder that - * succeeds + * Builds and returns a UuidInterface instance using the first builder that succeeds * * @param CodecInterface $codec The codec to use for building this instance * @param non-empty-string $bytes The byte string from which to construct a UUID @@ -60,7 +58,7 @@ class FallbackBuilder implements UuidBuilderInterface throw new BuilderNotFoundException( 'Could not find a suitable builder for the provided codec and fields', 0, - $lastBuilderException + $lastBuilderException, ); } } diff --git a/src/Builder/UuidBuilderInterface.php b/src/Builder/UuidBuilderInterface.php index fb5d341..7c46ef3 100644 --- a/src/Builder/UuidBuilderInterface.php +++ b/src/Builder/UuidBuilderInterface.php @@ -30,8 +30,7 @@ interface UuidBuilderInterface * @param CodecInterface $codec The codec to use for building this UuidInterface instance * @param non-empty-string $bytes The byte string from which to construct a UUID * - * @return UuidInterface Implementations may choose to return more specific - * instances of UUIDs that implement UuidInterface + * @return UuidInterface Implementations may choose to return more specific instances of UUIDs that implement UuidInterface */ public function build(CodecInterface $codec, string $bytes): UuidInterface; } diff --git a/src/Codec/CodecInterface.php b/src/Codec/CodecInterface.php index 6def8cd..2dd706b 100644 --- a/src/Codec/CodecInterface.php +++ b/src/Codec/CodecInterface.php @@ -26,8 +26,7 @@ interface CodecInterface /** * Returns a hexadecimal string representation of a UuidInterface * - * @param UuidInterface $uuid The UUID for which to create a hexadecimal - * string representation + * @param UuidInterface $uuid The UUID for which to create a hexadecimal string representation * * @return non-empty-string Hexadecimal string representation of a UUID */ @@ -36,8 +35,7 @@ interface CodecInterface /** * Returns a binary string representation of a UuidInterface * - * @param UuidInterface $uuid The UUID for which to create a binary string - * representation + * @param UuidInterface $uuid The UUID for which to create a binary string representation * * @return non-empty-string Binary string representation of a UUID */ @@ -46,22 +44,18 @@ interface CodecInterface /** * Returns a UuidInterface derived from a hexadecimal string representation * - * @param non-empty-string $encodedUuid The hexadecimal string - * representation to convert into a UuidInterface instance + * @param non-empty-string $encodedUuid The hexadecimal string representation to convert into a UuidInterface instance * - * @return UuidInterface An instance of a UUID decoded from a hexadecimal - * string representation + * @return UuidInterface An instance of a UUID decoded from a hexadecimal string representation */ public function decode(string $encodedUuid): UuidInterface; /** * Returns a UuidInterface derived from a binary string representation * - * @param non-empty-string $bytes The binary string representation to - * convert into a UuidInterface instance + * @param non-empty-string $bytes The binary string representation to convert into a UuidInterface instance * - * @return UuidInterface An instance of a UUID decoded from a binary string - * representation + * @return UuidInterface An instance of a UUID decoded from a binary string representation */ public function decodeBytes(string $bytes): UuidInterface; } diff --git a/src/Codec/GuidStringCodec.php b/src/Codec/GuidStringCodec.php index 04c65e0..58900a7 100644 --- a/src/Codec/GuidStringCodec.php +++ b/src/Codec/GuidStringCodec.php @@ -59,10 +59,8 @@ class GuidStringCodec extends StringCodec public function decodeBytes(string $bytes): UuidInterface { - $hex = bin2hex($bytes); - - // Specifically call parent::decode to preserve correct byte order - return parent::decode($hex); + // Call parent::decode() to preserve the correct byte order. + return parent::decode(bin2hex($bytes)); } /** @@ -75,8 +73,7 @@ class GuidStringCodec extends StringCodec private function swapBytes(string $bytes): string { return $bytes[3] . $bytes[2] . $bytes[1] . $bytes[0] - . $bytes[5] . $bytes[4] - . $bytes[7] . $bytes[6] + . $bytes[5] . $bytes[4] . $bytes[7] . $bytes[6] . substr($bytes, 8); } } diff --git a/src/Codec/OrderedTimeCodec.php b/src/Codec/OrderedTimeCodec.php index 9c05186..e4845e9 100644 --- a/src/Codec/OrderedTimeCodec.php +++ b/src/Codec/OrderedTimeCodec.php @@ -24,20 +24,18 @@ use function strlen; use function substr; /** - * OrderedTimeCodec encodes and decodes a UUID, optimizing the byte order for - * more efficient storage + * OrderedTimeCodec encodes and decodes a UUID, optimizing the byte order for more efficient storage * - * For binary representations of version 1 UUID, this codec may be used to - * reorganize the time fields, making the UUID closer to sequential when storing - * the bytes. According to Percona, this optimization can improve database - * INSERTs and SELECTs using the UUID column as a key. + * For binary representations of version 1 UUID, this codec may be used to reorganize the time fields, making the UUID + * closer to sequential when storing the bytes. According to Percona, this optimization can improve database INSERT and + * SELECT statements using the UUID column as a key. * - * The string representation of the UUID will remain unchanged. Only the binary - * representation is reordered. + * The string representation of the UUID will remain unchanged. Only the binary representation is reordered. * - * **PLEASE NOTE:** Binary representations of UUIDs encoded with this codec must - * be decoded with this codec. Decoding using another codec can result in - * malformed UUIDs. + * PLEASE NOTE: Binary representations of UUIDs encoded with this codec must be decoded with this codec. Decoding using + * another codec can result in malformed UUIDs. + * + * @deprecated Please migrate to {@link https://uuid.ramsey.dev/en/stable/rfc4122/version6.html Version 6, reordered time-based UUIDs}. * * @link https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/ Storing UUID Values in MySQL * @@ -46,8 +44,7 @@ use function substr; class OrderedTimeCodec extends StringCodec { /** - * Returns a binary string representation of a UUID, with the timestamp - * fields rearranged for optimized storage + * Returns a binary string representation of a UUID, with the timestamp fields rearranged for optimized storage * * @return non-empty-string */ @@ -57,22 +54,18 @@ class OrderedTimeCodec extends StringCodec !($uuid->getFields() instanceof Rfc4122FieldsInterface) || $uuid->getFields()->getVersion() !== Version::Time ) { - throw new InvalidArgumentException( - 'Expected RFC 4122 version 1 (time-based) UUID' - ); + throw new InvalidArgumentException('Expected version 1 (time-based) UUID'); } $bytes = $uuid->getFields()->getBytes(); - return $bytes[6] . $bytes[7] - . $bytes[4] . $bytes[5] + return $bytes[6] . $bytes[7] . $bytes[4] . $bytes[5] . $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3] . substr($bytes, 8); } /** - * Returns a UuidInterface derived from an ordered-time binary string - * representation + * Returns a UuidInterface derived from an ordered-time binary string representation * * @throws InvalidArgumentException if $bytes is an invalid length * @@ -81,15 +74,12 @@ class OrderedTimeCodec extends StringCodec public function decodeBytes(string $bytes): UuidInterface { if (strlen($bytes) !== 16) { - throw new InvalidArgumentException( - '$bytes string should contain 16 characters.' - ); + throw new InvalidArgumentException('$bytes string should contain 16 characters.'); } // Rearrange the bytes to their original order. $rearrangedBytes = $bytes[4] . $bytes[5] . $bytes[6] . $bytes[7] - . $bytes[2] . $bytes[3] - . $bytes[0] . $bytes[1] + . $bytes[2] . $bytes[3] . $bytes[0] . $bytes[1] . substr($bytes, 8); $uuid = parent::decodeBytes($rearrangedBytes); @@ -99,8 +89,7 @@ class OrderedTimeCodec extends StringCodec || $uuid->getFields()->getVersion() !== Version::Time ) { throw new UnsupportedOperationException( - 'Attempting to decode a non-time-based UUID using ' - . 'OrderedTimeCodec' + 'Attempting to decode a non-time-based UUID using OrderedTimeCodec', ); } diff --git a/src/Codec/StringCodec.php b/src/Codec/StringCodec.php index c4c6fe8..7a41fb9 100644 --- a/src/Codec/StringCodec.php +++ b/src/Codec/StringCodec.php @@ -29,9 +29,7 @@ use function strlen; use function substr; /** - * StringCodec encodes and decodes RFC 4122 UUIDs - * - * @link http://tools.ietf.org/html/rfc4122 + * StringCodec encodes and decodes RFC 9562 (formerly RFC 4122) UUIDs * * @immutable */ @@ -82,9 +80,7 @@ class StringCodec implements CodecInterface public function decodeBytes(string $bytes): UuidInterface { if (strlen($bytes) !== 16) { - throw new InvalidArgumentException( - '$bytes string should contain 16 characters.' - ); + throw new InvalidArgumentException('$bytes string should contain 16 characters.'); } return $this->builder->build($this, $bytes); @@ -105,11 +101,7 @@ class StringCodec implements CodecInterface */ protected function getBytes(string $encodedUuid): string { - $parsedUuid = str_replace( - ['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}', '-'], - '', - $encodedUuid - ); + $parsedUuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}', '-'], '', $encodedUuid); $components = [ substr($parsedUuid, 0, 8), @@ -120,9 +112,7 @@ class StringCodec implements CodecInterface ]; if (!Uuid::isValid(implode('-', $components))) { - throw new InvalidUuidStringException( - 'Invalid UUID string: ' . $encodedUuid - ); + throw new InvalidUuidStringException('Invalid UUID string: ' . $encodedUuid); } /** @var non-empty-string */ diff --git a/src/Codec/TimestampFirstCombCodec.php b/src/Codec/TimestampFirstCombCodec.php index e7cf97d..4cc8c51 100644 --- a/src/Codec/TimestampFirstCombCodec.php +++ b/src/Codec/TimestampFirstCombCodec.php @@ -23,28 +23,28 @@ use function substr; use function substr_replace; /** - * TimestampFirstCombCodec encodes and decodes COMBs, with the timestamp as the - * first 48 bits + * TimestampFirstCombCodec encodes and decodes COMBs, with the timestamp as the first 48 bits * - * In contrast with the TimestampLastCombCodec, the TimestampFirstCombCodec - * adds the timestamp to the first 48 bits of the COMB. To generate a - * timestamp-first COMB, set the TimestampFirstCombCodec as the codec, along - * with the CombGenerator as the random generator. + * In contrast with the TimestampLastCombCodec, the TimestampFirstCombCodec adds the timestamp to the first 48 bits of + * the COMB. To generate a timestamp-first COMB, set the TimestampFirstCombCodec as the codec, along with the + * CombGenerator as the random generator. * - * ``` php + * ``` * $factory = new UuidFactory(); * * $factory->setCodec(new TimestampFirstCombCodec($factory->getUuidBuilder())); * * $factory->setRandomGenerator(new CombGenerator( * $factory->getRandomGenerator(), - * $factory->getNumberConverter() + * $factory->getNumberConverter(), * )); * * $timestampFirstComb = $factory->uuid4(); * ``` * - * @link https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys + * @deprecated Please migrate to {@link https://uuid.ramsey.dev/en/stable/rfc4122/version7.html Version 7, Unix Epoch Time UUIDs}. + * + * @link https://web.archive.org/web/20240118030355/https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys * * @immutable */ @@ -103,9 +103,7 @@ class TimestampFirstCombCodec extends StringCodec $first48Bits = substr($bytes, 0, 6); $last48Bits = substr($bytes, -6); - $bytes = substr_replace($bytes, $last48Bits, 0, 6); - /** @var non-empty-string */ - return substr_replace($bytes, $first48Bits, -6); + return substr_replace(substr_replace($bytes, $last48Bits, 0, 6), $first48Bits, -6); } } diff --git a/src/Codec/TimestampLastCombCodec.php b/src/Codec/TimestampLastCombCodec.php index ffc8674..14d10b6 100644 --- a/src/Codec/TimestampLastCombCodec.php +++ b/src/Codec/TimestampLastCombCodec.php @@ -15,34 +15,31 @@ declare(strict_types=1); namespace Ramsey\Uuid\Codec; /** - * TimestampLastCombCodec encodes and decodes COMBs, with the timestamp as the - * last 48 bits + * TimestampLastCombCodec encodes and decodes COMBs, with the timestamp as the last 48 bits * - * The CombGenerator when used with the StringCodec (and, by proxy, the - * TimestampLastCombCodec) adds the timestamp to the last 48 bits of the COMB. - * The TimestampLastCombCodec is provided for the sake of consistency. In - * practice, it is identical to the standard StringCodec but, it may be used - * with the CombGenerator for additional context when reading code. + * The CombGenerator when used with the StringCodec (and, by proxy, the TimestampLastCombCodec) adds the timestamp to + * the last 48 bits of the COMB. The TimestampLastCombCodec is provided for the sake of consistency. In practice, it is + * identical to the standard StringCodec, but it may be used with the CombGenerator for additional context when reading + * code. * - * Consider the following code. By default, the codec used by UuidFactory is the - * StringCodec, but here, we explicitly set the TimestampLastCombCodec. It is - * redundant, but it is clear that we intend this COMB to be generated with the + * Consider the following code. By default, the codec used by UuidFactory is the StringCodec, but here, we explicitly + * set the TimestampLastCombCodec. It is redundant, but it is clear that we intend this COMB to be generated with the * timestamp appearing at the end. * - * ``` php + * ``` * $factory = new UuidFactory(); * * $factory->setCodec(new TimestampLastCombCodec($factory->getUuidBuilder())); * * $factory->setRandomGenerator(new CombGenerator( * $factory->getRandomGenerator(), - * $factory->getNumberConverter() + * $factory->getNumberConverter(), * )); * * $timestampLastComb = $factory->uuid4(); * ``` * - * @link https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys + * @deprecated Please use {@see StringCodec} instead. * * @immutable */ diff --git a/src/Converter/Number/GenericNumberConverter.php b/src/Converter/Number/GenericNumberConverter.php index e62ea49..bae27d7 100644 --- a/src/Converter/Number/GenericNumberConverter.php +++ b/src/Converter/Number/GenericNumberConverter.php @@ -19,8 +19,7 @@ use Ramsey\Uuid\Math\CalculatorInterface; use Ramsey\Uuid\Type\Integer as IntegerObject; /** - * GenericNumberConverter uses the provided calculator to convert decimal - * numbers to and from hexadecimal values + * GenericNumberConverter uses the provided calculator to convert decimal numbers to and from hexadecimal values * * @immutable */ diff --git a/src/Converter/NumberConverterInterface.php b/src/Converter/NumberConverterInterface.php index d90e288..a837207 100644 --- a/src/Converter/NumberConverterInterface.php +++ b/src/Converter/NumberConverterInterface.php @@ -15,19 +15,17 @@ declare(strict_types=1); namespace Ramsey\Uuid\Converter; /** - * A number converter converts UUIDs from hexadecimal characters into - * representations of integers and vice versa + * A number converter converts UUIDs from hexadecimal characters into representations of integers and vice versa * * @immutable */ interface NumberConverterInterface { /** - * Converts a hexadecimal number into a string integer representation of - * the number + * Converts a hexadecimal number into a string integer representation of the number * - * The integer representation returned is a string representation of the - * integer to accommodate unsigned integers greater than PHP_INT_MAX. + * The integer representation returned is a string representation of the integer to accommodate unsigned integers + * that are greater than `PHP_INT_MAX`. * * @param non-empty-string $hex The hexadecimal string representation to convert * @@ -36,12 +34,10 @@ interface NumberConverterInterface public function fromHex(string $hex): string; /** - * Converts a string integer representation into a hexadecimal string - * representation of the number + * Converts a string integer representation into a hexadecimal string representation of the number * - * @param numeric-string $number A string integer representation to convert; - * this must be a numeric string to accommodate unsigned integers - * greater than PHP_INT_MAX. + * @param numeric-string $number A string integer representation to convert; this must be a numeric string to accommodate + * unsigned integers that are greater than `PHP_INT_MAX`. * * @return non-empty-string Hexadecimal string */ diff --git a/src/Converter/Time/GenericTimeConverter.php b/src/Converter/Time/GenericTimeConverter.php index a32b16e..430109b 100644 --- a/src/Converter/Time/GenericTimeConverter.php +++ b/src/Converter/Time/GenericTimeConverter.php @@ -27,16 +27,14 @@ use function str_pad; use const STR_PAD_LEFT; /** - * GenericTimeConverter uses the provided calculator to calculate and convert - * time values + * GenericTimeConverter uses the provided calculator to calculate and convert time values * * @immutable */ class GenericTimeConverter implements TimeConverterInterface { /** - * The number of 100-nanosecond intervals from the Gregorian calendar epoch - * to the Unix epoch. + * The number of 100-nanosecond intervals from the Gregorian calendar epoch to the Unix epoch. */ private const GREGORIAN_TO_UNIX_INTERVALS = '122192928000000000'; @@ -61,46 +59,31 @@ class GenericTimeConverter implements TimeConverterInterface // Convert the seconds into a count of 100-nanosecond intervals. $sec = $this->calculator->multiply( $timestamp->getSeconds(), - new IntegerObject(self::SECOND_INTERVALS) + new IntegerObject(self::SECOND_INTERVALS), ); // Convert the microseconds into a count of 100-nanosecond intervals. $usec = $this->calculator->multiply( $timestamp->getMicroseconds(), - new IntegerObject(self::MICROSECOND_INTERVALS) + new IntegerObject(self::MICROSECOND_INTERVALS), ); - // Combine the seconds and microseconds intervals and add the count of - // 100-nanosecond intervals from the Gregorian calendar epoch to the - // Unix epoch. This gives us the correct count of 100-nanosecond - // intervals since the Gregorian calendar epoch for the given seconds - // and microseconds. + // Combine the intervals of seconds and microseconds and add the count of 100-nanosecond intervals from the + // Gregorian calendar epoch to the Unix epoch. This gives us the correct count of 100-nanosecond intervals since + // the Gregorian calendar epoch for the given seconds and microseconds. /** @var IntegerObject $uuidTime */ - $uuidTime = $this->calculator->add( - $sec, - $usec, - new IntegerObject(self::GREGORIAN_TO_UNIX_INTERVALS) - ); + $uuidTime = $this->calculator->add($sec, $usec, new IntegerObject(self::GREGORIAN_TO_UNIX_INTERVALS)); - $uuidTimeHex = str_pad( - $this->calculator->toHexadecimal($uuidTime)->toString(), - 16, - '0', - STR_PAD_LEFT - ); - - return new Hexadecimal($uuidTimeHex); + return new Hexadecimal(str_pad($this->calculator->toHexadecimal($uuidTime)->toString(), 16, '0', STR_PAD_LEFT)); } public function convertTime(Hexadecimal $uuidTimestamp): Time { - // From the total, subtract the number of 100-nanosecond intervals from - // the Gregorian calendar epoch to the Unix epoch. This gives us the - // number of 100-nanosecond intervals from the Unix epoch, which also - // includes the micro-time. + // From the total, subtract the number of 100-nanosecond intervals from the Gregorian calendar epoch to the Unix + // epoch. This gives us the number of 100-nanosecond intervals from the Unix epoch, which also includes the microtime. $epochNanoseconds = $this->calculator->subtract( $this->calculator->toInteger($uuidTimestamp), - new IntegerObject(self::GREGORIAN_TO_UNIX_INTERVALS) + new IntegerObject(self::GREGORIAN_TO_UNIX_INTERVALS), ); // Convert the 100-nanosecond intervals into seconds and microseconds. @@ -108,7 +91,7 @@ class GenericTimeConverter implements TimeConverterInterface RoundingMode::HALF_UP, 6, $epochNanoseconds, - new IntegerObject(self::SECOND_INTERVALS) + new IntegerObject(self::SECOND_INTERVALS), ); $split = explode('.', (string) $unixTimestamp, 2); diff --git a/src/Converter/Time/PhpTimeConverter.php b/src/Converter/Time/PhpTimeConverter.php index 7522f5f..9f82a02 100644 --- a/src/Converter/Time/PhpTimeConverter.php +++ b/src/Converter/Time/PhpTimeConverter.php @@ -33,24 +33,22 @@ use function substr; use const STR_PAD_LEFT; /** - * PhpTimeConverter uses built-in PHP functions and standard math operations - * available to the PHP programming language to provide facilities for - * converting parts of time into representations that may be used in UUIDs + * PhpTimeConverter uses built-in PHP functions and standard math operations available to the PHP programming language + * to provide facilities for converting parts of time into representations that may be used in UUIDs * * @immutable */ class PhpTimeConverter implements TimeConverterInterface { /** - * The number of 100-nanosecond intervals from the Gregorian calendar epoch - * to the Unix epoch. + * The number of 100-nanosecond intervals from the Gregorian calendar epoch to the Unix epoch. */ private const GREGORIAN_TO_UNIX_INTERVALS = 0x01b21dd213814000; /** * The number of 100-nanosecond intervals in one second. */ - private const SECOND_INTERVALS = 10000000; + private const SECOND_INTERVALS = 10_000_000; /** * The number of 100-nanosecond intervals in one microsecond. @@ -61,7 +59,9 @@ class PhpTimeConverter implements TimeConverterInterface public function __construct( private readonly CalculatorInterface $calculator = new BrickMathCalculator(), - private readonly TimeConverterInterface $fallbackConverter = new GenericTimeConverter(new BrickMathCalculator()) + private readonly TimeConverterInterface $fallbackConverter = new GenericTimeConverter( + new BrickMathCalculator(), + ), ) { $this->phpPrecision = (int) ini_get('precision'); } @@ -71,8 +71,8 @@ class PhpTimeConverter implements TimeConverterInterface $seconds = new IntegerObject($seconds); $microseconds = new IntegerObject($microseconds); - // Calculate the count of 100-nanosecond intervals since the Gregorian - // calendar epoch for the given seconds and microseconds. + // Calculate the count of 100-nanosecond intervals since the Gregorian calendar epoch + // for the given seconds and microseconds. $uuidTime = ((int) $seconds->toString() * self::SECOND_INTERVALS) + ((int) $microseconds->toString() * self::MICROSECOND_INTERVALS) + self::GREGORIAN_TO_UNIX_INTERVALS; @@ -83,7 +83,7 @@ class PhpTimeConverter implements TimeConverterInterface if (!is_int($uuidTime)) { return $this->fallbackConverter->calculateTime( $seconds->toString(), - $microseconds->toString() + $microseconds->toString(), ); } @@ -96,8 +96,7 @@ class PhpTimeConverter implements TimeConverterInterface // Convert the 100-nanosecond intervals into seconds and microseconds. $splitTime = $this->splitTime( - ((int) $timestamp->toString() - self::GREGORIAN_TO_UNIX_INTERVALS) - / self::SECOND_INTERVALS + ((int) $timestamp->toString() - self::GREGORIAN_TO_UNIX_INTERVALS) / self::SECOND_INTERVALS, ); if (!isset($splitTime['sec']) || !isset($splitTime['usec'])) { @@ -108,7 +107,7 @@ class PhpTimeConverter implements TimeConverterInterface } /** - * @param float|int $time The time to split into seconds and microseconds + * @param float | int $time The time to split into seconds and microseconds * * @return array{sec?: numeric-string, usec?: numeric-string} */ @@ -117,24 +116,19 @@ class PhpTimeConverter implements TimeConverterInterface /** @var numeric-string[] $split */ $split = explode('.', (string) $time, 2); - // If the $time value is a float but $split only has 1 element, then the - // float math was rounded up to the next second, so we want to return - // an empty array to allow use of the fallback converter. + // If the $time value is a float but $split only has 1 element, then the float math was rounded up to the next + // second, so we want to return an empty array to allow use of the fallback converter. if (is_float($time) && count($split) === 1) { return []; } if (count($split) === 1) { - return [ - 'sec' => $split[0], - 'usec' => '0', - ]; + return ['sec' => $split[0], 'usec' => '0']; } - // If the microseconds are less than six characters AND the length of - // the number is greater than or equal to the PHP precision, then it's - // possible that we lost some precision for the microseconds. Return an - // empty array, so that we can choose to use the fallback converter. + // If the microseconds are less than six characters AND the length of the number is greater than or equal to the + // PHP precision, then it's possible that we lost some precision for the microseconds. Return an empty array so + // that we can choose to use the fallback converter. if (strlen($split[1]) < 6 && strlen((string) $time) >= $this->phpPrecision) { return []; } diff --git a/src/Converter/Time/UnixTimeConverter.php b/src/Converter/Time/UnixTimeConverter.php index 1cd2e26..954959d 100644 --- a/src/Converter/Time/UnixTimeConverter.php +++ b/src/Converter/Time/UnixTimeConverter.php @@ -27,8 +27,8 @@ use function str_pad; use const STR_PAD_LEFT; /** - * UnixTimeConverter converts Unix Epoch timestamps to/from hexadecimal values - * consisting of milliseconds elapsed since the Unix Epoch + * UnixTimeConverter converts Unix Epoch timestamps to/from hexadecimal values consisting of milliseconds elapsed since + * the Unix Epoch * * @immutable */ @@ -45,13 +45,9 @@ class UnixTimeConverter implements TimeConverterInterface $timestamp = new Time($seconds, $microseconds); // Convert the seconds into milliseconds. - $sec = $this->calculator->multiply( - $timestamp->getSeconds(), - new IntegerObject(self::MILLISECONDS), - ); + $sec = $this->calculator->multiply($timestamp->getSeconds(), new IntegerObject(self::MILLISECONDS)); - // Convert the microseconds into milliseconds; the scale is zero because - // we need to discard the fractional part. + // Convert the microseconds into milliseconds; the scale is zero because we need to discard the fractional part. $usec = $this->calculator->divide( RoundingMode::DOWN, // Always round down to stay in the previous millisecond. 0, @@ -62,14 +58,7 @@ class UnixTimeConverter implements TimeConverterInterface /** @var IntegerObject $unixTime */ $unixTime = $this->calculator->add($sec, $usec); - $unixTimeHex = str_pad( - $this->calculator->toHexadecimal($unixTime)->toString(), - 12, - '0', - STR_PAD_LEFT - ); - - return new Hexadecimal($unixTimeHex); + return new Hexadecimal(str_pad($this->calculator->toHexadecimal($unixTime)->toString(), 12, '0', STR_PAD_LEFT)); } public function convertTime(Hexadecimal $uuidTimestamp): Time @@ -80,7 +69,7 @@ class UnixTimeConverter implements TimeConverterInterface RoundingMode::HALF_UP, 6, $milliseconds, - new IntegerObject(self::MILLISECONDS) + new IntegerObject(self::MILLISECONDS), ); $split = explode('.', (string) $unixTimestamp, 2); diff --git a/src/Converter/TimeConverterInterface.php b/src/Converter/TimeConverterInterface.php index e10b61c..b0b9199 100644 --- a/src/Converter/TimeConverterInterface.php +++ b/src/Converter/TimeConverterInterface.php @@ -18,24 +18,20 @@ use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Time; /** - * A time converter converts timestamps into representations that may be used - * in UUIDs + * A time converter converts timestamps into representations that may be used in UUIDs * * @immutable */ interface TimeConverterInterface { /** - * Uses the provided seconds and micro-seconds to calculate the count of - * 100-nanosecond intervals since UTC 00:00:00.00, 15 October 1582, for - * RFC 4122 variant UUIDs + * Uses the provided seconds and micro-seconds to calculate the count of 100-nanosecond intervals since + * UTC 00:00:00.00, 15 October 1582, for RFC 9562 (formerly RFC 4122) variant UUIDs * - * @link http://tools.ietf.org/html/rfc4122#section-4.2.2 RFC 4122, § 4.2.2: Generation Details + * @link https://www.rfc-editor.org/rfc/rfc9562#appendix-A RFC 9562, Appendix A. Test Vectors * - * @param numeric-string $seconds A string representation of the number of - * seconds since the Unix epoch for the time to calculate - * @param numeric-string $microseconds A string representation of the - * micro-seconds associated with the time to calculate + * @param numeric-string $seconds A string representation of seconds since the Unix epoch for the time to calculate + * @param numeric-string $microseconds A string representation of the micro-seconds associated with the time to calculate * * @return Hexadecimal The full UUID timestamp as a Hexadecimal value */ @@ -44,9 +40,8 @@ interface TimeConverterInterface /** * Converts a timestamp extracted from a UUID to a Unix timestamp * - * @param Hexadecimal $uuidTimestamp A hexadecimal representation of a UUID - * timestamp; a UUID timestamp is a count of 100-nanosecond intervals - * since UTC 00:00:00.00, 15 October 1582. + * @param Hexadecimal $uuidTimestamp A hexadecimal representation of a UUID timestamp; a UUID timestamp is a count + * of 100-nanosecond intervals since UTC 00:00:00.00, 15 October 1582. * * @return Time An instance of {@see Time} */ diff --git a/src/Exception/DceSecurityException.php b/src/Exception/DceSecurityException.php index e6d8001..bd8ca4c 100644 --- a/src/Exception/DceSecurityException.php +++ b/src/Exception/DceSecurityException.php @@ -17,8 +17,7 @@ namespace Ramsey\Uuid\Exception; use RuntimeException as PhpRuntimeException; /** - * Thrown to indicate an exception occurred while dealing with DCE Security - * (version 2) UUIDs + * Thrown to indicate an exception occurred while dealing with DCE Security (version 2) UUIDs */ class DceSecurityException extends PhpRuntimeException implements UuidExceptionInterface { diff --git a/src/Exception/InvalidUuidStringException.php b/src/Exception/InvalidUuidStringException.php index 6d97581..cfc7eee 100644 --- a/src/Exception/InvalidUuidStringException.php +++ b/src/Exception/InvalidUuidStringException.php @@ -17,8 +17,8 @@ namespace Ramsey\Uuid\Exception; /** * Thrown to indicate that the string received is not a valid UUID * - * The InvalidArgumentException that this extends is the ramsey/uuid version - * of this exception. It exists in the same namespace as this class. + * The InvalidArgumentException that this extends is the ramsey/uuid version of this exception. It exists in the same + * namespace as this class. */ class InvalidUuidStringException extends InvalidArgumentException implements UuidExceptionInterface { diff --git a/src/Exception/NameException.php b/src/Exception/NameException.php index fd96a1f..ee72e16 100644 --- a/src/Exception/NameException.php +++ b/src/Exception/NameException.php @@ -17,8 +17,7 @@ namespace Ramsey\Uuid\Exception; use RuntimeException as PhpRuntimeException; /** - * Thrown to indicate that an error occurred while attempting to hash a - * namespace and name + * Thrown to indicate that an error occurred while attempting to hash a namespace and name */ class NameException extends PhpRuntimeException implements UuidExceptionInterface { diff --git a/src/Exception/RandomSourceException.php b/src/Exception/RandomSourceException.php index a44dd34..7b24604 100644 --- a/src/Exception/RandomSourceException.php +++ b/src/Exception/RandomSourceException.php @@ -19,8 +19,8 @@ use RuntimeException as PhpRuntimeException; /** * Thrown to indicate that the source of random data encountered an error * - * This exception is used mostly to indicate that random_bytes() or random_int() - * threw an exception. However, it may be used for other sources of random data. + * This exception is used mostly to indicate that random_bytes() or random_int() threw an exception. However, it may be + * used for other sources of random data. */ class RandomSourceException extends PhpRuntimeException implements UuidExceptionInterface { diff --git a/src/FeatureSet.php b/src/FeatureSet.php index 2a50dab..8ef8d0b 100644 --- a/src/FeatureSet.php +++ b/src/FeatureSet.php @@ -57,8 +57,7 @@ use const PHP_INT_SIZE; /** * FeatureSet detects and exposes available features in the current environment * - * A feature set is used by UuidFactory to determine the available features and - * capabilities of the environment. + * A feature set is used by UuidFactory to determine the available features and capabilities of the environment. */ class FeatureSet { @@ -78,18 +77,15 @@ class FeatureSet /** * @param bool $useGuids True build UUIDs using the GuidStringCodec - * @param bool $force32Bit True to force the use of 32-bit functionality - * (primarily for testing purposes) - * @param bool $ignoreSystemNode True to disable attempts to check for the - * system node ID (primarily for testing purposes) - * @param bool $enablePecl True to enable the use of the PeclUuidTimeGenerator - * to generate version 1 UUIDs + * @param bool $force32Bit True to force the use of 32-bit functionality (primarily for testing purposes) + * @param bool $ignoreSystemNode True to disable attempts to check for the system node ID (primarily for testing purposes) + * @param bool $enablePecl True to enable the use of the PeclUuidTimeGenerator to generate version 1 UUIDs */ public function __construct( bool $useGuids = false, private bool $force32Bit = false, private bool $ignoreSystemNode = false, - private bool $enablePecl = false + private bool $enablePecl = false, ) { $this->randomGenerator = $this->buildRandomGenerator(); $this->setCalculator(new BrickMathCalculator()); @@ -270,13 +266,9 @@ class FeatureSet * Returns a DCE Security generator configured for this environment */ private function buildDceSecurityGenerator( - DceSecurityProviderInterface $dceSecurityProvider + DceSecurityProviderInterface $dceSecurityProvider, ): DceSecurityGeneratorInterface { - return new DceSecurityGenerator( - $this->numberConverter, - $this->timeGenerator, - $dceSecurityProvider - ); + return new DceSecurityGenerator($this->numberConverter, $this->timeGenerator, $dceSecurityProvider); } /** @@ -288,10 +280,7 @@ class FeatureSet return new RandomNodeProvider(); } - return new FallbackNodeProvider([ - new SystemNodeProvider(), - new RandomNodeProvider(), - ]); + return new FallbackNodeProvider([new SystemNodeProvider(), new RandomNodeProvider()]); } /** @@ -326,11 +315,7 @@ class FeatureSet return new PeclUuidTimeGenerator(); } - return (new TimeGeneratorFactory( - $this->nodeProvider, - $this->timeConverter, - $timeProvider - ))->getGenerator(); + return (new TimeGeneratorFactory($this->nodeProvider, $this->timeConverter, $timeProvider))->getGenerator(); } /** diff --git a/src/Fields/FieldsInterface.php b/src/Fields/FieldsInterface.php index 59cf70a..a28f25b 100644 --- a/src/Fields/FieldsInterface.php +++ b/src/Fields/FieldsInterface.php @@ -15,9 +15,8 @@ declare(strict_types=1); namespace Ramsey\Uuid\Fields; /** - * UUIDs consist of unsigned integers, the bytes of which are separated - * into fields and arranged in a particular layout defined by the specification - * for the variant + * UUIDs consist of unsigned integers, the bytes of which are separated into fields and arranged in a particular layout + * defined by the specification for the variant * * @immutable */ diff --git a/src/Generator/CombGenerator.php b/src/Generator/CombGenerator.php index 0fbc296..9584bc9 100644 --- a/src/Generator/CombGenerator.php +++ b/src/Generator/CombGenerator.php @@ -29,33 +29,32 @@ use const STR_PAD_LEFT; /** * CombGenerator generates COMBs (combined UUID/timestamp) * - * The CombGenerator, when used with the StringCodec (and, by proxy, the - * TimestampLastCombCodec) or the TimestampFirstCombCodec, combines the current - * timestamp with a UUID (hence the name "COMB"). The timestamp either appears - * as the first or last 48 bits of the COMB, depending on the codec used. + * The CombGenerator, when used with the StringCodec (and, by proxy, the TimestampLastCombCodec) or the + * TimestampFirstCombCodec, combines the current timestamp with a UUID (hence the name "COMB"). The timestamp either + * appears as the first or last 48 bits of the COMB, depending on the codec used. * - * By default, COMBs will have the timestamp set as the last 48 bits of the - * identifier. + * By default, COMBs will have the timestamp set as the last 48 bits of the identifier. * - * ``` php + * ``` * $factory = new UuidFactory(); * * $factory->setRandomGenerator(new CombGenerator( * $factory->getRandomGenerator(), - * $factory->getNumberConverter() + * $factory->getNumberConverter(), * )); * * $comb = $factory->uuid4(); * ``` * - * To generate a COMB with the timestamp as the first 48 bits, set the - * TimestampFirstCombCodec as the codec. + * To generate a COMB with the timestamp as the first 48 bits, set the TimestampFirstCombCodec as the codec. * - * ``` php + * ``` * $factory->setCodec(new TimestampFirstCombCodec($factory->getUuidBuilder())); * ``` * - * @link https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys + * @deprecated Please migrate to {@link https://uuid.ramsey.dev/en/stable/rfc4122/version7.html Version 7, Unix Epoch Time UUIDs}. + * + * @link https://web.archive.org/web/20240118030355/https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys */ class CombGenerator implements RandomGeneratorInterface { @@ -68,13 +67,11 @@ class CombGenerator implements RandomGeneratorInterface } /** - * @param positive-int $length The number of bytes of random binary data to - * generate + * @param positive-int $length The number of random bytes to generate * * @return non-empty-string * - * @throws InvalidArgumentException if $length is not a positive integer - * greater than or equal to CombGenerator::TIMESTAMP_BYTES + * @throws InvalidArgumentException if $length is not a positive integer greater than or equal to CombGenerator::TIMESTAMP_BYTES * * @inheritDoc */ @@ -101,22 +98,15 @@ class CombGenerator implements RandomGeneratorInterface $this->numberConverter->toHex($this->timestamp()), self::TIMESTAMP_BYTES * 2, '0', - STR_PAD_LEFT + STR_PAD_LEFT, ); /** @var non-empty-string */ - return (string) hex2bin( - str_pad( - bin2hex($hash), - $length - self::TIMESTAMP_BYTES, - '0' - ) - . $lsbTime - ); + return (string) hex2bin(str_pad(bin2hex($hash), $length - self::TIMESTAMP_BYTES, '0') . $lsbTime); } /** - * Returns current timestamp as string integer, precise to 0.00001 seconds + * Returns the current timestamp as a string integer, precise to 0.00001 seconds * * @return numeric-string */ diff --git a/src/Generator/DceSecurityGenerator.php b/src/Generator/DceSecurityGenerator.php index 6312285..25b4cfe 100644 --- a/src/Generator/DceSecurityGenerator.php +++ b/src/Generator/DceSecurityGenerator.php @@ -31,8 +31,8 @@ use function substr_replace; use const STR_PAD_LEFT; /** - * DceSecurityGenerator generates strings of binary data based on a local - * domain, local identifier, node ID, clock sequence, and the current time + * DceSecurityGenerator generates strings of binary data based on a local domain, local identifier, node ID, clock + * sequence, and the current time */ class DceSecurityGenerator implements DceSecurityGeneratorInterface { @@ -55,7 +55,7 @@ class DceSecurityGenerator implements DceSecurityGeneratorInterface public function __construct( private readonly NumberConverterInterface $numberConverter, private readonly TimeGeneratorInterface $timeGenerator, - private readonly DceSecurityProviderInterface $dceSecurityProvider + private readonly DceSecurityProviderInterface $dceSecurityProvider, ) { } @@ -63,32 +63,26 @@ class DceSecurityGenerator implements DceSecurityGeneratorInterface int $localDomain, ?IntegerObject $localIdentifier = null, Hexadecimal | int | string | null $node = null, - ?int $clockSeq = null + ?int $clockSeq = null, ): string { if (!in_array($localDomain, self::DOMAINS)) { - throw new DceSecurityException( - 'Local domain must be a valid DCE Security domain' - ); + throw new DceSecurityException('Local domain must be a valid DCE Security domain'); } if ($localIdentifier && $localIdentifier->isNegative()) { throw new DceSecurityException( - 'Local identifier out of bounds; it must be a value between 0 and 4294967295' + 'Local identifier out of bounds; it must be a value between 0 and 4294967295', ); } if ($clockSeq > self::CLOCK_SEQ_HIGH || $clockSeq < self::CLOCK_SEQ_LOW) { - throw new DceSecurityException( - 'Clock sequence out of bounds; it must be a value between 0 and 63' - ); + throw new DceSecurityException('Clock sequence out of bounds; it must be a value between 0 and 63'); } switch ($localDomain) { case Uuid::DCE_DOMAIN_ORG: if ($localIdentifier === null) { - throw new DceSecurityException( - 'A local identifier must be provided for the org domain' - ); + throw new DceSecurityException('A local identifier must be provided for the org domain'); } break; @@ -109,13 +103,11 @@ class DceSecurityGenerator implements DceSecurityGeneratorInterface $identifierHex = $this->numberConverter->toHex($localIdentifier->toString()); - // The maximum value for the local identifier is 0xffffffff, or - // 4294967295. This is 8 hexadecimal digits, so if the length of - // hexadecimal digits is greater than 8, we know the value is greater - // than 0xffffffff. + // The maximum value for the local identifier is 0xffffffff, or 4,294,967,295. This is 8 hexadecimal digits, so + // if the length of hexadecimal digits is greater than 8, we know the value is greater than 0xffffffff. if (strlen($identifierHex) > 8) { throw new DceSecurityException( - 'Local identifier out of bounds; it must be a value between 0 and 4294967295' + 'Local identifier out of bounds; it must be a value between 0 and 4294967295', ); } diff --git a/src/Generator/DceSecurityGeneratorInterface.php b/src/Generator/DceSecurityGeneratorInterface.php index 2eb9dc6..55f02c4 100644 --- a/src/Generator/DceSecurityGeneratorInterface.php +++ b/src/Generator/DceSecurityGeneratorInterface.php @@ -19,28 +19,23 @@ use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; /** - * A DCE Security generator generates strings of binary data based on a local - * domain, local identifier, node ID, clock sequence, and the current time + * A DCE Security generator generates strings of binary data based on a local domain, local identifier, node ID, clock + * sequence, and the current time * * @see UuidV2 */ interface DceSecurityGeneratorInterface { /** - * Generate a binary string from a local domain, local identifier, node ID, - * clock sequence, and current time + * Generate a binary string from a local domain, local identifier, node ID, clock sequence, and current time * - * @param int $localDomain The local domain to use when generating bytes, - * according to DCE Security - * @param IntegerObject|null $localIdentifier The local identifier for the - * given domain; this may be a UID or GID on POSIX systems, if the local - * domain is person or group, or it may be a site-defined identifier - * if the local domain is org - * @param Hexadecimal|positive-int|non-empty-string|null $node A 48-bit - * number representing the hardware address - * @param int<0, 63>|null $clockSeq A 6-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time - * or if the node ID changes + * @param int $localDomain The local domain to use when generating bytes, according to DCE Security + * @param IntegerObject | null $localIdentifier The local identifier for the given domain; this may be a UID or GID + * on POSIX systems if the local domain is "person" or "group," or it may be a site-defined identifier if the + * local domain is "org" + * @param Hexadecimal | positive-int | non-empty-string | null $node A 48-bit number representing the hardware address + * @param int<0, 63> | null $clockSeq A 6-bit number used to help avoid duplicates that could arise when the clock + * is set backwards in time or if the node ID changes * * @return non-empty-string A binary string */ @@ -48,6 +43,6 @@ interface DceSecurityGeneratorInterface int $localDomain, ?IntegerObject $localIdentifier = null, Hexadecimal | int | string | null $node = null, - ?int $clockSeq = null + ?int $clockSeq = null, ): string; } diff --git a/src/Generator/DefaultNameGenerator.php b/src/Generator/DefaultNameGenerator.php index 9d8b7fb..a73b630 100644 --- a/src/Generator/DefaultNameGenerator.php +++ b/src/Generator/DefaultNameGenerator.php @@ -21,8 +21,7 @@ use ValueError; use function hash; /** - * DefaultNameGenerator generates strings of binary data based on a namespace, - * name, and hashing algorithm + * DefaultNameGenerator generates strings of binary data based on a namespace, name, and hashing algorithm */ class DefaultNameGenerator implements NameGeneratorInterface { diff --git a/src/Generator/DefaultTimeGenerator.php b/src/Generator/DefaultTimeGenerator.php index 10a1716..1460860 100644 --- a/src/Generator/DefaultTimeGenerator.php +++ b/src/Generator/DefaultTimeGenerator.php @@ -35,15 +35,14 @@ use function strlen; use const STR_PAD_LEFT; /** - * DefaultTimeGenerator generates strings of binary data based on a node ID, - * clock sequence, and the current time + * DefaultTimeGenerator generates strings of binary data based on a node ID, clock sequence, and the current time */ class DefaultTimeGenerator implements TimeGeneratorInterface { public function __construct( private readonly NodeProviderInterface $nodeProvider, private readonly TimeConverterInterface $timeConverter, - private readonly TimeProviderInterface $timeProvider + private readonly TimeProviderInterface $timeProvider, ) { } @@ -63,14 +62,10 @@ class DefaultTimeGenerator implements TimeGeneratorInterface if ($clockSeq === null) { try { - // This does not use "stable storage"; see RFC 4122, Section 4.2.1.1. + // This does not use "stable storage"; see RFC 9562, section 6.3. $clockSeq = random_int(0, 0x3fff); } catch (Throwable $exception) { - throw new RandomSourceException( - $exception->getMessage(), - (int) $exception->getCode(), - $exception - ); + throw new RandomSourceException($exception->getMessage(), (int) $exception->getCode(), $exception); } } @@ -84,27 +79,20 @@ class DefaultTimeGenerator implements TimeGeneratorInterface $timeHex = str_pad($uuidTime->toString(), 16, '0', STR_PAD_LEFT); if (strlen($timeHex) !== 16) { - throw new TimeSourceException(sprintf( - 'The generated time of \'%s\' is larger than expected', - $timeHex - )); + throw new TimeSourceException(sprintf('The generated time of \'%s\' is larger than expected', $timeHex)); } $timeBytes = (string) hex2bin($timeHex); return $timeBytes[4] . $timeBytes[5] . $timeBytes[6] . $timeBytes[7] - . $timeBytes[2] . $timeBytes[3] - . $timeBytes[0] . $timeBytes[1] - . pack('n*', $clockSeq) - . $node; + . $timeBytes[2] . $timeBytes[3] . $timeBytes[0] . $timeBytes[1] + . pack('n*', $clockSeq) . $node; } /** - * Uses the node provider given when constructing this instance to get - * the node ID (usually a MAC address) + * Uses the node provider given when constructing this instance to get the node ID (usually a MAC address) * - * @param non-empty-string|positive-int|null $node A node value that may be - * used to override the node provider + * @param non-empty-string | positive-int | null $node A node value that may be used to override the node provider * * @return non-empty-string 6-byte binary string representation of the node * @@ -116,7 +104,7 @@ class DefaultTimeGenerator implements TimeGeneratorInterface $node = $this->nodeProvider->getNode(); } - // Convert the node to hex, if it is still an integer. + // Convert the node to hex if it is still an integer. if (is_int($node)) { $node = dechex($node); } diff --git a/src/Generator/NameGeneratorFactory.php b/src/Generator/NameGeneratorFactory.php index 6f08e29..d68e94b 100644 --- a/src/Generator/NameGeneratorFactory.php +++ b/src/Generator/NameGeneratorFactory.php @@ -15,8 +15,7 @@ declare(strict_types=1); namespace Ramsey\Uuid\Generator; /** - * NameGeneratorFactory retrieves a default name generator, based on the - * environment + * NameGeneratorFactory retrieves a default name generator, based on the environment */ class NameGeneratorFactory { diff --git a/src/Generator/NameGeneratorInterface.php b/src/Generator/NameGeneratorInterface.php index b512e89..18d9aec 100644 --- a/src/Generator/NameGeneratorInterface.php +++ b/src/Generator/NameGeneratorInterface.php @@ -17,14 +17,13 @@ namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\UuidInterface; /** - * A name generator generates strings of binary data created by hashing together - * a namespace with a name, according to a hashing algorithm + * A name generator generates strings of binary data created by hashing together a namespace with a name, according to a + * hashing algorithm */ interface NameGeneratorInterface { /** - * Generate a binary string from a namespace and name hashed together with - * the specified hashing algorithm + * Generate a binary string from a namespace and name hashed together with the specified hashing algorithm * * @param UuidInterface $ns The namespace * @param string $name The name to use for creating a UUID diff --git a/src/Generator/PeclUuidNameGenerator.php b/src/Generator/PeclUuidNameGenerator.php index 9d7b207..ecd02de 100644 --- a/src/Generator/PeclUuidNameGenerator.php +++ b/src/Generator/PeclUuidNameGenerator.php @@ -23,8 +23,7 @@ use function uuid_generate_sha1; use function uuid_parse; /** - * PeclUuidNameGenerator generates strings of binary data from a namespace and a - * name, using ext-uuid + * PeclUuidNameGenerator generates strings of binary data from a namespace and a name, using ext-uuid * * @link https://pecl.php.net/package/uuid ext-uuid */ @@ -36,10 +35,7 @@ class PeclUuidNameGenerator implements NameGeneratorInterface 'md5' => uuid_generate_md5($ns->toString(), $name), 'sha1' => uuid_generate_sha1($ns->toString(), $name), default => throw new NameException( - sprintf( - 'Unable to hash namespace and name with algorithm \'%s\'', - $hashAlgorithm - ) + sprintf('Unable to hash namespace and name with algorithm \'%s\'', $hashAlgorithm), ), }; diff --git a/src/Generator/PeclUuidTimeGenerator.php b/src/Generator/PeclUuidTimeGenerator.php index 306edce..75c2b4a 100644 --- a/src/Generator/PeclUuidTimeGenerator.php +++ b/src/Generator/PeclUuidTimeGenerator.php @@ -23,8 +23,7 @@ use function uuid_parse; use const UUID_TYPE_TIME; /** - * PeclUuidTimeGenerator generates strings of binary data for time-base UUIDs, - * using ext-uuid + * PeclUuidTimeGenerator generates strings of binary data for time-base UUIDs, using ext-uuid * * @link https://pecl.php.net/package/uuid ext-uuid */ diff --git a/src/Generator/RandomBytesGenerator.php b/src/Generator/RandomBytesGenerator.php index 12edb96..c169e63 100644 --- a/src/Generator/RandomBytesGenerator.php +++ b/src/Generator/RandomBytesGenerator.php @@ -18,8 +18,7 @@ use Ramsey\Uuid\Exception\RandomSourceException; use Throwable; /** - * RandomBytesGenerator generates strings of random binary data using the - * built-in `random_bytes()` PHP function + * RandomBytesGenerator generates strings of random binary data using the built-in `random_bytes()` PHP function * * @link http://php.net/random_bytes random_bytes() */ @@ -35,11 +34,7 @@ class RandomBytesGenerator implements RandomGeneratorInterface try { return random_bytes($length); } catch (Throwable $exception) { - throw new RandomSourceException( - $exception->getMessage(), - (int) $exception->getCode(), - $exception - ); + throw new RandomSourceException($exception->getMessage(), (int) $exception->getCode(), $exception); } } } diff --git a/src/Generator/RandomGeneratorFactory.php b/src/Generator/RandomGeneratorFactory.php index b723ac2..f4c3a6f 100644 --- a/src/Generator/RandomGeneratorFactory.php +++ b/src/Generator/RandomGeneratorFactory.php @@ -15,8 +15,7 @@ declare(strict_types=1); namespace Ramsey\Uuid\Generator; /** - * RandomGeneratorFactory retrieves a default random generator, based on the - * environment + * RandomGeneratorFactory retrieves a default random generator, based on the environment */ class RandomGeneratorFactory { diff --git a/src/Generator/RandomGeneratorInterface.php b/src/Generator/RandomGeneratorInterface.php index 172d976..d6d506e 100644 --- a/src/Generator/RandomGeneratorInterface.php +++ b/src/Generator/RandomGeneratorInterface.php @@ -22,8 +22,7 @@ interface RandomGeneratorInterface /** * Generates a string of randomized binary data * - * @param positive-int $length The number of bytes of random binary data to - * generate + * @param positive-int $length The number of random bytes to generate * * @return non-empty-string A binary string */ diff --git a/src/Generator/TimeGeneratorFactory.php b/src/Generator/TimeGeneratorFactory.php index 6a8f51b..6ee9b56 100644 --- a/src/Generator/TimeGeneratorFactory.php +++ b/src/Generator/TimeGeneratorFactory.php @@ -19,15 +19,14 @@ use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Provider\TimeProviderInterface; /** - * TimeGeneratorFactory retrieves a default time generator, based on the - * environment + * TimeGeneratorFactory retrieves a default time generator, based on the environment */ class TimeGeneratorFactory { public function __construct( private readonly NodeProviderInterface $nodeProvider, private readonly TimeConverterInterface $timeConverter, - private readonly TimeProviderInterface $timeProvider + private readonly TimeProviderInterface $timeProvider, ) { } @@ -36,10 +35,6 @@ class TimeGeneratorFactory */ public function getGenerator(): TimeGeneratorInterface { - return new DefaultTimeGenerator( - $this->nodeProvider, - $this->timeConverter, - $this->timeProvider - ); + return new DefaultTimeGenerator($this->nodeProvider, $this->timeConverter, $this->timeProvider); } } diff --git a/src/Generator/TimeGeneratorInterface.php b/src/Generator/TimeGeneratorInterface.php index d77fddb..38e6c70 100644 --- a/src/Generator/TimeGeneratorInterface.php +++ b/src/Generator/TimeGeneratorInterface.php @@ -17,20 +17,17 @@ namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\Type\Hexadecimal; /** - * A time generator generates strings of binary data based on a node ID, - * clock sequence, and the current time + * A time generator generates strings of binary data based on a node ID, clock sequence, and the current time */ interface TimeGeneratorInterface { /** * Generate a binary string from a node ID, clock sequence, and current time * - * @param Hexadecimal|non-empty-string|positive-int|null $node A 48-bit - * number representing the hardware address; this number may be - * represented as an integer or a hexadecimal string - * @param int<0, 16383>|null $clockSeq A 14-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time - * or if the node ID changes + * @param Hexadecimal | non-empty-string | positive-int | null $node A 48-bit number representing the hardware + * address; this number may be represented as an integer or a hexadecimal string + * @param int<0, 16383> | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the + * clock is set backwards in time or if the node ID changes * * @return non-empty-string A binary string */ diff --git a/src/Generator/UnixTimeGenerator.php b/src/Generator/UnixTimeGenerator.php index 2af98be..e54db66 100644 --- a/src/Generator/UnixTimeGenerator.php +++ b/src/Generator/UnixTimeGenerator.php @@ -31,11 +31,10 @@ use const PHP_INT_SIZE; use const STR_PAD_LEFT; /** - * UnixTimeGenerator generates bytes that combine a 48-bit timestamp in - * milliseconds since the Unix Epoch with 80 random bits + * UnixTimeGenerator generates bytes, combining a 48-bit timestamp in milliseconds since the Unix Epoch with 80 random bits * - * Code and concepts within this class are borrowed from the symfony/uid package - * and are used under the terms of the MIT license distributed with symfony/uid. + * Code and concepts within this class are borrowed from the symfony/uid package and are used under the terms of the MIT + * license distributed with symfony/uid. * * symfony/uid is copyright (c) Fabien Potencier. * @@ -62,8 +61,9 @@ class UnixTimeGenerator implements TimeGeneratorInterface } /** - * @param DateTimeInterface|null $dateTime A date-time instance to use when - * generating bytes + * @param Hexadecimal | int | string | null $node Unused in this generator + * @param int | null $clockSeq Unused in this generator + * @param DateTimeInterface | null $dateTime A date-time instance to use when generating bytes * * @return non-empty-string */ @@ -108,23 +108,17 @@ class UnixTimeGenerator implements TimeGeneratorInterface } /** - * Special thanks to Nicolas Grekas for sharing the following information: + * Special thanks to Nicolas Grekas () for sharing the following information: * * Within the same ms, we increment the rand part by a random 24-bit number. * - * Instead of getting this number from random_bytes(), which is slow, we get - * it by sha512-hashing self::$seed. This produces 64 bytes of entropy, - * which we need to split in a list of 24-bit numbers. unpack() first splits - * them into 16 x 32-bit numbers; we take the first byte of each of these - * numbers to get 5 extra 24-bit numbers. Then, we consume those numbers - * one-by-one and run this logic every 21 iterations. + * Instead of getting this number from random_bytes(), which is slow, we get it by sha512-hashing self::$seed. This + * produces 64 bytes of entropy, which we need to split in a list of 24-bit numbers. `unpack()` first splits them + * into 16 x 32-bit numbers; we take the first byte of each number to get 5 extra 24-bit numbers. Then, we consume + * each number one-by-one and run this logic every 21 iterations. * - * self::$rand holds the random part of the UUID, split into 5 x 16-bit - * numbers for x86 portability. We increment this random part by the next - * 24-bit number in the self::$seedParts list and decrement - * self::$seedIndex. - * - * @link https://twitter.com/nicolasgrekas/status/1583356938825261061 Tweet from Nicolas Grekas + * `self::$rand` holds the random part of the UUID, split into 5 x 16-bit numbers for x86 portability. We increment + * this random part by the next 24-bit number in the `self::$seedParts` list and decrement `self::$seedIndex`. */ private function increment(): string { diff --git a/src/Guid/Fields.php b/src/Guid/Fields.php index e60568d..47d3dce 100644 --- a/src/Guid/Fields.php +++ b/src/Guid/Fields.php @@ -38,7 +38,7 @@ use function unpack; use const STR_PAD_LEFT; /** - * GUIDs consist of a set of named fields, according to RFC 4122 + * GUIDs consist of a set of named fields, according to RFC 9562 (formerly RFC 4122) * * @see Guid * @@ -63,22 +63,19 @@ final class Fields implements FieldsInterface { if (strlen($this->bytes) !== 16) { throw new InvalidArgumentException( - 'The byte string must be 16 bytes long; ' - . 'received ' . strlen($this->bytes) . ' bytes' + 'The byte string must be 16 bytes long; received ' . strlen($this->bytes) . ' bytes', ); } if (!$this->isCorrectVariant()) { throw new InvalidArgumentException( - 'The byte string received does not conform to the RFC ' - . '4122 or Microsoft Corporation variants' + 'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) ' + . 'or Microsoft Corporation variants', ); } if (!$this->isCorrectVersion()) { - throw new InvalidArgumentException( - 'The byte string received does not contain a valid version' - ); + throw new InvalidArgumentException('The byte string received does not contain a valid version'); } } @@ -96,8 +93,8 @@ final class Fields implements FieldsInterface pack( 'v*', hexdec(bin2hex(substr($this->bytes, 2, 2))), - hexdec(bin2hex(substr($this->bytes, 0, 2))) - ) + hexdec(bin2hex(substr($this->bytes, 0, 2))), + ), ); return new Hexadecimal($hex[1]); @@ -107,13 +104,7 @@ final class Fields implements FieldsInterface { // Swap the bytes from little endian to network byte order. /** @var non-empty-string[] $hex */ - $hex = unpack( - 'H*', - pack( - 'v', - hexdec(bin2hex(substr($this->bytes, 4, 2))) - ) - ); + $hex = unpack('H*', pack('v', hexdec(bin2hex(substr($this->bytes, 4, 2))))); return new Hexadecimal($hex[1]); } @@ -122,13 +113,7 @@ final class Fields implements FieldsInterface { // Swap the bytes from little endian to network byte order. /** @var non-empty-string[] $hex */ - $hex = unpack( - 'H*', - pack( - 'v', - hexdec(bin2hex(substr($this->bytes, 6, 2))) - ) - ); + $hex = unpack('H*', pack('v', hexdec(bin2hex(substr($this->bytes, 6, 2))))); return new Hexadecimal($hex[1]); } diff --git a/src/Guid/Guid.php b/src/Guid/Guid.php index 0af0210..af551cf 100644 --- a/src/Guid/Guid.php +++ b/src/Guid/Guid.php @@ -24,22 +24,18 @@ use Ramsey\Uuid\Uuid; * * From Wikipedia: * - * > The first three fields are unsigned 32- and 16-bit integers and are subject - * > to swapping, while the last two fields consist of uninterpreted bytes, not - * > subject to swapping. This byte swapping applies even for versions 3, 4, and - * > 5, where the canonical fields do not correspond to the content of the UUID. + * > The first three fields are unsigned 32- and 16-bit integers and are subject to swapping, while the last two fields + * > consist of uninterpreted bytes, not subject to swapping. This byte swapping applies even for versions 3, 4, and 5, + * > where the canonical fields do not correspond to the content of the UUID. * - * The first three fields of a GUID are encoded in little-endian byte order, - * while the last three fields are in network (big-endian) byte order. This is - * according to the history of the Microsoft definition of a GUID. + * The first three fields of a GUID are encoded in little-endian byte order, while the last three fields are in network + * (big-endian) byte order. This is according to the history of the Microsoft GUID definition. * * According to the .NET Guid.ToByteArray method documentation: * - * > Note that the order of bytes in the returned byte array is different from - * > the string representation of a Guid value. The order of the beginning - * > four-byte group and the next two two-byte groups is reversed, whereas the - * > order of the last two-byte group and the closing six-byte group is the - * > same. + * > Note that the order of bytes in the returned byte array is different from the string representation of a Guid value. + * > The order of the beginning four-byte group and the next two two-byte groups is reversed, whereas the order of the + * > last two-byte group and the closing six-byte group is the same. * * @link https://en.wikipedia.org/wiki/Universally_unique_identifier#Variants UUID Variants on Wikipedia * @link https://docs.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid Windows GUID structure @@ -54,7 +50,7 @@ final class Guid extends Uuid Fields $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, - TimeConverterInterface $timeConverter + TimeConverterInterface $timeConverter, ) { parent::__construct($fields, $numberConverter, $codec, $timeConverter); } diff --git a/src/Guid/GuidBuilder.php b/src/Guid/GuidBuilder.php index 84bf25d..7b813f0 100644 --- a/src/Guid/GuidBuilder.php +++ b/src/Guid/GuidBuilder.php @@ -32,10 +32,9 @@ use Throwable; class GuidBuilder implements UuidBuilderInterface { /** - * @param NumberConverterInterface $numberConverter The number converter to - * use when constructing the Guid - * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to Unix timestamps + * @param NumberConverterInterface $numberConverter The number converter to use when constructing the Guid + * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a + * UUID to Unix timestamps */ public function __construct( private readonly NumberConverterInterface $numberConverter, @@ -54,19 +53,14 @@ class GuidBuilder implements UuidBuilderInterface public function build(CodecInterface $codec, string $bytes): UuidInterface { try { - return new Guid( - $this->buildFields($bytes), - $this->numberConverter, - $codec, - $this->timeConverter - ); + return new Guid($this->buildFields($bytes), $this->numberConverter, $codec, $this->timeConverter); } catch (Throwable $e) { throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e); } } /** - * Proxy method to allow injecting a mock, for testing + * Proxy method to allow injecting a mock for testing * * @param non-empty-string $bytes */ diff --git a/src/Lazy/LazyUuidFromString.php b/src/Lazy/LazyUuidFromString.php index d94fe17..44ad835 100644 --- a/src/Lazy/LazyUuidFromString.php +++ b/src/Lazy/LazyUuidFromString.php @@ -35,17 +35,18 @@ use function substr; /** * Lazy version of a UUID: its format has not been determined yet, so it is mostly only usable for string/bytes - * conversion. This object optimizes instantiation, serialization and string conversion time, at the cost of - * increased overhead for more advanced UUID operations. + * conversion. This object optimizes instantiation, serialization and string conversion time, at the cost of increased + * overhead for more advanced UUID operations. * - * @internal this type is used internally for performance reasons and is not supposed to be directly referenced - * in consumer libraries. + * > [!NOTE] + * > The {@see FieldsInterface} does not declare methods that deprecated API relies upon: the API has been ported from + * > the {@see \Ramsey\Uuid\Uuid} definition, and is deprecated anyway. * - * Note: the {@see FieldsInterface} does not declare methods that deprecated API - * relies upon: the API has been ported from the {@see \Ramsey\Uuid\Uuid} definition, - * and is deprecated anyway. - * Note: the deprecated API from {@see \Ramsey\Uuid\Uuid} is in use here (on purpose): it will be removed - * once the deprecated API is gone from this class too. + * > [!NOTE] + * > The deprecated API from {@see \Ramsey\Uuid\Uuid} is in use here (on purpose): it will be removed once the + * > deprecated API is gone from this class too. + * + * @internal this type is used internally for performance reasons and is not supposed to be directly referenced in consumer libraries. */ final class LazyUuidFromString implements TimeBasedUuidInterface { @@ -112,19 +113,17 @@ final class LazyUuidFromString implements TimeBasedUuidInterface public function getUrn(): string { - return ($this->unwrapped ?? $this->unwrap()) - ->getUrn(); + return ($this->unwrapped ?? $this->unwrap())->getUrn(); } public function compareTo(UuidInterface $other): int { - return ($this->unwrapped ?? $this->unwrap()) - ->compareTo($other); + return ($this->unwrapped ?? $this->unwrap())->compareTo($other); } public function equals(?object $other): bool { - if (! $other instanceof UuidInterface) { + if (!$other instanceof UuidInterface) { return false; } @@ -139,20 +138,17 @@ final class LazyUuidFromString implements TimeBasedUuidInterface public function getFields(): FieldsInterface { - return ($this->unwrapped ?? $this->unwrap()) - ->getFields(); + return ($this->unwrapped ?? $this->unwrap())->getFields(); } public function getHex(): Hexadecimal { - return ($this->unwrapped ?? $this->unwrap()) - ->getHex(); + return ($this->unwrapped ?? $this->unwrap())->getHex(); } public function getInteger(): IntegerObject { - return ($this->unwrapped ?? $this->unwrap()) - ->getInteger(); + return ($this->unwrapped ?? $this->unwrap())->getInteger(); } public function toString(): string diff --git a/src/Math/BrickMathCalculator.php b/src/Math/BrickMathCalculator.php index 20d9d4a..697871b 100644 --- a/src/Math/BrickMathCalculator.php +++ b/src/Math/BrickMathCalculator.php @@ -81,7 +81,7 @@ final class BrickMathCalculator implements CalculatorInterface int $roundingMode, int $scale, NumberInterface $dividend, - NumberInterface ...$divisors + NumberInterface ...$divisors, ): NumberInterface { $brickRounding = $this->getBrickRoundingMode($roundingMode); diff --git a/src/Math/CalculatorInterface.php b/src/Math/CalculatorInterface.php index cea445c..7e04b77 100644 --- a/src/Math/CalculatorInterface.php +++ b/src/Math/CalculatorInterface.php @@ -61,9 +61,8 @@ interface CalculatorInterface * @param int $roundingMode The RoundingMode constant to use for this operation * @param int $scale The scale to use for this operation * @param NumberInterface $dividend The integer to be divided - * @param NumberInterface ...$divisors The integers to divide $dividend by, in - * the order in which the division operations should take place - * (left-to-right) + * @param NumberInterface ...$divisors The integers to divide $dividend by, in the order in which the division + * operations should take place (left-to-right) * * @return NumberInterface The quotient of dividing the provided parameters left-to-right */ @@ -71,7 +70,7 @@ interface CalculatorInterface int $roundingMode, int $scale, NumberInterface $dividend, - NumberInterface ...$divisors + NumberInterface ...$divisors, ): NumberInterface; /** diff --git a/src/Math/RoundingMode.php b/src/Math/RoundingMode.php index e710270..1497aa6 100644 --- a/src/Math/RoundingMode.php +++ b/src/Math/RoundingMode.php @@ -31,19 +31,91 @@ declare(strict_types=1); namespace Ramsey\Uuid\Math; /** - * Specifies a rounding behavior for numerical operations capable of discarding - * precision. + * Specifies a rounding behavior for numerical operations capable of discarding precision. * - * Each rounding mode indicates how the least significant returned digit of a - * rounded result is to be calculated. If fewer digits are returned than the - * digits needed to represent the exact numerical result, the discarded digits - * will be referred to as the discarded fraction regardless the digits' - * contribution to the value of the number. In other words, considered as a - * numerical value, the discarded fraction could have an absolute value greater - * than one. + * Each rounding mode indicates how the least significant returned digit of a rounded result is to be calculated. If + * fewer digits are returned than the digits needed to represent the exact numerical result, the discarded digits will + * be referred to as the discarded fraction regardless of the digits' contribution to the value of the number. In other + * words, considered as a numerical value, the discarded fraction could have an absolute value greater than one. */ final class RoundingMode { + /** + * Asserts that the requested operation has an exact result; hence no rounding is necessary. + */ + public const UNNECESSARY = 0; + + /** + * Rounds away from zero. + * + * Always increments the digit prior to a nonzero discarded fraction. Note that this rounding mode never decreases + * the magnitude of the calculated value. + */ + public const UP = 1; + + /** + * Rounds towards zero. + * + * Never increments the digit prior to a discarded fraction (i.e., truncates). Note that this rounding mode never + * increases the magnitude of the calculated value. + */ + public const DOWN = 2; + + /** + * Rounds towards positive infinity. + * + * If the result is positive, behaves as for UP; if negative, behaves as for DOWN. Note that this rounding mode + * never decreases the calculated value. + */ + public const CEILING = 3; + + /** + * Rounds towards negative infinity. + * + * If the result is positive, behave as for DOWN; if negative, behave as for UP. Note that this rounding mode never + * increases the calculated value. + */ + public const FLOOR = 4; + + /** + * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round up. + * + * Behaves as for UP if the discarded fraction is >= 0.5; otherwise, behaves as for DOWN. Note that this is the + * rounding mode commonly taught at school. + */ + public const HALF_UP = 5; + + /** + * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round down. + * + * Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves as for DOWN. + */ + public const HALF_DOWN = 6; + + /** + * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards positive infinity. + * + * If the result is positive, behaves as for HALF_UP; if negative, behaves as for HALF_DOWN. + */ + public const HALF_CEILING = 7; + + /** + * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards negative infinity. + * + * If the result is positive, behaves as for HALF_DOWN; if negative, behaves as for HALF_UP. + */ + public const HALF_FLOOR = 8; + + /** + * Rounds towards the "nearest neighbor" unless both neighbors are equidistant, in which case rounds towards the even neighbor. + * + * Behaves as for HALF_UP if the digit to the left of the discarded fraction is odd; behaves as for HALF_DOWN if it's even. + * + * Note that this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a + * sequence of calculations. It is sometimes known as "Banker's rounding", and is chiefly used in the USA. + */ + public const HALF_EVEN = 9; + /** * Private constructor. This class is not instantiable. * @@ -52,95 +124,4 @@ final class RoundingMode private function __construct() { } - - /** - * Asserts that the requested operation has an exact result, hence no - * rounding is necessary. - */ - public const UNNECESSARY = 0; - - /** - * Rounds away from zero. - * - * Always increments the digit prior to a nonzero discarded fraction. - * Note that this rounding mode never decreases the magnitude of the - * calculated value. - */ - public const UP = 1; - - /** - * Rounds towards zero. - * - * Never increments the digit prior to a discarded fraction (i.e., - * truncates). Note that this rounding mode never increases the magnitude of - * the calculated value. - */ - public const DOWN = 2; - - /** - * Rounds towards positive infinity. - * - * If the result is positive, behaves as for UP; if negative, behaves as for - * DOWN. Note that this rounding mode never decreases the calculated value. - */ - public const CEILING = 3; - - /** - * Rounds towards negative infinity. - * - * If the result is positive, behave as for DOWN; if negative, behave as for - * UP. Note that this rounding mode never increases the calculated value. - */ - public const FLOOR = 4; - - /** - * Rounds towards "nearest neighbor" unless both neighbors are equidistant, - * in which case round up. - * - * Behaves as for UP if the discarded fraction is >= 0.5; otherwise, behaves - * as for DOWN. Note that this is the rounding mode commonly taught at - * school. - */ - public const HALF_UP = 5; - - /** - * Rounds towards "nearest neighbor" unless both neighbors are equidistant, - * in which case round down. - * - * Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves - * as for DOWN. - */ - public const HALF_DOWN = 6; - - /** - * Rounds towards "nearest neighbor" unless both neighbors are equidistant, - * in which case round towards positive infinity. - * - * If the result is positive, behaves as for HALF_UP; if negative, behaves - * as for HALF_DOWN. - */ - public const HALF_CEILING = 7; - - /** - * Rounds towards "nearest neighbor" unless both neighbors are equidistant, - * in which case round towards negative infinity. - * - * If the result is positive, behaves as for HALF_DOWN; if negative, behaves - * as for HALF_UP. - */ - public const HALF_FLOOR = 8; - - /** - * Rounds towards the "nearest neighbor" unless both neighbors are - * equidistant, in which case rounds towards the even neighbor. - * - * Behaves as for HALF_UP if the digit to the left of the discarded fraction - * is odd; behaves as for HALF_DOWN if it's even. - * - * Note that this is the rounding mode that statistically minimizes - * cumulative error when applied repeatedly over a sequence of calculations. - * It is sometimes known as "Banker's rounding", and is chiefly used in the - * USA. - */ - public const HALF_EVEN = 9; } diff --git a/src/Nonstandard/Fields.php b/src/Nonstandard/Fields.php index 0a3d86e..cc7c90d 100644 --- a/src/Nonstandard/Fields.php +++ b/src/Nonstandard/Fields.php @@ -32,14 +32,12 @@ use function substr; use const STR_PAD_LEFT; /** - * Nonstandard UUID fields do not conform to the RFC 4122 standard + * Nonstandard UUID fields do not conform to the RFC 9562 (formerly RFC 4122) standard * - * Since some systems may create nonstandard UUIDs, this implements the - * Rfc4122\FieldsInterface, so that functionality of a nonstandard UUID is not - * degraded, in the event these UUIDs are expected to contain RFC 4122 fields. + * Since some systems may create nonstandard UUIDs, this implements the {@see FieldsInterface}, so that functionality of + * a nonstandard UUID is not degraded, in the event these UUIDs are expected to contain RFC 9562 (formerly RFC 4122) fields. * - * Internally, this class represents the fields together as a 16-byte binary - * string. + * Internally, this class represents the fields together as a 16-byte binary string. * * @immutable */ @@ -57,8 +55,7 @@ final class Fields implements FieldsInterface { if (strlen($this->bytes) !== 16) { throw new InvalidArgumentException( - 'The byte string must be 16 bytes long; ' - . 'received ' . strlen($this->bytes) . ' bytes' + 'The byte string must be 16 bytes long; received ' . strlen($this->bytes) . ' bytes', ); } } diff --git a/src/Nonstandard/Uuid.php b/src/Nonstandard/Uuid.php index 5810b5f..32a2496 100644 --- a/src/Nonstandard/Uuid.php +++ b/src/Nonstandard/Uuid.php @@ -20,7 +20,7 @@ use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Uuid as BaseUuid; /** - * Nonstandard\Uuid is a UUID that doesn't conform to RFC 4122 + * Nonstandard\Uuid is a UUID that doesn't conform to RFC 9562 (formerly RFC 4122) * * @immutable */ @@ -30,7 +30,7 @@ final class Uuid extends BaseUuid Fields $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, - TimeConverterInterface $timeConverter + TimeConverterInterface $timeConverter, ) { parent::__construct($fields, $numberConverter, $codec, $timeConverter); } diff --git a/src/Nonstandard/UuidBuilder.php b/src/Nonstandard/UuidBuilder.php index 279b7ef..4286c25 100644 --- a/src/Nonstandard/UuidBuilder.php +++ b/src/Nonstandard/UuidBuilder.php @@ -30,14 +30,13 @@ use Throwable; class UuidBuilder implements UuidBuilderInterface { /** - * @param NumberConverterInterface $numberConverter The number converter to - * use when constructing the Nonstandard\Uuid - * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to Unix timestamps + * @param NumberConverterInterface $numberConverter The number converter to use when constructing the Nonstandard\Uuid + * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a + * UUID to Unix timestamps */ public function __construct( private readonly NumberConverterInterface $numberConverter, - private readonly TimeConverterInterface $timeConverter + private readonly TimeConverterInterface $timeConverter, ) { } @@ -47,25 +46,19 @@ class UuidBuilder implements UuidBuilderInterface * @param CodecInterface $codec The codec to use for building this instance * @param non-empty-string $bytes The byte string from which to construct a UUID * - * @return Uuid The Nonstandard\UuidBuilder returns an instance of - * Nonstandard\Uuid + * @return Uuid The Nonstandard\UuidBuilder returns an instance of Nonstandard\Uuid */ public function build(CodecInterface $codec, string $bytes): UuidInterface { try { - return new Uuid( - $this->buildFields($bytes), - $this->numberConverter, - $codec, - $this->timeConverter - ); + return new Uuid($this->buildFields($bytes), $this->numberConverter, $codec, $this->timeConverter); } catch (Throwable $e) { throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e); } } /** - * Proxy method to allow injecting a mock, for testing + * Proxy method to allow injecting a mock for testing * * @param non-empty-string $bytes */ diff --git a/src/Nonstandard/UuidV6.php b/src/Nonstandard/UuidV6.php index c50c55b..f3df98e 100644 --- a/src/Nonstandard/UuidV6.php +++ b/src/Nonstandard/UuidV6.php @@ -28,13 +28,14 @@ use Ramsey\Uuid\TimeBasedUuidInterface; use Ramsey\Uuid\Uuid as BaseUuid; /** - * Reordered time, or version 6, UUIDs include timestamp, clock sequence, and - * node values that are combined into a 128-bit unsigned integer + * Reordered time, or version 6, UUIDs include timestamp, clock sequence, and node values that are combined into a + * 128-bit unsigned integer * * @deprecated Use {@see \Ramsey\Uuid\Rfc4122\UuidV6} instead. * * @link https://github.com/uuid6/uuid6-ietf-draft UUID version 6 IETF draft * @link http://gh.peabody.io/uuidv6/ "Version 6" UUIDs + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.6 RFC 9562, 5.6. UUID Version 6 * * @immutable */ @@ -43,26 +44,23 @@ class UuidV6 extends BaseUuid implements UuidInterface, TimeBasedUuidInterface use TimeTrait; /** - * Creates a version 6 (reordered time) UUID + * Creates a version 6 (reordered Gregorian time) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID - * @param NumberConverterInterface $numberConverter The number converter to use - * for converting hex values to/from integers - * @param CodecInterface $codec The codec to use when encoding or decoding - * UUID strings - * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to unix timestamps + * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a + * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, - TimeConverterInterface $timeConverter + TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Version::ReorderedTime) { throw new InvalidArgumentException( - 'Fields used to create a UuidV6 must represent a ' - . 'version 6 (reordered time) UUID' + 'Fields used to create a UuidV6 must represent a version 6 (reordered time) UUID', ); } @@ -85,7 +83,7 @@ class UuidV6 extends BaseUuid implements UuidInterface, TimeBasedUuidInterface $bin = (string) hex2bin($hex); /** @var LazyUuidFromString $uuid */ - $uuid = Uuid::fromBytes($bin); + $uuid = BaseUuid::fromBytes($bin); return $uuid->toUuidV1(); } @@ -106,7 +104,7 @@ class UuidV6 extends BaseUuid implements UuidInterface, TimeBasedUuidInterface $bin = (string) hex2bin($hex); /** @var LazyUuidFromString $uuid */ - $uuid = Uuid::fromBytes($bin); + $uuid = BaseUuid::fromBytes($bin); return $uuid->toUuidV6(); } diff --git a/src/Provider/Dce/SystemDceSecurityProvider.php b/src/Provider/Dce/SystemDceSecurityProvider.php index 8f6e507..e895759 100644 --- a/src/Provider/Dce/SystemDceSecurityProvider.php +++ b/src/Provider/Dce/SystemDceSecurityProvider.php @@ -42,7 +42,7 @@ class SystemDceSecurityProvider implements DceSecurityProviderInterface */ public function getUid(): IntegerObject { - /** @var IntegerObject | string | null $uid */ + /** @var IntegerObject | float | int | string | null $uid */ static $uid = null; if ($uid instanceof IntegerObject) { @@ -55,9 +55,8 @@ class SystemDceSecurityProvider implements DceSecurityProviderInterface if ($uid === '') { throw new DceSecurityException( - 'Unable to get a user identifier using the system DCE ' - . 'Security provider; please provide a custom identifier or ' - . 'use a different provider' + 'Unable to get a user identifier using the system DCE Security provider; please provide a custom ' + . 'identifier or use a different provider', ); } @@ -75,7 +74,7 @@ class SystemDceSecurityProvider implements DceSecurityProviderInterface */ public function getGid(): IntegerObject { - /** @var IntegerObject | string | null $gid */ + /** @var IntegerObject | float | int | string | null $gid */ static $gid = null; if ($gid instanceof IntegerObject) { @@ -88,9 +87,8 @@ class SystemDceSecurityProvider implements DceSecurityProviderInterface if ($gid === '') { throw new DceSecurityException( - 'Unable to get a group identifier using the system DCE ' - . 'Security provider; please provide a custom identifier or ' - . 'use a different provider' + 'Unable to get a group identifier using the system DCE Security provider; please provide a custom ' + . 'identifier or use a different provider', ); } @@ -136,9 +134,7 @@ class SystemDceSecurityProvider implements DceSecurityProviderInterface */ private function hasShellExec(): bool { - $disabledFunctions = strtolower((string) ini_get('disable_functions')); - - return !str_contains($disabledFunctions, 'shell_exec'); + return !str_contains(strtolower((string) ini_get('disable_functions')), 'shell_exec'); } /** @@ -155,17 +151,14 @@ class SystemDceSecurityProvider implements DceSecurityProviderInterface /** * Returns the user identifier for a user on a Windows system * - * Windows does not have the same concept as an effective POSIX UID for the - * running script. Instead, each user is uniquely identified by an SID - * (security identifier). The SID includes three 32-bit unsigned integers - * that make up a unique domain identifier, followed by an RID (relative - * identifier) that we will use as the UID. The primary caveat is that this - * UID may not be unique to the system, since it is, instead, unique to the - * domain. + * Windows does not have the same concept as an effective POSIX UID for the running script. Instead, each user is + * uniquely identified by an SID (security identifier). The SID includes three 32-bit unsigned integers that make up + * a unique domain identifier, followed by an RID (relative identifier) that we will use as the UID. The primary + * caveat is that this UID may not be unique to the system, since it is, instead, unique to the domain. * * @link https://www.lifewire.com/what-is-an-sid-number-2626005 What Is an SID Number? - * @link https://bit.ly/30vE7NM Well-known SID Structures - * @link https://bit.ly/2FWcYKJ Well-known security identifiers in Windows operating systems + * @link https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/81d92bba-d22b-4a8c-908a-554ab29148ab Well-known SID Structures + * @link https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers#well-known-sids Well-known SIDs * @link https://www.windows-commandline.com/get-sid-of-user/ Get SID of user */ private function getWindowsUid(): string @@ -188,11 +181,10 @@ class SystemDceSecurityProvider implements DceSecurityProviderInterface /** * Returns a group identifier for a user on a Windows system * - * Since Windows does not have the same concept as an effective POSIX GID - * for the running script, we will get the local group memberships for the - * user running the script. Then, we will get the SID (security identifier) - * for the first group that appears in that list. Finally, we will return - * the RID (relative identifier) for the group and use that as the GID. + * Since Windows does not have the same concept as an effective POSIX GID for the running script, we will get the + * local group memberships for the user running the script. Then, we will get the SID (security identifier) for the + * first group that appears in that list. Finally, we will return the RID (relative identifier) for the group and + * use that as the GID. * * @link https://www.windows-commandline.com/list-of-user-groups-command-line/ List of user groups command line */ diff --git a/src/Provider/DceSecurityProviderInterface.php b/src/Provider/DceSecurityProviderInterface.php index 8325da6..f1c3e97 100644 --- a/src/Provider/DceSecurityProviderInterface.php +++ b/src/Provider/DceSecurityProviderInterface.php @@ -18,8 +18,7 @@ use Ramsey\Uuid\Rfc4122\UuidV2; use Ramsey\Uuid\Type\Integer as IntegerObject; /** - * A DCE provider provides access to local domain identifiers for version 2, - * DCE Security, UUIDs + * A DCE provider provides access to local domain identifiers for version 2, DCE Security, UUIDs * * @see UuidV2 */ diff --git a/src/Provider/Node/FallbackNodeProvider.php b/src/Provider/Node/FallbackNodeProvider.php index 10d8aa2..2b6bc5c 100644 --- a/src/Provider/Node/FallbackNodeProvider.php +++ b/src/Provider/Node/FallbackNodeProvider.php @@ -19,8 +19,7 @@ use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Type\Hexadecimal; /** - * FallbackNodeProvider retrieves the system node ID by stepping through a list - * of providers until a node ID can be obtained + * FallbackNodeProvider retrieves the system node ID by stepping through a list of providers until a node ID can be obtained */ class FallbackNodeProvider implements NodeProviderInterface { @@ -45,10 +44,6 @@ class FallbackNodeProvider implements NodeProviderInterface } } - throw new NodeException( - 'Unable to find a suitable node provider', - 0, - $lastProviderException - ); + throw new NodeException(message: 'Unable to find a suitable node provider', previous: $lastProviderException); } } diff --git a/src/Provider/Node/RandomNodeProvider.php b/src/Provider/Node/RandomNodeProvider.php index 7614136..9334ce0 100644 --- a/src/Provider/Node/RandomNodeProvider.php +++ b/src/Provider/Node/RandomNodeProvider.php @@ -31,7 +31,7 @@ use const STR_PAD_LEFT; /** * RandomNodeProvider generates a random node ID * - * @link http://tools.ietf.org/html/rfc4122#section-4.5 RFC 4122, § 4.5: Node IDs that Do Not Identify the Host + * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.10 RFC 9562, 6.10. UUIDs That Do Not Identify the Host */ class RandomNodeProvider implements NodeProviderInterface { @@ -40,30 +40,16 @@ class RandomNodeProvider implements NodeProviderInterface try { $nodeBytes = random_bytes(6); } catch (Throwable $exception) { - throw new RandomSourceException( - $exception->getMessage(), - (int) $exception->getCode(), - $exception - ); + throw new RandomSourceException($exception->getMessage(), (int) $exception->getCode(), $exception); } // Split the node bytes for math on 32-bit systems. $nodeMsb = substr($nodeBytes, 0, 3); $nodeLsb = substr($nodeBytes, 3); - // Set the multicast bit; see RFC 4122, section 4.5. - $nodeMsb = hex2bin( - str_pad( - dechex(hexdec(bin2hex($nodeMsb)) | 0x010000), - 6, - '0', - STR_PAD_LEFT - ) - ); + // Set the multicast bit; see RFC 9562, section 6.10. + $nodeMsb = hex2bin(str_pad(dechex(hexdec(bin2hex($nodeMsb)) | 0x010000), 6, '0', STR_PAD_LEFT)); - // Recombine the node bytes. - $node = $nodeMsb . $nodeLsb; - - return new Hexadecimal(str_pad(bin2hex($node), 12, '0', STR_PAD_LEFT)); + return new Hexadecimal(str_pad(bin2hex($nodeMsb . $nodeLsb), 12, '0', STR_PAD_LEFT)); } } diff --git a/src/Provider/Node/StaticNodeProvider.php b/src/Provider/Node/StaticNodeProvider.php index 81936b4..f0f1543 100644 --- a/src/Provider/Node/StaticNodeProvider.php +++ b/src/Provider/Node/StaticNodeProvider.php @@ -29,7 +29,7 @@ use const STR_PAD_LEFT; /** * StaticNodeProvider provides a static node value with the multicast bit set * - * @link http://tools.ietf.org/html/rfc4122#section-4.5 RFC 4122, § 4.5: Node IDs that Do Not Identify the Host + * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.10 RFC 9562, 6.10. UUIDs That Do Not Identify the Host */ class StaticNodeProvider implements NodeProviderInterface { @@ -41,9 +41,7 @@ class StaticNodeProvider implements NodeProviderInterface public function __construct(Hexadecimal $node) { if (strlen($node->toString()) > 12) { - throw new InvalidArgumentException( - 'Static node value cannot be greater than 12 hexadecimal characters' - ); + throw new InvalidArgumentException('Static node value cannot be greater than 12 hexadecimal characters'); } $this->node = $this->setMulticastBit($node); @@ -61,13 +59,7 @@ class StaticNodeProvider implements NodeProviderInterface { $nodeHex = str_pad($node->toString(), 12, '0', STR_PAD_LEFT); $firstOctet = substr($nodeHex, 0, 2); - - $firstOctet = str_pad( - dechex(hexdec($firstOctet) | 0x01), - 2, - '0', - STR_PAD_LEFT - ); + $firstOctet = str_pad(dechex(hexdec($firstOctet) | 0x01), 2, '0', STR_PAD_LEFT); return new Hexadecimal($firstOctet . substr($nodeHex, 2)); } diff --git a/src/Provider/Node/SystemNodeProvider.php b/src/Provider/Node/SystemNodeProvider.php index 16ce8a9..4672b31 100644 --- a/src/Provider/Node/SystemNodeProvider.php +++ b/src/Provider/Node/SystemNodeProvider.php @@ -39,13 +39,12 @@ use const PREG_PATTERN_ORDER; /** * SystemNodeProvider retrieves the system node ID, if possible * - * The system node ID, or host ID, is often the same as the MAC address for a - * network interface on the host. + * The system node ID, or host ID, is often the same as the MAC address for a network interface on the host. */ class SystemNodeProvider implements NodeProviderInterface { /** - * Pattern to match nodes in ifconfig and ipconfig output. + * Pattern to match nodes in `ifconfig` and `ipconfig` output. */ private const IFCONFIG_PATTERN = '/[^:]([0-9a-f]{2}([:-])[0-9a-f]{2}(\2[0-9a-f]{2}){4})[^:]/i'; @@ -59,16 +58,14 @@ class SystemNodeProvider implements NodeProviderInterface $node = $this->getNodeFromSystem(); if ($node === '') { - throw new NodeException( - 'Unable to fetch a node for this system' - ); + throw new NodeException('Unable to fetch a node for this system'); } return new Hexadecimal($node); } /** - * Returns the system node, if it can find it + * Returns the system node if found */ protected function getNodeFromSystem(): string { @@ -99,9 +96,7 @@ class SystemNodeProvider implements NodeProviderInterface */ protected function getIfconfig(): string { - $disabledFunctions = strtolower((string) ini_get('disable_functions')); - - if (str_contains($disabledFunctions, 'passthru')) { + if (str_contains(strtolower((string) ini_get('disable_functions')), 'passthru')) { return ''; } @@ -147,17 +142,18 @@ class SystemNodeProvider implements NodeProviderInterface */ protected function getSysfs(): string { - $mac = ''; - /** @var string $os */ $os = constant('PHP_OS'); - if (strtoupper($os) === 'LINUX') { - $addressPaths = glob('/sys/class/net/*/address', GLOB_NOSORT); + if (strtoupper($os) !== 'LINUX') { + return ''; + } - if ($addressPaths === false || count($addressPaths) === 0) { - return ''; - } + $addressPaths = glob('/sys/class/net/*/address', GLOB_NOSORT); + + if ($addressPaths === false || count($addressPaths) === 0) { + return ''; + } /** @var string[] $macs */ $macs = []; @@ -175,9 +171,8 @@ class SystemNodeProvider implements NodeProviderInterface return $address !== '00:00:00:00:00:00' && preg_match(self::SYSFS_PATTERN, $address); }); - /** @var string|bool $mac */ - $mac = reset($macs); - } + /** @var bool | string $mac */ + $mac = reset($macs); return (string) $mac; } diff --git a/src/Provider/Time/FixedTimeProvider.php b/src/Provider/Time/FixedTimeProvider.php index 4da47a7..35de8c0 100644 --- a/src/Provider/Time/FixedTimeProvider.php +++ b/src/Provider/Time/FixedTimeProvider.php @@ -21,8 +21,7 @@ use Ramsey\Uuid\Type\Time; /** * FixedTimeProvider uses a known time to provide the time * - * This provider allows the use of a previously-generated, or known, time - * when generating time-based UUIDs. + * This provider allows the use of a previously generated, or known, time when generating time-based UUIDs. */ class FixedTimeProvider implements TimeProviderInterface { @@ -33,7 +32,7 @@ class FixedTimeProvider implements TimeProviderInterface /** * Sets the `usec` component of the time * - * @param int|string|IntegerObject $value The `usec` value to set + * @param IntegerObject | int | string $value The `usec` value to set */ public function setUsec(int | string | IntegerObject $value): void { @@ -43,7 +42,7 @@ class FixedTimeProvider implements TimeProviderInterface /** * Sets the `sec` component of the time * - * @param int|string|IntegerObject $value The `sec` value to set + * @param IntegerObject | int | string $value The `sec` value to set */ public function setSec(int | string | IntegerObject $value): void { diff --git a/src/Rfc4122/Fields.php b/src/Rfc4122/Fields.php index 628ba81..a99149b 100644 --- a/src/Rfc4122/Fields.php +++ b/src/Rfc4122/Fields.php @@ -31,10 +31,9 @@ use function unpack; use const STR_PAD_LEFT; /** - * RFC 4122 variant UUIDs consist of a set of named fields + * RFC 9562 (formerly RFC 4122) variant UUIDs consist of a set of named fields * - * Internally, this class represents the fields together as a 16-byte binary - * string. + * Internally, this class represents the fields together as a 16-byte binary string. * * @immutable */ @@ -50,27 +49,26 @@ final class Fields implements FieldsInterface * @param non-empty-string $bytes A 16-byte binary string representation of a UUID * * @throws InvalidArgumentException if the byte string is not exactly 16 bytes - * @throws InvalidArgumentException if the byte string does not represent an RFC 4122 UUID + * @throws InvalidArgumentException if the byte string does not represent an RFC 9562 (formerly RFC 4122) UUID * @throws InvalidArgumentException if the byte string does not contain a valid version */ public function __construct(private readonly string $bytes) { if (strlen($this->bytes) !== 16) { throw new InvalidArgumentException( - 'The byte string must be 16 bytes long; ' - . 'received ' . strlen($this->bytes) . ' bytes' + 'The byte string must be 16 bytes long; ' . 'received ' . strlen($this->bytes) . ' bytes', ); } if (!$this->isCorrectVariant()) { throw new InvalidArgumentException( - 'The byte string received does not conform to the RFC 4122 variant' + 'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) variant', ); } if (!$this->isCorrectVersion()) { throw new InvalidArgumentException( - 'The byte string received does not contain a valid RFC 4122 version' + 'The byte string received does not contain a valid RFC 9562 (formerly RFC 4122) version', ); } } @@ -144,22 +142,18 @@ final class Fields implements FieldsInterface /** * Returns the full 60-bit timestamp, without the version * - * For version 2 UUIDs, the time_low field is the local identifier and - * should not be returned as part of the time. For this reason, we set the - * bottom 32 bits of the timestamp to 0's. As a result, there is some loss - * of fidelity of the timestamp, for version 2 UUIDs. The timestamp can be - * off by a range of 0 to 429.4967295 seconds (or 7 minutes, 9 seconds, and - * 496730 microseconds). + * For version 2 UUIDs, the time_low field is the local identifier and should not be returned as part of the time. + * For this reason, we set the bottom 32 bits of the timestamp to 0's. As a result, there is some loss of timestamp + * fidelity, for version 2 UUIDs. The timestamp can be off by a range of 0 to 429.4967295 seconds (or 7 minutes, 9 + * seconds, and 496,730 microseconds). * - * For version 6 UUIDs, the timestamp order is reversed from the typical RFC - * 4122 order (the time bits are in the correct bit order, so that it is - * monotonically increasing). In returning the timestamp value, we put the - * bits in the order: time_low + time_mid + time_hi. + * For version 6 UUIDs, the timestamp order is reversed from the typical RFC 9562 (formerly RFC 4122) order (the + * time bits are in the correct bit order, so that it is monotonically increasing). In returning the timestamp + * value, we put the bits in the order: time_low + time_mid + time_hi. */ public function getTimestamp(): Hexadecimal { - /** @var non-empty-string $timestamp */ - $timestamp = match ($this->getVersion()) { + return new Hexadecimal(match ($this->getVersion()) { Version::DceSecurity => sprintf( '%03x%04s%08s', hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, @@ -172,9 +166,8 @@ final class Fields implements FieldsInterface $this->getTimeMid()->toString(), hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff ), - // The Unix timestamp in version 7 UUIDs is a 48-bit number, - // but for consistency, we will return a 60-bit number, padded - // to the left with zeros. + // The Unix timestamp in version 7 UUIDs is a 48-bit number, but for consistency, we will return a 60-bit + // number, padded to the left with zeros. Version::UnixTime => sprintf( '%011s%04s', $this->getTimeLow()->toString(), @@ -186,9 +179,7 @@ final class Fields implements FieldsInterface $this->getTimeMid()->toString(), $this->getTimeLow()->toString() ), - }; - - return new Hexadecimal($timestamp); + }); } public function getVersion(): ?Version diff --git a/src/Rfc4122/FieldsInterface.php b/src/Rfc4122/FieldsInterface.php index 732556a..311323e 100644 --- a/src/Rfc4122/FieldsInterface.php +++ b/src/Rfc4122/FieldsInterface.php @@ -19,30 +19,30 @@ use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Variant; /** - * RFC 4122 defines fields for a specific variant of UUID + * UUID fields, as defined by RFC 4122 + * + * This interface defines the fields of an RFC 4122 variant UUID. Since RFC 9562 removed the concept of fields and + * instead defined layouts that are specific to a given version, this interface is a legacy artifact of the earlier, and + * now obsolete, RFC 4122. * * The fields of an RFC 4122 variant UUID are: * * * **time_low**: The low field of the timestamp, an unsigned 32-bit integer * * **time_mid**: The middle field of the timestamp, an unsigned 16-bit integer - * * **time_hi_and_version**: The high field of the timestamp multiplexed with - * the version number, an unsigned 16-bit integer - * * **clock_seq_hi_and_reserved**: The high field of the clock sequence - * multiplexed with the variant, an unsigned 8-bit integer - * * **clock_seq_low**: The low field of the clock sequence, an unsigned - * 8-bit integer - * * **node**: The spatially unique node identifier, an unsigned 48-bit - * integer + * * **time_hi_and_version**: The high field of the timestamp multiplexed with the version number, an unsigned 16-bit integer + * * **clock_seq_hi_and_reserved**: The high field of the clock sequence multiplexed with the variant, an unsigned 8-bit integer + * * **clock_seq_low**: The low field of the clock sequence, an unsigned 8-bit integer + * * **node**: The spatially unique node identifier, an unsigned 48-bit integer * - * @link http://tools.ietf.org/html/rfc4122#section-4.1 RFC 4122, § 4.1: Format + * @link https://www.rfc-editor.org/rfc/rfc4122#section-4.1 RFC 4122, 4.1. Format + * @link https://www.rfc-editor.org/rfc/rfc9562#section-4 RFC 9562, 4. UUID Format * * @immutable */ interface FieldsInterface extends BaseFieldsInterface { /** - * Returns the full 16-bit clock sequence, with the variant bits (two most - * significant bits) masked out + * Returns the full 16-bit clock sequence, with the variant bits (two most significant bits) masked out */ public function getClockSeq(): Hexadecimal; @@ -84,46 +84,44 @@ interface FieldsInterface extends BaseFieldsInterface /** * Returns the variant * - * The variant number describes the layout of the UUID. The variant - * number has the following meaning: + * The variant number describes the layout of the UUID. The variant number has the following meaning: * * - 0 - Reserved for NCS backward compatibility - * - 2 - The RFC 4122 variant + * - 2 - The RFC 9562 (formerly RFC 4122) variant * - 6 - Reserved, Microsoft Corporation backward compatibility * - 7 - Reserved for future definition * - * For RFC 4122 variant UUIDs, this value should always be the integer `2`. + * For RFC 9562 (formerly RFC 4122) variant UUIDs, this value should always be the integer `2`. * - * @link http://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant + * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field */ public function getVariant(): Variant; /** - * Returns the version + * Returns the UUID version * - * The version number describes how the UUID was generated and has the - * following meaning: + * The version number describes how the UUID was generated and has the following meaning: * * 1. Gregorian time UUID * 2. DCE security UUID * 3. Name-based UUID hashed with MD5 * 4. Randomly generated UUID * 5. Name-based UUID hashed with SHA-1 - * 6. Reordered time UUID + * 6. Reordered Gregorian time UUID * 7. Unix Epoch time UUID + * 8. Custom format UUID * - * This returns `null` if the UUID is not an RFC 4122 variant, since version - * is only meaningful for this variant. + * This returns `null` if the UUID is not an RFC 9562 (formerly RFC 4122) variant, since the version is only + * meaningful for this variant. * - * @link http://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version + * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field */ public function getVersion(): ?Version; /** * Returns true if these fields represent a nil UUID * - * The nil UUID is special form of UUID that is specified to have all 128 - * bits set to zero. + * The nil UUID is a special form of UUID that is specified to have all 128 bits set to zero. */ public function isNil(): bool; } diff --git a/src/Rfc4122/MaxTrait.php b/src/Rfc4122/MaxTrait.php index 9bdbb10..988b524 100644 --- a/src/Rfc4122/MaxTrait.php +++ b/src/Rfc4122/MaxTrait.php @@ -17,11 +17,6 @@ namespace Ramsey\Uuid\Rfc4122; /** * Provides common functionality for max UUIDs * - * The max UUID is special form of UUID that is specified to have all 128 bits - * set to one. It is the inverse of the nil UUID. - * - * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.10 Max UUID - * * @immutable */ trait MaxTrait diff --git a/src/Rfc4122/MaxUuid.php b/src/Rfc4122/MaxUuid.php index 7143885..ac50bce 100644 --- a/src/Rfc4122/MaxUuid.php +++ b/src/Rfc4122/MaxUuid.php @@ -17,8 +17,9 @@ namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Uuid; /** - * The max UUID is special form of UUID that is specified to have all 128 bits - * set to one + * The max UUID is a special form of UUID that has all 128 bits set to one (`1`) + * + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.10 RFC 9562, 5.10. Max UUID * * @immutable */ diff --git a/src/Rfc4122/NilTrait.php b/src/Rfc4122/NilTrait.php index 8bbe13e..6461e96 100644 --- a/src/Rfc4122/NilTrait.php +++ b/src/Rfc4122/NilTrait.php @@ -17,11 +17,6 @@ namespace Ramsey\Uuid\Rfc4122; /** * Provides common functionality for nil UUIDs * - * The nil UUID is special form of UUID that is specified to have all 128 bits - * set to zero. - * - * @link https://tools.ietf.org/html/rfc4122#section-4.1.7 RFC 4122, § 4.1.7: Nil UUID - * * @immutable */ trait NilTrait diff --git a/src/Rfc4122/NilUuid.php b/src/Rfc4122/NilUuid.php index 831378e..a139de7 100644 --- a/src/Rfc4122/NilUuid.php +++ b/src/Rfc4122/NilUuid.php @@ -17,8 +17,9 @@ namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Uuid; /** - * The nil UUID is special form of UUID that is specified to have all 128 bits - * set to zero + * The nil UUID is a special form of UUID that has all 128 bits set to zero (`0`) + * + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.9 RFC 9562, 5.9. Nil UUID * * @immutable */ diff --git a/src/Rfc4122/TimeTrait.php b/src/Rfc4122/TimeTrait.php index 068b0bc..7384d9c 100644 --- a/src/Rfc4122/TimeTrait.php +++ b/src/Rfc4122/TimeTrait.php @@ -31,11 +31,9 @@ use const STR_PAD_LEFT; trait TimeTrait { /** - * Returns a DateTimeInterface object representing the timestamp associated - * with the UUID + * Returns a DateTimeInterface object representing the timestamp associated with the UUID * - * @return DateTimeImmutable A PHP DateTimeImmutable instance representing - * the timestamp of a time-based UUID + * @return DateTimeImmutable A PHP DateTimeImmutable instance representing the timestamp of a time-based UUID */ public function getDateTime(): DateTimeInterface { diff --git a/src/Rfc4122/UuidBuilder.php b/src/Rfc4122/UuidBuilder.php index 0427094..d58e350 100644 --- a/src/Rfc4122/UuidBuilder.php +++ b/src/Rfc4122/UuidBuilder.php @@ -27,7 +27,7 @@ use Ramsey\Uuid\UuidInterface; use Throwable; /** - * UuidBuilder builds instances of RFC 4122 UUIDs + * UuidBuilder builds instances of RFC 9562 (formerly 4122) UUIDs * * @immutable */ @@ -36,19 +36,16 @@ class UuidBuilder implements UuidBuilderInterface /** * Constructs the UUID builder * - * @param NumberConverterInterface $numberConverter The number converter to - * use when constructing the Uuid - * @param TimeConverterInterface $timeConverter The time converter to use - * for converting Gregorian time extracted from version 1, 2, and 6 - * UUIDs to Unix timestamps - * @param TimeConverterInterface $unixTimeConverter The time converter - * to use for converter Unix Epoch time extracted from version 7 UUIDs - * to Unix timestamps + * @param NumberConverterInterface $numberConverter The number converter to use when constructing the Uuid + * @param TimeConverterInterface $timeConverter The time converter to use for converting Gregorian time extracted + * from version 1, 2, and 6 UUIDs to Unix timestamps + * @param TimeConverterInterface $unixTimeConverter The time converter to use for converter Unix Epoch time + * extracted from version 7 UUIDs to Unix timestamps */ public function __construct( private readonly NumberConverterInterface $numberConverter, private readonly TimeConverterInterface $timeConverter, - private readonly TimeConverterInterface $unixTimeConverter = new UnixTimeConverter(new BrickMathCalculator()) + private readonly TimeConverterInterface $unixTimeConverter = new UnixTimeConverter(new BrickMathCalculator()), ) { } @@ -74,36 +71,26 @@ class UuidBuilder implements UuidBuilderInterface return new MaxUuid($fields, $this->numberConverter, $codec, $this->timeConverter); } - switch ($fields->getVersion()) { - case Version::Time: - return new UuidV1($fields, $this->numberConverter, $codec, $this->timeConverter); - case Version::DceSecurity: - return new UuidV2($fields, $this->numberConverter, $codec, $this->timeConverter); - case Version::HashMd5: - return new UuidV3($fields, $this->numberConverter, $codec, $this->timeConverter); - case Version::Random: - return new UuidV4($fields, $this->numberConverter, $codec, $this->timeConverter); - case Version::HashSha1: - return new UuidV5($fields, $this->numberConverter, $codec, $this->timeConverter); - case Version::ReorderedTime: - return new UuidV6($fields, $this->numberConverter, $codec, $this->timeConverter); - case Version::UnixTime: - return new UuidV7($fields, $this->numberConverter, $codec, $this->unixTimeConverter); - case Version::Custom: - return new UuidV8($fields, $this->numberConverter, $codec, $this->timeConverter); - } - - throw new UnsupportedOperationException( - 'The UUID version in the given fields is not supported ' - . 'by this UUID builder' - ); + return match ($fields->getVersion()) { + Version::Time => new UuidV1($fields, $this->numberConverter, $codec, $this->timeConverter), + Version::DceSecurity => new UuidV2($fields, $this->numberConverter, $codec, $this->timeConverter), + Version::HashMd5 => new UuidV3($fields, $this->numberConverter, $codec, $this->timeConverter), + Version::Random => new UuidV4($fields, $this->numberConverter, $codec, $this->timeConverter), + Version::HashSha1 => new UuidV5($fields, $this->numberConverter, $codec, $this->timeConverter), + Version::ReorderedTime => new UuidV6($fields, $this->numberConverter, $codec, $this->timeConverter), + Version::UnixTime => new UuidV7($fields, $this->numberConverter, $codec, $this->unixTimeConverter), + Version::Custom => new UuidV8($fields, $this->numberConverter, $codec, $this->timeConverter), + default => throw new UnsupportedOperationException( + 'The UUID version in the given fields is not supported by this UUID builder', + ), + }; } catch (Throwable $e) { throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e); } } /** - * Proxy method to allow injecting a mock, for testing + * Proxy method to allow injecting a mock for testing * * @param non-empty-string $bytes */ diff --git a/src/Rfc4122/UuidInterface.php b/src/Rfc4122/UuidInterface.php index 69f26b9..4d9fa5a 100644 --- a/src/Rfc4122/UuidInterface.php +++ b/src/Rfc4122/UuidInterface.php @@ -17,10 +17,9 @@ namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\UuidInterface as BaseUuidInterface; /** - * Also known as a Leach-Salz variant UUID, an RFC 4122 variant UUID is a - * universally unique identifier defined by RFC 4122 + * A universally unique identifier (UUID), as defined in RFC 9562 (formerly RFC 4122) * - * @link https://tools.ietf.org/html/rfc4122 RFC 4122 + * @link https://www.rfc-editor.org/rfc/rfc9562 RFC 9562 * * @immutable */ diff --git a/src/Rfc4122/UuidV1.php b/src/Rfc4122/UuidV1.php index af16c25..6a3d997 100644 --- a/src/Rfc4122/UuidV1.php +++ b/src/Rfc4122/UuidV1.php @@ -23,8 +23,9 @@ use Ramsey\Uuid\TimeBasedUuidInterface; use Ramsey\Uuid\Uuid; /** - * Gregorian time, or version 1, UUIDs include timestamp, clock sequence, and node - * values that are combined into a 128-bit unsigned integer + * Gregorian time, or version 1, UUIDs include timestamp, clock sequence, and node values, combined into a 128-bit unsigned integer + * + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.1 RFC 9562, 5.1. UUID Version 1 * * @immutable */ @@ -36,23 +37,20 @@ final class UuidV1 extends Uuid implements UuidInterface, TimeBasedUuidInterface * Creates a version 1 (Gregorian time) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID - * @param NumberConverterInterface $numberConverter The number converter to use - * for converting hex values to/from integers - * @param CodecInterface $codec The codec to use when encoding or decoding - * UUID strings - * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to unix timestamps + * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a + * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, - TimeConverterInterface $timeConverter + TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Version::Time) { throw new InvalidArgumentException( - 'Fields used to create a UuidV1 must represent a ' - . 'version 1 (time-based) UUID' + 'Fields used to create a UuidV1 must represent a version 1 (time-based) UUID', ); } diff --git a/src/Rfc4122/UuidV2.php b/src/Rfc4122/UuidV2.php index 7c1623a..4992b6c 100644 --- a/src/Rfc4122/UuidV2.php +++ b/src/Rfc4122/UuidV2.php @@ -26,22 +26,19 @@ use Ramsey\Uuid\Uuid; use function hexdec; /** - * DCE Security version, or version 2, UUIDs include local domain identifier, - * local ID for the specified domain, and node values that are combined into a - * 128-bit unsigned integer + * DCE Security version, or version 2, UUIDs include local domain identifier, local ID for the specified domain, and + * node values that are combined into a 128-bit unsigned integer * - * It is important to note that a version 2 UUID suffers from some loss of - * fidelity of the timestamp, due to replacing the time_low field with the - * local identifier. When constructing the timestamp value for date - * purposes, we replace the local identifier bits with zeros. As a result, - * the timestamp can be off by a range of 0 to 429.4967295 seconds (or 7 - * minutes, 9 seconds, and 496730 microseconds). + * It is important to note that a version 2 UUID suffers from some loss of timestamp fidelity, due to replacing the + * time_low field with the local identifier. When constructing the timestamp value for date purposes, we replace the + * local identifier bits with zeros. As a result, the timestamp can be off by a range of 0 to 429.4967295 seconds (or 7 + * minutes, 9 seconds, and 496,730 microseconds). * - * Astute observers might note this value directly corresponds to 2^32 - 1, - * or 0xffffffff. The local identifier is 32-bits, and we have set each of - * these bits to 0, so the maximum range of timestamp drift is 0x00000000 - * to 0xffffffff (counted in 100-nanosecond intervals). + * Astute observers might note this value directly corresponds to `2^32-1`, or `0xffffffff`. The local identifier is + * 32-bits, and we have set each of these bits to `0`, so the maximum range of timestamp drift is `0x00000000` to + * `0xffffffff` (counted in 100-nanosecond intervals). * + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.2 RFC 9562, 5.2. UUID Version 2 * @link https://publications.opengroup.org/c311 DCE 1.1: Authentication and Security Services * @link https://publications.opengroup.org/c706 DCE 1.1: Remote Procedure Call * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01 DCE 1.1: Auth & Sec, §5.2.1.1 @@ -59,23 +56,20 @@ final class UuidV2 extends Uuid implements UuidInterface, TimeBasedUuidInterface * Creates a version 2 (DCE Security) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID - * @param NumberConverterInterface $numberConverter The number converter to use - * for converting hex values to/from integers - * @param CodecInterface $codec The codec to use when encoding or decoding - * UUID strings - * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to unix timestamps + * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a + * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, - TimeConverterInterface $timeConverter + TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Version::DceSecurity) { throw new InvalidArgumentException( - 'Fields used to create a UuidV2 must represent a ' - . 'version 2 (DCE Security) UUID' + 'Fields used to create a UuidV2 must represent a version 2 (DCE Security) UUID' ); } @@ -112,8 +106,6 @@ final class UuidV2 extends Uuid implements UuidInterface, TimeBasedUuidInterface { $fields = $this->getFields(); - return new IntegerObject( - $this->getNumberConverter()->fromHex($fields->getTimeLow()->toString()) - ); + return new IntegerObject($this->getNumberConverter()->fromHex($fields->getTimeLow()->toString())); } } diff --git a/src/Rfc4122/UuidV3.php b/src/Rfc4122/UuidV3.php index 2a887f6..ff4bdff 100644 --- a/src/Rfc4122/UuidV3.php +++ b/src/Rfc4122/UuidV3.php @@ -22,8 +22,10 @@ use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; /** - * Version 3 UUIDs are named-based, using a combination of a namespace and name - * that are hashed into a 128-bit unsigned integer using MD5 + * Version 3 UUIDs are named-based, using a combination of a namespace and name that are hashed into a 128-bit unsigned + * integer using the MD5 hashing algorithm + * + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.3 RFC 9562, 5.3. UUID Version 3 * * @immutable */ @@ -33,23 +35,20 @@ final class UuidV3 extends Uuid implements UuidInterface * Creates a version 3 (name-based, MD5-hashed) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID - * @param NumberConverterInterface $numberConverter The number converter to use - * for converting hex values to/from integers - * @param CodecInterface $codec The codec to use when encoding or decoding - * UUID strings - * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to unix timestamps + * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a + * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, - TimeConverterInterface $timeConverter + TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Version::HashMd5) { throw new InvalidArgumentException( - 'Fields used to create a UuidV3 must represent a ' - . 'version 3 (name-based, MD5-hashed) UUID' + 'Fields used to create a UuidV3 must represent a version 3 (name-based, MD5-hashed) UUID', ); } diff --git a/src/Rfc4122/UuidV4.php b/src/Rfc4122/UuidV4.php index e3eca6f..08c4276 100644 --- a/src/Rfc4122/UuidV4.php +++ b/src/Rfc4122/UuidV4.php @@ -22,8 +22,9 @@ use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; /** - * Random, or version 4, UUIDs are randomly or pseudo-randomly generated 128-bit - * integers + * Random, or version 4, UUIDs are randomly or pseudo-randomly generated 128-bit integers + * + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.4 RFC 9562, 5.4. UUID Version 4 * * @immutable */ @@ -33,23 +34,20 @@ final class UuidV4 extends Uuid implements UuidInterface * Creates a version 4 (random) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID - * @param NumberConverterInterface $numberConverter The number converter to use - * for converting hex values to/from integers - * @param CodecInterface $codec The codec to use when encoding or decoding - * UUID strings - * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to unix timestamps + * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a + * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, - TimeConverterInterface $timeConverter + TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Version::Random) { throw new InvalidArgumentException( - 'Fields used to create a UuidV4 must represent a ' - . 'version 4 (random) UUID' + 'Fields used to create a UuidV4 must represent a version 4 (random) UUID', ); } diff --git a/src/Rfc4122/UuidV5.php b/src/Rfc4122/UuidV5.php index d6be4e4..199ca34 100644 --- a/src/Rfc4122/UuidV5.php +++ b/src/Rfc4122/UuidV5.php @@ -22,8 +22,10 @@ use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; /** - * Version 5 UUIDs are named-based, using a combination of a namespace and name - * that are hashed into a 128-bit unsigned integer using SHA1 + * Version 5 UUIDs are named-based, using a combination of a namespace and name that are hashed into a 128-bit unsigned + * integer using the SHA1 hashing algorithm + * + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.5 RFC 9562, 5.5. UUID Version 5 * * @immutable */ @@ -33,23 +35,20 @@ final class UuidV5 extends Uuid implements UuidInterface * Creates a version 5 (name-based, SHA1-hashed) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID - * @param NumberConverterInterface $numberConverter The number converter to use - * for converting hex values to/from integers - * @param CodecInterface $codec The codec to use when encoding or decoding - * UUID strings - * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to unix timestamps + * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a + * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, - TimeConverterInterface $timeConverter + TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Version::HashSha1) { throw new InvalidArgumentException( - 'Fields used to create a UuidV5 must represent a ' - . 'version 5 (named-based, SHA1-hashed) UUID' + 'Fields used to create a UuidV5 must represent a version 5 (named-based, SHA1-hashed) UUID', ); } diff --git a/src/Rfc4122/UuidV6.php b/src/Rfc4122/UuidV6.php index 4b12d90..ddfdd50 100644 --- a/src/Rfc4122/UuidV6.php +++ b/src/Rfc4122/UuidV6.php @@ -18,10 +18,10 @@ use Ramsey\Uuid\Nonstandard\UuidV6 as NonstandardUuidV6; use Ramsey\Uuid\TimeBasedUuidInterface; /** - * Reordered time, or version 6, UUIDs include timestamp, clock sequence, and - * node values that are combined into a 128-bit unsigned integer + * Reordered Gregorian time, or version 6, UUIDs include timestamp, clock sequence, and node values that are combined + * into a 128-bit unsigned integer * - * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.6 UUID Version 6 + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.6 RFC 9562, 5.6. UUID Version 6 * * @immutable */ diff --git a/src/Rfc4122/UuidV7.php b/src/Rfc4122/UuidV7.php index f5c548c..5629183 100644 --- a/src/Rfc4122/UuidV7.php +++ b/src/Rfc4122/UuidV7.php @@ -23,10 +23,9 @@ use Ramsey\Uuid\TimeBasedUuidInterface; use Ramsey\Uuid\Uuid; /** - * Unix Epoch time, or version 7, UUIDs include a timestamp in milliseconds - * since the Unix Epoch, along with random bytes + * Unix Epoch time, or version 7, UUIDs include a timestamp in milliseconds since the Unix Epoch, along with random bytes * - * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.7 UUID Version 7 + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.7 RFC 9562, 5.7. UUID Version 7 * * @immutable */ @@ -38,23 +37,20 @@ final class UuidV7 extends Uuid implements UuidInterface, TimeBasedUuidInterface * Creates a version 7 (Unix Epoch time) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID - * @param NumberConverterInterface $numberConverter The number converter to use - * for converting hex values to/from integers - * @param CodecInterface $codec The codec to use when encoding or decoding - * UUID strings - * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to unix timestamps + * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a + * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, - TimeConverterInterface $timeConverter + TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Version::UnixTime) { throw new InvalidArgumentException( - 'Fields used to create a UuidV7 must represent a ' - . 'version 7 (Unix Epoch time) UUID' + 'Fields used to create a UuidV7 must represent a version 7 (Unix Epoch time) UUID', ); } diff --git a/src/Rfc4122/UuidV8.php b/src/Rfc4122/UuidV8.php index cda5cb8..63c1092 100644 --- a/src/Rfc4122/UuidV8.php +++ b/src/Rfc4122/UuidV8.php @@ -22,41 +22,36 @@ use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; /** - * Version 8, Custom UUIDs provide an RFC 4122 compatible format for - * experimental or vendor-specific uses + * Custom format, or version 8, UUIDs provide an RFC-compatible format for experimental or vendor-specific uses * - * The only requirement for version 8 UUIDs is that the version and variant bits - * must be set. Otherwise, implementations are free to set the other bits - * according to their needs. As a result, the uniqueness of version 8 UUIDs is + * The only requirement for version 8 UUIDs is that the version and variant bits must be set. Otherwise, implementations + * are free to set the other bits according to their needs. As a result, the uniqueness of version 8 UUIDs is * implementation-specific and should not be assumed. * - * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.8 UUID Version 8 + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.8 RFC 9562, 5.8. UUID Version 8 * * @immutable */ final class UuidV8 extends Uuid implements UuidInterface { /** - * Creates a version 8 (custom) UUID + * Creates a version 8 (custom format) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID - * @param NumberConverterInterface $numberConverter The number converter to use - * for converting hex values to/from integers - * @param CodecInterface $codec The codec to use when encoding or decoding - * UUID strings - * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to unix timestamps + * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a + * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, - TimeConverterInterface $timeConverter + TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Version::Custom) { throw new InvalidArgumentException( - 'Fields used to create a UuidV8 must represent a ' - . 'version 8 (custom) UUID' + 'Fields used to create a UuidV8 must represent a version 8 (custom format) UUID', ); } diff --git a/src/Rfc4122/Validator.php b/src/Rfc4122/Validator.php index 96d0abc..d2b7645 100644 --- a/src/Rfc4122/Validator.php +++ b/src/Rfc4122/Validator.php @@ -21,7 +21,7 @@ use function preg_match; use function str_replace; /** - * Rfc4122\Validator validates strings as UUIDs of the RFC 4122 variant + * Rfc4122\Validator validates strings as UUIDs of the RFC 9562 (formerly RFC 4122) variant * * @immutable */ @@ -40,8 +40,7 @@ final class Validator implements ValidatorInterface public function validate(string $uuid): bool { - $uuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid); - $uuid = strtolower($uuid); + $uuid = strtolower(str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid)); return $uuid === Uuid::NIL || $uuid === Uuid::MAX || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); } diff --git a/src/Rfc4122/VariantTrait.php b/src/Rfc4122/VariantTrait.php index 777071a..65862ef 100644 --- a/src/Rfc4122/VariantTrait.php +++ b/src/Rfc4122/VariantTrait.php @@ -27,7 +27,7 @@ use function unpack; use const STR_PAD_LEFT; /** - * Provides common functionality for handling the variant, as defined by RFC 4122 + * Provides common functionality for handling the variant, as defined by RFC 9562 (formerly RFC 4122) * * @immutable */ @@ -39,11 +39,9 @@ trait VariantTrait abstract public function getBytes(): string; /** - * Returns the variant identifier, according to RFC 4122, for the given bytes + * Returns the variant * - * @link https://tools.ietf.org/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1: Variant - * - * @return Variant The variant identifier, according to RFC 4122 + * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field */ public function getVariant(): Variant { @@ -52,27 +50,16 @@ trait VariantTrait } if ($this->isMax() || $this->isNil()) { - // RFC 4122 defines these special types of UUID, so we will consider - // them as belonging to the RFC 4122 variant. return Variant::Rfc4122; } /** @var int[] $parts */ $parts = unpack('n*', $this->getBytes()); - // $parts[5] is a 16-bit, unsigned integer containing the variant bits - // of the UUID. We convert this integer into a string containing a - // binary representation, padded to 16 characters. We analyze the first - // three characters (three most-significant bits) to determine the - // variant. - $binary = str_pad( - decbin($parts[5]), - 16, - '0', - STR_PAD_LEFT - ); - - $msb = substr($binary, 0, 3); + // $parts[5] is a 16-bit, unsigned integer containing the variant bits of the UUID. We convert this integer into + // a string containing a binary representation, padded to 16 characters. We analyze the first three characters + // (three most-significant bits) to determine the variant. + $msb = substr(str_pad(decbin($parts[5]), 16, '0', STR_PAD_LEFT), 0, 3); if ($msb === '111') { return Variant::ReservedFuture; diff --git a/src/Rfc4122/Version.php b/src/Rfc4122/Version.php index 35ded30..1ee63fa 100644 --- a/src/Rfc4122/Version.php +++ b/src/Rfc4122/Version.php @@ -19,76 +19,58 @@ namespace Ramsey\Uuid\Rfc4122; * * The version number has the following meaning: * - * 1. Time-based UUID + * 1. Gregorian time UUID * 2. DCE security UUID * 3. Name-based UUID hashed with MD5 * 4. Randomly generated UUID * 5. Name-based UUID hashed with SHA-1 - * 6. Reordered time-based UUID - * 7. Unix Epoch time-based UUID - * 8. Implementation-specific custom UUID + * 6. Reordered Gregorian time UUID + * 7. Unix Epoch time UUID + * 8. Implementation-specific, custom format UUID * - * @link http://tools.ietf.org/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3: Version + * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field * - * phpcs:disable Generic.NamingConventions.UpperCaseConstantName.ClassConstantNotUpperCase + * phpcs:disable Generic.NamingConventions.UpperCaseConstantName */ enum Version: int { /** - * Version 1 (time-based) UUID - * - * @link https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3 + * Version 1 (Gregorian time) UUID */ case Time = 1; /** * Version 2 (DCE Security) UUID - * - * @link https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3 */ case DceSecurity = 2; /** * Version 3 (name-based and hashed with MD5) UUID - * - * @link https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3 */ case HashMd5 = 3; /** * Version 4 (random) UUID - * - * @link https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3 */ case Random = 4; /** * Version 5 (name-based and hashed with SHA1) UUID - * - * @link https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.3 RFC 4122, § 4.1.3 */ case HashSha1 = 5; /** - * Version 6 (reordered time-based) UUID - * - * @link https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-04#section-4 draft-peabody-dispatch-new-uuid-format-04, § 4 - * @link https://github.com/uuid6/uuid6-ietf-draft UUID version 6 IETF draft - * @link http://gh.peabody.io/uuidv6/ "Version 6" UUIDs + * Version 6 (reordered Gregorian time) UUID */ case ReorderedTime = 6; /** - * Version 7 (Unix Epoch time-based) UUID - * - * @link https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-04#section-4 draft-peabody-dispatch-new-uuid-format-04, § 4 + * Version 7 (Unix Epoch time) UUID */ case UnixTime = 7; /** - * Version 8 (implementation-specific custom) UUID - * - * @link https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-04#section-4 draft-peabody-dispatch-new-uuid-format-04, § 4 + * Version 8 (implementation-specific custom format) UUID */ case Custom = 8; @@ -131,9 +113,4 @@ enum Version: int * Alias for {@see self::Custom} */ public const V8 = self::Custom; - - /** - * Alias for {@see self::ReorderedTime} - */ - public const Peabody = self::ReorderedTime; } diff --git a/src/Rfc4122/VersionTrait.php b/src/Rfc4122/VersionTrait.php index b5923a0..0633e58 100644 --- a/src/Rfc4122/VersionTrait.php +++ b/src/Rfc4122/VersionTrait.php @@ -15,14 +15,19 @@ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; /** - * Provides common functionality for handling the version, as defined by RFC 4122 + * Provides common functionality for handling the version, as defined by RFC 9562 (formerly RFC 4122) * * @immutable */ trait VersionTrait { /** - * Returns the version + * Returns the UUID version + * + * This returns `null` if the UUID is not an RFC 9562 (formerly RFC 4122) variant, since the version is only + * meaningful for this variant. + * + * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field */ abstract public function getVersion(): ?Version; @@ -37,7 +42,7 @@ trait VersionTrait abstract public function isNil(): bool; /** - * Returns true if the version matches one of those defined by RFC 4122 + * Returns true if the version matches one of those defined by RFC 9562 (formerly RFC 4122) * * @return bool True if the UUID version is valid, false otherwise */ diff --git a/src/Type/Decimal.php b/src/Type/Decimal.php index 1bb8c79..bb688b6 100644 --- a/src/Type/Decimal.php +++ b/src/Type/Decimal.php @@ -26,12 +26,10 @@ use function str_starts_with; /** * A value object representing a decimal * - * This class exists for type-safety purposes, to ensure that decimals - * returned from ramsey/uuid methods as strings are truly decimals and not some - * other kind of string. + * This class exists for type-safety purposes, to ensure that decimals returned from ramsey/uuid methods as strings are + * truly decimals and not some other kind of string. * - * To support values as true decimals and not as floats or doubles, we store the - * decimals as strings. + * To support values as true decimals and not as floats or doubles, we store the decimals as strings. */ final class Decimal implements NumberInterface { diff --git a/src/Type/Hexadecimal.php b/src/Type/Hexadecimal.php index f9125cc..2268d47 100644 --- a/src/Type/Hexadecimal.php +++ b/src/Type/Hexadecimal.php @@ -26,9 +26,8 @@ use function substr; /** * A value object representing a hexadecimal number * - * This class exists for type-safety purposes, to ensure that hexadecimal numbers - * returned from ramsey/uuid methods as strings are truly hexadecimal and not some - * other kind of string. + * This class exists for type-safety purposes, to ensure that hexadecimal numbers returned from ramsey/uuid methods as + * strings are truly hexadecimal and not some other kind of string. * * @immutable */ @@ -40,7 +39,7 @@ final class Hexadecimal implements TypeInterface private readonly string $value; /** - * @param non-empty-string|self $value The hexadecimal value to store + * @param self | non-empty-string $value The hexadecimal value to store */ public function __construct(self | string $value) { @@ -107,9 +106,7 @@ final class Hexadecimal implements TypeInterface } if (!preg_match('/^[A-Fa-f0-9]+$/', $value)) { - throw new InvalidArgumentException( - 'Value must be a hexadecimal number' - ); + throw new InvalidArgumentException('Value must be a hexadecimal number'); } /** @var non-empty-string */ diff --git a/src/Type/Integer.php b/src/Type/Integer.php index 0948048..b0f7896 100644 --- a/src/Type/Integer.php +++ b/src/Type/Integer.php @@ -27,12 +27,11 @@ use function substr; /** * A value object representing an integer * - * This class exists for type-safety purposes, to ensure that integers - * returned from ramsey/uuid methods as strings are truly integers and not some - * other kind of string. + * This class exists for type-safety purposes, to ensure that integers returned from ramsey/uuid methods as strings are + * truly integers and not some other kind of string. * - * To support large integers beyond PHP_INT_MAX and PHP_INT_MIN on both 64-bit - * and 32-bit systems, we store the integers as strings. + * To support large integers beyond PHP_INT_MAX and PHP_INT_MIN on both 64-bit and 32-bit systems, we store the integers + * as strings. * * @immutable */ @@ -48,7 +47,7 @@ final class Integer implements NumberInterface */ private bool $isNegative = false; - public function __construct(float | int | self | string $value) + public function __construct(self | float | int | string $value) { $this->value = $value instanceof self ? (string) $value : $this->prepareValue($value); } @@ -112,7 +111,7 @@ final class Integer implements NumberInterface $value = (string) $value; $sign = '+'; - // If the value contains a sign, remove it for digit pattern check. + // If the value contains a sign, remove it for the digit pattern check. if (str_starts_with($value, '-') || str_starts_with($value, '+')) { $sign = substr($value, 0, 1); $value = substr($value, 1); diff --git a/src/Type/Time.php b/src/Type/Time.php index fccaff7..89625c6 100644 --- a/src/Type/Time.php +++ b/src/Type/Time.php @@ -22,9 +22,8 @@ use function sprintf; /** * A value object representing a timestamp * - * This class exists for type-safety purposes, to ensure that timestamps used - * by ramsey/uuid are truly timestamp integers and not some other kind of string - * or integer. + * This class exists for type-safety purposes, to ensure that timestamps used by ramsey/uuid are truly timestamp + * integers and not some other kind of string or integer. * * @immutable */ @@ -34,8 +33,8 @@ final class Time implements TypeInterface private readonly IntegerObject $microseconds; public function __construct( - int | float | string | IntegerObject $seconds, - int | float | string | IntegerObject $microseconds = new IntegerObject(0), + IntegerObject | float | int | string $seconds, + IntegerObject | float | int | string $microseconds = new IntegerObject(0), ) { $this->seconds = $seconds instanceof IntegerObject ? $seconds : new IntegerObject($seconds); $this->microseconds = $microseconds instanceof IntegerObject ? $microseconds : new IntegerObject($microseconds); diff --git a/src/Uuid.php b/src/Uuid.php index 5cd6797..f3fcc31 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -47,48 +47,44 @@ use function substr; class Uuid implements Rfc4122UuidInterface { /** - * When this namespace is specified, the name string is a fully qualified - * domain name + * When this namespace is specified, the name string is a fully qualified domain name * - * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs + * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.6 RFC 9562, 6.6. Namespace ID Usage and Allocation */ public const NAMESPACE_DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; /** * When this namespace is specified, the name string is a URL * - * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs + * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.6 RFC 9562, 6.6. Namespace ID Usage and Allocation */ public const NAMESPACE_URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; /** * When this namespace is specified, the name string is an ISO OID * - * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs + * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.6 RFC 9562, 6.6. Namespace ID Usage and Allocation */ public const NAMESPACE_OID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8'; /** - * When this namespace is specified, the name string is an X.500 DN in DER - * or a text output format + * When this namespace is specified, the name string is an X.500 DN (in DER or a text output format) * - * @link http://tools.ietf.org/html/rfc4122#appendix-C RFC 4122, Appendix C: Some Name Space IDs + * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.6 RFC 9562, 6.6. Namespace ID Usage and Allocation */ public const NAMESPACE_X500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8'; /** - * The nil UUID is a special form of UUID that is specified to have all 128 - * bits set to zero + * The Nil UUID is a special form of UUID that is specified to have all 128 bits set to zero * - * @link http://tools.ietf.org/html/rfc4122#section-4.1.7 RFC 4122, § 4.1.7: Nil UUID + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.9 RFC 9562, 5.9. Nil UUID */ public const NIL = '00000000-0000-0000-0000-000000000000'; /** - * The max UUID is a special form of UUID that is specified to have all 128 - * bits set to one + * The Max UUID is a special form of UUID that is specified to have all 128 bits set to one * - * @link https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.10 Max UUID + * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.10 RFC 9562, 5.10. Max UUID */ public const MAX = 'ffffffff-ffff-ffff-ffff-ffffffffffff'; @@ -130,9 +126,8 @@ class Uuid implements Rfc4122UuidInterface private static ?UuidFactoryInterface $factory = null; /** - * @var bool flag to detect if the UUID factory was replaced internally, - * which disables all optimizations for the default/happy path internal - * scenarios + * @var bool flag to detect if the UUID factory was replaced internally, which disables all optimizations for the + * default/happy path internal scenarios * @phpstan-ignore property.readOnlyByPhpDocDefaultValue */ private static bool $factoryReplaced = false; @@ -140,9 +135,8 @@ class Uuid implements Rfc4122UuidInterface /** * Creates a universally unique identifier (UUID) from an array of fields * - * Unless you're making advanced use of this library to generate identifiers - * that deviate from RFC 4122, you probably do not want to instantiate a - * UUID directly. Use the static methods, instead: + * Unless you're making advanced use of this library to generate identifiers that deviate from RFC 9562 (formerly + * RFC 4122), you probably do not want to instantiate a UUID directly. Use the static methods, instead: * * ``` * use Ramsey\Uuid\Uuid; @@ -154,18 +148,16 @@ class Uuid implements Rfc4122UuidInterface * ``` * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID - * @param NumberConverterInterface $numberConverter The number converter to use - * for converting hex values to/from integers - * @param CodecInterface $codec The codec to use when encoding or decoding - * UUID strings - * @param TimeConverterInterface $timeConverter The time converter to use - * for converting timestamps extracted from a UUID to unix timestamps + * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers + * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings + * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a + * UUID to unix timestamps */ public function __construct( private readonly Rfc4122FieldsInterface $fields, private readonly NumberConverterInterface $numberConverter, private readonly CodecInterface $codec, - private readonly TimeConverterInterface $timeConverter + private readonly TimeConverterInterface $timeConverter, ) { } @@ -312,8 +304,7 @@ class Uuid implements Rfc4122UuidInterface /** * Sets the factory used to create UUIDs * - * @param UuidFactoryInterface $factory A factory that will be used by this - * class to create UUIDs + * @param UuidFactoryInterface $factory A factory that will be used by this class to create UUIDs */ public static function setFactory(UuidFactoryInterface $factory): void { @@ -330,8 +321,7 @@ class Uuid implements Rfc4122UuidInterface * * @param non-empty-string $bytes A binary string * - * @return UuidInterface A UuidInterface instance created from a binary - * string representation + * @return UuidInterface A UuidInterface instance created from a binary string representation * * @throws InvalidArgumentException */ @@ -350,7 +340,7 @@ class Uuid implements Rfc4122UuidInterface . '-' . substr($base16Uuid, 16, 4) . '-' - . substr($base16Uuid, 20, 12) + . substr($base16Uuid, 20, 12), ); } @@ -362,8 +352,7 @@ class Uuid implements Rfc4122UuidInterface * * @param non-empty-string $uuid A hexadecimal string * - * @return UuidInterface A UuidInterface instance created from a hexadecimal - * string representation + * @return UuidInterface A UuidInterface instance created from a hexadecimal string representation * * @throws InvalidArgumentException */ @@ -383,14 +372,11 @@ class Uuid implements Rfc4122UuidInterface * Creates a UUID from a DateTimeInterface instance * * @param DateTimeInterface $dateTime The date and time - * @param Hexadecimal|null $node A 48-bit number representing the hardware - * address - * @param int<0, 16383>|null $clockSeq A 14-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time - * or if the node ID changes + * @param Hexadecimal | null $node A 48-bit number representing the hardware address + * @param int<0, 16383> | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set + * backwards in time or if the node ID changes * - * @return UuidInterface A UuidInterface instance that represents a - * version 1 UUID created from a DateTimeInterface instance + * @return UuidInterface A UuidInterface instance that represents a version 1 UUID created from a DateTimeInterface instance */ public static function fromDateTime( DateTimeInterface $dateTime, @@ -405,8 +391,7 @@ class Uuid implements Rfc4122UuidInterface * * @param Hexadecimal $hex Hexadecimal object representing a hexadecimal number * - * @return UuidInterface A UuidInterface instance created from the Hexadecimal - * object representing a hexadecimal number + * @return UuidInterface A UuidInterface instance created from the Hexadecimal object representing a hexadecimal number * * @throws InvalidArgumentException */ @@ -429,8 +414,7 @@ class Uuid implements Rfc4122UuidInterface * * @param numeric-string $integer String representation of 128-bit integer * - * @return UuidInterface A UuidInterface instance created from the string - * representation of a 128-bit integer + * @return UuidInterface A UuidInterface instance created from the string representation of a 128-bit integer * * @throws InvalidArgumentException */ @@ -454,18 +438,14 @@ class Uuid implements Rfc4122UuidInterface } /** - * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, - * and the current time + * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, and the current time * - * @param Hexadecimal|positive-int|non-empty-string|null $node A 48-bit - * number representing the hardware address; this number may be - * represented as an integer or a hexadecimal string - * @param int<0, 16383>|null $clockSeq A 14-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time - * or if the node ID changes + * @param Hexadecimal | non-empty-string | positive-int | null $node A 48-bit number representing the hardware + * address; this number may be represented as an integer or a hexadecimal string + * @param int<0, 16383> | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the + * clock is set backwards in time or if the node ID changes * - * @return UuidInterface A UuidInterface instance that represents a - * version 1 UUID + * @return UuidInterface A UuidInterface instance that represents a version 1 UUID */ public static function uuid1(Hexadecimal | int | string | null $node = null, ?int $clockSeq = null): UuidInterface { @@ -473,24 +453,18 @@ class Uuid implements Rfc4122UuidInterface } /** - * Returns a version 2 (DCE Security) UUID from a local domain, local - * identifier, host ID, clock sequence, and the current time + * Returns a version 2 (DCE Security) UUID from a local domain, local identifier, host ID, clock sequence, and the current time * - * @param int $localDomain The local domain to use when generating bytes, - * according to DCE Security - * @param IntegerObject|null $localIdentifier The local identifier for the - * given domain; this may be a UID or GID on POSIX systems, if the local - * domain is person or group, or it may be a site-defined identifier - * if the local domain is org - * @param Hexadecimal|null $node A 48-bit number representing the hardware - * address - * @param int<0, 63>|null $clockSeq A 6-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time - * or if the node ID changes (in a version 2 UUID, the lower 8 bits of - * this number are replaced with the domain) + * @param int $localDomain The local domain to use when generating bytes, according to DCE Security + * @param IntegerObject | null $localIdentifier The local identifier for the given domain; this may be a UID or GID + * on POSIX systems, if the local domain is "person" or "group," or it may be a site-defined identifier if the + * local domain is "org" + * @param Hexadecimal | null $node A 48-bit number representing the hardware address + * @param int<0, 63> | null $clockSeq A 6-bit number used to help avoid duplicates that could arise when the clock + * is set backwards in time or if the node ID changes (in a version 2 UUID, the lower 8 bits of this number are + * replaced with the domain). * - * @return UuidInterface A UuidInterface instance that represents a - * version 2 UUID + * @return UuidInterface A UuidInterface instance that represents a version 2 UUID */ public static function uuid2( int $localDomain, @@ -502,14 +476,12 @@ class Uuid implements Rfc4122UuidInterface } /** - * Returns a version 3 (name-based) UUID based on the MD5 hash of a - * namespace ID and a name + * Returns a version 3 (name-based) UUID based on the MD5 hash of a namespace ID and a name * - * @param non-empty-string|UuidInterface $ns The namespace (must be a valid UUID) + * @param UuidInterface | non-empty-string $ns The namespace (must be a valid UUID) * @param string $name The name to use for creating a UUID * - * @return UuidInterface A UuidInterface instance that represents a - * version 3 UUID + * @return UuidInterface A UuidInterface instance that represents a version 3 UUID */ public static function uuid3(UuidInterface | string $ns, string $name): UuidInterface { @@ -519,8 +491,7 @@ class Uuid implements Rfc4122UuidInterface /** * Returns a version 4 (random) UUID * - * @return UuidInterface A UuidInterface instance that represents a - * version 4 UUID + * @return UuidInterface A UuidInterface instance that represents a version 4 UUID */ public static function uuid4(): UuidInterface { @@ -528,14 +499,12 @@ class Uuid implements Rfc4122UuidInterface } /** - * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a - * namespace ID and a name + * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a namespace ID and a name * - * @param non-empty-string|UuidInterface $ns The namespace (must be a valid UUID) + * @param UuidInterface | non-empty-string $ns The namespace (must be a valid UUID) * @param string $name The name to use for creating a UUID * - * @return UuidInterface A UuidInterface instance that represents a - * version 5 UUID + * @return UuidInterface A UuidInterface instance that represents a version 5 UUID */ public static function uuid5(UuidInterface | string $ns, string $name): UuidInterface { @@ -543,17 +512,13 @@ class Uuid implements Rfc4122UuidInterface } /** - * Returns a version 6 (reordered time) UUID from a host ID, sequence number, - * and the current time + * Returns a version 6 (reordered Gregorian time) UUID from a host ID, sequence number, and the current time * - * @param Hexadecimal|null $node A 48-bit number representing the hardware - * address - * @param int<0, 16383>|null $clockSeq A 14-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time - * or if the node ID changes + * @param Hexadecimal | null $node A 48-bit number representing the hardware address + * @param int<0, 16383> | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set + * backwards in time or if the node ID changes * - * @return UuidInterface A UuidInterface instance that represents a - * version 6 UUID + * @return UuidInterface A UuidInterface instance that represents a version 6 UUID */ public static function uuid6( ?Hexadecimal $node = null, @@ -565,12 +530,10 @@ class Uuid implements Rfc4122UuidInterface /** * Returns a version 7 (Unix Epoch time) UUID * - * @param DateTimeInterface|null $dateTime An optional date/time from which - * to create the version 7 UUID. If not provided, the UUID is generated - * using the current date/time. + * @param DateTimeInterface | null $dateTime An optional date/time from which to create the version 7 UUID. If not + * provided, the UUID is generated using the current date/time. * - * @return UuidInterface A UuidInterface instance that represents a - * version 7 UUID + * @return UuidInterface A UuidInterface instance that represents a version 7 UUID */ public static function uuid7(?DateTimeInterface $dateTime = null): UuidInterface { @@ -581,26 +544,20 @@ class Uuid implements Rfc4122UuidInterface return $factory->uuid7($dateTime); } - throw new UnsupportedOperationException( - 'The provided factory does not support the uuid7() method', - ); + throw new UnsupportedOperationException('The provided factory does not support the uuid7() method'); } /** - * Returns a version 8 (custom) UUID + * Returns a version 8 (custom format) UUID * - * The bytes provided may contain any value according to your application's - * needs. Be aware, however, that other applications may not understand the - * semantics of the value. + * The bytes provided may contain any value according to your application's needs. Be aware, however, that other + * applications may not understand the semantics of the value. * - * @param string $bytes A 16-byte octet string. This is an open blob - * of data that you may fill with 128 bits of information. Be aware, - * however, bits 48 through 51 will be replaced with the UUID version - * field, and bits 64 and 65 will be replaced with the UUID variant. You - * MUST NOT rely on these bits for your application needs. + * @param string $bytes A 16-byte octet string. This is an open blob of data that you may fill with 128 bits of + * information. Be aware, however, bits 48 through 51 will be replaced with the UUID version field, and bits 64 + * and 65 will be replaced with the UUID variant. You MUST NOT rely on these bits for your application needs. * - * @return UuidInterface A UuidInterface instance that represents a - * version 8 UUID + * @return UuidInterface A UuidInterface instance that represents a version 8 UUID */ public static function uuid8(string $bytes): UuidInterface { @@ -611,8 +568,6 @@ class Uuid implements Rfc4122UuidInterface return $factory->uuid8($bytes); } - throw new UnsupportedOperationException( - 'The provided factory does not support the uuid8() method', - ); + throw new UnsupportedOperationException('The provided factory does not support the uuid8() method'); } } diff --git a/src/UuidFactory.php b/src/UuidFactory.php index c8767ed..34a2917 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -57,13 +57,12 @@ class UuidFactory implements UuidFactoryInterface private ValidatorInterface $validator; /** - * @var bool whether the feature set was provided from outside, or we can - * operate under "default" assumptions + * @var bool whether the feature set was provided from outside, or we can operate under "default" assumptions */ private bool $isDefaultFeatureSet; /** - * @param FeatureSet|null $features A set of available features in the current environment + * @param FeatureSet | null $features A set of available features in the current environment */ public function __construct(?FeatureSet $features = null) { @@ -115,8 +114,7 @@ class UuidFactory implements UuidFactoryInterface /** * Sets the name generator to use for this factory * - * @param NameGeneratorInterface $nameGenerator A generator to generate - * binary data, based on a namespace and name + * @param NameGeneratorInterface $nameGenerator A generator to generate binary data, based on a namespace and name */ public function setNameGenerator(NameGeneratorInterface $nameGenerator): void { @@ -152,8 +150,7 @@ class UuidFactory implements UuidFactoryInterface /** * Sets the time generator to use for this factory * - * @param TimeGeneratorInterface $generator A generator to generate binary - * data, based on the time + * @param TimeGeneratorInterface $generator A generator to generate binary data, based on the time */ public function setTimeGenerator(TimeGeneratorInterface $generator): void { @@ -173,8 +170,8 @@ class UuidFactory implements UuidFactoryInterface /** * Sets the DCE Security generator to use for this factory * - * @param DceSecurityGeneratorInterface $generator A generator to generate - * binary data, based on a local domain and local identifier + * @param DceSecurityGeneratorInterface $generator A generator to generate binary data, based on a local domain and + * local identifier */ public function setDceSecurityGenerator(DceSecurityGeneratorInterface $generator): void { @@ -194,8 +191,7 @@ class UuidFactory implements UuidFactoryInterface /** * Sets the random generator to use for this factory * - * @param RandomGeneratorInterface $generator A generator to generate binary - * data, based on some random input + * @param RandomGeneratorInterface $generator A generator to generate binary data, based on some random input */ public function setRandomGenerator(RandomGeneratorInterface $generator): void { @@ -207,8 +203,8 @@ class UuidFactory implements UuidFactoryInterface /** * Sets the number converter to use for this factory * - * @param NumberConverterInterface $converter A converter to use for working - * with large integers (i.e. integers greater than PHP_INT_MAX) + * @param NumberConverterInterface $converter A converter to use for working with large integers (i.e., integers + * greater than PHP_INT_MAX) */ public function setNumberConverter(NumberConverterInterface $converter): void { @@ -228,8 +224,7 @@ class UuidFactory implements UuidFactoryInterface /** * Sets the UUID builder to use for this factory * - * @param UuidBuilderInterface $builder A builder for constructing instances - * of UuidInterface + * @param UuidBuilderInterface $builder A builder for constructing instances of UuidInterface */ public function setUuidBuilder(UuidBuilderInterface $builder): void { @@ -246,8 +241,7 @@ class UuidFactory implements UuidFactoryInterface /** * Sets the validator to use for this factory * - * @param ValidatorInterface $validator A validator to use for validating - * whether a string is a valid UUID + * @param ValidatorInterface $validator A validator to use for validating whether a string is a valid UUID */ public function setValidator(ValidatorInterface $validator): void { @@ -279,21 +273,11 @@ class UuidFactory implements UuidFactoryInterface public function fromDateTime( DateTimeInterface $dateTime, ?Hexadecimal $node = null, - ?int $clockSeq = null + ?int $clockSeq = null, ): UuidInterface { - $timeProvider = new FixedTimeProvider( - new Time($dateTime->format('U'), $dateTime->format('u')) - ); - - $timeGenerator = new DefaultTimeGenerator( - $this->nodeProvider, - $this->timeConverter, - $timeProvider - ); - - $nodeHex = $node ? $node->toString() : null; - - $bytes = $timeGenerator->generate($nodeHex, $clockSeq); + $timeProvider = new FixedTimeProvider(new Time($dateTime->format('U'), $dateTime->format('u'))); + $timeGenerator = new DefaultTimeGenerator($this->nodeProvider, $this->timeConverter, $timeProvider); + $bytes = $timeGenerator->generate($node?->toString(), $clockSeq); return $this->uuidFromBytesAndVersion($bytes, Version::Time); } @@ -314,14 +298,9 @@ class UuidFactory implements UuidFactoryInterface int $localDomain, ?IntegerObject $localIdentifier = null, ?Hexadecimal $node = null, - ?int $clockSeq = null + ?int $clockSeq = null, ): UuidInterface { - $bytes = $this->dceSecurityGenerator->generate( - $localDomain, - $localIdentifier, - $node, - $clockSeq - ); + $bytes = $this->dceSecurityGenerator->generate($localDomain, $localIdentifier, $node, $clockSeq); return $this->uuidFromBytesAndVersion($bytes, Version::DceSecurity); } @@ -345,17 +324,15 @@ class UuidFactory implements UuidFactoryInterface public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface { - $nodeHex = $node?->toString(); - $bytes = $this->timeGenerator->generate($nodeHex, $clockSeq); + $bytes = $this->timeGenerator->generate($node?->toString(), $clockSeq); // Rearrange the bytes, according to the UUID version 6 specification. $v6 = $bytes[6] . $bytes[7] . $bytes[4] . $bytes[5] . $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3]; $v6 = bin2hex($v6); - // Drop the first four bits, while adding an empty four bits for the - // version field. This allows us to reconstruct the correct time from - // the bytes of this UUID. + // Drop the first four bits, while adding an empty four bits for the version field. This allows us to + // reconstruct the correct time from the bytes of this UUID. /** @var non-empty-string $v6Bytes */ $v6Bytes = hex2bin(substr($v6, 1, 12) . '0' . substr($v6, -3)); $v6Bytes .= substr($bytes, 8); @@ -366,12 +343,10 @@ class UuidFactory implements UuidFactoryInterface /** * Returns a version 7 (Unix Epoch time) UUID * - * @param DateTimeInterface|null $dateTime An optional date/time from which - * to create the version 7 UUID. If not provided, the UUID is generated - * using the current date/time. + * @param DateTimeInterface | null $dateTime An optional date/time from which to create the version 7 UUID. If not + * provided, the UUID is generated using the current date/time. * - * @return UuidInterface A UuidInterface instance that represents a - * version 7 UUID + * @return UuidInterface A UuidInterface instance that represents a version 7 UUID */ public function uuid7(?DateTimeInterface $dateTime = null): UuidInterface { @@ -382,20 +357,17 @@ class UuidFactory implements UuidFactoryInterface } /** - * Returns a version 8 (Custom) UUID + * Returns a version 8 (custom format) UUID * - * The bytes provided may contain any value according to your application's - * needs. Be aware, however, that other applications may not understand the - * semantics of the value. + * The bytes provided may contain any value according to your application's needs. Be aware, however, that other + * applications may not understand the semantics of the value. * - * @param non-empty-string $bytes A 16-byte octet string. This is an open blob - * of data that you may fill with 128 bits of information. Be aware, - * however, bits 48 through 51 will be replaced with the UUID version - * field, and bits 64 and 65 will be replaced with the UUID variant. You - * MUST NOT rely on these bits for your application needs. + * @param non-empty-string $bytes A 16-byte octet string. This is an open blob of data that you may fill with 128 + * bits of information. Be aware, however, bits 48 through 51 will be replaced with the UUID version field, and + * bits 64 and 65 will be replaced with the UUID variant. You MUST NOT rely on these bits for your application + * needs. * - * @return UuidInterface A UuidInterface instance that represents a - * version 8 UUID + * @return UuidInterface A UuidInterface instance that represents a version 8 UUID */ public function uuid8(string $bytes): UuidInterface { @@ -405,13 +377,11 @@ class UuidFactory implements UuidFactoryInterface /** * Returns a Uuid created from the provided byte string * - * Uses the configured builder and codec and the provided byte string to - * construct a Uuid object. + * Uses the configured builder and codec and the provided byte string to construct a Uuid object. * * @param non-empty-string $bytes The byte string from which to construct a UUID * - * @return UuidInterface An instance of UuidInterface, created from the - * provided bytes + * @return UuidInterface An instance of UuidInterface, created from the provided bytes */ public function uuid(string $bytes): UuidInterface { @@ -421,14 +391,12 @@ class UuidFactory implements UuidFactoryInterface /** * Returns a version 3 or 5 namespaced Uuid * - * @param non-empty-string|UuidInterface $ns The namespace (must be a valid UUID) + * @param UuidInterface | non-empty-string $ns The namespace (must be a valid UUID) * @param string $name The name to hash together with the namespace * @param Version $version The version of UUID to create (3 or 5) - * @param non-empty-string $hashAlgorithm The hashing algorithm to use when - * hashing together the namespace and name + * @param non-empty-string $hashAlgorithm The hashing algorithm to use when hashing together the namespace and name * - * @return UuidInterface An instance of UuidInterface, created by hashing - * together the provided namespace and name + * @return UuidInterface An instance of UuidInterface, created by hashing together the provided namespace and name */ private function uuidFromNsAndName( UuidInterface | string $ns, @@ -449,13 +417,12 @@ class UuidFactory implements UuidFactoryInterface } /** - * Returns an RFC 4122 variant Uuid, created from the provided bytes and version + * Returns a Uuid created from the provided bytes and version * * @param non-empty-string $bytes The byte string to convert to a UUID - * @param Version $version The RFC 4122 version to apply to the UUID + * @param Version $version The version to apply to the UUID * - * @return UuidInterface An instance of UuidInterface, created from the - * byte string and version + * @return UuidInterface An instance of UuidInterface, created from the byte string and version */ private function uuidFromBytesAndVersion(string $bytes, Version $version): UuidInterface { diff --git a/src/UuidFactoryInterface.php b/src/UuidFactoryInterface.php index 046dcaf..d3212de 100644 --- a/src/UuidFactoryInterface.php +++ b/src/UuidFactoryInterface.php @@ -20,8 +20,7 @@ use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Validator\ValidatorInterface; /** - * UuidFactoryInterface defines the common functionality all `UuidFactory` instances - * must implement + * UuidFactoryInterface defines the common functionality all `UuidFactory` instances must implement * * @immutable */ @@ -32,8 +31,7 @@ interface UuidFactoryInterface * * @param non-empty-string $bytes A binary string * - * @return UuidInterface A UuidInterface instance created from a binary - * string representation + * @return UuidInterface A UuidInterface instance created from a binary string representation */ public function fromBytes(string $bytes): UuidInterface; @@ -41,19 +39,16 @@ interface UuidFactoryInterface * Creates a UUID from a DateTimeInterface instance * * @param DateTimeInterface $dateTime The date and time - * @param Hexadecimal|null $node A 48-bit number representing the hardware - * address - * @param int<0, 16383>|null $clockSeq A 14-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time - * or if the node ID changes + * @param Hexadecimal | null $node A 48-bit number representing the hardware address + * @param int<0, 16383> | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the + * clock is set backwards in time or if the node ID changes * - * @return UuidInterface A UuidInterface instance that represents a - * version 1 UUID created from a DateTimeInterface instance + * @return UuidInterface A UuidInterface instance that represents a version 1 UUID created from a DateTimeInterface instance */ public function fromDateTime( DateTimeInterface $dateTime, ?Hexadecimal $node = null, - ?int $clockSeq = null + ?int $clockSeq = null, ): UuidInterface; /** @@ -61,8 +56,7 @@ interface UuidFactoryInterface * * @param numeric-string $integer String representation of 128-bit integer * - * @return UuidInterface A UuidInterface instance created from the string - * representation of a 128-bit integer + * @return UuidInterface A UuidInterface instance created from the string representation of a 128-bit integer */ public function fromInteger(string $integer): UuidInterface; @@ -71,8 +65,7 @@ interface UuidFactoryInterface * * @param non-empty-string $uuid A hexadecimal string * - * @return UuidInterface A UuidInterface instance created from a hexadecimal - * string representation + * @return UuidInterface A UuidInterface instance created from a hexadecimal string representation */ public function fromString(string $uuid): UuidInterface; @@ -82,91 +75,73 @@ interface UuidFactoryInterface public function getValidator(): ValidatorInterface; /** - * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, - * and the current time + * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, and the current time * - * @param Hexadecimal|int<1, max>|non-empty-string|null $node A 48-bit number - * representing the hardware address; this number may be represented as - * an integer or a hexadecimal string - * @param int<0, 16383>|null $clockSeq A 14-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time - * or if the node ID changes + * @param Hexadecimal | non-empty-string | positive-int | null $node A 48-bit number representing the hardware + * address; this number may be represented as an integer or a hexadecimal string + * @param int<0, 16383> | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the + * clock is set backwards in time or if the node ID changes * - * @return UuidInterface A UuidInterface instance that represents a - * version 1 UUID + * @return UuidInterface A UuidInterface instance that represents a version 1 UUID */ public function uuid1(Hexadecimal | int | string | null $node = null, ?int $clockSeq = null): UuidInterface; /** - * Returns a version 2 (DCE Security) UUID from a local domain, local - * identifier, host ID, clock sequence, and the current time + * Returns a version 2 (DCE Security) UUID from a local domain, local identifier, host ID, clock sequence, and the + * current time * - * @param int $localDomain The local domain to use when generating bytes, - * according to DCE Security - * @param IntegerObject|null $localIdentifier The local identifier for the - * given domain; this may be a UID or GID on POSIX systems, if the local - * domain is person or group, or it may be a site-defined identifier - * if the local domain is org - * @param Hexadecimal|null $node A 48-bit number representing the hardware - * address - * @param int<0, 63>|null $clockSeq A 6-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time - * or if the node ID changes + * @param int $localDomain The local domain to use when generating bytes, according to DCE Security + * @param IntegerObject | null $localIdentifier The local identifier for the given domain; this may be a UID or GID + * on POSIX systems, if the local domain is "person" or "group," or it may be a site-defined identifier if the + * local domain is "org" + * @param Hexadecimal | null $node A 48-bit number representing the hardware address + * @param int<0, 63> | null $clockSeq A 6-bit number used to help avoid duplicates that could arise when the clock + * is set backwards in time or if the node ID changes * - * @return UuidInterface A UuidInterface instance that represents a - * version 2 UUID + * @return UuidInterface A UuidInterface instance that represents a version 2 UUID */ public function uuid2( int $localDomain, ?IntegerObject $localIdentifier = null, ?Hexadecimal $node = null, - ?int $clockSeq = null + ?int $clockSeq = null, ): UuidInterface; /** - * Returns a version 3 (name-based) UUID based on the MD5 hash of a - * namespace ID and a name + * Returns a version 3 (name-based) UUID based on the MD5 hash of a namespace ID and a name * - * @param non-empty-string|UuidInterface $ns The namespace (must be a valid UUID) + * @param UuidInterface | non-empty-string $ns The namespace (must be a valid UUID) * @param string $name The name to use for creating a UUID * - * @return UuidInterface A UuidInterface instance that represents a - * version 3 UUID + * @return UuidInterface A UuidInterface instance that represents a version 3 UUID */ public function uuid3(UuidInterface | string $ns, string $name): UuidInterface; /** * Returns a version 4 (random) UUID * - * @return UuidInterface A UuidInterface instance that represents a - * version 4 UUID + * @return UuidInterface A UuidInterface instance that represents a version 4 UUID */ public function uuid4(): UuidInterface; /** - * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a - * namespace ID and a name + * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a namespace ID and a name * - * @param non-empty-string|UuidInterface $ns The namespace (must be a valid UUID) + * @param UuidInterface | non-empty-string $ns The namespace (must be a valid UUID) * @param string $name The name to use for creating a UUID * - * @return UuidInterface A UuidInterface instance that represents a - * version 5 UUID + * @return UuidInterface A UuidInterface instance that represents a version 5 UUID */ public function uuid5(UuidInterface | string $ns, string $name): UuidInterface; /** - * Returns a version 6 (reordered time) UUID from a host ID, sequence number, - * and the current time + * Returns a version 6 (reordered time) UUID from a host ID, sequence number, and the current time * - * @param Hexadecimal|null $node A 48-bit number representing the hardware - * address - * @param int<0, 16383>|null $clockSeq A 14-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time - * or if the node ID changes + * @param Hexadecimal | null $node A 48-bit number representing the hardware address + * @param int<0, 16383> | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the + * clock is set backwards in time or if the node ID changes * - * @return UuidInterface A UuidInterface instance that represents a - * version 6 UUID + * @return UuidInterface A UuidInterface instance that represents a version 6 UUID */ public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface; } diff --git a/src/UuidInterface.php b/src/UuidInterface.php index 5a9871e..5efaacd 100644 --- a/src/UuidInterface.php +++ b/src/UuidInterface.php @@ -21,8 +21,7 @@ use Ramsey\Uuid\Type\Integer as IntegerObject; use Stringable; /** - * A UUID is a universally unique identifier adhering to an agreed-upon - * representation format and standard for generation + * A UUID is a universally unique identifier adhering to an agreed-upon representation format and standard for generation * * @immutable */ @@ -46,15 +45,10 @@ interface UuidInterface extends JsonSerializable, Stringable public function __unserialize(array $data): void; /** - * Returns -1, 0, or 1 if the UUID is less than, equal to, or greater than - * the other UUID + * Returns -1, 0, or 1 if the UUID is less than, equal to, or greater than the other UUID * - * The first of two UUIDs is greater than the second if the most - * significant field in which the UUIDs differ is greater for the first - * UUID. - * - * * Q. What's the value of being able to sort UUIDs? - * * A. Use them as keys in a B-Tree or similar mapping. + * The first of two UUIDs is greater than the second if the most significant field in which the UUIDs differ is + * greater for the first UUID. * * @param UuidInterface $other The UUID to compare * @@ -65,11 +59,10 @@ interface UuidInterface extends JsonSerializable, Stringable /** * Returns true if the UUID is equal to the provided object * - * The result is true if and only if the argument is not null, is a UUID - * object, has the same variant, and contains the same value, bit-for-bit, - * as the UUID. + * The result is true if and only if the argument is not null, is a UUID object, has the same variant, and contains + * the same value, bit-for-bit, as the UUID. * - * @param object|null $other An object to test for equality with this UUID + * @param object | null $other An object to test for equality with this UUID * * @return bool True if the other object is equal to this UUID */ @@ -101,7 +94,9 @@ interface UuidInterface extends JsonSerializable, Stringable * Returns the string standard representation of the UUID as a URN * * @link http://en.wikipedia.org/wiki/Uniform_Resource_Name Uniform Resource Name - * @link https://tools.ietf.org/html/rfc4122#section-3 RFC 4122, § 3: Namespace Registration Template + * @link https://www.rfc-editor.org/rfc/rfc9562.html#section-4 RFC 9562, 4. UUID Format + * @link https://www.rfc-editor.org/rfc/rfc9562.html#section-7 RFC 9562, 7. IANA Considerations + * @link https://www.rfc-editor.org/rfc/rfc4122.html#section-3 RFC 4122, 3. Namespace Registration Template */ public function getUrn(): string; diff --git a/src/Variant.php b/src/Variant.php index 4be8bdf..12065bc 100644 --- a/src/Variant.php +++ b/src/Variant.php @@ -24,37 +24,36 @@ namespace Ramsey\Uuid; * - 6 - Reserved, Microsoft Corporation backward compatibility * - 7 - Reserved for future definition * - * For RFC 4122 variant UUIDs, this value should always be the integer `2`. + * For RFC 9562 (formerly RFC 4122) variant UUIDs, this value should always be the integer `2`. * - * @link https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1 + * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field */ enum Variant: int { /** - * Variant: reserved, NCS backward compatibility - * - * @link https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1 + * Reserved, NCS backward compatibility */ case ReservedNcs = 0; /** - * Variant: the UUID layout specified in RFC 4122 - * - * @link https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1 + * The UUID layout specified in RFC 9562 (formerly RFC 4122) */ - case Rfc4122 = 2; + case Rfc9562 = 2; /** - * Variant: reserved, Microsoft Corporation backward compatibility - * - * @link https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1 + * Reserved, Microsoft Corporation backward compatibility */ case ReservedMicrosoft = 6; /** - * Variant: reserved for future definition - * - * @link https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.1 RFC 4122, § 4.1.1 + * Reserved for future definition */ case ReservedFuture = 7; + + /** + * The UUID layout specified in RFC 9562 (formerly RFC 4122) + * + * This is an alias for {@see self::Rfc9562}. + */ + public const Rfc4122 = self::Rfc9562; // phpcs:ignore Generic.NamingConventions.UpperCaseConstantName } diff --git a/src/functions.php b/src/functions.php index 2c15928..05962bd 100644 --- a/src/functions.php +++ b/src/functions.php @@ -20,15 +20,12 @@ use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; /** - * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, - * and the current time + * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, and the current time * - * @param Hexadecimal|positive-int|non-empty-string|null $node A 48-bit number - * representing the hardware address; this number may be represented as an - * integer or a hexadecimal string - * @param int<0, 16383>|null $clockSeq A 14-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time or - * if the node ID changes + * @param Hexadecimal | positive-int | non-empty-string | null $node A 48-bit number representing the hardware address; + * this number may be represented as an integer or a hexadecimal string + * @param int<0, 16383> | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock + * is set backwards in time or if the node ID changes * * @return non-empty-string Version 1 UUID as a string */ @@ -38,20 +35,15 @@ function v1(Hexadecimal | int | string | null $node = null, ?int $clockSeq = nul } /** - * Returns a version 2 (DCE Security) UUID from a local domain, local - * identifier, host ID, clock sequence, and the current time + * Returns a version 2 (DCE Security) UUID from a local domain, local identifier, host ID, clock sequence, and the current time * - * @param int $localDomain The local domain to use when generating bytes, - * according to DCE Security - * @param IntegerObject|null $localIdentifier The local identifier for the - * given domain; this may be a UID or GID on POSIX systems, if the local - * domain is person or group, or it may be a site-defined identifier - * if the local domain is org - * @param Hexadecimal|null $node A 48-bit number representing the hardware - * address - * @param int<0, 63>|null $clockSeq A 6-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time or if - * the node ID changes + * @param int $localDomain The local domain to use when generating bytes, according to DCE Security + * @param IntegerObject | null $localIdentifier The local identifier for the given domain; this may be a UID or GID on + * POSIX systems, if the local domain is "person" or "group," or it may be a site-defined identifier if the local + * domain is "org" + * @param Hexadecimal | null $node A 48-bit number representing the hardware address + * @param int<0, 63> | null $clockSeq A 6-bit number used to help avoid duplicates that could arise when the clock is set + * backwards in time or if the node ID changes * * @return non-empty-string Version 2 UUID as a string */ @@ -59,16 +51,15 @@ function v2( int $localDomain, ?IntegerObject $localIdentifier = null, ?Hexadecimal $node = null, - ?int $clockSeq = null + ?int $clockSeq = null, ): string { return Uuid::uuid2($localDomain, $localIdentifier, $node, $clockSeq)->toString(); } /** - * Returns a version 3 (name-based) UUID based on the MD5 hash of a - * namespace ID and a name + * Returns a version 3 (name-based) UUID based on the MD5 hash of a namespace ID and a name * - * @param non-empty-string|UuidInterface $ns The namespace (must be a valid UUID) + * @param UuidInterface | non-empty-string $ns The namespace (must be a valid UUID) * @param non-empty-string $name The name to use for creating a UUID * * @return non-empty-string Version 3 UUID as a string @@ -89,10 +80,9 @@ function v4(): string } /** - * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a - * namespace ID and a name + * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a namespace ID and a name * - * @param non-empty-string|UuidInterface $ns The namespace (must be a valid UUID) + * @param UuidInterface | non-empty-string $ns The namespace (must be a valid UUID) * @param non-empty-string $name The name to use for creating a UUID * * @return non-empty-string Version 5 UUID as a string @@ -103,14 +93,11 @@ function v5(UuidInterface | string $ns, string $name): string } /** - * Returns a version 6 (reordered time) UUID from a host ID, sequence number, - * and the current time + * Returns a version 6 (reordered Gregorian time) UUID from a host ID, sequence number, and the current time * - * @param Hexadecimal|null $node A 48-bit number representing the hardware - * address - * @param int<0, 16383>|null $clockSeq A 14-bit number used to help avoid - * duplicates that could arise when the clock is set backwards in time or if - * the node ID changes + * @param Hexadecimal | null $node A 48-bit number representing the hardware address + * @param int<0, 16383> | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock + * is set backwards in time or if the node ID changes * * @return non-empty-string Version 6 UUID as a string */ @@ -122,9 +109,8 @@ function v6(?Hexadecimal $node = null, ?int $clockSeq = null): string /** * Returns a version 7 (Unix Epoch time) UUID * - * @param DateTimeInterface|null $dateTime An optional date/time from which - * to create the version 7 UUID. If not provided, the UUID is generated - * using the current date/time. + * @param DateTimeInterface|null $dateTime An optional date/time from which to create the version 7 UUID. If not + * provided, the UUID is generated using the current date/time. * * @return non-empty-string Version 7 UUID as a string */ @@ -134,17 +120,14 @@ function v7(?DateTimeInterface $dateTime = null): string } /** - * Returns a version 8 (custom) UUID + * Returns a version 8 (custom format) UUID * - * The bytes provided may contain any value according to your application's - * needs. Be aware, however, that other applications may not understand the - * semantics of the value. + * The bytes provided may contain any value according to your application's needs. Be aware, however, that other + * applications may not understand the semantics of the value. * - * @param string $bytes A 16-byte octet string. This is an open blob - * of data that you may fill with 128 bits of information. Be aware, - * however, bits 48 through 51 will be replaced with the UUID version - * field, and bits 64 and 65 will be replaced with the UUID variant. You - * MUST NOT rely on these bits for your application needs. + * @param string $bytes A 16-byte octet string. This is an open blob of data that you may fill with 128 bits of + * information. Be aware, however, bits 48 through 51 will be replaced with the UUID version field, and bits 64 and + * 65 will be replaced with the UUID variant. You MUST NOT rely on these bits for your application needs. * * @return non-empty-string Version 8 UUID as a string */ diff --git a/tests/Builder/FallbackBuilderTest.php b/tests/Builder/FallbackBuilderTest.php index 267ce19..32cb984 100644 --- a/tests/Builder/FallbackBuilderTest.php +++ b/tests/Builder/FallbackBuilderTest.php @@ -107,8 +107,9 @@ class FallbackBuilderTest extends TestCase } catch (UnableToBuildUuidException $exception) { switch ($exception->getMessage()) { case 'The byte string received does not contain a valid version': - case 'The byte string received does not conform to the RFC 4122 variant': - case 'The byte string received does not conform to the RFC 4122 or Microsoft Corporation variants': + case 'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) variant': + case 'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) ' + . 'or Microsoft Corporation variants': // This is expected; ignoring. break; default: diff --git a/tests/Codec/OrderedTimeCodecTest.php b/tests/Codec/OrderedTimeCodecTest.php index ddf4d22..433a34c 100644 --- a/tests/Codec/OrderedTimeCodecTest.php +++ b/tests/Codec/OrderedTimeCodecTest.php @@ -162,9 +162,7 @@ class OrderedTimeCodecTest extends TestCase ]); $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage( - 'Expected RFC 4122 version 1 (time-based) UUID' - ); + $this->expectExceptionMessage('Expected version 1 (time-based) UUID'); $codec->encodeBinary($uuid); } @@ -184,9 +182,7 @@ class OrderedTimeCodecTest extends TestCase $uuid = $factory->fromString($nonTimeBasedUuid); $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage( - 'Expected RFC 4122 version 1 (time-based) UUID' - ); + $this->expectExceptionMessage('Expected version 1 (time-based) UUID'); $codec->encodeBinary($uuid); } diff --git a/tests/Guid/FieldsTest.php b/tests/Guid/FieldsTest.php index eecef58..793ed9a 100644 --- a/tests/Guid/FieldsTest.php +++ b/tests/Guid/FieldsTest.php @@ -39,7 +39,7 @@ class FieldsTest extends TestCase $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( - 'The byte string received does not conform to the RFC 4122 or ' + 'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) or ' . 'Microsoft Corporation variants' ); diff --git a/tests/Rfc4122/FieldsTest.php b/tests/Rfc4122/FieldsTest.php index 12ded15..9504980 100644 --- a/tests/Rfc4122/FieldsTest.php +++ b/tests/Rfc4122/FieldsTest.php @@ -40,7 +40,7 @@ class FieldsTest extends TestCase $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( - 'The byte string received does not conform to the RFC 4122 variant' + 'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) variant' ); new Fields($bytes); @@ -78,7 +78,7 @@ class FieldsTest extends TestCase $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage( - 'The byte string received does not contain a valid RFC 4122 version' + 'The byte string received does not contain a valid RFC 9562 (formerly RFC 4122) version' ); new Fields($bytes); diff --git a/tests/Rfc4122/UuidV8Test.php b/tests/Rfc4122/UuidV8Test.php index b870f27..9e8e1ff 100644 --- a/tests/Rfc4122/UuidV8Test.php +++ b/tests/Rfc4122/UuidV8Test.php @@ -29,10 +29,7 @@ class UuidV8Test extends TestCase $timeConverter = Mockery::mock(TimeConverterInterface::class); $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage( - 'Fields used to create a UuidV8 must represent a ' - . 'version 8 (custom) UUID' - ); + $this->expectExceptionMessage('Fields used to create a UuidV8 must represent a version 8 (custom format) UUID'); new UuidV8($fields, $numberConverter, $codec, $timeConverter); }