In some of my setters, I pass an array of objects. I would like to ensure that it only contains instances from a given class. Reading the doc, here is what I do :
class Foo
{
public function __construct()
{
}
}
class ErrorFoo
{
public function __construct()
{
}
}
$arrayObject = Array();
array_push($arrayObject, new Foo());
array_push($arrayObject, new Foo());
array_push($arrayObject, new ErrorFoo());
$error = false;
foreach ($arrayObject as $obj)
{
if ( $obj instanceof Foo )
{
echo "ok" . '<br>';
}
else
{
echo "error" . '<br>';
$error = true;
}
}
Do you know a simpler way than iterate through the array like this?
Create a class that extends ArrayObject, redefine its offsetSet() method and do the check in it. Use this class instead of a plain array to store the objects of type Foo.
class ArrayOfFoo extends ArrayObject
{
public function offsetSet($index, $newval)
{
// Verify the input
if (! $newval instanceof Foo) {
// do something
throw new InvalidArgumentException('Invalid type');
}
// Let the parent class do its job
parent::offsetSet($index, $newval);
}
}
This code throws an exception when the object of type ErrorFoo is added to the array:
$ArrayObject = new ArrayOfFoo();
$ArrayObject[] = new Foo();
$ArrayObject[] = new Foo();
// This throws an exception
$ArrayObject[] = new ErrorFoo();
An instance of the ArrayObject class can be used in the same way an array is used (setting, unsetting and fetching values from it). Its method getArrayCopy() can be used to get an array that can be passed as argument to functions that expect arrays (explode(), f.e.)
One alternative is using variadics to enforce types. It's an array inside the function, but not outside:
function doSomething(MyObject ...$array)
{
// $array contains only MyObject instances in it
}
doSomething(new MyObject, new MyObject, new MyObject);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With