Foros del Web » Programando para Internet » PHP » Frameworks y PHP orientado a objetos »

Extender objetos

Estas en el tema de Extender objetos en el foro de Frameworks y PHP orientado a objetos en Foros del Web. Hola .. (introducción) Estoy usando la classe "FPDF" ( www.fpdf.org ) que genera PDF's dinámicos desde PHP. Bien, dicha classe tiene como ejemplos bastantes "classes" ...

  #1 (permalink)  
Antiguo 21/03/2005, 09:46
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 4 meses
Puntos: 129
Extender objetos

Hola ..

(introducción)
Estoy usando la classe "FPDF" (www.fpdf.org) que genera PDF's dinámicos desde PHP. Bien, dicha classe tiene como ejemplos bastantes "classes" que extienden a la classe padre para aportar nuevas funcionalidades.

Hasta aquí todo OK, .. el detalle está que cada extensión funciona por sí sola pero hay funcionalidades de várias extensiones (que extenden a la classe padre) que me gustaría usar.

Actualmente .. lo único que hago es tomar todos esos métodos y demás lógica del las classes "extensoras" (no sé como llamarlo) y las uno (cut-and-poaste) sobre una classe "extended". Supongo que esto si bien funciona . .no será lo "políticamente correcto" .. así que quería saber si UDs. conocen la técnica para trabajar este tipo de problemas .. Supongo que algún array como "contenedor" y temas similares .. pero mi conocimiento de OOP es bajo .. sólo soy "usuario" de OOP con este requerimiento. (para ejemplos .. please con "peritas y manzanas" xDD).

En resumen dispongo de N classes que extienden a la padre tipo:

Código PHP:
class PDF extends FPDF {

var 
$DisplayPreferences='';

function 
DisplayPreferences($preferences) {
    
$this->DisplayPreferences.=$preferences;
}

function 
_putcatalog()
{
    
parent::_putcatalog();
    if(
is_int(strpos($this->DisplayPreferences,'FullScreen')))
        
$this->_out('/PageMode /FullScreen');
    if(
$this->DisplayPreferences) {
        
$this->_out('/ViewerPreferences<<');
        if(
is_int(strpos($this->DisplayPreferences,'HideMenubar')))
            
$this->_out('/HideMenubar true');
        if(
is_int(strpos($this->DisplayPreferences,'HideToolbar')))
            
$this->_out('/HideToolbar true');
        if(
is_int(strpos($this->DisplayPreferences,'HideWindowUI')))
            
$this->_out('/HideWindowUI true');
        if(
is_int(strpos($this->DisplayPreferences,'DisplayDocTitle')))
            
$this->_out('/DisplayDocTitle true');
        if(
is_int(strpos($this->DisplayPreferences,'CenterWindow')))
            
$this->_out('/CenterWindow true');
        if(
is_int(strpos($this->DisplayPreferences,'FitWindow')))
            
$this->_out('/FitWindow true');
        
$this->_out('>>');
    }
}

y otra más por ejemplo ...
Código PHP:
class PDF_Javascript extends FPDF {

    var 
$javascript;
    var 
$n_js;

    function 
IncludeJS($script) {
        
$this->javascript=$script;
    }

    function 
_putjavascript() {
        
$this->_newobj();
        
$this->n_js=$this->n;
        
$this->_out('<<');
        
$this->_out('/Names [(EmbeddedJS) '.($this->n+1).' 0 R ]');
        
$this->_out('>>');
        
$this->_out('endobj');
        
$this->_newobj();
        
$this->_out('<<');
        
$this->_out('/S /JavaScript');
        
$this->_out('/JS '.$this->_textstring($this->javascript));
        
$this->_out('>>');
        
$this->_out('endobj');
    }

    function 
_putresources() {
        
parent::_putresources();
        if (!empty(
$this->javascript)) {
            
$this->_putjavascript();
        }
    }

    function 
_putcatalog() {
        
parent::_putcatalog();
        if (isset(
$this->javascript)) {
            
$this->_out('/Names <</JavaScript '.($this->n_js).' 0 R>>');
        }
    }

Instancio y uso el objeto (ahora uno sólo) tipo:
Código PHP:
$pdf=new PDF();
$pdf->SetDisplayMode('fullpage');
$pdf->DisplayPreferences('HideMenubar,HideToolbar,HideWindowUI');
$pdf->AddPage();
$pdf->SetFont('Arial','',16);
$pdf->Write(6,'Only the document should appear, no interface element.');
$pdf->Output(); 
Pero, .. claro .. si intento hacer eso con los dos . .pues alega PHP sobre duplicidad de classes (lógico) ..

He visto que algunas veces se extienden en "cadena" (el padre al hijo .. del hijo al nieto ... ) .. Podría servir .. pero realmente no son "padre ->hijo" sino todas son al padre (nuevos métodos). (tal vez aquí esté confundido .. esa es la impresión que me dá sin haber leido mucha teoría al respecto sobre modelos y temas afines).

Un salduo,
  #2 (permalink)  
Antiguo 22/03/2005, 12:42
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 20 años, 6 meses
Puntos: 1
que tal.
Si es que entiendo bien tu cuestinamiento, lo que necesitas es crear una clase totalmente nueva que manipule tantas extensiones como desees. Es decir, esta nueva clase se especializa en manipular extensiones de la clase FPDF. Podriamos llamarla 'FpdfExtensionHandler' y no hereda de ninguna otra clase, sino instancia objetos que heredan de Fpdf, de tal forma que podrías tener algo asi:

Código PHP:
final class FpdfExtensionsHandler
{
    const 
HANDLERS_DIRECTORY 'path/al/directorio/de/las/clases_extensiones/';
    private 
$extensions      = array();
    public  
$extension       null;
    
    public function 
__construct()
    {
        return 
true;
    }
    
    
/**
     * @return Bool
     * @param String $ExtensionName
     */
    
public function LoadExtension($ExtensionName)
    {
        
$extension_path self::HANDLERS_DIRECTORY.$ExtensionName
        
if ( file_exists($extension_path) && !class_exists($ExtensionName) )
        {
            include_once(
$extension_path);
            
$this->extensions[$ExtensionName] = new $ExtensionName();
        }
        return 
true;
    }
    
    
/**
     * @return Bool
     * @param String $ExtensionName
     */
    
public function SetExtension($ExtensionName)
    {
        if ( 
array_key_exists($ExtensionName,$this->extensions) )
        {
            
$this->extension =& $this->extensions[$ExtensionName];
        }
    }

de esta forma tu puedes cargar las extensiones que desees dentro del mismo objeto, simplemente usas el método LoadExtension para cargarlo, y luego SetExtension para usar la extensión que desees, la variable $this->extension siempre apunta a la extensión seleccionada.

Espero haber entendido correctamente tu cuestionamiento. Este proceso te permite seguir cargando tantas extensiones como desees. Obviamente hacen falta métodos para comprobar la existencia de las clases, etc etc.

saludos
  #3 (permalink)  
Antiguo 22/03/2005, 15:29
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 4 meses
Puntos: 129
Gracias sism82,

Mas o menos entendí tu planteamiento. Sobre la implementación (el prototipo) que propones, veo que usas el modelo de datos de OOP De PHP 5 .. actualmente uso PHP4 .. así que las declaraciones de los métodos públicos y privados no lo voy a poder hacer así .. ¿Tendría que cambiar alguna cosa más para adaptar el ejemplo a PHP4?

Un saludo,
  #4 (permalink)  
Antiguo 23/03/2005, 08:41
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 20 años, 6 meses
Puntos: 1
fuera de las palabras reservadas como final, private, public etc. Creo que php4 tampoco acepta declaraciones de constantes de clase (const), entonces la constante HANDLERS_DIRECTORY puedes usarla como variable interna, o bien, sacarla de la clase, yo creo que es preferible lo primero. Creo que con eso basta para adaptarlo a php4.

Suerte
  #5 (permalink)  
Antiguo 23/03/2005, 10:18
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 4 meses
Puntos: 129
Gracias .. probaré a ver si me resulta.

Un saludo,
  #6 (permalink)  
Antiguo 26/03/2005, 18:33
Avatar de jpinedo
Colaborador
 
Fecha de Ingreso: septiembre-2003
Ubicación: Lima, Perú
Mensajes: 3.120
Antigüedad: 20 años, 7 meses
Puntos: 41
Cita:
Iniciado por Cluster
Pero, .. claro .. si intento hacer eso con los dos . .pues alega PHP sobre duplicidad de classes (lógico)
Cluster... podrías explicar un poco más este asunto porque no acabo de entender el problema??
Saludos
  #7 (permalink)  
Antiguo 28/03/2005, 06:06
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 4 meses
Puntos: 129
Cita:
Iniciado por jpinedo
Cluster... podrías explicar un poco más este asunto porque no acabo de entender el problema??
Saludos
OK, voy a tratar de gráficar mejor el problema:

Como comentaba .. uso una classe "padre" (fpdf) .. dicha classe, por parte de usuarios han creado funcionalidades nuevas para ella. Las pueden ver en:
http://www.fpdf.org/es/script/index.php

Si se fijan .. todas son un "extended" (o hacen mejor dicho) a la classe "fpdf". Por si sólas funcionan de forma independiente y bien. Ahora, el detalle es ¿que sucede si dese usar várias de estas classes "extended" simultáneamente? (dicho de otra forma o mejor: usar algunos métodos de alguna y otra classe de las que extienden a fpdf).

Por eso .. necesito algún método o técnica para poder "llamar" a cada uno de estos "extenden" (classe) a modo de "pre-carga" y bajo una misma instancia tipo:

$pdf=new PDF();

Poder llamar a un método (supongo que nuevo) tipo:

$pdf->CargaExtended(nose.pdf ó nombre_Classe);

Y a partir de ahí .. poder usar esos métodos que están en la classe "nombre_Classe" que cargue .. pero con la peculiaridad de que no sea uno a uno sino poder "cargar" várias classes "extended" a la vez:

$pdf->CargaExtended(nose.pdf ó nombre_Classe);
$pdf->CargaExtended(nose.pdf ó nombre_Classe);
$pdf->CargaExtended(nose.pdf ó nombre_Classe);
(o como array ... o separado por parámetros las llamadas a más classes extended)

Más o menos es la idea de sism82, pero adaptado para el modelo de datos de POO de PHP4 a ser posible.

Un saludo,
  #8 (permalink)  
Antiguo 28/03/2005, 13:12
 
Fecha de Ingreso: marzo-2005
Mensajes: 163
Antigüedad: 19 años, 2 meses
Puntos: 0
A veces dicen que es mejor no meterse, ya que se puede generar mas confusion que otra cosa. Si no entiendo mal tu problema es que tenes en la jerarquia de clases, como padre a fpdf y varias clases hijas que proveen diferentes servicios. No te alcanzaria con hacer un casting de un objeto padre a uno de los hijos y usar los servicios del hijo? Es decir, :
Código PHP:
$pdf=new PDF();
$algo = (extenedClase)$pdf;
//este tipo de casting no funciona, pero es para entender la idea
$algo->servicio(); 
Este codigo sacado de http://ar2.php.net/oop habla de castings.

Código PHP:
<?php 
class foo 
   function 
foo($name="foo") { 
       
$this->name=$name
   } 


class 
bar extends foo 
   function 
boom() { 
       echo 
"BOOOM!"
   } 


$f = new foo(); 
$temp explode(":",serialize($f)); 
$temp[2] = "\"bar\""
$b unserialize(implode(":",$temp)); 

$b->boom(); 

?>
Si entendi cualquier cosa les pido disculpas...
Suerte :)

Última edición por MartinTandil; 28/03/2005 a las 13:13
  #9 (permalink)  
Antiguo 28/03/2005, 15:53
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 4 meses
Puntos: 129
Si, MartinTandil ... hasta ahí lo tengo claro .. pero el detalle es que quiero usar várias de esas classes "bar" de tu ejemplo con sus própios métos que estas implemente y que en su base extienden al padre pero "uno por uno" pero quiero usarlas simultánemente, disponer de todos los métodos de unas y de otras para usarlos ..

Un saludo,
  #10 (permalink)  
Antiguo 28/03/2005, 17:40
Avatar de jpinedo
Colaborador
 
Fecha de Ingreso: septiembre-2003
Ubicación: Lima, Perú
Mensajes: 3.120
Antigüedad: 20 años, 7 meses
Puntos: 41
Discúlpame pero creo que recién voy entendiendo el problema:
Lo que quieres es manejar una sola instancia:
$pdf = new ExtensionesDeFpdf();

Porque lo que quieres es tener en esa variable/objeto ($pdf) la funcionalidad de varias de las hijas de fpdf.
De esa manera al final sólo hacer un :
$pdf->output();

Lo que estás haciendo ahora es definir (con copiar-pegar) todos los métodos dentro de una sola clase y por eso funciona... pero quieres algo "mejor hecho" o "más ortodoxo".

¿Estoy en lo cierto?
  #11 (permalink)  
Antiguo 28/03/2005, 20:12
Avatar de jpinedo
Colaborador
 
Fecha de Ingreso: septiembre-2003
Ubicación: Lima, Perú
Mensajes: 3.120
Antigüedad: 20 años, 7 meses
Puntos: 41
Lo que yo creo es que esas extensiones no han sido escritas para trabajar juntas.
La verdad no tengo idea de cómo solucionar tu problema... pero al parecer el tema tiene que ver directamente con la herencia múltiple (no soportada por PHP, y que se supone que podría suplirse de manera efectiva con la composición).
Digo esto porque lo que necesitas es una clase que herede de todas esas extensiones .... o sea que implemente todos sus atributos y métodos.
Por eso creoq tendrías que buscar alternativas a la herencia múltiple, pero que te den un mayor control porque hay varios métodos del padre que son redefinidos por las hijas y hay que saber cuál de todos querría utilizarse.

Con la solución de sism82 lo que estarías haciendo es tener un montón de instancias (cada una de una Clase hija) y las acciones tendrán efecto en cada una de esas instancias por separado.
Entonces al hacer algo como:
$pdf->output();
¿Qué pasaría?... no creo que funcione como se espera. Pero tal vez sism82 puede ponernos un ejemplo de cómo se utilizaría su clase en este caso particular.

Saludos
  #12 (permalink)  
Antiguo 29/03/2005, 07:39
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 4 meses
Puntos: 129
Gracias Jpinedo .. Realmente no me he metido con OOP .. sólo a nivel "usuario" de classes.

El problema como comenté lo solvento "pegando" físicamente esos métodos que uso de uno y de otra classe "extended" que dispongo sobre una sóla .. así todo funciona bien.. Pero la idea es la de crear un sistema más dinámico a modo de sistema "plug-in" para una classe "padre" .. Pero si PHP hasta la fecha (o peor todavía para PHP 4 que es lo que realmente necesito usarlo) no lo soporta .. mm bueno.. "es lo que hay" no importa, nos esperaremos a que PHP soporte dichas funcionalidades (o yo me pueda cambiar a PHP 5 si es que este las soporta).

Un saludo,
  #13 (permalink)  
Antiguo 29/03/2005, 08:58
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 20 años, 6 meses
Puntos: 1
Que tal. Mmm es posible que no este viendo el problema. O bien, no explique bien el funcionamiento del código que puse anteriormente. No recuerdo del todo bien lo que puse pero la idea es sencilla. Los métodos a implementar, ya sea con php4 o php5 (da igual) son:

PdfExtensionHandler::LoadExtenstion($StringExtensi onName);

este método instanciaria dinamicamente las extensiones que desees utilizar, digamos que durante el proceso de una página vas a utilizar 3 extensiones, entonces llamas consecutivamente 3 veces:

Código PHP:
$pdf_extension_handler->LoadExtension('AlgunaExtension');
$pdf_extension_handler->LoadExtension('SegundaExtension');
$pdf_extension_handler->LoadExtension('TerceraExtension'); 
con eso, suponiendo que todo sale bien, se crean internamente las instancias de cada uno de las extensiones. Ahora, para utilizarlas, defines cual quieres usar con:

PdfExtensionHandler::SetExtension($StringExtension Name)
Que lo que hace es posicionar en la variable PdfExtensionHandler::$Extension, una referencia a la instancia de la extensión seleccionada.

Código PHP:
$pdf_extension_handler->SetExtension('SegundaExtension');
$pdf_extension_handler->extension->AlgunMetodoDeSegundaExtension();
$pdf_extension_handler->extension->OtroMetodoDeSegundaExtension();
$pdf_extension_handler->extension->TercerMetodoDeSegundaExtension(); 
En php 5 incluso pudieras ir un paso mas y omitir la variable interna $extension, e implementar el método mágico _call($MethodName), que basicamente es el punto donde todas las llamdas a un método no implementado serán dirigidas, entonces dentro de ese método mágico _call, tu harias la llamada a $this->extension->$MethodName($args); y de esa forma sería llamado el método del objeto al que este apuntando la referencia de $extension

este es un ejemplo de como uso esa función para desplegar un error de 'feature not supported'

Código PHP:
    /**
     * This function will work only in PHP5, catch all the undefined method calls.
     * Previous versions drop a fatal error when an undefined method is called
     * @date Jan/15/2005
     * @return bool
     * @param String CalledMethodName
     * @param Array $Parameters
     * @access magic
     */
    
function __call($CalledMethodName$Parameters
    {
        
$error_arguments = array();
        
$error_arguments['method'] = $CalledMethodName;
        return 
$this->HandleError(PDB_ERROR_FEATURE_NOT_SUPPORTED$error_arguments);
    } 
Si no deseas o no puedes usar php5, pues entonces tendrás que hacer las llamadas a los métodos directamente usando la referencia $extension.
Que inconveniente existe con esta implementación?
La herencia multiple dudo que alguna vez vaya a ser implementada en php, en general he leído que no es recomendada, hace mas confusas las cosas, por ello Java se olvidó de usar la herencia multiple y a cambio hizo lo mas cercano que pudo con las interfaces.

espero haber sido mas explicito esta vez, saludos.

en este caso $Parameters no lo utilizo, pero es parte de la definición del método magico _call
  #14 (permalink)  
Antiguo 29/03/2005, 09:48
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 4 meses
Puntos: 129
Entonces sim82 .. bajo el concepto que explicas, el uso alternativo de esas extensiones pre-cargadas ¿sería tipo?:

Código PHP:
$pdf_extension_handler->SetExtension('SegundaExtension'); 
$pdf_extension_handler->extension->AlgunMetodoDeSegundaExtension(); 
$pdf_extension_handler->extension->OtroMetodoDeSegundaExtension(); 
$pdf_extension_handler->extension->TercerMetodoDeSegundaExtension(); 

$pdf_extension_handler->SetExtension('OtraExtension'); 
$pdf_extension_handler->extension->AlgunMetodoDeOtraExtension(); 
$pdf_extension_handler->extension->OtroMetodoDeOtraExtension(); 
$pdf_extension_handler->extension->TercerMetodoDeOtraExtension(); 
Y para llamar a un método de la classe "padre"?

sería?:
Código PHP:
$pdf_extension_handler->metodo_classe_padre(); 
Un saludo,

Última edición por Cluster; 29/03/2005 a las 09:51
  #15 (permalink)  
Antiguo 29/03/2005, 14:06
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 20 años, 6 meses
Puntos: 1
Correcto. Ahora, para llamar a un método de la clase padre, no podrías hacer lo que indicas, recuerda que la clase que creamos no hereda de Fpdf, no hereda de ninguna, sino que manipula instancias de las clases hijas de Fpdf. Como lo hacemos? se me ocurre sencillamente que puedes mandarlo llamar desde cualquier clase hija, es decir, seria lo mismo:

Código PHP:
$pdf_extension_handler->SetExtension('SegundaExtension');
$pdf_extension_handler->extension->MetodoClasePadre(); 

//lo anterior es igual que

$pdf_extension_handler->SetExtension('TerceraExtension');
$pdf_extension_handler->extension->MetodoClasePadre(); 
por que tanto segunda como tercera extensión heredan del mismo padre, por lo tanto los métodos de la clase padre son compartidos por todas las clases hijas, es decir, por todas las extensiones. Por ello no importaría cual extensión este "seteada", cualquiera tiene acceso a los métodos del padre.
Si no te gusta eso, puedes hacer una referencia a la clase padre en una nueva variable interna llamada $padre y utilizarla como

Código PHP:
$pdf_extension_handler->padre->PrimerMetodoPadre()
$pdf_extension_handler->padre->SegundoMetodoPadre(); 
O tal vez no entendí tu pregunta, si es asi, a ver si me la puedes repetir :p
  #16 (permalink)  
Antiguo 29/03/2005, 19:32
Avatar de jpinedo
Colaborador
 
Fecha de Ingreso: septiembre-2003
Ubicación: Lima, Perú
Mensajes: 3.120
Antigüedad: 20 años, 7 meses
Puntos: 41
El problema sería que hay hijas que redefinen métodos del padre... por lo que supongo que podrías tratar al padre como una extensión más. De esa manera te aseguras de utilizar los métodos originales del padre. O sea:
Código PHP:
$pdf_extension_handler->LoadExtension('ClasePadre'); 
$pdf_extension_handler->LoadExtension('Extension1'); 
$pdf_extension_handler->LoadExtension('Extension2'); 
Y cuando quieras utilizar métodos originales del padre:
Código PHP:
$pdf_extension_handler->SetExtension('ClasePadre');
$pdf_extension_handler->extension->MetodoClasePadre(); 
La forma de utilizar esa clase (Extensions handler) sí se intuía.
En este momento no puedo hacer pruebas (y tal vez permanezca así durante unos diez días más mientras me ponen el speedy)... pero voy a exponerles mis dudas respecto al método de sism82:
- El objeto $pdf_extension_handler mantiene un arreglo de referencias a varias instancias de distintas hijas de FPDF.
- Aunque desde $pdf_extension_handler manejemos el comportamiento de todas ellas juntas... siempre van a seguir trabajando individualmente sin conocerse entre sí.

¿Cuál es el problema?
- No he utilizado FPDF, pero a raíz de este tema he estado mirando un poco el código (repito, no he hecho pruebas) y cuando uno crea una instancia de FPDF (o de una de sus hijas), uno sigue una secuencia. Voy a poner un ejemplo sencillo:
Código PHP:
$pdf = new Familiar_de_FPDF();
$pdf->AddPage();
$pdf->Método_para_escribir_texto('Este es un texto');
$pdf->Método_para_insertar_salto_de_linea();
$pdf->Método_para_escribir_texto('Este es un poco más de texto');
$pdf->Output(); 
Utilizando la manera expuesta por sism82, Suponiendo que quiero escribir JavaScript y texto HTML (para eso tendría que utilizar dos extensiones), internamente tendría tres instancias:
Código PHP:
$extensions['FPDF']; // El padre, si se trabaja como puse al comienzo de este post
$extensions['FPDF_HTML']; // Me acabo de inventar el nombre... tal vez así se llame de verdad
$extensions['FPDF_JS']; // Igual 
Entonces lo utilizaríamos así:
Código PHP:
pdf_extension_handler->SetExtension('FPDF'); 
$pdf_extension_handler->extension->Metodo_de_FPDF();
$pdf_extension_handler->SetExtension('FPDF_JS'); 
$pdf_extension_handler->extension->Metodo_de_FPDF_JS(); 
$pdf_extension_handler->SetExtension('FPDF_HTML'); 
$pdf_extension_handler->extension->Metodo_de_FPDF_HTML(); 
Y si quiero utilizar el método Output() para generar por fin el pdf????
$pdf_extension_handler->extension->output()
Dará el output del objeto que se estaba utilizando... pero no se generará lo que queríamos. Tampoco podríamos ir seleccionando una por una las extensiones y dándole Output... con esto quiero decir que estamos generando varios documentos pdf en varias instancias... y no es lo que deseamos.

Saludos

Última edición por jpinedo; 29/03/2005 a las 19:33
  #17 (permalink)  
Antiguo 29/03/2005, 22:31
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 20 años, 6 meses
Puntos: 1
efectivamente, la misma duda me asalto. pero como no tengo idea del funcionamiento interno de las clases de fpdf, no puedo opinar del tema. Este fin de semana le doy una checada al codigo, seguro que habra una forma de "compartir" las variables para que los metodos actuen como se requiere. Como por ejemplo utilizar variables estaticas o pasar referencias a los constructores de cada extension. De momento no puedo sugerir nada mas

saludos
  #18 (permalink)  
Antiguo 30/03/2005, 07:48
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 4 meses
Puntos: 129
Si, .. el problema que plantea jpinedo es lo que sucedería. Esa classe contiene métodos que interactuan entre ellos (variables) para ir generando ese documento PDF .. cada método digamos que genera una "porción" de ese código "PDF" (por decirlo más simple .. variable "acomulador") que al final de todo ha de usar cierto método para ver su resultado.

Por eso, si lo que propones sism82 funciona de forma independiente y no está preparado para definir/usar "variables globales" para el objeto "padre" de los resultados de las ejecuciones de otros métodos de las classes hijas .. mm no funcionará como se espera (o como debería para este caso).

Gracias igualmente por la ayuda, aunque poco puedo aportar al tema .. pero la pregunta mas que solventarme el problema puntual es mas bien un "concepto" que se podría extender a desarrollo de "objetos con plug-in" a modo de realizar esa "interface" entre los objetos hijos de un padre y de esta forma crear nuevos "plug-in" (disculpen si el término no es el adecuado) de forma sencilla y sobre todo transparente para el creador de esa classe hija.

Un saludo,
  #19 (permalink)  
Antiguo 30/03/2005, 08:01
 
Fecha de Ingreso: marzo-2005
Mensajes: 163
Antigüedad: 19 años, 2 meses
Puntos: 0
El problema que existe es la falta de herencia multiple. Si la herencia multiple existiera podrias hacer una clase que heredara de todas las extensiones y asi si utilizarias un solo objeto con todos los metodos de las extensiones. COmo esta planteado segun sism82 no lograras lo que pretendias inicialmente, ya que son instancias independientes que sufriran transformacion por separados. Y estuve pensando tu problema de las extensiones y te digo, inicialmente no puedes hacer lo que planteas. Creo que va encontra de la OOP, un ejemplo sencillo te podria ayudar a entender por que. La herencia se basa en que el hijo es del tipo del padre, pero el padre no es del tipo del hijo.Que quiero decir, imagina una clase poligono, y dos subclases rectangulo y triangulo. Ambas clases hijas son poligonos, pero el poligono no necesariamente es un triangulo. NO se si ayuda esta explicacion. Con esto lo que quiero expresar es que no vas a poder hacer lo que necesitas con las clases de pdf y sus extensiones.
Tal ves alguno piense distinto que yo, asi que seria bueno explicarse asi poder determinar feacientemente si se puede o no, lograr lo que quiere cluster.
Saludos

Última edición por MartinTandil; 30/03/2005 a las 08:03
  #20 (permalink)  
Antiguo 30/03/2005, 08:50
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 20 años, 6 meses
Puntos: 1
Cluster: Pongamoslo asi. Si has copiado y pegado metodos de verias extensiones para que trabajen juntos esos métodos. Supongo entonces que esos métodos manipulan la misma variable $content?, por ponerle de algún modo a la variable que va almacenando los datos?. Repito, ignoro detalles del código, pero creo que se puede alterar el comportamiento para que todas las extensiones actuen sobre la misma variable usando referencias. El tema es interesante, no creo esperar hasta el fin de semana, en la noche le doy una checada :)

MartinTandil: Mucho se ha hablado sobre las ventajas y desventajas de la herencia multiple, desde mi punto de vista personal, trae mas desventajas a largo plazo y conforme los proyectos crecen. Ahora, no creo que lo que plantee cluster vaya en contra de la OOP, cluster esta planteando un problema, no una implementación, ningún problema puede ir en contra de OOP, solo hay que encontrar la forma adecuada para solucionarlo.

Ojalá Jpinedo nos aporte su opinión pronto. Como ves la posibilidad de utilizar referencias para que todos los métodos de las distintas clases actuen sobre el mismo contenido?

saludos
  #21 (permalink)  
Antiguo 30/03/2005, 09:06
 
Fecha de Ingreso: marzo-2005
Mensajes: 163
Antigüedad: 19 años, 2 meses
Puntos: 0
Cita:
Iniciado por sism82
MartinTandil: Mucho se ha hablado sobre las ventajas y desventajas de la herencia multiple, desde mi punto de vista personal, trae mas desventajas a largo plazo y conforme los proyectos crecen. Ahora, no creo que lo que plantee cluster vaya en contra de la OOP, cluster esta planteando un problema, no una implementación, ningún problema puede ir en contra de OOP, solo hay que encontrar la forma adecuada para solucionarlo.
saludos
Seguramente me exprese mal y ofresco mis disculpas, no me queria referir a ir en contra de la OOP. Lo que queria notar es sobre el concepto de la herencia ya que el problema planteado habla de crear una instancia padre y que pueda ejecutar cualquier metodo de las instancias hijas, cuando conceptualmente es al reves. Se crean instancias de las clases hijas y se pueden ejecutar metodos del padre o de si misma solamente (Ya que tampoco se podrian ejecutar metodos de los hermanos). Igualmente este es un caso particular, ya que en general la herencia se plantea con clases abstractas para que cada hija implemente su comportamiento como le sea mas conveniente. Por otro lado, tampoco es visto el codigo de estas extensiones.Simplemente di mi punto de vista desde mi vago conocimiento de OOP. Tampoco estoy a favor o en contra de la herencia multiple, simplemente que es la solucion que requiere Cluster. Obviamente en vista de la no existencia de dicha herencia es necesario buscar otra alternativa.
Bueno, meti puro texto y ni una sola idea. Asi que mejor me voy a sentar a pensar asi puedo colaborar con esto en ves de hablar tanto.
Saludos
  #22 (permalink)  
Antiguo 30/03/2005, 10:26
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 4 meses
Puntos: 129
Cita:
Supongo entonces que esos métodos manipulan la misma variable $content?, por ponerle de algún modo a la variable que va almacenando los datos?.
Si, sisms82 así es como funcionan las classes hija .. como son un "extended" usan referencias "$this-> ...." así que todo funciona bien si hago un "cut-and-paste".

Por lo demás realmente sólo conozco de "oidas" los fundamentos de OOP (me confieso "usuario" de OOP sólo), por eso desconozco si teorícamente es correcto el planteamiento que solicito o no .. pero entiendo mas o menos lo que comentas MartinTandil sobre padres e hijos .. Tal vez no sea ese el termino a usar realmente ..

Un saludo,
  #23 (permalink)  
Antiguo 30/03/2005, 11:54
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 20 años, 6 meses
Puntos: 1
porpuesta

MartinTandil: me parece perfecto, hacen falta proponer mas solcuciones para llegar a la ideal.

Cluster:
voila....... a riesgo de volver a equivocarme (ojalá mas gente aporte equivocaciones :p para estar mas cerca de encontrar la solución), creo que lo único que hace falta es que todas las instancias manipulen la misma variable "$content" del padre. Creo que se soluciona sencillamente con una referencia. Cluster, lo que propongo a continuación no es optimo, pero considerando que en php4 todas las variables son publicas, tal vez puedas hacer lo siguiente. Por favor, revisen el código para ver si me equivoco :p. Desde luego puede haber mas cosas que necesiten compartirse, como por ejemplo métodos, pero de eso no se sabrá hasta checar el código de las extensiones.

Código PHP:
$pdf_extension_handler->LoadExtension('ClasePadre');
$pdf_extension_handler->LoadExtension('ClaseHijaUno');
$pdf_extension_handler->LoadExtension('ClaseHijaDos'); 
ahora bien, ya tenemos 3 instancias separadas. Suponiendo que la variable que deben compartir es ClasePadre::$Content, se podría tal vez hacer esto ??? la importancia radica en el método LoadExtension...

Código PHP:
final class FpdfExtensionsHandler
{
    const 
HANDLERS_DIRECTORY   'path/al/directorio/de/las/clases_extensiones/';
    private 
$extensions        = array();
    private 
$content_reference null;
    public  
$extension         null;
    
    public function 
__construct()
    {
        return 
true;
    }

    
/**
    * @return Bool
    * @param String $ExtensionName
    */
    
public function LoadExtension($ExtensionName)
    {
        
$extension_path self::HANDLERS_DIRECTORY.$ExtensionName
        
if ( file_exists($extension_path) && !class_exists($ExtensionName) )
        {
            include_once(
$extension_path);
            
$share_content = empty($this->extensions) ? false true//si ya se cargo un objeto, se debe compartir la variable content
            
$this->extensions[$ExtensionName] = new $ExtensionName();
            
$this->extension =& $this->extensions->[$ExtensionName]; //se genera una referencia al ultimo objeto instanciado
            //si se debe compartir el contenido, se reescribe la variable content del recien instanciado objeto
            
if ( $share_content )
            {
                 
//todas las instancias trabajaran sobre la misma referencia a content
                
$this->extension->content =& $this->content_reference;
            }
            else 
//de otra forma se inicializa la referencia a content
            
{
                
$this->content_reference $this->extension->content;
            }
            return 
true;
        }
        else
        {
            return 
false;
        }
    } 
    
    
/**
     * @return Bool
     * @param String $ExtensionName
     */
    
public function SetExtension($ExtensionName)
    {
        if ( 
array_key_exists($ExtensionName,$this->extensions) )
        {
            
$this->extension =& $this->extensions[$ExtensionName];
            return 
true;
        }
        else
        {
        return 
false;
        }
    }

ah por cierto, sorry, lo quitale las palabras de visibilidad a las variables y metodos (public, private etc), la costumbre :)
  #24 (permalink)  
Antiguo 30/03/2005, 12:29
 
Fecha de Ingreso: marzo-2005
Mensajes: 163
Antigüedad: 19 años, 2 meses
Puntos: 0
La verdad sism82, que me parece que deberia funcionar perfectamente. Lo unico que opino es que andaria bien si solamente la variable que modifican es la $content, si existiera otra variable de la clase padre que modifiquen los hijos se veran reflejados en la estructura de datos de ellos y no en la de todos como las modificaciones a $content. No se si me explico. En este caso la $content sera reemplazada por el $pages que utiliza la clase padre y sus hijos, con esto ya pueden todos los hijos escribir en la misma variable. Ahora, la clase FPDF tiene unas cuantas variables mas, cualquiera de ella que sea necesario que la modifique alguna de las clases hijas tienen que ser tambien compartida.
Realmente me parace una muy buena solucion.
Saludos
  #25 (permalink)  
Antiguo 30/03/2005, 12:49
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 4 meses
Puntos: 129
;( ... Como comenta MartinTandil, esta classe concreta "FPDF" trabaja con varias variables (disculpen la redundancia) ..

No se podría hacer una especie de "contendor" .. mm no sé como se obtienen todos las variables del objeto padre para pasarlas como "globales" a los hijos? .. Tal vez esto enrrede mucho más el tema (además que hablo sin mucho fundamento teórico al respecto). El objetivo sería "no tocar las classes hijas" (su código) tan sólo (ya que algo hay que hacer) usar el "FpdfExtensionsHandler" y usarlo como se propone.

Un saludo,
  #26 (permalink)  
Antiguo 30/03/2005, 19:01
Avatar de jpinedo
Colaborador
 
Fecha de Ingreso: septiembre-2003
Ubicación: Lima, Perú
Mensajes: 3.120
Antigüedad: 20 años, 7 meses
Puntos: 41
Bueno... creo que por ahí va la solución.
Supongo que lo que habrá que hacer es no sólo referenciar la variable "content" (que en fpdf debe ser "buffer" si no me equivoco), sino todos los atributos del padre.
Con esto estaríamos haciendo que todas las extensiones actúen sobre las mismas variables.
Como les dije, no puedo hacer pruebas... pero tal vez se puedan utilizar funciones como get_class_vars(). Aquí he reescrito la clase de sism82 para que se pueda utilizar con PHP4 y le he agregado la parte que refreencia a todos los atributos comunes. No sé si funcione.
Código PHP:
class FpdfExtensionsHandler
    var 
$_extensions_dir    'path/al/directorio/de/las/clases_extensiones/'
    var 
$extensions            = array();
    var 
$vars_ref            = array(); // Contiene referencias a los atributos comunes.
    
var $extension            null;

    
/** 
    * @return Bool 
    * @param String $ExtensionName 
    */ 
    
function LoadExtension($ExtensionName){
        
$extension_path $this->_extensions_dir.$ExtensionName 
        
if (file_exists($extension_path) && !class_exists($ExtensionName)){
            include_once(
$extension_path); 
            
$share_content = empty($this->extensions) ? false true//si ya se cargo un objeto, se debe compartir sus atributos
            
$this->extensions[$ExtensionName] = new $ExtensionName();
            
$this->extension =& $this->extensions->[$ExtensionName]; //se genera una referencia al ultimo objeto instanciado 
            //si se debe compartir el contenido, se reescribe la variable content del recien instanciado objeto 
            // Primero capturamos todos los atributos definidos en la clase.
            
$class_vars get_class_vars($ExtensionName);
            if (
$share_content){ 
                 
//todas las instancias trabajaran sobre los mismos atributos comunes
                
foreach($this->vars_ref as $var_name => $var_value){
                    if(
array_key_exists($var_name$class_vars))
                        
$this->extension->$var_name = & $this->vars_ref[$var_name];
                }
            }else{
                
//de otra forma se inicializan las referencia a los atributos
                
foreach ($class_vars as $var_name => $var_value){
                    
$this->vars_ref[$var_name] = & $this->extension->$var_name;
                }
            }
            return 
true;
        }else{
            return 
false;
        }
    }
    
    
/**
     * @return Bool
     * @param String $ExtensionName
     */ 
    
function SetExtension($ExtensionName){
        if ( 
array_key_exists($ExtensionName,$this->extensions) ){
            
$this->extension =& $this->extensions[$ExtensionName];
            return 
true;
        }else{
            return 
false;
        }
    }

Saludos
  #27 (permalink)  
Antiguo 30/03/2005, 23:45
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 20 años, 6 meses
Puntos: 1
parece que llegue algo tarde a la casa para escribir algo mas elaborado, aqui lo dejo. Cluster, ojala lo puedas probar, de antemano disculpas por algun error que se me haya pasado por ahi, pero esperemos que no

Código PHP:
/**
 * This class has as goal, allow to use different FPDF extensions. Its created to work under PHP4
 */
class FpdfExtensionsHandler
{

    
/**
     * FPDF main object
     * @var object class FPDF
     * @final
     * @access public
     */
    
var $fpdf                  null;
    
    
/**
     * save the variables of the FPDF class
     * @var Array
     * @final
     * @access private
     */
    
var $fpdf_vars             null;
    
    
/**
     * save references to the loaded extensions
     * @var Array
     * @final
     * @access private
     */
    
var $extensions_references = array();
    
    
/**
     * save the extensions vars
     * @var Array
     * @final
     * @access private
     */
    
var $extensions_vars       = array();
    
    
/**
     * default directory to search the extensions
     * @var String
     * @final
     * @accesss private
     */
    
var $default_extensions_dir './';
    
    
/**
     * here can pass as many arguments as needed for the Fpdf constructor
     * @return bool
     * @param Mixed $FpdfConstructorArugment1
     * @param Mixed $FpdfConstructorArugment2
     * @param Mixed $FpdfConstructorArugmentN...
     * @final
     * @access public
     */
    
function FpdfExtensionHandler()
    {
        if ( 
class_exists('FPDF') )
        {
            
//getting FPDF vars
            
$this->fpdf_vars get_class_vars('FPDF');
            
            
//create FPDF instance
            
$arguments        func_get_args();
            
$string_arguments "";
            foreach ( 
$arguments as $index => $argument )
            {
                
$string_arguments .= "\$arguments[$index], ";
            }
            
$string_arguments substr($string_arguments,0,strlen($string_arguments) - 2);
            
$eval_code        "\$this->fpdf = new FPDF({$string_arguments});";
            eval(
$eval_code);
            return 
true;
        }
        else
        {
            die(
"Missing class FPDF!");
        }
    }
    
    
/**
     * Try to load a new extension
     * @return bool
     * @param String $ExtensionName
     * @param String $ExtensionDirectory
     * @param Mixed $ExtensionConstructorArg1
     * @param Mixed $ExtensionConstructorArg2
     * @param Mixed $ExtensionConstructorArgN...
     * @final
     * @acces public
     */
    
function LoadExtension($ExtensionName$ExtensionDirectory null)
    {
        
$ExtensionName      = (string)$ExtensionName;
        
$ExtensionDirectory $ExtensionDirectory === null
                            
null
                            
: (string)$ExtensionDirectory;
        
$class_file  $ExtensionDirectory === null
                     
$this->default_extensions_dir.$ExtensionName
                     
$ExtensionDirectory.$ExtensionName;
        if ( 
file_exists($class_file) )
        {
            include_once 
$class_file;
            if ( !
class_exists($ExtensionName) )
            {
                die(
"Class '{$class_file}' does not exists in file '{$class_file}'!");
            }
            else
            {
                
//getting extension constructor arguments
                
$arguments   func_get_args();
                
$num_args    count($arguments);
                
$string_args "";
                for ( 
$i 2$i $num_args$i++ )
                {
                    
$string_args .= "\$arguments[$i], ";
                }
                
$string_args substr($string_args,0,strlen($string_args) - 2);
                
$eval_code "\$this->extensions_references[\$ExtensionName] =& new \$ExtensionName($string_args);"
                
eval($eval_code);
                if ( !
is_subclass_of($this->extensions_references[$ExtensionName], 'FPDF') )
                {
                    die(
"Class '{$ExtensionName}' is not a subclass of FPDF!");
                }
                else
                {
                    
$this->extensions_vars[$ExtensionName] = array();
                    
$this->extensions_vars[$ExtensionName] = get_class_vars($ExtensionName);
                    
$this->MergeExtensions();
                    return 
true;
                }
            }
        }
        else
        {
            die(
"Unable to open class file '{$class_file}'!");
        }
        
    }
    
    
/**
     * Merge the loaded extensions variables, so every instance will edit the same variables
     * @return bool
     * @param void
     * @final
     * @acces private
     */
    
function MergeExtensionsVars()
    {
        foreach ( 
$this->extensions_vars as $class_name => $class_vars )
        {
            foreach ( 
$class_vars as $variable_name )
            {
                if ( 
array_key_exists($variable_name$this->fpdf_vars) )
                {
                    
$this->extensions_references[$class_name]->$variable_name =& $this->fpdf->$variable_name;
                }
            }
        }
    }
    
    
/**
     * Change the default directory for extensions
     * @return bool
     * @param String $DirectoryName
     * @final
     * @acces public
     */
    
function SetDefaultExtensionDir($DirectoryName)
    {
        
$this->default_extensions_dir = (string)$DirectoryName;
        return 
true;
    }
    
    
/**
     * Change the working extension
     * @return bool
     * @param String $ExtensionName
     * @final
     * @acces public
     */
    
function SetExtension($ExtensionName)
    {
        
$ExtensionName = (string)$ExtensionName;
        if ( 
array_key_exists($ExtensionName) )
        {
            
$this->extension =& $this->extensions_references[$ExtensionName];
            return 
true;
        }
        {
            die(
"Extension '{$ExtensionName}' does not has been loaded yet!");
        }
        
    }
    
    

  #28 (permalink)  
Antiguo 31/03/2005, 10:28
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 4 meses
Puntos: 129
Estube probando ambas propuestas .. pero me faltó un pequeño detallito: un ejemplo completo de uso (instanciar principalmente)

Tampoco sé si he de modificar las actuales "classes" hijas que dispongo .. es decir, cada una de estas clases hijas actualmente hacen:

classs nombre_hija extended nombre_padre{
// sus métodos ... y variables ...
}

He de dejarlo sin el "extended nombre_padre" .. pues en teoría es el "handdler" el que ya gestiona eso? ...

Un saludo,
  #29 (permalink)  
Antiguo 31/03/2005, 10:59
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 4 meses
Puntos: 129
sism82

Intentando probar tu propuesta me topé con algunos problemas con el siguiente método:

Código PHP:
    /** 
     * Try to load a new extension 
     * @return bool 
     * @param String $ExtensionName 
     * @param String $ExtensionDirectory 
     * @param Mixed $ExtensionConstructorArg1 
     * @param Mixed $ExtensionConstructorArg2 
     * @param Mixed $ExtensionConstructorArgN... 
     * @final 
     * @acces public 
     */ 
    
function LoadExtension($ExtensionFile,$ExtensionName$ExtensionDirectory null
    { 
        
$ExtensionName      = (string)$ExtensionName
        
$ExtensionDirectory $ExtensionDirectory === null 
                            
null 
                            
: (string)$ExtensionDirectory
        
$class_file  $ExtensionDirectory === null 
                     
$this->default_extensions_dir.$ExtensionFile 
                     
$ExtensionDirectory.$ExtensionFile
                    
        if ( 
file_exists($class_file) ) 
        { 
            include_once 
$class_file
            if ( !
class_exists($ExtensionName) ) 
            { 
                die(
"Class '{$ExtensionName}' does not exists in file '{$class_file}'!"); 
            } 
            else 
            { 
                
//getting extension constructor arguments 
                
$arguments   func_get_args(); 
                
$num_args    count($arguments); 
                
$string_args ""
                for ( 
$i 2$i $num_args$i++ ) 
                { 
                    
$string_args .= "\$arguments[$i], "
                } 
                
$string_args substr($string_args,0,strlen($string_args) - 2); 
                
$eval_code "\$this->extensions_references[\$ExtensionName] =& new \$ExtensionName($string_args);";
                eval(
$eval_code); 
                if ( !
is_subclass_of($this->extensions_references[$ExtensionName], 'FPDF') ) 
                { 
                    die(
"Class '{$ExtensionName}' is not a subclass of FPDF!"); 
                } 
                else 
                { 
                    
$this->extensions_vars[$ExtensionName] = array(); 
                    
$this->extensions_vars[$ExtensionName] = get_class_vars($ExtensionName); 
                    
$this->MergeExtensionsVars(); 
                    return 
true
                } 
            } 
        } 
        else 
        { 
            die(
"Unable to open class file '{$class_file}'!"); 
        } 
         
    } 
Si te fijas .. tuve que agregar "$ExtensionFile" .. pues se estaba usando $ExtensionName tanto como nombre del archivo ".php" como el nombre de la classe que podría contener. No sé si es que se asumia que el nombre del archivo sería=al de la classe (sin .php ni nada más) .. Pero con esa modificación por lo menos por ahí no hay problemas.

También había otros detallitos que ahí están corregidos:
$this->MergeExtensions(); en lugar de $this->MergeExtensionsVars();

Pero a partir de ahí ya me asaltaron otro tipo de errores:
Warning: array_key_exists(): The second argument should be either an array or an object in ...
En el método MergeExtensionsVars()

Estoy usando la propuesta tipo:
Código PHP:
$pdf=new FpdfExtensionsHandler();
$pdf->SetDefaultExtensionDir($_SERVER['DOCUMENT_ROOT'].'/classes/fpdf/');
$pdf->LoadExtension('cabecera_pie.php','cabecera_pie');
$pdf->SetExtension('cabecera_pie'); 
Siendo cabecera_pie (la classe):

Código PHP:
<?
class cabecera_pie extends FPDF
{

//Cabecera de página
function Header()
{
    
//Logo    
    
$this->Image('../../img/logo.jpg',115,9,83);    
    
//Salto de línea
    
$this->Ln(10);
}

//Pie de página
function Footer()
{
    
    
$this->SetY(-15);
    
//Arial italic 8
    
$this->SetFont('Arial','I',10);
    
        
//$this->Ln(5);
    
$this->MultiCell(0,4,"Pie de página",0,'C');
}
}
?>

Un saludo,

Última edición por Cluster; 31/03/2005 a las 11:03
  #30 (permalink)  
Antiguo 31/03/2005, 11:13
Avatar de sism82  
Fecha de Ingreso: octubre-2003
Ubicación: Guadalajara
Mensajes: 865
Antigüedad: 20 años, 6 meses
Puntos: 1
si cluster. Los siguientes detalles son importantes:

- El nombre de la clase es FpdfExtensionsHandler, en plural 'extensions', a diferencia del constructor, asi que es posible que el constructor no se este ejecutando si no cambiaste ese detalle, y por lo tanto $this->fpdf_vars no se inicializa corectamente, por eso el error de array_key_exists.

- La variable $fpdf_vars esta inicializada en null en las declaraciones, debe ser array();

- La función array_key_exists del método SetExtension no tiene segundo argumento, el segundo argumento debe ser $this->extensions_references

saludos
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Tema Cerrado




La zona horaria es GMT -6. Ahora son las 02:23.