Path: g2news2.google.com!news3.google.com!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail From: Stefan+Use...@Froehlich.Priv.at (Stefan Froehlich) Newsgroups: de.comp.lang.php.misc Subject: Re: is_callable() und private Methoden Date: 14 Feb 2011 08:19:45 GMT Lines: 95 Message-ID: <1t4d58e2b4i41f4n3e9%sfroehli@Froehlich.Priv.at> References: <3t4d581648i611bn3e9%sfroehli@Froehlich.Priv.at> <4d58de36$0$32432$91cee783@newsreader04.highway.telekom.at> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Trace: individual.net w+yA4TWKPxzkiKZW/MFMSgeemqTN+kKviu6fF7hL62sb7ZvtY= X-Orig-Path: not-for-mail Cancel-Lock: sha1:vtKti4mKgF6UDSND0fTAU3uBNUI= X-Blattlinie: dieser Artikel repraesentiert meine persoenliche Meinung X-Medieninhaber: Stefan Froehlich X-Verleger: Stefan Froehlich X-Verlagsort: Wien User-Agent: tin/1.9.3-20080506 ("Dalintober") (UNIX) (Linux/2.6.28.7 (i686)) On Mon, 14 Feb 2011 08:47:58 Helmut Chang wrote: > > | public function __clone() { > > | if (count($this->items)> 0) { > > | $item = reset($this->items); > > | if (is_callable(array($item, '__clone'))) { > Und du kannst sicherstellen, dass alle Elemente von $this->items > denselben Typ haben? Weil du prüfst ja nur das erste Element. In der Collection schon, ja. Frueher habe ich einfach darauf vertraut. > > Dazu muss ich noch ergaenzen, dass alle Multitons, so auch die Klasse > > "Incoterm", auf einer gemeinsamen Basisklasse beruhen, in der __clone() > > als privat deklariert ist und bei Aufruf aus der eigenen Klasse heraus > > eine Exception wirft. > Za wos denn das? Weil derartige Objekte prinzipiell nicht clonebar sind/sein duerfen. Da moechte ich, dass mir das Programm um die Ohren fliegt, sollte es versehentlich doch einmal passieren. > Im Prinzip ist dir dein Programm um die Ohren geflogen, weil du versucht > hast, eine Collection zu clonen, die gar nicht clonebar ist, weil deren > Elemente nicht clonebar sind. Ah, nein: die Collection ist sehr wohl clonebar, nur muss sie auf die gleichen Objektinstanzen referenzieren, wie das Original. Bei anderen Objekten (die keine Multitons sind) ist das hingegen nicht der Fall. > > | echo phpversion(); > > | var_dump($item); > > | var_dump(is_callable(array($item, '__clone'))); > > ...kommt das erwartete, aber falsche Ergebnis: > > | 5.3.3-7 > > | object(Incoterm)#287 (3) {...} > > | bool(true) > > Wieso erwartest du dieses Ergebnis, wenns doch falsch ist? Und was genau > ist jetzt falsch? Weil's halt dem (unerwarteten) Verhalten des Programms entspricht. > > Und nun? Der einzige Unterschied ist: der Echtfall laeuft > > ueber den Apache, der Trivialfall ueber CLI. > ...najo, nicht ganz. Der Kontext ist ein anderer... Und das macht bei PHP > oft etwas aus ;) Klar - die Schwierigkeit lag in diesem Fall darin, das Original in seiner Komplexitaet so weit zu reduzieren, dass ich den Code in gleichem Kontext ueberhaupt via CLI aufrufen konnte. Und siehe da - der Fehlerteufel ist inzwischen gefunden. Es gab frueher einmal neben der privaten __clone()-Implementierung eine ebensolche __call()-Implementierung (die gleichermassen eine Exception wirft und von Klassen, die __call() tatsaechlich benoetigen explizit ueberschrieben werden muss). Seit dem PHP-Update vorige Woche meckert PHP aber "private __call()" als unzulaessig an, weshalb ich die Signatur auf "public __call()" geaendert habe. Nun liest sich das Trivialbeispiel also so: | abstract class A { | private function __clone() { throw new Exception('failed'); } | public function __call($method, Array $parameters) { throw new Exception('failed'); } | } | | class B extends A { } | | $b = new B(); | var_dump($b); | var_dump(is_callable(array($b, '__clone'))); ...und (was mir nicht bewusst war) __call() ersetzt nicht nur fehlende Methoden, sondern auch solche mit unzureichenden Zugriffsrechten. Ist in dem Fall halt ein bisserl unpraktisch... Da __call() im Gegensatz zu __get() und __set() bei Abwesenheit aber nicht automatisch von PHP mit Inhalt befuellt wird, kann ich (im Gegensatz zu den beiden anderen) zum Glueck aber auch ganz gut darauf verzichten. Servus, Stefan -- http://kontaktinser.at/ - die kostenlose Kontaktboerse fuer Oesterreich Offizieller Erstbesucher(TM) von mmeike Stefan - das Gefühl zu schwanken! (Sloganizer)