yo tengo un par de preguntas sobre las clases PHP pero no se les puede pedir por separado, por lo que aquí voy:Algunos (avanzado) preguntas en torno a las clases PHP
tengo un CMS que estoy construyendo y en el núcleo de ahí están mis clases baseClass, logger, DB y modules. DB y logger son clases estáticas, así que puedo usarlos desde otros objetos. Hay muchas clases de módulos que se cargan en los BaseClass con:
class baseClass {
private $_modules;
public function __construct() {
logger::log("instance created.");
$this->_modules = Array()
}
public function __destruct() {
foreach($this->_modules as $name) $this->unloadModule($name);
logger::log("instance destroyed.");
}
public function loadModule($name) {
if (class_exists($name)) {
if (!isset($this->$name)) {
$this->_modules[] = $name;
$this->$name = new $name();
logger::log("module '$name' loaded.");
}
else logger::log("module '$name' already loaded.", 2);
}
else logger::log("module '$name' does not exist.", 3);
}
public function unloadModule($name) {
if (isset($this->$name)) {
unset($this->$name);
foreach($this->_modules as $id => $mod_name) {
if ($name==$mod_name) {
unset($this->_modules[$id]);
logger::log("module '$name' unloaded.");
}
}
}
else logger::log("module '$name' not loaded.", 2);
}
public function listModules() {
return $this->_modules;
}
}
$instance = new baseClass();
$instance->loadModule('moduleX');
$instance->loadModule('moduleY');
Pregunta 1: ¿Es mi aplicación loadmodule una buena idea o si tiene una mejor solución. O es posible extender una clase a la inversa, por lo que no tendría que cargar los módulos, en lugar de su definición de clase se carga a sí mismos en los BaseClass como:
class moduleX reverseExtends baseClass {
public function f1();
public function f2();
}
class moduleY reverseExtends baseClass {
public function f3();
public function f4();
}
$instance = new baseClass();
$instance->f1();
$instance->f2();
$instance->f3();
$instance->f4();
o al menos:
$instance->moduleX->f1();
$instance->moduleX->f2();
$instance->moduleY->f3();
$instance->moduleY->f4();
Pregunta 2: Por ahora estoy usando mi registrador y las clases de DB como clases estáticas (los llamo con logger :: y DB: :) para que sean accesibles desde cualquier contexto y ámbito - ¿es posible instanciar y todavía los utilizo dentro de mi objeto baseClass, pero sin instanciarlos dentro de la baseClass o configurarlos de esta manera dentro de cada clase que voy a usarlo con: métodos diferentes
public function __construct() {
global $logger_instance;
$this->logger = $logger_instance;
}
que he probado que van desde malos como pasando una referencia del objeto original dentro de los BaseClass a feo como el uso de funciones de contenedor. El uso de referencias destruye mi objeto logger cuando baseClass está desarmado y es difícil de acceder a través de módulos - $ this-> base-> logger-> log() - que a su vez requiere una referencia al objeto baseClass ($ this-> base) y mata mi objeto baseClass en unloadModule ... En cuanto a la función de envoltura - Quiero poder tener varias instancias del objeto logger, por lo que pasar un identificador de instancia junto con la función lo hace realmente feo y una solución "falsa".
necesito algo como:
public function someFuncionInsideSomeClass() {
$logger->('Log something'); //or $logger('Log something') with __invoke()
//$logger here is in the global scope
}
Pregunta 3: Quiero un módulo para poder modificar el código de otro. Por ejemplo, tengo un módulo de base de datos cargado, luego cargo un módulo logger y quiero que el módulo logger se integre en el código del módulo de base de datos sin que yo tenga que meterme con su código original. Por supuesto, el registrador tendría que encargarse de la integración en sí (o más bien de mí como codificador). Un simple ejemplo:
class tagCreator {
public function createTag($tag,$data) {
$tag1 = $tag;
$tag2 = '/'.$tag;
return "<$tag1>$data<$tag2>";
}
}
class styleFunctionality {
public function __construct() {
//if class is loaded (tagCreator) | load class (tagCreator)
//do some magic here to tagCreator
//tagCreator -> createTag -> add argument $style
//tagCreator -> createTag -> $tag1 += ' style="'.$style.'"'
//else issue error tagCreator does not exist
}
}
$instance = new baseClass();
$instance->loadModule('tagCreator');
echo $instance->createTag('span','some string');
// returns <span>some string</span>
$instance->loadModule('styleFunctionality');
echo $instance->createTag('span','some string','font-weight: bold');
// returns <span style="font-weight: bold">some string</span>
Nota: no me refiero necesariamente la sobrecarga de funciones, que podría querer cambiar sólo un poco de código dentro de un método
Nota 2: Llamar a $ ejemplo-> createTag () no es un error - planeo escribir alguna fantasía función __ llamada() para la clase base para elegir los métodos de sus módulos cargados
lo siento por el tema de largo y gracias por leer hasta aquí, yo incluso appreciat e una respuesta a una sola de mis preguntas :)
Q1 - Puede utilizar la carga automática para cargar sus clases a pedido para que su segundo método de llamada sea posible '$ instancia-> móduloY-> f4();'. P2 - Creo que el método estático sería la manera de ir allí. – JohnP
Pensé en eso, pero a veces podría haber declarado todos los módulos, pero no quisiera que todos los cargaran en mi baseClass. –
Respondí con más detalles. No debería cargar en su clase base – JohnP