tags:

views:

92

answers:

2

In recent updates to PHP, they added in various interfaces to allow an object to be treated as an array, such as ArrayAccess, Iterator, Countable, etc.

My question is, would it then make sense that the following should work:

function useArray(array $array)
{
    print_r($array);
}

useArray(new ArrayObj(array(1,2,3,4,5));

As of right now, PHP throws a type-hinting error, as $array is not technically an array. However, it implements all the interfaces that makes it basically identical to an array.

echo $array[0]; // 1
$array[0] = 2;
echo $array[0]; // 2

Logically, the object should be able to be used anywhere an array can be used, as it implements the same interface as an array.

Am I confused in my logic, or does it makes sense that if an object implements the same interface as an array, it should be able to be used in all the same places?

A: 

Your type hinting is stating its of type "array" but your passing in an "ArrayObj"

function useArray(array $array)
...
useArray(new ArrayObj

So yeah its going to complain.

Am I confused in my logic, or does it makes sense that if an object implements the same interface as an array, it should be able to be used in all the same places?

If the object implements the same interface as another class, yeah you can use them interchangeably, but it still valid for the compiler to complain about your type hinting, since its not of the same type.

Just because two objects implement the same interface does not mean they are of the same type.

Mr-sk
+4  A: 

Am I confused in my logic, or does it makes sense that if an object implements the same interface as an array, it should be able to be used in all the same places?

An array is a special PHP variable type - not an object - as such it doesn't implement any interfaces. ArrayObject is a full-fledged object that implements numerous interfaces (Countable, ArrayAccess, etc.) and enables an object to act like an array in certain cases (like in a foreach loop). So while they don't implement the same interfaces they sometimes behave the same.

The ideal solution would be for PHP to support multiple function signatures:

function useArray(array $array) { }
function useArray(ArrayObject $array) { }

But until we get that (if we ever get that) you'll just have to check variable types outside the function definition:

function useArray($array) {
 if (is_array($array) || $array instanceof ArrayObject) {
   // Do some stuff
 } else {
   throw new Exception('I require an array or an array-like structure!');
 }
}

Or try to do array-type stuff with the $array argument and handle any warnings/errors that useArray might generate.

pygorex1
I think you should emphasise *behave*. It's really the keyword in my opinion. Type Hints hint for types, not behaviors.
Gordon
@pygorex <pedant>You should test for exceptional states and return early or throw exceptions rather than test for acceptable states, so you don't have the meat of your function indented five levels.</pedant>
bluej100