La definición básica de una clase comienza con la palabra reservada class, seguido de un nombre de clase, y continuando con un par de llaves que encierran las definiciones de las propiedades y métodos pertenecientes a dicha clase.
El nombre de clase puede ser cualquier etiqueta válida, siempre que 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. Como expresión regular, se expresaría 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 (llamados "métodos").
Ejemplo #1 Definición de una clase sencilla
<?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;
}
}
?>
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 que sea otro objeto si el método es llamado estáticamente desde el contexto de un objeto secundario).
Ejemplo #2 Algunos ejemplos de la pseudovariable $this
<?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()
{
// Nota: la siguiente línea arrojará una advertencia si E_STRICT está habilitado.
A::foo();
}
}
$a = new A();
$a->foo();
// Nota: la siguiente línea arrojará una advertencia si E_STRICT está habilitado.
A::foo();
$b = new B();
$b->bar();
// Nota: la siguiente línea arrojará una advertencia si E_STRICT está habilitado.
B::bar();
?>
El resultado del ejemplo sería:
$this está definida (A) $this no está definida. $this está definida (B) $this no está definida.
Para crear una instancia de una clase, se debe emplear la palabra reservada new. Un objeto siempre se creará a menos que el objeto tenga un constructor que arroje una excepción en caso de error. Las clases deberían ser definidas antes de la instanciación (y en algunos casos esto es un requerimiento).
Si se emplea un string que contenga el nombre de una clase con new, se creará una nueva instancia de esa clase. Si la clase estuviera en un espacio de nombres, se debe utilizar su nombre completo al realizar esto.
Ejemplo #3 Creación de una instancia
<?php
$instancia = new ClaseSencilla();
// Esto también se puede hacer con una variable:
$nombreClase = 'Foo';
$instancia = new $nombreClase(); // Foo()
?>
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
$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 sería:
NULL NULL object(ClaseSencilla)#1 (1) { ["var"]=> string(27) "$asignada tendrá este valor" }
PHP 5.3.0 introdujo un par de formas nuevas para crear instancias de un objeto:
Ejemplo #5 Creación de nuevos objetos
<?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 sería:
bool(true) bool(true) bool(true)
Una clase puede heredar 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 puede heredar 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 podrá ser sobrescrito. Es posible acceder a los métodos sobrescritos o a las propiedades estáticas haciendo referencia a ellos con parent::.
Cuando se sobrescriben métodos, la firma de los parámetros debería ser 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 #6 Herencia de clases sencilla
<?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 sería:
Clase extendida un valor predeterminado
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 #7 Resolución de nombres de clases
<?php
namespace NS {
class NombreClase {
}
echo NombreClase::class;
}
?>
El resultado del ejemplo sería:
NS\NombreClase