JTagua

Tutorial PHP(46): Introducción a clases y objetos.

Licencia

Creative Commons License

Visitas:

  • 773.763 hits
Anuncios

Tutorial PHP(46): Introducción a clases y objetos.

class

La definición básica 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 métodos pertenecientes a la clase.

El nombre de clase puede ser cualquier etiqueta válida 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 la cantidad de letras, números o guiones bajos que sea. Como una 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 (llamadas “métodos”).

Ejemplo #1 Definición simple de una clase

<?php
class SimpleClass
{
    // Declaración de la propiedad
    public $var = 'a default value';

    // Declaración del método
    public function displayVar() {
        echo $this->var;
    }
}
?>

La pseudo-variable $this está disponible cuando un método es invocado dentro del contexto de un objeto. $this es una referencia del objeto que invoca (usualmente el objeto al que el método pertenece, pero posiblemente sea otro objeto, si el método es llamado estáticamente 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 {
            echo "\$this no está definida.\n";
        }
    }
}

class B
{
    function bar()
    {
        // Nota: la siguiente línea arrojará un Warning si E_STRICT está habilitada.
        A::foo();
    }
}

$a = new A();
$a->foo();

// Nota: la siguiente línea arrojará un Warning si E_STRICT está habilitada.
A::foo();
$b = new B();
$b->bar();

// Nota: la siguiente línea arrojará un Warning si E_STRICT está habilitada.
B::bar();
?>

El resultado del ejemplo sería:

$this está definida (A)
$this no está definida.
$this está definida (B)
$this 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 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 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 Creación de una instancia

<?php
$instance = new SimpleClass();

// Esto también 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 función. Una copia de un objeto ya creado se puede lograr a través de la clonación de la misma.

Ejemplo #4 Asignación de objetos

<?php

$instance = new SimpleClass();

$assigned   =  $instance;
$reference  =& $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 sería:

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 sería:

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

extends

Una clase puede heredar los métodos y propiedades de otra clase al utilizar la palabra clave extends en la declaración de la clase. No es posible extender 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 parent. Sin embargo, si la clase parent definió un método como final, éste no podrá ser sobrescrito. Es posible acceder a los métodos sobrescritos o propiedades estáticas referenciándolos con parent::.

Cuando se sobrescriben métodos, la cantidad y disposición de los parámetros debería 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 parámetros.

Ejemplo #6 Herencia simple de clases

<?php
class ExtendClass extends SimpleClass
{
    // Redefinición del método parent
    function displayVar()
    {
        echo "Clase extendida\n";
        parent::displayVar();
    }
}

$extended = new ExtendClass();
$extended->displayVar();
?>

El resultado del ejemplo sería:

Clase extendida
un valor por defecto

::class

Desde PHP 5.5, la palabra clave class también se usa para la resolución de nombres de clases. Se puede obtener un string con un nombre completamente cualificado de la clase NombreClase usando NombreClase::class. Esto es particularmete útil con clases con 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

Anuncios

Los números de 2013

Los duendes de las estadísticas de WordPress.com prepararon un informe sobre el año 2013 de este blog.

Aquí hay un extracto:

El Museo del Louvre tiene 8.5 millones de visitantes por año. Este blog fue visto cerca de 130.000 veces en 2013. Si fuese una exposición en el Museo del Louvre, se precisarían alrededor de 6 días para que toda esa gente la visitase.

Haz click para ver el reporte completo.

Tutorial PHP(45): Funciones anónimas.

Funciones anónimas.

Las funciones anónimas, también conocidas como clausuras (closures), permiten la creación de funciones que no tienen un nombre especificado. Son más útiles como valor de los parámetros de llamadas de retorno, pero tienen muchos otros usos.

Ejemplo #1 Ejemplo de función anónima

<?php
echo preg_replace_callback('~-([a-z])~', function ($coincidencia) {
    return strtoupper($coincidencia[1]);
}, 'hola-mundo');
// imprime holaMundo
?>

Las clausuras también se pueden usar como valores de variables; PHP automáticamente convierte tales expresiones en instancias de la clase interna Closure. Se asume que una clausura a una variable usa la misma sintaxis que cualquier otra asignación, incluido el punto y coma final:

Ejemplo #2 Ejemplo de asignación de variable de una función anónima

<?php
$saludo = function($nombre)
{
    printf("Hola %s\r\n", $nombre);
};

$saludo('Mundo');
$saludo('PHP');
?>

Las clausuras también pueden heredar variables del ámbito padre. Cualquier variable de estas debe ser declarada en la cabecera de la función. Heredar variables del ámbito padre no es lo mismo que usar variables globales. Las variables globales existen en el ámbito global, lo que implica que no importa qué función se esté ejecutando. El ámbito padre de una clausura es la función en la que la clausura fue declarado (no necesariamente la función desde la que se llamó). Vea el siguiente ejemplo:

Ejemplo #3 Clausuras y ámbito

<?php
// Un carro de compras básico que contiene una lista de productos añadidos
// y la cantidad de cada producto. Incluye un método que
// calcula el precio total de los artículos del carro usando una
// clausura como llamada de retorno.
class Carro
{
    const PRECIO_MANTEQUILLA = 1.00;
    const PRECIO_LECHE       = 3.00;
    const PRECIO_HUEVOS      = 6.95;

    protected $productos = array();
    
    public function añadir($producto, $cantidad)
    {
        $this->productos[$producto] = $cantidad;
    }
    
    public function obtenerCantidad($producto)
    {
        return isset($this->productos[$producto]) ? $this->productos[$producto] :
               FALSE;
    }
    
    public function obtenerTotal($impuesto)
    {
        $total = 0.00;
        
        $llamadaDeRetorno =
            function ($cantidad, $producto) use ($impuesto, &$total)
            {
                $precioUnidad = constant(__CLASS__ . "::PRECIO_" .
                    strtoupper($producto));
                $total += ($precioUnidad * $cantidad) * ($impuesto + 1.0);
            };
        
        array_walk($this->productos, $llamadaDeRetorno);
        return round($total, 2);
    }
}

$mi_carro = new Carro;

// Añadir algunos artículos al carro
$mi_carro->añadir('mantequilla', 1);
$mi_carro->añadir('leche', 3);
$mi_carro->añadir('huevos', 6);

// Imprimir el total con un impuesto de venta del 5%.
print $mi_carro->obtenerTotal(0.05) . "\n";
// El resultado es 54.29
?>

Las funciones anónimas son implementadas usando la clase Closure.
Historial de cambios

Versión Descripción
5.4.0 $this puede ser usado en funciones anónimas.
5.3.0 Las funciones anónimas se encuentran disponibles.

Nota: Es posible usar func_num_args(), func_get_arg(), y func_get_args() desde dentro de una clausura.

Tutorial PHP(44): Funciones internas.

PHP se estandariza con muchas funciones y construcciones. También existen funciones que necesitan extensiones específicas de PHP compiladas, si no, aparecerán errores fatales “undefined function” (“función no definida”). Por ejemplo, para usar las funciones de image tales como imagecreatetruecolor(), PHP debe ser compilado con soporte para GD. O para usar mysql_connect(), PHP debe ser compilado con soporte para MySQL. Hay muchas funciones de núcleo que está incluidas en cada versión de PHP, tales como las funciones de string y de variable. Una llamada a phpinfo() o get_loaded_extensions() mostrará las extensiones que están cargadas en PHP. Observe también que muchas extensiones están habilitadas por defecto y que el manual de PHP está dividido por extensiones. Véase configuración, instalación, y capítulos individuales de extensiones para más información sobre cómo configurar PHP.

Interpretar y comprender un prototipo de una función está explicado dentro de la sección del manual titulada cómo interpretar la definición de una función. Es importante comprender lo que devuelve una función o si una función funciona directamente con un valor pasado. Por ejemplo, str_replace() devolverá la cadena modificada mientras que usort() funciona con la variable actual pasada. Cada página del manual también tiene información específica para cada función, como información sobre parámetros de funciones, cambios de comportamiento, valores devueltos en caso de éxito o fallo, e información de disponibilidad. Conocer estas importantes diferencias (a menudo imperceptibles) es crucial para escribir código de PHP correcto.

Nota: Si los parámetros dados a una función no son los que se esperaban, como pasar un array donde se esperaba un string, el valor devuelto de la función será indefinido. En este caso lo más probable es que devuelva NULL pero esto es sólo una convención, y no se puede confiar en ello.

Véase también function_exists(), la referencia de funciones, get_extension_funcs(), y dl().

Tutorial PHP(43): Funciones variables.

Funciones variables.

PHP soporta el concepto de funciones variables. Esto significa que si un nombre de variable tiene paréntesis anexos a él, PHP buscará una función con el mismo nombre que lo evaluado por la variable, e intentará ejecutarla. Entre otras cosas, esto se puede usar para implementar llamadas de retorno, tablas de funciones, y así sucesivamente.

Las funciones variables no funcionarán con constructores de lenguaje como echo, print, unset(), isset(), empty(), include, require y similares. Utilice funciones de envoltura para hacer uso de cualquiera de estos constructores como funciones variables.

Ejemplo #1 Ejemplo de función variable

<?php function foo() {
    echo "En foo()\n";
}

function bar($arg = '')
{
    echo "En bar(); el argumento era '$arg'.\n";
}

// Esta es una función de envoltura alrededor de echo
function hacerecho($cadena)
{
    echo $cadena;
}

$func = 'foo';
$func();        // Esto llama a foo()

$func = 'bar';
$func('prueba');  // Esto llama a bar()

$func = 'hacerecho';
$func('prueba');  // Esto llama a hacerecho()
?>

Los métodos de objetos también puede ser llamados con la sintaxis de funciones variables.

Ejemplo #2 Ejemplo de método variable

<?php  function Variable()     {   
      $nombre = 'Bar';
      $this--->$nombre(); // Esto llama al método Bar()
    }

    function Bar()
    {
        echo "Esto es Bar";
    }
}

$foo = new Foo();
$nombrefunc = "Variable";
$foo->$nombrefunc();  // Esto llama a $foo->Variable()
?>

Cuando se llaman a métodos estáticos, la llamada a la función es más fuerte que el operador de propiedad static:

Ejemplo #3 Ejemplo de método variable con propiedades estáticas

class Foo
{
    static $variable = 'propiedad estática';
    static function Variable()
    {
        echo 'Método Variable llamado';
    }
}

echo Foo::$variable; // Esto imprime 'propiedad estática'. No necesita una $variable en este ámbito.
$variable = "Variable";
Foo::$variable();  // Esto llama a $foo->Variable() leyendo $variable en este ámbito.

?>

Véase también is_callable(), call_user_func(), variables variables y function_exists().

Tutorial PHP(41): Argumentos de funciones.

La información puede ser pasada a las funciones mediante la lista de argumentos, la cual es una lista de expresiones delimitadas por comas. Los argumentos son evaluados de izquierda a derecha.

PHP soporta argumentos pasados por valor (por defecto), pasados por referencia, y valores de argumentos predeterminados. Las Listas de argumentos de longitud variable también están soportadas, vea también las referencias de funciones para func_num_args(), func_get_arg(), y func_get_args() para más información.

Ejemplo #1 Pasar arrays a funciones

<?php
function tomar_array($entrada)
{
    echo "$entrada[0] + $entrada[1] = ".$entrada[0]+$entrada[1];
}
?>

Hacer que los argumentos sean pasados por referencia ¶

Por defecto, los argumentos de las funciones son pasados por valor (por lo que si el valor del argumento dentro de la función se cambia, no se cambia fuera de la función). Para permitir a una función modificar sus argumentos, éstos deben pasarse por referencia.

Para hacer que un argumento a una función sea siempre pasado por referencia hay que poner delante del nombre del argumento el signo ‘ampersand’ (&) en la definición de la función:

Ejemplo #2 Pasar parámetros de una función por referencia

<?php
function añadir_algo(&$cadena)
{
    $cadena .= 'y algo más.';
}
$cad = 'Esto es una cadena, ';
añadir_algo($cad);
echo $cad;    // imprime 'Esto es una cadena, y algo más.'
?>

Valores de argumentos predeterminados ¶

Una función puede definir valores predeterminados al estilo C++ para argumentos escalares como sigue:

Ejemplo #3 Uso de parámetros predeterminados en funciones

<?php
function hacercafé($tipo = "capuchino")
{
    return "Hacer una taza de $tipo.\n";
}
echo hacercafé();
echo hacercafé(null);
echo hacercafé("espresso");
?>

El resultado del ejemplo sería:

Hacer una taza de capuchino.
Hacer una taza de .
Hacer una taza de espresso.

PHP también permite el uso de arrays y del tipo especial NULL como valores predeterminados, por ejemplo:

Ejemplo #4 Usar tipos no escalares como valores predeterminados

<?php
function hacercafé($tipos = array("capuchino"), $fabricanteCafé = NULL)
{
    $aparato = is_null($fabricanteCafé) ? "las manos" : $fabricanteCafé;
    return "Hacer una taza de ".join(", ", $tipos)." con $aparato.\n";
}
echo hacercafé();
echo hacercafé(array("capuchino", "lavazza"), "una tetera");
?>

El valor predeterminado debe ser una expresión constante, no (por ejemplo) una variable, un miembro de una clase o una llamada a una función.

Observe que cuando se usan argumentos predeterminados, cualquiera de ellos debería estar a la derecha de los argumentos no predeterminados; si no, las cosas no funcionarán como se esperaba. Considere el siguiente trozo de código:

Ejemplo #5 Uso incorrecto de argumentos predeterminados en una función

 
<?php
function haceryogur($tipo = "acidófilo", $sabor)
{
    return "Hacer un tazón de yogur $tipo de $sabor.\n";
}
 
echo haceryogur("frambuesa");   // no funcionará como se esperaba
?>

El resultado del ejemplo sería:

Warning: Missing argument 2 in call to haceryogur() in
/usr/local/etc/httpd/htdocs/phptest/functest.html on line 41
Hacer un tazón de yogur frambuesa de .

Ahora compare el ejemplo de arriba con este:

Ejemplo #6 Uso correcto de argumentos predeterminados en una función

<?php
function haceryogur($sabor, $tipo = "acidófilo")
{
    return "Hacer un tazón de yogur $tipo de $sabor.\n";
}
 
echo haceryogur("frambuesa");   // funciona como se esperaba
?>

El resultado del ejemplo sería:

Hacer un tazón de yogur acidófilo de frambuensa.

Nota: A partir de PHP 5, los argumentos que son pasados por referencia pueden tener un valor predeterminado.

Listas de argumentos de longitud variable ¶

PHP tiene soporte para listas de argumentos de longitud variable en funciones definidas por el usuario. Esto realmente es bastante fácil si se usan las funciones func_num_args(), func_get_arg(), y func_get_args().

No se necesita una sintaxis especial, y la lista de argumentos aún puede ser proporcionada explícitamente con definiciones de funciones, y se comportará con normalidad.

Tutorial PHP(42): Devolución de valores.

Devolución de valores.

Los valores son devueltos usando la sentencia opcional return. Se puede devolver cualquier tipo, incluidos arrays y objetos. Esto causa que la función finalice su ejecución inmediatamente y pase el control de nuevo a la línea desde la que fue llamada. Véase return para más información.

Nota: Si se omite return será devuelto el valor NULL.

Ejemplo #1 Uso de return

<?php
  function cuadrado($núm) {
   return $núm * $núm;
 }
   echo cuadrado(4);   // imprime '16'.
 ?>

Una función no puede devolver múltiples valores, pero se pueden obtener resultados similares devolviendo un array.

Ejemplo #2 Devolver un array para obtener múltiples valores

<?php
function números_pequeños()  { 
   return array (0, 1, 2);
 }
 list ($cero, $uno, $dos) = números_pequeños();
?>

Para devolver una referencia desde una función use el operador de referencia &, en la declaración de la función y cuando se asigne el valor devuelto a una variable:

Ejemplo #3 Devolver una referencia desde una función

<?php
function &devolver_referencia() {
   return $algunaref;
 }
 $nuevaref =& devolver_referencia();
 ?>

Para más información sobre referencias, por favor, lea las Referencias Explicadas.

Tutorial PHP(40): Funciones definidas por el usuario.

Una función puede ser definida usando una sintaxis como la siguiente:

Ejemplo #1 Pseudo código para demostrar el uso de funciones

<?php 
function foo($arg_1, $arg_2, /* ..., */ $arg_n)
{
    echo "Función de ejemplo.\n";
    return $valordevuelto;
}
?>

Cualquier código PHP válido puede aparecer dentro de una función, incluso otras funciones y definiciones de clases. Los nombres de las funciones siguen las mismas reglas que otras etiquetas de PHP. Un nombre de función válido comienza con una letra o guión bajo, seguido de cualquier número de letras, números, o guiones bajos. Como expresión regular se expresaría así: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*.

Sugerencia

Vea también Guia de Entorno de Usuario para Nombres.

Las funciones no necesitan ser definidas antes de que se referencien, excepto cuando una función está condicionalmente definida como se muestra en los dos ejemplos de abajo.

Cuando una función está definida de una forma condicional como en los dos ejemplos mostrados, sus definiciones deben ser procesadas antes de ser llamadas.

Ejemplo #2 Funciones condicionales

<?php

$haceralgo = true;

/* No podemos llamar a foo() desde aquí
   ya que no existe aún,
   pero podemos llamar a bar() */

bar();

if ($haceralgo) {
  function foo()
  {
    echo "No existo hasta que la ejecución del programa llegue hasta mí.\n";
  }
}

/* Ahora podemos llamar de forma segura a foo()
   ya que $haceralgo se evaluó como verdadero */

if ($haceralgo) foo();

function bar() 
{
  echo "Existo desde el momento inmediato que comenzó el programa.\n";
}
?>

Ejemplo #3 Funciones dentro de funciones

<?php
function foo() 
{
  function bar() 
  {
    echo "No existo hasta que se llame a foo().\n";
  }
}

/* No podemos llamar aún a bar()
   ya que no existe. */

foo();

/* Ahora podemos llamar a bar(),
   el procesamiento de foo()
   la ha hecho accesible. */

bar();
?>

Todas las funciones y las clases de PHP tienen ámbito global – pueden ser llamadas fuera de una función incluso si fueron definidas dentro, y viceversa.

PHP no soporta la sobrecarga de funciones, ni es posible ‘desdefinir’ ni redefinir funciones previamente declaradas.

Nota: Los nombres de las fuciones son insensibles a mayúsculas-minúsculas, por lo que es una buena idea llamar a las funciones tal y como aparecen en sus declaraciones.

El número variable de argumentos y los argumentos predeterminados están soportados por las funciones. Vea también las referencias de funciones para func_num_args(), func_get_arg(), y func_get_args() para más información.

En PHP es posible llamar a funciones recursivas. Sin embargo, evite las llamadas a funciones/métodos recursivos con más de 100-200 niveles de recursividad ya que pueden agotar la pila y causar la terminación del script actual.

Ejemplo #4 Funciones recursivas

<?php
function recursividad($a)
{
    if ($a < 20) {
        echo "$a\n";
        recursividad($a + 1);
    }
}
?>

Tutorial PHP(38): require, require_once

require

(PHP 4, PHP 5)

require es idéntico a include excepto que en caso de fallo producirá un error fatal de nivel E_COMPILE_ERROR. En otras palabras, éste detiene el script mientras que include sólo emitirá una advertencia (E_WARNING) lo cual permite continuar el script.

Véase la documentación de include para más información.

require_once

(PHP 4, PHP 5)

La sentencia require_once es idéntica a require excepto que PHP verificará si el archivo ya ha sido incluido y si es así, no se incluye (require) de nuevo.

Ver la documentación de include_once para información sobre el comportamiento de _once, y como difiere de sus hermanos no _once.

Tutorial PHP(39): goto.

goto

(PHP 5 >= 5.3.0)

El operador goto puede ser usado para saltar a otra sección en el programa. El punto de destino es especificado mediante una etiqueta seguida de dos puntos y la instrucción es dada como goto seguida de la etiqueta del destino deseado. Este goto no es completamente sin restricciones. La etiqueta de destino debe estar dentro del mismo fichero y contexto, lo que significa que no se puede saltar fuera de una función o método, ni se puede saltar dentro de uno. Tampoco se puede saltar dentro de cualquier clase de estructura de bucle o switch. Se puede saltar fuera de estos y un uso común es utilizar un goto en lugar de un break multi-nivel.

Ejemplo #1 Ejemplo de goto

<?php
 goto a;
 echo 'Foo';
 a: echo 'Bar';
?>

El resultado del ejemplo sería:

Bar

Ejemplo #2 Ejemplo de goto en un bucle

<?php
 for($i=0,$j=50; $i<100; $i++) {
   while($j--) {
     if($j==17) goto end; 
  }   }
 echo "i = $i";
end: echo 'j alcanzó 17';
?>

El resultado del ejemplo sería:

j alcanzó 17

Ejemplo #3 Esto no funcionará

<php
 goto loop;
 for($i=0,$j=50; $i<100; $i++) {  
 while($j--) {   
  loop:
   }
 } echo "$i = $i";
?>

El resultado del ejemplo sería:

Fatal error: ‘goto’ into loop or switch statement is disallowed in script on line 2
(Error fatal: ‘goto’ hacia el interior de un bucle o sentencia switch no esta permitido en el script en la línea 2)

Nota: El operador goto está disponible a partir de PHP 5.3.