2008-09-16 8 views
7

Ist es möglich, in PHP (as it is in C++) eine class method AUSSERHALB der class definition?Definieren von Klassenmethoden in PHP

+1

Soweit ich weiß, was Sie fragen, ist in C++ nicht möglich. Vielleicht möchten Sie klären. – erlando

+0

In C++ können Sie Funktionen außerhalb der Klasse definieren, und wenn der erste Parameter von diesem Klassentyp ist, dann erhalten Sie, was wie eine Überladung aussieht (d. H. Ein explizites "This"). Die Methode wird beispielsweise für den Operator << von std :: cout verwendet. Leider erkennt PHP einen Typ beim Aufruf einer Funktion nicht. Die Anzahl der Parameter ist die einzige Möglichkeit, um zwischen PHP-Funktionen zu unterscheiden. Die Funktion selbst kann auf einen Parametertyp testen und sich anders verhalten, aber zwei Funktionen mit demselben Namen und derselben Anzahl von Parametern sind in PHP illegal. –

Antwort

1

Nr

Sie zuvor deklarierten Klassen erweitern können zu erklären, obwohl, ob das hilft.

8

Nein, ab PHP 5.2. Sie können jedoch die magische Methode __call verwenden, um den Aufruf an eine beliebige Funktion oder Methode weiterzuleiten.

class A { 

    public function __call($method, $args) { 
     if ($method == 'foo') { 
      return call_user_func_array('bar', $args); 
     } 
    } 

} 

function bar($x) { 
    echo $x; 
} 

$a = new A(); 
$a->foo('12345'); // will result in calling bar('12345') 

In PHP 5.4 gibt es Unterstützung für Züge. Merkmal ist eine Implementierung von Methoden, die nicht als eigenständiges Objekt instanziiert werden können. Stattdessen kann die Eigenschaft verwendet werden, um die Klasse mit der enthaltenen Implementierung zu erweitern. Erfahren Sie mehr über Eigenschaften here.

0

Nein, es ist nicht möglich. Wenn Sie die Funktion/Methode außerhalb des Klassenkonstrukts definieren, wird sie zur globalen Funktion.

+0

Alle außerhalb einer Klasse definierten Funktionen sind nicht global. Wenn Sie die Funktion in einer Variablen speichern, ist sie nicht global. ('$ func = function() {...};') –

3

Sie könnten vielleicht __call or __callStatic außer Kraft setzen, um zur Laufzeit eine fehlende Methode zu finden, aber Sie müssten Ihr eigenes System für das Auffinden und Aufrufen des Codes erstellen. Sie könnten beispielsweise eine Klasse "Delegate" laden, um den Methodenaufruf zu verarbeiten.

Hier ist ein Beispiel - wenn Sie versucht haben, $ foo-> bar() aufzurufen, würde die Klasse versuchen, eine FooDelegate_bar-Klasse zu erstellen und sie mit denselben Argumenten() aufrufen. Wenn Sie Klasse Auto-Laden eingerichtet haben, kann der Delegat in einer separaten Datei leben, bis sie benötigt ...

class Foo { 

    public function __call($method, $args) { 
     $delegate="FooDelegate_".$method; 
     if (class_exists($delegate)) 
     { 
      $handler=new $delegate($this); 
      return call_user_func_array(array(&$handler, $method), $args); 
     } 


    } 

} 
0

C++ kann dies auch nicht tun. Haben Sie die Deklaration mit de finition verwechselt?

0

Nein, wie alle gesagt haben, ist es nicht streng möglich.

Sie können jedoch something like this tun, um ein Mixin in PHP zu emulieren oder Methoden zu einer Klasse zur Laufzeit hinzuzufügen, was ungefähr so ​​nah ist, wie Sie bekommen werden. Im Grunde verwendet es nur Entwurfsmuster, um die gleiche Funktionalität zu erreichen. Zope 3 tut etwas Ähnliches, um Mixins in Python zu emulieren, eine andere Sprache, die sie nicht direkt unterstützt.

+0

Ihre Aussage über Python ist falsch, da Python die mehrfache Vererbung unterstützt und tatsächlich Methoden zur Laufzeit unterstützt. – lkraider

5

Ja, es ist möglich, eine Methode zu einer PHP-Klasse hinzuzufügen, nachdem sie definiert wurde. Sie möchten classkit verwenden, was eine "experimentelle" Erweiterung ist. Es scheint, dass diese Erweiterung nicht standardmäßig aktiviert ist, also hängt es davon ab, ob Sie eine benutzerdefinierte PHP-Binärdatei kompilieren oder PHP-DLLs laden können (z. B. DreamHost erlaubt benutzerdefinierte PHP-Binärdateien und sie sind ziemlich einfach einzurichten)).

<?php 
class A { } 
classkit_method_add('A', 'bar', '$message', 'echo $message;', 
    CLASSKIT_ACC_PUBLIC); 
$a = new A(); 
$a->bar('Hello world!'); 

Beispiel aus dem PHP Handbuch:

<?php 
class Example { 
    function foo() { 
     echo "foo!\n"; 
    } 
} 

// create an Example object 
$e = new Example(); 

// Add a new public method 
classkit_method_add(
    'Example', 
    'add', 
    '$num1, $num2', 
    'return $num1 + $num2;', 
    CLASSKIT_ACC_PUBLIC 
); 

// add 12 + 4 
echo $e->add(12, 4); 
+0

Beachten Sie, dass hierfür eine PECL-Erweiterung erforderlich ist, die nicht alle Benutzer automatisch auf ihrem Server haben. Außerdem heißt es jetzt runkit. http://www.php.net/manual/en/function.runkit-method-add.php –

1

Als PHP 5.3 Verschlüsse unterstützt, können Sie dynamisch Instanzmethoden als Variablen Halte Verschlüsse definieren:

$class->foo = function (&$self, $n) { 
    print "Current \$var: " . $self->var . "\n"; 
    $self->var += $n; 
    print "New \$var:  " .$self->var . "\n"; 
}; 

Unter $self (man kann‘ Verwenden Sie $this außerhalb Objektkontext) als eine Referenz (&), können Sie die Instanz ändern.

treten jedoch Probleme auf, wenn Sie versuchen, die normalerweise die Funktion aufrufen:

$class->foo(2); 

Sie einen fatalen Fehler. PHP denkt foo ist eine Methode von $class, wegen der Syntax. Außerdem müssen Sie die Instanz als erstes Argument übergeben.

Es gibt glücklicherweise eine spezielle Funktion für Funktionen mit Namen genannt Aufruf call_user_func:

call_user_func($class->foo, &$class, 2); 
# => Current $var: 0 
# => New $var:  2 

Denken Sie daran & vor der Instanzvariable zu setzen.

Was noch einfacher ist, wenn Sie die __call magische Methode verwenden:

class MyClass { 
    public function __call ($method, $arguments) { 
    if (isset($this->$method)) { 
     call_user_func_array($this->$method, array_merge(array(&$this), $arguments)); 
    } 
    } 
} 

Jetzt können Sie $class->foo(2) stattdessen nennen. Die magische Methode __call fängt den Aufruf einer unbekannten Methode ab und ruft den Abschluss in der Variablen $class->foo mit demselben Namen wie die aufgerufene Methode auf.

Natürlich, wenn $class->var war privat, die Schließung in der $class->foo Variable gespeichert wäre nicht in der Lage, darauf zuzugreifen.

+0

Beachten Sie, dass die Verwendung von & beim Aufruf einer Funktion in PHP nicht erlaubt ist. Es wurde vor einiger Zeit akzeptiert (wahrscheinlich notwendig in PHP 4), aber heute erhalten Sie Warnungen oder Fehler, wenn Sie den Code 'call_user_func ($ class-> foo, & $ class, 2);' ausführen. –

+0

Ich weiß. Es war notwendig, vorher – jocap

+0

Und außerdem, in den neuesten PHP-Versionen können Sie $ this in closures verwenden. – jocap