2009-06-03 5 views
2

En PHP, il est possible de spécifier des types d'arguments bien qu'ils l'appellent type hinting.Implémenter l'interface PHP de sorte que l'instance d'objet puisse être passée en argument de type tableau?

Je mettre en œuvre une interface où l'une des fonctions spécifie un tableau comme le type d'argument:

function myFunction(array $argument){ 
} 

J'aimerais définir une classe, une instance qui peut être utilisé comme argument pour cette fonction. En d'autres termes, cela étendrait ArrayObject ou implémenterait ArrayAccess ou quelque chose du genre.

est-il intégré dans l'interface ou classe abstraite qui fonctionnera pour cela? (ArrayObject ne fonctionne pas)

+0

Pourquoi n'ArrayObject pas de travail pour cela? – Fortega

+0

Je pense que vous devez soit changer l'indice de type OU simplement fournir des tableaux à la fonction. array est un type de données primitif et ne peut pas être hérité. – PatrikAkerstrand

+0

Les tableaux ne sont pas des objets, dans la mesure où vous devez utiliser soit le tableau xor ArrayObject. – stefs

Répondre

2

Il n'y a pas, mais je vous suggère deux alternatives:

  1. Retirez le spécificateur tableau et contrôleront plutôt au sein de la fonction à l'aide is_array et instanceof ArrayObject
  2. Utilisation (array) $ ArrayObject lors de l'appel de la routine ou dans le cadre de 1. ci-dessus.

Exemple soulmerge :-)

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

myFunction((array)$a); 

sorties

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

Notez que la deuxième option va convertir votre objet en un tableau mappant les noms des membres de l'objet à leurs valeurs, il ne vous fera pas utiliser les fonctions ArrayObject! – soulmerge

+0

Étant donné que l'interface n'est pas définie par moi, je n'ai pas la possibilité de supprimer l'indicateur de type. Je pense que l'option 2 servira mieux mon but que je veux avoir plus de contrôle sur les clés et les valeurs que je reçois de l'utilisation d'un tableau régulier. Je vais donc utiliser mon propre objet et le projeter dans un tableau quand je le passe à la fonction. –

+0

Remarque $ a [] = et $ a-> append() sont équivalents lorsque ArrayObject implémente arrayaccess. À un certain point, php.net documentera leurs bibliothèques. –

3

Ce n'est pas possible. array() n'est pas un objet de n'importe quelle classe. Par conséquent, il ne peut pas implémenter une interface (voir here). Vous ne pouvez donc pas utiliser un objet et un tableau de manière interchangeable. La solution dépend fortement de ce que vous souhaitez réaliser.

Pourquoi changez-vous pas la signature de la fonction pour permettre seulement ArrayObject s, ArrayIterator s, ArrayAccess s, IteratorAggregate s, Iterator s ou Traversable s (en fonction de ce que vous voulez faire à l'intérieur de la fonction)?

Si vous devez vous fier aux capacités d'interaction de l'objet transmis, vous devez utiliser Traversable comme indicateur de type. Cela garantira que l'objet peut être utilisé avec foreach(). Si vous avez besoin d'un accès par clé de type tableau à l'objet (par exemple, $test['test']), vous devez utiliser ArrayAccess comme indicateur de type. Mais si vous avez besoin que l'objet transmis soit d'un type personnalisé spécifique, utilisez le type personnalisé comme indice de type. Une autre option serait de ne pas utiliser du tout d'indice de type et de déterminer le type de l'argument passé dans le corps de la fonction et traiter l'argument en conséquence (ou lancer un InvalidArgumentException ou quelque chose comme ça).

if (is_array($arg)) { ... } 
else if ($arg instanceof Traversable) { ... } 
else if ($arg instanceof ArrayAccess) { ... } 
else { 
    throw new InvalidArgumentException('...'); 
} 
0

Non, ce n'est pas possible car array est un type primitif en PHP. Une instance d'une classe est un objet, et la comparaison interne à PHP s'arrête déjà à ce point (les interfaces et autres ne sont pas vérifiés).

Vous pouvez créer un tableau de votre objet:

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