2

In PHP it is possible to specify argument types although they call it type hinting.

I am implementing an interface where one of the functions specifies an array as the argument type:

function myFunction(array $argument){
}

I'd like to define a class, an instance of which can be used as the argument for this function. In other words it would extend ArrayObject or implement ArrayAccess or something along those lines.

Is there a built in interface or abstract class that will work for this? (ArrayObject doesn't)

3
  • Why doesn't ArrayObject work for this? Commented Jun 3, 2009 at 11:40
  • I think you either have to change the type hint OR simply supply arrays to the function. array is a primitive datatype, and can't be inherited. Commented Jun 3, 2009 at 11:42
  • arrays are not objects, insofar you have to settle with either array xor ArrayObject. Commented Jun 3, 2009 at 11:52

3 Answers 3

3

This isn't possible. array() is not an object of any class. Hence, it can't implement any interface (see here). So you can't use an object and an array interchangeably. The solution strongly depends on what you'd like to achieve.

Why don't you change the function signature to allow only ArrayObjects, ArrayIterators, ArrayAccesss, IteratorAggregates, Iterators or Traversables (depending on what you'd like to do inside the function)?

If you have to rely on interation-capabilities of the passed object you should use Traversable as the type-hint. This will ensure that the object can be used with foreach(). If you need array-like key-access to the object (e.g. $test['test']) you should use ArrayAccess as the type-hint. But if you need the passed object to be of a specific custom type, use the custom type as the type-hint.

Another option would be to not use a type-hint at all and determine the type of the passed argument within the function body and process the argument accordingly (or throw an InvalidArgumentException or something like that).

if (is_array($arg)) { ... }
else if ($arg instanceof Traversable) { ... }
else if ($arg instanceof ArrayAccess) { ... }
else {
    throw new InvalidArgumentException('...');
}
Sign up to request clarification or add additional context in comments.

Comments

2

There isn't, but I'd suggest two alternatives:

  1. Remove the array specifier and rather check within the function using is_array and instanceof ArrayObject
  2. Use (array) $ArrayObject when calling the routine or as part of 1. above.

Example for soulmerge :-)

function myFunction(array $argument){
    echo var_export($argument,true);
}
$a = new ArrayObject();
$a[] = 'hello';
$a[] = 'and goodbye';

myFunction((array)$a);  

outputs

 array (
   0 => 'hello',
   1 => 'and goodbye',
 )

3 Comments

Note that the second option will convert your object into an array mapping the member names of the object to their values, it will not make you use of the ArrayObject functions!
Since the interface is not defined by me I don't have the option of dropping the type hint. I think option 2 will serve my purpose best as I want to have more control over the keys and values than I get from using a regular array. So I will use my own object and cast it to array when I pass it to the function.
Note $a[]= and $a->append() are equivalent as ArrayObject implements arrayaccess. At some point php.net will document their libraries.
0

No, this is not possible, as array is a primitive type in PHP. An instance of a class is an object, and the PHP-internal comparison already stops at this point (Interfaces and the like are not checked).

You could create an array out of your object:

$array = array();
foreach ($yourObject as $key => $value) {
    $array[$key] = $value;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.