You are on page 1of 53

Clases y Objetos

Pgina 1 de 53

Funciones annimas

Referencia del lenguaje PHP Manual

Introduccin

Clases y Objetos
Tabla de contenidos
Introduccin Lo bsico Propiedades Constantes de Clases Auto-carga de Clases Constructores y destructores Visibilidad Herencia de Objetos Operador de Resolucin de mbito (::) Palabra Clave Static Abstraccin de clases Interfaces de objetos Traits Sobrecarga Iteracin de objetos Mtodos mgicos Palabra clave Final Clonacin de Objetos Comparacin de Objetos Implicacin de Tipos Enlace esttico en tiempo de ejecucin Objetos y referencias Serializacin de objetos Registro de cambios de POO Referencia del lenguaje PHP Manual Clases y Objetos PHP Manual Introduccin Lo bsico

Funciones annimas Clases y Objetos

Introduccin
A partir de PHP 5, el modelo de objetos ha sido reescrito para permitir un mejor rendimiento y con ms caractersticas. Este fue un cambio importante a partir de PHP 4. PHP 5 tiene un modelo de objetos completo. Entre las caractersticas de PHP 5 estn la inclusin de la visibilidad, las clases abstractas y clases y mtodos finales, mtodos mgicos adicionales, interfaces, clonacin y tipos sugeridos. PHP trata los objetos de la misma manera como referencias o manejadores, lo que significa que cada variable contiene una referencia de objeto en lugar de una copia de todo el objeto. Ver objetos y referencias

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 2 de 53

Sugerencia Vea tambin Guia de Entorno de Usuario para Nombres. Clases y Objetos Introduccin Clases y Objetos PHP Manual Clases y Objetos PHP Manual Lo bsico Propiedades

Lo bsico
class
La definicin bsica de clases comienza con la palabra clave class, seguido por un nombre de clase, continuado por un par de llaves que encierran las definiciones de las propiedades y mtodos pertenecientes a la clase. El nombre de clase puede ser cualquier etiqueta vlida que no sea una palabra reservada de PHP. Un nombre vlido de clase comienza con una letra o un guin bajo, seguido de la cantidad de letras, nmeros o guiones bajos que sea. Como una expresin regular, se expresara de la siguiente forma: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*. Una clase puede tener sus propias constantes, variables (llamadas "propiedades"), y funciones (llamadas "mtodos"). Ejemplo #1 Definicin simple de una clase
<?php class SimpleClass { // Declaracin de la propiedad public $var = 'a default value'; // Declaracin del mtodo public function displayVar() { echo $this->var; } } ?>

La pseudo-variable $this est disponible cuando un mtodo es invocado dentro del contexto de un objeto. $this es una referencia del objeto que invoca (usualmente el objeto al que el mtodo pertenece, pero posiblemente sea otro objeto, si el mtodo es llamado estticamente desde el contexto de un objeto secundario). Ejemplo #2 Algunos ejemplo de la pseudo-variable $this
<?php class A { function foo() { if (isset($this)) { echo '$this est definida ('; echo get_class($this); echo ")\n"; } else {

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 3 de 53

echo "\$this no est definida.\n"; } } } class B { function bar() { // Nota: la siguiente lnea arrojar un Warning si E_STRICT est habilitada. A::foo(); } } $a = new A(); $a->foo(); // Nota: la siguiente lnea arrojar un Warning si E_STRICT est habilitada. A::foo(); $b = new B(); $b->bar(); // Nota: la siguiente lnea arrojar un Warning si E_STRICT est habilitada. B::bar(); ?>

El resultado del ejemplo sera:


$this $this $this $this est definida (A) no est definida. est definida (B) no est definida.

new
Para crear una instancia de una clase, la palabra clave new debe ser usada. Un objeto siempre se crear a menos que el objeto tenga un constructor que arroje una excepcin en caso de error. Las clases deberan ser definidas antes de la instanciacin (y en algunos casos esto es un requerimiento). Si un string que contiene el nombre de una clase se usa con new, una nueva instancia de esa clase ser creada. Si la clase est en un espacio de nombres, su nombre completo debe ser usado cuando se hace esto. Ejemplo #3 Creacin de una instancia
<?php $instance = new SimpleClass(); // Esto tambin se puede hacer con variables: $className = 'Foo'; $instance = new $className(); // Foo() ?>

En el contexto de una clase, es posible crear un nuevo objeto con new self y new parent. Cuando se asigna una instancia de una clase ya creada a una nueva variable, sta ltima acceder a la misma instancia como al objeto que le fue asignado. Esta conducta es la misma cuando se pasan instancias a una funcin. Una copia de un objeto ya creado se puede lograr a travs de la clonacin de la misma.

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 4 de 53

Ejemplo #4 Asignacin de objetos


<?php $instance = new SimpleClass(); $assigned $reference = $instance; =& $instance;

$instance->var = '$assigned tendr este valor'; $instance = null; // $instance y $reference se transforman en null var_dump($instance); var_dump($reference); var_dump($assigned); ?>

El resultado del ejemplo sera:


NULL NULL object(SimpleClass)#1 (1) { ["var"]=> string(30) "$assigned tendr este valor" }

PHP 5.3.0 introdujo un par de nuevas maneras para crear instancias de un objeto: Ejemplo #5 Creando nuevos objetos
<?php class Test { static public function getNew() { return new static; } } class Child extends Test {} $obj1 = new Test(); $obj2 = new $obj1; var_dump($obj1 !== $obj2); $obj3 = Test::getNew(); var_dump($obj3 instanceof Test); $obj4 = Child::getNew(); var_dump($obj4 instanceof Child); ?>

El resultado del ejemplo sera:


bool(true) bool(true) bool(true)

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 5 de 53

extends
Una clase puede heredar los mtodos y propiedades de otra clase al utilizar la palabra clave extends en la declaracin de la clase. No es posible extender mltiples clases; una clase slo puede heredar de una clase base. Los mtodos y propiedades heredados pueden ser sobrescritos con la redeclaracin de stos utilizando el mismo nombre que en la clase parent. Sin embargo, si la clase parent defini un mtodo como final, ste no podr ser sobrescrito. Es posible acceder a los mtodos sobrescritos o propiedades estticas referencindolos con parent::. Cuando se sobrescriben mtodos, la cantidad y disposicin de los parmetros debera ser la misma o PHP generar un error a nivel de E_STRICT. Esto no se aplica a los constructores, que permiten la sobrescritura con diferentes parmetros. Ejemplo #6 Herencia simple de clases
<?php class ExtendClass extends SimpleClass { // Redefinicin del mtodo parent function displayVar() { echo "Clase extendida\n"; parent::displayVar(); } } $extended = new ExtendClass(); $extended->displayVar(); ?>

El resultado del ejemplo sera:


Clase extendida un valor por defecto

Introduccin Lo bsico

Clases y Objetos PHP Manual Clases y Objetos PHP Manual

Propiedades Constantes de Clases

Propiedades
Las variables pertenecientes a clases son llamadas "propiedades". Tambin se les puede referir usando otros trminos como "atributos" o "campos", pero para los propsitos de esta referencia vamos a utilizar "propiedades". stas se definen usando una de las palabras claves public, protected, o private, seguido por una declaracin normal de variable. Esta declaracin puede incluir una inicializacin, pero esta inicializacin debe ser un valor constante, es decir, debe tener la capacidad de ser evaluada en la compilacin y no debe depender de informacin en tiempo de ejecucin para ser evaluada. Vea Visibilidad para ms informacin sobre que significan public, protected, y private. Nota:

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 6 de 53

Con el fin de mantener la compatibilidad con PHP 4, PHP 5 continuar aceptando el uso de la palabra clave var en la declaracin de propiedades en lugar de (o adems de) public, protected, o private. Sin embargo, var ya no se requiere ms. Entre las versiones 5.0 y 5.1.3 de PHP, el uso de var fue considerado obsoleto y emitir un Warning E_STRICT, pero a partir de PHP 5.1.3 no est ms obsoleta y no emitir la advertencia. Si declara una propiedad utilizando var en lugar de public, protected, o private, entonces PHP tratar dicha propiedad como si hubiera sido definida como public. Dentro de los mtodos de clase, las propiedades, constantes y mtodos pueden ser accedidos a travs de $this->property (donde property es el nombre de la propiedad) a menos que el acceso sea a una propiedad esttica dentro del contexto de un mtodo de clase esttico, en cuyo caso sera accedida usando self::$property. Vea Static para ms informacin. La pseudo-variable $this est disponible dentro de cualquier mtodo de clase cuando ste es invocado dentro del contexto de un objeto. $this es una referencia del objeto que invoca (usualmente el objeto al que el mtodo pertenece, pero posiblemente sea otro objeto, si el mtodo es llamado estticamente desde el contexto de un objeto secundario). Ejemplo #1 Declaracin de propiedades
<?php class SimpleClass { // Declaraciones invlida de propiedades: public $var1 = 'hola ' . 'mundo'; public $var2 = <<<EOD hola mundo EOD; public $var3 = 1+2; public $var4 = self::myStaticMethod(); public $var5 = $myVar; // Declaraciones vlida de propiedades: public $var6 = myConstant; public $var7 = array(true, false); // Esto se permite slo en PHP 5.3.0 y superiores. public $var8 = <<<'EOD' hola mundo EOD; } ?>

Nota: Existen varias funciones interesantes para manipular clases y objetos. Quiz le interese echar un vistazo a las Funciones de Clases/Objetos. A diferencia de heredocs, nowdocs puede ser utilizado en cualquier contexto de datos estticos, incluyendo declaracin de propiedades. Ejemplo #2 Ejemplo del uso de nowdoc para inicializar una propiedad
<?php class foo { // A partir de PHP 5.3.0 public $bar = <<<'EOT' bar

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 7 de 53

EOT; } ?>

Nota: El soporte nowdoc fue agregado en PHP 5.3.0. Lo bsico Propiedades Clases y Objetos PHP Manual Clases y Objetos PHP Manual Constantes de Clases Auto-carga de Clases

Constantes de Clases
Es posible definir valores constantes en funcin de cada clase mantenindola invariable. Las constantes se diferencian de variables comunes en que no utilizan el smbolo $ al declararlas o usarlas. El valor debe ser una expresin constante, no (por ejemplo) una variable, una propiedad, un resultado de una operacin matemtica, o una llamada a una funcin. Tambin es posible para las interfaces tener constantes. Ver la documentacin de interfaces para ejemplos. A partir de PHP 5.3.0, es posible hacer referencia a una clase utilizando una variable. El valor de la variable no puede ser una palabra clave (por ej., self, parent y static). Ejemplo #1 Definicin y uso de una constante
<?php class MyClass { const constant = 'valor constante'; function showConstant() { echo self::constant . "\n"; } } echo MyClass::constant . "\n"; $classname = "MyClass"; echo $classname::constant . "\n"; // A partir de PHP 5.3.0 $class = new MyClass(); $class->showConstant(); echo $class::constant."\n"; // A partir de PHP 5.3.0 ?>

Ejemplo #2 Ejemplo de datos estticos


<?php class foo { // A partir de PHP 5.3.0 const bar = <<<'EOT' bar

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 8 de 53

EOT; } ?>

A diferencia de heredocs, nowdocs puede ser utilizado en cualquier contexto de datos estticos. Nota: El soporte nowdoc fue agregado en PHP 5.3.0. Propiedades Constantes de Clases Clases y Objetos PHP Manual Clases y Objetos PHP Manual Auto-carga de Clases Constructores y destructores

Auto-carga de Clases
Muchos desarrolladores que escriben aplicaciones orientadas a objetos crean un archivo fuente PHP para cada definicin de clase. Una de las mayores molestias es tener que hacer una larga lista de includes al comienzo de cada script (uno por cada clase). En PHP 5, esto ya no es ms necesario. Se puede definir una funcin __autoload() la cual es automticamente invocada en caso de que est intentando utilizar una clase/interfaz que todava no haya sido definida. Al invocar a esta funcin el motor de scripting est dando una ltima oportunidad de cargar la clase antes que PHP falle con un error. Sugerencia spl_autoload_register() proporciona una alternativa ms flexible para la carga automtica de clases. Por esta razn, el uso de __autoload() no se recomienda y puede ser obsoleta o eliminada en el futuro. Nota: Antes de 5.3.0, las excepciones lanzadas en la funcin __autoload no podan ser capturadas en el bloque catch y eso resultaba en un error fatal. Desde 5.3.0+ las excepciones lanzadas en la funcin __autoload pueden ser capturadas en el bloque catch, con 1 disposicin. Si se lanza una excepcin personalizada, entonces la clase de excepcin personalizada debe estar disponible. La funcin __autoload puede ser usada recursivamente para auto-cargar la clase de excepcin personalizada. Nota: La auto-carga no est disponible si utiliza PHP en modo interactivo CLI. Nota: Si el nombre de la clase es usado, por ejemplo, en call_user_func() entonces puede contener algunos caracteres peligrosos tal como ../. Se recomienda no utilizar la entrada del usuario en tales funciones o al menos verifique dicha entrada en __autoload(). Ejemplo #1 Ejemplo de auto-carga

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 9 de 53

Este ejemplo intenta cargar las clases MyClass1 y MyClass2 de los archivos MyClass1.php y MyClass2.php respectivamente.
<?php function __autoload($class_name) { include $class_name . '.php'; } $obj = new MyClass1(); $obj2 = new MyClass2(); ?>

Ejemplo #2 Otro ejemplo de auto-carga Este ejemplo intenta cargar la interfaz ITest.
<?php function __autoload($name) { var_dump($name); } class Foo implements ITest { } /* string(5) "ITest" Fatal error: Interface 'ITest' not found in ... */ ?>

Ejemplo #3 Auto-carga con manejo de excepciones para 5.3.0+ Este ejemplo lanza una excepcin y demuestra los bloques try/catch.
<?php function __autoload($name) { echo "Intentando cargar $name.\n"; throw new Exception("Imposible cargar $name."); } try { $obj = new NonLoadableClass(); } catch (Exception $e) { echo $e->getMessage(), "\n"; } ?>

El resultado del ejemplo sera:


Intentando cargar NonLoadableClass. Imposible cargar NonLoadableClass.

Ejemplo #4 Auto-carga con manejo de excepciones para 5.3.0+ - Omitiendo excepcin personalizada Este ejemplo lanza una excepcin para una excepcin personalizada no cargable.
<?php function __autoload($name) { echo "Intentando cargar $name.\n";

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 10 de 53

throw new MissingException("Imposible cargar $name."); } try { $obj = new NonLoadableClass(); } catch (Exception $e) { echo $e->getMessage(), "\n"; } ?>

El resultado del ejemplo sera:


Intentando cargar NonLoadableClass. Intentando cargar MissingException. Fatal error: Class 'MissingException' not found in testMissingException.php on line 4

Ver tambin
unserialize() unserialize_callback_func spl_autoload() spl_autoload_register() Clases y Objetos PHP Manual Clases y Objetos PHP Manual Constructores y destructores Visibilidad

Constantes de Clases Auto-carga de Clases

Constructores y destructores
Constructor
void __construct ([ mixed $args [, $... ]] ) PHP 5 permite a los desarrolladores declarar mtodos constructores para las clases. Aquellas que tengan un mtodo constructor lo invocarn en cada nuevo objeto creado, lo que lo hace idneo para cualquier inicializacin que el objeto pueda necesitar antes de ser usado. Nota: Constructores parent no son llamados implcitamente si la clase child define un constructor. Para ejecutar un constructor parent, se requiere invocar a parent::__construct() desde el constructor child. Ejemplo #1 Utilizacin de nuevos constructores unificados
<?php class BaseClass { function __construct() { print "En el constructor de BaseClass\n"; } } class SubClass extends BaseClass { function __construct() { parent::__construct(); print "En el constructor de SubClass\n"; }

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 11 de 53

} $obj = new BaseClass(); $obj = new SubClass(); ?>

Por motivos de compatibilidad, si PHP 5 no puede encontrar una funcin __construct() para una determinada clase, buscar el viejo estilo de la funcin constructora, mediante el nombre de la clase. Efectivamente, esto significa que en el nico caso en el que se tendra compatibilidad es si la clase tiene un mtodo llamado __construct() que fuese utilizado para diferentes propsitos. A diferencia con otros mtodos, PHP no generar un mensaje de error a nivel de E_STRICT cuando __construct() es sobrescrito con diferentes parmetros que los mtodos padre __construct() tienen. A partir de PHP 5.3.3, los mtodos con el mismo nombre que el ltimo elemento de una clase en un nombre de espacios no sern ms tratados como un constructor. Este cambio no afecta a clases sin espacio de nombres. Ejemplo #2 Constructores en clases pertenecientes a un nombre de espacios
<?php namespace Foo; class Bar { public function Bar() { // Tratado como constructor en PHP 5.3.0 - 5.3.2 // Tratado como mtodo regular a partir de PHP 5.3.3 } } ?>

Destructor
void __destruct ( void ) PHP 5 introduce un concepto de destructor similar al de otros lenguajes orientados a objetos, tal como C++. El mtodo destructor ser llamado tan pronto como no hayan otras referencias a un objeto determinado, o en cualquier otra circunstancia de finalizacin. Ejemplo #3 Ejemplo de Destructor
<?php class MyDestructableClass { function __construct() { print "En el constructor\n"; $this->name = "MyDestructableClass"; } function __destruct() { print "Destruyendo " . $this->name . "\n"; } } $obj = new MyDestructableClass(); ?>

Como los constructores, los destructores padre no sern llamados implcitamente por el motor. Para ejecutar un destructor padre, se deber llamar explcitamente a parent::__destruct() en el interior del destructor.

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 12 de 53

El destructor ser invocado an si la ejecucin del script es detenida usando exit(). Llamar a exit() en un destructor evitar que se ejecuten las rutinas restantes de finalizacin. Nota: Los destructores invocados durante la finalizacin del script tienen los headers HTTP ya enviados. El directorio de trabajo en la fase de finalizacin del script puede ser diferente con algunos SAPIs (por ej., Apache). Nota: Intentar lanzar una excepcin desde un destructor (invocado en la finalizacin del script) causa un error fatal. Auto-carga de Clases Constructores y destructores Clases y Objetos PHP Manual Clases y Objetos PHP Manual Visibilidad Herencia de Objetos

Visibilidad
La visibilidad de una propiedad o mtodo se puede definir anteponiendo una de las palabras claves public, protected o private en la declaracin. Miembros de clases declarados como public pueden ser accedidos de cualquier lado. Miembros declarados como protected, slo de la clase misma, por herencia y clases parent. Aquellos definidos como private, nicamentede la clase que los defini.

Visibilidad de Propiedades
Las propiedades de clases deben ser definidas como public, private, o protected. Si se declaran usando var, sern definidas como public. Ejemplo #1 Declaracin de propiedades
<?php /** * Definicin de MyClass */ class MyClass { public $public = 'Public'; protected $protected = 'Protected'; private $private = 'Private'; function { echo echo echo } } $obj = new MyClass(); echo $obj->public; // Funciona echo $obj->protected; // Error Fatal echo $obj->private; // Error Fatal $obj->printHello(); // Muestra Public, Protected y Private printHello() $this->public; $this->protected; $this->private;

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 13 de 53

/** * Definicin de MyClass2 */ class MyClass2 extends MyClass { // Se puede redeclarar los mtodos public y protected, pero no el private protected $protected = 'Protected2'; function { echo echo echo } } $obj2 = new MyClass2(); echo $obj2->public; // Funciona echo $obj2->private; // Undefined echo $obj2->protected; // Error Fatal $obj2->printHello(); // Muestra Public, Protected2, Undefined ?> printHello() $this->public; $this->protected; $this->private;

Nota: La forma de declaracin de una variable de PHP 4 con la palabra clave var todava es soportado (como un sinnimo de public) por razones de compatibilidad. En PHP 5 antes de 5.1.3, su uso genera un Warning E_STRICT.

Visibilidad de Mtodos
Los mtodos de clases pueden ser definidos como public, private, o protected. Aquellos declarados sin ninguna palabra clave de visibilidad explcita sern definidos como public. Ejemplo #2 Declaracin de mtodos
<?php /** * Definicin de MyClass */ class MyClass { // Declaracin de un constructor public public function __construct() { } // Declaracin de un mtodo public public function MyPublic() { } // Declaracin de un mtodo protected protected function MyProtected() { } // Declaracin de un mtodo private private function MyPrivate() { } // Esto es public function Foo() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); } }

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 14 de 53

$myclass = new MyClass; $myclass->MyPublic(); // Funciona $myclass->MyProtected(); // Error Fatal $myclass->MyPrivate(); // Error Fatal $myclass->Foo(); // Public, Protected y Private funcionan /** * Definicin de MyClass2 */ class MyClass2 extends MyClass { // Esto es public function Foo2() { $this->MyPublic(); $this->MyProtected(); $this->MyPrivate(); // Error Fatal } } $myclass2 = new MyClass2; $myclass2->MyPublic(); // Funciona $myclass2->Foo2(); // Public y Protected funcionan, pero Private no class Bar { public function test() { $this->testPrivate(); $this->testPublic(); } public function testPublic() { echo "Bar::testPublic\n"; } private function testPrivate() { echo "Bar::testPrivate\n"; } } class Foo extends Bar { public function testPublic() { echo "Foo::testPublic\n"; } private function testPrivate() { echo "Foo::testPrivate\n"; } } $myFoo = new foo(); $myFoo->test(); // Bar::testPrivate // Foo::testPublic ?>

Visibilidad desde otros objetos


Los objetos del mismo tipo tendrn acceso a los miembros private y protected entre ellos aunque no sean de la misma instancia. Esto es porque los detalles especficos de implementacin ya se conocen cuando se encuentra dentro de estos objetos.

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 15 de 53

Ejemplo #3 Accediendo a miembros private del mismo tipo de objeto


<?php class Test { private $foo; public function __construct($foo) { $this->foo = $foo; } private function bar() { echo 'Mtodo private accedido.'; } public function baz(Test $other) { // Se puede cambiar la propiedad private: $other->foo = 'hola'; var_dump($other->foo); // Tambin se puede invocar al mtodo private: $other->bar(); } } $test = new Test('test'); $test->baz(new Test('other')); ?>

El resultado del ejemplo sera:


string(5) "hola" Mtodo private accedido.

Constructores y destructores Visibilidad

Clases y Objetos Herencia de Objetos PHP Manual Clases y Objetos Operador de Resolucin de mbito (::) PHP Manual

Herencia de Objetos
La herencia es un principio de programacin bien establecido y PHP hace uso de l en su modelado de objetos. Este principio afectar la manera en que muchas clases y objetos se relacionan unas con otras. Por ejemplo, cuando se extiende una clase, la subclase hereda todos los mtodos pblicos y protegidos de la clase padre. A menos que una clase sobrescriba esos mtodos, mantendrn su funcionalidad original. Esto es til para la definicin y abstraccin de la funcionalidad y permite la implementacin de funcionalidad adicional en objetos similares sin la necesidad de reimplementar toda la funcionalidad compartida. Nota:

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 16 de 53

A menos que la carga automtica sea utilizada, entonces las clases deben ser definidas antes de ser usadas. Si una clase se extiende a otra, entonces la clase padre debe ser declarada antes de la estructura de clase hija. Esta regla se aplica a las clases que heredan de otras clases e interfaces. Ejemplo #1 Ejemplo de herencia
<?php class foo { public function printItem($string) { echo 'Foo: ' . $string . PHP_EOL; } public function printPHP() { echo 'PHP is great.' . PHP_EOL; } } class bar extends foo { public function printItem($string) { echo 'Bar: ' . $string . PHP_EOL; } } $foo = new foo(); $bar = new bar(); $foo->printItem('baz'); $foo->printPHP(); $bar->printItem('baz'); $bar->printPHP(); ?>

// // // //

Salida: Salida: Salida: Salida:

'Foo: baz' 'PHP is great' 'Bar: baz' 'PHP is great'

Visibilidad Herencia de Objetos

Clases y Objetos Operador de Resolucin de mbito (::) PHP Manual Clases y Objetos Palabra Clave Static PHP Manual

Operador de Resolucin de mbito (::)


El Operador de Resolucin de mbito (tambin denominado Paamayim Nekudotayim) o en trminos simples, el doble dos-puntos, es un token que permite acceder a elementos estticos, constantes, y sobrescribir propiedades o mtodos de una clase. Cuando se hace referencia a estos items desde el exterior de la definicin de la clase, se utiliza el nombre de la clase. A partir de PHP 5.3.0, es posible hacer referencia a una clase usando una variable. El valor de la variable no puede ser una palabra clave (por ej., self, parent y static).

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 17 de 53

Paamayim Nekudotayim podra, en un principio, parecer una extraa eleccin para bautizar a un doble dos-puntos. Sin embargo, mientras se escriba el Zend Engine 0.5 (que utiliz PHP 3), asi es como el equipo Zend decidi bautizarlo. En realidad, significa doble dos-puntos - en Hebreo! Ejemplo #1 :: desde el exterior de la definicin de la clase
<?php class MyClass { const CONST_VALUE = 'Un valor constante'; } $classname = 'MyClass'; echo $classname::CONST_VALUE; // A partir de PHP 5.3.0 echo MyClass::CONST_VALUE; ?>

Las tres palabras claves especiales self, parent y static son utilizadas para acceder a propiedades y mtodos desde el interior de la definicin de la clase. Ejemplo #2 :: desde el interior de la definicin de la clase
<?php class OtherClass extends MyClass { public static $my_static = 'variable esttica'; public static function doubleColon() { echo parent::CONST_VALUE . "\n"; echo self::$my_static . "\n"; } } $classname = 'OtherClass'; echo $classname::doubleColon(); // A partir de PHP 5.3.0 OtherClass::doubleColon(); ?>

Cuando una clase extendida sobrescribe la definicin parent de un mtodo, PHP no invocar al mtodo parent. Depende de la clase extendida el hecho de llamar o no al mtodo parent. Esto tambin se aplica a definiciones de mtodos Constructores y Destructores, Sobrecarga, y Mgicos. Ejemplo #3 Invocando a un mtodo parent
<?php class MyClass { protected function myFunc() { echo "MyClass::myFunc()\n"; } } class OtherClass extends MyClass { // Sobrescritura de definicin parent public function myFunc() { // Pero todava se puede llamar a la funcin parent parent::myFunc(); echo "OtherClass::myFunc()\n"; }

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 18 de 53

} $class = new OtherClass(); $class->myFunc(); ?>

Vase tambin algunos ejemplos de trucos de llamadas estticas . Herencia de Objetos Clases y Objetos PHP Manual Operador de Resolucin de mbito (::) Clases y Objetos PHP Manual Palabra Clave Static Abstraccin de clases

Palabra Clave Static


Declarar propiedades o mtodos de clases como estticos los hacen accesibles sin necesidad de una instanciacin de la clase. Una propiedad declarada como static no puede ser accedida con un objeto de clase instanciado (pero s se puede con mtodos estticos). Por motivos de compatibilidad con PHP 4, si no se utiliza ninguna declaracin de visibilidad, se tratar a las propiedades o mtodos como si hubiesen sido definidos como public. Debido a que los mtodos estticos se pueden invocar sin tener creada una instancia del objeto, la pseudo-variable $this no est disponible dentro de los mtodos declarados como static. Las propiedades estticas no pueden ser accedidas a travs del objeto utilizando el operador flecha (->). Invocar mtodos no estticos estticamente genera un Warning a nivel de E_STRICT. Como cualquier otra variable esttica en PHP, las propiedades estticas slo pueden ser inicializadas utilizando una string literal o una constante; las expresiones no estn permitidas. Por tanto, puede inicializar una propiedad esttica con enteros o arrays (por ejemplo), pero no puede hacerlo con otra variable, con el valor de devolucin de una funcin, o con un objeto. A partir de PHP 5.3.0, es posible hacer referencia a una clase usando una variable. El valor de la variable no puede ser una palabra clave (por ej., self, parent y static). Ejemplo #1 Ejemplo de propiedad esttica
<?php class Foo { public static $my_static = 'foo'; public function staticValue() { return self::$my_static; } } class Bar extends Foo { public function fooStatic() { return parent::$my_static; } }

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 19 de 53

print Foo::$my_static . "\n"; $foo = new Foo(); print $foo->staticValue() . "\n"; print $foo->my_static . "\n";

// Undefined "Property" my_static

print $foo::$my_static . "\n"; $classname = 'Foo'; print $classname::$my_static . "\n"; // A partir de PHP 5.3.0 print Bar::$my_static . "\n"; $bar = new Bar(); print $bar->fooStatic() . "\n"; ?>

Ejemplo #2 Ejemplo de mtodo esttico


<?php class Foo { public static function aStaticMethod() { // ... } } Foo::aStaticMethod(); $classname = 'Foo'; $classname::aStaticMethod(); // A partir de PHP 5.3.0 ?>

Operador de Resolucin de mbito (::) Palabra Clave Static

Clases y Objetos PHP Manual Clases y Objetos PHP Manual

Abstraccin de clases Interfaces de objetos

Abstraccin de clases
PHP 5 introduce clases y mtodos abstractos. Las clases definidas como abstract seguramente no son instanciadas y cualquier clase que contiene almenos un mtodo abstracto debe ser definida como abstract. Los mtodos definidos como abstractos simplemente declaran la estructura del mtodo, pero no pueden definir la implementacin. Cuando se hereda de una clase abstracta, todos los mtodos definidos como abstract en la definicin de la clase parent deben ser redefinidos en la clase child; adicionalmente, estos mtodos deben ser definidos con la misma visibilidad (o con una menos restrictiva). Por ejemplo, si el mtodo abstracto est definido como protected, la implementacin de la funcin puede ser redefinida como protected o public, pero nunca como private. Por otra parte, las estructuras de los mtodos tienen que coincidir, es decir, los (type hinting) tipos sugeridos y el nmero de argumentos requeridos deben ser los mismos. Esto tambin aplica a los constructores de PHP 5.4. Antes de PHP 5.4 las estructuras del constructor podan ser diferentes. Ejemplo #1 Ejemplo de clase abstracta
<?php abstract class AbstractClass { // Forzando la extensin de clase para definir este mtodo abstract protected function getValue(); abstract protected function prefixValue($prefix);

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 20 de 53

// Mtodo comn public function printOut() { print $this->getValue() . "\n"; } } class ConcreteClass1 extends AbstractClass { protected function getValue() { return "ConcreteClass1"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass1"; } } class ConcreteClass2 extends AbstractClass { public function getValue() { return "ConcreteClass2"; } public function prefixValue($prefix) { return "{$prefix}ConcreteClass2"; } } $class1 = new ConcreteClass1; $class1->printOut(); echo $class1->prefixValue('FOO_') ."\n"; $class2 = new ConcreteClass2; $class2->printOut(); echo $class2->prefixValue('FOO_') ."\n"; ?>

El resultado del ejemplo sera:


ConcreteClass1 FOO_ConcreteClass1 ConcreteClass2 FOO_ConcreteClass2

Cdigos antiguos que no tengan clases o funciones definidas por el usuario llamadas 'abstract' deberan ejecutarse sin modificaciones. Palabra Clave Static Abstraccin de clases Clases y Objetos PHP Manual Clases y Objetos PHP Manual Interfaces de objetos Traits

Interfaces de objetos
Las interfaces de objetos permiten crear cdigo con el cual especificamos qu mtodos deben ser implementados por una clase, sin tener que definir cmo estos mtodos son manipulados.

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 21 de 53

Las interfaces son definidas utilizando la palabra clave interface, de la misma forma que con clases estndar, pero sin mtodos que tengan su contenido definido. Todos los mtodos declarados en una interfaz deben ser public, ya que sta es la naturaleza de una interfaz.

implements
Para implementar una interfaz, se utiliza el operador implements. Todos los mtodos en una interfaz deben ser implementados dentro de la clase; el no cumplir con esta regla resultar en un error fatal. Las clases pueden implementar ms de una interfaz si se deseara, separndolas cada una por una coma. Nota: Una clase no puede implementar dos interfaces que compartan nombres de funciones, puesto que esto causara ambigedad. Nota: Las interfaces se pueden extender al igual que las clases utilizando el operador extends. Nota: La clase que implemente una interfaz debe utilizar exactamente las mismas estructuras de mtodos que fueron definidos en la interfaz. De no cumplir con esta regla, se generar un error fatal.

Constantes
Es posible tener constantes dentro de las interfaces. Las constantes de interfaces funcionan como las constantes de clases excepto porque no pueden ser sobrescritas por una clase/interfaz que las herede.

Ejemplos
Ejemplo #1 Ejemplo de interfaz
<?php // Declarar la interfaz 'iTemplate' interface iTemplate { public function setVariable($name, $var); public function getHtml($template); } // Implementar la interfaz // sto funcionar class Template implements iTemplate { private $vars = array(); public function setVariable($name, $var) { $this->vars[$name] = $var;

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 22 de 53

} public function getHtml($template) { foreach($this->vars as $name => $value) { $template = str_replace('{' . $name . '}', $value, $template); } return $template; } } // sto no funcionar // Error fatal: La Clase BadTemplate contiene un mtodo abstracto // y por lo tanto debe declararse como abstracta (iTemplate::getHtml) class BadTemplate implements iTemplate { private $vars = array(); public function setVariable($name, $var) { $this->vars[$name] = $var; } } ?>

Ejemplo #2 Interfaces extensibles


<?php interface a { public function foo(); } interface b extends a { public function baz(Baz $baz); } // sto s funcionar class c implements b { public function foo() { } public function baz(Baz $baz) { } } // sto no funcionar y resultar en un error fatal class d implements b { public function foo() { } public function baz(Foo $foo) { } } ?>

Ejemplo #3 Herencia mltiple de interfaces

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 23 de 53

<?php interface a { public function foo(); } interface b { public function bar(); } interface c extends a, b { public function baz(); } class d implements c { public function foo() { } public function bar() { } public function baz() { } } ?>

Ejemplo #4 Interfaces con constantes


<?php interface a { const b = 'Interface constant'; } // Imprime: Interface constant echo a::b; // Sin embargo sto no funcionar ya que no est permitido // sobrescribir constantes class b implements a { const b = 'Class constant'; } ?>

Una interfaz, junto con type-hinting, proveen una buena forma de asegurarse que determinado objeto contiene mtodos particulares. Vea el operador instanceof y type hinting. Abstraccin de clases Interfaces de objetos Clases y Objetos PHP Manual Clases y Objetos PHP Manual Traits Sobrecarga

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 24 de 53

Traits
Desde PHP 5.4.0, PHP implementa una metodologa de reutilizacin de cdigo llamada Traits. Los traits (rasgos) son un mecanismo de reutilizacin de cdigo en lenguajes de herencia simple, como PHP. El objetivo de un trait es el de reducir las limitaciones propias de la herencia simple permitiendo que los desarrolladores reutilicen a voluntad conjuntos de mtodos sobre varias clases independientes y pertenecientes a clases jerrquicas distintas. La semntica a la hora combinar Traits y clases se define de tal manera que reduzca su complejidad y se eviten los problemas tpicos asociados a la herencia mltiple y a los Mixins. Un Trait es similar a una clase, pero con el nico objetivo de agrupar funcionalidades muy especficas y de una manera coherente. No se puede instanciar directamente un Trait. Es por tanto un aadido a la herencia tradicional, y habilita la composicin horizontal de comportamientos; es decir, permite combinar miembros de clases sin tener que usar herencia. Ejemplo #1 Ejemplo de Trait
<?php trait ezcReflectionReturnInfo { function getReturnType() { /*1*/ } function getReturnDescription() { /*2*/ } } class ezcReflectionMethod extends ReflectionMethod { use ezcReflectionReturnInfo; /* ... */ } class ezcReflectionFunction extends ReflectionFunction { use ezcReflectionReturnInfo; /* ... */ } ?>

Precedencia
Los miembros heredados de una clase base se sobrescriben cuando se inserta otro miembro homnimo desde un Trait. De acuerdo con el orden de precedencia, los miembros de la clase actual sobrescriben los mtodos del Trait, que a su vez sobrescribe los mtodos heredados. Ejemplo #2 Ejemplo de Orden de Precedencia Se sobrescribe un miembro de la clase base con el mtodo insertado en MiHolaMundo a partir del Trait DecirMundo. El comportamiento es el mismo para los mtodos definidos en la clase MiHolaMundo. Segn el orden de precedencia los mtodos de la clase actual sobrescriben los mtodos del Trait, a la vez que el Trait sobrescribe los mtodos de la clase base.
<?php class Base { public function decirHola() { echo 'Hola '; } } trait DecirMundo { public function decirHola() { parent::decirHola();

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 25 de 53

echo 'Mundo!'; } } class MiHolaMundo extends Base { use DecirMundo; } $o = new MiHolaMundo(); $o->decirHola(); ?>

El resultado del ejemplo sera:


Hola Mundo!

Ejemplo #3 Ejemplo de Orden de Precedencia #2


<?php trait HolaMundo { public function decirHola() { echo 'Hola Mundo!'; } } class ElMundoNoEsSuficiente { use HolaMundo; public function decirHola() { echo 'Hola Universo!'; } } $o = new ElMundoNoEsSuficiente(); $o->decirHola(); ?>

El resultado del ejemplo sera:


Hola Universo!

Multiples Traits
Se pueden insertar mltiples Traits en una clase, mediante una lista separada por comas en la sentencia use. Ejemplo #4 Uso de Mltiples Traits
<?php trait Hola { public function decirHola() { echo 'Hola '; } } trait Mundo { public function decirMundo() { echo 'Mundo'; } } class MiHolaMundo { use Hola, Mundo;

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 26 de 53

public function decirAdmiracin() { echo '!'; } } $o = new MiHolaMundo(); $o->decirHola(); $o->decirMundo(); $o->decirAdmiracin(); ?>

El resultado del ejemplo sera:


Hola Mundo!

Resolucin de Conflictos
Si dos Traits insertan un mtodo con el mismo nombre, se produce un error fatal, siempre y cuando no se haya resuelto explicitamente el conflicto. Para resolver los conflictos de nombres entre Traits en una misma clase, se debe usar el operador insteadof para elejir unvocamente uno de los mtodos conflictivos. Como esto slo permite excluir mtodos, se puede usar el operador as para permitir incluir uno de los mtodos conflictivos bajo otro nombre. Ejemplo #5 Resolucin de Conflictos En este ejemplo, Talker utiliza los traits A y B. Como A y B tienen mtodos conflictos, se define el uso de la variante de smallTalk del trait B, y la variante de bigTalk del traita A. Aliased_Talker hace uso del operador as para poder usar la implementacin de bigTalk de B, bajo el alias adicional talk.
<?php trait A { public function smallTalk() { echo 'a'; } public function bigTalk() { echo 'A'; } } trait B { public function smallTalk() { echo 'b'; } public function bigTalk() { echo 'B'; } } class Talker { use A, B { B::smallTalk insteadof A; A::bigTalk insteadof B; } } class Aliased_Talker {

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 27 de 53

use A, B { B::smallTalk insteadof A; A::bigTalk insteadof B; B::bigTalk as talk; } } ?>

Modificando la Visibilidad de los Mtodos


Al usar el operador as, se puede tambin ajustar la visibilidad del mtodo en la clase exhibida. Ejemplo #6 Modificar la Visibilidad de un Mtodo
<?php trait HolaMundo { public function decirHola() { echo 'Hola Mundo!'; } } // Cambiamos visibilidad de decirHola class MiClase1 { use HolaMundo { decirHola as protected } } // Mtodo alias con visibilidad cambiada // La visibilidad de decirHola no cambia class MiClase2 { use HolaMundo { hacerHolaMundo as private decirHola } } ?>

Traits Compuestos de Traits


Al igual que las clases, los Traits tambin pueden hacer uso de otros Traits. Al usar uno o ms traits en la definicin de un trait, ste puede componerse parcial o completamente de miembros de finidos en esos otros traits. Ejemplo #7 Traits Compuestos de Traits
<?php trait Hola { public function decirHola() { echo 'Hola '; } } trait Mundo { public function decirMundo() { echo 'Mundo!'; } } trait HolaMundo { use Hola, Mundo; } class MiHolaMundo { use HolaMundo; }

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 28 de 53

$o = new MiHolaMundo(); $o->decirHola(); $o->decirMundo(); ?>

El resultado del ejemplo sera:


Hola Mundo!

Miembros Abstractos de Traits


Los traits soportan el uso de mtodos abstractos para imponer requisitos a la clase a la que se exhiban. Ejemplo #8 Expresar Resquisitos con Mtodos Abstractos
<?php trait Hola { public function decirHolaMundo() { echo 'Hola'.$this->obtenerMundo(); } abstract public function obtenerMundo(); } class MiHolaMundo { private $mundo; use Hola; public function obtenerMundo() { return $this->mundo; } public function asignarMundo($val) { $this->mundo = $val; } } ?>

Miembros Estticos en Traits


Los mtodos de un trait pueden referenciar a variables estticas, pero no puede ser definido en el trait. Los traits, sin embargo, pueden definir mtodo estticos a la clase a la que se exhiben. Ejemplo #9 Variables estticas
<?php trait Contador { public function inc() { static $c = 0; $c = $c + 1; echo "$c\n"; } } class C1 { use Contador; } class C2 { use Contador; }

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 29 de 53

$o = new C1(); $o->inc(); // echo 1 $p = new C2(); $p->inc(); // echo 1 ?>

Ejemplo #10 Mtodos Estticos


<?php trait EjemploEstatico { public static function hacerAlgo() { return 'Hacer algo'; } } class Ejemplo { use EjemploEstatico; } Ejemplo::hacerAlgo(); ?>

Propiedades
Los traits tambin pueden definir propiedades. Ejemplo #11 Definir Propiedades
<?php trait PropiedadesTrait { public $x = 1; } class EjemploPropiedades { use PropiedadesTrait; } $ejemplo = new EjemploPropiedades; $ejemplo->x; ?>

Si un trait define una propiedad una clase no puede definir una propiedad con el mismo nombre, si no se emitir un error.ste de tipo E_STRICT si la definicin de la clase es compatible (misma visibilidad y valor inicial) o de otro modo un error fatal. Ejemplo #12 Resolucin de Conflictos
<?php trait PropiedadesTrait { public $misma = true; public $diferente = false; } class EjemploPropiedades { use PropiedadesTrait; public $misma = true; // Estndares estrictos public $diferente = true; // Error fatal } ?>

Interfaces de objetos Traits

Clases y Objetos PHP Manual Clases y Objetos

Sobrecarga Iteracin de objetos

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 30 de 53

PHP Manual

Sobrecarga
La sobrecarga en PHP ofrece los medios para "crear" dinmicamente propiedades y mtodos. Estas entidades dinmicas se procesan por los mtodos mgicos que se pueden establecer en una clase para diversas acciones. Se invoca a los mtodos de sobrecarga cuando se interacta con propiedades o mtodos que no se han declarado o que no son visibles en el mbito activo. A lo largo de esta seccin usaremos los trminos "propiedades inaccesibles" y "mtodos inaccesibles" para referirnos a esta combinacin de declaracin y visibilidad. Todos los mtodos sobrecargados deben definirse como public. Nota: No se puede pasar ninguno de los parmetros de estos mtodos mgicos por referencia. Nota: La interpretacin de PHP de "overloading" es distinta de la mayora de los lenguajes orientados a objetos. La sobrecarga tradicionalmente ofrece la capacidad de tener mltiples mtodos con el mismo nombre, pero con un tipo o un nmero distinto de parmetros.

Historial de cambios
Versin 5.3.0 5.1.0 Descripcin Se aade __callStatic. Se aadieron advertencias para hacer cumplir la visibilidad public e impedir la declaracin static. Aadidos los mtodos __isset y __unset.

Sobrecarga de propiedades
public void __set ( string $name , mixed $value ) public mixed __get ( string $name ) public bool __isset ( string $name ) public void __unset ( string $name ) __set() se ejecuta al escribir datos sobre propiedades inaccesibles. __get() se utiliza para consultar datos a partir de propiedades inaccesibles. __isset() se lanza al llamar a isset() o a empty() sobre propiedades inaccesibles. __unset() se invoca cuando se usa unset() sobre propiedades inaccesibles. El parmetro $name es el nombre de la propiedad con la que se est interactuando. En el mtodo __set() el parmetro $value especifica el valor que se debe asignar a la propiedad $name.

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 31 de 53

La sobrecarga de propiedades slo funciona en contextos de objetos. Estos mtodos mgicos no se lanzarn en contextos estticos. Por esa razn, no se deben declarar como estticos. Desde PHP 5.3.0, se emite un aviso si alguno de los mtodos de sobrecarga es declarado como static. Nota: Debido a la forma en que PHP procesa el operador de asignacin, el valor que devuelve __set() se ignora. Del mismo modo, nunca se llama a __get() al encadenar asignaciones como sta:
$a = $obj->b = 8;

Nota: No se puede utilizar una propiedad sobrecargada en ninguna construccin del lenguaje que no sea isset(). Esto significa que si se invoca a empty() en una propiedad sobrecargada, no se llamar al mtodo de sobrecarga. Para solventar esta limitacin, se debe copiar la propiedad sobrecargada en una variable de mbito local que empty() pueda manejar. Ejemplo #1 Sobrecarga de propiedades mediante los mtodos __get(), __set(), __isset() y __unset()
<?php class PropertyTest { /** Localizacin de los datos sobrecargados. private $data = array();

*/ */ */

/** La sobrecarga no se usa en propiedades declaradas. public $declared = 1;

/** La sobre carga slo funciona aqu al acceder desde fuera de la clase. private $hidden = 2; public function __set($name, $value) { echo "Estableciendo '$name' a '$value'\n"; $this->data[$name] = $value; } public function __get($name) { echo "Consultando '$name'\n"; if (array_key_exists($name, $this->data)) { return $this->data[$name]; } $trace = debug_backtrace(); trigger_error( 'Propiedad indefinida mediante __get(): ' . $name . ' en ' . $trace[0]['file'] . ' en la lnea ' . $trace[0]['line'], E_USER_NOTICE); return null; } /** Desde PHP 5.1.0 */ public function __isset($name) {

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 32 de 53

echo "Est definido '$name'?\n"; return isset($this->data[$name]); } /** Desde PHP 5.1.0 */ public function __unset($name) { echo "Eliminando '$name'\n"; unset($this->data[$name]); } /** No es un mtodo mgico, esta aqu para completar el ejemplo. public function getHidden() { return $this->hidden; } } echo "<pre>\n"; $obj = new PropertyTest; $obj->a = 1; echo $obj->a . "\n\n"; var_dump(isset($obj->a)); unset($obj->a); var_dump(isset($obj->a)); echo "\n"; echo $obj->declared . "\n\n"; echo "Vamos a probar con la propiedad privada que se llama 'hidden':\n"; echo "Las propiedades privadas pueden consultarse en la clase, por lo que no se usa _ ()...\n"; echo $obj->getHidden() . "\n"; echo "Las propiedades privadas no son visibles fuera de la clase, por lo que se usa _ ()...\n"; echo $obj->hidden . "\n"; ?> */

El resultado del ejemplo sera:


Estableciendo 'a' a '1' Consultando 'a' 1 Est definido 'a'? bool(true) Eliminando 'a' Est definido 'a'? bool(false) 1 Vamos a probar con la propiedad privada que se llama 'hidden': Las propiedades privadas pueden consultarse en la clase, por lo que no se usa __get() 2 Las propiedades privadas no son visibles fuera de la clase, por lo que se usa __get() Consultando 'hidden' Notice: Propiedad indefinida mediante __get(): hidden en <file> en la lnea 69 in <f

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 33 de 53

Sobrecarga de mtodos
public mixed __call ( string $name , array $arguments ) public static mixed __callStatic ( string $name , array $arguments ) __call() es lanzado al invocar un mtodo inaccesible en un contexto de objeto. __callStatic() es lanzado al invocar un mtodo inaccesible en un contexto esttico. El parmetro $name corresponde al nombre del mtodo al que se est llamando. El parmetro $arguments es un array enumerado que contiene los parmetros que se han pasado al mtodo $name. Ejemplo #2 Sobrecarga de mtodos mediante los mtodos __call() and __callStatic()
<?php class MethodTest { public function __call($name, $arguments) { // Nota: el valor $name es sensible a maysculas. echo "Llamando al mtodo de objeto '$name' " . implode(', ', $arguments). "\n"; } /** Desde PHP 5.3.0 */ public static function __callStatic($name, $arguments) { // Nota: el valor $name es sensible a maysculas. echo "Llamando al mtodo esttico '$name' " . implode(', ', $arguments). "\n"; } } $obj = new MethodTest; $obj->runTest('en contexto de objeto'); MethodTest::runTest('en contexto esttico'); ?> // Desde PHP 5.3.0

El resultado del ejemplo sera:


Llamando al mtodo de objeto 'runTest' en contexto de objeto Llamando al mtodo esttico 'runTest' en contexto esttico

Traits Sobrecarga

Clases y Objetos PHP Manual Clases y Objetos PHP Manual

Iteracin de objetos Mtodos mgicos

Iteracin de objetos
PHP 5 ofrece una manera para que los objetos sean definidos por lo que es posible iterar a travs de una lista de elementos, con, por ejemplo, una sentencia foreach. Por defecto, todas las propiedades visibles sern utilizados para la iteracin. Ejemplo #1 Iteracin simple de objeto

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 34 de 53

<?php class MyClass { public $var1 = 'value 1'; public $var2 = 'value 2'; public $var3 = 'value 3'; protected $protected = 'protected var'; private $private = 'private var'; function iterateVisible() { echo "MyClass::iterateVisible:\n"; foreach($this as $key => $value) { print "$key => $value\n"; } } } $class = new MyClass(); foreach($class as $key => $value) { print "$key => $value\n"; } echo "\n"; $class->iterateVisible(); ?>

El resultado del ejemplo sera:


var1 => value 1 var2 => value 2 var3 => value 3 MyClass::iterateVisible: var1 => value 1 var2 => value 2 var3 => value 3 protected => protected var private => private var

Como se muestra en la salida, el foreach itera a travs de todas las propiedades visibles que se puedan acceder. Para dar un paso ms, se puede implementar la interfaz Iterator. Esto permite al objeto decidir cmo ser iterado y qu valores estarn disponibles en cada iteracin. Ejemplo #2 Iteracin de objeto implementando Iterator
<?php class MyIterator implements Iterator { private $var = array(); public function __construct($array) { if (is_array($array)) { $this->var = $array; } }

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 35 de 53

public function rewind() { echo "rewinding\n"; reset($this->var); } public function current() { $var = current($this->var); echo "current: $var\n"; return $var; } public function key() { $var = key($this->var); echo "key: $var\n"; return $var; } public function next() { $var = next($this->var); echo "next: $var\n"; return $var; } public function valid() { $key = key($this->var); $var = ($key !== NULL && $key !== FALSE); echo "valid: $var\n"; return $var; } } $values = array(1,2,3); $it = new MyIterator($values); foreach ($it as $a => $b) { print "$a: $b\n"; } ?>

El resultado del ejemplo sera:


rewinding valid: 1 current: 1 key: 0 0: 1 next: 2 valid: 1 current: 2 key: 1 1: 2 next: 3 valid: 1 current: 3 key: 2 2: 3 next: valid:

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 36 de 53

La interface IteratorAggregate se puede usar como alternativa para implementar todos los mtodos de Iterator. IteratorAggregate solamente requiere la implementacin de un nico mtodo, IteratorAggregate::getIterator(), el cual debera devolver una instancia de una clase que implemente Iterator. Ejemplo #3 Iteracin de objeto implementando IteratorAggregate
<?php class MyCollection implements IteratorAggregate { private $items = array(); private $count = 0; // Se requiere la definicin de la interfaz IteratorAggregate public function getIterator() { return new MyIterator($this->items); } public function add($value) { $this->items[$this->count++] = $value; } } $coll = new MyCollection(); $coll->add('value 1'); $coll->add('value 2'); $coll->add('value 3'); foreach ($coll as $key => $val) { echo "key/value: [$key -> $val]\n\n"; } ?>

El resultado del ejemplo sera:


rewinding current: value 1 valid: 1 current: value 1 key: 0 key/value: [0 -> value 1] next: value 2 current: value 2 valid: 1 current: value 2 key: 1 key/value: [1 -> value 2] next: value 3 current: value 3 valid: 1 current: value 3 key: 2 key/value: [2 -> value 3] next: current: valid:

Nota: Para ms ejemplos de iteradores, vea la extensin SPL.

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 37 de 53

Sobrecarga Iteracin de objetos

Clases y Objetos PHP Manual Clases y Objetos PHP Manual

Mtodos mgicos Palabra clave Final

Mtodos mgicos
Los nombres de mtodo __construct(), __destruct(), __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __toString(), __invoke(), __set_state() y __clone() son mgicos en las clases PHP. No se puede tener mtodos con estos nombres en cualquiera de las clases a menos que desee la funcionalidad mgica asociada a estos. Precaucin PHP se reserva todos los nombres de los mtodos que comienzan con __ como mgicos. Se recomienda que no utilice los nombres de mtodos con __ en PHP a menos que desee alguna funcionalidad mgica documentada.

__sleep() y __wakeup()
public array __sleep ( void ) void __wakeup ( void ) serialize() comprueba si la clase tiene un mtodo con el nombre mgico __sleep(). Si es as, el mtodo se ejecuta antes de cualquier serializacin. Se puede limpiar el objeto y se supone que devuelve un array con los nombres de todas las variables de el objeto que se va a serializar. Si el mtodo no devuelve nada, entonces NULL es serializado y un error E_NOTICE es emitido. Nota: No es posible para __sleep() devolver nombres de propiedades privadas en las clases padres. Hacer esto resultara un nivel de error E_NOTICE. En su lugar, puede utilizar la interfaz Serializable. El uso para el que est destinado __sleep() consiste en confirmar datos pendientes o realizar tareas similares de limpieza. Adems, el mtodo es til si tiene objetos muy grandes que no necesitan guardarse por completo. Por el contrario, unserialize() comprueba la presencia de un mtodo con el nombre mgico __wakeup(). Si est presente, este mtodo puede reconstruir cualquier recurso que el objeto pueda tener. El uso para el que est destinado __wakeup() es restablecer las conexiones de base de datos que se puedan haber perdido durante la serializacin y realizar otras tareas de reinicializacin. Ejemplo #1 Sleep y wakeup
<?php class Connection { protected $link; private $server, $username, $password, $db; public function __construct($server, $username, $password, $db) {

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 38 de 53

$this->server = $server; $this->username = $username; $this->password = $password; $this->db = $db; $this->connect(); } private function connect() { $this->link = mysql_connect($this->server, $this->username, $this>password); mysql_select_db($this->db, $this->link); } public function __sleep() { return array('server', 'username', 'password', 'db'); } public function __wakeup() { $this->connect(); } } ?>

__toString()
public string __toString ( void ) El mtodo __toString() permite a una clase decidir cmo comportarse cuando se le trata como un string. Por ejemplo, lo que echo $obj; mostrara. Este mtodo debe devolver un string, si no se emitir un nivel de error fatal E_RECOVERABLE_ERROR. Ejemplo #2 Ejemplo simple
<?php // Declarar una clase simple class TestClass { public $foo; public function __construct($foo) { $this->foo = $foo; } public function __toString() { return $this->foo; } } $class = new TestClass('Hola Mundo'); echo $class; ?>

El resultado del ejemplo sera:


Hola Mundo

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 39 de 53

Antes de PHP 5.2.0 el mtodo __toString() se llama slo cuando se combina directamente con echo() o print(). Desde PHP 5.2.0, se le llama en cualquier contexto de string (e.j. en printf() con el modificador %s) pero no en el contexto de otros tipos (e.j. con el modificador %d). Desde PHP 5.2.0, la conversin de los objetos sin el mtodo __toString() a string podra causar E_RECOVERABLE_ERROR.

__invoke()
mixed __invoke ([ $... ] ) El mtodo __invoke() es llamado cuando un script intenta llamar a un objeto como si fuera una funcin. Nota: Esta caracterstica est disponible desde PHP 5.3.0. Ejemplo #3 Uso de __invoke()
<?php class CallableClass { public function __invoke($x) { var_dump($x); } } $obj = new CallableClass; $obj(5); var_dump(is_callable($obj)); ?>

El resultado del ejemplo sera:


int(5) bool(true)

__set_state()
static object __set_state ( array $properties ) Este mtodo static es llamado para las clases exportadas por var_export(), desde PHP 5.1.0. El nico parmetro de este mtodo es un array que contiene las propiedades exportadas en la forma array('property' => value, ...). Ejemplo #4 Uso de __set_state() (desde PHP 5.1.0)
<?php class A { public $var1; public $var2; public static function __set_state($an_array) // A partir de PHP 5.1.0 { $obj = new A; $obj->var1 = $an_array['var1'];

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 40 de 53

$obj->var2 = $an_array['var2']; return $obj; } } $a = new A; $a->var1 = 5; $a->var2 = 'foo'; eval('$b = ' . var_export($a, true) . ';'); // $b = A::__set_state(array( // 'var1' => 5, // 'var2' => 'foo', // )); var_dump($b); ?>

El resultado del ejemplo sera:


object(A)#2 (2) { ["var1"]=> int(5) ["var2"]=> string(3) "foo" }

Iteracin de objetos Mtodos mgicos

Clases y Objetos PHP Manual Clases y Objetos PHP Manual

Palabra clave Final Clonacin de Objetos

Palabra clave Final


PHP 5 introduce la nueva palabra clave final, que impide que las clases hijas sobrescriban un mtodo, antecediendo su definicin con la palabra final. Si la propia clase se define como final, entonces no se podr heredar de ella. Ejemplo #1 Ejemplo de mtodos Final
<?php class BaseClass { public function test() { echo "llamada a BaseClass::test()\n"; } final public function moreTesting() { echo "llamada a BaseClass::moreTesting()\n"; } } class ChildClass extends BaseClass { public function moreTesting() { echo "llamada a ChildClass::moreTesting()\n"; } } // Devuelve un error Fatal: Cannot override final method BaseClass::moreTesting () ?>

Ejemplo #2 Ejemplo de clase Final

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 41 de 53

<?php final class BaseClass { public function test() { echo "llamada a BaseClass::test()\n"; } // Aqu no importa si definimos una funcin como final o no final public function moreTesting() { echo "llamada a BaseClass::moreTesting()\n"; } } class ChildClass extends BaseClass { } // Devuelve un error Fatal: Class ChildClass may not inherit from final class (BaseCl ?>

Nota: Las propiedades no pueden declararse como final. Slo pueden las clases y los mtodos. Mtodos mgicos Palabra clave Final Clases y Objetos PHP Manual Clases y Objetos PHP Manual Clonacin de Objetos Comparacin de Objetos

Clonacin de Objetos
No siempre se desea crear una copia de un objeto replicando todas sus propiedades completamente. Un buen ejemplo que ilustra la necesidad de contar con un constructor de copias, sera si tuviramos un objeto que represente una ventana en GTK y el objeto almacene los recursos de esta ventana GTK, de forma que cuando creas un duplicado el comportamiento esperado sera una nueva ventana con las mismas propiedades, y que el nuevo objeto referencie a los recursos de la nueva ventana. Otro ejemplo es si un objeto hace referencia a otro objeto necesario, de forma que cuando se realiza una rplica del objeto principal, se espera que se cree una nueva instancia de este otro objeto, de forma que la rplica tenga su propia copia Para crear una copia de un objeto se utiliza la palabra clave clone (que invoca, si fuera posible, al mtodo __clone() del objeto). No se puede llamar al mtodo __clone() de un objeto directamente.
$copia_de_objeto = clone $objeto;

Cuando se clona un objeto, PHP5 llevar a cabo una copia superficial de las propiedades del objeto. Las propiedades que sean referencias a otras variables, mantendrn las referencias. void __clone ( void ) Una vez que la clonacin ha finalizado, se llamar al mtodo __clone() del nuevo objeto (si el mtodo __clone() estuviera definido), para permitirle realizar los cambios necesarios sobre sus propiedades. Ejemplo #1 Clonacin de un objeto
<?php class SubObject { static $instances = 0; public $instance;

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 42 de 53

public function __construct() { $this->instance = ++self::$instances; } public function __clone() { $this->instance = ++self::$instances; } } class MyCloneable { public $object1; public $object2; function __clone() { // Forzamos la copia de this->object, si no // har referencia al mismo objeto. $this->object1 = clone $this->object1; } } $obj = new MyCloneable(); $obj->object1 = new SubObject(); $obj->object2 = new SubObject(); $obj2 = clone $obj; print("Objeto Original:\n"); print_r($obj); print("Objeto Clonado:\n"); print_r($obj2); ?>

El resultado del ejemplo sera:


Objeto Original: MyCloneable Object ( [object1] => SubObject Object ( [instance] => 1 ) [object2] => SubObject Object ( [instance] => 2 ) ) Objeto Clonado: MyCloneable Object ( [object1] => SubObject Object ( [instance] => 3 ) [object2] => SubObject Object

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 43 de 53

( [instance] => 2 ) )

Palabra clave Final Clonacin de Objetos

Clases y Objetos PHP Manual Clases y Objetos PHP Manual

Comparacin de Objetos Implicacin de Tipos

Comparacin de Objetos
En PHP 5, la comparacin de objetos es ms complicada que en PHP 4, y en mayor concordancia con lo que cabe esperar de un Lenguaje Orientado a Objetos (tenga en cuenta que PHP lo es). Al utilizar el operador de comparacin (==), se comparan de una forma sencilla las variables de cada objeto, es decir: Dos instancias de un objeto son iguales si tienen los mismos atributos y valores, y son instancias de la misma clase. Por otra parte, cuando se utiliza el operador identidad (===), las variables de un objeto son idnticas s y slo s hacen referencia a la misma instancia de la misma clase. Un ejemplo aclarar estas reglas. Ejemplo #1 Ejemplo de comparacin de objetos en PHP 5
<?php function bool2str($bool) { if ($bool === false) { return 'FALSO'; } else { return 'VERDADERO'; } } function { echo echo echo echo } compararObjetos(&$o1, &$o2) 'o1 'o1 'o1 'o1 == o2 : ' . bool2str($o1 == $o2) . != o2 : ' . bool2str($o1 != $o2) . === o2 : ' . bool2str($o1 === $o2) !== o2 : ' . bool2str($o1 !== $o2) "\n"; "\n"; . "\n"; . "\n";

class Bandera { public $bandera; function Bandera($bandera = true) { $this->bandera = $bandera; } } class OtraBandera { public $bandera; function OtraBandera($bandera = true) {

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 44 de 53

$this->bandera = $bandera; } } $o $p $q $r = = = = new Bandera(); new Bandera(); $o; new OtraBandera();

echo "Dos instancias de la misma clase\n"; compararObjetos($o, $p); echo "\nDos referencias a la misma instancia\n"; compararObjetos($o, $q); echo "\nInstancias de dos clases diferentes\n"; compararObjetos($o, $r); ?>

El resultado del ejemplo sera:


Dos instancias de la misma clase o1 == o2 : VERDADERO o1 != o2 : FALSO o1 === o2 : FALSO o1 !== o2 : VERDADERO Dos referencias a la misma instancia o1 == o2 : VERDADERO o1 != o2 : FALSO o1 === o2 : VERDADERO o1 !== o2 : FALSO Instancias de dos clases diferentes o1 == o2 : FALSO o1 != o2 : VERDADERO o1 === o2 : FALSO o1 !== o2 : VERDADERO

Nota: Las extensiones pueden definir sus propias reglas para la comparacin de sus objetos. Clonacin de Objetos Comparacin de Objetos Clases y Objetos Implicacin de Tipos PHP Manual Clases y Objetos Enlace esttico en tiempo de ejecucin PHP Manual

Implicacin de Tipos
Desde PHP 5 se incorpora la implicacin de tipos. Ahora, las funciones pueden obligar a que sus parmetros sean objetos (especificando el nombre de la clase en el prototipo de la funcin), interfaces, arrays (desde PHP 5.1) o tipos callable (despe PHP 5.4). Sin embargo, si se usa NULL como el valor predeterminado del parmetro, ser permitido como un argumento para llamada posterior. Si se especifica una clase o una interfaz como tipo implicado tambin se permitirn todos sus hijos o implementaciones too.

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 45 de 53

La implicacin de tipos no puede usarse con tipos escalares como int o string. Tampoco estn permitidos los Traits. Ejemplo #1 Ejemplos de Implicacin de Tipos
<?php // Una clase de ejemplo class MiClase { /** * Una funcin de prueba * * El primer parmetro debe ser un objeto del tipo OtraClase */ public function prueba(OtraClase $otraclase) { echo $otraclase->var; } /** * Otra funcin de prueba * * El primer parmetro debe ser un array */ public function prueba_array(array $array_entrada) { print_r($array_entrada); } /** * El primer parmetro debe ser un iterador */ public function prueba_interface(Traversable $iterador) { echo get_class($iterador); } /** * El primer parmetro debe ser de tipo callable */ public function prueba_callable(callable $callback, $data) { call_user_func($callback, $data); } } // Otra clase de ejemplo class OtraClase { public $var = 'Hola Mundo'; } ?>

Si no se satisface el type hint, se produce un error fatal capturable


<?php // Una instancia de cada clase $miclase = new MiClase; $otraclase = new OtraClase; // Error Fatal: El argumento 1 debe ser un objeto de la clase OtraClase $miclase->prueba('hola'); // Error Fatal: El argumento 1 debe ser una instancia de OtraClase $foo = new stdClass; $miclase->prueba($foo);

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 46 de 53

// Error fatal: El argumento 1 no puede ser null $miclase->prueba(null); // Funciona: Imprime en pantalla Hola Mundo $miclase->prueba($otraclase); // Error Fatal: El argumento 1 debe ser un array $miclase->prueba('una cadena'); // Funciona: Imprime en pantalla el array $miclase->prueba(array('a', 'b', 'c')); // Funciona: Imprime en pantalla ArrayObject $miclase->prueba_interface(new ArrayObject(array())); // Funciona: Imprime en pantalla int(1) $miclase->prueba_callable('var_dump', 1); ?>

Los tipos sugeridos tamben se pueden usar con funciones:


<?php // Una clase de ejemplo class MiClase { public $var = 'Hola Mundo'; } /** * Una funcin de prueba * * El primer parmetro debe ser un objeto del tipo MiClase */ function miFuncin (MiClase $foo) { echo $foo->var; } // Funciona $miclase = new MiClase; miFuncin($miclase); ?>

Tipo implicado que acepta valores de tipo NULL:


<?php /* Se acepta el valor NULL */ function prueba(stdClass $obj = NULL) { } prueba(NULL); prueba(new stdClass); ?>

Comparacin de Objetos Implicacin de Tipos

Clases y Objetos Enlace esttico en tiempo de ejecucin PHP Manual Clases y Objetos Objetos y referencias PHP Manual

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 47 de 53

Enlace esttico en tiempo de ejecucin


Desde PHP 5.3.0, PHP incorpora una nueva funcionalidad llamada enlace esttico en tiempo de ejecucin que permite hacer referencias a la clase en uso dentro de un contexto de herencia esttica. De forma ms precisa, un enlace esttico en tiempo de ejecucin para funcionar almacena el nombre de clase de la ltima llamada que no tenga "propagacin". En el caso de las llamadas a mtodos estticos, se trata de la clase a la que se llam explcitamente (normalmente, la que precede al operador ::); en los casos de llamadas a mtodos que no son estticos, se resolvera a la clase del objeto. Una "llamada con propagacin" es una llamada esttica que est precedida por self::, parent::, static::, o, si seguimos la jerarqua de clases, forward_static_call(). La funcin get_called_class() puede utilizarse para obtener un string con el nombre de la clase que realiza la llamada, y static:: revela cul es su alcance. Se le ha llamado "enlace esttico en tiempo de ejecucin" teniendo en cuenta un punto de vista interno. "Enlace en tiempo de ejecucin" viene del hecho de que static:: ya resuelve a la clase en la que se defini el mtodo, sino que en su lugar se resolver utilizando informacin en tiempo de ejecucin debido a que se puede utilizar (entre otras cosas) para las llamadas de mtodos estticos, se le llam tambin "enlace esttico".

Limitaciones de self::
Las referencias estticas que hay dentro de la clase en uso, como self:: o __CLASS__, se resuelven empleando el nombre de la clase a la que pertenece la funcin: Ejemplo #1 Uso de self::
<?php class A { public static function who() { echo __CLASS__; } public static function test() { self::who(); } } class B extends A { public static function who() { echo __CLASS__; } } B::test(); ?>

El resultado del ejemplo sera:


A

Uso de Enlace Esttico en Tiempo de ejecucin


Los enlaces estticos en tiempo de ejecucin tratan de resolver estas limitaciones empleando una palabra clave que haga referencia a la clase que realiz la llamada en tiempo de ejecucin. Es decir, una palabra clave que en el ejemplo anterior permita hacer referencia desde test() a B. Se

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 48 de 53

decidi no crear una nueva palabra clave, por lo que en su lugar se ha utilizado la palabra reservada static. Ejemplo #2 Uso bsico de static::
<?php class A { public static function who() { echo __CLASS__; } public static function test() { static::who(); // He aqu el enlace esttico en tiempo de ejecucin } } class B extends A { public static function who() { echo __CLASS__; } } B::test(); ?>

El resultado del ejemplo sera:


B

Nota: En contextos no estticos, la clase que realiza la llamada ser la clase del objeto instanciado. Dado que $this-> tratar de invocar mtodos privados en su mismo mbito, el uso de static:: puede provocar diferents resultados. Otra diferencia es que static:: slo puede hacer referencia a propiedades estticas. Ejemplo #3 Uso de static:: en un contexto no esttico
<?php class A { private function foo() { echo "exito!\n"; } public function test() { $this->foo(); static::foo(); } } class B extends A { /* foo() se copiar en B, por lo tanto su mbito seguir siendo A * y la llamada tendr xito */ } class C extends A { private function foo() { /* se reemplaza el mtodo original; el mbito del nuevo es ahora C */ } } $b = new B(); $b->test(); $c = new C();

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 49 de 53

$c->test(); ?>

//falla

El resultado del ejemplo sera:


exito! exito! exito! Fatal error: Call to private method C::foo() from context 'A' in /tmp/test.php on li

Nota: En una llamada que se resuelva como esttica, la resolucin de enlaces estticos en tiempo de ejecucin se dentendr sin propagarse. Por otra parte, las llamadas estticas que utilicen palabras clave como parent:: o self:: s propagarn la informacin. Ejemplo #4 Llamadas que propagan y que no propagan
<?php class A { public static function foo() { static::who(); } public static function who() { echo __CLASS__."\n"; } } class B extends A { public static function test() { A::foo(); parent::foo(); self::foo(); } public static function who() { echo __CLASS__."\n"; } } class C extends B { public static function who() { echo __CLASS__."\n"; } } C::test(); ?>

El resultado del ejemplo sera:


A C C

Implicacin de Tipos

Clases y Objetos PHP Manual Enlace esttico en tiempo de ejecucin Clases y Objetos PHP Manual

Objetos y referencias Serializacin de objetos

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 50 de 53

Objetos y referencias
Uno de los puntos clave de la POO de PHP 5 que a menudo se menciona es que "por omisin los objetos se pasan por referencia". Esto no es completamente cierto. Esta seccin rectifica esa creencia general, usando algunos ejemplos. Una referencia en PHP es un alias, que permite a dos variables diferentes escribir sobre un mismo valor. Desde PHP 5, una variable de tipo objeto ya no contiene el objeto en s como valor. nicamente contiene un identificador del objeto que le permite localizar al objeto real. Cuando se pasa un objeto como parmetro, o se devuelve como retorno, o se asigna a otra variable, las distintas variables no son alias: guardan una copia del identificador, que apunta al mismo objeto. Ejemplo #1 Referencias y Objetos
<?php class A { public $foo = 1; } $a = new A; $b = $a; // $a y $b son copias del mismo identificador // ($a) = ($b) = <id>

$b->foo = 2; echo $a->foo."\n"; $c = new A; $d = &$c;

// $c y $d son referencias // ($c,$d) = <id>

$d->foo = 2; echo $c->foo."\n"; $e = new A; function foo($obj) { // ($obj) = ($e) = <id> $obj->foo = 2; } foo($e); echo $e->foo."\n"; ?>

El resultado del ejemplo sera:


2 2 2

Enlace esttico en tiempo de ejecucin Objetos y referencias

Clases y Objetos PHP Manual Clases y Objetos PHP Manual

Serializacin de objetos Registro de cambios de POO

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 51 de 53

Serializacin de objetos serializacin de objetos - objetos en sesiones


La funcin serialize() devuelve un string que contiene un flujo de bytes que representa cualquier valor que se pueda almacenar en PHP. Por otra parte, unserialize() puede restaurar los valores originales a partir de dicho string. Al utilizar serialize para guardar un objeto, almacenar todas las variables de dicho objeto. En cambio los mtodos no se guardarn, slo el nombre de la clase. Para poder deserializar (unserialize()) un objeto, debe estar definida la clase de ese objeto. Es decir, si se tiene un objeto de la clase A, y lo serializamos, se obtendr un string que haga referencia a la clase A y contenga todas las variables que haya en esta clase. Si se desea deseralizar en otro fichero, antes debe estar presente la definicin de la clase A. Esto se puede hacer, por ejemplo, escribiendo la definicin de la clase A en un fichero, para despus o bien incluirlo, o bien hacer uso de la funcin spl_autoload_register().
<?php // classa.inc: class A { public $one = 1; public function show_one() { echo $this->one; } } // page1.php: include("classa.inc"); $a = new A; $s = serialize($a); // almacenamos $s en algn lugar en el que page2.php puede encontrarlo. file_put_contents('store', $s); // page2.php: // se necesita para que unserialize funcione correctamente. include("classa.inc"); $s = file_get_contents('store'); $a = unserialize($s); // now use the function show_one() of the $a object. $a->show_one(); ?>

Si una aplicacin est usando sesiones, y utiliza session_register() para registrar objetos, estos objetos se serializarn automticamente al final de cada pgina PHP, y se deserializan tambin automticamente en cada una de las siguientes peticiones. Esto significa que, una vez que formen parte de la sesin, estos objetos se podrn utilizar en cualquier pgina de la aplicacin. Sin embargo, la funcin session_register(): ha sido borrada a partir de PHP 5.4.0 Si una aplicacin serializa objetos para su uso posterior, se recomienda encarecidamente que se incluya la definicin de la clase en toda la aplicacin. Si no se hiciera, se deserializara el objeto sin una definicin de clase, lo cual dara como resultado que PHP definiera al objeto con la clase __PHP_Incomplete_Class_Name, que no tiene mtodos, haciendo que el objeto no fuera til.

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 52 de 53

Por tanto, si en el ejemplo anterior $a se guardara en una sesin mediante session_register("a"), sera necesario incluir el fichero classa.inc en todas las pginas, no slo en page1.php y page2.php. Objetos y referencias Serializacin de objetos Clases y Objetos PHP Manual Clases y Objetos PHP Manual Registro de cambios de POO Espacios de Nombres

Registro de cambios de POO


Aqu se registran los cambios del modelo de POO de PHP 5. Las descripciones y otras notas respecto a estas nuevas funcionalidades estn documentadas dentro de la documentacin de POO 5. Versin 5.4.0 5.3.3 5.3.0 5.3.0 5.3.0 Descripcin Cambiado: Si una clase abstracta define una firma para el constructor ahora se har cumplir. Cambiado: Los mtodos con el mismo nombre que el ltimo elemento de un nombre de clase perteneciente a un espacio de nombres ya no sern tratado como un constructor. Este cambio no afecta a las clases que no pertenecen a un espacio de nombres. Cambiado: Ya no es necesario que los valores por omisin de los mtodos de una clase que implemente un interfaz coincidan con los valores por omisin de los prototipos de la interfaz. Cambiado: Ahora es posible hacer referencia a la clase utilizando una variable (p.ej., echo $nombreclase::constante;). La variable no puede contener como valor una palabra clave (p.ej., self, parent o static). Cambiado: Se emite un error de nivel E_WARNING si al sobrecargar un mtodo mgico se le declara como esttico. Adems, hace necesario que tengan visibilidad pblica. Cambiado: Antes de 5.3.0, las excepciones lanzadas en la funcin __autoload() no podan capturarse en el bloque catch, y provocaban un error fatal. Ahora, las excepciones lanzadas dentro de la funcin __autoload pueden capturarse en el bloque catch, con una nica salvedad. Si se lanza una excepcin definida por el usuario, entonces esta excepcin debera estar disponible. Se puede utilizar recursivamente la funcin __autoload para cargar automticamente la clase de la excepcin definida por el usuario. Aadido: El mtodo __callStatic. Aadido: Soporte heredoc y nowdoc para constantes de clase y definicin de propiedades. Nota: los valores heredoc deben seguir las mismas reglas que las cadenas de dobles comillas (p.ej., no contener variables). Aadido: Enlaces estticos en tiempo de ejecucin. Aadido: El mtodo __invoke(). Cambiado: Al mtodo __toString() slo se le invocaba cuando se le combinaba con echo () o con print(). Pero ahora, se le invoca en cualquier contexto de strings (p.ej, en printf() con el modificador %s) pero no en contextos de otro tipo (p.ej. con el modificador %d). Desde PHP 5.2.0, convertir objetos a string sin el mtodo __toString emitir un error de nivel E_RECOVERABLE_ERROR. Cambiado: En versiones anteriores de PHP 5, se consideraba obsoleto el uso de var y emita un error de nivel E_STRICT. Ya no est obsoleto, y por tanto no emite el error.

5.3.0

5.3.0 5.3.0 5.3.0 5.3.0 5.2.0

5.1.3

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

Clases y Objetos

Pgina 53 de 53

Versin 5.1.0 5.1.0

Descripcin Cambiado: Ahora se invoca al mtodo esttico __set_state() en las clases exportadas por var_export(). Aadido: Los mtodos __isset() y __unset(). Clases y Objetos PHP Manual Espacios de Nombres

Serializacin de objetos

file://C:\Users\YIMY\AppData\Local\Temp\~hh3BAB.htm

20/08/2013

You might also like