Hace unas semanas publiqué en mi blog una experiencia extraña que tuve con PHP5 y la orientación a objetos.
Básicamente, se trata de un problema de la herencia y el polimorfismo. Por un au otra razón, me vi en la necesidad de obtener información sobre la clase que definía a un objeto. Entonces se me ocurrió implementar métodos en estas clases que retornaran la información que necesitaba.
Para efectos simples, supongamos que tengo 2 clases, Papa e Hijo, más un archivo de pruebas.
Algo así:
Dad.php
Código PHP:
<?php
class Dad {
const NAME = 'Papi';
// Magic Method to access a class constant
private function __get($name)
{
if(defined("self::$name"))
{
return constant("self::$name");
}
trigger_error ("$name isn't defined");
}
public function myFile()
{
return __FILE__ ;
}
public function myClass()
{
return __CLASS__;
}
public function myName()
{
$me = new self;
return get_class($me);
}
}
Child.php
Código PHP:
<?php
require_once 'Dad.php' ;
class Child extends Dad
{
const NAME = 'Hijo';
public function myFile()
{
return __FILE__;
}
}
test.php
Código PHP:
<?php
require_once 'Child.php' ;
require_once 'Dad.php' ;
$dad = new Dad();
$child = new Child();
echo '<h1>Class Constants</h1>';
echo '<p>' . var_dump($dad->NAME) . '</p>';
echo '<p>' . var_dump($child->NAME) . '</p>';
echo '<h1>File</h1>';
echo '<p>' . var_dump($dad->myFile()) . '</p>';
echo '<p>' . var_dump($child->myFile()) . '</p>';
echo '<h1>Class Name</h1>';
echo '<p>' . var_dump($dad->myClass()) . '</p>';
echo '<p>' . var_dump($child->myClass()) . '</p>';
echo '<h1>Class Name of an Object</h1>';
echo '<p>' . var_dump($dad->myName()) . '</p>';
echo '<p>' . var_dump($child->myName()) . '</p>';
OK. ¿Donde está el problema?
Al ejecutar test.php, me di cuenta que, ninguna de las constantes especiales
__FILE__ o
__CLASS__, ni
$this, ni
self retornaron el resultado esperado.
Si llamaba los métodos desde la clase hija, seguían comportándose como si se estuvieran llamando desde la clase padre, EXCEPTO si redefinía en la clase hija el mismo método, con el mismo código.
No se si esto es un "bug" o es la implementación habitual de OOP en PHP5, pero hasta ahora, me ha pasado lo mismo en distintas versiones de PHP5 (no he probado en PHP4).
¿Ustedes que creen? ¿Será algo que deba cambiarse en el futuro PHP6?