Merge branch '4.x' into 5.x

This commit is contained in:
Ben Ramsey
2025-06-01 01:20:09 -05:00
58 changed files with 1205 additions and 1502 deletions
+395
View File
@@ -0,0 +1,395 @@
Attribution 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are
intended for use by those authorized to give the public
permission to use material in ways otherwise restricted by
copyright and certain other rights. Our licenses are
irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it.
Licensors should also secure all rights necessary before
applying our licenses so that the public can reuse the
material as expected. Licensors should clearly mark any
material not subject to the license. This includes other CC-
licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public
licenses, a licensor grants the public permission to use the
licensed material under specified terms and conditions. If
the licensor's permission is not necessary for any reason--for
example, because of any applicable exception or limitation to
copyright--then that use is not regulated by the license. Our
licenses grant only permissions under copyright and certain
other rights that a licensor has authority to grant. Use of
the licensed material may still be restricted for other
reasons, including because others have copyright or other
rights in the material. A licensor may make special requests,
such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to
respect those requests where reasonable. More considerations
for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution 4.0 International Public License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution 4.0 International Public License ("Public License"). To the
extent this Public License may be interpreted as a contract, You are
granted the Licensed Rights in consideration of Your acceptance of
these terms and conditions, and the Licensor grants You such rights in
consideration of benefits the Licensor receives from making the
Licensed Material available under these terms and conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright
and Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
c. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
d. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
e. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
f. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
g. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
h. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
i. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
j. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
k. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part; and
b. produce, reproduce, and Share Adapted Material.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified
form), You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
4. If You Share Adapted Material You produce, the Adapter's
License You apply must not prevent recipients of the Adapted
Material from complying with this Public License.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material; and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the “Licensor.” The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.
Creative Commons may be contacted at creativecommons.org.
+3 -5
View File
@@ -1,7 +1,6 @@
# ramsey/uuid Documentation
Changes to the documentation are automatically built by [Read the Docs][] and
viewable from <https://uuid.ramsey.dev>.
Changes to the documentation are automatically built by [Read the Docs][] and viewable from <https://uuid.ramsey.dev>.
## Getting Started
@@ -17,8 +16,8 @@ pip install -r requirements.txt
## Building the Docs
To build the docs, change to the `docs/` directory, and make sure you're working
on the virtualenv environment created in the last step.
To build the docs, change to the `docs/` directory, and make sure you're working on the virtualenv environment created
in the last step.
``` bash
cd docs/
@@ -32,5 +31,4 @@ Then, to view the docs after building them:
open _build/html/index.html
```
[read the docs]: https://readthedocs.org
+1 -1
View File
@@ -23,7 +23,7 @@ def get_version():
if os.environ.get('READTHEDOCS') == 'True':
return os.environ.get('READTHEDOCS_VERSION')
pipe = Popen('git branch | grep \*', stdout=PIPE, shell=True, universal_newlines=True)
pipe = Popen('git branch | grep \\*', stdout=PIPE, shell=True, universal_newlines=True)
version = pipe.stdout.read()
if version:
+14 -8
View File
@@ -4,15 +4,21 @@
Copyright
=========
Copyright © 2012-|year| Ben Ramsey <ben@benramsey.com>
Copyright © 2012-|year| `Ben Ramsey <https://benramsey.com>`_ and
`contributors <https://github.com/ramsey/uuid/contributors>`_.
ramsey/uuid documentation is licensed under the Creative Commons Attribution 4.0
International License. To view a copy of this license, visit
http://creativecommons.org/licenses/by/4.0/ or send a letter to Creative
Commons, PO Box 1866, Mountain View, CA 94042, USA.
Documentation for ramsey/uuid is licensed under the Creative Commons Attribution 4.0 International License. To view a
copy of this license, visit http://creativecommons.org/licenses/by/4.0/ or send a letter to Creative Commons, PO Box
1866, Mountain View, CA 94042, USA.
ramsey/uuid source code is licensed under the terms of the MIT License. To view
a copy of this license, see the LICENSE file distributed with the software or
visit `<https://opensource.org/licenses/MIT/>`_.
ramsey/uuid is open source software: you can distribute it and/or modify it under the terms of the MIT License (the
"License"). You may not use ramsey/uuid except in compliance with the License.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
You should have received a copy of the MIT License along with this program. If not, see
https://opensource.org/license/mit/.
.. |year| date:: %Y
+10 -28
View File
@@ -8,44 +8,26 @@ Customization
:titlesonly:
:hidden:
customize/ordered-time-codec
customize/timestamp-first-comb-codec
customize/calculators
customize/validators
customize/factory
ramsey/uuid offers a variety of ways to modify the standard behavior of the
library through dependency injection. Using `FeatureSet`_, `UuidFactory`_, and
:php:meth:`Uuid::setFactory() <Ramsey\\Uuid\\Uuid::setFactory()>`, you are able
to replace just about any `builder`_, `codec`_, `converter`_, `generator`_,
`provider`_, and more.
Ordered-time Codec
The ordered-time codec exists to rearrange the bytes of a version 1,
Gregorian time UUID so that the timestamp portion of the UUID is
monotonically increasing. To learn more, see :ref:`customize.ordered-time-codec`.
Timestamp-first COMB Codec
The timestamp-first COMB codec replaces part of a version 4, random UUID
with a timestamp, so that the UUID becomes monotonically increasing. To
learn more, see :ref:`customize.timestamp-first-comb-codec`.
ramsey/uuid offers a variety of ways to modify the standard behavior of the library through dependency injection. Using
`FeatureSet`_, `UuidFactory`_, and :php:meth:`Uuid::setFactory() <Ramsey\\Uuid\\Uuid::setFactory()>`, you are able to
replace just about any `builder`_, `codec`_, `converter`_, `generator`_, `provider`_, and more.
Using a Custom Calculator
It's possible to replace the default calculator ramsey/uuid uses. If your
requirements require a different solution for making calculations, see
:ref:`customize.calculators`.
It's possible to replace the default calculator ramsey/uuid uses. If your requirements require a different solution
for making calculations, see :ref:`customize.calculators`.
Using a Custom Validator
If your requirements require a different level of validation or a different
UUID format, you may replace the default validator. See
:ref:`customize.validators`, to learn more.
If your requirements require a different level of validation or a different UUID format, you may replace the default
validator. See :ref:`customize.validators`, to learn more.
Replace the Default Factory
Not only are you able to inject alternate builders, codecs, etc. into the
factory and use the factory to generate UUIDs, you may also replace the
global, static factory used by the static methods on the Uuid class. To find
out how, see :ref:`customize.factory`.
Not only are you able to inject alternate builders, codecs, etc. into the factory and use the factory to generate
UUIDs, you may also replace the global, static factory used by the static methods on the Uuid class. To find out
how, see :ref:`customize.factory`.
.. _UuidFactory: https://github.com/ramsey/uuid/blob/5.x/src/UuidFactory.php
.. _FeatureSet: https://github.com/ramsey/uuid/blob/5.x/src/FeatureSet.php
+7 -11
View File
@@ -4,13 +4,11 @@
Using a Custom Calculator
=========================
By default, ramsey/uuid uses `brick/math`_ as its internal calculator. However,
you may change the calculator, if your needs require something else.
By default, ramsey/uuid uses `brick/math`_ as its internal calculator. However, you may change the calculator, if your
needs require something else.
To swap the default calculator with your custom one, first make an adapter that
wraps your custom calculator and implements
:php:interface:`Ramsey\\Uuid\\Math\\CalculatorInterface`. This might look
something like this:
To swap the default calculator with your custom one, first make an adapter that wraps your custom calculator and
implements :php:interface:`Ramsey\\Uuid\\Math\\CalculatorInterface`. This might look something like this:
.. code-block:: php
:caption: Create a custom calculator wrapper that implements CalculatorInterface
@@ -47,10 +45,9 @@ something like this:
}
The easiest way to use your custom calculator wrapper is to instantiate a new
FeatureSet, set the calculator on it, and pass the FeatureSet into a new
UuidFactory. Using the factory, you may then generate and work with UUIDs, using
your custom calculator.
The easiest way to use your custom calculator wrapper is to instantiate a new FeatureSet, set the calculator on it, and
pass the FeatureSet into a new UuidFactory. Using the factory, you may then generate and work with UUIDs, using your
custom calculator.
.. code-block:: php
:caption: Use your custom calculator wrapper when working with UUIDs
@@ -71,5 +68,4 @@ your custom calculator.
$uuid = $factory->uuid1();
.. _brick/math: https://github.com/brick/math
+21 -25
View File
@@ -4,8 +4,13 @@
Replace the Default Factory
===========================
In many of the examples throughout this documentation, we've seen how to
configure the factory and then use that factory to generate and work with UUIDs.
.. attention::
The OrderedTimeCodec is no longer present in ramsey/uuid 5.0.0. This documentation must be updated with new examples
to show replacing the default factory with something other than the OrderedTimeCodec.
In many of the examples throughout this documentation, we've seen how to configure the factory and then use that factory
to generate and work with UUIDs.
For example:
@@ -23,10 +28,8 @@ For example:
$orderedTimeUuid = $factory->uuid1();
When doing this, the default behavior of ramsey/uuid is left intact. If we call
``Uuid::uuid1()`` to generate a version 1 UUID after configuring the factory as
shown above, it won't use :ref:`OrderedTimeCodec <customize.ordered-time-codec>`
to generate the UUID.
When doing this, the default behavior of ramsey/uuid is left intact. If we call ``Uuid::uuid1()`` to generate a version
1 UUID after configuring the factory as shown above, it won't use OrderedTimeCodec to generate the UUID.
.. code-block:: php
:caption: The behavior differs between $factory->uuid1() and Uuid::uuid1()
@@ -48,10 +51,8 @@ to generate the UUID.
bin2hex($uuid->getBytes())
);
In this example, we print out details for two different UUIDs. The first was
generated with the :ref:`OrderedTimeCodec <customize.ordered-time-codec>` using
``$factory->uuid1()``. The second was generated using ``Uuid::uuid1()``. It
looks something like this:
In this example, we print out details for two different UUIDs. The first was generated with the OrderedTimeCodec using
``$factory->uuid1()``. The second was generated using ``Uuid::uuid1()``. It looks something like this:
.. code-block:: text
@@ -61,15 +62,13 @@ looks something like this:
UUID: 2ff09730-6251-11ea-ba64-0242ac130003
Bytes: 2ff09730625111eaba640242ac130003
Notice the arrangement of the bytes. The first set of bytes has been rearranged,
according to the ordered-time codec rules, but the second set of bytes remains
in the same order as the UUID string.
Notice the arrangement of the bytes. The first set of bytes has been rearranged, according to the ordered-time codec
rules, but the second set of bytes remains in the same order as the UUID string.
*Configuring the factory does not change the default behavior.*
If we want to change the default behavior, we must *replace* the factory used
by the Uuid static methods, and we can do this using the
:php:meth:`Uuid::setFactory() <Ramsey\\Uuid\\Uuid::setFactory>` static method.
If we want to change the default behavior, we must *replace* the factory used by the Uuid static methods, and we can do
this using the :php:meth:`Uuid::setFactory() <Ramsey\\Uuid\\Uuid::setFactory>` static method.
.. code-block:: php
:caption: Replace the factory to globally affect Uuid behavior
@@ -79,15 +78,12 @@ by the Uuid static methods, and we can do this using the
$uuid = Uuid::uuid1();
Now, every time we call :php:meth:`Uuid::uuid() <Ramsey\\Uuid\\Uuid::uuid1>`,
ramsey/uuid will use the factory configured with the :ref:`OrderedTimeCodec
<customize.ordered-time-codec>` to generate version 1 UUIDs.
Now, every time we call :php:meth:`Uuid::uuid() <Ramsey\\Uuid\\Uuid::uuid1>`, ramsey/uuid will use the factory configured
with the OrderedTimeCodec to generate version 1 UUIDs.
.. warning::
Calling :php:meth:`Uuid::setFactory() <Ramsey\\Uuid\\Uuid::setFactory>` to
replace the factory will change the behavior of Uuid no matter where it is
used, so keep this in mind when replacing the factory. If you replace the
factory deep inside a method somewhere, any later code that calls a static
method on :php:class:`Ramsey\\Uuid\\Uuid` will use the new factory to
generate UUIDs.
Calling :php:meth:`Uuid::setFactory() <Ramsey\\Uuid\\Uuid::setFactory>` to replace the factory will change the
behavior of Uuid no matter where it is used, so keep this in mind when replacing the factory. If you replace the
factory deep inside a method somewhere, any later code that calls a static method on :php:class:`Ramsey\\Uuid\\Uuid`
will use the new factory to generate UUIDs.
-86
View File
@@ -1,86 +0,0 @@
.. _customize.ordered-time-codec:
==================
Ordered-time Codec
==================
.. attention::
:ref:`Version 6, reordered time UUIDs <rfc4122.version6>` are a new version
of UUID that eliminate the need for the ordered-time codec. If you aren't
currently using the ordered-time codec, and you need time-based, sortable
UUIDs, consider using version 6 UUIDs.
UUIDs arrange their bytes according to the standard recommended by `RFC 4122`_.
Unfortunately, this means the bytes aren't in an arrangement that supports
sorting by creation time or an otherwise incrementing value. The Percona
article, "`Storing UUID Values in MySQL`_," explains at length the problems this
can cause. It also recommends a solution: the *ordered-time UUID*.
RFC 4122 version 1, Gregorian time UUIDs rearrange the bytes of the time fields
so that the lowest bytes appear first, the middle bytes are next, and the
highest bytes come last. Logical sorting is not possible with this arrangement.
An ordered-time UUID is a version 1 UUID with the time fields arranged in
logical order so that the UUIDs can be sorted by creation time. These UUIDs are
*monotonically increasing*, each one coming after the previously-created one, in
a proper sort order.
.. code-block:: php
:caption: Use the ordered-time codec to generate a version 1 UUID
:name: customize.ordered-time-codec-example
use Ramsey\Uuid\Codec\OrderedTimeCodec;
use Ramsey\Uuid\UuidFactory;
$factory = new UuidFactory();
$codec = new OrderedTimeCodec($factory->getUuidBuilder());
$factory->setCodec($codec);
$orderedTimeUuid = $factory->uuid1();
printf(
"UUID: %s\nVersion: %d\nDate: %s\nNode: %s\nBytes: %s\n",
$orderedTimeUuid->toString(),
$orderedTimeUuid->getFields()->getVersion()?->value,
$orderedTimeUuid->getDateTime()->format('r'),
$orderedTimeUuid->getFields()->getNode()->toString(),
bin2hex($orderedTimeUuid->getBytes())
);
This will use the ordered-time codec to generate a version 1 UUID and will print
out details about the UUID similar to these:
.. code-block:: text
UUID: 593200aa-61ae-11ea-bbf2-0242ac130003
Version: 1
Date: Mon, 09 Mar 2020 02:33:23 +0000
Node: 0242ac130003
Bytes: 11ea61ae593200aabbf20242ac130003
.. attention::
Only the byte representation is rearranged. The string representation
follows the format of a standard version 1 UUID. This means only the byte
representation of an ordered-time codec encoded UUID may be used for
sorting, such as with database results.
To store the byte representation to a database field, see
:ref:`database.bytes`.
.. hint::
If you use this codec and store the bytes of the UUID to the database, as
recommended above, you will need to use this codec to decode the bytes, as
well. Otherwise, the UUID string value will be incorrect.
.. code-block:: php
// Using a factory configured with the OrderedTimeCodec, as shown above.
$orderedTimeUuid = $factory->fromBytes($bytes);
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
.. _Storing UUID Values in MySQL: https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/
@@ -1,72 +0,0 @@
.. _customize.timestamp-first-comb-codec:
==========================
Timestamp-first COMB Codec
==========================
.. attention::
:ref:`Version 7, Unix Epoch time UUIDs <rfc4122.version7>` are a new version
of UUID that eliminate the need for the timestamp-first COMB codec. If you
aren't currently using the timestamp-first COMB codec, and you need
time-based, sortable UUIDs, consider using version 7 UUIDs.
:ref:`Version 4, random UUIDs <rfc4122.version4>` are doubly problematic when it
comes to sorting and storing to databases (see :ref:`database.order`), since
their values are random, and there is no timestamp associated with them that may
be rearranged, like with the :ref:`ordered-time codec
<customize.ordered-time-codec>`. In 2002, Jimmy Nilsson recognized this problem
with random UUIDs and proposed a solution he called "COMBs" (see "`The Cost of
GUIDs as Primary Keys`_").
So-called because they *combine* random bytes with a timestamp, the
timestamp-first COMB codec replaces the first 48 bits of a version 4, random
UUID with a Unix timestamp and microseconds, creating an identifier that can be
sorted by creation time. These UUIDs are *monotonically increasing*, each one
coming after the previously-created one, in a proper sort order.
.. code-block:: php
:caption: Use the timestamp-first COMB codec to generate a version 4 UUID
:name: customize.timestamp-first-comb-codec-example
use Ramsey\Uuid\Codec\TimestampFirstCombCodec;
use Ramsey\Uuid\Generator\CombGenerator;
use Ramsey\Uuid\UuidFactory;
$factory = new UuidFactory();
$codec = new TimestampFirstCombCodec($factory->getUuidBuilder());
$factory->setCodec($codec);
$factory->setRandomGenerator(new CombGenerator(
$factory->getRandomGenerator(),
$factory->getNumberConverter()
));
$timestampFirstComb = $factory->uuid4();
printf(
"UUID: %s\nVersion: %d\nBytes: %s\n",
$timestampFirstComb->toString(),
$timestampFirstComb->getFields()->getVersion()?->value,
bin2hex($timestampFirstComb->getBytes())
);
This will use the timestamp-first COMB codec to generate a version 4 UUID with
the timestamp replacing the first 48 bits and will print out details about the
UUID similar to these:
.. code-block:: text
UUID: 9009ebcc-cd99-4b5f-90cf-9155607d2de9
Version: 4
Bytes: 9009ebcccd994b5f90cf9155607d2de9
Note that the bytes are in the same order as the string representation. Unlike
the :ref:`ordered-time codec <customize.ordered-time-codec>`, the
timestamp-first COMB codec affects both the string representation and the byte
representation. This means either the string UUID or the bytes may be stored to
a datastore and sorted. To learn more, see :ref:`database`.
.. _The Cost of GUIDs as Primary Keys: https://www.informit.com/articles/printerfriendly/25862
+11 -12
View File
@@ -4,16 +4,13 @@
Using a Custom Validator
========================
By default, ramsey/uuid validates UUID strings with the lenient validator
:php:class:`Ramsey\\Uuid\\Validator\\GenericValidator`. This validator ensures
the string is 36 characters, has the dashes in the correct places, and uses only
hexadecimal values. It does not ensure the string is of the RFC 4122 variant or
contains a valid version.
By default, ramsey/uuid validates UUID strings with the lenient validator :php:class:`Ramsey\\Uuid\\Validator\\GenericValidator`.
This validator ensures the string is 36 characters, has the dashes in the correct places, and uses only hexadecimal
values. It does not ensure the string is of the `RFC 9562`_ (formerly `RFC 4122`_) variant or contains a valid version.
The validator :php:class:`Ramsey\\Uuid\\Rfc4122\\Validator` validates UUID
strings to ensure they match the RFC 4122 variant and contain a valid version.
Since it is not enabled by default, you will need to configure ramsey/uuid to
use it, if you want stricter validation.
The validator :php:class:`Ramsey\\Uuid\\Rfc4122\\Validator` validates UUID strings to ensure they match the `RFC 9562`_
(formerly `RFC 4122`_) variant and contain a valid version. Since it is not enabled by default, you will need to
configure ramsey/uuid to use it, if you want stricter validation.
.. code-block:: php
:caption: Set an alternate validator to use for Uuid::isValid()
@@ -34,6 +31,8 @@ use it, if you want stricter validation.
.. tip::
If you want to use your own validation, create a class that implements
:php:interface:`Ramsey\\Uuid\\Validator\\ValidatorInterface` and use the
same method to set your validator on the factory.
If you want to use your own validation, create a class that implements :php:interface:`Ramsey\\Uuid\\Validator\\ValidatorInterface`
and use the same method to set your validator on the factory.
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
+42 -72
View File
@@ -6,35 +6,30 @@ Using In a Database
.. tip::
`ramsey/uuid-doctrine`_ allows the use of ramsey/uuid as a `Doctrine field
type`_. If you use Doctrine, it's a great option for working with UUIDs and
databases.
`ramsey/uuid-doctrine`_ allows the use of ramsey/uuid as a `Doctrine field type`_. If you use Doctrine, it's a great
option for working with UUIDs and databases.
There are several strategies to consider when working with UUIDs in a database.
Among these are whether to store the string representation or bytes and whether
the UUID column should be treated as a primary key. We'll discuss a few of these
approaches here, but the final decision on how to use UUIDs in a database is up
to you since your needs will be different from those of others.
There are several strategies to consider when working with UUIDs in a database. Among these are whether to store the
string representation or bytes and whether the UUID column should be treated as a primary key. We'll discuss a few of
these approaches here, but the final decision on how to use UUIDs in a database is up to you since your needs will be
different from those of others.
.. note::
All database code examples in this section assume the use of `MariaDB`_ and
`PHP Data Objects (PDO)`_. If using a different database engine or
connection library, your code will differ, but the general concepts should
remain the same.
All database code examples in this section assume the use of `MariaDB`_ and `PHP Data Objects (PDO)`_. If using a
different database engine or connection library, your code will differ, but the general concepts should remain the
same.
.. _database.string:
Storing As a String
###################
Perhaps the easiest way to store a UUID to a database is to create a ``char(36)``
column and store the UUID as a string. When stored as a string, UUIDs require
no special treatment in SQL statements or when displaying them.
Perhaps the easiest way to store a UUID to a database is to create a ``char(36)`` column and store the UUID as a string.
When stored as a string, UUIDs require no special treatment in SQL statements or when displaying them.
The primary drawback is the size. At 36 characters, UUIDs can take up a lot of
space, and when handling a lot of data, this can add up.
The primary drawback is the size. At 36 characters, UUIDs can take up a lot of space, and when handling a lot of data,
this can add up.
.. code-block:: sql
:caption: Create a table with a column for UUIDs
@@ -45,8 +40,8 @@ space, and when handling a lot of data, this can add up.
`notes` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Using this database table, we can store the string UUID using code similar to
this (assume some of the variables in this example have been set beforehand):
Using this database table, we can store the string UUID using code similar to this (assume some of the variables in this
example have been set beforehand):
.. code-block:: php
:caption: Store a string UUID to the uuid column
@@ -73,19 +68,17 @@ this (assume some of the variables in this example have been set beforehand):
':notes' => $notes,
]);
.. _database.bytes:
Storing As Bytes
################
In :ref:`the previous example <database.uuid-column-store-example>`, we saw how
to store the string representation of a UUID to a ``char(36)`` column. As
discussed, the primary drawback is the size. However, if we store the UUID in
byte form, we only need a ``char(16)`` column, saving over half the space.
In :ref:`the previous example <database.uuid-column-store-example>`, we saw how to store the string representation of a
UUID to a ``char(36)`` column. As discussed, the primary drawback is the size. However, if we store the UUID in byte
form, we only need a ``char(16)`` column, saving over half the space.
The primary drawback with this approach is ease-of-use. Since the UUID bytes are
stored in the database, querying and selecting data becomes more difficult.
The primary drawback with this approach is ease-of-use. Since the UUID bytes are stored in the database, querying and
selecting data becomes more difficult.
.. code-block:: sql
:caption: Create a table with a column for UUID bytes
@@ -96,9 +89,8 @@ stored in the database, querying and selecting data becomes more difficult.
`notes` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Using this database table, we can store the UUID bytes using code similar to
this (again, assume some of the variables in this example have been set
beforehand):
Using this database table, we can store the UUID bytes using code similar to this (again, assume some of the variables
in this example have been set beforehand):
.. code-block:: php
:caption: Store UUID bytes to the uuid column
@@ -109,9 +101,8 @@ beforehand):
':notes' => $notes,
]);
Now, when we ``SELECT`` the records from the database, we will need to convert
the ``notes.uuid`` column to a ramsey/uuid object, so that we are able to use
it.
Now, when we ``SELECT`` the records from the database, we will need to convert the ``notes.uuid`` column to a
ramsey/uuid object, so that we are able to use it.
.. code-block:: php
:caption: Covert database UUID bytes to UuidInterface instance
@@ -170,46 +161,37 @@ We'll also need to query the database using the bytes.
);
}
.. _database.pk:
Using As a Primary Key
######################
In the previous examples, we didn't use the UUID as a primary key, but it's
logical to use the ``notes.uuid`` field as a primary key. There's nothing wrong
with this approach, but there are a couple of points to consider:
In the previous examples, we didn't use the UUID as a primary key, but it's logical to use the ``notes.uuid`` field as a
primary key. There's nothing wrong with this approach, but there are a couple of points to consider:
* InnoDB stores data in the primary key order
* All the secondary keys also contain the primary key (in InnoDB)
We'll deal with the first point in the section, :ref:`database.order`. For the
second point, if you are using the string version of the UUID (i.e.,
``char(36)``), then not only will the primary key be large and take up a lot of
space, but every secondary key that uses that primary key will also be much
larger.
We'll deal with the first point in the section, :ref:`database.order`. For the second point, if you are using the string
version of the UUID (i.e., ``char(36)``), then not only will the primary key be large and take up a lot of space, but
every secondary key that uses that primary key will also be much larger.
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`).
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.
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:
Using As a Unique Key
#####################
Instead of :ref:`using UUIDs as a primary key <database.pk>`, you may choose to
use an ``AUTO_INCREMENT`` column with the ``int unsigned`` data type as a
primary key, while using a ``char(36)`` for UUIDs and setting a ``UNIQUE KEY``
on this column. This will aid in lookups while helping keep your secondary keys
small.
Instead of :ref:`using UUIDs as a primary key <database.pk>`, you may choose to use an ``AUTO_INCREMENT`` column with
the ``int unsigned`` data type as a primary key, while using a ``char(36)`` for UUIDs and setting a ``UNIQUE KEY`` on
this column. This will aid in lookups while helping keep your secondary keys small.
.. code-block:: sql
:caption: Use an auto-incrementing column as primary key, with UUID as a unique key
@@ -223,38 +205,26 @@ small.
UNIQUE KEY `notes_uuid_uk` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
.. _database.order:
Insertion Order and Sorting
###########################
UUID versions 1, 2, 3, 4, and 5 are not *monotonically increasing*. If using
these versions as primary keys, the inserts will be random, and the data will be
scattered on disk (for InnoDB). Over time, as the database size grows, lookups
will become slower and slower.
UUID versions 1, 2, 3, 4, and 5 are not *monotonically increasing*. If using these versions as primary keys, the inserts
will be random, and the data will be scattered on disk (for InnoDB). Over time, as the database size grows, lookups will
become slower and slower.
.. tip::
See Percona's "`Storing UUID Values in MySQL`_" post, for more details on
the performance of UUIDs as primary keys.
See Percona's "`Storing UUID Values in MySQL`_" post, for more details on the performance of UUIDs as primary keys.
To minimize these problems, two solutions have been devised:
1. :ref:`rfc4122.version6` UUIDs
2. :ref:`rfc4122.version7` UUIDs
.. note::
We previously recommended the use of the :ref:`timestamp-first COMB
<customize.timestamp-first-comb-codec>` or :ref:`ordered-time
<customize.ordered-time-codec>` codecs to solve these problems. However,
UUID versions 6 and 7 were defined to provide these solutions in a
standardized way.
.. _ramsey/uuid-doctrine: https://github.com/ramsey/uuid-doctrine
.. _Doctrine field type: https://www.doctrine-project.org/projects/doctrine-dbal/en/2.10/reference/types.html
.. _Doctrine field type: https://www.doctrine-project.org/projects/doctrine-dbal/en/stable/reference/types.html
.. _MariaDB: https://mariadb.org
.. _PHP Data Objects (PDO): https://www.php.net/pdo
.. _Storing UUID Values in MySQL: https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/
.. _Storing UUID Values in MySQL: https://www.percona.com/blog/store-uuid-optimized-way/
+39 -62
View File
@@ -8,19 +8,16 @@ Frequently Asked Questions (FAQs)
:local:
:depth: 1
.. _faq.rhumsaa-abandoned:
How do I fix "rhumsaa/uuid is abandoned" messages?
##################################################
When installing your project's dependencies using Composer, you might see the
following message:
When installing your project's dependencies using Composer, you might see the following message:
.. code-block:: text
Package rhumsaa/uuid is abandoned; you should avoid using it. Use
ramsey/uuid instead.
Package rhumsaa/uuid is abandoned; you should avoid using it. Use ramsey/uuid instead.
Don't panic. Simply execute the following commands with Composer:
@@ -29,20 +26,17 @@ Don't panic. Simply execute the following commands with Composer:
composer remove rhumsaa/uuid
composer require ramsey/uuid=^2.9
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``.
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.
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?
--------
@@ -56,76 +50,59 @@ But Why?
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`_.
UUIDs are defined by a set of rules --- published as `RFC 9562`_ (formerly `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 9562`_.
As an example, let's think about :php:class:`Rfc4122\\UuidV1
<Ramsey\\Uuid\\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.
As an example, let's think about :php:class:`Rfc4122\\UuidV1 <Ramsey\\Uuid\\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 <Ramsey\\Uuid\\UuidInterface>` or
:php:interface:`Rfc4122\\UuidInterface <Ramsey\\Uuid\\Rfc4122\\UuidInterface>`.
However, ramsey/uuid *can* make guarantees about classes that implement :php:interface:`UuidInterface <Ramsey\\Uuid\\UuidInterface>`
or :php:interface:`Rfc4122\\UuidInterface <Ramsey\\Uuid\\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.
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 <reference.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 <Ramsey\\Uuid\\Type\\Integer>` should never contain
any characters other than numeral digits, and :php:class:`Type\\Hexadecimal
<Ramsey\\Uuid\\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 the reason why ramsey/uuid specifies certain :ref:`argument and return types <reference.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 <Ramsey\\Uuid\\Type\\Integer>` should never contain any characters other than numeral digits,
and :php:class:`Type\\Hexadecimal <Ramsey\\Uuid\\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.
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:
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... <customize>`
ramsey/uuid is able to provide this flexibility through the use of `interfaces`_,
`factories`_, and `dependency injection`_.
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 <Ramsey\\Uuid\\Rfc4122\\UuidV1>` nor a
:php:class:`UuidV4 <Ramsey\\Uuid\\Rfc4122\\UuidV4>` nor an
:php:class:`Integer <Ramsey\\Uuid\\Type\\Integer>` nor a
:php:class:`Time <Ramsey\\Uuid\\Type\\Time>`, etc. will ever change because of
`downstream`_ code.
At the same time, ramsey/uuid is able to guarantee that neither a :php:class:`UuidV1 <Ramsey\\Uuid\\Rfc4122\\UuidV1>`
nor a :php:class:`UuidV4 <Ramsey\\Uuid\\Rfc4122\\UuidV4>` nor an :php:class:`Integer <Ramsey\\Uuid\\Type\\Integer>` nor
a :php:class:`Time <Ramsey\\Uuid\\Type\\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`_.
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 9562`_.
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`.
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
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
.. _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
+3 -22
View File
@@ -1,28 +1,11 @@
.. _index:
==================
ramsey/uuid Manual
==================
======================
ramsey/uuid User Guide
======================
For `ramsey/uuid <https://github.com/ramsey/uuid>`_ |version|. Updated on |today|.
This work is licensed under the `Creative Commons Attribution 4.0 International
<https://creativecommons.org/licenses/by/4.0/>`_ license.
.. admonition:: Support ramsey/uuid!
:class: tip
Your support encourages and motivates me to continue building and
maintaining open source software. If you benefit from my work, consider
supporting me financially.
You may support ramsey/uuid as an individual through `GitHub Sponsors
<https://github.com/sponsors/ramsey>`_ or as a company through the
**Tidelift Subscription**. With the Tidelift Subscription, you can get
commercial maintenance and assurances, while supporting my work.
Learn more about :ref:`ramsey/uuid for enterprise <tidelift>`!
Contents
--------
@@ -41,8 +24,6 @@ Contents
FAQs <faq>
reference
copyright
tidelift
Indices and Tables
------------------
+10 -11
View File
@@ -4,17 +4,16 @@
Introduction
============
ramsey/uuid is a PHP library for generating and working with `RFC 4122`_ version
1, 2, 3, 4, 5, 6, and 7 universally unique identifiers (UUID). ramsey/uuid also
supports optional and non-standard features, such as GUIDs and other approaches
for encoding/decoding UUIDs.
ramsey/uuid is a PHP library for generating and working with `RFC 9562`_ (formerly `RFC 4122`_) version 1, 2, 3, 4, 5,
6, 7, and 8 universally unique identifiers (UUID). ramsey/uuid also supports optional and non-standard features, such as
GUIDs and other approaches for encoding/decoding UUIDs.
What Is a UUID?
###############
A universally unique identifier, or UUID, is a 128-bit unsigned integer, usually
represented as a hexadecimal string split into five groups with dashes. The most
widely-known and used types of UUIDs are defined by `RFC 4122`_.
A universally unique identifier, or UUID, is a 128-bit unsigned integer, usually represented as a hexadecimal string
split into five groups with dashes. The most widely-known and used types of UUIDs are defined by `RFC 9562`_ (formerly
`RFC 4122`_).
A UUID, when encoded in hexadecimal string format, looks like:
@@ -22,10 +21,10 @@ A UUID, when encoded in hexadecimal string format, looks like:
ebb5c735-0308-4e3c-9aea-8a270aebfe15
The probability of duplicating a UUID is close to zero, so they are a great
choice for generating unique identifiers in distributed systems.
The probability of duplicating a UUID is close to zero, so they are a great choice for generating unique identifiers in
distributed systems.
UUIDs can also be stored in binary format, as a string of 16 bytes.
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
+10 -20
View File
@@ -8,33 +8,23 @@ Nonstandard UUIDs
:titlesonly:
:hidden:
nonstandard/version6
nonstandard/guid
nonstandard/other
Outside of `RFC 4122`_, other types of UUIDs are in-use, following rules of
their own. Some of these are on their way to becoming accepted standards, while
others have historical reasons for remaining valid today. Still, others are
completely random and do not follow any rules.
Outside of `RFC 9562`_ (formerly `RFC 4122`_), other types of UUIDs are in-use, following rules of their own. Some of
these are on their way to becoming accepted standards, while others have historical reasons for remaining valid today.
Still, others are completely random and do not follow any rules.
For these cases, ramsey/uuid provides a special functionality to handle these
alternate, nonstandard forms.
Version 6: Reordered Time
This is a new version of UUID that combines the features of a
:ref:`version 1 UUID <rfc4122.version1>` with a *monotonically increasing*
UUID. For more details, see :ref:`nonstandard.version6`.
For these cases, ramsey/uuid provides a special functionality to handle these alternate, nonstandard forms.
Globally Unique Identifiers (GUIDs)
A globally unique identifier, or GUID, is often used as a synonym for UUID.
A key difference is the order of the bytes. Any `RFC 4122`_ version UUID may
be represented as a GUID. For more details, see :ref:`nonstandard.guid`.
A globally unique identifier, or GUID, is often used as a synonym for UUID. A key difference is the order of the
bytes. Any `RFC 9562`_ version UUID may be represented as a GUID. For more details, see :ref:`nonstandard.guid`.
Other Nonstandard UUIDs
Sometimes, UUID string or byte representations don't follow `RFC 4122`_.
Rather than reject these identifiers, ramsey/uuid returns them with the
special Nonstandard\\Uuid instance type. For more details, see
Sometimes, UUID string or byte representations don't follow `RFC 9562`_. Rather than reject these identifiers,
ramsey/uuid returns them with the special Nonstandard\\Uuid instance type. For more details, see
:ref:`nonstandard.other`.
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
+41 -56
View File
@@ -6,25 +6,21 @@ Globally Unique Identifiers (GUIDs)
.. tip::
Using these techniques to work with GUIDs is useful if you're working with
identifiers that have been stored in GUID byte order. For example, this is
the case if working with the ``UNIQUEIDENTIFIER`` data type in Microsoft SQL
Server. This is a GUID, stored as a 16-byte binary string. If working
directly with the bytes, you may use the GUID functionality in ramsey/uuid
to properly handle this data type.
Using these techniques to work with GUIDs is useful if you're working with identifiers that have been stored in GUID
byte order. For example, this is the case if working with the ``UNIQUEIDENTIFIER`` data type in Microsoft SQL Server.
This is a GUID, stored as a 16-byte binary string. If working directly with the bytes, you may use the GUID
functionality in ramsey/uuid to properly handle this data type.
According to the Windows Dev Center article on `GUID structure`_, "GUIDs are the
Microsoft implementation of the distributed computing environment (DCE)
universally unique identifier." For all intents and purposes, a GUID string
representation is identical to that of an `RFC 4122`_ UUID. For historical
reasons, *the byte order is not*.
According to the Windows Dev Center article on `GUID structure`_, "GUIDs are the Microsoft implementation of the
distributed computing environment (DCE) universally unique identifier." For all intents and purposes, a GUID string
representation is identical to that of an `RFC 9562`_ (formerly `RFC 4122`_) UUID. For historical reasons, *the byte
order is not*.
The `.NET Framework documentation`_ explains:
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.
This is best explained by example.
@@ -52,9 +48,8 @@ This is best explained by example.
bin2hex($guid->getBytes())
);
This transforms the bytes of a GUID, as represented by ``$guidBytes``, into a
:php:class:`Ramsey\\Uuid\\Guid\\Guid` instance and prints out some details about
it. It looks something like this:
This transforms the bytes of a GUID, as represented by ``$guidBytes``, into a :php:class:`Ramsey\\Uuid\\Guid\\Guid`
instance and prints out some details about it. It looks something like this:
.. code-block:: text
@@ -63,36 +58,31 @@ it. It looks something like this:
Version: 4
Bytes: 0eab93fc9ec9584b975e9c5e68c53624
Note the difference between the string GUID and the bytes. The bytes are
arranged like this:
Note the difference between the string GUID and the bytes. The bytes are arranged like this:
.. code-block:: text
0e ab 93 fc 9e c9 58 4b 97 5e 9c 5e 68 c5 36 24
In an `RFC 4122`_ UUID, the bytes are stored in the same order as you see
presented in the string representation. This is often called *network byte
order*, or *big-endian* order. In a GUID, the order of the bytes are reversed
in each grouping for the first 64 bits and stored in *little-endian* order. The
remaining 64 bits are stored in network byte order. See `Endianness
<#nonstandard-guid-endianness>`_ to learn more.
In an `RFC 9562`_ (formerly `RFC 4122`_) UUID, the bytes are stored in the same order as you see presented in the string
representation. This is often called *network byte order*, or *big-endian* order. In a GUID, the order of the bytes are
reversed in each grouping for the first 64 bits and stored in *little-endian* order. The remaining 64 bits are stored in
network byte order. See `Endianness <#nonstandard-guid-endianness>`_ to learn more.
.. caution::
The bytes themselves do not indicate their order. If you decode GUID bytes
as a UUID or UUID bytes as a GUID, you will get the wrong values. However,
you can always create a GUID or UUID from the same string value; the bytes
for each will be in a different order, even though the string is the same.
The key is to know ahead of time in what order the bytes are stored. Then,
you will be able to decode them using the correct approach.
The bytes themselves do not indicate their order. If you decode GUID bytes as a UUID or UUID bytes as a GUID, you
will get the wrong values. However, you can always create a GUID or UUID from the same string value; the bytes for
each will be in a different order, even though the string is the same.
The key is to know ahead of time in what order the bytes are stored. Then, you will be able to decode them using the
correct approach.
Converting GUIDs to UUIDs
#########################
Continuing from the example, :ref:`nonstandard.guid.decode-bytes-example`, we
can take the GUID string representation and convert it into a standard UUID.
Continuing from the example, :ref:`nonstandard.guid.decode-bytes-example`, we can take the GUID string representation
and convert it into a standard UUID.
.. code-block:: php
:caption: Convert a GUID to a UUID
@@ -108,9 +98,8 @@ can take the GUID string representation and convert it into a standard UUID.
bin2hex($uuid->getBytes())
);
Because the GUID was a version 4, random UUID, this creates an instance of
:php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV4` from the GUID string and prints out a
few details about it. It looks something like this:
Because the GUID was a version 4, random UUID, this creates an instance of :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV4`
from the GUID string and prints out a few details about it. It looks something like this:
.. code-block:: text
@@ -119,34 +108,30 @@ few details about it. It looks something like this:
Version: 4
Bytes: fc93ab0ec99e4b58975e9c5e68c53624
Note how the UUID string is identical to the GUID string. However, the byte
order is different, since they are in big-endian order. The bytes are now
arranged like this:
Note how the UUID string is identical to the GUID string. However, the byte order is different, since they are in
big-endian order. The bytes are now arranged like this:
.. code-block:: text
fc 93 ab 0e c9 9e 4b 58 97 5e 9c 5e 68 c5 36 24
.. admonition:: Endianness
:name: nonstandard.guid.endianness
Big-endian and little-endian refer to the ordering of bytes in a multi-byte
number. Big-endian order places the most significant byte first, followed by
the other bytes in descending order. Little-endian order places the least
Big-endian and little-endian refer to the ordering of bytes in a multi-byte number. Big-endian order places the most
significant byte first, followed by the other bytes in descending order. Little-endian order places the least
significant byte first, followed by the other bytes in ascending order.
Take the hexadecimal number ``0x1234``, for example. In big-endian order,
the bytes are stored as ``12 34``, and in little-endian order, they are
stored as ``34 12``. In either case, the number is still ``0x1234``.
Take the hexadecimal number ``0x1234``, for example. In big-endian order, the bytes are stored as ``12 34``, and in
little-endian order, they are stored as ``34 12``. In either case, the number is still ``0x1234``.
Networking protocols usually use big-endian ordering, while computer
processor architectures often use little-endian ordering.
The terms originated in Jonathan Swift's *Gulliver's Travels*, where the
Lilliputians argue over which end of a hard-boiled egg is the best end to
crack.
Networking protocols usually use big-endian ordering, while computer processor architectures often use little-endian
ordering.
The terms originated in Jonathan Swift's *Gulliver's Travels*, where the Lilliputians argue over which end of a
hard-boiled egg is the best end to crack.
.. _GUID structure: https://docs.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid#remarks
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
.. _.NET Framework documentation: https://docs.microsoft.com/en-us/dotnet/api/system.guid.tobytearray#remarks
.. _GUID structure: https://learn.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
.. _.NET Framework documentation: https://learn.microsoft.com/en-us/dotnet/api/system.guid.tobytearray
+12 -14
View File
@@ -4,20 +4,19 @@
Other Nonstandard UUIDs
=======================
Sometimes, you might encounter a string that looks like a UUID but doesn't
follow the `RFC 4122`_ specification. Take this string, for example:
Sometimes, you might encounter a string that looks like a UUID but doesn't follow the `RFC 9562`_ (formerly `RFC 4122`_)
specification. Take this string, for example:
.. code-block:: text
d95959bc-2ff5-43eb-fccd-14883ba8f174
At a glance, this looks like a valid UUID, but the variant bits don't match RFC
4122. Instead of throwing a validation exception, ramsey/uuid will assume this
is a UUID, since it fits the format and has 128 bits, but it will represent it
as a :php:class:`Ramsey\\Uuid\\Nonstandard\\Uuid`.
At a glance, this looks like a valid UUID, but the variant bits don't match `RFC 9562`_ (formerly `RFC 4122`_). Instead
of throwing a validation exception, ramsey/uuid will assume this is a UUID, since it fits the format and has 128 bits,
but it will represent it as a :php:class:`Ramsey\\Uuid\\Nonstandard\\Uuid`.
.. code-block:: php
:caption: Create an instance of Nonstandard\\Uuid from a non-RFC 4122 UUID
:caption: Create an instance of :php:class:`Ramsey\\Uuid\\Nonstandard\\Uuid` from a non-RFC 9562 UUID
use Ramsey\Uuid\Uuid;
@@ -31,8 +30,8 @@ as a :php:class:`Ramsey\\Uuid\\Nonstandard\\Uuid`.
$uuid->getFields()->getVariant()?->value
);
This will create a Nonstandard\\Uuid from the given string and print out a few
details about it. It will look something like this:
This will create a :php:class:`Ramsey\\Uuid\\Nonstandard\\Uuid` from the given string and print out a few details about
it. It will look something like this:
.. code-block:: text
@@ -41,9 +40,8 @@ details about it. It will look something like this:
Version: 0
Variant: 7
Note that the version is 0. Since the variant is 7, and there is no
formal specification for this variant of UUID, ramsey/uuid has no way of knowing
what type of UUID this is.
Note that the version is 0. Since the variant is 7, and there is no formal specification for this variant of UUID,
ramsey/uuid has no way of knowing what type of UUID this is.
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
-17
View File
@@ -1,17 +0,0 @@
.. _nonstandard.version6:
=========================
Version 6: Reordered Time
=========================
.. attention::
This documentation has moved to :ref:`RFC 4122 UUIDs: Version 6: Reordered
Time <rfc4122.version6>`.
Version 6 UUIDs have been promoted to the ``Rfc4122`` namespace. While still
in draft form, the version 6 format is not expected to change in any way
that breaks compatibility.
The :php:class:`Ramsey\\Uuid\\Nonstandard\\UuidV6` class is deprecated in
favor of :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV6`.
+19 -27
View File
@@ -4,7 +4,6 @@
Getting Started
===============
Requirements
############
@@ -13,37 +12,30 @@ ramsey/uuid |version| requires the following:
* PHP 8.0+
* `ext-json <https://www.php.net/manual/en/book.json.php>`_
The JSON extension is normally enabled by default, but it is possible to disable
it. Other required extensions include
`PCRE <https://www.php.net/manual/en/book.pcre.php>`_
and `SPL <https://www.php.net/manual/en/book.spl.php>`_. These standard
extensions cannot be disabled without patching PHP's build system and/or C
sources.
The JSON extension is normally enabled by default, but it is possible to disable it. Other required extensions include
`PCRE <https://www.php.net/manual/en/book.pcre.php>`_ and `SPL <https://www.php.net/manual/en/book.spl.php>`_. These
standard extensions cannot be disabled without patching PHP's build system and/or C sources.
ramsey/uuid recommends installing/enabling the following extensions. While not
required, these extensions improve the performance of ramsey/uuid.
ramsey/uuid recommends installing/enabling the following extensions. While not required, these extensions improve the
performance of ramsey/uuid.
* `ext-gmp <https://www.php.net/manual/en/book.gmp.php>`_
* `ext-bcmath <https://www.php.net/manual/en/book.bc.php>`_
Install With Composer
#####################
The only supported installation method for ramsey/uuid is
`Composer <https://getcomposer.org>`_. Use the following command to add
ramsey/uuid to your project dependencies:
The only supported installation method for ramsey/uuid is `Composer <https://getcomposer.org>`_. Use the following
command to add ramsey/uuid to your project dependencies:
.. code-block:: bash
composer require ramsey/uuid
Using ramsey/uuid
#################
After installing ramsey/uuid, the quickest way to get up-and-running is to use
the static generation methods.
After installing ramsey/uuid, the quickest way to get up-and-running is to use the static generation methods.
.. code-block:: php
@@ -62,18 +54,16 @@ This will return an instance of :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV4`.
.. tip::
.. rubric:: Use the Interfaces
Feel free to use ``instanceof`` to check the specific instance types of
UUIDs. However, when using type hints, it's best to use the interfaces.
Feel free to use ``instanceof`` to check the specific instance types of UUIDs. However, when using type hints, it's
best to use the interfaces.
The most lenient interface is :php:interface:`Ramsey\\Uuid\\UuidInterface`,
while :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface` ensures the
UUIDs you're using conform to the `RFC 4122`_ standard. If you're not sure
which one to use, start with the stricter
The most lenient interface is :php:interface:`Ramsey\\Uuid\\UuidInterface`, while
:php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface` ensures the UUIDs you're using conform to the `RFC 9562`_
(formerly `RFC 4122`_) standard. If you're not sure which one to use, start with the stricter
:php:interface:`Rfc4122\\UuidInterface <Ramsey\\Uuid\\Rfc4122\\UuidInterface>`.
ramsey/uuid provides a number of helpful static methods that help you work with
and generate most types of UUIDs, without any special customization of the
library.
ramsey/uuid provides a number of helpful static methods that help you work with and generate most types of UUIDs,
without any special customization of the library.
.. list-table::
:widths: 25 75
@@ -96,6 +86,8 @@ library.
- This generates a :ref:`rfc4122.version6` UUID.
* - :php:meth:`Uuid::uuid7() <Ramsey\\Uuid\\Uuid::uuid7>`
- This generates a :ref:`rfc4122.version7` UUID.
* - :php:meth:`Uuid::uuid8() <Ramsey\\Uuid\\Uuid::uuid8>`
- This generates a :ref:`rfc4122.version8` UUID.
* - :php:meth:`Uuid::isValid() <Ramsey\\Uuid\\Uuid::isValid>`
- Checks whether a string is a valid UUID.
* - :php:meth:`Uuid::fromString() <Ramsey\\Uuid\\Uuid::fromString>`
@@ -107,6 +99,6 @@ library.
* - :php:meth:`Uuid::fromDateTime() <Ramsey\\Uuid\\Uuid::fromDateTime>`
- Creates a version 1 UUID instance from a PHP `DateTimeInterface`_.
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
.. _DateTimeInterface: https://www.php.net/datetimeinterface
-1
View File
@@ -26,7 +26,6 @@ Reference
reference/guid-guid
reference/nonstandard-fields
reference/nonstandard-uuid
reference/nonstandard-uuidv6
reference/uuidfactoryinterface
reference/types
reference/exceptions
+32 -46
View File
@@ -78,91 +78,77 @@ Calculators
.. php:const:: UNNECESSARY
Asserts that the requested operation has an exact result, hence no
rounding is necessary.
Asserts that the requested operation has an exact result, hence no rounding is necessary.
.. php:const:: UP
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.
Always increments the digit prior to a nonzero discarded fraction. Note that this rounding mode never decreases
the magnitude of the calculated value.
.. php:const:: DOWN
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.
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.
.. php:const:: CEILING
Rounds towards positive infinity.
If the result is positive, behaves as for :php:const:`UP
<Ramsey\\Uuid\\Math\\RoundingMode::UP>`; if negative, behaves as for
:php:const:`DOWN <Ramsey\\Uuid\\Math\\RoundingMode::DOWN>`. Note that
this rounding mode never decreases the calculated value.
If the result is positive, behaves as for :php:const:`UP <Ramsey\\Uuid\\Math\\RoundingMode::UP>`; if negative,
behaves as for :php:const:`DOWN <Ramsey\\Uuid\\Math\\RoundingMode::DOWN>`. Note that this rounding mode never
decreases the calculated value.
.. php:const:: FLOOR
Rounds towards negative infinity.
If the result is positive, behave as for :php:const:`DOWN
<Ramsey\\Uuid\\Math\\RoundingMode::DOWN>`; if negative, behave as for
:php:const:`UP <Ramsey\\Uuid\\Math\\RoundingMode::UP>`. Note that this
rounding mode never increases the calculated value.
If the result is positive, behave as for :php:const:`DOWN <Ramsey\\Uuid\\Math\\RoundingMode::DOWN>`; if negative,
behave as for :php:const:`UP <Ramsey\\Uuid\\Math\\RoundingMode::UP>`. Note that this rounding mode never
increases the calculated value.
.. php:const:: HALF_UP
Rounds towards "nearest neighbor" unless both neighbors are equidistant,
in which case round up.
Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.
Behaves as for :php:const:`UP <Ramsey\\Uuid\\Math\\RoundingMode::UP>` if
the discarded fraction is >= 0.5; otherwise, behaves as for
:php:const:`DOWN <Ramsey\\Uuid\\Math\\RoundingMode::DOWN>`. Note that
this is the rounding mode commonly taught at school.
Behaves as for :php:const:`UP <Ramsey\\Uuid\\Math\\RoundingMode::UP>` if the discarded fraction is >= 0.5;
otherwise, behaves as for :php:const:`DOWN <Ramsey\\Uuid\\Math\\RoundingMode::DOWN>`. Note that this is the
rounding mode commonly taught at school.
.. php:const:: HALF_DOWN
Rounds towards "nearest neighbor" unless both neighbors are equidistant,
in which case round down.
Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.
Behaves as for :php:const:`UP <Ramsey\\Uuid\\Math\\RoundingMode::UP>` if
the discarded fraction is > 0.5; otherwise, behaves as for
:php:const:`DOWN <Ramsey\\Uuid\\Math\\RoundingMode::DOWN>`.
Behaves as for :php:const:`UP <Ramsey\\Uuid\\Math\\RoundingMode::UP>` if the discarded fraction is > 0.5;
otherwise, behaves as for :php:const:`DOWN <Ramsey\\Uuid\\Math\\RoundingMode::DOWN>`.
.. php:const:: HALF_CEILING
Rounds towards "nearest neighbor" unless both neighbors are equidistant,
in which case round towards positive infinity.
Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards positive
infinity.
If the result is positive, behaves as for :php:const:`HALF_UP
<Ramsey\\Uuid\\Math\\RoundingMode::HALF_UP>`; if negative, behaves as
for :php:const:`HALF_DOWN <Ramsey\\Uuid\\Math\\RoundingMode::HALF_DOWN>`.
If the result is positive, behaves as for :php:const:`HALF_UP <Ramsey\\Uuid\\Math\\RoundingMode::HALF_UP>`; if
negative, behaves as for :php:const:`HALF_DOWN <Ramsey\\Uuid\\Math\\RoundingMode::HALF_DOWN>`.
.. php:const:: HALF_FLOOR
Rounds towards "nearest neighbor" unless both neighbors are equidistant,
in which case round towards negative infinity.
Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards negative
infinity.
If the result is positive, behaves as for :php:const:`HALF_DOWN
<Ramsey\\Uuid\\Math\\RoundingMode::HALF_DOWN>`; if negative, behaves as
for :php:const:`HALF_UP <Ramsey\\Uuid\\Math\\RoundingMode::HALF_UP>`.
If the result is positive, behaves as for :php:const:`HALF_DOWN <Ramsey\\Uuid\\Math\\RoundingMode::HALF_DOWN>`;
if negative, behaves as for :php:const:`HALF_UP <Ramsey\\Uuid\\Math\\RoundingMode::HALF_UP>`.
.. php:const:: HALF_EVEN
Rounds towards the "nearest neighbor" unless both neighbors are
equidistant, in which case rounds towards the even neighbor.
Rounds towards the "nearest neighbor" unless both neighbors are equidistant, in which case rounds towards the
even neighbor.
Behaves as for :php:const:`HALF_UP <Ramsey\\Uuid\\Math\\RoundingMode::HALF_UP>`
if the digit to the left of the discarded fraction is odd; behaves as
for :php:const:`HALF_DOWN <Ramsey\\Uuid\\Math\\RoundingMode::HALF_DOWN>`
Behaves as for :php:const:`HALF_UP <Ramsey\\Uuid\\Math\\RoundingMode::HALF_UP>` if the digit to the left of the
discarded fraction is odd; behaves as for :php:const:`HALF_DOWN <Ramsey\\Uuid\\Math\\RoundingMode::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.
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.
+6 -12
View File
@@ -4,10 +4,8 @@
Exceptions
==========
All exceptions in the :php:ns:`Ramsey\\Uuid` namespace implement
:php:interface:`Ramsey\\Uuid\\Exception\\UuidExceptionInterface`. This provides
a base type you may use to catch any and all exceptions that originate from this
library.
All exceptions in the :php:ns:`Ramsey\\Uuid` namespace implement :php:interface:`Ramsey\\Uuid\\Exception\\UuidExceptionInterface`.
This provides a base type you may use to catch any and all exceptions that originate from this library.
.. php:namespace:: Ramsey\Uuid\Exception
@@ -25,15 +23,13 @@ library.
Extends `RuntimeException <https://www.php.net/runtimeexception>`_.
Thrown to indicate that the PHP DateTime extension encountered an
exception or error.
Thrown to indicate that the PHP DateTime extension encountered an exception or error.
.. php:exception:: DceSecurityException
Extends `RuntimeException <https://www.php.net/runtimeexception>`_.
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
.. php:exception:: InvalidArgumentException
@@ -57,15 +53,13 @@ library.
Extends `RuntimeException <https://www.php.net/runtimeexception>`_.
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
.. php:exception:: NodeException
Extends `RuntimeException <https://www.php.net/runtimeexception>`_.
Thrown to indicate that attempting to fetch or create a node ID encountered
an error.
Thrown to indicate that attempting to fetch or create a node ID encountered an error.
.. php:exception:: RandomSourceException
+2 -3
View File
@@ -10,9 +10,8 @@ Guid\\Guid
Implements :php:interface:`Ramsey\\Uuid\\UuidInterface`.
Guid represents a :ref:`nonstandard.guid`. In addition to providing the
methods defined on the interface, this class additionally provides the
following methods.
Guid represents a :ref:`nonstandard.guid`. In addition to providing the methods defined on the interface, this class
additionally provides the following methods.
.. php:method:: getFields()
+23 -3
View File
@@ -4,8 +4,8 @@
Helper Functions
================
ramsey/uuid additionally provides the following helper functions, which return
only the string standard representation of a UUID.
ramsey/uuid additionally provides the following helper functions, which return only the string standard representation
of a UUID.
.. php:function:: Ramsey\Uuid\v1([$node[, $clockSeq]])
@@ -54,9 +54,29 @@ only the string standard representation of a UUID.
.. php:function:: Ramsey\Uuid\v6([$node[, $clockSeq]])
Generates a string standard representation of a version 6, reordered time UUID.
Generates a string standard representation of a version 6, reordered Gregorian time UUID.
:param Ramsey\\Uuid\\Type\\Hexadecimal|null $node: An optional hexadecimal node to use
:param int|null $clockSeq: An optional clock sequence to use
:returns: A string standard representation of a version 6 UUID
:returntype: string
.. php:function:: Ramsey\Uuid\v7([$dateTime])
Generates a string standard representation of a version 7, Unix Epoch time UUID.
:param \\DatetimeInterface|null $node: An optional date/time from which to create the version 7 UUID. If not
provided, the UUID is generated using the current date/time
:returns: A string standard representation of a version 7 UUID
:returntype: string
.. php:function:: Ramsey\Uuid\v8($bytes)
Generates a string standard representation of a version 8, implementation-specific, custom format UUID.
: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.
:returns: A string standard representation of a version 8 UUID
:returntype: string
+2 -2
View File
@@ -4,8 +4,7 @@
Predefined Namespaces
=====================
`RFC 4122`_ defines a handful of UUIDs to use with "for some potentially
interesting name spaces."
`RFC 9562`_ (formerly `RFC 4122`_) defines a handful of UUIDs to use with "for some potentially interesting name spaces."
.. list-table::
:widths: 30 70
@@ -25,6 +24,7 @@ interesting name spaces."
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
.. _ISO object identifier (OID): http://www.oid-info.com
.. _X.500: https://en.wikipedia.org/wiki/X.500
.. _DN: https://en.wikipedia.org/wiki/Distinguished_Name
+1 -1
View File
@@ -10,4 +10,4 @@ Nonstandard\\Fields
Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\FieldsInterface`.
Nonstandard\Fields represents the fields of a nonstandard UUID.
Nonstandard\\Fields represents the fields of a nonstandard UUID.
+2 -3
View File
@@ -10,9 +10,8 @@ Nonstandard\\Uuid
Implements :php:interface:`Ramsey\\Uuid\\UuidInterface`.
Nonstandard\Uuid represents :ref:`nonstandard.other`. In addition to
providing the methods defined on the interface, this class additionally
provides the following methods.
Nonstandard\\Uuid represents :ref:`nonstandard.other`. In addition to providing the methods defined on the interface,
this class additionally provides the following methods.
.. php:method:: getFields()
-34
View File
@@ -1,34 +0,0 @@
.. _reference.nonstandard.uuidv6:
===================
Nonstandard\\UuidV6
===================
.. php:namespace:: Ramsey\Uuid\Nonstandard
.. php:class:: UuidV6
.. attention::
:php:class:`Ramsey\\Uuid\\Nonstandard\\UuidV6` is deprecated in favor of
:php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV6`. Please migrate any code
using ``Nonstandard\UuidV6`` to ``Rfc4122\UuidV6``. The interface is
otherwise identical.
Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface` and
:php:interface:`Ramsey\\Uuid\\TimeBasedUuidInterface`.
UuidV6 represents a :ref:`version 6, reordered time UUID
<nonstandard.version6>`. In addition to providing the methods defined on the
interface, this class additionally provides the following methods.
.. php:method:: toUuidV1()
:returns: A version 1 UUID, converted from this version 6 UUID
:returntype: Ramsey\\Uuid\\Rfc4122\\UuidV1
.. php:staticmethod:: fromUuidV1()
:param Ramsey\\Uuid\\Rfc4122\\UuidV1 $uuidV1: A version 1 UUID
:returns: A version 6 UUID, converted from the given version 1 UUID
:returntype: Ramsey\\Uuid\\Rfc4122\\UuidV6
+8 -8
View File
@@ -10,9 +10,8 @@ Rfc4122\\FieldsInterface
Implements :php:interface:`Ramsey\\Uuid\\Fields\\FieldsInterface`.
Rfc4122\FieldsInterface represents the fields of an RFC 4122 UUID.
In addition to the methods defined on the interface, this class additionally
defines the following methods.
Rfc4122\\FieldsInterface represents the fields of an `RFC 9562`_ (formerly `RFC 4122`_) UUID. In addition to the
methods defined on the interface, this class additionally defines the following methods.
.. php:method:: getClockSeq()
@@ -56,8 +55,7 @@ Rfc4122\\FieldsInterface
.. php:method:: getVariant()
Returns the variant, which, for RFC 4122 variant UUIDs, should always be
the value ``2``.
Returns the variant, which, for `RFC 9562`_ (formerly `RFC 4122`_) variant UUIDs, should always be the value ``2``.
:returns: The UUID variant.
:returntype: Ramsey\\Uuid\\Variant
@@ -70,9 +68,11 @@ Rfc4122\\FieldsInterface
.. php:method:: isNil()
A *nil* UUID is a special type of UUID with all 128 bits set to zero.
Its string standard representation is always
``00000000-0000-0000-0000-000000000000``.
A *nil* UUID is a special type of UUID with all 128 bits set to zero. Its string standard representation is
always ``00000000-0000-0000-0000-000000000000``.
:returns: True if this UUID represents a nil UUID.
:returntype: ``bool``
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
+5 -3
View File
@@ -10,11 +10,13 @@ Rfc4122\\UuidInterface
Implements :php:interface:`Ramsey\\Uuid\\UuidInterface`.
Rfc4122\UuidInterface represents an RFC 4122 UUID. In addition to the
methods defined on the interface, this interface additionally defines the
following methods.
Rfc4122\\UuidInterface represents an `RFC 9562`_ (formerly `RFC 4122`_) UUID. In addition to the methods defined on
the interface, this interface additionally defines the following methods.
.. php:method:: getFields()
:returns: The fields that comprise this UUID.
:returntype: Ramsey\\Uuid\\Rfc4122\\FieldsInterface
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
+2 -3
View File
@@ -11,9 +11,8 @@ Rfc4122\\UuidV1
Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface` and
:php:interface:`Ramsey\\Uuid\\TimeBasedUuidInterface`.
UuidV1 represents a :ref:`version 1, Gregorian time UUID <rfc4122.version1>`.
In addition to providing the methods defined on the interface, this class
additionally provides the following methods.
UuidV1 represents a :ref:`version 1, Gregorian time UUID <rfc4122.version1>`. In addition to providing the methods
defined on the interface, this class additionally provides the following methods.
.. php:method:: getDateTime()
+8 -12
View File
@@ -10,30 +10,26 @@ Rfc4122\\UuidV2
Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface`.
UuidV2 represents a :ref:`version 2, DCE Security UUID <rfc4122.version2>`.
In addition to providing the methods defined on the interface, this class
additionally provides the following methods.
UuidV2 represents a :ref:`version 2, DCE Security UUID <rfc4122.version2>`. In addition to providing the methods
defined on the interface, this class additionally provides the following methods.
.. php:method:: getDateTime()
Returns a `DateTimeInterface <https://www.php.net/datetimeinterface>`_
instance representing the timestamp associated with the UUID
Returns a `DateTimeInterface <https://www.php.net/datetimeinterface>`_ instance representing the timestamp
associated with the UUID
.. caution::
It is important to note that version 2 UUIDs suffer from some loss
of timestamp precision. See :ref:`rfc4122.version2.timestamp-problems`
to learn more.
It is important to note that version 2 UUIDs suffer from some loss of timestamp precision. See
:ref:`rfc4122.version2.timestamp-problems` to learn more.
:returns: A date object representing the timestamp associated with the UUID
:returntype: ``\DateTimeInterface``
.. php:method:: getLocalDomain()
:returns: The local domain identifier for this UUID, which is one of
:php:const:`Ramsey\\Uuid\\Uuid::DCE_DOMAIN_PERSON`,
:php:const:`Ramsey\\Uuid\\Uuid::DCE_DOMAIN_GROUP`, or
:php:const:`Ramsey\\Uuid\\Uuid::DCE_DOMAIN_ORG`
:returns: The local domain identifier for this UUID, which is one of :php:const:`Ramsey\\Uuid\\Uuid::DCE_DOMAIN_PERSON`,
:php:const:`Ramsey\\Uuid\\Uuid::DCE_DOMAIN_GROUP`, or :php:const:`Ramsey\\Uuid\\Uuid::DCE_DOMAIN_ORG`
:returntype: ``int``
.. php:method:: getLocalDomainName()
+1 -1
View File
@@ -10,4 +10,4 @@ Rfc4122\\UuidV3
Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface`.
UuidV3 represents a :ref:`version 3, name-based (MD5) UUID <rfc4122.version3>`.
UuidV3 represents a :ref:`version 3, name-based (MD5 hashed) UUID <rfc4122.version3>`.
+1 -1
View File
@@ -10,4 +10,4 @@ Rfc4122\\UuidV5
Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface`.
UuidV5 represents a :ref:`version 5, name-based (SHA-1) UUID <rfc4122.version5>`.
UuidV5 represents a :ref:`version 5, name-based (SHA-1 hashed) UUID <rfc4122.version5>`.
+2 -3
View File
@@ -10,9 +10,8 @@ Rfc4122\\UuidV6
Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface`.
UuidV6 represents a :ref:`version 6, reordered time UUID
<rfc4122.version6>`. In addition to providing the methods defined on the
interface, this class additionally provides the following methods.
UuidV6 represents a :ref:`version 6, reordered Gregorian time UUID <rfc4122.version6>`. In addition to providing the
methods defined on the interface, this class additionally provides the following methods.
.. php:method:: getDateTime()
+2 -3
View File
@@ -10,9 +10,8 @@ Rfc4122\\UuidV7
Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface`.
UuidV7 represents a :ref:`version 7, Unix Epoch time UUID <rfc4122.version7>`.
In addition to providing the methods defined on the interface, this class
additionally provides the following methods.
UuidV7 represents a :ref:`version 7, Unix Epoch time UUID <rfc4122.version7>`. In addition to providing the methods
defined on the interface, this class additionally provides the following methods.
.. php:method:: getDateTime()
+1 -1
View File
@@ -10,4 +10,4 @@ Rfc4122\\UuidV8
Implements :php:interface:`Ramsey\\Uuid\\Rfc4122\\UuidInterface`.
UuidV8 represents a :ref:`version 8, custom UUID <rfc4122.version8>`.
UuidV8 represents a :ref:`version 8, implementation-specific, custom format UUID <rfc4122.version8>`.
+23 -23
View File
@@ -12,44 +12,48 @@ Rfc4122\\Version
.. php:case:: Time : 1
A version 1 UUID uses a timestamp based on the Gregorian calendar epoch,
along with the MAC address (or *node*) for a network interface on the
local machine. For more details, see :ref:`rfc4122.version1`.
A version 1 UUID uses a timestamp based on the Gregorian calendar epoch, along with the MAC address (or *node*)
for a network interface on the local machine. For more details, see :ref:`rfc4122.version1`.
.. php:case:: DceSecurity : 2
Like a version 1 UUID, a version 2 UUID uses the current time, along
with the MAC address (or *node*) for a network interface on the local
machine. Additionally, a version 2 UUID replaces the low part of the
time field with a local identifier such as the user ID or group ID of
the local account that created the UUID. For more details, see
:ref:`rfc4122.version2`.
Like a version 1 UUID, a version 2 UUID uses the current time, along with the MAC address (or *node*) for a
network interface on the local machine. Additionally, a version 2 UUID replaces the low part of the time field
with a local identifier such as the user ID or group ID of the local account that created the UUID. For more
details, see :ref:`rfc4122.version2`.
.. php:case:: HashMd5 : 3
Name-based UUIDs combine a namespace with a name. This way, the UUIDs
are unique to the namespace they're created in. Version 3 UUIDs use the
MD5 hashing algorithm to combine the namespace and name. For more
details, see :ref:`rfc4122.version3`.
Name-based UUIDs combine a namespace with a name. This way, the UUIDs are unique to the namespace they're
created in. Version 3 UUIDs use the MD5 hashing algorithm to combine the namespace and name. For more details,
see :ref:`rfc4122.version3`.
.. php:case:: Random : 4
Version 4 UUIDs are randomly-generated identifiers. For more details,
see :ref:`rfc4122.version4`.
Version 4 UUIDs are randomly-generated identifiers. For more details, see :ref:`rfc4122.version4`.
.. php:case:: HashSha1 : 5
Name-based UUIDs combine a namespace with a name. This way, the UUIDs
are unique to the namespace they're created in. Version 5 UUIDs use the
SHA-1 hashing algorithm to combine the namespace and name. For more
details, see :ref:`rfc4122.version5`.
Name-based UUIDs combine a namespace with a name. This way, the UUIDs are unique to the namespace they're
created in. Version 5 UUIDs use the SHA-1 hashing algorithm to combine the namespace and name. For more details,
see :ref:`rfc4122.version5`.
.. php:case:: ReorderedTime : 6
Reordered Gregorian time UUIDs combine the features of a :ref:`version 1 UUID <rfc4122.version1>` with a
*monotonically increasing* UUID. For more details, see :ref:`rfc4122.version6`.
.. php:case:: UnixTime : 7
Unix Epoch time UUIDs combine a timestamp--based on milliseconds elapsed since the Unix Epoch--and random bytes
to create a monotonically increasing, sortable UUID without the privacy and entropy concerns associated with
version 1 and version 6 UUIDs. For more details, see :ref:`rfc4122.version7`.
.. php:case:: Custom : 8
Implementation-specific, custom format UUIDs allow applications to generate custom identifiers in an
RFC-compatible format. For more details, see :ref:`rfc4122.version8`.
.. php:const:: V1
An alias for :php:case:`Ramsey\\Uuid\\Rfc4122\\Version::Time`.
@@ -81,7 +85,3 @@ Rfc4122\\Version
.. php:const:: V8
An alias for :php:case:`Ramsey\\Uuid\\Rfc4122\\Version::Custom`.
.. php:const:: Peabody
An alias for :php:case:`Ramsey\\Uuid\\Rfc4122\\Version::ReorderedTime`.
+12 -18
View File
@@ -8,8 +8,7 @@ Types
.. php:class:: TypeInterface
Implements `JsonSerializable <https://www.php.net/jsonserializable>`_ and
`Serializable <https://www.php.net/serializable>`_.
Implements `JsonSerializable <https://www.php.net/jsonserializable>`_ and `Serializable <https://www.php.net/serializable>`_.
TypeInterface ensures consistency in typed values returned by ramsey/uuid.
@@ -36,39 +35,34 @@ Types
Implements :php:interface:`Ramsey\\Uuid\\Type\\NumberInterface`.
A value object representing a decimal, 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.
A value object representing a decimal, 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.
.. php:class:: Hexadecimal
Implements :php:interface:`Ramsey\\Uuid\\Type\\TypeInterface`.
A value object representing a hexadecimal number, 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.
A value object representing a hexadecimal number, 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.
.. php:class:: Integer
Implements :php:interface:`Ramsey\\Uuid\\Type\\NumberInterface`.
A value object representing an integer, 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.
A value object representing an integer, 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.
.. php:class:: Time
Implements :php:interface:`Ramsey\\Uuid\\Type\\TypeInterface`.
A value object representing a timestamp, 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.
A value object representing a timestamp, 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.
.. php:method:: getSeconds()
+19 -11
View File
@@ -4,9 +4,8 @@
Uuid
====
Ramsey\Uuid\Uuid provides static methods for the most common functionality for
generating and working with UUIDs. It also provides constants used throughout
the ramsey/uuid library.
Ramsey\\Uuid\\Uuid provides static methods for the most common functionality for generating and working with UUIDs. It
also provides constants used throughout the ramsey/uuid library.
.. php:namespace:: Ramsey\Uuid
@@ -30,8 +29,7 @@ the ramsey/uuid library.
.. php:const:: NIL
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.
.. php:const:: DCE_DOMAIN_PERSON
@@ -92,7 +90,7 @@ the ramsey/uuid library.
.. php:staticmethod:: uuid6([$node[, $clockSeq]])
Generates a version 6, reordered time UUID. See :ref:`rfc4122.version6`.
Generates a version 6, reordered Gregorian time UUID. See :ref:`rfc4122.version6`.
:param Ramsey\\Uuid\\Type\\Hexadecimal|null $node: An optional hexadecimal node to use
:param int|null $clockSeq: An optional clock sequence to use
@@ -107,10 +105,20 @@ the ramsey/uuid library.
:returns: A version 7 UUID
:returntype: Ramsey\\Uuid\\Rfc4122\\UuidV7
.. php:staticmethod:: uuid8($bytes)
Generates a version 8, implementation-specific, custom format UUID. See :ref:`rfc4122.version8`.
: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.
:returns: A version 8 UUID
:returntype: Ramsey\\Uuid\\Rfc4122\\UuidV8
.. php:staticmethod:: fromString($uuid)
Creates an instance of UuidInterface from the string standard
representation.
Creates an instance of UuidInterface from the string standard representation.
:param string $uuid: The string standard representation of a UUID
:returntype: Ramsey\\Uuid\\UuidInterface
@@ -131,8 +139,7 @@ the ramsey/uuid library.
.. php:staticmethod:: fromDateTime($dateTime[, $node[, $clockSeq]])
Creates a version 1 UUID instance from a `DateTimeInterface
<https://www.php.net/datetimeinterface>`_ instance.
Creates a version 1 UUID instance from a `DateTimeInterface <https://www.php.net/datetimeinterface>`_ instance.
:param DateTimeInterface $dateTime: The date from which to create the UUID instance
:param Ramsey\\Uuid\\Type\\Hexadecimal|null $node: An optional hexadecimal node to use
@@ -154,7 +161,8 @@ the ramsey/uuid library.
:param Ramsey\\Uuid\\UuidFactoryInterface $factory: A UUID factory to use for all UUID generation
:returntype: void
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
.. _ISO object identifier (OID): http://www.oid-info.com
.. _X.500: https://en.wikipedia.org/wiki/X.500
.. _DN: https://en.wikipedia.org/wiki/Distinguished_Name
+3 -5
View File
@@ -61,7 +61,7 @@ UuidFactoryInterface
.. php:method:: uuid6([$node[, $clockSeq]])
Generates a version 6, reordered time UUID. See :ref:`rfc4122.version6`.
Generates a version 6, reordered Gregorian time UUID. See :ref:`rfc4122.version6`.
:param Ramsey\\Uuid\\Type\\Hexadecimal|null $node: An optional hexadecimal node to use
:param int|null $clockSeq: An optional clock sequence to use
@@ -70,8 +70,7 @@ UuidFactoryInterface
.. php:method:: fromString($uuid)
Creates an instance of UuidInterface from the string standard
representation.
Creates an instance of UuidInterface from the string standard representation.
:param string $uuid: The string standard representation of a UUID
:returntype: Ramsey\\Uuid\\UuidInterface
@@ -92,8 +91,7 @@ UuidFactoryInterface
.. php:method:: fromDateTime($dateTime[, $node[, $clockSeq]])
Creates a version 1 UUID instance from a `DateTimeInterface
<https://www.php.net/datetimeinterface>`_ instance.
Creates a version 1 UUID instance from a `DateTimeInterface <https://www.php.net/datetimeinterface>`_ instance.
:param DateTimeInterface $dateTime: The date from which to create the UUID instance
:param Ramsey\\Uuid\\Type\\Hexadecimal|null $node: An optional hexadecimal node to use
+1 -1
View File
@@ -57,4 +57,4 @@ UuidInterface
:returns: The string standard representation of the UUID.
:returntype: ``string``
.. _URN: https://tools.ietf.org/html/rfc8141
.. _URN: https://www.rfc-editor.org/rfc/rfc8141
+4 -1
View File
@@ -31,4 +31,7 @@ Validators
Implements :php:interface:`Ramsey\\Uuid\\Validator\\ValidatorInterface`.
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.
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
+10 -6
View File
@@ -8,18 +8,17 @@ Variant
.. php:enum:: Variant : int
The variant number describes the layout of the UUID. UUIDs generated
according to the layout defined in `RFC 4122`_ will always have a variant
value set to ``2``. In ramsey/uuid, this is the enum value
:php:case:`Ramsey\\Uuid\\Variant::Rfc4122`.
The variant number describes the layout of the UUID. UUIDs generated according to the layout defined in `RFC 9562`_
(formerly `RFC 4122`_) will always have a variant value set to ``2``. In ramsey/uuid, this is the enum value
:php:case:`Ramsey\\Uuid\\Variant::Rfc9562`.
.. php:case:: ReservedNcs : 0
Reserved for NCS backward compatibility.
.. php:case:: Rfc4122 : 2
.. php:case:: Rfc9562 : 2
The RFC 4122 variant.
The `RFC 9562`_ (formerly `RFC 4122`_) variant.
.. php:case:: ReservedMicrosoft : 6
@@ -29,4 +28,9 @@ Variant
Reserved for future definition.
.. php:const:: Rfc4122
This is an alias for :php:case:`Ramsey\\Uuid\\Variant::Rfc9562`.
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
+26 -36
View File
@@ -1,8 +1,8 @@
.. _rfc4122:
==============
RFC 4122 UUIDs
==============
==================================
RFC 9562 (formerly RFC 4122) UUIDs
==================================
.. toctree::
:titlesonly:
@@ -17,51 +17,41 @@ RFC 4122 UUIDs
rfc4122/version7
rfc4122/version8
`RFC 4122`_ defines five versions of UUID, while a `new Internet-Draft under
review`_ defines three new versions. Each version has different generation
algorithms and properties. Which one you choose depends on your use-case. You
can find out more about their applications on the specific page for that version.
`RFC 9562`_ (formerly `RFC 4122`_) defines eight versions of UUIDs. Each version has different generation algorithms and
properties. Which one you choose depends on your use-case. You can find out more about their applications on the
specific page for that version.
Version 1: Gregorian Time
This version of UUID combines a timestamp, node value (in the form of a MAC
address from the local computer's network interface), and a clock sequence
to ensure uniqueness. For more details, see :doc:`rfc4122/version1`.
This version of UUID combines a timestamp, node value (in the form of a MAC address from the local computer's
network interface), and a clock sequence to ensure uniqueness. For more details, see :doc:`rfc4122/version1`.
Version 2: DCE Security
This version of UUID is the same as Version 1, except the ``clock_seq_low``
field is replaced with a *local domain* and the ``time_low`` field is
replaced with a *local identifier*. For more details, see
:doc:`rfc4122/version2`.
This version of UUID is the same as Version 1, except the ``clock_seq_low`` field is replaced with a *local domain*
and the ``time_low`` field is replaced with a *local identifier*. For more details, see :doc:`rfc4122/version2`.
Version 3: Name-based (MD5)
This version of UUID hashes together a namespace and a name to create a
deterministic UUID. The hashing algorithm used is MD5. For more details, see
:doc:`rfc4122/version3`.
This version of UUID hashes together a namespace and a name to create a deterministic UUID. The hashing algorithm
used is MD5. For more details, see :doc:`rfc4122/version3`.
Version 4: Random
This version creates a UUID using truly-random or pseudo-random numbers. For
more details, see :doc:`rfc4122/version4`.
This version creates a UUID using truly-random or pseudo-random numbers. For more details, see :doc:`rfc4122/version4`.
Version 5: Named-based (SHA-1)
This version of UUID hashes together a namespace and a name to create a
deterministic UUID. The hashing algorithm used is SHA-1. For more details,
see :doc:`rfc4122/version5`.
This version of UUID hashes together a namespace and a name to create a deterministic UUID. The hashing algorithm
used is SHA-1. For more details, see :doc:`rfc4122/version5`.
Version 6: Reordered Time
This version of UUID combines the features of a
:ref:`version 1 UUID <rfc4122.version1>` with a *monotonically increasing*
UUID. For more details, see :ref:`rfc4122.version6`.
Version 6: Reordered Gregorian Time
This version of UUID combines the features of a :ref:`version 1 UUID <rfc4122.version1>` with a *monotonically
increasing* UUID. For more details, see :ref:`rfc4122.version6`.
Version 7: Unix Epoch Time
This version of UUID combines a timestamp--based on milliseconds elapsed
since the Unix Epoch--and random bytes to create a monotonically increasing,
sortable UUID without the privacy and entropy concerns associated with
version 1 and version 6 UUIDs. For more details, see :ref:`rfc4122.version7`.
This version of UUID combines a timestamp--based on milliseconds elapsed since the Unix Epoch--and random bytes to
create a monotonically increasing, sortable UUID without the privacy and entropy concerns associated with version 1
and version 6 UUIDs. For more details, see :ref:`rfc4122.version7`.
Version 8: Custom
This version of UUID allows applications to generate custom identifiers in
an RFC-compatible format. For more details, see :doc:`rfc4122/version8`.
Version 8: Implementation-Specific, Custom Format
This version of UUID allows applications to generate custom identifiers in an RFC-compatible format. For more
details, see :doc:`rfc4122/version8`.
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
.. _new Internet-Draft under review: https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
+43 -70
View File
@@ -6,32 +6,26 @@ Version 1: Gregorian Time
.. attention::
If you need a time-based UUID, and you don't need the other features
included in version 1 UUIDs, we recommend using
If you need a time-based UUID, and you don't need the other features included in version 1 UUIDs, we recommend using
:ref:`version 7 UUIDs <rfc4122.version7>`.
A version 1 UUID uses a timestamp based on the `Gregorian calendar epoch`_,
along with the MAC address (or *node*) for a network interface on the local
machine. This serves two purposes:
A version 1 UUID uses a timestamp based on the `Gregorian calendar epoch`_, along with the MAC address (or *node*) for a
network interface on the local machine. This serves two purposes:
1. You can know *when* the identifier was created.
2. You can know *where* the identifier was created.
In a distributed system, these two pieces of information can be valuable. Not
only is there no need for a central authority to generate identifiers, but you
can determine what nodes in your infrastructure created the UUIDs and at what
In a distributed system, these two pieces of information can be valuable. Not only is there no need for a central
authority to generate identifiers, but you can determine what nodes in your infrastructure created the UUIDs and at what
time.
.. tip::
It is also possible to use a **randomly-generated node**, rather than a
hardware address. This is useful for when you don't want to leak machine
information, while still using a UUID based on time. Keep reading to find
out how.
It is also possible to use a **randomly-generated node**, rather than a hardware address. This is useful for when
you don't want to leak machine information, while still using a UUID based on time. Keep reading to find out how.
By default, ramsey/uuid will attempt to look up a MAC address for the machine it
is running on, using this value as the node. If it cannot find a MAC address, it
will generate a random node.
By default, ramsey/uuid will attempt to look up a MAC address for the machine it is running on, using this value as the
node. If it cannot find a MAC address, it will generate a random node.
.. code-block:: php
:caption: Generate a version 1, Gregorian time UUID
@@ -49,8 +43,8 @@ will generate a random node.
$uuid->getFields()->getNode()->toString()
);
This will generate a version 1 UUID and print out its string representation, the
time the UUID was created, and the node used to create the UUID.
This will generate a version 1 UUID and print out its string representation, the time the UUID was created, and the node
used to create the UUID.
It will look something like this:
@@ -61,8 +55,7 @@ It will look something like this:
Date: Sun, 01 Mar 2020 23:32:15 +0000
Node: 0242ac130003
You may provide custom values for version 1 UUIDs, including node and clock
sequence.
You may provide custom values for version 1 UUIDs, including node and clock sequence.
.. code-block:: php
:caption: Provide custom node and clock sequence to create a version 1,
@@ -80,37 +73,29 @@ sequence.
.. tip::
Version 1 UUIDs generated in ramsey/uuid are instances of UuidV1. Check out
the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV1` API documentation to learn
more about what you can do with a UuidV1 instance.
Version 1 UUIDs generated in ramsey/uuid are instances of UuidV1. Check out the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV1`
API documentation to learn more about what you can do with a UuidV1 instance.
.. _rfc4122.version1.custom:
Providing a Custom Node
#######################
You may override the default behavior by passing your own node value when
generating a version 1 UUID.
You may override the default behavior by passing your own node value when generating a version 1 UUID.
In the :ref:`example above <rfc4122.version1.custom-example>`, we saw how to
pass a custom node and clock sequence. An interesting thing to note about the
example is its use of StaticNodeProvider. Why didn't we pass in a
In the :ref:`example above <rfc4122.version1.custom-example>`, we saw how to pass a custom node and clock sequence. An
interesting thing to note about the example is its use of StaticNodeProvider. Why didn't we pass in a
:php:class:`Hexadecimal <Ramsey\\Uuid\\Type\\Hexadecimal>` value, instead?
According to `RFC 4122, section 4.5`_, node values that do not identify the
host --- in other words, our own custom node value --- should set the
unicast/multicast bit to one (1). This bit will never be set in IEEE 802
addresses obtained from network cards, so it helps to distinguish it from a
hardware MAC address.
According to `RFC 9562, section 6.10`_, node values that do not identify the host --- in other words, our own custom
node value --- should set the unicast/multicast bit to one (1). This bit will never be set in IEEE 802 addresses
obtained from network cards, so it helps to distinguish it from a hardware MAC address.
The StaticNodeProvider sets this bit for you. This is why we used it rather
than providing a :php:class:`Hexadecimal <Ramsey\\Uuid\\Type\\Hexadecimal>`
value directly.
The StaticNodeProvider sets this bit for you. This is why we used it rather than providing a :php:class:`Hexadecimal
<Ramsey\\Uuid\\Type\\Hexadecimal>` value directly.
Recall from the example that the node value we set was ``121212121212``, but if
you take a look at this value with ``$uuid->getFields()->getNode()->toString()``,
it becomes:
Recall from the example that the node value we set was ``121212121212``, but if you take a look at this value with
``$uuid->getFields()->getNode()->toString()``, it becomes:
.. code-block:: text
@@ -118,15 +103,13 @@ it becomes:
That's a result of this bit being set by the StaticNodeProvider.
.. _rfc4122.version1.random:
Generating a Random Node
########################
Instead of providing a custom node, you may also generate a random node each
time you generate a version 1 UUID. The RandomNodeProvider may be used to
generate a random node value, and like the StaticNodeProvider, it also sets the
Instead of providing a custom node, you may also generate a random node each time you generate a version 1 UUID. The
RandomNodeProvider may be used to generate a random node value, and like the StaticNodeProvider, it also sets the
unicast/multicast bit for you.
.. code-block:: php
@@ -140,53 +123,43 @@ unicast/multicast bit for you.
$uuid = Uuid::uuid1($nodeProvider->getNode());
.. _rfc4122.version1.clock:
What's a Clock Sequence?
########################
The clock sequence part of a version 1 UUID helps prevent collisions. Since this
UUID is based on a timestamp and a machine node value, it is possible for
collisions to occur for multiple UUIDs generated within the same microsecond on
The clock sequence part of a version 1 UUID helps prevent collisions. Since this UUID is based on a timestamp and a
machine node value, it is possible for collisions to occur for multiple UUIDs generated within the same microsecond on
the same machine.
The clock sequence is the solution to this problem.
The clock sequence is a 14-bit number --- this supports values from 0 to 16,383
--- which means it should be possible to generate up to 16,384 UUIDs per
microsecond with the same node value, before hitting a collision.
The clock sequence is a 14-bit number --- this supports values from 0 to 16,383 --- which means it should be possible to
generate up to 16,384 UUIDs per microsecond with the same node value, before hitting a collision.
.. caution::
ramsey/uuid does not use *stable storage* for clock sequence values.
Instead, all clock sequences are randomly-generated. If you are generating
a lot of version 1 UUIDs every microsecond, it is possible to hit collisions
because of the random values. If this is the case, you should use your own
mechanism for generating clock sequence values, to ensure against
randomly-generated duplicates.
See `section 4.2 of RFC 4122`_, for more information.
ramsey/uuid does not use *stable storage* for clock sequence values. Instead, all clock sequences are
randomly-generated. If you are generating a lot of version 1 UUIDs every microsecond, it is possible to hit
collisions because of the random values. If this is the case, you should use your own mechanism for generating clock
sequence values, to ensure against randomly-generated duplicates.
See `section 6.3 of RFC 9562`_, for more information.
.. _rfc4122.version1.privacy:
Privacy Concerns
################
As discussed earlier in this section, version 1 UUIDs use a MAC address from a
local hardware network interface. This means it is possible to uniquely identify
the machine on which a version 1 UUID was created.
As discussed earlier in this section, version 1 UUIDs use a MAC address from a local hardware network interface. This
means it is possible to uniquely identify the machine on which a version 1 UUID was created.
If the value provided by the timestamp of a version 1 UUID is important to you,
but you do not wish to expose the interface address of any of your local
machines, see :ref:`rfc4122.version1.random` or :ref:`rfc4122.version1.custom`.
If you do not need an identifier with a timestamp value embedded in it, see
:ref:`rfc4122.version4` to learn about random UUIDs.
If the value provided by the timestamp of a version 1 UUID is important to you, but you do not wish to expose the
interface address of any of your local machines, see :ref:`rfc4122.version1.random` or :ref:`rfc4122.version1.custom`.
If you do not need an identifier with a timestamp value embedded in it, see :ref:`rfc4122.version4` to learn about
random UUIDs.
.. _Gregorian calendar epoch: https://en.wikipedia.org/wiki/Gregorian_calendar
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
.. _RFC 4122, section 4.5: https://tools.ietf.org/html/rfc4122#section-4.5
.. _section 4.2 of RFC 4122: https://tools.ietf.org/html/rfc4122#section-4.2
.. _RFC 9562, section 6.10: https://www.rfc-editor.org/rfc/rfc9562#section-6.10
.. _section 6.3 of RFC 9562: https://www.rfc-editor.org/rfc/rfc9562#section-6.3
+71 -112
View File
@@ -6,32 +6,26 @@ Version 2: DCE Security
.. tip::
DCE Security UUIDs are so-called because they were defined as part of the
"Authentication and Security Services" for the `Distributed Computing
Environment`_ (DCE) in the early 1990s.
DCE Security UUIDs are so-called because they were defined as part of the "Authentication and Security Services" for
the `Distributed Computing Environment`_ (DCE) in the early 1990s.
Version 2 UUIDs are not widely used. See :ref:`rfc4122.version2.problems`
before deciding whether to use them.
Version 2 UUIDs are not widely used. See :ref:`rfc4122.version2.problems` before deciding whether to use them.
Like a :ref:`version 1 UUID <rfc4122.version1>`, a version 2 UUID uses the
current time, along with the MAC address (or *node*) for a network interface on
the local machine. Additionally, a version 2 UUID replaces the low part of the
time field with a local identifier such as the user ID or group ID of the local
account that created the UUID. This serves three purposes:
Like a :ref:`version 1 UUID <rfc4122.version1>`, a version 2 UUID uses the current time, along with the MAC address (or
*node*) for a network interface on the local machine. Additionally, a version 2 UUID replaces the low part of the time
field with a local identifier such as the user ID or group ID of the local account that created the UUID. This serves
three purposes:
1. You can know *when* the identifier was created (see
:ref:`rfc4122.version2.timestamp-problems`).
1. You can know *when* the identifier was created (see :ref:`rfc4122.version2.timestamp-problems`).
2. You can know *where* the identifier was created.
3. You can know *who* created the identifier.
In a distributed system, these three pieces of information can be valuable. Not
only is there no need for a central authority to generate identifiers, but you
can determine what nodes in your infrastructure created the UUIDs, at what time
they were created, and the account on the machine that created them.
In a distributed system, these three pieces of information can be valuable. Not only is there no need for a central
authority to generate identifiers, but you can determine what nodes in your infrastructure created the UUIDs, at what
time they were created, and the account on the machine that created them.
By default, ramsey/uuid will attempt to look up a MAC address for the machine it
is running on, using this value as the node. If it cannot find a MAC address, it
will generate a random node.
By default, ramsey/uuid will attempt to look up a MAC address for the machine it is running on, using this value as the
node. If it cannot find a MAC address, it will generate a random node.
.. code-block:: php
:caption: Use a domain to generate a version 2, DCE Security UUID
@@ -51,9 +45,8 @@ will generate a random node.
$uuid->getLocalIdentifier()->toString()
);
This will generate a version 2 UUID and print out its string representation, the
time the UUID was created, and the node used to create it, as well as the name
of the local domain specified and the local domain identifier (in this case, a
This will generate a version 2 UUID and print out its string representation, the time the UUID was created, and the node
used to create it, as well as the name of the local domain specified and the local domain identifier (in this case, a
`POSIX`_ UID, automatically obtained from the local machine).
It will look something like this:
@@ -67,8 +60,8 @@ It will look something like this:
Domain: person
ID: 501
Just as with version 1 UUIDs, you may provide custom values for version 2 UUIDs,
including local identifier, node, and clock sequence.
Just as with version 1 UUIDs, you may provide custom values for version 2 UUIDs, including local identifier, node, and
clock sequence.
.. code-block:: php
:caption: Provide custom identifier, node, and clock sequence to create a
@@ -93,10 +86,8 @@ including local identifier, node, and clock sequence.
.. tip::
Version 2 UUIDs generated in ramsey/uuid are instances of UuidV2. Check out
the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV2` API documentation to learn
more about what you can do with a UuidV2 instance.
Version 2 UUIDs generated in ramsey/uuid are instances of UuidV2. Check out the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV2`
API documentation to learn more about what you can do with a UuidV2 instance.
.. _rfc4122.version2.domains:
@@ -105,13 +96,11 @@ Domains
The *domain* value tells what the local identifier represents.
If using the *person* or *group* domains, ramsey/uuid will attempt to look up
these values from the local machine. On `POSIX`_ systems, it will use ``id -u``
and ``id -g``, respectively. On Windows, it will use ``whoami`` and ``wmic``.
If using the *person* or *group* domains, ramsey/uuid will attempt to look up these values from the local machine. On
`POSIX`_ systems, it will use ``id -u`` and ``id -g``, respectively. On Windows, it will use ``whoami`` and ``wmic``.
The *org* domain is site-defined. Its intent is to identify the organization
that generated the UUID, but since this can have different meanings for
different companies and projects, you get to define its value.
The *org* domain is site-defined. Its intent is to identify the organization that generated the UUID, but since this can
have different meanings for different companies and projects, you get to define its value.
.. list-table:: DCE Security Domains
:widths: 30 70
@@ -130,143 +119,113 @@ different companies and projects, you get to define its value.
.. note::
According to section 5.2.1.1 of `DCE 1.1: Authentication and Security Services
<https://publications.opengroup.org/c311>`_, the domain "can potentially hold
values outside the range [0, 2\ :sup:`8` -- 1]; however, the only values
currently registered are in the range [0, 2]."
As a result, ramsey/uuid supports only the *person*, *group*, and *org*
domains.
According to section 5.2.1.1 of `DCE 1.1: Authentication and Security Services <https://publications.opengroup.org/c311>`_,
the domain "can potentially hold values outside the range [0, 2\ :sup:`8` -- 1]; however, the only values currently
registered are in the range [0, 2]."
As a result, ramsey/uuid supports only the *person*, *group*, and *org* domains.
.. _rfc4122.version2.nodes:
Custom and Random Nodes
#######################
In the :ref:`example above <rfc4122.version2.custom-example>`, we provided a
custom node when generating a version 2 UUID. You may also generate random
node values.
To learn more, see the :ref:`rfc4122.version1.custom` and
:ref:`rfc4122.version1.random` sections under :ref:`rfc4122.version1`.
In the :ref:`example above <rfc4122.version2.custom-example>`, we provided a custom node when generating a version 2
UUID. You may also generate random node values.
To learn more, see the :ref:`rfc4122.version1.custom` and :ref:`rfc4122.version1.random` sections under
:ref:`rfc4122.version1`.
.. _rfc4122.version2.clock:
Clock Sequence
##############
In a version 2 UUID, the clock sequence serves the same purpose as in a version
1 UUID. See :ref:`rfc4122.version1.clock` to learn more.
In a version 2 UUID, the clock sequence serves the same purpose as in a version 1 UUID. See :ref:`rfc4122.version1.clock`
to learn more.
.. warning::
The clock sequence in a version 2 UUID is a 6-bit number. It supports values
from 0 to 63. This is different from the 14-bit number used by version 1
UUIDs.
See :ref:`rfc4122.version2.uniqueness-problems` to understand how this
affects version 2 UUIDs.
The clock sequence in a version 2 UUID is a 6-bit number. It supports values from 0 to 63. This is different from
the 14-bit number used by version 1 UUIDs.
See :ref:`rfc4122.version2.uniqueness-problems` to understand how this affects version 2 UUIDs.
.. _rfc4122.version2.problems:
Problems With Version 2 UUIDs
#############################
Version 2 UUIDs can be useful for the data they contain. However, there are
trade-offs in choosing to use them.
Version 2 UUIDs can be useful for the data they contain. However, there are trade-offs in choosing to use them.
.. _rfc4122.version2.privacy-problems:
Privacy
-------
Unless using a randomly-generated node, version 2 UUIDs use the MAC address for
a local hardware interface as the node value. In addition, they use a local
identifier --- usually an account or group ID. Some may consider the use of
these identifying features a breach of privacy. The use of a timestamp further
complicates the issue, since these UUIDs could be used to identify a user
account on a specific machine at a specific time.
If you don't need an identifier with a local identifier and timestamp value
embedded in it, see :ref:`rfc4122.version4` to learn about random UUIDs.
Unless using a randomly-generated node, version 2 UUIDs use the MAC address for a local hardware interface as the node
value. In addition, they use a local identifier --- usually an account or group ID. Some may consider the use of these
identifying features a breach of privacy. The use of a timestamp further complicates the issue, since these UUIDs could
be used to identify a user account on a specific machine at a specific time.
If you don't need an identifier with a local identifier and timestamp value embedded in it, see :ref:`rfc4122.version4`
to learn about random UUIDs.
.. _rfc4122.version2.uniqueness-problems:
Limited Uniqueness
------------------
With the inclusion of the local identifier and domain comes a serious limitation
in the number of unique UUIDs that may be created. This is because:
With the inclusion of the local identifier and domain comes a serious limitation in the number of unique UUIDs that may
be created. This is because:
1. The local identifier replaces the lower 32 bits of the timestamp.
2. The domain replaces the lower 8 bits of the clock sequence.
As a result, the timestamp advances --- the clock *ticks* --- only once every
429.49 seconds (about 7 minutes). This means the clock sequence is important to
ensure uniqueness, but since the clock sequence is only 6 bits, compared to 14
bits for version 1 UUIDs, **only 64 unique UUIDs per combination of node,
domain, and identifier may be generated per 7-minute tick of the clock**.
As a result, the timestamp advances --- the clock *ticks* --- only once every 429.49 seconds (about 7 minutes). This
means the clock sequence is important to ensure uniqueness, but since the clock sequence is only 6 bits, compared to 14
bits for version 1 UUIDs, **only 64 unique UUIDs per combination of node, domain, and identifier may be generated per
7-minute tick of the clock**.
You can overcome this lack of uniqueness by using a
:ref:`random node <rfc4122.version2.nodes>`, which provides 47 bits of
randomness to the UUID --- after setting the unicast/multicast bit (see
discussion on :ref:`rfc4122.version1.custom`) --- increasing the number of UUIDs
per 7-minute clock tick to 2\ :sup:`53` (or 9,007,199,254,740,992), at the
expense of remaining locally unique.
You can overcome this lack of uniqueness by using a :ref:`random node <rfc4122.version2.nodes>`, which provides 47 bits
of randomness to the UUID --- after setting the unicast/multicast bit (see discussion on :ref:`rfc4122.version1.custom`)
--- increasing the number of UUIDs per 7-minute clock tick to 2\ :sup:`53` (or 9,007,199,254,740,992), at the expense of
remaining locally unique.
.. note::
This lack of uniqueness did not present a problem for DCE, since:
[T]he security architecture of DCE depends upon the uniqueness of
security-version UUIDs *only within the context of a cell*; that is,
only within the context of the local [Registration Service's]
(persistent) datastore, and that degree of uniqueness can be guaranteed
by the RS itself (namely, the RS maintains state in its datastore, in
the sense that it can always check that every UUID it maintains is
different from all other UUIDs it maintains). In other words, while
security-version UUIDs are (like all UUIDs) specified to be "globally
unique in space and time", security is not compromised if they are
merely "locally unique per cell".
-- `DCE 1.1: Authentication and Security Services, section 5.2.1.1
<https://publications.opengroup.org/c311>`_
[T]he security architecture of DCE depends upon the uniqueness of security-version UUIDs *only within the
context of a cell*; that is, only within the context of the local [Registration Service's] (persistent)
datastore, and that degree of uniqueness can be guaranteed by the RS itself (namely, the RS maintains state in
its datastore, in the sense that it can always check that every UUID it maintains is different from all other
UUIDs it maintains). In other words, while security-version UUIDs are (like all UUIDs) specified to be "globally
unique in space and time", security is not compromised if they are merely "locally unique per cell".
-- `DCE 1.1: Authentication and Security Services, section 5.2.1.1 <https://publications.opengroup.org/c311>`_
.. _rfc4122.version2.timestamp-problems:
Lossy Timestamps
----------------
Version 2 UUIDs are generated in the same way as version 1 UUIDs, but the low
part of the timestamp (the ``time_low`` field) is replaced by a 32-bit integer
that represents a local identifier. Because of this, not only do version 2 UUIDs
have :ref:`limited uniqueness <rfc4122.version2.uniqueness-problems>`, but they
also lack time precision.
Version 2 UUIDs are generated in the same way as version 1 UUIDs, but the low part of the timestamp (the ``time_low``
field) is replaced by a 32-bit integer that represents a local identifier. Because of this, not only do version 2 UUIDs
have :ref:`limited uniqueness <rfc4122.version2.uniqueness-problems>`, but they also lack time precision.
When reconstructing the timestamp to return a `DateTimeInterface`_ instance from
:php:meth:`UuidV2::getDateTime() <Ramsey\\Uuid\\Rfc4122\\UuidV2::getDateTime>`,
we replace the 32 lower bits of the timestamp with zeros, since the local
identifier should not be part of the timestamp. This results in a loss of
precision, causing the timestamp to be off by a range of 0 to 429.4967295
seconds (or 7 minutes, 9 seconds, and 496,730 microseconds).
When reconstructing the timestamp to return a `DateTimeInterface`_ instance from :php:meth:`UuidV2::getDateTime()
<Ramsey\\Uuid\\Rfc4122\\UuidV2::getDateTime>`, we replace the 32 lower bits of the timestamp with zeros, since the local
identifier should not be part of the timestamp. This results in a loss of precision, causing the timestamp to be off by
a range of 0 to 429.4967295 seconds (or 7 minutes, 9 seconds, and 496,730 microseconds).
When using version 2 UUIDs, treat the timestamp as an approximation. At worst,
it could be off by about 7 minutes.
When using version 2 UUIDs, treat the timestamp as an approximation. At worst, it could be off by about 7 minutes.
.. hint::
If the value 429.4967295 looks familiar, it's because it directly
corresponds to 2\ :sup:`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).
If the value 429.4967295 looks familiar, it's because it directly corresponds to 2\ :sup:`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).
.. _Distributed Computing Environment: https://en.wikipedia.org/wiki/Distributed_Computing_Environment
.. _POSIX: https://en.wikipedia.org/wiki/POSIX
+19 -28
View File
@@ -6,27 +6,21 @@ Version 3: Name-based (MD5)
.. attention::
`RFC 4122`_ states, "If backward compatibility is not an issue, SHA-1 is
preferred." As a result, the use of :ref:`version 5 UUIDs
<rfc4122.version5>` is preferred over version 3 UUIDs, unless you have a
specific use-case for version 3 UUIDs.
`RFC 9562`_ states, "Where possible, UUIDv5 SHOULD be used in lieu of UUIDv3." Unless you have a specific use-case
for version 3 UUIDs, use :ref:`version 5 UUIDs <rfc4122.version5>`.
.. note::
To learn about name-based UUIDs, read the section :ref:`rfc4122.version5`.
Version 3 UUIDs behave exactly the same as :ref:`version 5 UUIDs
<rfc4122.version5>`. The only difference is the hashing algorithm used to
generate the UUID.
To learn about name-based UUIDs, read the section :ref:`rfc4122.version5`. Version 3 UUIDs behave exactly the same
as :ref:`version 5 UUIDs <rfc4122.version5>`. The only difference is the hashing algorithm used to generate the UUID.
Version 3 UUIDs use `MD5`_ as the hashing algorithm for combining
the namespace and the name.
Version 3 UUIDs use `MD5`_ as the hashing algorithm for combining the namespace and the name.
Due to the use of a different hashing algorithm, version 3 UUIDs generated with
any given namespace and name will differ from version 5 UUIDs generated using
the same namespace and name.
Due to the use of a different hashing algorithm, version 3 UUIDs generated with any given namespace and name will differ
from version 5 UUIDs generated using the same namespace and name.
As an example, let's take a look at generating a version 3 UUID using the same
namespace and name used in ":ref:`rfc4122.version5.url-example`."
As an example, let's take a look at generating a version 3 UUID using the same namespace and name used in
":ref:`rfc4122.version5.url-example`."
.. code-block:: php
:caption: Generate a version 3, name-based UUID for a URL
@@ -36,13 +30,11 @@ namespace and name used in ":ref:`rfc4122.version5.url-example`."
$uuid = Uuid::uuid3(Uuid::NAMESPACE_URL, 'https://www.php.net');
Even though the namespace and name are the same, the version 3 UUID generated
will always be ``3f703955-aaba-3e70-a3cb-baff6aa3b28f``.
Even though the namespace and name are the same, the version 3 UUID generated will always be
``3f703955-aaba-3e70-a3cb-baff6aa3b28f``.
Likewise, we can use the custom namespace we created in
":ref:`rfc4122.version5.create-namespace`" to generate a version 3 UUID, but the
result will be different from the version 5 UUID with the same custom namespace
and name.
Likewise, we can use the custom namespace we created in ":ref:`rfc4122.version5.create-namespace`" to generate a version
3 UUID, but the result will be different from the version 5 UUID with the same custom namespace and name.
.. code-block:: php
:caption: Use a custom namespace to create version 3, name-based UUIDs
@@ -54,15 +46,14 @@ and name.
$uuid = Uuid::uuid3(WIDGET_NAMESPACE, 'widget/1234567890');
With this custom namespace, the version 3 UUID for the name "widget/1234567890"
will always be ``53564aa3-4154-3ca5-ac90-dba59dc7d3cb``.
With this custom namespace, the version 3 UUID for the name "widget/1234567890" will always be
``53564aa3-4154-3ca5-ac90-dba59dc7d3cb``.
.. tip::
Version 3 UUIDs generated in ramsey/uuid are instances of UuidV3. Check out
the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV3` API documentation to learn
more about what you can do with a UuidV3 instance.
Version 3 UUIDs generated in ramsey/uuid are instances of UuidV3. Check out the
:php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV3` API documentation to learn more about what you can do with a UuidV3
instance.
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
.. _MD5: https://en.wikipedia.org/wiki/MD5
+7 -10
View File
@@ -4,10 +4,9 @@
Version 4: Random
=================
Version 4 UUIDs are perhaps the most popular form of UUID. They are
randomly-generated and do not contain any information about the time they are
created or the machine that generated them. If you don't care about this
information, then a version 4 UUID might be perfect for your needs.
Version 4 UUIDs are perhaps the most popular form of UUID. They are randomly-generated and do not contain any
information about the time they are created or the machine that generated them. If you don't care about this information,
then a version 4 UUID might be perfect for your needs.
.. code-block:: php
:caption: Generate a version 4, random UUID
@@ -23,17 +22,15 @@ information, then a version 4 UUID might be perfect for your needs.
$uuid->getFields()->getVersion()?->value
);
This will generate a version 4 UUID and print out its string representation.
It will look something like this:
This will generate a version 4 UUID and print out its string representation. It will look something like this:
.. code-block:: text
UUID: 1ee9aa1b-6510-4105-92b9-7171bb2f3089
Version: 4
.. tip::
Version 4 UUIDs generated in ramsey/uuid are instances of UuidV4. Check out
the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV4` API documentation to learn
more about what you can do with a UuidV4 instance.
Version 4 UUIDs generated in ramsey/uuid are instances of UuidV4. Check out the
:php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV4` API documentation to learn more about what you can do with a UuidV4
instance.
+34 -46
View File
@@ -6,40 +6,32 @@ Version 5: Name-based (SHA-1)
.. danger::
Since :ref:`version 3 <rfc4122.version3>` and version 5 UUIDs essentially
use a *salt* (the namespace) to hash data, it may be tempting to use them to
hash passwords. **DO NOT do this under any circumstances!** You should not
store any sensitive information in a version 3 or version 5 UUID, since `MD5
and SHA-1 are insecure and have known attacks demonstrated against them
<https://en.wikipedia.org/wiki/Hash_function_security_summary>`_. *Use these
types of UUIDs as identifiers only.*
Since :ref:`version 3 <rfc4122.version3>` and version 5 UUIDs essentially use a *salt* (the namespace) to hash data,
it may be tempting to use them to hash passwords. **DO NOT do this under any circumstances!** You should not store
any sensitive information in a version 3 or version 5 UUID, since `MD5 and SHA-1 are insecure and have known attacks
demonstrated against them <https://en.wikipedia.org/wiki/Hash_function_security_summary>`_.
The first thing that comes to mind with most people think of a UUID is a
*random* identifier, but name-based UUIDs aren't random at all. In fact, they're
deterministic. For any given identical namespace and name, you will always
*Use these types of UUIDs as identifiers only.*
The first thing that comes to mind with most people think of a UUID is a *random* identifier, but name-based UUIDs
aren't random at all. In fact, they're deterministic. For any given identical namespace and name, you will always
generate the same UUID.
Name-based UUIDs are useful when you need an identifier that's based on
something's *name* --- think *identity* --- and will always be the same no
matter where or when it is created.
Name-based UUIDs are useful when you need an identifier that's based on something's *name* --- think *identity* --- and
will always be the same no matter where or when it is created.
For example, let's say I want to create an identifier for a URL. I could use
a :ref:`version 1 <rfc4122.version1>` or :ref:`version 4 <rfc4122.version4>`
UUID to create an identifier for the URL, but what if I'm working with a
distributed system, and I want to ensure that every client in this system can
always generate the same identifier for any given URL?
For example, let's say I want to create an identifier for a URL. I could use a :ref:`version 1 <rfc4122.version1>` or
:ref:`version 4 <rfc4122.version4>` UUID to create an identifier for the URL, but what if I'm working with a distributed
system, and I want to ensure that every client in this system can always generate the same identifier for any given URL?
This is where a name-based UUID comes in handy.
Name-based UUIDs combine a namespace with a name. This way, the UUIDs are unique
to the namespace they're created in. `RFC 4122`_ defines some
:ref:`predefined namespaces <reference.name-based-namespaces>`, one of which is
for URLs.
Name-based UUIDs combine a namespace with a name. This way, the UUIDs are unique to the namespace they're created in.
`RFC 9562`_ defines some :ref:`predefined namespaces <reference.name-based-namespaces>`, one of which is for URLs.
.. note::
Version 5 UUIDs use `SHA-1`_ as the hashing algorithm for combining the
namespace and the name.
Version 5 UUIDs use `SHA-1`_ as the hashing algorithm for combining the namespace and the name.
.. code-block:: php
:caption: Generate a version 5, name-based UUID for a URL
@@ -49,29 +41,27 @@ for URLs.
$uuid = Uuid::uuid5(Uuid::NAMESPACE_URL, 'https://www.php.net');
The UUID generated will always be the same, as long as the namespace and name
are the same. The version 5 UUID for "https://www.php.net" in the URL namespace
will always be ``a8f6ae40-d8a7-58f0-be05-a22f94eca9ec``. See for yourself. Run
the code above, and you'll see it always generates the same UUID.
The UUID generated will always be the same, as long as the namespace and name are the same. The version 5 UUID for
"https://www.php.net" in the URL namespace will always be ``a8f6ae40-d8a7-58f0-be05-a22f94eca9ec``. See for yourself.
Run the code above, and you'll see it always generates the same UUID.
.. tip::
Version 5 UUIDs generated in ramsey/uuid are instances of UuidV5. Check out
the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV5` API documentation to learn
more about what you can do with a UuidV5 instance.
Version 5 UUIDs generated in ramsey/uuid are instances of UuidV5. Check out the
:php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV5` API documentation to learn more about what you can do with a UuidV5
instance.
.. _rfc4122.version5.custom-namespaces:
Custom Namespaces
#################
If you're working with name-based UUIDs for names that don't fit into any of
the :ref:`predefined namespaces <reference.name-based-namespaces>`, or you don't
want to use any of the predefined namespaces, you can create your own namespace.
If you're working with name-based UUIDs for names that don't fit into any of the :ref:`predefined namespaces
<reference.name-based-namespaces>`, or you don't want to use any of the predefined namespaces, you can create your own
namespace.
The best way to do this is to generate a :ref:`version 1 <rfc4122.version1>` or
:ref:`version 4 <rfc4122.version4>` UUID and save this UUID as your namespace.
The best way to do this is to generate a :ref:`version 1 <rfc4122.version1>` or :ref:`version 4 <rfc4122.version4>` UUID
and save this UUID as your namespace.
.. code-block:: php
:caption: Generate a custom namespace UUID
@@ -83,8 +73,8 @@ The best way to do this is to generate a :ref:`version 1 <rfc4122.version1>` or
printf("My namespace UUID is %s\n", $uuid->toString());
This will generate a version 1, Gregorian time UUID, which we'll store to a
constant so we can reuse it as our own custom namespace.
This will generate a version 1, Gregorian time UUID, which we'll store to a constant so we can reuse it as our own
custom namespace.
.. code-block:: php
:caption: Use a custom namespace to create version 5, name-based UUIDs
@@ -96,13 +86,11 @@ constant so we can reuse it as our own custom namespace.
$uuid = Uuid::uuid5(WIDGET_NAMESPACE, 'widget/1234567890');
With this custom namespace, the version 5 UUID for the name "widget/1234567890"
will always be ``a35477ae-bfb1-5f2e-b5a4-4711594d855f``.
With this custom namespace, the version 5 UUID for the name "widget/1234567890" will always be
``a35477ae-bfb1-5f2e-b5a4-4711594d855f``.
We can publish this namespace, allowing others to use it to generate identifiers
for widgets. When two or more systems try to reference the same widget, they'll
end up generating the same identifier for it, which is exactly what we want.
We can publish this namespace, allowing others to use it to generate identifiers for widgets. When two or more systems
try to reference the same widget, they'll end up generating the same identifier for it, which is exactly what we want.
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
.. _SHA-1: https://en.wikipedia.org/wiki/SHA-1
+33 -102
View File
@@ -1,49 +1,30 @@
.. _rfc4122.version6:
=========================
Version 6: Reordered Time
=========================
.. note::
Version 6, reordered time UUIDs are a new format of UUID, proposed in an
`Internet-Draft under review`_ at the IETF. While the draft is still going
through the IETF process, the version 6 format is not expected to change
in any way that breaks compatibility.
===================================
Version 6: Reordered Gregorian Time
===================================
.. attention::
If you need a time-based UUID, and you don't need the other features
included in version 6 UUIDs, we recommend using
If you need a time-based UUID, and you don't need the other features included in version 6 UUIDs, we recommend using
:ref:`version 7 UUIDs <rfc4122.version7>`.
Version 6 UUIDs solve `two problems that have long existed`_ with the use of
:ref:`version 1 <rfc4122.version1>` UUIDs:
Version 6 UUIDs solve `two problems that have long existed`_ with the use of :ref:`version 1 <rfc4122.version1>` UUIDs:
1. Scattered database records
2. Inability to sort by an identifier in a meaningful way (i.e., insert order)
To overcome these issues, we need the ability to generate UUIDs that are
*monotonically increasing* while still providing all the benefits of version
1 UUIDs.
To overcome these issues, we need the ability to generate UUIDs that are *monotonically increasing* while still
providing all the benefits of version 1 UUIDs.
Version 6 UUIDs do this by storing the time in standard byte order, instead of
breaking it up and rearranging the time bytes, according to the `RFC 4122`_
definition. All other fields remain the same, and the version maintains its
position, according to RFC 4122.
Version 6 UUIDs do this by storing the time in standard byte order, instead of breaking it up and rearranging the time
bytes, according to the `RFC 9562`_ (formerly `RFC 4122`_) definition for version 1 UUIDs. All other fields remain the
same.
In all other ways, version 6 UUIDs function like version 1 UUIDs.
.. tip::
Prior to version 4.0.0, ramsey/uuid provided a solution for this with the
:ref:`ordered-time codec <customize.ordered-time-codec>`. Use of the
ordered-time codec is still valid and acceptable. However, you may replace
UUIDs generated using the ordered-time codec with version 6 UUIDs. Keep
reading to find out how.
.. code-block:: php
:caption: Generate a version 6, reordered time UUID
:caption: Generate a version 6, reordered Gregorian time UUID
:name: rfc4122.version6.example
use Ramsey\Uuid\Uuid;
@@ -58,8 +39,8 @@ In all other ways, version 6 UUIDs function like version 1 UUIDs.
$uuid->getFields()->getNode()->toString()
);
This will generate a version 6 UUID and print out its string representation, the
time the UUID was created, and the node used to create the UUID.
This will generate a version 6 UUID and print out its string representation, the time the UUID was created, and the node
used to create the UUID.
It will look something like this:
@@ -70,12 +51,10 @@ It will look something like this:
Date: Sun, 08 Mar 2020 04:29:37 +0000
Node: 0242ac130003
You may provide custom values for version 6 UUIDs, including node and clock
sequence.
You may provide custom values for version 6 UUIDs, including node and clock sequence.
.. code-block:: php
:caption: Provide custom node and clock sequence to create a version 6,
reordered time UUID
:caption: Provide custom node and clock sequence to create a version 6, reordered Gregorian time UUID
:name: rfc4122.version6.custom-example
use Ramsey\Uuid\Provider\Node\StaticNodeProvider;
@@ -89,32 +68,28 @@ sequence.
.. tip::
Version 6 UUIDs generated in ramsey/uuid are instances of UuidV6. Check out
the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV6` API documentation to
learn more about what you can do with a UuidV6 instance.
Version 6 UUIDs generated in ramsey/uuid are instances of UuidV6. Check out the
:php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV6` API documentation to learn more about what you can do with a UuidV6
instance.
.. _rfc4122.version6.nodes:
Custom and Random Nodes
#######################
In the :ref:`example above <rfc4122.version6.custom-example>`, we provided a
custom node when generating a version 6 UUID. You may also generate random
node values.
To learn more, see the :ref:`rfc4122.version1.custom` and
:ref:`rfc4122.version1.random` sections under :ref:`rfc4122.version1`.
In the :ref:`example above <rfc4122.version6.custom-example>`, we provided a custom node when generating a version 6
UUID. You may also generate random node values.
To learn more, see the :ref:`rfc4122.version1.custom` and :ref:`rfc4122.version1.random` sections under
:ref:`rfc4122.version1`.
.. _rfc4122.version6.clock:
Clock Sequence
##############
In a version 6 UUID, the clock sequence serves the same purpose as in a version
1 UUID. See :ref:`rfc4122.version1.clock` to learn more.
In a version 6 UUID, the clock sequence serves the same purpose as in a version 1 UUID. See :ref:`rfc4122.version1.clock`
to learn more.
.. _rfc4122.version6.version1-conversion:
@@ -150,64 +125,20 @@ It is possible to convert back-and-forth between version 6 and version 1 UUIDs.
$uuid1 = $uuid6->toUuidV1();
}
.. _rfc4122.version6.ordered-time-conversion:
Ordered-time to Version 6 Conversion
####################################
You may convert UUIDs previously generated and stored using the
:ref:`ordered-time codec <customize.ordered-time-codec>` into version 6 UUIDs.
.. caution::
If you perform this conversion, the bytes and string representation of your
UUIDs will change. This will break any software that expects your
identifiers to be fixed.
.. code-block:: php
:caption: Convert an ordered-time codec encoded UUID to a version 6 UUID
:name: rfc4122.version6.convert-ordered-time-example
use Ramsey\Uuid\Codec\OrderedTimeCodec;
use Ramsey\Uuid\Rfc4122\UuidV1;
use Ramsey\Uuid\Rfc4122\UuidV6;
use Ramsey\Uuid\UuidFactory;
// The bytes of a version 1 UUID previously stored in some datastore
// after encoding to bytes with the OrderedTimeCodec.
$bytes = hex2bin('11ea60faf17c8af6ad23acde48001122');
$factory = new UuidFactory();
$codec = new OrderedTimeCodec($factory->getUuidBuilder());
$factory->setCodec($codec);
$orderedTimeUuid = $factory->fromBytes($bytes);
if ($orderedTimeUuid instanceof UuidV1) {
$uuid6 = UuidV6::fromUuidV1($orderedTimeUuid);
}
.. _rfc4122.version6.privacy:
Privacy Concerns
################
Like :ref:`version 1 UUIDs <rfc4122.version1>`, version 6 UUIDs use a MAC
address from a local hardware network interface. This means it is possible to
uniquely identify the machine on which a version 6 UUID was created.
Like :ref:`version 1 UUIDs <rfc4122.version1>`, version 6 UUIDs use a MAC address from a local hardware network
interface. This means it is possible to uniquely identify the machine on which a version 6 UUID was created.
If the value provided by the timestamp of a version 6 UUID is important to you,
but you do not wish to expose the interface address of any of your local
machines, see :ref:`rfc4122.version6.nodes`.
If the value provided by the timestamp of a version 6 UUID is important to you, but you do not wish to expose the
interface address of any of your local machines, see :ref:`rfc4122.version6.nodes`.
If you do not need an identifier with a node value embedded in it, but you still
need the benefit of a monotonically increasing unique identifier, see
:ref:`rfc4122.version7`.
If you do not need an identifier with a node value embedded in it, but you still need the benefit of a monotonically
increasing unique identifier, see :ref:`rfc4122.version7`.
.. _Internet-Draft under review: https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.6
.. _two problems that have long existed: https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/
.. _RFC 4122: https://tools.ietf.org/html/rfc4122
.. _two problems that have long existed: https://www.percona.com/blog/store-uuid-optimized-way/
.. _RFC 4122: https://www.rfc-editor.org/rfc/rfc4122
.. _RFC 9562: https://www.rfc-editor.org/rfc/rfc9562
+27 -49
View File
@@ -4,48 +4,33 @@
Version 7: Unix Epoch Time
==========================
.. note::
Version 7, Unix Epoch time UUIDs are a new format of UUID, proposed in an
`Internet-Draft under review`_ at the IETF. While the draft is still going
through the IETF process, the version 7 format is not expected to change
in any way that breaks compatibility.
.. admonition:: ULIDs and Version 7 UUIDs
:class: hint
Version 7 UUIDs are binary-compatible with `ULIDs`_ (universally unique
lexicographically-sortable identifiers).
Version 7 UUIDs are binary-compatible with `ULIDs`_ (universally unique lexicographically-sortable identifiers).
Both use a 48-bit timestamp in milliseconds since the Unix Epoch, filling
the rest with random data. Version 7 UUIDs then add the version and variant
bits required by the UUID specification, which reduces the randomness from
80 bits to 74. Otherwise, they are identical.
Both use a 48-bit timestamp in milliseconds since the Unix Epoch, filling the rest with random data. Version 7 UUIDs
then add the version and variant bits required by the UUID specification, which reduces the randomness from 80 bits
to 74. Otherwise, they are identical.
You may even convert a version 7 UUID to a ULID.
:ref:`See below for an example. <rfc4122.version7.ulid>`
You may even convert a version 7 UUID to a ULID. :ref:`See below for an example. <rfc4122.version7.ulid>`
Version 7 UUIDs solve `two problems that have long existed`_ with the use of
:ref:`version 1 <rfc4122.version1>` UUIDs:
Version 7 UUIDs solve `two problems that have long existed`_ with the use of :ref:`version 1 <rfc4122.version1>` UUIDs:
1. Scattered database records
2. Inability to sort by an identifier in a meaningful way (i.e., insert order)
To overcome these issues, we need the ability to generate UUIDs that are
*monotonically increasing*.
To overcome these issues, we need the ability to generate UUIDs that are *monotonically increasing*.
:ref:`Version 6 UUIDs <rfc4122.version6>` provide an excellent solution for
those who need monotonically increasing, sortable UUIDs with the features of
version 1 UUIDs (MAC address and clock sequence), but if those features aren't
:ref:`Version 6 UUIDs <rfc4122.version6>` provide an excellent solution for those who need monotonically increasing,
sortable UUIDs with the features of version 1 UUIDs (MAC address and clock sequence), but if those features aren't
necessary for your application, using a version 6 UUID might be overkill.
Version 7 UUIDs combine random data (like version 4 UUIDs) with a timestamp (in
milliseconds since the Unix Epoch, i.e., 1970-01-01 00:00:00 UTC) to create a
monotonically increasing, sortable UUID that doesn't have any privacy concerns,
Version 7 UUIDs combine random data (like version 4 UUIDs) with a timestamp (in milliseconds since the Unix Epoch, i.e.,
1970-01-01 00:00:00 UTC) to create a monotonically increasing, sortable UUID that doesn't have any privacy concerns,
since it doesn't include a MAC address.
For this reason, implementations should use version 7 UUIDs over versions 1 and
6, if possible.
For this reason, implementations should use version 7 UUIDs over versions 1 and 6, if possible.
.. code-block:: php
:caption: Generate a version 7, Unix Epoch time UUID
@@ -62,8 +47,7 @@ For this reason, implementations should use version 7 UUIDs over versions 1 and
$uuid->getDateTime()->format('r'),
);
This will generate a version 7 UUID and print out its string representation and
the time it was created.
This will generate a version 7 UUID and print out its string representation and the time it was created.
It will look something like this:
@@ -73,8 +57,8 @@ It will look something like this:
Version: 7
Date: Wed, 14 Sep 2022 16:41:10 +0000
To use an existing date and time to generate a version 7 UUID, you may pass a
``\DateTimeInterface`` instance to the ``uuid7()`` method.
To use an existing date and time to generate a version 7 UUID, you may pass a ``\DateTimeInterface`` instance to the
``uuid7()`` method.
.. code-block:: php
:caption: Generate a version 7 UUID from an existing date and time
@@ -103,23 +87,20 @@ Which will print something like this:
.. tip::
Version 7 UUIDs generated in ramsey/uuid are instances of UuidV7. Check out
the :php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV7` API documentation to learn
more about what you can do with a UuidV7 instance.
Version 7 UUIDs generated in ramsey/uuid are instances of UuidV7. Check out the
:php:class:`Ramsey\\Uuid\\Rfc4122\\UuidV7` API documentation to learn more about what you can do with a UuidV7
instance.
.. _rfc4122.version7.ulid:
Convert a Version 7 UUID to a ULID
##################################
As mentioned in the callout above, version 7 UUIDs are binary-compatible with
`ULIDs`_. This means you can encode a version 7 UUID using `Crockford's Base 32
algorithm`_ and it will be a valid ULID, timestamp and all.
As mentioned in the callout above, version 7 UUIDs are binary-compatible with `ULIDs`_. This means you can encode a
version 7 UUID using `Crockford's Base 32 algorithm`_ and it will be a valid ULID, timestamp and all.
Using the third-party library `tuupola/base32`_, here's how we can encode a
version 7 UUID as a ULID. Note that there's a little bit of work to perform the
conversion, since you're working with different bases.
Using the third-party library `tuupola/base32`_, here's how we can encode a version 7 UUID as a ULID. Note that there's
a little bit of work to perform the conversion, since you're working with different bases.
.. code-block:: php
:caption: Encode a version 7, Unix Epoch time UUID as a ULID
@@ -158,16 +139,13 @@ This will print something like this:
.. caution::
Be aware that all version 7 UUIDs may be converted to ULIDs but not all
ULIDs may be converted to UUIDs.
Be aware that all version 7 UUIDs may be converted to ULIDs but not all ULIDs may be converted to UUIDs.
For that matter, all UUIDs of any version may be encoded as ULIDs, but they
will not be monotonically increasing and sortable unless they are version 7
UUIDs. You will also not be able to extract a meaningful timestamp from the
ULID, unless it was converted from a version 7 UUID.
For that matter, all UUIDs of any version may be encoded as ULIDs, but they will not be monotonically increasing and
sortable unless they are version 7 UUIDs. You will also not be able to extract a meaningful timestamp from the ULID,
unless it was converted from a version 7 UUID.
.. _ULIDs: https://github.com/ulid/spec
.. _Internet-Draft under review: https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.7
.. _two problems that have long existed: https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/
.. _two problems that have long existed: https://www.percona.com/blog/store-uuid-optimized-way/
.. _Crockford's Base 32 algorithm: https://www.crockford.com/base32.html
.. _tuupola/base32: https://packagist.org/packages/tuupola/base32
+10 -25
View File
@@ -1,29 +1,18 @@
.. _rfc4122.version8:
=================
Version 8: Custom
=================
========================
Version 8: Custom Format
========================
.. note::
Version 8, custom UUIDs are a new format of UUID, proposed in an
`Internet-Draft under review`_ at the IETF. While the draft is still going
through the IETF process, the version 8 format is not expected to change
in any way that breaks compatibility.
Version 8 UUIDs allow applications to create custom UUIDs in an RFC-compatible
way. The only requirement is the version and variant bits must be set according
to the UUID specification. 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.
Version 8 UUIDs allow applications to create custom UUIDs in an RFC-compatible way. The only requirement is the version
and variant bits must be set according to the UUID specification. 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.
.. warning::
The bytes should be a 16-byte octet string, an open blob of data that you
may fill with 128 bits of information. 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.
The bytes should be a 16-byte octet string, an open blob of data that you may fill with 128 bits of information.
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.
.. code-block:: php
:caption: Generate a version 8, custom UUID
@@ -39,13 +28,9 @@ understand the semantics of the value.
$uuid->getFields()->getVersion()
);
This will generate a version 8 UUID and print out its string representation.
It will look something like this:
This will generate a version 8 UUID and print out its string representation. It will look something like this:
.. code-block:: text
UUID: 00112233-4455-8677-8899-aabbccddeeff
Version: 8
.. _Internet-Draft under review: https://datatracker.ietf.org/doc/html/draft-ietf-uuidrev-rfc4122bis-00#section-5.8
+29 -46
View File
@@ -4,21 +4,19 @@
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.
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
<Ramsey\\Uuid\\Rfc4122\\UuidV1>`.
Let's say we have a method that uses a type hint for :php:class:`UuidV1 <Ramsey\\Uuid\\Rfc4122\\UuidV1>`.
.. code-block:: php
@@ -27,12 +25,10 @@ Let's say we have a method that uses a type hint for :php:class:`UuidV1
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?
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() <Ramsey\\Uuid\\Uuid::uuid1>` to
create a regular UuidV1 instance and pass it.
One way is to use :php:meth:`Uuid::uuid1() <Ramsey\\Uuid\\Uuid::uuid1>` to create a regular UuidV1 instance and pass it.
.. code-block:: php
@@ -44,9 +40,8 @@ create a regular UuidV1 instance and pass it.
$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.
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
@@ -63,18 +58,15 @@ by generating a UUID ahead of time and using it as a known value.
.. note::
These examples assume the use of `PHPUnit`_ for tests. The concepts will
work no matter what testing framework you use.
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.
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
@@ -85,14 +77,13 @@ tricky to test.
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 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 <customize.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`.
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
@@ -111,9 +102,8 @@ long as you implement :php:interface:`Ramsey\\Uuid\\UuidFactoryInterface`.
}
}
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()
<Ramsey\\Uuid\\UuidFactoryInterface::uuid1>` method for our tests.
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() <Ramsey\\Uuid\\UuidFactoryInterface::uuid1>` method for our tests.
.. code-block:: php
@@ -137,15 +127,13 @@ and we can even change the value returned by the :php:meth:`uuid1()
.. 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.
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.
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:
@@ -153,8 +141,7 @@ and we can even change the value returned by the :php:meth:`uuid1()
Mocking UuidInterface
---------------------
Another technique for testing with UUIDs is to mock
:php:interface:`UuidInterface <Ramsey\\Uuid\\UuidInterface>`.
Another technique for testing with UUIDs is to mock :php:interface:`UuidInterface <Ramsey\\Uuid\\UuidInterface>`.
Consider a method that accepts a UuidInterface.
@@ -165,11 +152,9 @@ Consider a method that accepts a UuidInterface.
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.
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
@@ -189,10 +174,8 @@ object were called.
.. 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.
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
-74
View File
@@ -1,74 +0,0 @@
.. role:: btn-info
:class: btn btn-info
.. role:: btn-neutral
:class: btn btn-neutral
.. |nbsp| unicode:: 0xA0
:trim:
.. |Learn More| replace:: :btn-neutral:`Learn More`
.. _Learn More: https://tidelift.com/subscription/pkg/packagist-ramsey-uuid?utm_source=undefined&utm_medium=referral&utm_campaign=enterprise
.. |Request a Demo| replace:: :btn-info:`Request a Demo`
.. _Request a Demo: https://tidelift.com/subscription/request-a-demo?utm_source=undefined&utm_medium=referral&utm_campaign=enterprise
.. _tidelift:
==========================
ramsey/uuid for Enterprise
==========================
.. rubric:: Available as part of the Tidelift Subscription
Tidelift is working with the maintainers of ramsey/uuid and thousands of other
open source projects to deliver commercial support and maintenance for the open
source dependencies you use to build your applications. Save time, reduce risk,
and improve code health, while paying the maintainers of the exact dependencies
you use.
.. centered:: |Learn More|_ |nbsp| |nbsp| |nbsp| |Request a Demo|_
.. rubric:: Enterprise-ready open source software --- managed for you
The Tidelift Subscription is a managed open source subscription for application
dependencies covering millions of open source projects across JavaScript,
Python, Java, PHP, Ruby, .NET, and more.
Your subscription includes:
Security updates
Tidelifts security response team coordinates patches for new breaking
security vulnerabilities and alerts immediately through a private channel,
so your software supply chain is always secure.
Licensing verification and indemnification
Tidelift verifies license information to enable easy policy enforcement and
adds intellectual property indemnification to cover creators and users in
case something goes wrong. You always have a 100% up-to-date bill of
materials for your dependencies to share with your legal team, customers,
or partners.
Maintenance and code improvement
Tidelift ensures the software you rely on keeps working as long as you need
it to work. Your managed dependencies are actively maintained and we recruit
additional maintainers where required.
Package selection and version guidance
We help you choose the best open source packages from the start—and then
guide you through updates to stay on the best releases as new issues arise.
Roadmap input
Take a seat at the table with the creators behind the software you use.
Tidelifts participating maintainers earn more income as their software is
used by more subscribers, so theyre interested in knowing what you need.
Tooling and cloud integration
Tidelift works with GitHub, GitLab, BitBucket, and more. We support every
cloud platform (and other deployment targets, too).
The end result? All of the capabilities you expect from commercial-grade
software, for the full breadth of open source you use. That means less time
grappling with esoteric open source trivia, and more time building your own
applications—and your business.
.. centered:: |Learn More|_ |nbsp| |nbsp| |nbsp| |Request a Demo|_
+13 -19
View File
@@ -4,28 +4,22 @@
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
library to 3.x.
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 library to 3.x.
One major breaking change is the transition from the ``Rhumsaa`` root namespace
to ``Ramsey``. In most cases, all you will need is to change the namespace to
``Ramsey`` in your code, and everything will "just work."
One major breaking change is the transition from the ``Rhumsaa`` root namespace to ``Ramsey``. In most cases, all you
will need is to change the namespace to ``Ramsey`` in your code, and everything will "just work."
.. note::
For more details on the namespace change, including reasons for the change,
read the blog post "`Introducing ramsey/uuid
<https://benramsey.com/blog/2016/04/ramsey-uuid/>`_".
For more details on the namespace change, including reasons for the change, read the blog post "`Introducing
ramsey/uuid <https://benramsey.com/blog/2016/04/ramsey-uuid/>`_".
Here are full details on the breaking changes to the public API of this library:
1. All namespace references of ``Rhumsaa`` have changed to ``Ramsey``. Simply
change the namespace to ``Ramsey`` in your code and everything should work.
2. The console application has moved to
`ramsey/uuid-console <https://packagist.org/packages/ramsey/uuid-console>`_.
If using the console functionality, use Composer to require
``ramsey/uuid-console``.
3. The Doctrine field type mapping has moved to
`ramsey/uuid-doctrine <https://packagist.org/packages/ramsey/uuid-doctrine>`_.
If using the Doctrine functionality, use Composer to require
``ramsey/uuid-doctrine``.
1. All namespace references of ``Rhumsaa`` have changed to ``Ramsey``. Simply change the namespace to ``Ramsey`` in your
code and everything should work.
2. The console application has moved to `ramsey/uuid-console <https://packagist.org/packages/ramsey/uuid-console>`_. If
using the console functionality, use Composer to require ``ramsey/uuid-console``.
3. The Doctrine field type mapping has moved to `ramsey/uuid-doctrine <https://packagist.org/packages/ramsey/uuid-doctrine>`_.
If using the Doctrine functionality, use Composer to require ``ramsey/uuid-doctrine``.
+84 -130
View File
@@ -4,16 +4,13 @@
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.
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`_.
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:
@@ -22,11 +19,10 @@ What's New?
There are a lot of new features in ramsey/uuid! Here are a few of them:
* Support :ref:`version 6 UUIDs <nonstandard.version6>`.
* Support :ref:`version 6 UUIDs <rfc4122.version6>`.
* Support :ref:`version 2 (DCE Security) UUIDs <rfc4122.version2>`.
* 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:
* 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 <Ramsey\\Uuid\\Rfc4122\\UuidV1>`
* :php:class:`Rfc4122\\UuidV2 <Ramsey\\Uuid\\Rfc4122\\UuidV2>`
@@ -35,16 +31,14 @@ There are a lot of new features in ramsey/uuid! Here are a few of them:
* :php:class:`Rfc4122\\UuidV5 <Ramsey\\Uuid\\Rfc4122\\UuidV5>`
* :php:class:`Rfc4122\\NilUuid <Ramsey\\Uuid\\Rfc4122\\NilUuid>`
* Add classes to represent version 6 UUIDs, GUIDs, and nonstandard
(non-RFC 4122 variants) UUIDs:
* Add classes to represent version 6 UUIDs, GUIDs, and nonstandard (non-RFC 4122 variants) UUIDs:
* :php:class:`Nonstandard\\UuidV6 <Ramsey\\Uuid\\Nonstandard\\UuidV6>`
* :php:class:`Nonstandard\\Uuid <Ramsey\\Uuid\\Nonstandard\\Uuid>`
* :php:class:`Guid\\Guid <Ramsey\\Uuid\\Guid\\Guid>`
* Add :php:meth:`Uuid::fromDateTime() <Ramsey\\Uuid\\Uuid::fromDateTime>` to
create version 1 UUIDs from instances of DateTimeInterface.
* Add :php:meth:`Uuid::fromDateTime() <Ramsey\\Uuid\\Uuid::fromDateTime>` to create version 1 UUIDs from instances of
DateTimeInterface.
.. _upgrading.3-to-4.changed:
@@ -55,67 +49,53 @@ What's Changed?
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.
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
<upgrading.3-to-4.static-methods>` on the :php:class:`Uuid <Ramsey\\Uuid\\Uuid>`
class. They've changed slightly, but this won't affect you if your type hints
* 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 <upgrading.3-to-4.static-methods>` on the
:php:class:`Uuid <Ramsey\\Uuid\\Uuid>` class. They've changed slightly, but this won't affect you if your type hints
use :php:interface:`UuidInterface <Ramsey\\Uuid\\UuidInterface>`.
* The :ref:`return types for three methods <upgrading.3-to-4.return-types>`
defined on :php:interface:`UuidInterface <Ramsey\\Uuid\\UuidInterface>` have
changed, breaking backwards compatibility. **Take note and update your code.**
* :ref:`There are a number of deprecations. <upgrading.3-to-4.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
<reference.exceptions>`. The exception UnsatisfiedDependencyException no
longer exists.
* If you customize ramsey/uuid at all by implementing the interfaces, take a
look at the :ref:`interface <upgrading.3-to-4.interfaces>` and
:ref:`constructor <upgrading.3-to-4.constructors>` changes and update your
code.
* The :ref:`return types for three methods <upgrading.3-to-4.return-types>` defined on :php:interface:`UuidInterface
<Ramsey\\Uuid\\UuidInterface>` have changed, breaking backwards compatibility. **Take note and update your code.**
* :ref:`There are a number of deprecations. <upgrading.3-to-4.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 <reference.exceptions>`. The exception
UnsatisfiedDependencyException no longer exists.
* If you customize ramsey/uuid at all by implementing the interfaces, take a look at the :ref:`interface
<upgrading.3-to-4.interfaces>` and :ref:`constructor <upgrading.3-to-4.constructors>` changes and update your code.
.. tip::
If you maintain a public project that uses ramsey/uuid version 3 and you
find that **your code does not require any changes to upgrade** to version
4, consider using the following version constraint in your project's
``composer.json`` file:
If you maintain a public project that uses ramsey/uuid version 3 and you find that **your code does not require any
changes to upgrade** to version 4, consider using the following version constraint in your project's ``composer.json``
file:
.. code-block:: bash
composer require ramsey/uuid:"^3 || ^4"
This will allow any `downstream users`_ of your project who aren't ready to
upgrade to version 4 the ability to continue using your project while
deciding on an appropriate upgrade schedule.
If your downstream users do not specify ramsey/uuid as a dependency, and
they use functionality specific to version 3, they may need to update their
own Composer dependencies to use ramsey/uuid ``^3`` to avoid using version 4.
This will allow any `downstream users`_ of your project who aren't ready to upgrade to version 4 the ability to
continue using your project while deciding on an appropriate upgrade schedule.
If your downstream users do not specify ramsey/uuid as a dependency, and they use functionality specific to version
3, they may need to update their own Composer dependencies to use ramsey/uuid ``^3`` to avoid using version 4.
.. _upgrading.3-to-4.static-methods:
Uuid Static Methods
###################
All the static methods on the :php:class:`Uuid <Ramsey\\Uuid\\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 <Ramsey\\Uuid\\Rfc4122\\UuidInterface>`,
which implements the familiar interface :php:interface:`UuidInterface
<Ramsey\\Uuid\\UuidInterface>`.
All the static methods on the :php:class:`Uuid <Ramsey\\Uuid\\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 <Ramsey\\Uuid\\Rfc4122\\UuidInterface>`, which implements the familiar interface
:php:interface:`UuidInterface <Ramsey\\Uuid\\UuidInterface>`.
If your type hints are for :php:interface:`UuidInterface
<Ramsey\\Uuid\\UuidInterface>`, then you should not require any changes.
If your type hints are for :php:interface:`UuidInterface <Ramsey\\Uuid\\UuidInterface>`, then you should not require any
changes.
.. list-table:: Return types for Uuid static methods
:align: center
@@ -137,27 +117,21 @@ If your type hints are for :php:interface:`UuidInterface
- :php:class:`Uuid <Ramsey\\Uuid\\Uuid>`
- :php:class:`Rfc4122\\UuidV5 <Ramsey\\Uuid\\Rfc4122\\UuidV5>`
:php:meth:`Uuid::fromString() <Ramsey\\Uuid\\Uuid::fromString>`,
:php:meth:`Uuid::fromBytes() <Ramsey\\Uuid\\Uuid::fromBytes>`, and
:php:meth:`Uuid::fromInteger() <Ramsey\\Uuid\\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 <Ramsey\\Uuid\\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
<Ramsey\\Uuid\\Nonstandard\\Uuid>`. These return types implement
:php:interface:`UuidInterface <Ramsey\\Uuid\\UuidInterface>`. If using this as
a type hint, you shouldn't need to make any changes.
:php:meth:`Uuid::fromString() <Ramsey\\Uuid\\Uuid::fromString>`, :php:meth:`Uuid::fromBytes() <Ramsey\\Uuid\\Uuid::fromBytes>`,
and :php:meth:`Uuid::fromInteger() <Ramsey\\Uuid\\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 <Ramsey\\Uuid\\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
<Ramsey\\Uuid\\Nonstandard\\Uuid>`. These return types implement :php:interface:`UuidInterface <Ramsey\\Uuid\\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 <Ramsey\\Uuid\\UuidInterface>`
method return types have changed in version 4 and you will need to update your
code, if you use these methods.
The following :php:interface:`UuidInterface <Ramsey\\Uuid\\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
@@ -177,11 +151,10 @@ code, if you use these methods.
- ``mixed`` [#f1]_
- :php:class:`Type\\Integer <Ramsey\\Uuid\\Type\\Integer>`
In version 3, the following :php:class:`Uuid <Ramsey\\Uuid\\Uuid>` methods
return ``int``, ``string``, or Moontoast\\Math\\BigNumber, depending on the
environment. In version 4, they all return numeric ``string`` values for the
sake of consistency. These methods :ref:`are also deprecated
<upgrading.3-to-4.deprecations.uuid>` and will be removed in version 5.
In version 3, the following :php:class:`Uuid <Ramsey\\Uuid\\Uuid>` methods return ``int``, ``string``, or
Moontoast\\Math\\BigNumber, depending on the environment. In version 4, they all return numeric ``string`` values for
the sake of consistency. These methods :ref:`are also deprecated <upgrading.3-to-4.deprecations.uuid>` and will be
removed in version 5.
* ``getClockSeqHiAndReserved()``
* ``getClockSeqLow()``
@@ -194,7 +167,6 @@ sake of consistency. These methods :ref:`are also deprecated
* ``getTimeMid()``
* ``getTimestamp()``
.. _upgrading.3-to-4.deprecations:
Deprecations
@@ -205,9 +177,8 @@ Deprecations
UuidInterface
-------------
The following :php:interface:`UuidInterface <Ramsey\\Uuid\\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
The following :php:interface:`UuidInterface <Ramsey\\Uuid\\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
@@ -258,14 +229,12 @@ recommendations, though, since these methods will go away in version 5.
Uuid
----
:php:class:`Uuid <Ramsey\\Uuid\\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`
:php:class:`Uuid <Ramsey\\Uuid\\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 <Ramsey\\Uuid\\Uuid>` is being replaced by more-specific
concrete classes, such as:
:php:class:`Uuid <Ramsey\\Uuid\\Uuid>` is being replaced by more-specific concrete classes, such as:
* :php:class:`Rfc4122\\UuidV1 <Ramsey\\Uuid\\Rfc4122\\UuidV1>`
* :php:class:`Rfc4122\\UuidV3 <Ramsey\\Uuid\\Rfc4122\\UuidV3>`
@@ -273,11 +242,10 @@ will be ``final``. For more information, see :ref:`faq.final`
* :php:class:`Rfc4122\\UuidV5 <Ramsey\\Uuid\\Rfc4122\\UuidV5>`
* :php:class:`Nonstandard\\Uuid <Ramsey\\Uuid\\Nonstandard\\Uuid>`
However, the :php:class:`Uuid <Ramsey\\Uuid\\Uuid>` class isn't going away.
It will still hold common constants and static methods.
However, the :php:class:`Uuid <Ramsey\\Uuid\\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::UUID_TYPE_IDENTIFIER`` is deprecated. Use ``Uuid::UUID_TYPE_DCE_SECURITY`` instead.
* ``Uuid::VALID_PATTERN`` is deprecated. Use the following instead:
.. code-block:: php
@@ -288,9 +256,8 @@ will be ``final``. For more information, see :ref:`faq.final`
$genericPattern = (new GenericValidator())->getPattern();
$rfc4122Pattern = (new Rfc4122Validator())->getPattern();
The following :php:class:`Uuid <Ramsey\\Uuid\\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.
The following :php:class:`Uuid <Ramsey\\Uuid\\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()``
@@ -305,13 +272,10 @@ encouraged to update your code, since they will go away in version 5.
.. 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
<upgrading.3-to-4.deprecations.uuidinterface>`, combined with the
arbitrary-precision mathematics library of your choice (e.g., `brick/math`_,
`gmp`_, `bcmath`_, etc.).
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 <upgrading.3-to-4.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
@@ -320,19 +284,17 @@ encouraged to update your code, since they will go away in version 5.
$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.
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.
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
-------------
@@ -438,35 +400,31 @@ Provider\\NodeProviderInterface
Constructor Changes
###################
There are a handful of constructor changes that might affect your use of
ramsey/uuid, especially if you customize the library.
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 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
The first constructor parameter used to be ``array $fields`` and is now :php:interface:`Rfc4122\\FieldsInterface $fields
<Ramsey\\Uuid\\Rfc4122\\FieldsInterface>`.
``Converter\TimeConverterInterface $timeConverter`` is required as a new fourth
parameter.
``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.
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
``iterable<Ramsey\Uuid\Provider\NodeProviderInterface>`` as its constructor
parameter.
Provider\\Node\\FallbackNodeProvider now requires ``iterable<Ramsey\Uuid\Provider\NodeProviderInterface>`` as its
constructor parameter.
.. code-block::
@@ -485,23 +443,19 @@ parameter.
Provider\\Time\\FixedTimeProvider
---------------------------------
The constructor for Provider\\Time\\FixedTimeProvider no longer accepts an
array. It accepts :php:class:`Type\\Time <Ramsey\\Uuid\\Type\\Time>` instances.
The constructor for Provider\\Time\\FixedTimeProvider no longer accepts an array. It accepts
:php:class:`Type\\Time <Ramsey\\Uuid\\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() <Ramsey\\Uuid\\Rfc4122\\UuidInterface::getFields>`
method returns a :php:class:`Type\\Hexadecimal <Ramsey\\Uuid\\Type\\Hexadecimal>`
instance; you will need to construct an array if you wish to match the
return value of the deprecated ``getFieldsHex()`` method.
.. [#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() <Ramsey\\Uuid\\Rfc4122\\UuidInterface::getFields>` method returns a
:php:class:`Type\\Hexadecimal <Ramsey\\Uuid\\Type\\Hexadecimal>` instance; you will need to construct an array if
you wish to match the return value of the deprecated ``getFieldsHex()`` method.
.. _downstream users: https://en.wikipedia.org/wiki/Downstream_(software_development)
.. _version 6 UUIDs: http://gh.peabody.io/uuidv6/
+1 -1
View File
@@ -135,7 +135,7 @@ interface UuidFactoryInterface
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 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