Introduction
There may be times in your Laravel projects when you want to manually build Collections of data. This might be because you're pulling in data from an external source, such as an API, or because you're generating the data yourself.
Building Collections manually like this can sometimes lead to items of the wrong data type being added to the Collection. For example, you might want to add an integer to a Collection but accidentally add a string instead.
Of course, a good-quality test suite will likely catch these types of problems. But, unfortunately, these types of issues can sometimes slip through the cracks.
So it can be useful to check your Collections to ensure that they contain the correct data types before you start interacting with them.
This is where the ensure()
method comes in. In this Quickfire article, we're going to quickly look at how to use the ensure()
method to ensure that the items in a Collection are of the correct data type.
Using the ensure()
Method
The ensure()
method allows you to ensure that the items in a Collection are of a specific data type. If an item in the Collection is not of the specified data type, the method will throw an UnexpectedValueException
.
Let's take a look at some examples of how to use the ensure()
method.
Checking Primitives
You can use the ensure()
method to verify that all the items in a Collection are of these primitive types: string
, int
, float
, bool
, or array
.
For example, if we wanted to verify that a Collection only contains string
items, we could do so like this:
1$collection = collect(['Ash', 'Allen']);2 3$collection->ensure('string');
Similarly, if we wanted to verify that a Collection only contains int
items, we could do so like this:
1$collection = collect([1, 2, 3, 4, 5]);2 3$collection->ensure('int');
In the following example, the ensure
method will throw an UnexpectedValueException
because the Collection contains an int
item, but we're trying to ensure that it only contains string
items:
1// โ The `ensure` method will throw an exception!2 3$collection = collect([1, 2, 3, 4, 5]);4 5$collection->ensure('string');
The message of the exception thrown will be:
1Collection should only include 'string' items, but 'int' found.
Checking Objects and Interfaces
As well as being able to verify whether a Collection only contains primitive types, you can also use the ensure()
method to verify that a Collection only contains objects of a specific class or interface.
For example, if we wanted to verify that a Collection only contains items of the App\Models\User
class, we could do so like this:
1use App\Models\User;2 3$collection = collect([4 new User('Ash'),5 new User('Allen'),6]);7 8$collection->ensure(User::class);
In the following example, the ensure
method will throw an UnexpectedValueException
because the Collection contains a Post
object, but we're trying to ensure that it only contains User
objects:
1// โ The `ensure` method will throw an exception! 2 3use App\Models\User; 4use App\Models\Post; 5 6$collection = collect([ 7 new User('Ash'), 8 new User('Allen'), 9 new Post(),10]);11 12$collection->ensure(User::class);
We can also use the ensure
method to verify that a Collection only contains items that implement a specific interface. For example, if we wanted to verify that a Collection only contains items that implement the Illuminate\Auth\Authenticatable
interface, we could do so like this:
1use App\Models\User;2use Illuminate\Auth\Authenticatable;3 4$collection = collect([5 new User('Ash'),6 new User('Allen'),7]);8 9$collection->ensure(Authenticatable::class);
In the above example, we're assuming that the App\Models\User
class implements the Illuminate\Auth\Authenticatable
interface.
Checking Multiple Types
There may also be times when you want to verify that a Collection contains items of multiple types. You can do this by passing an array of types to the ensure()
method.
As long as each item matches at least one of the types in the array, the ensure
method will not throw an exception.
For example, if we wanted to verify that a Collection contains items that are either int
or float
, we could do so like this:
1$collection = collect([1, 2, 3.5, 4, 5]);2 3$collection->ensure(['int', 'float']);
Similarly, if we wanted to verify that a Collection contains items that are instances of either App\Models\User
or App\Models\Post
, we could do so like this:
1use App\Models\User; 2use App\Models\Post; 3 4$collection = collect([ 5 new User('Ash'), 6 new User('Allen'), 7 new Post(), 8]); 9 10$collection->ensure([User::class, Post::class]);
If you're using the ensure
method to check that the Collection contains items of multiple classes, this might be an indication that you should make use of interfaces. So you might want to consider refactoring your classes so they both implement the same interface. This would allow you to use the ensure
method to check that the Collection contains items that implement the interface, rather than checking for both of the specific classes.
However, this isn't always possible or needed. It's all dependent on the specific use case.
Using the above approach (passing multiple types to the ensure
method) can be really handy if you don't have ownership of the classes in the Collection. For example, the classes might belong to a third-party package, and so it might be difficult (or impossible) to change them to implement the same interface.
In this case, the ensure
method can be a useful way to ensure that the Collection contains the correct types of items.
Things to Note
It's important to note that the ensure
method will only verify the items that are already in the Collection. If you add any more items to the Collection after calling the ensure
method, it won't stop you from adding the wrong type of item to the Collection.
For this reason, if you're going to run the ensure
method, you may want to consider running it only once you've finished adding items to the Collection.
Additionally, it's best to use the ensure
method as a last resort fallback to catch any errors that might have slipped through the cracks. In a perfect world, you never want this method to throw an exception.
So, while the ensure
method can be a useful tool, it's not a replacement for a good quality code and a thorough test suite.
Making proper use of type hinting, return types, and strict type-checking can help to avoid adding the incorrect data to the Collection in the first place.
Conclusion
Hopefully, this article has given you a quick insight into the ensure()
method.
You might also be interested in checking out my 220+ page ebook "Battle Ready Laravel" which covers similar topics in more depth.
Or, you might want to check out my other 440+ ebook "Consuming APIs in Laravel" which teaches you how to use Laravel to consume APIs from other services.
If you're interested in getting updated each time I publish a new post, feel free to sign up for my newsletter below.
Keep on building awesome stuff! ๐