From 271fdc81e99128834766754bf9790b0d9e856208 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 14 Mar 2020 16:48:14 -0500 Subject: [PATCH] Finish documentation for version 4.0.0 of library --- README.md | 7 + docs/customize/factory.rst | 2 +- docs/database.rst | 10 +- docs/faq.rst | 102 +++++++ docs/index.rst | 1 + docs/reference/uuidinterface.rst | 5 + docs/testing.rst | 199 +++++++++++++ docs/upgrading/2-to-3.rst | 6 +- docs/upgrading/3-to-4.rst | 477 ++++++++++++++++++++++++++++++- 9 files changed, 800 insertions(+), 9 deletions(-) create mode 100644 docs/testing.rst diff --git a/README.md b/README.md index 1d4428b..0e539e6 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,13 @@ composer require ramsey/uuid ``` +## Upgrading to Version 4 + +See the documentation for a thorough upgrade guide: + +* [Upgrading ramsey/uuid Version 3 to 4](https://uuid.ramsey.dev/en/latest/upgrading/3-to-4.html) + + ## Documentation Please see for documentation, tips, examples, and diff --git a/docs/customize/factory.rst b/docs/customize/factory.rst index 4d8eed7..abc0551 100644 --- a/docs/customize/factory.rst +++ b/docs/customize/factory.rst @@ -24,7 +24,7 @@ For example: $orderedTimeUuid = $factory->uuid1(); When doing this, the default behavior of ramsey/uuid is left intact. If we call -``Uuid::uuid()`` to generate a version 1 UUID after configuring the factory as +``Uuid::uuid1()`` to generate a version 1 UUID after configuring the factory as shown above, it won't use :ref:`OrderedTimeCodec ` to generate the UUID. diff --git a/docs/database.rst b/docs/database.rst index d939be5..2db1a38 100644 --- a/docs/database.rst +++ b/docs/database.rst @@ -193,6 +193,12 @@ For this reason, if you choose to use UUIDs as primary keys, it might be worth the drawbacks to use UUID bytes (i.e., ``char(16)``) instead of the string representation (see :ref:`database.bytes`). +.. hint:: + + If not using InnoDB with MySQL or MariaDB, consult your database engine + documentation to find whether it also has similar properties that will + factor into your use of UUIDs. + .. _database.uk: @@ -225,8 +231,8 @@ Insertion Order and Sorting UUIDs are not *monotonically increasing*. Even time-based UUIDs are not. If using UUIDs as primary keys, the inserts will be random, and the data will be -scattered on disk. Over time, as the database size grows, lookups will become -slower and slower. +scattered on disk (for InnoDB). Over time, as the database size grows, lookups +will become slower and slower. .. note:: diff --git a/docs/faq.rst b/docs/faq.rst index b070ed0..5342398 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -6,6 +6,10 @@ Frequently Asked Questions (FAQs) .. contents:: :local: + :depth: 1 + + +.. _faq.rhumsaa-abandoned: How do I fix "rhumsaa/uuid is abandoned" messages? ################################################## @@ -28,3 +32,101 @@ Don't panic. Simply execute the following commands with Composer: After doing so, you will have the latest ramsey/uuid package in the 2.x series, and there will be no need to modify any code; the namespace in the 2.x series is still ``Rhumsaa``. + + +.. _faq.final: + +Why does ramsey/uuid use ``final``? +################################### + +You might notice that many of the concrete classes returned in ramsey/uuid are +marked as ``final``. There are specific reasons for this choice, and I will +offer a few solutions for those looking to extend or mock the classes, for +testing purposes. + +But Why? +-------- + +.. raw:: html + +
+ +
+

via GIPHY

+ +First, let's take a look at why ramsey/uuid uses ``final``. + +UUIDs are defined by a set of rules --- published as `RFC 4122`_ --- and those +rules shouldn't change. If they do, then it's no longer a UUID --- at least not +as defined by `RFC 4122`_. + +As an example, let's think about :php:class:`Rfc4122\\UuidV1 +`. If our application wants to do something +special with this type, it might use the ``instanceof`` operator to check that a +variable is a UuidV1, or it might use a type hint on a method argument. If a +third-party library passes a UUID object to us that extends UuidV1 but +overrides some very important internal logic, then we may no longer have a +version 1 UUID. Perhaps we can all be adults and play nicely, but ramsey/uuid +cannot make any guarantees for any subclasses of UuidV1. + +However, ramsey/uuid *can* make guarantees about classes that implement +:php:interface:`UuidInterface ` or +:php:interface:`Rfc4122\\UuidInterface `. + +So, if we're working with an instance of a class that is marked ``final``, we +can guarantee that the rules for the creation of that object will not change, +even if a third-party library passes us an instance of the same class. + +This is the reason why ramsey/uuid specifies certain :ref:`argument and return +types ` that are marked ``final``. Since these are ``final``, +ramsey/uuid is able to guarantee the type of data these value objects contain. +:php:class:`Type\\Integer ` should never contain +any characters other than numeral digits, and :php:class:`Type\\Hexadecimal +` should never contain any characters other +than hexadecimal digits. If other libraries could extend these and return them +from UUID instances, then ramsey/uuid cannot guarantee their values. + +This is very similar to using strict types with ``int``, ``float``, or ``bool``. +These types cannot change, so think of final classes in ramsey/uuid as types +that cannot change. + +Overriding Behavior +------------------- + +You may override the behavior of ramsey/uuid as much as you want. Despite the +use of ``final``, the library is very flexible. Take a look at the myriad +opportunities to change how the library works: + +* :ref:`rfc4122.version1.random` +* :ref:`customize.timestamp-first-comb-codec` +* :ref:`customize.factory` +* :ref:`And more... ` + +ramsey/uuid is able to provide this flexibility through the use of `interfaces`_, +`factories`_, and `dependency injection`_. + +At the same time, ramsey/uuid is able to guarantee that neither a +:php:class:`UuidV1 ` nor a +:php:class:`UuidV4 ` nor an +:php:class:`Integer ` nor a +:php:class:`Time `, etc. will ever change because of +`downstream`_ code. + +UUIDs have specific rules that make them practically unique. ramsey/uuid ensures +that other code cannot change this expectation, while allowing your code and +third-party libraries to change how UUIDs are generated and to return different +types of UUIDs not specified by `RFC 4122`_. + +Testing With UUIDs +------------------ + +Sometimes, the use of ``final`` can throw a wrench in our ability to write +tests, but it doesn't have to be that way. To learn a few techniques for using +ramsey/uuid instances in your tests, take a look at :ref:`testing`. + + +.. _RFC 4122: https://tools.ietf.org/html/rfc4122 +.. _interfaces: https://www.php.net/interfaces +.. _factories: https://en.wikipedia.org/wiki/Factory_%28object-oriented_programming%29 +.. _dependency injection: https://en.wikipedia.org/wiki/Dependency_injection +.. _downstream: https://en.wikipedia.org/wiki/Downstream_(software_development) diff --git a/docs/index.rst b/docs/index.rst index cbd31e1..7b24a8c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -23,6 +23,7 @@ Contents nonstandard database customize + testing upgrading FAQs reference diff --git a/docs/reference/uuidinterface.rst b/docs/reference/uuidinterface.rst index b27d2bd..02c1819 100644 --- a/docs/reference/uuidinterface.rst +++ b/docs/reference/uuidinterface.rst @@ -46,3 +46,8 @@ UuidInterface :returns: The string standard representation of the UUID. :returntype: ``string`` + + .. php:method:: __toString() + + :returns: The string standard representation of the UUID. + :returntype: ``string`` diff --git a/docs/testing.rst b/docs/testing.rst new file mode 100644 index 0000000..34bf6eb --- /dev/null +++ b/docs/testing.rst @@ -0,0 +1,199 @@ +.. _testing: + +================== +Testing With UUIDs +================== + +One problem with the use of ``final`` is the inability to create a `mock object`_ +to use in tests. However, the following techniques should help with testing. + +.. tip:: + + To learn why ramsey/uuid uses ``final``, take a look at :ref:`faq.final`. + + +.. _testing.inject: + +Inject a UUID of a Specific Type +-------------------------------- + +Let's say we have a method that uses a type hint for :php:class:`UuidV1 +`. + +.. code-block:: php + + public function tellTime(UuidV1 $uuid): string + { + return $uuid->getDateTime()->format('Y-m-d H:i:s'); + } + +Since this method uses UuidV1 as the type hint, we're not able to pass another +object that implements UuidInterface, and we cannot extend or mock UuidV1, so +how do we test this? + +One way is to use :php:meth:`Uuid::uuid1() ` to +create a regular UuidV1 instance and pass it. + +.. code-block:: php + + public function testTellTime(): void + { + $uuid = Uuid::uuid1(); + $myObj = new MyClass(); + + $this->assertIsString($myObj->tellTime($uuid)); + } + +This might satisfy our testing needs if we only want to assert that the method +returns a string. If we want to test for a specific string, we can do that, too, +by generating a UUID ahead of time and using it as a known value. + +.. code-block:: php + + public function testTellTime(): void + { + // We generated this version 1 UUID ahead of time and know the + // exact date and time it contains, so we can use it to test the + // return value of our method. + $uuid = Uuid::fromString('177ef0d8-6630-11ea-b69a-0242ac130003'); + $myObj = new MyClass(); + + $this->assertSame('2020-03-14 20:12:12', $myObj->tellTime($uuid)); + } + +.. note:: + + These examples assume the use of `PHPUnit`_ for tests. The concepts will + work no matter what testing framework you use. + + +.. _testing.static: + +Returning Specific UUIDs From a Static Method +--------------------------------------------- + +Sometimes, rather than pass UUIDs as method arguments, we might call the static +methods on the Uuid class from inside the method we want to test. This can be +tricky to test. + +.. code-block:: php + + public function tellTime(): string + { + $uuid = Uuid::uuid1(); + + return $uuid->getDateTime()->format('Y-m-d H:i:s'); + } + +We can call this in a test and assert that it returns a string, but we can't +return a specific UUID value from the static method call --- or can we? + +We can do this by :ref:`overriding the default factory `. + +First, we create our own factory class for testing. In this example, we extend +UuidFactory, but you may create your own separate factory class for testing, as +long as you implement :php:interface:`Ramsey\\Uuid\\UuidFactoryInterface`. + +.. code-block:: php + + namespace MyPackage; + + use Ramsey\Uuid\UuidFactory; + use Ramsey\Uuid\UuidInterface; + + class MyTestUuidFactory extends UuidFactory + { + public $uuid1; + + public function uuid1($node = null, ?int $clockSeq = null): UuidInterface + { + return $this->uuid1; + } + } + +Now, from our tests, we can replace the default factory with our new factory, +and we can even change the value returned by the :php:meth:`uuid1() +` method for our tests. + +.. code-block:: php + + /** + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testTellTime(): void + { + $factory = new MyTestUuidFactory(); + Uuid::setFactory($factory); + + $myObj = new MyClass(); + + $factory->uuid1 = Uuid::fromString('177ef0d8-6630-11ea-b69a-0242ac130003'); + $this->assertSame('2020-03-14 20:12:12', $myObj->tellTime()); + + $factory->uuid1 = Uuid::fromString('13814000-1dd2-11b2-9669-00007ffffffe'); + $this->assertSame('1970-01-01 00:00:00', $myObj->tellTime()); + } + +.. attention:: + + The factory is a static property on the Uuid class. By replacing it like + this, all uses of the Uuid class after this point will continue to use the + new factory. This is why we must run the test in a separate process. + Otherwise, this could cause other tests to fail. + + Running tests in separate processes can significantly slow down your tests, + so try to use this technique sparingly, and if possible, pass your + dependencies to your objects, rather than creating (or fetching them) from + within. This makes testing easier. + + +.. _testing.mock: + +Mocking UuidInterface +--------------------- + +Another technique for testing with UUIDs is to mock +:php:interface:`UuidInterface `. + +Consider a method that accepts a UuidInterface. + +.. code-block:: php + + public function tellTime(UuidInterface $uuid): string + { + return $uuid->getDateTime()->format('Y-m-d H:i:s'); + } + +We can mock UuidInterface, passing that mocked value into this method. Then, we +can make assertions about what methods were called on the mock object. In the +following example test, we don't care whether the return value matches an +actual date format. What we care about is that the methods on the UuidInterface +object were called. + +.. code-block:: php + + public function testTellTime(): void + { + $dateTime = Mockery::mock(DateTime::class); + $dateTime->expects()->format('Y-m-d H:i:s')->andReturn('a test date'); + + $uuid = Mockery::mock(UuidInterface::class, [ + 'getDateTime' => $dateTime, + ]); + + $myObj = new MyClass(); + + $this->assertSame('a test date', $myObj->tellTime($uuid)); + } + +.. note:: + + One of my favorite mocking libraries is `Mockery`_, so that's what I use in + these examples. However, other mocking libraries exist, and PHPUnit provides + built-in mocking capabilities. + + +.. _mock object: https://en.wikipedia.org/wiki/Mock_object +.. _PHPUnit: https://phpunit.de +.. _Mockery: https://github.com/mockery/mockery diff --git a/docs/upgrading/2-to-3.rst b/docs/upgrading/2-to-3.rst index 6dd9e72..2c64fa3 100644 --- a/docs/upgrading/2-to-3.rst +++ b/docs/upgrading/2-to-3.rst @@ -1,8 +1,8 @@ .. _upgrading.2-to-3: -====================== -ramsey/uuid 2.x to 3.x -====================== +============== +Version 2 to 3 +============== While we have made significant internal changes to the library, we have made every effort to ensure a seamless upgrade path from the 2.x series of this diff --git a/docs/upgrading/3-to-4.rst b/docs/upgrading/3-to-4.rst index 0af37f8..d49c33b 100644 --- a/docs/upgrading/3-to-4.rst +++ b/docs/upgrading/3-to-4.rst @@ -1,5 +1,476 @@ .. _upgrading.3-to-4: -====================== -ramsey/uuid 3.x to 4.x -====================== +============== +Version 3 to 4 +============== + +I've made great efforts to ensure that the upgrade experience for most will be +seamless and uneventful. However, no matter the degree to which you use +ramsey/uuid (customized or unchanged), there are a number of things to be aware +of as you upgrade your code to use version 4. + +.. tip:: + + These are the changes that are most likely to affect you. For a full list of + changes, take a look at the `4.0.0 changelog`_. + + +.. _upgrading.3-to-4.new: + +What's New? +########### + +There are a lot of new features in ramsey/uuid! Here are a few of them: + +* Support :ref:`version 6 UUIDs `. +* Support :ref:`version 2 (DCE Security) UUIDs `. +* Add classes to represent each version of RFC 4122 UUID. When generating new + UUIDs or creating UUIDs from existing strings, bytes, or integers, if the UUID + is an RFC 4122 variant, one of these instances will be returned: + + * :php:class:`Rfc4122\\UuidV1 ` + * :php:class:`Rfc4122\\UuidV2 ` + * :php:class:`Rfc4122\\UuidV3 ` + * :php:class:`Rfc4122\\UuidV4 ` + * :php:class:`Rfc4122\\UuidV5 ` + * Rfc4122\\NilUuid + +* Add classes to represent version 6 UUIDs, GUIDs, and nonstandard + (non-RFC 4122 variant) UUIDs: + + * :php:class:`Nonstandard\\UuidV6 ` + * :php:class:`Nonstandard\\Uuid ` + * :php:class:`Guid\\Guid ` + +* Add :php:meth:`Uuid::fromDateTime() ` to + create version 1 UUIDs from instances of DateTimeInterface. + + +.. _upgrading.3-to-4.changed: + +What's Changed? +############### + +.. attention:: + + ramsey/uuid version 4 requires PHP 7.2 or later. + +Quite a bit has changed, but much remains familiar. Unless you've changed the +behavior of ramsey/uuid through custom codecs, providers, generators, etc., the +standard functionality and API found in version 3 will not differ much. + +.. rubric:: Here are the highlights: + +* ramsey/uuid now works on 32-bit and 64-bit systems, with no degradation in + functionality! All Degraded\* classes are deprecated and no longer used; + they'll go away in ramsey/uuid version 5. +* Pay attention to the :ref:`return types for the static methods + ` on the :php:class:`Uuid ` + class. They've changed slightly, but this won't affect you if your type hints + use :php:interface:`UuidInterface `. +* The :ref:`return types for three methods ` + defined on :php:interface:`UuidInterface ` have + changed, breaking backward compatibility. **Take note, and update your code.** +* :ref:`There are a number of deprecations. ` + These shouldn't affect you now, but please take a look at the recommendations + and update your code soon. These will go away in ramsey/uuid version 5. +* ramsey/uuid now :ref:`throws custom exceptions for everything + `. The exception UnsatisfiedDependencyException no + longer exists. +* If you customize ramsey/uuid at all by implementing the interfaces, take a + look at the :ref:`interface ` and + :ref:`constructor ` changes and update your + code. + + +.. _upgrading.3-to-4.static-methods: + +Uuid Static Methods +################### + +All the static methods on the :php:class:`Uuid ` class +continue to work as they did in version 3, with this slight change: **they now +return more-specific types**, all of which implement the new interface +:php:interface:`Rfc4122\\UuidInterface `, +which implements the familiar interface :php:interface:`UuidInterface +`. + +If your type hints are for :php:interface:`UuidInterface +`, then you should not require any changes. + +.. list-table:: Return types for Uuid static methods + :align: center + :header-rows: 1 + + * - Method + - 3.x Returned + - 4.x Returns + * - :php:meth:`Uuid::uuid1() ` + - :php:class:`Uuid ` + - :php:class:`Rfc4122\\UuidV1 ` + * - :php:meth:`Uuid::uuid3() ` + - :php:class:`Uuid ` + - :php:class:`Rfc4122\\UuidV3 ` + * - :php:meth:`Uuid::uuid4() ` + - :php:class:`Uuid ` + - :php:class:`Rfc4122\\UuidV4 ` + * - :php:meth:`Uuid::uuid5() ` + - :php:class:`Uuid ` + - :php:class:`Rfc4122\\UuidV5 ` + +:php:meth:`Uuid::fromString() `, +:php:meth:`Uuid::fromBytes() `, and +:php:meth:`Uuid::fromInteger() ` all return +an appropriate more-specific type, based on the input value. If the input value +is a version 1 UUID, for example, the return type will be an +:php:class:`Rfc4122\\UuidV1 `. If the input looks +like a UUID or is a 128-bit number, but it doesn't validate as an RFC 4122 UUID, +the return type will be a :php:class:`Nonstandard\\Uuid +`. These return types implement +:php:interface:`UuidInterface `. If using this as +a type hint, you shouldn't need to make any changes. + + +.. _upgrading.3-to-4.return-types: + +Changed Return Types +#################### + +The following :php:interface:`UuidInterface ` +method return types have changed in version 4, and you will need to update your +code, if you use these methods. + +.. list-table:: Changed UuidInterface method return types + :widths: 40 30 30 + :align: center + :header-rows: 1 + + * - Method + - 3.x Returned + - 4.x Returns + * - :php:meth:`UuidInterface::getFields() ` + - ``array`` + - :php:class:`Rfc4122\\FieldsInterface ` + * - :php:meth:`UuidInterface::getHex() ` + - ``string`` + - :php:class:`Type\\Hexadecimal ` + * - :php:meth:`UuidInterface::getInteger() ` + - ``mixed`` [#f1]_ + - :php:class:`Type\\Integer ` + + +.. _upgrading.3-to-4.deprecations: + +Deprecations +############ + +.. _upgrading.3-to-4.deprecations.uuidinterface: + +UuidInterface +------------- + +The following :php:interface:`UuidInterface ` +methods are deprecated, but upgrading to version 4 should not cause any problems +if using these methods. You are encouraged to update your code according to the +recommendations, though, since these methods will go away in version 5. + +.. list-table:: Deprecated UuidInterface methods + :widths: 30 70 + :align: center + :header-rows: 1 + + * - Deprecated Method + - Update To + * - ``getDateTime()`` + - Use ``getDateTime()`` on :php:meth:`UuidV1 + `, :php:meth:`UuidV2 + `, or :php:meth:`UuidV6 + ` + * - ``getClockSeqHiAndReservedHex()`` + - :php:meth:`getFields()->getClockSeqHiAndReserved()->toString() ` + * - ``getClockSeqLowHex()`` + - :php:meth:`getFields()->getClockSeqLow()->toString() ` + * - ``getClockSequenceHex()`` + - :php:meth:`getFields()->getClockSeq()->toString() ` + * - ``getFieldsHex()`` + - :php:meth:`getFields() ` [#f2]_ + * - ``getLeastSignificantBitsHex()`` + - ``substr($uuid->getHex()->toString(), 0, 16)`` + * - ``getMostSignificantBitsHex()`` + - ``substr($uuid->getHex()->toString(), 16)`` + * - ``getNodeHex()`` + - :php:meth:`getFields()->getNode()->toString() ` + * - ``getNumberConverter()`` + - This method has no replacement; plan accordingly. + * - ``getTimeHiAndVersionHex()`` + - :php:meth:`getFields()->getTimeHiAndVersion()->toString() ` + * - ``getTimeLowHex()`` + - :php:meth:`getFields()->getTimeLow()->toString() ` + * - ``getTimeMidHex()`` + - :php:meth:`getFields()->getTimeMid()->toString() ` + * - ``getTimestampHex()`` + - :php:meth:`getFields()->getTimestamp()->toString() ` + * - ``getUrn()`` + - :php:meth:`Ramsey\\Uuid\\Rfc4122\\UuidInterface::getUrn` + * - ``getVariant()`` + - :php:meth:`getFields()->getVariant() ` + * - ``getVersion()`` + - :php:meth:`getFields()->getVersion() ` + +.. _upgrading.3-to-4.deprecations.uuid: + +Uuid +---- + +:php:class:`Uuid ` as an instantiable class is deprecated. +In ramsey/uuid version 5, its constructor will be ``private``, and the class +will be ``final``. For more information, see :ref:`faq.final` + +.. note:: + + :php:class:`Uuid ` is being replaced by more-specific + concrete classes, such as: + + * :php:class:`Rfc4122\\UuidV1 ` + * :php:class:`Rfc4122\\UuidV3 ` + * :php:class:`Rfc4122\\UuidV4 ` + * :php:class:`Rfc4122\\UuidV5 ` + * :php:class:`Nonstandard\\Uuid ` + + However, the :php:class:`Uuid ` class isn't going away. + It will still hold common constants and static methods. + +* ``Uuid::UUID_TYPE_IDENTIFIER`` is deprecated. Use + ``Uuid::UUID_TYPE_DCE_SECURITY`` instead. +* ``Uuid::VALID_PATTERN`` is deprecated. Use the following instead: + + .. code-block:: php + + use Ramsey\Uuid\Validator\GenericValidator; + use Ramsey\Uuid\Rfc4122\Validator as Rfc4122Validator; + + $genericPattern = (new GenericValidator())->getPattern(); + $rfc4122Pattern = (new Rfc4122Validator())->getPattern(); + +The following :php:class:`Uuid ` methods are deprecated. If +using these methods, you shouldn't have any problems on version 4, but you are +encouraged to update your code, since they will go away in version 5. + +* ``getClockSeqHiAndReserved()`` +* ``getClockSeqLow()`` +* ``getClockSequence()`` +* ``getLeastSignificantBits()`` +* ``getMostSignificantBits()`` +* ``getNode()`` +* ``getTimeHiAndVersion()`` +* ``getTimeLow()`` +* ``getTimeMid()`` +* ``getTimestamp()`` + +.. hint:: + + There are no direct replacements for these methods. In ramsey/uuid version + 3, they returned ``int`` or Moontoast\\Math\\BigNumber values, depending + on the environment. To update your code, you should use the recommended + alternates listed in :ref:`Deprecations: UuidInterface + `, combined with the + arbitrary-precision mathematics library of your choice (e.g., `brick/math`_, + `gmp`_, `bcmath`_, etc.). + + .. code-block:: php + :caption: Using brick/math to convert a node to a string integer + + use Brick\Math\BigInteger; + + $node = BigInteger::fromBase($uuid->getFields()->getNode()->toString(), 16); + + +.. _upgrading.3-to-4.interfaces: + +Interface Changes +################# + +For those who customize ramsey/uuid by implementing the interfaces provided, +there are a few breaking changes to note. + +.. hint:: + + Most existing methods on interfaces have type hints added to them. If you + implement any interfaces, please be aware of this and update your classes. + +UuidInterface +------------- + +.. list-table:: + :widths: 25 75 + :align: center + :header-rows: 1 + + * - Method + - Description + * - :php:meth:`__toString() ` + - New method; returns ``string`` + * - :php:meth:`getDateTime() ` + - Deprecated; now returns `DateTimeInterface`_ + * - :php:meth:`getFields() ` + - Used to return ``array``; now returns :php:class:`Rfc4122\\FieldsInterface ` + * - :php:meth:`getHex() ` + - Used to return ``string``; now returns :php:class:`Type\\Hexadecimal ` + * - :php:meth:`getInteger() ` + - New method; returns :php:class:`Type\\Integer ` + +UuidFactoryInterface +-------------------- + +.. list-table:: + :widths: 25 75 + :align: center + :header-rows: 1 + + * - Method + - Description + * - :php:meth:`uuid2() ` + - New method; returns :php:class:`Rfc4122\\UuidV2 ` + * - :php:meth:`uuid6() ` + - New method; returns :php:class:`Nonstandard\\UuidV6 ` + * - :php:meth:`fromDateTime() ` + - New method; returns :php:class:`UuidInterface ` + * - :php:meth:`fromInteger() ` + - Changed to accept only strings + * - :php:meth:`getValidator() ` + - New method; returns :php:class:`UuidInterface ` + +Builder\\UuidBuilderInterface +----------------------------- + +.. list-table:: + :widths: 25 75 + :align: center + :header-rows: 1 + + * - Method + - Description + * - ``build()`` + - Second parameter used to accept ``array $fields``; now accepts ``string $bytes`` + +Converter\\TimeConverterInterface +--------------------------------- + +.. list-table:: + :widths: 25 75 + :align: center + :header-rows: 1 + + * - Method + - Description + * - ``calculateTime()`` + - Used to return ``string[]``; now returns :php:class:`Type\\Hexadecimal ` + * - ``convertTime()`` + - New method; returns :php:class:`Type\\Time ` + +Provider\\TimeProviderInterface +--------------------------------- + +.. list-table:: + :widths: 25 75 + :align: center + :header-rows: 1 + + * - Method + - Description + * - ``currentTime()`` + - Method removed from interface; use ``getTime()`` instead + * - ``getTime()`` + - New method; returns :php:class:`Type\\Time ` + +Provider\\NodeProviderInterface +--------------------------------- + +.. list-table:: + :widths: 25 75 + :align: center + :header-rows: 1 + + * - Method + - Description + * - ``getNode()`` + - Used to return ``string|false|null``; now returns :php:class:`Type\\Hexadecimal ` + + +.. _upgrading.3-to-4.constructors: + +Constructor Changes +################### + +There are a handful of constructor changes that might affect your use of +ramsey/uuid, especially if you customize the library. + +Uuid +---- + +The constructor for :php:class:`Ramsey\\Uuid\\Uuid` is deprecated. However, +there are a few changes to it that might affect your use of this class. + +The first constructor parameter used to be ``array $fields`` and is now +:php:interface:`Rfc4122\\FieldsInterface $fields +`. + +``Converter\TimeConverterInterface $timeConverter`` is required as a new fourth +parameter. + +Builder\\DefaultUuidBuilder +--------------------------- + +While Builder\\DefaultUuidBuilder is deprecated, it now inherits from +Rfc4122\\UuidBuilder, which requires ``Converter\TimeConverterInterface +$timeConverter`` as its second constructor argument. + +Provider\\Node\\FallbackNodeProvider +------------------------------------ + +Provider\\Node\\FallbackNodeProvider now requires a +Provider\\Node\\NodeProviderCollection as its constructor parameter. This +behaves like a typed array. + +.. code-block:: + + use MyPackage\MyCustomNodeProvider; + use Ramsey\Uuid\Provider\Node\FallbackNodeProvider; + use Ramsey\Uuid\Provider\Node\NodeProviderCollection; + use Ramsey\Uuid\Provider\Node\RandomNodeProvider; + use Ramsey\Uuid\Provider\Node\SystemNodeProvider; + + $collection = new NodeProviderCollection(); + $collection[] = new MyCustomNodeProvider(); + $collection[] = new SystemNodeProvider(); + $collection[] = new RandomNodeProvider(); + + $provider = new FallbackNodeProvider($collection); + +Provider\\Time\\FixedTimeProvider +--------------------------------- + +The constructor for Provider\\Time\\FixedTimeProvider no longer accepts an +array. It accepts :php:class:`Type\\Time ` instances. + + +------------------------------------------------------------------------------- + +.. rubric:: Footnotes + +.. [#f1] This ``mixed`` return type could have been an ``int``, ``string``, or + Moontoast\\Math\\BigNumber. In version 4, ramsey/uuid cleans this up for + the sake of consistency. + +.. [#f2] The :php:meth:`getFields() ` + method returns a :php:class:`Type\\Hexadecimal ` + instance; you will need to construct an array if you wish to match the + return value of the deprecated ``getFieldsHex()`` method. + + +.. _version 6 UUIDs: http://gh.peabody.io/uuidv6/ +.. _4.0.0 changelog: https://github.com/ramsey/uuid/releases/tag/4.0.0 +.. _brick/math: https://github.com/brick/math +.. _gmp: https://www.php.net/gmp +.. _bcmath: https://www.php.net/bcmath +.. _DateTimeInterface: https://www.php.net/datetimeinterface