POO y las clases en PHP (segunda parte)
Prof. Dr. Jorge Domínguez Chávez
En la sesión anterior trabajamos con la clase Database.php que gestiona la conexión a la base de
datos y los diversos formularios de nuestra aplicación WEB.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<? php
class Database {
public $db ;
// variable p ú blica que gestiona la conexion a la db
private static $dns = " mysql : host = localhost ; dbname = tucoplast " ;
private static $user = " root " ;
private static $pass = " pumas " ;
private static $instance ;
public function __construct () {
$this - > db = new PDO ( self :: $dns , self :: $user , self :: $pass ) ;
}
/* Evita el copiado del objeto . Patr ó n Singleton */
private function __clone () { }
/* Funci ó n encargada de crear , si es necesario , el objeto .
/* Funci ó n a llamar desde fuera de la clase para instanciar el objeto
y utilizar sus m é todos */
public static function getInstance () {
if (! isset ( self :: $instance ) ) {
$object = __CLASS__ ;
self :: $instance = new $object ;
}
return self :: $instance ;
}
}
?>
La variable public $db; es pública y gestiona la conexion a la db, mientras que las siguientescuatro
variables son privadas estáticas, sólo son reconocidas por la clase y NO fuera de ella.
La function __construct () es llamada automáticamente al ser ejecutada la clase.
La private function __clone() evita que la clase Database sea clonada o copiada; esto es hecho por
seguridad.
La public static function getInstance() es llamada fuera de la clase para instanciar el objeto y utilizar
sus métodos, sin abrir un nuevo canal para ello.
1
1.
1
2
3
4
5
6
7
Formulario Clientes
<? php
include_once ( ' conexion . php ' ) ;
$pdo = Database :: getInstance () ;
$sql = " SELECT id , nombre , direccion , telefono FROM clientes order by
id " ;
$registro = $pdo - > db - > prepare ( $sql ) -> execute ( $sql ) ;
?>
¿Ahora, cómo trabaja realmente la clase, sus variables y funciones cada vez que invoquemos la clase
conexion.php?
A continuación le presentamos la teoría, no toda, de la programación orientada a objeto en PHP.
2.
Introducción
A partir de PHP 5 se incluye un modelo de objetos completo. Algunas de sus características son:
visibilidad, clases y métodos abstractos y finales, métodos mágicos adicionales, interfaces, clonación
y determinación de tipos.
PHP trata los objetos igual que las referencias o manejadores, lo tanto cada variable contiene una
referencia a un objeto en lugar copiarlo. Véanse los Objetos y referencias.
Sugerencia Vea también Guía de entorno de usuario para nombres.
3.
Lo básico
3.1.
class
Una clase se define por la palabra reservada class, seguida de un nombre, y enmarcados par de llaves
las propiedades y métodos que le pertenecen.
El nombre de clase es cualquier etiqueta válida, siempre y cuando no sea una palabra reservada de
PHP. Un nombre válido de clase comienza con una letra o un guión bajo, seguido de una cantidad
arbitraria de letras, números o guiones bajos. Una expresión regular tiene la siguiente forma: ^[azA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$.
Una clase contiene sus propias constantes, variables (”propiedades”), y funciones (”métodos”).
Ejemplo 1 Definición de una clase sencilla
1
2
3
4
5
6
7
8
9
10
11
<? php
class ClaseSencilla {
// Declaraci ó n de una propiedad
public $var = ' un valor predeterminado ' ;
// Declaraci ó n de un m é todo
public function mostrarVar () {
echo $this - > var ;
}
}
?>
2
La pseudovariable $this está disponible cuando un método es invocado dentro del contexto de un
objeto. $this es una referencia al objeto invocador (usualmente el objeto al cual el método pertenece,
aunque puede ser cualquier otro objeto si el método es llamado estáticamente desde un objeto
secundario). A partir de PHP 7.0.0, la llamada estática a un método no estático desde un contexto
incompatible resulta en que $this no esté definido dentro del método. Una llamada estática a un
método no estático desde un contexto no compatible está obsoleta desde PHP 5.6.0. A partir de
PHP 7.0.0, una llamada estática a un método no estático está obsoleta en general (incluso si se
llama desde un contexto compatible). Antes de PHP 5.6.0, tales llamadas ocasionaban un aviso de
estrictez.
Ejemplo 2 Algunos ejemplos de la pseudovariable $this
Se asume que para este ejemplo error_reporting está inhabilitado; de lo contrario, el código emite
avisos de estrictez y obsolescencia, respectivamente, dependiendo de la versión de PHP.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<? php
class A {
function foo () {
if ( isset ( $this ) ) {
echo ' $this est á definida ( ' ;
echo get_class ( $this ) ;
echo ' ' ) \ n ' ' ;
} else {
echo ' ' \ $this no est á definida .\ n ' ' ;
}
}
}
class B {
function bar () {
A :: foo () ;
}
}
$a = new A () ;
$a - > foo () ;
A :: foo () ;
$b = new B () ;
$b - > bar () ;
B :: bar () ;
?>
Salida del ejemplo anterior en PHP 5:
1
2
3
4
$this
$this
$this
$this
est á definida ( A )
no est á definida .
est á definida ( B )
no est á definida .
Salida del ejemplo anterior en PHP 7:
1
2
$this est á definida ( A )
$this no est á definida .
3
$this no est á definida .
$this no est á definida .
3
4
3.2.
new
Para crear una instancia1 de una clase debe emplear la palabra reservada new. Un objeto se crea
siempre a menos que el objeto tenga un constructor que arroje una excepción en caso de error. Las
clases deben estar definidas antes de la instanciación.
Si se emplea un string que contenga el nombre de una clase con new, se crea una nueva instancia
de esa clase. Si la clase estuviera en un espacio de nombres, debe utilizar su nombre completo al
realizar esto.
Ejemplo 3 Creación de una instancia
<? php
$instancia = new ClaseSencilla () ; // ver ejemplo 1
1
2
3
4
5
6
7
// Esto tambi é n se puede hacer con una variable :
$nombreClase = ' ClaseSencilla ' ;
$instancia = new $nombreClase () ; // new ClaseSencilla ()
?>
En el contexto de una clase, es posible crear un nuevo objeto con new self y new parent.
Cuando se asigna una instancia ya creada de una clase a una nueva variable, ésta última accederá
a la misma instancia que el objeto que le fue asignado. Esta conducta es la misma que cuando se
pasan instancias a una función. Se puede realizar una copia de un objeto ya creado a través de la
clonación del mismo.
Ejemplo 4 Asignación de objetos
<? php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$instancia = new ClaseSencilla () ;
$asignada
= $instancia ;
$referencia =& $instancia ;
$instancia - > var = ' $asignada tendr á este valor ' ;
$instancia = null ; // $instancia y $referencia son null
var_dump ( $instancia ) ;
var_dump ( $referencia ) ;
var_dump ( $asignada ) ;
?>
El resultado del ejemplo es:
NULL
NULL
object ( ClaseSencilla ) #1 (1) {
[ " var " ]= > string (27) " $asignada tendr á este valor "
1
2
3
4
1
Podemos pensar en instancia como una copia independiente de la clase.
4
5
}
PHP 5.3.0 introdujo un par de formas nuevas para crear instancias de un objeto.
Ejemplo 5 Creación de nuevos objetos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<? php
class Prueba {
static public function getNew () {
return new static ;
}
}
class Hija extends Prueba {}
$obj1 = new Prueba () ;
$obj2 = new $obj1 ;
var_dump ( $obj1 !== $obj2 ) ;
$obj3 = Prueba :: getNew () ;
var_dump ( $obj3 instanceof Prueba ) ;
$obj4 = Hija :: getNew () ;
var_dump ( $obj4 instanceof Hija ) ;
?>
El resultado del ejemplo es:
1
2
3
bool ( true )
bool ( true )
bool ( true )
PHP 5.4.0 introdujo la posibilidad de acceder a un miembro de un objeto recién crecado en una
única expresión.
Ejemplo 6 Acceder a un mimebro de un objeto recién creado
1
2
3
<? php
echo ( new DateTime () ) -> format ( ' Y ' ) ;
?>
El resultado del ejemplo es similar a:
1
4.
2016
Propiedades y métodos
Las propiedades y métodos de una clase viven en «espacios de nombres» diferentes, por tanto, es
posible tener una propiedad y un método con el mismo nombre. Al hacer referencia tanto a una
propiedad como a un método se utiliza la misma notación, y si se accederá a la propiedad o se
llamará al método, solamente depende del contexto, es decir, si el empleo es el acceso a una variable
o la llamada a una función.
Ejemplo 7 Acceso a propiedad contra llamada a método
5
1
2
3
4
5
6
7
8
9
10
class Foo {
public $bar = ' propiedad ' ;
public function bar () {
return ' m é todo ' ;
}
}
$obj = new Foo () ;
echo $obj - > bar , PHP_EOL , $obj - > bar () , PHP_EOL ;
El resultado del ejemplo es:
propiedad
método
Esto significa que llamar a una función anónima que ha sido asignada a una propiedad no es posible
directamte. En su lugar, la propiedad ha de ser asignada primero a una variable, por ejemplo. A
partir de PHP 7.0.0, es posible llamar a dicha propiedad directamente encerrándola entre paréntesis.
Ejemplo 8 Llamar a una función anónima almacenada en una propiedad
1
2
3
4
5
6
7
8
9
class Foo {
public $bar ;
public function $ __construct () $ {
$this - > bar = function () {
return 42;
};
}
}
// A partir de PHP 5.3.0:
1
2
3
$obj = new Foo () ;
$func = $obj - > bar ;
echo $func () , PHP_EOL ;
// Alternativamente, a partir de PHP 7.0.0:
1
echo ( $obj - > bar ) () , PHP_EOL ;
El resultado del ejemplo es:
42
5.
extends
Una clase hereda los métodos y propiedades de otra clase empleando la palabra reservada extends
en la declaración de la clase. No es posible la extensión de múltiples clases; una clase sólo hereda de
una clase base.
Los métodos y propiedades heredados pueden ser sobrescritos con la redeclaración de éstos utilizando
el mismo nombre que en la clase madre. Sin embargo, si la clase madre definió un método como final,
éste no será sobrescrito. Es posible acceder a los métodos sobrescritos o a las propiedades estáticas
6
haciendo referencia a ellos con parent::.
Cuando se sobrescriben métodos, la firma de los parámetros sería la misma o PHP generará un error
de nivel E_STRICT. Esto no se aplica a los constructores, los cuales permiten la sobrescritura con
diferentes parámetros.
Ejemplo 9 Herencia de clases sencilla
1
2
3
4
5
6
7
8
9
10
11
12
<? php
class ClaseExtendida extends ClaseSencilla {
// Redefinici ó n del m é todo padre
function mostrarVar () {
echo ' Clase extendida \ n ' ;
parent :: mostrarVar () ;
}
}
$extendida = new ClaseExtendida () ;
$extendida - > mostrarVar () ;
?>
El resultado del ejemplo es:
1
2
3
Clase extendida
un valor predeterminado
:: class
Desde PHP 5.5, también se emplea la palabra reservada class para la resolución de nombres de clases. Se puede obtener un string con el nombre completamente cualificado de la clase NombreClase
utilizando NombreClase::class. Esto es particularmete útil con clases en espacios de nombres.
Ejemplo 10 Resolución de nombres de clases
1
2
3
4
5
6
7
8
<? php
namespace NS {
class NombreClase {
}
echo NombreClase :: class ;
}
?>
El resultado del ejemplo es:
NS\NombreClase
Nota: La resolución de nombres de clases con ::class es una transformación durante la
compilación. Esto significa que, en el instante de crear el string del nombre de la clase,
aún no se ha realizado ninguna autocarga. Como consecuencia, los nombres de clases se
expanden incluso si la clase no existe. No se emite ningún error en tal caso.
6.
Propiedades
Las variables pertenecientes a una clase se llaman ”propiedades”. También se les puede llamar usando
otros términos como ”atributos” o ”campos”, pero para los propósitos de esta referencia se va a utilizar
7
”propiedades”. Éstas se definen usando una de las palabras reservadas public, protected, o private,
seguido de una declaración normal de variable. Esta declaración puede incluir una inicialización,
pero esta inicialización debe ser un valor constante, es decir, debe poder ser evaluada durante la
compilación y no depender de información generada en la ejecución.
Véase la Visibilidad para más información sobre el significado de public, protected, y private.
Nota: Con el fin de mantener la compatibilidad con PHP 4, PHP 5 continuará aceptando
el uso de la palabra reservada var en la declaración de propiedades en lugar de (o además
de) public, protected, o private. Sin embargo, var ya no es necesaria. Entre las versiones
5.0 y 5.1.3 de PHP, el uso de var fue considerado obsoleto y emitía una advertencia
de nivel E_STRICT; pero a partir de PHP 5.1.3 ya no está obsoleta y no se emite la
advertencia.
Si se declara una propiedad utilizando var en lugar de public, protected, o private, PHP tratará
dicha propiedad como si hubiera sido definida como public.
Dentro de los métodos de una clase, se puede acceder a las propiedades no estáticas utilizando >(el operador de objeto): $this->propiedad (donde propiedad es el nombre de la propiedad). A las
propiedades estáticas se puede acceder utilizando :: (doble dos puntos): self::$propiedad. Véase la
palabra reservada ’static’para más información sobre la diferencia entre propiedades estáticas y no
estáticas.
La pseudovariable $this está disponible dentro de cualquier método de clase cuando éste es invocado
dentro del contexto de un objeto. $this es una referencia al objeto invocador (usualmente el objeto
al cual pertenece el método, aunque puede que sea otro objeto si el método es llamado estáticamente
desde el contexto de un objeto secundario).
Ejemplo 11 Declaración de propiedades
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<? php
class ClaseSencilla {
// V á lido a partir de PHP 5.6.0:
public $var1 = ' hola ' . ' mundo ' ;
// V á lido a partir de PHP 5.3.0:
public $var2 = <<< EOD
hola mundo
EOD ;
// V á lido a partir de PHP 5.6.0:
public $var3 = 1+2;
// Declaraciones de propiedades inv á lidas :
public $var4 = self :: miM é todoEst á tico () ;
public $var5 = $myVar ;
// Declaraciones de propiedades v á lidas :
public $var6 = miConstante ;
public $var7 = array ( true , false ) ;
// V á lido a partir de PHP 5.3.0:
public $var8 = <<<' EOD '
hola mundo
EOD ;
}
?>
8
Nota: Existen varias funciones interesantes para manipular clases y objetos. Puede ser
interesante echarle un vistazo a las Funciones de clases/objetos.
A partir de PHP 5.3.0, se puede utilizar heredocs y nowdocs en cualquier contexto de datos estáticos,
incluyendo la declaración de propiedades.
Ejemplo 12 Uso de nowdoc para inicializar una propiedad
1
2
3
4
5
6
7
8
9
10
11
<? php
class foo {
// A paritr de PHP 5.3.0
public $bar = <<<' EOT '
bar
EOT ;
public $baz = <<< EOT
baz
EOT ;
}
?>
Nota: Se añadio soporte para Nowdoc y Heredoc en PHP 5.3.0.
7.
Constantes de clases
Es posible definir valores constantes en función de cada clase manteniéndola invariable. Las constantes se diferencian de las variables comunes en que no utilizan el símbolo $ al declararlas o emplearlas.
La visibilidad predeterminada de las constantes de clase es public.
El valor debe ser una expresión constante, no (por ejemplo) una variable, una propiedad o una
llamada a una función.
También es posible que las interfaces tengan constantes. Consulte los ejemplos de la documentación
de interfaces.
A partir de PHP 5.3.0, es posible referirse a una clase utilizando una variable. El valor de la variable
no puede ser una palabra reservada (p.ej., self, parent o static).
Observe que las constantes de clase están asignadas una vez por clase, y no por cada instancia de la
clase.
Ejemplo 13 Definición y uso de una constante
1
2
3
4
5
6
7
8
9
10
11
12
13
<? php
class MiClase {
const CONSTANTE = ' valor constante ' ;
function mostrarConstante () {
echo self :: CONSTANTE . ' ' \ n ' ' ;
}
}
echo MiClase :: CONSTANTE . ' ' \ n ' ' ;
$nombreclase = ' ' MiClase ' ' ;
echo $nombreclase :: CONSTANTE . ' ' \ n ' ' ; // A partir de PHP 5.3.0
9
14
15
16
17
18
19
$clase = new MiClase () ;
$clase - > mostrarConstante () ;
echo $clase :: CONSTANTE . ' ' \ n ' ' ; // A partir de PHP 5.3.0
?>
Ejemplo 14 Datos estáticos
1
2
3
4
5
6
7
8
9
10
11
12
<? php
class foo {
// A partir
const BAR =
bar
EOT ;
// A partir
const BAZ =
baz
EOT ;
}
?>
de PHP 5.3.0
<<<' EOT '
de PHP 5.3.0
<<< EOT
Nota: El soporte para la inicialización de constantes con la sintaxis de Heredoc y Nowdoc
fue agregado en PHP 5.3.0.
La constante especial ::class está disponible a partir de PHP 5.5.0, y permite la resolución de nombres
de clase completamente cualificados en la compilación. Esto es útil para clases en espacios de nombres:
Ejemplo 15 Ejemplo de ::class en espacio de nombres
1
2
3
4
5
6
7
8
<? php
namespace foo {
class bar {
}
echo bar :: class ; // foo \ bar
}
?>
Ejemplo 16 Expresión constante
1
2
3
4
5
6
7
8
9
10
<? php
const UNO = 1;
class foo {
// A partir de PHP 5.6.0
const DOS = UNO * 2;
const TRES = UNO + self :: DOS ;
const SENTENCIA = ' El valor de TRES es ' . self :: TRES ;
}
?>
Es posible proporcionar una expresión escalar que implique literales numéricos y de string y/o
constantes en el contexto de una constante de clase.
10
Nota: El soporte para expresiones constantes se añadió en PHP 5.6.0.
Ejemplo 17 Modificadores de visibilidad de constantes de clase
1
2
3
4
5
6
7
8
9
<? php
class Foo {
// A partir de PHP 7.1.0
public const BAR = ' bar ' ;
private const BAZ = ' baz ' ;
}
echo Foo :: BAR , PHP_EOL ;
echo Foo :: BAZ , PHP_EOL ;
?>
Salida del ejemplo anterior en PHP 7.1:
1
2
bar
Fatal error : Uncaught Error : Cannot access private const Foo :: BAZ in \
dot
Nota: A partir de PHP 7.1.0, están permitidos los modificadores de visibilidad para
constantes de clase.
Es posible declarar una constante en una clase base, y sobreescribirla un hijo, y acceder al valor
correcto de la constante (const) desde el método static a través de get_called_class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<? php
abstract class dbObject {
const TABLE_NAME = ' undefined ' ;
public static function GetAll () {
$c = get_called_class () ;
return ' ' SELECT * FROM `' ' . $c :: TABLE_NAME . ' ' `' ' ;
}
}
class dbPerson extends dbObject {
const TABLE_NAME = ' persons ' ;
}
class dbAdmin extends dbPerson {
const TABLE_NAME = ' admins ' ;
}
echo dbPerson :: GetAll () . ' ' <br > ' ' ;// output : ' ' SELECT * FROM ` persons ` ' '
echo dbAdmin :: GetAll () . ' ' <br > ' ' ;// output : ' ' SELECT * FROM ` admins ` ' '
?>
11
8.
Autocarga de clases
Muchos desarrolladores que escriben aplicaciones orientadas a objetos crean un archivo fuente de
PHP para cada definición de clase. Una de las mayores molestias es tener que hacer una larga lista
de inclusiones al comienzo de cada script (uno por cada clase).
En PHP 5 esto ya no es necesario. La función spl_autoload_register() registra cualquier número
de autocargadores, posibilitando que las clases e interfaces sean cargadas automáticamente si no
están definidas actualmente. Al registrar autocargadores, a PHP se le da una última oportunidad
de cargar las clases o interfaces antes de que falle por un error.
Sugerencia
Aunque la función __autoload() también puede ser empleada para autocargar clases e interfaces, es
preferible utilizar la función spl_autoload_register(). Esto es debido a que es una alternativa más
flexible (posibilitando que se pueda especificar cualquier número de autocargadores en la aplicación,
tales como los de las bibliotecas de terceros). Por esta razón, se desaconseja el uso de __autoload(),
ya que podría estar obsoleta en el futuro.
Nota: Antes de 5.3.0, las excepciones lanzadas en la función __autoload() no podían ser
capturadas en el bloque catch, resultando en un error fatal. Desde 5.3 en adelante, esto
es posible simpre que, si se lanza una excepción personalizada, esté disponible la clase de
la excepción personalizada. La función __autoload() podría utilizarse recursivamente
para cargar la clase de excepción personalizada.
Nota: La autocarga no está disponible si se utiliza PHP en el modo interactivo CLI.
Nota: Si el nombre de la clase se utiliza, por ejemplo, en call_user_func(), este puede
contener algunos caracteres peligrosos tales como ../. Se recomienda no utilizar la entrada
del usuario en tales funciones, o al menos verificar dicha entrada en __autoload().
Ejemplo 18 Autocarga
Este ejemplo intenta cargar las clases MiClase1 y MiClase2 desde los archivos MiClase1.php y
MiClase2.php, respectivamente.
1
2
3
4
5
6
7
8
<? php
s p l _ a u t o l o a d _ r e g i s t e r ( function ( $nombre_clase ) {
include $nombre_clase . ' . php ' ;
}) ;
$obj = new MiClase1 () ;
$obj2 = new MiClase2 () ;
?>
Ejemplo 19 Otro ejemplo de autocarga
Este ejemplo intenta cargar la interfaz IPrueba.
1
2
3
4
5
6
<? php
s p l _ a u t o l o a d _ r e g i s t e r ( function ( $nombre ) {
var_dump ( $nombre ) ;
}) ;
12
7
8
9
10
11
12
13
14
15
class Foo implements IPrueba {
}
/*
string (7) ' ' IPrueba ' '
Fatal error : Interface ' IPrueba ' not found in ...
*/
?>
Ejemplo 20 Autocarga con manejo de excepciones para 5.3.0+
Este ejemplo lanza una excepción y demuestra los bloques try/catch.
1
2
3
4
5
6
7
8
9
10
11
12
<? php
s p l _ a u t o l o a d _ r e g i s t e r ( function ( $nombre ) {
echo ' ' Intentando cargar $nombre .\ n ' ' ;
throw new Exception ( ' ' Imposible cargar $nombre . ' ' ) ;
}) ;
try {
$obj = new ClaseNoCargable () ;
} catch ( Exception $e ) {
echo $e - > getMessage () , ' ' \ n ' ' ;
}
?>
El resultado del ejemplo es:
1
2
Intentando cargar ClaseNoCargable .
Imposible cargar ClaseNoCargable .
Ejemplo 21 Autocarga con manejo de excepciones para 5.3.0+: Excepción personalizada ausente
Este ejemplo lanza una excepción para una excepción personalizada no cargable.
1
2
3
4
5
6
7
8
9
10
11
12
<? php
s p l _ a u t o l o a d _ r e g i s t e r ( function ( $nombre ) {
echo ' ' Intentando cargar $nombre .\ n ' ' ;
throw new Excepci ó nAusente ( ' ' Imposible cargar $nombre . '' ) ;
}) ;
try {
$obj = new ClaseNoCargable () ;
} catch ( Exception $e ) {
echo $e - > getMessage () , ' ' \ n ' ' ;
}
?>
El resultado del ejemplo es:
1
2
3
4
Intentando cargar ClaseNoCargable .
Intentando cargar Excepci ó nAusente .
Fatal error : Class ' Excepci ó nAusente ' not found in t e s t E x c e p c i o n A u s e n t e
. php on line 4
Ver también
13
unserialize()
unserializec allbackf unc
spla utoloadr egister()
spla utoload()
__autoload()
9.
9.1.
Constructores y destructores
Constructor
__construct([mixedargs = ” ” [, ...]]) : void PHP 5 permite a los desarrolladores declarar métodos
constructores para las clases. Aquellas que tengan un método constructor lo invocarán en cada nuevo
objeto creado, lo que lo hace idóneo para cualquier inicialización que el objeto pueda necesitar antes
de ser usado.
Nota: Los constructores padres no son llamados implícitamente si la clase hija define un constructor. Para ejecutar un constructor padre, se requiere invocar a parent::
__construct() desde el constructor hijo. Si el hijo no define un constructor, entonces se
puede heredar de la clase madre como un método de clase normal (si no fue declarada
como privada).
Ejemplo 22 Utilización de nuevos constructores unificados
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<? php
class BaseClass {
function $ __construct () $ {
print ' ' En el constructor BaseClass \ n ' ' ;
}
}
class SubClass extends BaseClass {
function $ __construct () $ {
parent :: $ __construct () $ ;
print ' ' En el constructor SubClass \ n ' ' ;
}
}
class OtherSubClass extends BaseClass {
// heredando el constructor BaseClass
}
// En el constructor BaseClass
$obj = new BaseClass () ;
// En el constructor BaseClass
// En el constructor SubClass
$obj = new SubClass () ;
14
26
27
28
// En el constructor BaseClass
$obj = new OtherSubClass () ;
?>
Por motivos de retrocompatibilidad con PHP 3 y PHP 4, si PHP no puede encontrar una función
__construct() de una clase dada, se buscará la función constructora del estilo antiguo, por el nombre
de la clase. Efectivamente, esto significa que en el único caso en el que se tendría compatibilidad es
si la clase tiene un método llamado __construct() que fuese utilizado para diferentes semáticas.
Advertencia Los constructores del estilo antiguo están OBSOLETOS en PHP 7.0, por
lo que serán eliminados en una futura versión. Se debería utilizar siempre __construct()
en código nuevo.
A diferencia con otros métodos, PHP no generará un mensaje de error a nivel de E_STRICT cuando
__construct() es sobrescrito con diferentes parámetros que los métodos padre __construct() tienen.
A partir de PHP 5.3.3, los métodos con el mismo nombre que el último elemento de una clase en un
nombre de espacios no serán más tratados como un constructor. Este cambio no afecta a clases sin
espacio de nombres.
Ejemplo 23 Constructores en clases pertenecientes a un nombre de espacios
1
2
3
4
5
6
7
8
9
<? php
namespace Foo ;
class Bar {
public function Bar () {
// Tratado como constructor en PHP 5.3.0 - 5.3.2
// Tratado como m é todo regular a partir de PHP 5.3.3
}
}
?>
9.2.
Destructor
__destruct(void) : void PHP 5 introduce un concepto de destructor similar al de otros lenguajes
orientados a objetos, tal como C++. El método destructor será llamado tan pronto como no hayan
otras referencias a un objeto determinado, o en cualquier otra circunstancia de finalización.
Ejemplo 24 Destructor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<? php
class M yD e st r uc t a bl e Cl a s s {
function $ __construct () $ {
print ' ' En el constructor \ n ' ' ;
$this - > name = ' ' M yD e s tr u ct a b le C la s s ' ' ;
}
function __destruct () {
print ' ' Destruyendo ' ' . $this - > name . ' ' \ n ' ' ;
}
}
$obj = new M yD e st r u ct a bl e C la s s () ;
?>
15
Como los constructores, los destructores padre no serán llamados implícitamente por el motor. Para
ejecutar un destructor padre, se deberá llamar explícitamente a parent::__destruct() en el interior
del destructor. También como los constructores, una clase child puede heredar el destructor de los
padres si no implementa uno propio.
El destructor será invocado aún si la ejecución del script es detenida usando exit(). Llamar a exit()
en un destructor evitará que se ejecuten las rutinas restantes de finalización.
Nota: Los destructores invocados durante la finalización del script tienen los headers
HTTP ya enviados. El directorio de trabajo en la fase de finalización del script puede
ser diferente con algunos SAPIs (por ej., Apache).
Nota: Intentar lanzar una excepción desde un destructor (invocado en la finalización del
script) causa un error fatal.
10.
Visibilidad
La visibilidad de una propiedad, un método o (a partir de PHP 7.1.0) una constante se puede
definir anteponiendo a su declaración una de las palabras reservadas public, protected o private. A
los miembros de clase declarados como ’public’se puede acceder desde donde sea; a los miembros
declarados como ’protected’, solo desde la misma clase o mediante clases heredadas. A los miembros
declarados como ’private’únicamente se puede acceder desde la clase que los definió.
10.1.
Visibilidad de propiedades
Las propiedades de clases deben ser definidas como ’public’, ’privateó ’protected’. Si se declaran
usando var, serán definidas como ’public’.
Ejemplo 25 Declaración de propiedades
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<? php
/* *
* Definici ó n de MyClass
*/
class MyClass {
public $public = ' Public ' ;
protected $protected = ' Protected ' ;
private $private = ' Private ' ;
function printHello () {
echo $this - > public ;
echo $this - > protected ;
echo $this - > private ;
}
}
$obj = new MyClass () ;
echo $obj - > public ;
echo $obj - > protected ;
echo $obj - > private ;
$obj - > printHello () ;
//
//
//
//
Funciona bien
Error Fatal
Error Fatal
Muestra Public , Protected y Private
16
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/* *
* Definici ó n de MyClass2
*/
class MyClass2 extends MyClass {
// Se pueden redeclarar las propiedades p ú blica y protegida , pero no
la privada
public $public = ' Public2 ' ;
protected $protected = ' Protected2 ' ;
function printHello () {
echo $this - > public ;
echo $this - > protected ;
echo $this - > private ;
}
}
$obj2 = new MyClass2 () ;
echo $obj2 - > public ;
//
echo $obj2 - > protected ; //
echo $obj2 - > private ;
//
$obj2 - > printHello () ;
//
Funciona bien
Error Fatal
Undefined
Muestra Public2 , Protected2 , Undefined
?>
Nota: La forma de declaración de una variable de PHP 4 con la palabra clave var todavía
es soportado (como un sinónimo de public) por razones de compatibilidad. En PHP 5
antes de 5.1.3, su uso genera un Warning E_STRICT.
10.2.
Visibilidad de Métodos
Los métodos de clases pueden ser definidos como public, private, o protected. Aquellos declarados
sin ninguna palabra clave de visibilidad explícita serán definidos como public.
Ejemplo 26 Declaración de métodos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<? php
/* *
* Definici ó n de MyClass
*/
class MyClass {
// Declaraci ó n de un constructor public
public function $ __construct () $ { }
// Declaraci ó n de un m é todo public
public function MyPublic () { }
// Declaraci ó n de un m é todo protected
protected function MyProtected () { }
// Declaraci ó n de un m é todo private
17
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
private function MyPrivate () { }
// Esto es public
function Foo () {
$this - > MyPublic () ;
$this - > MyProtected () ;
$this - > MyPrivate () ;
}
}
$myclass = new MyClass ;
$myclass - > MyPublic () ; // Funciona
$myclass - > MyProtected () ; // Error Fatal
$myclass - > MyPrivate () ; // Error Fatal
$myclass - > Foo () ; // Public , Protected y Private funcionan
/* *
* Definici ó n 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 ' ' ;
}
18
68
69
70
71
72
73
74
75
76
77
private function testPrivate () {
echo ' ' Foo :: testPrivate \ n ' ' ;
}
}
$myFoo = new Foo () ;
$myFoo - > test () ; // Bar :: testPrivate
// Foo :: testPublic
?>
10.3.
Visibilidad de las constantes
A partir de PHP 7.1.0, las constantes de clase se pueden definir como públicas, privadas o protegidas.
Las constantes declaradas sin una visibilidad explítica serán definidas como públicas.
Ejemplo 27 Declaración de constantes a partir de PHP 7.1.0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<? php
/* *
* Definir MiClase
*/
class MiClase {
// Declarar una constante p ú blica
public const MY_PUBLIC = ' public ' ;
// Declarar una constante protegida
protected const MY_PROTECTED = ' protected ' ;
// Declarar una constante privada
private const MY_PRIVATE = ' private ' ;
public
echo
echo
echo
}
function foo () {
self :: MY_PUBLIC ;
self :: MY_PROTECTED ;
self :: MY_PRIVATE ;
}
$myclass = new MiClase () ;
MiClase :: MY_PUBLIC ; // Funciona
MiClase :: MY_PROTECTED ; // Error fatal
MiClase :: MY_PRIVATE ; // Error fatal
$myclass - > foo () ; // Funcionan Public , Protected y Private
/* *
* Definir MiClase2
*/
class MiClase2 extends MiClase {
// Esta es p ú blica
function foo2 () {
echo self :: MY_PUBLIC ;
19
36
37
38
39
40
41
42
43
44
echo self :: MY_PROTECTED ;
echo self :: MY_PRIVATE ; // Error fatal
}
}
$myclass2 = new MiClase2 ;
echo MiClase2 :: MY_PUBLIC ; // Funciona
$myclass2 - > foo2 () ; // Funcionan Public y Protected , pero no Private
?>
10.4.
Visibilidad desde otros objetos
Los objetos del mismo tipo tendrán acceso a los miembros private y protected entre ellos aunque no
sean de la misma instancia. Esto es porque los detalles específicos de implementación ya se conocen
cuando se encuentra dentro de estos objetos.
Ejemplo 28 Accediendo a miembros private del mismo tipo de objeto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<? php
class Test {
private $foo ;
public function __construct ( $foo ) {
$this - > foo = $foo ;
}
private function bar () {
echo ' M é todo private accedido . ' ;
}
public function baz ( Test $other ) {
// Se puede cambiar la propiedad private :
$other - > foo = ' hola ' ;
var_dump ( $other - > foo ) ;
// Tambi é n se puede invocar al m é todo private :
$other - > bar () ;
}
}
$test = new Test ( ' test ' ) ;
$test - > baz ( new Test ( ' other ' ) ) ;
?>
El resultado del ejemplo es:
1
string (5) ' ' hola ' '
Método private accedido.
20
11.
Herencia de Objetos
La herencia es un principio de programación 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 métodos públicos y protegidos
de la clase padre. A menos que una clase sobrescriba esos métodos, mantendrán su funcionalidad
original.
Esto es útil para la definición y abstracción de la funcionalidad y permite la implementación de
funcionalidad adicional en objetos similares sin la necesidad de reimplementar toda la funcionalidad
compartida.
Nota: A menos que la carga automática 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 29 Ejemplo de herencia
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<? 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 :
?>
Ejemplo :
<? php
class A {
// more code here
21
' Foo : baz '
' PHP is great '
' Bar : baz '
' PHP is great '
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
}
class B extends A {
// more code here
}
class C extends B {
// more code here
}
$someObj = new A () ; // no problems
$someOtherObj = new B () ; // no problems
$lastObj = new C () ; // still no problems
?>
Ejemplo
<? php
class Person {
public $name ;
protected $age ;
private $phone ;
public function talk () {
// Do stuff here
}
protected function walk () {
// Do stuff here
}
private function swim () {
// Do stuff here
}
}
class Tom extends Person {
/* Since Tom class extends Person class this means
that class Tom is a child class and class person is
the parent class and child class will inherit all public
and protected members ( properties and methods ) from
the parent class */
/* So class Tom will have these properties and methods */
// public $name ;
// protected $age ;
// public function talk () {}
// protected function walk () {}
22
85
86
87
88
// but it will not inherit the private members
// this is all what Object inheritance means
}
12.
Operador de Resolución de Ámbito (::)
El Operador de Resolución de Ámbito (también denominado Paamayim Nekudotayim) o en términos
simples, el doble dos-puntos, es un token que permite acceder a elementos estáticos, constantes, y
sobrescribir propiedades o métodos de una clase.
Cuando se hace referencia a estos items desde el exterior de la definición 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).
Paamayim Nekudotayim podría, en un principio, parecer una extraña elección para bautizar a un
doble dos-puntos. Sin embargo, mientras se escribía 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 30 :: desde el exterior de la definición de la clase
1
2
3
4
5
6
7
8
9
10
<? 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
métodos desde el interior de la definición de la clase.
Ejemplo 31 :: desde el interior de la definición de la clase
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<? php
class OtherClass extends MyClass {
public static $my_static = ' variable est á tica ' ;
public static function doubleColon () {
echo parent :: CONST_VALUE . ' ' \ n ' ' ;
echo self :: $my_static . ' ' \ n ' ' ;
}
}
$classname = ' OtherClass ' ;
$classname :: doubleColon () ; // A partir de PHP 5.3.0
OtherClass :: doubleColon () ;
?>
23
Cuando una clase extendida sobrescribe la definición parent de un método, PHP no invocará al
método parent. Depende de la clase extendida el hecho de llamar o no al método parent. Esto
también se aplica a definiciones de métodos Constructores y Destructores, Sobrecarga, y Mágicos.
Ejemplo 32 Invocando a un método parent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<? php
class MyClass {
protected function myFunc () {
echo ' ' MyClass :: myFunc () \ n ' ' ;
}
}
class OtherClass extends MyClass {
// Sobrescritura de definici ó n parent
public function myFunc () {
// Pero todav í a se puede llamar a la funci ó n parent
parent :: myFunc () ;
echo ' ' OtherClass :: myFunc () \ n ' ' ;
}
}
$class = new OtherClass () ;
$class - > myFunc () ;
?>
Véase también algunos ejemplos de trucos de llamadas estáticas .
12.1.
La palabra reservada static
Sugerencia Esta página describe el uso de la palabra reservada static para definir métodos y propiedades estáticos. static también se puede usar para definir variables estáticas
y para enlaces estáticos en tiempo de ejecución. Por favor, consulte estas páginas para
más información sobre estos significados de static.
Declarar propiedades o métodos de clases como estáticos los hacen accesibles sin la necesidad de instanciar la clase. Una propiedad declarada como static no puede ser accedida
con un objeto de clase instanciado (aunque un método estático sí lo puede hacer).
Por motivos de compatibilidad con PHP 4, si no se utiliza ninguna declaración de visibilidad, se
tratará a las propiedades o métodos como si hubiesen sido definidos como public.
13.
Métodos estáticos
Debido a que los métodos estáticos se pueden invocar sin tener creada una instancia del objeto, la
seudovariable $this no está disponible dentro de los métodos declarados como estáticos.
Precaución En PHP 5, llamar a métodos no estáticos de forma estática genera una
advertencia de nivel E_STRICT.
Advertencia En PHP 7, llamar a métodos no estáticos de forma estática está obsoleto
y generará una advertencia E_DEPRECATED. El soporte para las llamadas a métodos no
estáticos de forma estática podría ser eliminado en el futuro.
24
Ejemplo 33 Método estático
1
2
3
4
5
6
7
8
9
10
11
<? php
class Foo {
public static function unMetodoEstatico () {
// ...
}
}
Foo :: unMetodoEstatico () ;
$nombre_clase = ' Foo ' ;
$nombre_clase :: unMetodoEstatico () ; // A partir de PHP 5.3.0
?>
13.1.
Propiedades estáticas
No se puede acceder a las propiedades estáticas a través del objeto utilizando el operador flecha
(->).
Como cualquier otra variable estática de PHP, las propiedades estáticas sólo pueden ser inicializadas
utilizando un string literal o una constante; las expresiones no están permitidas. Por tanto, se puede
inicializar una propiedad estática con enteros o arrays (por ejemplo), pero no se puede hacer con
otra variable, con el valor de devolución de una función, 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 reservada (p.ej., self, parent y static).
Ejemplo 34 Propiedad estática
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<? php
class Foo {
public static $mi_static = ' foo ' ;
public function valorStatic () {
return self :: $mi_static ;
}
}
class Bar extends Foo {
public function fooStatic () {
return parent :: $mi_static ;
}
}
print Foo :: $mi_static . ' ' \ n ' ' ;
$foo = new Foo () ;
print $foo - > valorStatic () . ' ' \ n ' ' ;
print $foo - > mi_static . ' ' \ n ' ' ;
definida
print $foo :: $mi_static . ' ' \ n ' ' ;
$nombreClase = ' Foo ' ;
25
// ' ' Propiedad ' ' mi_static no
25
26
27
28
29
30
print $nombreClase :: $mi_static . ' ' \ n ' ' ; // A partir de PHP 5.3.0
print Bar :: $mi_static . ' ' \ n ' ' ;
$bar = new Bar () ;
print $bar - > fooStatic () . ' ' \ n ' ' ;
?>
14.
Palabra clave Final
PHP 5 introduce la nueva palabra clave final, que impide que las clases hijas sobrescriban un método,
antecediendo su definición con final. Si la propia clase se define como final, entonces no se podrá
heredar de ella.
Ejemplo 35 Métodos Final
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<? 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 36 Clase Final
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<? php
final class BaseClass {
public function test () {
echo ' ' llamada a BaseClass :: test () \ n ' ' ;
}
// Aqu í no importa si definimos una funci ó n 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 ( BaseClass )
26
16
?>
Nota: Las propiedades no pueden declararse como final. Sólo pueden las clases y los
métodos.
15.
Clonación 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, sería si tuviéramos
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 sería 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 réplica del objeto principal, se espera que se cree una nueva instancia de este otro objeto, de
forma que la réplica tenga su propia copia.
Para crear una copia de un objeto se utiliza la palabra clave clone (que invoca, si fuera posible, al
método __clone() del objeto). No se puede llamar al método __clone() de un objeto directamente.
1
$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, mantendrán las referencias.
__clone ( void ): void
Una vez que la clonación ha finalizado, se llamará al método __clone() del nuevo objeto (si el método
__clone() estuviera definido), para permitirle realizar los cambios necesarios sobre sus propiedades.
Ejemplo 37 Clonación de un objeto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<? php
class SubObject {
static $instances = 0;
public $instance ;
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 .
27
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
$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 es:
Objeto Original:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
MyCloneable Object (
[ object1 ] = > SubObject Object (
[ instance ] = > 1
)
[ object2 ] = > SubObject Object (
[ instance ] = > 2
)
)
Objeto Clonado :
MyCloneable Object (
[ object1 ] = > SubObject Object (
[ instance ] = > 3
)
[ object2 ] = > SubObject Object (
[ instance ] = > 2
)
)
PHP 7.0.0 introdujo la posibilidad de acceder a un miembro del objeto recién clonado en una única
expresión:
Ejemplo 38 Acceder a un miembre del objeto recién clonado
1
2
3
4
<? php
$dateTime = new DateTime () ;
echo ( clone $dateTime ) -> format ( ' Y ' ) ;
?>
28
El resultado del ejemplo sería algo similar a:
1
2016
29