2010-03-29 11 views

Répondre

4

En PHP, vous ne pouvez pas appeler une méthode arbitraire sur un objet comme new Foo()->someMethod();

fraîchement créé Désolé, mais c'est comme ça.

Mais vous pourriez construire un travail autour comme ceci:

<?php 
class CustomConstructor 
{ 
    public static function customConstruct($methodName) 
    { 
    $obj = new static; //only available in PHP 5.3 or later 
    call_user_method($methodName, $obj); 
    return $obj; 
    } 
} 

Extend CustomContructor comme ceci:

class YourClass extends CustomConstructor 
{ 
    public function someCoolMethod() 
    { 
    //cool stuff 
    } 
} 

Et les instancier comme ceci:

$foo = YourClass::customConstruct('someCoolMethod'); 

Je ne l'ai pas testé mais cela ou quelque chose comme ça devrait fonctionner.

Correction: Cela ne fonctionnera que dans PHP 5.3 et plus tard, car la liaison statique tardive est nécessaire.

+0

Voir la section du manuel pour call_user_method pour plus à ce sujet. – selfawaresoup

+0

PHP 6 ne l'aura pas non plus? – xdevel2000

+0

Je ne sais pas si ce problème sera corrigé dans PHP6. De toute façon, il reste encore longtemps avant que 6 ne sorte. – selfawaresoup

-1

J'ai essayé et a réussi -

<?php 

$obj = new test("testFunc"); 

class test{ 
    function __construct($funcName){ 
     if(method_exists($this, $funcName)){ 
      self::$funcName(); 
     } 
    } 

    function testFunc(){ 
     echo "blah"; 
     return $this; 
    } 
} 

?> 
+0

pourquoi un vote négatif ?? soin d'expliquer s'il vous plaît? – pinaki

+0

Cela ne parvient pas à atteindre la chaîne-capacité que le demandeur avait l'intention de traverser la question. Votre implémentation requiert également que les paramètres de fonctions du constructeur soient utilisés explicitement pour appeler la fonction chaînée, ce qui n'est pas ce que le constructeur devrait faire. – teynon

14

A partir de PHP 5.4, vous pouvez faire

(new Foo)->bar(); 

Avant cela, il est impossible.Voir

Mais vous avez des quelques alternatives

solution Incroyablement laide je ne peux pas expliquer:

end($_ = array(new C))->foo(); 

Pointless linéariser/désérialiser juste pour être en mesure de la chaîne

unserialize(serialize(new C))->foo(); 

De même approche inutile utilisant la réflexion

call_user_func(array(new ReflectionClass('Utils'), 'C'))->foo(); 

approche un peu plus sain d'esprit en utilisant des fonctions comme usine:

// global function 
function Factory($klass) { return new $klass; } 
Factory('C')->foo() 

// Lambda PHP < 5.3 
$Factory = create_function('$klass', 'return new $klass;'); 
$Factory('C')->foo(); 

// Lambda PHP > 5.3 
$Factory = function($klass) { return new $klass }; 
$Factory('C')->foo(); 

Approche la plus saine utilisant Factory Method Pattern Solution:

class C { public static function create() { return new C; } } 
C::create()->foo(); 
1

Vous ne devriez pas être en mesure d'exécuter du code comme

new C()->foo();

dans d'autres langues, du moins pas aussi longtemps que cette langue suit avec précision la logique. L'objet n'est pas seulement créé en utilisant C(), mais avec le plein new C(). Par conséquent, vous devriez hypothétiquement être en mesure d'exécuter ce code si vous incluez une autre paire de parenthèses: (new C())->foo();

(attention:. Je ne l'ai pas testé ce qui précède, je dis juste qu'il devrait travailler hypothétiquement)

La plupart des langues (que j'ai rencontrées) traitent de cette situation de la même manière. C, C#, Java, Delphi ...

+0

malheureusement, cela ne fonctionne pas. php n'est pas c, C#, java, delphi etc. – user187291

+0

Hm, impair. J'aurais vraiment juré que j'avais déjà fait ce genre de chose en PHP auparavant. Tant pis! – JMTyler

+0

Pas vrai. Sur la base d'une table de priorité d'opérateur, un nouveau() est d'abord exécuté. D'autres langues fonctionnent de la même manière. Donc en Java, C#, etc si vous faites du nouveau C(). Foo() tout va bien! – xdevel2000

8

Depuis PHP 5.4, vous pouvez le faire: (new Foo())->someMethod();

Questions connexes