2008-09-16 21 views
7

¿Es posible en PHP (as it is in C++) a declarar el class method FUERA del class definition?métodos de la clase que define en PHP

+1

Por lo que yo sé, lo que está preguntando no es posible en C++. Es posible que desee aclarar. – erlando

+0

En C++ puedes definir funciones fuera de la clase y si el primer parámetro es de ese tipo de clase, obtienes lo que parece una sobrecarga (es decir, un "esto" explícito). El método se usa para cosas como el operador << de std :: cout, por ejemplo. Desafortunadamente, PHP no reconoce un tipo cuando llama a una función. La cantidad de parámetros es lo único que se puede usar para distinguir entre funciones de PHP. La función en sí misma puede probar un tipo de parámetro y actuar de forma diferente sobre él, pero dos funciones con el mismo nombre y el mismo número de parámetros son algo ilegal en PHP. –

Respuesta

1

Puede extender las clases declarados anteriormente, sin embargo, si eso ayuda.

8

No, a partir de PHP 5.2. Sin embargo, puede usar el método mágico __call para reenviar la llamada a una función o método arbitrario.

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') 

En PHP 5.4 hay soporte para rasgos. El rasgo es una implementación de método (s) que no se pueden instanciar como objeto independiente. En cambio, el rasgo se puede usar para extender la clase con la implementación contenida. Conozca más sobre los Rasgos here.

0

No, no es posible. si define la función/método fuera de la construcción de clase, se convierte en función global.

+0

Todas las funciones definidas fuera de una clase no son globales. Si guarda la función en una variable, entonces no es global. ('$ func = function() {...};') –

3

Podría anular __call or __callStatic para localizar un método que falta en el tiempo de ejecución, pero tendría que crear su propio sistema para localizar y llamar al código. Por ejemplo, puede cargar una clase "Delegar" para manejar la llamada al método.

Aquí hay un ejemplo: si intentas llamar $ foo-> bar(), la clase intentará crear una clase FooDelegate_bar y invocar a bar() sobre ella con los mismos argumentos. Si usted tiene la clase de auto-carga configurado, el delegado puede vivir en un archivo separado hasta que sea necesario ...

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++ no puede hacer esto tampoco. ¿Confundió la declaración con finition?

0

No, como todos han dicho, no es estrictamente posible.

Sin embargo, puede hacer something like this para emular una mezcla en PHP o agregar métodos a una clase en tiempo de ejecución, que es lo más cerca que va a obtener. Básicamente, solo usa patrones de diseño para lograr la misma funcionalidad. Zope 3 hace algo similar para emular mixins en Python, otro lenguaje que no los admite directamente.

+0

Su afirmación sobre Python es incorrecta, ya que Python admite herencia múltiple y, de hecho, es compatible con la definición de métodos en tiempo de ejecución. – lkraider

5

Sí, es posible agregar un método a una clase de PHP después de que se haya definido. Desea utilizar classkit, que es una extensión "experimental". Parece que esta extensión no está habilitada por defecto, por lo que depende de si puede compilar un archivo binario PHP personalizado o cargar archivos DLL PHP si está en Windows (por ejemplo, Dreamhost permite binarios PHP personalizados, y son bastante fáciles de configurar)

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

Ejemplo del manual de PHP:

<?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

Tenga en cuenta que esto requiere una extensión PECL que no todos automáticamente tienen en su servidor. Además, ahora se llama runkit en su lugar. http://www.php.net/manual/en/function.runkit-method-add.php –

1

Como PHP 5.3 soporta cierres, puede definir dinámicamente métodos de instancia como variables que llevan a cabo cierres:

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

Tomando $self (se puede' t use $this fuera del contexto del objeto) como referencia (&), puede modificar la instancia.

Sin embargo, los problemas se producen cuando se intenta llamar a la función normal:

$class->foo(2); 

se obtiene un error fatal. PHP piensa que foo es un método de $class, debido a la sintaxis. Además, debe pasar la instancia como primer argumento.

No es afortunadamente una función especial para llamar a las funciones de llamadas call_user_func nombre:

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

Sólo recuerde poner & antes de la variable de instancia.

Lo que es aún más fácil es si se utiliza el método mágico __call:

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

Ahora se puede llamar $class->foo(2) lugar. El método magic __call capta la llamada a un método desconocido y llama al cierre en la variable $class->foo con el mismo nombre que el método llamado.

Por supuesto, si $class->var fuera privado, el cierre almacenado en la variable $class->foo no podría acceder a él.

+0

Tenga en cuenta que el uso de & al llamar a una función no es legal en PHP. Fue aceptado hace un tiempo (probablemente necesario en PHP 4) pero hoy recibes advertencias o errores cuando ejecutas el código 'call_user_func ($ class-> foo, & $ class, 2);'. –

+0

Lo sé. Fue necesario antes de – jocap

+0

y además, en las últimas versiones de PHP, puede usar $ this en cierres. – jocap

Cuestiones relacionadas