Is there a way in PHP for me to specify that an array will consist only of certain types of objects?
For example suppose I have a Car objec开发者_Python百科t and I want my array to consist only of Cars. Is there some syntax that allows me to do this?
No. PHP does not have any strong typing.
The only way I can think of enforcing this would be to have a CarArray class that has getters,setters,etc.. functions that enforce the parameters to be of class Car.
Out of the box not but you could implement ArrayObject on your Car
class and override the append method of ArrayObject to only accept instances of CarPart
for example. That way you have an object that behaves as an array and as long as you add items with append it will only accept items of the CarPart
type.
You could implement a basic list class like the following, and only allow items to be added to the list using the addItem
function in your code. You could probably add alot of functionality around it. And then carry out whatever array specific operations on the $list->items
array you want using standard php array functionality.
class list()
{
function __construct($type)
{
$this->type = $type;
$this->items = array();
}
public function addItem($item)
{
if( get_class($item) == $type )
{
$this->items[] = $item;
}
else
{
return false;
}
}
}
Here is a simple solution using an array filter to remove any objects that aren't cars.
// Return TRUE to keep the value, FALSE otherwise
function car_filter($val) {
return ($val instanceof Car);
}
$cars = array( ... ); // an array of cars
// Apply the filter
$cars = array_filter($cars, "car_filter")
Just wrap whatever you want to store the cars in with a typehinted API:
class Cars implements IteratorAggregate
{
protected $storage;
public function __construct(SplObjectStorage $storage)
{
$this->storage = $storage;
}
public function addCar(Car $car)
{
$this->storage->attach($car);
}
public function removeCar(Car $car)
{
$this->storage->detach($car);
}
public function getIterator()
{
return clone $this->storage;
}
// …
}
Whether you use SplObjectStorage
or ArrayObject
or a plain array
for $storage
is up to you. It's the wrapper that's taking care of that nothing but Cars
get into it.
Full working example on codepad
If you prefer to use array notation, e.g. square brackets, implement ArrayAccess
.
class Cars implements IteratorAggregate, ArrayAccess
{
// …
public function offsetSet($offset, $value)
{
if($value instanceof Car) {
$this->storage[$offset] = $value;
} else {
throw …
}
}
}
Full working example at codepad
精彩评论