2013-02-11 17 views
10

È possibile consentire una matrice o un oggetto che implementa ArrayAccess?Tipo PHP hinting per consentire Array o ArrayAccess

Ad esempio:

class Config implements ArrayAccess { 
    ... 
} 

class I_Use_A_Config 
{ 
    public function __construct(Array $test) 
    ... 
} 

voglio essere in grado di passare in entrambi una matrice o ArrayAccess.

C'è un modo pulito per fare questo oltre a controllare manualmente il tipo di parametro?

risposta

10

No, non esiste un modo "pulito" per farlo.

Il tipo array è un tipo primitivo. Gli oggetti che implementano l'interfaccia ArrayAccess si basano su classi, note anche come tipo composito. Non esiste un suggerimento tipo che comprenda entrambi.

Poiché si utilizza ArrayAccess come array, è possibile eseguire il cast. Per esempio:

$config = new Config; 
$lol = new I_Use_A_Config((array) $config); 

Se questo non è un'opzione (che si desidera utilizzare l'oggetto Config come è) allora è sufficiente rimuovere il tipo-suggerimento e verificare che sia o un array o un ArrayAccess. So che volevi evitarlo, ma non è un grosso problema. Sono solo poche righe e, quando tutto è detto e fatto, irrilevanti.

+0

Non è la risposta che speravo ma il casting su un array è davvero una buona idea. Grazie – Supericy

+0

Questa è una cattiva pratica, un client non dovrebbe fare ciò che la libreria può fare. – danidacar

+0

La trasmissione di un oggetto all'array non interessa se ArrayAccess è implementato o meno. AFAIK l'unica cosa che cambierà la funzionalità di lancio è la sottoclasse della classe ArrayObject. Speriamo che https://wiki.php.net/rfc/union_types lo faccia un giorno (non correlato al casting ovviamente, ma alla domanda dell'OP);) –

-3

Pozzetto php Tipo suggerimento per Array/Oggetto. Quindi Array dovrebbe funzionare bene. Tuttavia, il passaggio di un oggetto ArrayAccess sul metodo consentito solo per il tipo di matrice può generare errori. ArrayAccess viene utilizzato principalmente allo scopo di iterare l'oggetto ArrayAccess in modo simile a un array come in foreach.

-1

Hanno una soluzione reale in PHP 7.1.

http://php.net/manual/en/migration71.new-features.php#migration71.new-features.iterable-pseudo-type

Il iterabile pseudo-tipo è quello che volete. Qualsiasi array o tipo Traversable, (che è l'interfaccia di base per Iterators) passerà questo controllo.

Ora, per rendere questo chiaro per tutti coloro che vogliono ottenere un super approfondimento, sì, ci saranno casi limite. Dovresti pensare a questi casi limite e risolverli da soli, ma se vuoi assicurarti che se qualcuno passa in un elemento attraversabile a cui non è possibile accedere tramite una chiave, puoi farlo.

http://php.net/manual/en/function.iterator-to-array.php

Ora, indipendentemente da quello che passano nel tipo-suggerimento, si avrà un array, ma questo può rimuovere i vantaggi di utilizzare un generatore per la riduzione della memoria. Dovrebbe essere ovvio, ma a quanto pare non lo è, quindi eccolo qui. Tu, il programmatore, sei responsabile di capire i tuoi casi d'uso specifici per il codice e come stai pensando di usarlo e qual è il caso d'uso appropriato per il codice.

Poiché ciò non è ancora abbastanza chiaro, supponiamo che stiate cercando di passare qualcosa che è tipo-hintable e che si aspetta un particolare metodo o variabile per esistere, quindi si sta facendo una cattiva programmazione. Dovresti implementare un contratto che ha il tipo di reso che stai cercando e lo passa in un tipo piuttosto che generico. Se vuoi fare solo qualcosa di generico come il loop, è a questo che servono i tipi iterabili. Il suggerimento è nel nome: Iterate.

+0

Non è una risposta completamente corretta. L'iterazione attraversabile non implica che l'oggetto dato implementa ArrayAccess (ad esempio, gli oggetti possono essere accessibili da una chiave). Dovrai comunque eseguire ulteriori controlli di tipo nel codice. – mancze

+0

La domanda è: 'consentire una matrice o un oggetto che implementa ArrayAccess' Sì, questo lo permetterà. E sì, ti permetterà di accedervi tramite una chiave per ogni pseudo-tipo iterabile. È possibile accedere a qualsiasi membro di Iterator tramite. chiave. È nella definizione: http://php.net/manual/en/class.iterator.php Suggerimento: è quello chiamato "chiave". –

+0

1) Se interpreti la domanda in questo modo, nessuna dichiarazione di tipo si adatta anche come risposta (consente 'array' o' ArrayAccess') ma sicuramente non è la risposta desiderata perché consente più di questo. Lo stesso vale per "iterable". 2) Attenzione: il suggerimento "iterable" significa "array" o "Traversable", non "Iterator". Ad esempio 'Generator' è' Traversable' ma i valori non sono accessibili tramite chiave. E se si guarda l'esempio, l'intenzione è di specificare la dichiarazione di tipo per le configurazioni in cui l'accesso tramite chiave è probabilmente l'abilità prevista del parametro specificato. – mancze

Problemi correlati