2009-09-09 2 views
89

Was ich möchte, ist, etwas zu tun wie folgt aus:Können Sie in PHP ein Objekt instanziieren und eine Methode in derselben Zeile aufrufen?

$method_result = new Obj()->method(); 

Statt zu tun zu haben:

$obj = new Obj(); 
$method_result = $obj->method(); 

Das Ergebnis eigentlich nicht zu mir in meinem speziellen Fall egal. Aber gibt es einen Weg, dies zu tun?

+3

Übrigens, wenn Sie nicht 5.4 verwenden (was Sie wahrscheinlich nicht sind), können Sie eine Hilfsfunktion definieren, die ein Objekt einfach an kettenstopfen zurückgibt ... Funktion mit ($ obj) {return $ obj; } (wählte den Trick aus Laravel: P) .. dann können Sie tun mit (new Obj) -> Methode() – kapv89

+0

So einfach wie '(neues Objekt()) -> doSomething()'. –

Antwort

117

Die von Ihnen gewünschte Funktion ist ab PHP 5.4 verfügbar. Hier ist die Liste der neuen Funktionen in PHP 5.4:

http://docs.php.net/manual/en/migration54.new-features.php

Und der relevante Teil der neuen Features-Liste:

Klasse Mitglied Zugriff auf Instanziierung wurde hinzugefügt, z.B. (neues Foo) -> bar().

+7

Beachten Sie, dass dies auch bedeutet, Sie können tun '(neue Foo) -> Eigenschaft ', wenn Sie wollten. – dave1010

+0

Dies ist eine wirklich nette Funktion von PHP 5.4, schade, dass es nicht auf 5.3.27 verfügbar ist (auf dem ich bin). – crmpicco

+1

Beachten Sie, dass Sie Eigenschaften auf diese Weise noch nicht zuweisen können. (neu Foo) -> Eigenschaft = 'Eigenschaft'; – CMCDragonkai

14

Nein, das ist nicht möglich.
Sie müssen die Instanz einer Variablen zuweisen, bevor Sie eine ihrer Methoden aufrufen können.

Wenn Sie wirklich diese wan't tun Sie eine Fabrik als ropstah schlägt verwenden:

class ObjFactory{ 
    public static function newObj(){ 
     return new Obj(); 
    } 
} 
ObjFactory::newObj()->method(); 
+3

Pims Antwort ist korrekt. Alternativ können Sie statische Funktionen verwenden, wenn Sie keine Instanz des Objekts erstellen möchten. – Mark

+1

Was ist ein objFacotry?;) – Ropstah

6

Sie könnten eine statische Factory-Methode zur Herstellung des Objekts: über

ObjectFactory::NewObj()->method(); 
+2

Keine Notwendigkeit für eine separate Fabrik; Eine statische Methode in der gleichen Klasse wird dasselbe erreichen. – Brilliand

18

Wie :

$obj = new Obj(); $method_result = $obj->method(); // ? 

: P

+11

Große Antwort: P brachte mich zum Lachen. –

36

Sie können nicht tun, was Sie fragen; aber Sie können "schummeln", indem Sie die Tatsache verwenden, dass Sie in PHP eine Funktion haben können, die den gleichen Namen wie eine Klasse hat; Diese Namen werden nicht in Konflikt geraten.

Also, wenn Sie eine Klasse wie folgt erklärt:

class Test { 
    public function __construct($param) { 
     $this->_var = $param; 
    } 
    public function myMethod() { 
     return $this->_var * 2; 
    } 
    protected $_var; 
} 

Sie können dann eine Funktion deklarieren, die eine Instanz dieser Klasse gibt - und hat genau den gleichen Namen wie die Klasse:

function Test($param) { 
    return new Test($param); 
} 

Und nun wird es möglich, einen Einzeiler zu verwenden, wie Sie gefragt - nur, was Sie die Funktion aufrufen, indem somit nicht neu:

$a = Test(10)->myMethod(); 
var_dump($a); 

Und es funktioniert: hier, ich bin immer:

int 20 

als Ausgabe.


Und besser, Sie einige phpdoc auf Ihre Funktion setzen können:

/** 
* @return Test 
*/ 
function Test($param) { 
    return new Test($param); 
} 

diese Weise werden Sie auch Hinweise in Ihrem IDE haben werden - zumindest mit Eclipse PDT 2.x; siehe Screeshot:

http://extern.pascal-martin.fr/so/class-and-function.png



bearbeiten 2010-11-30: Nur zur Information, eine neue RFC eingereicht wurde, vor ein paar Tagen, das schlägt hinzufügen Diese Funktion zu einer der zukünftigen Versionen von PHP.

See: Request for Comments: Instance and method call/property access

Also, vielleicht Dinge wie dies tun wird in PHP 5.4 oder einem anderen zukünftigen Version möglich sein:

(new foo())->bar() 
(new $foo())->bar 
(new $bar->y)->x 
(new foo)[0] 
+0

schön! wusste das nicht – knittl

+0

Ich auch nicht, danke. – Ropstah

+0

Wow, sehr nett! Das wusste ich nicht. –

18

Sie können es mehr allgemein durch eine Identitätsfunktion definieren:

function identity($x) { 
    return $x; 
} 

identity(new Obj)->method(); 

Auf diese Weise müssen Sie keine Funktion für jede Klasse definieren.

+10

Schöne Lösung, wie es die Dummheit dieser Einschränkung betont :) – Ole

3

Auch ich suchte nach einem Einzeiler, um dies als Teil eines einzigen Ausdrucks für die Konvertierung von Daten von einem Format zum anderen zu erreichen. Ich mache das gerne in einer einzigen Codezeile, weil es sich um eine einzelne logische Operation handelt. Also, das ist ein wenig kryptisch, aber es lässt Sie instanziiert und ein Datum Objekt innerhalb einer einzigen Zeile verwenden:

$newDateString = ($d = new DateTime('2011-08-30') ? $d->format('F d, Y') : ''); 

Eine weitere Möglichkeit, einzeilige die Umwandlung von Datumszeichenketten von einem Format in ein anderes ist ein zu verwenden, Hilfsfunktion der OO Teile des Codes zu verwalten:

function convertDate($oldDateString,$newDateFormatString) { 
    $d = new DateTime($oldDateString); 
    return $d->format($newDateFormatString); 
} 

$myNewDate = convertDate($myOldDate,'F d, Y'); 

ich denke, der objektorientierte Ansatz kühl und notwendig ist, aber es kann manchmal sehr mühsam sein, erfordern zu viele Schritte einfache Operationen zu erreichen.

0

Ich sehe das schon recht alt ist wie Fragen gehen, aber hier ist etwas, was ich denke, sollte erwähnt werden:

Die Sonderklasse Methode innerhalb einer Klasse namens „__call()“ können neue Elemente erstellen verwendet werden . Sie verwenden es wie folgt aus:

<?php 
class test 
{ 

function __call($func,$args) 
{ 
    echo "I am here - $func\n"; 
} 

} 

    $a = new test(); 
    $a->new("My new class"); 
?> 

ausgegeben werden soll:

I am here - new 

So können Sie PHP täuschen in eine „neue“ innerhalb Ihrer Top-Level-Klasse Befehl zu machen (oder jede Klasse wirklich) und Setzen Sie Ihren Include-Befehl in die Funktion __call(), um die von Ihnen angeforderte Klasse einzuschließen. Natürlich würden Sie wahrscheinlich $ func testen wollen, um sicherzustellen, dass es ein "neuer" Befehl ist, der an den Befehl __call() gesendet wurde und (natürlich) Sie könnten auch andere Befehle haben, weil __call() funktioniert.

Verwandte Themen