2013-02-11 9 views
10

Ist es möglich, ein Array oder ein Objekt zu ermöglichen, die Arrayaccess implementiert?PHP Type Hinting ermöglichen Array oder Arrayaccess

Zum Beispiel:

class Config implements ArrayAccess { 
    ... 
} 

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

Ich möchte in der Lage sein, entweder in einem Array oder Arrayaccess passieren.

Gibt es eine saubere Art und Weise diese andere zu tun, als manuell den Parametertyp überprüft?

Antwort

10

Nein, es gibt keine „saubere“ Art und Weise, es zu tun.

Der Typ array ist ein primitiver Typ. Objekte, die die Schnittstelle ArrayAccess implementieren, basieren auf Klassen, die auch als zusammengesetzter Typ bezeichnet werden. Es gibt keinen Typhinweis, der beides umfasst.

Da Sie die ArrayAccess als Array verwenden Sie es nur werfen könnte. Zum Beispiel:

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

Wenn das keine Option ist (wollen Sie das Config Objekt verwenden, wie es ist), dann entfernen Sie einfach den Typ-Hinweis und überprüfen Sie, dass es entweder ein Array oder ein ArrayAccess ist. Ich weiß, dass du das vermeiden wolltest, aber es ist keine große Sache. Es sind nur ein paar Zeilen und, wenn alles gesagt und getan ist, belanglos.

+0

Nicht die Antwort, auf die ich gehofft habe, aber das Gießen zu einem Array ist eigentlich eine nette Idee. Danke – Supericy

+0

Dies ist eine schlechte Praxis, sollte ein Client nicht tun, was die Bibliothek tun kann. – danidacar

+0

Es ist egal, ob ArrayAccess implementiert ist oder nicht. AFAIK das einzige, was die Casting-Funktionalität ändern wird, ist das Unterklassen der ArrayObject-Klasse. Hoffentlich macht https://wiki.php.net/rfc/union_types es eines Tages (nicht im Zusammenhang mit Casting offensichtlich, aber auf die OP-Frage);) –

-3

Nun PHP unterstützt für Array/Objekt Hinting Typ. Also Array sollte gut funktionieren. Das Übergeben eines ArrayAccess-Objekts an die Methode, die nur für den Array-Typ zulässig ist, kann jedoch zu Fehlern führen. ArrayAccess wird hauptsächlich zum Zwecke des Iterierens des ArrayAccess-Objekts in einem arrayähnlichen Array wie foreach verwendet.

-1

Sie haben eine echte Lösung in PHP 7.1.

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

Die iterable pseudo-Typ ist, was Sie wollen. Jedes Array oder Traversable-Typ (dies ist die Basisschnittstelle für Iteratoren) wird diese Prüfung bestehen.

Nun, dies für jedermann klar zu machen, die in der Tiefe will bekommen super, ja, es werden Ränder Fällen. Sie sollten über diese Randfälle nachdenken und sie selbst lösen. Wenn Sie jedoch sicherstellen möchten, dass jemand ein traversierbares Element eingibt, auf das nicht über einen Schlüssel zugegriffen werden kann, können Sie dies tun.

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

nun unabhängig davon, was sie in der Art-Hinweis übergeben, wird ein Array, aber diese die Vorteile der Verwendung eines Generators zur Speicherreduzierung entfernen können. Es sollte offensichtlich sein, aber anscheinend ist es nicht, also hier ist es. Sie, der Programmierer, sind dafür verantwortlich, Ihre speziellen Anwendungsfälle für den Code zu ermitteln und wie Sie ihn verwenden wollen und welchen geeigneten Anwendungsfall der Code hat.

Da dies immer noch nicht klar genug ist, nehmen wir an, Sie versuchen, etwas einzugeben, das typhinweisbar ist und erwartet, dass eine bestimmte Methode oder Variable existiert, dann machen Sie schlechtes Programmieren. Sie sollten einen Vertrag implementieren, der den gesuchten Rückgabetyp enthält, und diesen anstelle eines generischen Typs übergeben. Wenn Sie nur etwas Generisches wie Schleifen machen wollen, sind das iterierbare Typen. Der Hinweis ist im Namen: Iterate.

+0

Das ist nicht ganz richtig beantworten. Durchsuchbare Iterfaces implizieren nicht, dass das angegebene Objekt ArrayAccess implementiert (z. B. Zugriff auf Elemente durch einen Schlüssel). Sie müssen in Ihrem Code weiterhin eine zusätzliche Typüberprüfung durchführen. – mancze

+0

Die Frage ist: 'Erlaube ein Array oder ein Objekt, das ArrayAccess implementiert' Ja, dies wird dies erlauben. Und ja, es wird Ihnen erlauben, über einen Schlüssel für jeden iterierbaren Pseudo-Typ darauf zuzugreifen. Auf jedes Mitglied des Iterators kann über zugegriffen werden. Schlüssel. Es ist in der Definition: http://php.net/manual/en/class.iterator.php Hinweis: Es ist der eine 'Schlüssel' genannt. –

+0

1) Wenn Sie Frage auf diese Weise interpretieren, dann passt auch keine Typdeklaration als Antwort (sie erlaubt 'array' oder' ArrayAccess'), ist aber sicherlich nicht die beabsichtigte Antwort, weil sie mehr als das erlaubt. Gleiches gilt für "iterierbar". 2) Vorsicht - "iterabler" Typhinweis bedeutet "Array" oder "Traversable", nicht "Iterator". Zum Beispiel ist 'Generator'' Traversable', aber die Werte sind nicht über die Taste erreichbar. Und wenn Sie sich das Beispiel ansehen, ist es beabsichtigt, eine Typdeklaration für Configs anzugeben, bei denen der Zugriff über den Schlüssel wahrscheinlich die erwartete Fähigkeit des gegebenen Parameters ist. – mancze

Verwandte Themen