php - the - ¿Cómo puedo llamar a un método estático en una clase variable?
static programacion (6)
Intento realizar algún tipo de función que cargue y ejemplifique una clase a partir de una variable determinada. Algo como esto:
<?php
function loadClass($class) {
$sClassPath = SYSPATH."/classes/{$class}.php";
if (file_exists($sClassPath)) {
require_once($sClassPath);
$class = $class::getInstance();
}
}
?>
Si lo uso así:
<?php
loadClass(''session'');
?>
Debe incluir y crear instancias de la clase de sesión.
Por cierto: la función estática getInstance proviene de este código:
<?php
function getCallingClass() {
$backtrace = debug_backtrace();
$method = $backtrace[1][''function''];
$file = file($backtrace[1][''file'']);
$line = $file[($backtrace[1][''line''] - 1)];
$class = trim(preg_replace("/^.+?([A-Za-z0-9_]*)::{$method}/(.*$/s", "//1//2", $line));
if(! class_exists($class)) {
return false;
} return $class;
}
class Core {
protected static $instances = array();
public static function getInstance() {
$class = getCallingClass();
if (!isset(self::$instances[$class])) {
self::$instances[$class] = new $class();
} return self::$instances[$class];
}
}
?>
La cuestión es que ahora la forma de usar las funciones en una clase es esta:
<?php
$session = session::getInstance();
?>
Pero ahora quiero construir eso en una función para que nunca más tenga que usar esa línea de código. Solo digo loadClass (''session''); y que puedo usar $ session-> blablablafunction ();
¿Por qué no usar la función __autoload ()?
entonces simplemente crea una instancia del objeto cuando sea necesario.
Fuera de mi cabeza, necesita pruebas, validación, etc.
<?php
function loadClass($className) {
if (is_object($GLOBALS[$className]))
return;
$sClassPath = SYSPATH."/classes/{$className}.php";
if (file_exists($sClassPath)) {
require_once($sClassPath);
$reflect = new ReflectionClass($className);
$classObj = $reflect->newInstanceArgs();
$GLOBALS[$className] = $classObj;
}
}
?>
Llamar a funciones estáticas en un nombre de clase variable aparentemente está disponible en PHP 5.3:
Foo::aStaticMethod();
$classname = ''Foo'';
$classname::aStaticMethod(); // As of PHP 5.3.0
http://php.net/manual/en/language.oop5.static.php
Definitivamente podría usar eso ahora mismo.
Hasta entonces, no puede suponer que todas las clases que esté cargando estén diseñadas para ser singleton. Siempre que use <5.3, deberá cargar la clase y crear instancias a través del constructor:
function loadClass($class) {
$sClassPath = SYSPATH."/classes/{$class}.php";
if (file_exists($sClassPath)) {
require_once($sClassPath);
$class = new $class;
}
}
O
Simplemente cargue la clase sin crear un objeto a partir de ella. A continuación, llame a ":: getInstance ()" en aquellos destinados a ser singletons, y "nuevo" en los que no lo son, desde fuera de la función loadClass ().
Aunque, como otros señalaron anteriormente, una __autoload () probablemente funcionaría bien para usted.
Los enlaces estáticos finales funcionarán para usted, creo. En la construcción de cada clase haz:
class ClassName
{
public static $instances = array();
public function __construct()
{
self::$instances[] = $this;
}
}
Entonces ... Aquí hay un autocargador que creé. Vea si esto resuelve su dilema.
// Shorten constants for convenience
define (''DS'', DIRECTORY_SEPARATOR);
define (''PS'', PATH_SEPARATOR);
$template = "default";
// Define an application path constants
define (''APP_ROOT'', realpath(''.'').DS);
define (''VIEW'', APP_ROOT . ''Views'' . DS);
define (''MODEL'', APP_ROOT . ''Models'' . DS);
define (''CONTROLLER'', APP_ROOT . ''Controllers'' . DS);
define (''TEMPLATE'', VIEW."templates".DS.$template.DS);
define (''CONTENT'', VIEW."content".DS);
define (''HELPERS'', MODEL."helpers".DS);
// Check if application is in development stage and set error reporting and
// logging accordingly
error_reporting(E_ALL);
if (defined(''DEVELOPMENT'')) {
ini_set(''display_errors'', 1);
} else {
ini_set(''display_errors'', 0);
ini_set(''log_errors'', ''On'');
ini_set(''error_log'', APP_ROOT.''error.log'');
}
$paths = array(APP_ROOT, VIEW, MODEL, CONTROLLER, TEMPLATE, CONTENT, HELPERS);
// Set the include path from Config Object
set_include_path(implode(PS, $paths));
// Autoloader
function __autoload($class)
{
require_once $class.''.php'';
return;
}
Entonces todo lo que tienes que hacer es
$var = new ClassName();
pero debe tener un archivo php en la ruta con el nombre ClassName.php donde ClassName es el mismo que el nombre de la clase que desea instanciar.
Parece que estás luchando contra el enlace estático de implementación actual de PHP, que es la razón por la que estás saltando por los aros con getCallingClass. Puedo decirte por experiencia que probablemente deberías dejar de tratar de crear instancias en una clase para padres a través de un método estático. Te causará más problemas al final. PHP 5.3 implementará "enlace estático tardío" y debería resolver su problema, pero obviamente eso no ayuda ahora.
Probablemente sea mejor utilizar la funcionalidad de autocarga mencionada por kodisha combinada con una implementación sólida de Singleton. No estoy seguro de si su objetivo es el azúcar sintáctico o no, pero cree que lo hará mejor a largo plazo para evitar algunos personajes.
Puede usar call_user_func()
:
$class = call_user_func(array($class, ''getInstance''));
El primer argumento es un tipo de callback
contiene el nombre de clase y el nombre del método en este caso.