Frequently Asked Questions (FAQs)

How do I fix “rhumsaa/uuid is abandoned” messages?

When installing your project’s dependencies using Composer, you might see the following message:

Package rhumsaa/uuid is abandoned; you should avoid using it. Use
ramsey/uuid instead.

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.

Why does ramsey/uuid use final?

You might notice that many of the concrete classes returned in ramsey/uuid are marked as final. There are specific reasons for this choice, and I will offer a few solutions for those looking to extend or mock the classes for testing purposes.

But Why?

via GIPHY

First, let’s take a look at why ramsey/uuid uses final.

UUIDs are defined by a set of rules — published as RFC 4122 — and those rules shouldn’t change. If they do, then it’s no longer a UUID — at least not as defined by RFC 4122.

As an example, let’s think about 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 UuidInterface or Rfc4122\UuidInterface.

So, if we’re working with an instance of a class that is marked final, we can guarantee that the rules for the creation of that object will not change, even if a third-party library passes us an instance of the same class.

This is the reason why ramsey/uuid specifies certain argument and return types that are marked final. Since these are final, ramsey/uuid is able to guarantee the type of data these value objects contain. Type\Integer should never contain any characters other than numeral digits, and Type\Hexadecimal should never contain any characters other than hexadecimal digits. If other libraries could extend these and return them from UUID instances, then ramsey/uuid cannot guarantee their values.

This is very similar to using strict types with int, float, or bool. These types cannot change, so think of final classes in ramsey/uuid as types that cannot change.

Overriding Behavior

You may override the behavior of ramsey/uuid as much as you want. Despite the use of final, the library is very flexible. Take a look at the myriad opportunities to change how the library works:

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 UuidV1 nor a UuidV4 nor an Integer nor a Time, etc. will ever change because of downstream code.

UUIDs have specific rules that make them practically unique. ramsey/uuid ensures that other code cannot change this expectation while allowing your code and third-party libraries to change how UUIDs are generated and to return different types of UUIDs not specified by RFC 4122.

Testing With UUIDs

Sometimes, the use of final can throw a wrench in our ability to write tests, but it doesn’t have to be that way. To learn a few techniques for using ramsey/uuid instances in your tests, take a look at Testing With UUIDs.