Let’s say I have an enum like this:
enum Shippint: string
{
case Express = 'express';
case Standard = 'standard';
case Economy = 'cheap';
/** @return string[] */
public static function values(): array
{
return array_column(self::cases(), 'value');
}
}
and I have 2 arrays that I want to compare and do something similar to array_diff
$arr1 = [
Delivery::tryFrom('express')
Delivery::tryFrom('cheap')
];
$arra2 = [
Delivery::tryFrom('express')
Delivery::tryFrom('standard')
]
I can loop through and convert each enums array to an array of strings
$arrOfStrings1 = [];
$arrayOfStrings2 = [];
foreach($arr1 as $value) {
$arrOfStrings1[] = $value->value;
}
foreach($arr2 as $value) {
$arrayOfStrings2[] = $value->value;
}
if (array_diff($arrOfStrings1, $arrayOfStrings2)) {
echo 'arrays different';
} else {
echo 'same'
}
I can hide this inside the enums methods, but still, maybe there is some built-in PHP way to do it? Unfortunately, it’s impossible to add __toSting()
to enums otherwise it’ll be possible to do array_diff
as it automatically converts objects to strings. Thanks
2
Answers
You can use array_udiff:
I know that people will probably hate me for this answer, but still, I’m going to write it.
You can use
__toString()
method inside an enum, and let me tell you how.If you try to define a
__toString()
method inside your enum, you will get an error that looks similar to:The check for the existence of
__toString()
method happens during compile-time, but not during runtime. So all we need to do is to find a way to define this method during runtime, and that’s where the UOPZ extension comes into play.The UOPZ extension defines a
uopz_add_function()
function which you can use to achieve this, here’s an example:This code works perfectly fine. This extension is very powerful for these kinds of issues.
More information on the function here: https://www.php.net/manual/en/function.uopz-add-function.php