¿Cómo puedo obtener el nombre de la clase de una llamada estática en una clase PHP extendida?


93

Tengo dos clases: Actiony MyAction. Este último se declara como:

class MyAction extends Action {/* some methods here */}

Todo lo que necesito es un método en la Actionclase (solo en él, porque habrá muchas clases heredadas y no quiero implementar este método en todas), que devolverá el nombre de clase de una llamada estática. Esto es de lo que estoy hablando:

Class Action {
 function n(){/* something */}
}

Y cuando lo llamo:

MyAction::n(); // it should return "MyAction"

Pero cada declaración en la clase principal tiene acceso solo a la __CLASS__variable de la clase principal , que tiene el valor "Acción".

¿Hay alguna forma posible de hacer esto?

Respuestas:


176

__CLASS__siempre devuelve el nombre de la clase en la que se usó, por lo que no es de mucha ayuda con un método estático. Si el método no fuera estático, simplemente podría usar get_class ($ this). p.ej

class Action {
    public function n(){
        echo get_class($this);
    }

}

class MyAction extends Action {

}

$foo=new MyAction;

$foo->n(); //displays 'MyAction'

Enlaces estáticos tardíos, disponibles en PHP 5.3+

Ahora que se lanzó PHP 5.3, puede usar enlaces estáticos tardíos , que le permiten resolver la clase de destino para una llamada de método estático en tiempo de ejecución en lugar de cuando está definida.

Si bien la función no introduce una nueva constante mágica para decirle el nombre de clase a través del cual fue llamado, sí proporciona una nueva función, get_called_class () que puede indicarle el nombre de la clase en la que se llamó a un método estático. Aquí hay un ejemplo:

Class Action {
    public static function n() {
        return get_called_class();
    }
}


class MyAction extends Action {

}


echo MyAction::n(); //displays MyAction

El único problema para el OP es que la función aún no está disponible. PHP 5.3 aún está en fase beta.
Ionuț G. Stan

3
@Paul, ¡gracias! Acabas de get_called_class()
salvarme el

1
Ojalá alguien pudiera ayudarme con un problema similar . El script PHP muere silenciosamente al ejecutarse new static();desde dentro de un método estático privado (usando xampp en Windows y php> 5.5). :s
Stphane

$ foo = new MyAction; echo get_class ($ foo); Esto también imprime MyAction.
sammry


16

No es la solución ideal, pero funciona en PHP <5.3.0.

El código fue copiado de septuro.com

if(!function_exists('get_called_class')) {
    class class_tools {
        static $i = 0;
        static $fl = null;

        static function get_called_class() {
            $bt = debug_backtrace();

            if (self::$fl == $bt[2]['file'].$bt[2]['line']) {
                self::$i++;
            } else {
                self::$i = 0;
                self::$fl = $bt[2]['file'].$bt[2]['line'];
            }

            $lines = file($bt[2]['file']);

            preg_match_all('/([a-zA-Z0-9\_]+)::'.$bt[2]['function'].'/',
                $lines[$bt[2]['line']-1],
                $matches);

            return $matches[1][self::$i];
        }
    }

    function get_called_class() {
        return class_tools::get_called_class();
    }
}


2
class MainSingleton { 
  private static $instances = array(); 
  private static function get_called_class() {
    $t = debug_backtrace();
    return $t[count($t)-1]["class"];
  }  

  public static function getInstance() { 
    $class = self::get_called_class();
    if(!isset(self::$instances[$class]) ) { 
      self::$instances[$class] = new $class; 
    } 
    return self::$instances[$class]; 
  } 

}

class Singleton extends MainSingleton { 
  public static function getInstance()
  {
    return parent::getInstance();
  }     
  protected function __construct() { 
    echo "A". PHP_EOL; 
  } 

  protected function __clone() {} 

  public function test() { 
    echo " * test called * "; 
  } 
} 

Singleton::getInstance()->test(); 
Singleton::getInstance()->test();

0

No hay forma, en las versiones PHP disponibles, de hacer lo que quiera. La solución de Paul Dixon es la única. Quiero decir, el ejemplo de código, ya que la última función de enlaces estáticos de la que habla está disponible a partir de PHP 5.3, que está en versión beta.


0

(PHP 5> = 5.3.0, PHP 7)
get_called_class - El nombre de la clase "Enlace estático tardío"

<?php

class Model
{
  public static function find()
  {
    return get_called_class();
  }
}

class User extends Model
{
}


echo User::find();

este enlace puede ser útil

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.