SlideShare ist ein Scribd-Unternehmen logo
1 von 103
Lenguajes de Script.
En el servidor web: PHP.
Universidad Nacional de Ingeniería
FACULTAD DE CIENCIAS Y SISTEMAS Departamento de Informática
Índice:
Lenguaje PHP 7.
Introducción:
En esta sección aprenderás a desarrollar sistemas web (una aplicación web
enlazada a un repositorio de datos) utilizando el Lenguaje PHP siguiendo el
paradigma de Programación Orientada a Objetos.
Primero necesitas entender los fundamentos de éstos: HTTP y sistemas cliente-
servidor.
El protocolo HTTP:
El estándar RFC 2068 deja establecido al Hyper Text Transfer Protocol (Protocolo
de Transferencia de Hipertexto) como un conjunto de normas para el intercambio
de datos entre computadoras que permite buscar y recuperar recursos.
Gracias a este protocolo en la Capa de Aplicación, el usuario al interactuar con el
navegador web puede realizar sus actividades.
HTTP se basa en el principio cliente-servidor: las solicitudes son generalmente
enviadas al inicio por una entidad denominada agente de usuario (o un proxy a
petición de uno) que puede ser un navegador web. Cada petición es dirigida a un
servidor que al final la gestionará y responderá. Entre ellos hay varios
intermediarios.
Desde el punto de vista del cliente el flujo es así:
1. Abrir o reusar una conexión TCP.
2. Realizar la petición HTTP:
Método Versión del protocolo
3. Leer la respuesta del servidor:
GET / HTTP/1.1
Host: developer.mozilla.org
Accept-Language: es
HTTP/1.1 200 OK
Date: Sat, 09 Oct 2010 14:28:02 GMT
Server: Apache
Last-Modified: Tue, 01 Dec 2009 20:18:22 GMT
ETag: "51142bc1-7449-479b075b2891b"
Accept-Ranges: bytes
Content-Length: 29769
Content-Type: text/html
<!DOCTYPE html... (here comes the 29769 bytes of the requested web
page)
Mensaje de estadoVersión del protocolo Código de estado
Encabezado
s
Respuesta
Figura 1. Ejemplo de petición HTTP. Enviada por el navegador
Figura 2. Ejemplo de respuesta HTTP de un servidor
El lenguaje PHP:
PHP (acrónimo recursivo que significa PHP Hypertext Preprocesor), fue creado en
1995 por Rasmus Lerdorf. Según Cobo (2005), es un lenguaje open source
interpretado del lado del servidor para ser robusto, versátil y modular cuyos
programas ejecutados en el servidor son embebidos en el código HTML al enviar al
cliente. Es multiplataforma y compatible con diferentes bases de datos.Los ficheros,
para que puedan ser reconocidos por el intérprete, deberán de tener la extensión
php. El código en este lenguaje debe estar encerrado entre las etiquetas <?php y
?>.
Sintaxis de PHP:
El código PHP debe estar delimitado por las etiquetas: <?php y ?> o bien <? ?> en
caso de que el valor de la directiva short_open_tag sea “1” en el archivo php.ini,
aunque la última etiqueta ?> es opcional. Las instrucciones deberán terminar con
“;”. Los comentarios se deberán escribir posterior a // para el caso de los
comentarios de una sola línea. En el caso de los comentarios multilínea, estos
deberán escribirse entre las etiquetas /**/.
<?php
//Ejemplo de código php
function haceAlgo(){
echo “Hello World!”;
}
haceAlgo();
?>
Código 1. Ejemplo de fichero PHP que imprime el mensaje en pantalla “Hola Mundo"
Tipos de datos de PHP:
En PHP el tipo de una variable es decido en tiempo de ejecución. PHP 7 admite 10
tipos primitivos, la mayoría similares a otros lenguajes de programación:
Tiposdedatosprimitivos
Escalares
boolean
integer
float
string
Compuestos
array: Estructura de datos en forma de mapa ordenado
object Para las instancias de clase
callable
iterable
Especiales
resource
Contiene referencia a recurso externo mantenido por
funciones especiales
null
Figura 3. Tipos de datos en PHP
Declaración, asignación de variables y operaciones:
En PHP toda variable debe empezar con $ seguido del nombre de la variable, que
puede empezar con _ (guión bajo) o letras. El resto de caracteres también puede
ser alfanumérico. El operador de asignación es =.
Precedencia de operadores:
La siguiente tabla la detalla:
Asociatividad Operadores Información adicional
no asociativo clone new clone and new
izquierda [ array()
derecha ** aritmética
derecha ++ -
- ~ (int) (float) (string) (array) (object)
(bool) @
tipos e incremento/decremento
no asociativo instanceof tipos
derecha ! lógico
izquierda * / % aritmética
izquierda + - . aritmética y string
izquierda << >> bit a bit
no asociativo < <= > >= comparación
no asociativo == != === !== <> <=> comparación
izquierda & bit a bit y referencias
izquierda ^ bit a bit
izquierda | bit a bit
izquierda && lógico
izquierda || lógico
derecha ?? comparación
izquierda ? : ternario
derecha = += -
= *= **= /= .= %= &= |= ^= <<= >>=
asignación
izquierda and lógico
izquierda xor lógico
izquierda or lógico
Tabla 1. Precedencia de operadores en PHP.
Fuente: PHP Group (2018) Manual de PHP: Precedencia de operadores recuperado de:
https://secure.php.net/manual/es/language.operators.precedence.php el 18 de septiembre de 2018.
En el siguiente código tomado de López (2016) se puede observar algunos de estos
con mayor claridad:
En el primer caso tenemos una operación de asignación, una aritmética, y una
lógica. El operador con la mayor preferencia es la suma, así que primero se realiza
1+3 igual a 4, luego se realiza la comparación lógica, donde la expresión 4>5 resulta
falsa, luego se evalúa la expresión false||$c (donde $c es true) lo que resulta en
verdadero, valor que se asigna a la variable $e.
En el segundo caso, el primer operador que vemos en la mesa es la negación,
entonces la resolvemos: !$d es !falso, entonces es cierto. La expresión ahora es,
$e == verdadero && verdadero. Primero tenemos que resolver la comparación $e
== verdadero. Sabiendo que $e es verdadero, la comparación resulta verdadera.
La operación final es el and lógico y resulta verdadero.
En el último caso, debido a los paréntesis se realiza la sumatoria de $a y $b, esto a
su vez se multiplica por 2, luego se realiza la multiplicación entre 3 y 4. Por último
se realiza la suma. Por último, la función integrada var_dump muestra el tipo y valor
de las variables. La salida en el navegador para este ejemplo es:
<?php
$a = 1;
$b = 3;
$c = true;
$d = false;
$e = $a + $b > 5 || $c; // true
var_dump($e);
$f = $e == true && !$d; // true
var_dump($f);
$g = ($a + $b) * 2 + 3 * 4; // 20
var_dump($g);
?>
bool(true) bool(true) int(20)
Código 2. Ejemplo de precedencia de operadores
Algunos ejemplos de archivos en PHP:
Como se mencionó anteriormente, para que el código fuente sea reconocido por el
intérprete, los ficheros deben tener la extensión php, sin embargo esto no implica
mantener el resto de código web. El intérprete de PHP ignora lo que no se encuentra
en este lenguaje y lo devuelve al navegador en bruto. Por tanto si es código CSS,
HTML o JS el navegador será el que lo procese. También es posible devolverlos
utilizando los constructores echo o print. Las imágenes siguientes demuestran lo
mencionado:
Código 3. Ejemplo de archivo que combina PHP y HTML. (Fuente: elaboración propia para la empresa Maltez
Ingenieros & Cía. Ltda.)
<?php
$s=$_SERVER['SERVER_NAME'];
$p=$_SERVER['SERVER_PORT'];
$url=$_SERVER['REQUEST_URI'];
$referer=$_SERVER['HTTP_REFERER'];
$dir= explode('/',$referer);
$rutabase=$dir[0].'/'.$dir[1].'/'.$dir[2].'/'.$dir[3];
echo '
<div class="col-12">
<p>Contáctenos</p>
</div>
<div class="col-lg-1 datoContacto">
<a class="nav-link"
href="https://api.whatsapp.com/send?phone=50588623846">
<img class="iconoSocial"
src="'.$rutabase.'/img/icons/whatsapp.png"
alt="Ícono WhatsApp">
</a>
<a class="nav-link" href="https://www.facebook.com/krmaltez">
<img class="iconoSocial" src="'.$rutabase.'/img/icons/fb.png"
alt="Ícono WhatsApp">
</a>
</div>
<div class="col-lg-2 datoContacto">
<img src="'.$rutabase.'/img/icons/telefono.png">
<a>(+505) 2252-4889</a>
</div>
<div class="col-lg-4 datoContacto">
<img src="'.$rutabase.'/img/icons/correo.png">
<a class="nav-link"
href="mailto:maltezingrmc@hotmail.com">maltezingrmc@hotmail.com</a>
</div>
<div class="col-lg-5 datoContacto">
<img src="'.$rutabase.'/img/icons/direccion.png">
<a>Bo. Riguero, del Parque Bill Stewart 1 C al N y 1/2 C al E.
Managua, Nicaragua.</a>
</div>
<div class="col-12">
<p>Sitio desarrollado por Gabriel Chavez Toruño, ©Maltez
Ingenieros</p>
</div>
’;
Código 4. PHP también puede escribir código HTML (Fuente: elaborado por el autor para la empresa Maltez
Ingenieros & Cia. Ltda.).
Figura 4. Resultado del código anterior.
Estructuras de control en PHP:
Para el control de flujo en la ejecución de código, se dispone de varias estructuras:
Ejemplo de bucle while
<?php
/* Factorial de un número */
$f=1; $n=5;
while ($n>=1) {
$f=$f*($n--);
}
echo $f;
?>
Ejemplo de If, else y else if
<?php
if ($a > $b) {
echo "a es mayor que b";
} else if ($a == $b) {
echo "a es igual que b";
} else {
echo "a es menor que b";
}
?>
Código 5. Ejemplo de if, else y else if Código 6. Cálculo del factorial de un número.
Ejemplo de bucle do-while
<?php
$f=1; $n=5;
do {
$f=$f*($n--);
}
while ($n>1);
echo $f;
?>
Código 7. Cálculo del factorial utilizando un bucle do-while.
Ejemplo de bucle for
<?php
$marcas=['Vokswagen', 'Ford', 'Suzuki', 'GM ', 'Chevrolet'];
for($i=0; $i<count($marcas); $i++){
echo $marcas[$i].'n';
}
?>
Código 8. El bucle recorre el arreglo e imprime cada elemento mientras el índice sea menor a la longitud de aquel
(obtenida mediante la función count())
Código 9 y Figura 5 El bucle foreach permite iterar de forma fácil sobre arreglos y objetos realizando un recorrido
completo sobre el mismo. En este ejemplo la salida es:
Ejemplo de bucle foreach
<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8"/>
<title>Ejemplo PHP</title>
</head>
<body>
<h1>
Ejemplo de bucle foreach
</h1>
<h3>
Resultado:
</h3>
<div id="resPHP">
<?php
$a = array(
"primero" => 'Carlos',
"segundo" => 'Enrique',
"tercero" => 'Luisa',
"quinto" => 'Agnes'
);
foreach ($a as $k => $v) {
echo "$a[$k] => $v<br/>";
}
?>
</div>
</body>
</html>
Ejemplo de switch
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h3>Ingresa un número</h3>
<form action="index.php" method="POST">
<input type="number" name="nb" placeholder="x">
<button type="submit">Enviar</button>
</form>
<?php
// put your code here
$x=filter_input(INPUT_POST, 'nb',
FILTER_SANITIZE_NUMBER_FLOAT);
$numero=($x!==false && $x!=='')?$x:'s';
switch ($numero) {
case ($numero===0):
echo "Este valor no es admitido";
break;
case ($numero<0):
echo "Este número es negativo";
break;
case ($numero>0):
echo "Este número es positivo";
break;
default:
break;
}
?>
</body>
</html>
Código 10. Ejemplo de estructura switch. En este código existe comunicación sincrónica, por lo que el resultado se
mostrará después que la página recargue.
Figura 6. Resultado del código anterior: la foto izq. muestra el mensaje cuando se ingresa 0; la del centro, cuando se
ingresa un número positivo y la de la derecha, cuando es negativo
Break y continue en PHP
Las instrucciones Break y continue funcionan con las estructuras de
control for, foreach, while, do-while o switch. Break finaliza la
ejecución de toda la estructura mientras que continue, dentro los ciclos,
permite saltar la ronda actual. Continue y Break pueden recibir como
parámetro la cantidad de niveles de bucles encerrados a saltar o
finalizar, respectivamente.
while ( $x ) {
continue;
break;
}
El siguiente código es adaptado de la documentación de PHP en español.
<?php
for( $i = 0; $i < 3; ++ $i )
{
echo ' [', $i, ']:<br>';
switch( $i )
{
case 0: echo 'uno<br/>'; break;
case 1: echo 'dos<br/>' ; XXXX;
case 2: echo 'tres<br/>' ; break;
}
echo ' <' , $i, '><br/><br/> ';
}
?>
Salta aquí
Vuelve aquí
Figura 7. Si se reemplaza la expresión XXXX por continue o break se obtiene diferentes resultados: Izq. muestra
el resultado si se reemplaza por continue o break (con parámetro 1); centro, utilizando continue 2 y der.,
utilizando break 2
Código 11. Ejemplo de break y continue
Sintaxis alternativa de estructuras de control:
Para if, else, elseif, while, for, foreach y switch existe una forma opcional en la cual
se cambia la llave de apertura por dos puntos (:) y la llave de cierre por endif,
endwhile, endfor, endforeach o endswitch, respectivamente seguido de punto y
coma (;). La estructura do-while no tiene una forma sintáctica opcional.
En el caso de switch, no debe haber salidas como espacios en blanco antes del
primer case.
En el ejemplo anterior el texto html se imprimirá solo si la variable $a es igual a 5.
A continuación un ejemplo de condicionales:
<?php if ($a == 5): ?>
A es igual a 5
<?php endif; ?>
<?php
if ($a == 5):
echo "a igual 5";
echo "...";
elseif ($a == 6):
echo "a igual 6";
echo "!!!";
else:
echo "a no es 5 ni 6";
endif;
?>
Código 12. Ejemplo de if con sintaxis alternativa. Fuente: PHP Group (2018) Manual de PHP: Sintaxis alternativa
de estructuras de control. Recuperado de: https://secure.php.net/manual/es/control-structures.alternative-
syntax.php el 26 de septiembre de 2018.
Código 13. Ejemplo de if, else, y else if con sintaxis alternativa. Fuente: PHP Group (2018) Manual de PHP:
Sintaxis alternativa de estructuras de control. Recuperado de: https://secure.php.net/manual/es/control-
structures.alternative-syntax.php el 26 de septiembre de 2018.
Inclusión de ficheros:
En un proyecto web no es buena idea mezclar PHP y HTML en un mismo
documento; también se recomienda reutilizar todo el código que se pueda. Para ello
se dispone de varias alternativas para tratar con ficheros existentes:
 Include: esta sentencia busca y evalúa el fichero especificado cada vez que
es invocada. Si el archivo no se encuentra, PHP arrojará una advertencia
pero permitirá continuar la ejecución de la secuencia de instrucciones.
 Require: similara a include, con la diferencia que arrojará un error fatal de
nivel E_COMPILE_ERROR si el archivo no lo halla.
 Include_once: Similar a include, con la diferencia que solo buscará y evaluará
al fichero la primera vez que es invocado. El resto de llamadas será ignorado.
 Require_once: funciona de forma similiar a require, excepto que es una sola
vez después que es invocado. El resto de llamadas será ignorado.
Contenido de “index.php”
<?php
echo 'Contenido de php';
include './externo.html';
?>
Contenido de “externo.html”
<p>Este párrafo se incluyó mediante una invocación al método
include de php.< /p>
Código 14. Ejemplo de include en PHP
Figura 8. Salida del código anterior en un navegador web
Funciones en PHP:
Una función puede ser definida mediante la sintaxis:
Como se observa en la definición anterior, no es necesario declarar el tipo de los
argumentos ni del valor devuelto.
Para llamar a la función basta con llamarla: haceAlgo(). Cuando una función está
definida dentro de una condición, sus definiciones deben ser procesadas antes de
ser llamadas.
PHP no admite la sobrecarga de funciones; además, sus nombres son insensibles
a mayúsculas, a diferencia de las variables.
Una función puede tener argumentos con valores predeterminados. Estos
argumentos no necesitan ser pasados al llamar a la función pero deben ser escritos
de último al definir la función.
<?php
function haceAlgo($arg_1, $arg_2, /* ..., */ $arg_m)
{
echo "Función de ejemplo.n";
return $valor_devuelto;
}
?>
Código 15. Sintaxis para definir una función.
<?php
function hacer_café($tipos = array("capuchino"), $fabricanteCafé = NULL)
{
$aparato = is_null($fabricanteCafé) ? "las manos" : $fabricanteCafé;
return "Hacer una taza de ".join(", ", $tipos)." con $aparato.n";
}
echo hacer_café();
echo hacer_café(array("capuchino", "lavazza"), "una tetera");
?>
Código 16. Ejemplo de argumentos con valores predeterminados. Fuente: PHP Group (2018) Manual de PHP:
Argumentos de PHP. Recuperado de: https://secure.php.net/manual/es/functions.arguments.php el 26 de septiembre
de 2018.
Para pasar el parámetro por referencia, se debe de anteponer & antes del
argumento en la declaración de la función.
PHP tiene soporte para una cantidad variable de argumentos en las funciones
definidas por el usuario. Esto se implementa mediante el token (…).
Algunas funciones y variables incluidas
PHP incluye algunas variables predefinidas muy útiles, denominadas
superglobales muchas de las cuales veremos en las siguientes páginas.
Función Descripción
$GLOBALS Hace referencia a las variables disponibles en el ámbito global.
$_SERVER Array que contiene información del entorno de ejecución y server
$_GET Array asociativo de variables pasados via parámetros URL
$_POST Array asociativo de variables pasadas al script mediante POST
$_FILES Array asociativo de elementos subidos a través de POST
$_COOKIE Array asociativo de variables pasadas a través de Cookies HTTP
$_SESSION Array asociativo que contiene variables de sesión disponibles
para el script actual
$_REQUEST Array asociativo que por defecto contiene el contenido de
$_GET, $_POST y $_COOKIE
$_ENV Array asociativo de variables pasadas con información del
entorno
Tabla 2. Variables globales en PHP. Fuente: PHP Group (2018) Manual de PHP: Superglobales. Recuperado
de: https://secure.php.net/manual/es/language.variables.superglobals.php el 26 de septiembre de 2018.
function modificar(&$a) {
$a *= 3;
}
Código 18. Ejemplo de paso por referencia de una variable como argumento de una función.
<?php
function sum(...$números) {
$acc = 0;
foreach ($números as $n) {
$acc += $n;
}
return $acc;
}
echo sum(1, 2, 3, 4);
?>
Código 17. Ejemplo de una lista de argumentos de longitud variable. Fuente: PHP Group (2018) Manual de
PHP: Argumentos de PHP. Recuperado de: https://secure.php.net/manual/es/functions.arguments.php el 26
de septiembre de 2018.
También su núcleo integra varias funciones para el manejo de cadenas y arreglos
entre las que están:
Función Descripción
str_replace (search, replace,
string)
Permite reemplazar una expresión a buscar, con otra dentro de
un string.
strtoupper (string) Convierte un string a mayúsculas.
strtolower (string) Convierte un string a minúsculas.
trim (string, character_mask) Permite eliminar los caracteres en blanco u otros especificados
mediante una máscara que se encuentren al inicio o al final
explode (delimiter, string) Retorna un array de substrings al dividir la cadena con el
delimitador
implode (string = '', array) Contrario a explode, une un array de strings mediante un
delimitador
echo | print_r | var_dump Las 3 imprimen una cadena, echo puede imprmir más de un
argumento, print_r devuelve la variable en forma entendible para
humanos y var dump devuelve también el tipo de dato
Is_string(variable) Devuelve true si el argumento es una cadena
Tabla 3. Algunas funciones integradas de PHP para el manejo de cadenas
Funcion Descripción
array([mixed $...]) Crea un array
array_push(array, arg1,…,argm) Inserta uno o más elementos al final de un array
array_pop (array) Extrae el último elemento del final del array, acortando el arreglo
array_push(array, arg1,…,argm) Añade al final del array uno o más elementos
array_shift(array) Extrae el elemento del inicio del array, acortando el arreglo.
array_unshift(array,
arg1,…,argm)
Añade al inicio de un array uno a más elementos
count (array) Cuenta los elementos de un array o un objeto contable
array_search (mixed aguja,
array pajar, boolean strict)
Busca un valor en un array devuelve la primera clave en caso de
éxito; de lo contrario, devuelve false
Tabla 4. Algunas funciones integradas de PHP para el manejo de arreglos
El resto de las variables y funciones predefinidas se encuentran en el Anexo I.
Información más detallada se encuentra en el sitio oficial de PHP.
Ejemplos sencillos de PHP en aplicaciones web
Estos son algunos ejemplos para ver cómo se usa lo expresado con anterioridad en
este documento de forma práctica.
1. Obteniendo datos a partir del usuario
Cuando un usuario navega en la web se puede observar en la URL los parámetros
que el usuario ha ingresado previamente. Aquí se simulará eso con el siguiente
código:
Para cada petición, PHP almacena los parámetros enviados como parte de la URI
en un arreglo llamado $_GET. El arreglo está estructurado de forma que cada una
de las claves es el nombre del parámetro, emparejado con su valor correspondiente.
<?php
$busqueda= isset($_GET['titulo']) || isset($_GET['cantante']);
?>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Parametros get en PHP</title>
</head>
<body>
<h1>Resultados de la búsqueda:</h1>
<br>
<p>Usted buscó <?php echo (int)$busqueda;?> título(s)</p>
<ul>
<li>
<b>Título: </b><?php echo $_GET['titulo'];?>
</li>
<li>
<b>Cantante: </b><?php echo $_GET['cantante'];?>
</li>
</ul>
</body>
</html>
Código 19. Ejemplo de de lectura de parámetros mediante GET en PHP. Adaptado de López, Antonio (2016).
Learning PHP 7. Packt Publishing. 1ra Ed.
Si se envía los parámetros necesarios mediante la URL se reflejará una salida
similar a la imagen anterior, de lo contrario y según la configuración del servidor,
mostrará una advertencia al intentar obtener los valores de esos elementos.
2. Formulario HTML para el envío de correos con PHP
En HTML, la etiqueta form tiene los atributos action, la url donde los datos serán
enviados o procesados, y method, para indicar el verbo HTTP a utilizar (GET o
POST). A continuación, un ejemplo real:
Figura 9. La página imprime la información enviada a la URL
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8" />
<meta name="description" content="Formulario de contacto Water Projects
S.A, Nicaragua, servicios y proyectos hÃ-dricos"/>
<title>Contactenos-Mi Empresa</title>
<meta name="viewport" content="width=device-width initial-scale=1.0" />
<link href="css/bootstrap.css" type="text/css" rel="stylesheet" />
<link href="css/home.css" type="text/css" rel="stylesheet" />
<link href="css/comun.css" type="text/css" rel="stylesheet" />
<link href="css/contacto.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="js/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>
<link href="css/leaflet.css" rel="stylesheet" type="text/css"/>
<script src="js/leaflet.js" type="text/javascript"></script>
</head>
<body>
<!--Barra de menú-->
<?php include './includes/menu.php' ?>
<div class="aplicarMargen container-fluid">
<div class="row">
<div class="headerPageContainer">
<h1>
Contáctenos
</h1>
<hr />
</div>
<h4 class="Descripcion">Si usted desea conocer más de nuestros
servicios y productos no dude en escribirnos.</h4>
</div>
<div class="row">
<form method="post" enctype="multipart/form-data"
action="enviarCorreo.php" role="form" class="col-md-8">
<div class="form-group">
<label for="inputNombre">Nombres:</label>
<input id="inputNombre" class="form-control" type="text"
name="Nombre" placeholder="Escriba su(s) nombre(s)" />
</div>
<div class="form-group">
<label for="inputApellido">Apellidos:</label>
<input id="inputApellido" class="form-control" type="text"
name="Apellido" placeholder="Escriba su(s) apellido(s)" />
</div>
<div class="form-group">
<label for="inputCorreo">Correo electrónico:</label>
<input id="inputCorreo" class="form-control" type="email"
name="Correo" placeholder="Ingrese un e-mail válido" />
</div>
Código 20. Página web de contacto (parte 1). Fuente: Elaboración propia
<div class="form-group">
<label for="inputAsunto">Asunto:</label>
<input id="inputAsunto" class="form-control" type="text"
name="Asunto" placeholder="Asunto del correo" />
</div>
<textarea class="form-control" name="Mensaje"
autocomplete="off"
placeholder="Escriba aquí su mensaje"
rows="10"></textarea>
<div class="btnContainer">
<button type="submit" class="btn btn-default
btnEnviar">Enviar</button>
</div>
</form>
<aside id="mapa" class="col-md-4 map pequeno">Hola</aside>
</div>
</div>
<script>
var lat, long;
lat=12.14132;
long=-86.27753;
var mymap = L.map('mapa').setView([lat, long], 18);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data &copy; <a
href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
'<a href="http://creativecommons.org/licenses/by-
sa/2.0/">CC-BY-SA</a>, ' +
'Imagery © <a href="http://mapbox.com">Mapbox</a>',
id: 'mapbox.streets'
}).addTo(mymap);
L.control.scale().addTo(mymap);
var myIcon = L.icon({
iconUrl: '/img/iconos/marker.png',
shadowUrl: '',
iconSize: [38, 95], // size of the icon
shadowSize: [50, 64], // size of the shadow
iconAnchor: [22, 94], // point of the icon which will
correspond to marker's location
shadowAnchor: [4, 62], // the same for the shadow
popupAnchor: [-3, -76] // point from which the popup should open
relative to the iconAnchor
});
L.marker([lat, long], {icon: myIcon}).addTo(mymap);
</script>
</body>
</html>
Código 21. Página web de contacto (parte 2). Fuente: Elaboración propia
Los datos recopilados son procesados por enviarCorreo.php,
<?php
if(isset($_POST['Correo']) && !empty($_POST['Correo'])){
$para="contacto@empresa.net"; $asunto=null; $nombre=null;
$apellido=null; $emisor=null; $mensaje=null;
if(isset($_POST['Asunto']) && !empty($_POST['Asunto'])){
$asunto=$_POST['Asunto'];
}
if(isset($_POST['Nombre']) && !empty($_POST['Nombre'])){
$Nombre=$_POST['Nombre'];
}
if(isset($_POST['Apellido']) && !empty($_POST['Apellido'])){
$apellido=$_POST['Apellido'];
}
if(isset($_POST['Correo']) && !empty($_POST['Correo'])){
$emisor=$_POST['Correo'];
}
if(isset($_POST['Mensaje']) && !empty($_POST['Mensaje'])){
$mensaje=$_POST['Mensaje'];
}
if (is_string(validarFormatoCorreo($emisor))) {
$cabecera='From: '.$nombre.''.$apellido.'<'.$emisor.
'>'."rn".
'Reply-To: '.$emisor."rn".
'X-Mailer: PHP/'.phpversion();
$bool=mail($para, $asunto, $mensaje, $cabecera);
if($bool){
$txt='¡Correo enviado satisfactoriamente!';
imprimirPagMensaje($txt);
}
else{
$txt='Error al enviar correo';
imprimirMensaje($txt);
}
}
else{
$txt='Error al enviar correo';
imprimirMensaje($txt);
}
}
function validarFormatoCorreo($correo_e){
$correo_e = filter_var($correo_e, FILTER_SANITIZE_EMAIL);
return (filter_var($correo_e, FILTER_VALIDATE_EMAIL)) ? $correo_e : 0;
}
function imprimirMensaje($mensaje){
echo $mensaje; /*Aquí también se puede escribir código HTML*/
}
?>
Código 22. EnviarCorreo.php. Fuente: Elaboración propia
En el código anterior se definió el método de envío de los datos del formulario
mediante el verbo POST; debido a esta razón, los parámetros no se muestran en la
URL del navegador, aunque son visibles si se recurre al inspector de red.
El correo se enviará si existe un valor para la clave “Correo” de la variable
superglobal $_POST, la cual guarda las variables enviadas mediante este verbo; es
decir, el email del emisor. Si existe, se verifica que también hayan sido enviados el
nombre y apellido del remitente, el asunto y contenido del correo; de lo contrario se
imprime un mensaje de error.
Si el formato del email del emisor es correcto, se procede a declarar y asignar los
valores adicionales para la cabecera como from, Cc, Bcc y el servidor que envía el
correo, los cuales se deben de separarse con retorno de carro y salto de línea
(“rn”). Una vez hecho esto, se procede a enviar el correo con la función mail()
pasándole como argumentos el destinatario, asunto, contenido del mensaje y
parámetros adicionales de la cabecera. Si no ocurre ningún error se indica al
usuario; en caso de error, también.
Las siguientes imágenes muestran las correspondientes pantallas:
Figura 10. Página de contacto. Fuente: Elaboración propia
Figura 11. Mensaje que se muestra al usuario cuando el correo se envió satisfactoriamente. Fuente:
Elaboración propia
Programación Orientada a Objetos en PHP:
PHP es un lenguaje multiparadigma. Si bien se puede programar de forma
estructurada o funcional, una aplicación compleja requiere de otro arquetipo para
su ciclo de vida. La programación Orientada a Objetos (POO) surge como un
modelo versátil que permite acercar la codificación al entendimiento de la realidad.
PHP lo soporta de forma completa desde su versión 5.
En POO, casi todo son objetos y todos los objetos interactúan entre sí. Un objeto
tiene unas características, que son los atributos, y unas acciones, que son los
métodos. Por ejemplo, el objeto Animal tiene como atributos el color y el peso, y
tiene como métodos moverse y comer. Para construir estos objetos, debe utilizar
una clase.
Cuando se trabaja en php orientado a objeto hay que tener en cuenta que se va a
trabajar en la creación de un objeto o mejor conocido en php como clases, donde le
vamos a dar a este propiedades y métodos que describan al objeto y las acciones
que realiza este.
Al programar orientado a objeto hay que tener en cuenta que se tiene que pensar
todo de forma abstracta hay que abstraer todo lo posible de este objeto para lograr
crear un buen objeto.
1. Conceptos básicos:
La programación Orientada a Objetos es un modelo de programación en el cual el
comportamiento del programa es llevado a cabo por objetos, entidades que
representan seres o conceptos en la vida real del problema a resolver. La POO es
uno de los paradigmas más utilizados actualmente.
Se sostiene en los siguientes conceptos:
 Objeto: es una entidad que representa un elemento o concepto de la vida
real y posee propiedades que lo diferencian del resto (atributos) y
comportamiento (funcionalidad o métodos que operan sobre dichas
propiedades).
 Clase: es la descripción de un conjunto de objetos (una plantilla para objetos).
Expresa las propiedades y comportamiento de un tipo de objetos concreto.
La instanciación es la lectura de estas definiciones y la creación de un objeto
a partir de ella.
 Abstracción: se utiliza al momento de definir una clase, para que esta tenga
los métodos y atributos relevantes. Existen diferentes grados de abstracción
para determinar qué se hace y no cómo se hace. Estos niveles se ponen de
al abstraer la escena de un conjunto de elementos del mundo real que
aparecen una y otra vez con ligeras variantes en sistemas diferentes.
 Encapsulamiento: es reunir todos los elementos que pueden considerarse
pertenecientes a una misma entidad al mismo nivel de abstracción. Define
los niveles de acceso para los elementos de esa clase: público, protegido y
privado.
 Ocultación: cada objeto expone una interfaz al exterior para que poder
prestar sus servicios. Mientras la clase actúa como una caja negra y se puede
modificar, la interfaz no cambia.
 Herencia: modela el hecho de que los objetos tienden a organizarse en
jerarquías. La clase base o padre es aquella de la hereda un objeto.
 Polimorfismo: permite a una operación (función) tener el mismo nombre en
clases diferentes y que actúe de modo diferente en cada una de ellas, por
ejemplo en el caso de herencia.
En este acápite, empezaremos con los códigos básicos para desarrollar con PHP
orientado a objetos y desarrollaremos un ejemplo de aplicación web de agenda
conectado a MySql en donde se abordarán los conceptos anteriores.
2. Definiciones de clases:
Una clase se define mediante la palabra reservada class seguida del nombre y
llaves ({}) que encierran las definiciones de los atributos y métodos. Se utiliza la
palabra reservada class seguida del nombre de la clase y se abre una llave, de
forma que todo lo que está dentro de estas llaves pertenece a todo este objeto,
dentro de estas llaves que abren y cierran van todo lo que es propiedades y métodos
del objeto.
Para acceder a alguna de las propiedades no estáticas de la clase, se utiliza la
seudovariable $this seguida del operador -> y el nombre de la variable. Es mejor
mantener un nivel de acceso protected para todos los atributos de la clase. Para
constantes, se usa self seguido de :: (doble dos puntos).
Para crear un objeto a partir de una clase; es decir, instanciarla, se utiliza la palabra
clave new seguida del nombre de la clase y ().
Es correcto crear un método constructor para las clases y facilitar la instanciación
de las mismas. Para ello se declara el método mágico __construct() como cualquier
otro método.
Si los atributos de la clase tienen un nivel de acceso protegido (acceso sólo desde
la misma clase), que es lo más recomendado, entonces se deben crear métodos
para leer y modificar dichos valores: getters y setters. Esta es una de las formas en
que se cumple el principio de ocultación.
Una clase sirve para fabricar objetos
partiendo de un modelo. Estos objetos
tienen sus propios atributos y ciertos
métodos. Por ejemplo, la clase Animal
tiene los atributos color y peso y los
métodos comer y moverse.
<?php
class NombreClase
{
} ?>
Cuando se crean ejemplares
de animales en la clase
Animal, se crea una instancia
de esta clase. Crear una
instancia de una clase significa
que se crea un objeto de un
tipo determinado (Animal) con
ciertos atributos (color, peso).
Se recomienda crear una clase por cada archivo PHP que tenga el mismo nombre
que la clase.
a. La encapsulación.
Todos los atributos en POO deben estar ocultos de otros elementos que utilizan sus
clases. Si trabaja en equipo y crea la clase Animal, los otros programadores no van
a poder cambiar directamente los atributos de su clase. De esta forma, los atributos
color y peso se ocultan en otras clases; se declaran privadas. La clase Animal tiene
métodos para leer o escribir en estos atributos. Este es el principio de
encapsulación, que permite proteger el código cuando trabaja en equipo.
La clase Animal, que tiene como propiedades el color y el peso, dispone de un
método para modificar su color, un método para leer el color, un método para
modificar su peso, un método para leer su peso, así como otros métodos tales como
comer o moverse.
b. Propiedades de una clase.
<?php
class Animal /* palabra clave class
seguida del nombre de la clase.*/
{ // Declaración de atributos y métodos.
}
?>
Las propiedades de las clases son los atributos del objeto como por ejemplo: el
tamaño de una persona, el peso de una mesa. En php hay 3 niveles de acceso tanto
para las propiedades como para los métodos los cuales son:
 Public: Cuando le damos este nivel de acceso a un atributo, este puede ser
accedido desde cualquier parte, así sea dentro de su misma clase como desde
otra.
 Private: Cuando se le da el nivel de acceso private estamos quitándole la libertad
de acceso a las demás que intenten acceder, solo puede ser accedida desde su
propia clase donde este fue definido.
 Protected: Cuando le damos el nivel de acceso protegido sigue restringiendo la
libertad de acceso a los demás que no sean de la clase donde se esta
declarando o de sus subclases.
Ahora, un ejemplo de cómo se colocaría la propiedad dentro del objeto en php.
<?php
class NombreClase {
public $a;
private $b;
protected $c; }
?>
<?php
class Animal // palabra clave seguida del nombre de la clase.
{ // Declaración de atributos.
private $color = "gris";
private $peso = 10;
}
?>
c. Métodos de una clase.
Los tipos de acceso también se utilizan en los métodos y son los mismos. Para
comprender que es el método de una clase u objeto, sería un ejemplo el de un objeto
persona que tiene el método caminar, o sentarse o comer.
Método sería todo lo que es capaz de realizar el objeto, en PHP su sintaxis utiliza la
palabra reservada function, ahora veamos un ejemplo:
<?php
class NombreClase
{
public $a;
private $b;
protected $c;
public function A($a) { }
private function B() { }
protected function C() { }
}
?>
En el ejemplo se crearon 3 métodos dentro del objeto los cuales tienen cada uno de
estos los distintos tipos de nivel de acceso, los métodos son más que funciones
pero las funciones que realiza dicho objeto.
<?php
class Animal // palabra clave seguida del nombre de la clase.
{
// Declaración de atributos y métodos.
private $color = "gris";
private $peso = 10;
public function comer()
{
//Método posible para acceder a las propiedades
//color y peso
}
public function moverse()
{
//Método posible para acceder a las propiedades
//color y peso
}
}
?>
d. Añadir un método en la clase
Añadir código a la clase significa aplicar la clase. Para acceder a los atributos de su
clase, debe utilizar la pseudovariable $this, que representa el objeto sobre el que va
a escribir. Para acceder al atributo o al método del objeto, utilice el operador ->.
Por ejemplo, para aplicar el método añadir_un_kilo() en la clase Animal:
<?php
class Animal // palabra clave seguida del nombre de la clase.
{
// Declaración de atributos y métodos.
private $color = "gris";
private $peso = 10;
public function comer()
{
//Método para acceder a las propiedades
//color y peso
}
public function moverse()
{
//Método para acceder a las propiedades
//color y peso
}
public function añadir_un_kilo()
{ $this->peso = $this->peso + 1;}
}
?>
Cuando llama al método añadir_un_kilo(), añadirá 1 al peso actual y por lo tanto el
peso final será 11.
Las propiedades se declaran con el símbolo $, pero se llaman con $this sin este
símbolo.
A continuación, un ejemplo:
<?php
class Foto {
private $IdFoto;
private $FkProyecto;
private $Url_Foto;
private $Eliminada;
function getIdFoto() {
return $this->IdFoto;
}
function getFkProyecto() {
return $this->FkProyecto;
}
function getUrl_Foto() {
return $this->Url_Foto;
}
function getEliminada() {
return $this->Eliminada;
}
function setIdFoto($IdFoto) {
$this->IdFoto = $IdFoto;
}
function setFkProyecto($FkProyecto) {
$this->FkProyecto = $FkProyecto;
}
function setUrl_Foto($Url_Foto) {
$this->Url_Foto = $Url_Foto;
}
function setEliminada($Eliminada) {
$this->Eliminada = $Eliminada;
}
function __construct($IdFoto, $FkProyecto, $Url_Foto,
$Eliminada) {
$this->IdFoto = $IdFoto;
$this->FkProyecto = $FkProyecto;
$this->Url_Foto = $Url_Foto;
$this->Eliminada = $Eliminada;
}
}
$f = new Foto(1,2,'/imgs/proyectos/E/p1/01.jpg',false);
?>
Código 23. Ejemplo de definición de una clase en PHP y su instanciación. (Fuente: elaboración propia).
Definicióndeclase
Atributos
Getters y setters
Constructor
Métodos
Instanciación
e. Utilización de la clase
Como primer paso, tenemos que crear un archivo que contenga un código PHP
animal.class.php. Para utilizar la clase Animal, debe incluirla en la página donde la
quiere llamar. En una página uso.php podría incluirla de la siguiente manera:
<?php
include(’Animal.class.php’);
?>
Ahora que ha cargado la clase, puede instanciarla, es decir, crear un objeto que
tenga como modelo la clase Animal:
<?php
//carga de la clase
include(’animal.class.php’);
//instanciar la clase Animal
$perro = new Animal();
?>
La variable $perro es una instancia de la clase animal, con los atributos propios de
color, peso; y como métodos comer, moverse, añadir_un_kilo.
f. Actualizar y leer los atributos de la instancia.
El principio de encapsulación requiere que todos los atributos sean privados. Por lo
tanto, debe crear métodos públicos que permitan leer o escribir en sus atributos
desde otra página PHP. Estos métodos son accesos.
Generalmente sus nombres van precedidos del prefijo get para leer el valor del
atributo y set para escribir el valor del atributo. La clase Animal con los accesos es:
<?php
class Animal // palabra clave seguida del nombre de la clase.
{
// Declaración de atributos
private $color = "gris";
private $peso = 10;
//accesos
public function getColor()
{ return $this->color; //devuelve el color}
public function setColor($color)
{ $this->color = $color; //escrito en el atributo color }
public function getPeso()
{ return $this->peso; //devuelve el peso }
public function setPeso($peso)
{ $this->peso = $peso; //escrito en el atributo peso }
//métodos
public function comer()
{ //método para acceder a las propiedades
//color y peso }
public function moverse()
{ //método para acceder a las propiedades
//color y peso }
public function añadir_un_kilo()
{ $this->peso = $this->peso + 1; }
}
?>
Los accesos son públicos y por lo tanto permiten leer o escribir en los atributos
desde cualquier otra clase o página PHP. Ejemplo con la página uso.php:
<?php
//carga de la clase
include(’animal.class.php’);
//instanciar la clase Animal
$perro = new Animal();
//leer el peso
echo "El peso del perro es:".$perro->getPeso()." kg<br />";
//añadir un kilo al perro
$perro->añadir_un_kilo();
//leer el peso
echo "El peso del perro es:".$perro->getPeso()." kg<br />";
//actualizar el peso del perro
$perro->setPeso(15);
//leer el peso
echo "El peso del perro es:".$perro->getPeso()." kg<br />";
?>
Da como resultado:
 El peso del perro es:10 kg
 El peso del perro es:11 kg
 El peso del perro es:15 kg
En efecto, el peso del perro se inicializa a 10. A continuación el método
añadir_un_kilo() añade 1; por lo tanto, su peso se convierte en 11. Para terminar, el
método setPeso(15) ajusta el peso a 15. Por ejemplo, para crear un gato blanco de
5 kg y un perro negro de 18 kg:
<?php
//carga de la clase
include(’Animal.class.php’);
//instanciar la clase Animal
$perro = new Animal();
//actualizar el peso del perro
$perro->setPeso(18);
echo "El peso del perro es:".$perro->getPeso()." kg<br />"; //leer el peso
$perro->setColor("negro"); //actualizar el color del perro
echo "El color del perro es:".$perro->getColor()."<br />"; //leer el color
$gato = new Animal(); //instanciar la clase Animal
$gato->setPeso(5); //actualizar el peso del gato
echo "El peso del gato es:".$gato->getPeso()." kg<br />"; //leer el peso
//actualizar el color del gato
$gato->setColor("blanco");
//leer el color
echo "El color del gato es:".$gato->getColor()."<br />";
?>
Da como resultado:
 El peso del perro es:18 kg
 El color del perro es:negro
 El peso del gato es:5 kg
 El color del gato es:blanco
Paso como argumento de tipo objeto.
Los métodos son como las funciones, pueden tomar argumentos de tipos diferentes
(Integer, String…) e incluso de tipo Objeto.
$gato y $perro son objetos de tipo Animal. Pueden pasar como argumento un
método, siempre y cuando acepte este tipo de objeto.
Para probar este ejemplo, cambie el método comer() de la clase Animal. Se
convierte en comer_animal(Animal $animal_comido) y toma como argumento un
objeto de tipo Animal.
La página animal.class.php se convierte en:
<?php
class Animal
{ // Declaración de atributos
private $color = "gris";
private $peso = 10;
//Accesos
public function getColor()
{ return $this->color; //devuelve el color }
public function setColor($color)
{ $this->color = $color; //escrito en el atributo color }
public function getPeso()
{ return $this->peso; //devuelve el peso }
public function setPeso($peso)
{ $this->peso = $peso; //escrito en el atributo peso }
//Métodos
public function comer_animal(Animal $animal_comido)
{ /* El animal que come aumenta su peso tanto
como el del animal comido */
$this->peso = $this->peso +
$animal_comido->peso;
/* El peso del animal comido y su color se
restablecen a 0 */
$animal_comido->peso = 0;
$animal_comido->color = ""; }
public function moverse()
{ /*método que pueda acceder a las propiedades
color y peso */ }
public function añadir_un_kilo()
{ $this->peso = $this->peso + 1; }
}
?>
Para probar este método, la página uso.php se convierte en:
<?php
//carga de la clase
include(’animal.class.php’);
//instanciar la clase Animal
$gato = new Animal();
//actualizar el peso del gato
$gato->setPeso(8);
//leer el peso
echo "El peso del gato es:".$gato->getPeso()." kg<br />";
//actualizar el color del gato
$gato->setColor("negro");
//leer el color
echo "El color del gato es:".$gato->getColor()."<br />";
//instanciar la clase Animal
$pez = new Animal();
//actualizar el peso del pez
$pez->setPeso(1);
//leer el peso
echo "El peso del pez es:".$pez->getPeso()." kg<br />";
//actualizar el color del pez
$pez->setColor("blanco");
//leer el color
echo "El color del pez es:".$pez->getColor()."<br /><br />";
//el gato come al pez
$gato->comer_animal($pez);
//leer el peso
echo "El nuevo peso del gato es:".$gato->getPeso()." kg<br />";
//leer el peso
echo "El peso del pez es:".$pez->getPeso()." kg<br />";
//leer el color
echo "El color del pez es:".$pez->getColor()."<br /><br />";
?>
Da como resultado:
 El peso del gato es:8 kg
 El color del gato es:negro
 El peso del pez es:1 kg
 El color del pez es:blanco
 El nuevo peso del gato es:9 kg
 El peso del pez es:0 kg
 El color del pez es:
El objeto $gato llama al método comer_animal ($pez) y pasa como argumento el
objeto de tipo Animal $pez. Es decir, el objeto $pez con sus atributos y sus métodos
se pasan como argumento. Esto permite pasar como argumento varios valores con
un único parámetro. El método comer_animal(Animal $animal_comido) solo acepta
un argumento de tipo Animal. Por lo tanto, no puede llamar al método de la siguiente
manera: $gato->comer_animal("Rana");
Ni de esta manera: $gato->comer_animal(4);
Ya que los tipos "Rana" (String) y 4 (Integer) no son de tipo Animal.
g. Constructores.
En la programación orientada a objetos (POO u OOP en Inglés) existe un método
especial o mágico llamado método constructor. Este método se encarga de
inicializar algunas variables --dentro de la clase se llaman propiedades o atributos-
- que serán necesarias a la hora de crear una instancia de la clase o lo que es lo
mismo, un objeto. Este método mágico usa la palabra reservada __construct
El constructor, como su nombre indica, sirve para construir un objeto del tipo clase.
Cuando escribe new Animal(), por defecto llama al constructor de la clase Animal.
Puede crear sus propios constructores y así pasar como argumento el valor de los
atributos que desea asignar a su objeto.
El constructor se designa __construct y no tiene return.
<?php
class NombreClase
{ public $a;
private $b;
protected $c;
function __construct()
{ $this->a = 'x';
$this->b = 'w';
$this->c = 'z'; }
//...código
}
?>
De esta forma al momento de ser creado el objeto se van a inicializar las
propiedades del objeto como en el ejemplo donde en el objeto a la propiedad a se
le asigna x, a la propiedad b se le asigna w y a la propiedad c se le asigna z. La
variable $this sirve para referirnos a este objeto.
Al igual que hay un constructor existe un destructor que realiza todo el trabajo
opuesto, que sería destruir todas las variables creadas.
Para añadir un constructor que toma como argumentos el peso y el color, la página
animal.class.php se convierte en:
<?php
class Animal
{ // Declaración de atributos
private $color = "gris";
private $peso = 10;
public function __construct ($color, $peso)
//Constructor que solicita 2 argumentos.
{ echo ’Llamar al constructor.<br />’;
$this->color = $color; // Inicialización del color.
$this->peso = $peso; // Inicialización del peso. }
/* Etc. */
}
?>
Llamar al constructor en la página uso.php:
<?php
//carga de la clase
include(’animal.class.php’);
//instanciar la clase Animal con su constructor
$perro = new Animal("beige",7);
//leer el peso
echo "El peso del perro es:" . $perro->getPeso() . " kg<br />";
//leer el color
echo "El color del perro es:" .$perro->getColor() . "<br />";
//actualizar el color del perro
$perro->setColor("negro");
//leer el color
echo "El color del perro es:" . $perro->getColor() . "<br />";
?>
Da como resultado:
 Llamar al constructor.
 El peso del perro es:7 kg
 El color del perro es:beige
 El color del perro es:negro
Se muestra en primer lugar "Llamar al constructor", ya que la instrucción echo que
se ha escrito en el constructor __construct de su clase Animal se llama cada vez
que ejecuta new Animal().
El constructor toma como argumento los valores de sus atributos. Esto evita llamar
los métodos setColor() y setPeso().
En PHP no se puede declarar dos constructores en la misma clase.
h. Destructor.
El destructor destruye el objeto con el fin de liberarlo de la memoria junto con todas
las variables creadas en el objeto, algo que no se utiliza mucho ya que PHP ya se
encarga de liberar o eliminar todos los recursos utilizados al finalizar de ejecutar un
script; sin embargo puede ser utilizado, su palabra reservada es __destruct()
También puede destruir un objeto utilizando la función unset(). Esta función toma
como argumento el objeto que hay que destruir.
<?php
//destrucción del objeto
unset($perro);
?>
Pero se recomienda añadir la función __destruct() en la clase. Por ejemplo, para
destruir el objeto $perro:
<?php
class NombreClase {
public $a;
private $b;
protected $c;
function __construct() {
$this->a = 'x';
$this->b = 'w';
$this->c = 'z'; }
function __destruct() { echo "el atributo asignado " .$this->a . " ha sido eliminado
por el destructor."; }
//...código
}
?>
Otro ejemplo sería:
<?php
class Animal
{
// Declaración de atributos
private $color = "gris";
private $peso = 10;
public function __construct ($color, $peso)
//Constructor que solicita 2 argumentos.
{
echo ’Llamar al constructor.<br />’;
$this->color = $color; // Inicialización del
// color.
$this->peso = $peso; // Inicialización del peso.
}
public function __destruct()
{
echo ’Llamar al destructor’;
}
Etc.
.
.
.
}
?>
Generalmente no es necesario aplicar el destructor en la clase.
Ejemplo:
Cree dos peces en la página uso.php:
pez1, gris, 10 kg
pez2, rojo, 7 kg
Muestre su peso y a continuación el pez1 se come al pez2. Vuelva a mostrar su
peso.
<?php
//carga de la clase
include(’animal.class.php’);
//instanciar la clase Animal con su constructor
$pez1 = new Animal("gris",10);
$pez2 = new Animal("rojo",7);
//leer el peso
echo "El peso del pez1 es:".$pez1->getPeso()." kg<br />";
//leer el peso
echo "El peso del pez2 es:".$pez2->getPeso()." kg<br />";
//el pez1 se come al pez2
$pez1->comer_animal($pez2);
//leer el peso
echo "El nuevo peso del pez1 es:".$pez1->getPeso()." kg<br />";
//leer el nuevo peso
echo "El nuevo peso del pez2 es:".$pez2->getPeso()." kg<br />";
?>
Resultado:
Llamada al constructor.
Llamada al constructor.
El peso del pez1 es:10 kg
El peso del pez2 es:7 kg
El nuevo peso del pez1 es:17 kg
El nuevo peso del pez2 es:0 kg
Llamada al destructor
Llamada al destructor
Las constantes de clase
Una constante de clase es similar a una constante normal, es decir, un valor
asignado a un nombre y que no cambia nunca. Por ejemplo:
define(’PI’,3.1415926535);
Una constante de clase representa una constante pero que está unida a esta clase.
Para crear un animal con el constructor __construct ($color, $peso), escriba:
$perro = new Animal("gris",10);
Si lee el código, no puede saber inmediatamente que el número 10 representa el
peso del animal.
Utilice constantes que representen, cada una, un peso distinto:
const PESO_LIGERO = 5;
const PESO_MEDIO = 10;
const PESO_PESADO = 15;
Las constantes siempre están en mayúsculas, sin el símbolo $ y precedidas de la
palabra clave const.
La clase animal.class.php se convierte en:
<?php
class Animal
{
// Declaración de atributos
private $color = "gris";
private $peso = 10;
//constantes de clase
const PESO_LIGERO = 5;
const PESO_MEDIO = 10;
const PESO_PESADO = 15;
etc.
.
.
.
?>
Para llamar a esta constante desde la página uso.php, la sintaxis es algo peculiar.
Debe escribir :: entre la clase y su constante:
<?php
//carga de la clase
include(’Animal.class.php’);
//instanciar la clase Animal con su constructor
$pez1 = new Animal("gris",Animal::PESO_MEDIO);
$pez2 = new Animal("rojo",Animal::PESO_LIGERO);
//leer el peso
echo "El peso del pez1 es:".$pez1->getPeso()." kg<br />";
//leer el peso
echo "El peso del pez2 es:".$pez2->getPeso()." kg<br />";
//el pez1 se come al pez2
$pez1->comer_animal($pez2);
//leer el peso
echo "El nuevo peso del pez1 es:".$pez1->getPeso()." kg<br />";
//leer el nuevo peso
echo "El nuevo peso del pez2 es:".$pez2->getPeso()." kg<br />";
?>
Da como resultado:
Llamada al constructor.
Llamada al constructor.
El peso del pez1 es:10 kg
El peso del pez2 es:5 kg
El nuevo peso del pez1 es:15 kg
El nuevo peso del pez2 es:0 kg
Animal::PESO_MEDIO siempre es 10, sea cual sea la instancia. Por lo tanto, la
constante no está unida a la instancia, sino a la clase. Por este motivo la sintaxis es
peculiar.
Los atributos y los métodos.
a. Método estático.
El método estático está unido a la clase, pero no al objeto. En el ejemplo de la clase
animal, un método estático está unido al Animal, y no a los perros, los gatos o los
peces.
Para convertir un método estático, debe añadir la palabra clave static delante de
function.
Por ejemplo, modifique el método moverse() para convertirlo en estático y muestre
"El animal se mueve.".
La clase animal.class.php se convierte en:
<?php
class Animal
{
// Declaración de atributos
private $color = "gris";
private $peso = 10;
//constantes de clase
const PESO_LIGERO = 5;
const PESO_MEDIO = 10;
const PESO_PESADO = 15;
public function __construct ($color, $peso)
// Constructor que solicita 2 argumentos.
{
echo ’Llamada al constructor.<br />’;
$this->color = $color; // Inicialización del color.
$this->peso = $peso; // Inicialización del peso.
}
//accesos
public function getColor()
{
return $this->color; //devuelve el color
}
public function setColor($color)
{
$this->color = $color; //escrito en el atributo color
}
public function getPeso()
{
return $this->peso; //devuelve el peso
}
public function setPeso($peso)
{
$this->peso = $peso; //escrito en el atributo peso
}
//métodos
public function comer_animal(Animal $animal_comido)
{
//el animal que come aumenta su peso tanto como
//el del animal comido
$this->peso = $this->peso + $animal_comido->peso;
//el peso del animal comido y su color se restablecen a 0
$animal_comido->peso = 0;
$animal_comido->color = "";
}
public static function moverse()
{
echo "El animal se mueve.";
}
public function añadir_un_kilo()
{
$this->peso = $this->peso + 1;
}
}
?>
Es imposible escribir en un método estático la palabra clave $this, ya que representa
el objeto, y el método estático está unido a la clase.
Para llamar a este método desde la página uso.php, debe utilizar la misma sintaxis
que en las constantes (también unidas a la clase), es decir, introducir :: entre la
clase y su método estático:
<?php
//carga de la clase
include(’Animal.class.php’);
//llamada al método estático
Animal::moverse()
?>
Da como resultado:
El animal se mueve.
Puede llamar al método estático desde un objeto, pero el método estático no puede
cambiar nada de este objeto:
<?php
//carga de la clase
include(’animal.class.php’);
//instanciar la clase Animal con su constructor
$perro1 = new Animal("gris",Animal::PESO_MEDIO);
//llamada al método estático
$perro1->moverse();
?>
Da como resultado:
Llamada al constructor
El animal se mueve.
b. Atributo estático.
Un atributo estático es un atributo propio de la clase y no del objeto, al igual que en
los métodos estáticos. Es el mismo principio que en una constante, salvo que el
atributo está en una variable y puede cambiar su valor.
Un atributo estático se escribe añadiendo la palabra clave static delante de su
nombre.
Por ejemplo, para añadir un atributo estático que representa a un contador que
indica el número de veces que se instancia la clase:
La clase animal.class.php se convierte en:
<?php
class Animal
{
// Declaración de atributos
private $color = "gris";
private $peso = 10;
//constantes de clase
const PESO_LIGERO = 5;
const PESO_MEDIO = 10;
const PESO_PESADO = 15;
// Declaración de la variable estática $contador
private static $contador = 0;
etc.
.
.
.
?>
Para cambiar el valor de este contador, no puede utilizar $this. De hecho, $this
representa un objeto (perro, gato), y no la clase Animal. El contador es de tipo
estático y por lo tanto está unido a la clase. Para llamar a este atributo en la clase,
debe utilizar la palabra clave self, que representa la clase.
Para añadir 1 al contador cada vez que vaya a instanciar la clase Animal, debe
modificar el constructor. A continuación debe añadir un método que permita leer
este atributo privado con ayuda de un método de tipo public static y getContador().
La clase animal.class.php se convierte en:
<?php
class Animal
{
// Declaración de atributos
private $color = "gris";
private $peso = 10;
//constantes de clase
const PESO_LIGERO = 5;
const PESO_MEDIO = 10;
const PESO_PESADO = 15;
// Declaración de la variable estática $contador
private static $contador = 0;
public function __construct ($color, $peso) // Constructor
//que solicita 2 argumentos.
{
echo ’Llamada al constructor.<br />’;
$this->color = $color; // Inicialización del color.
$this->peso = $peso; // Inicialización del peso.
self::$contador = self::$contador + 1;
}
// método estático que devuelve el valor del contador
public static function getContador()
{
return self::$contador;
}
...
?>
La página uso.php:
<?php
//carga de la clase
include(’Animal.class.php’);
//instanciar la clase Animal
$perro1 = new Animal("rojo",10);
//instanciar la clase Animal
$perro2 = new Animal("gris",5);
//instanciar la clase Animal
$perro3 = new Animal("negro",15);
//instanciar la clase Animal
$perro4 = new Animal("blanco",8);
//llamada al método estático
echo "Número de animales que se han instanciado: ".Animal::
getContador();
?>
Da como resultado:
Llamada al constructor.
Llamada al constructor.
Llamada al constructor.
Llamada al constructor.
Número de animales que se han instanciado: 4
Herencia en PHP.
La herencia es un concepto muy importante en POO. Permite reutilizar el código de
una clase sin necesidad de volver a escribirlo. Una clase hija hereda de una clase
madre, es decir, accede a todos los atributos y los métodos públicos de la clase
madre. Por ejemplo, la clase Mamífero hereda de la clase Animal, y la clase Coche
hereda de la clase Vehículo.
Si la clase A es una subcategoría de la clase B, entonces puede hacer que la clase
A (Mamífero o Coche) herede de la clase B (Animal o Vehículo). Imagine como unas
clases Pez y Gato serían ejemplos de herencia de la clase Animal.
Para crear la clase Pez que hereda de la clase Animal, debe utilizar la palabra clave
extends entre el nombre de la clase hija y el nombre de la clase madre.
Cree un archivo pez.class.php y escriba el siguiente código:
<?php
class Pez extends Animal
{
}
?>
Ahora añada un atributo privado que corresponda a la variable vive_en_el_mar y
los accesos get y set. Para terminar, el método público nadar().
<?php
class Pez extends Animal
{
private $vive_en_el_mar; //tipo de pez
//accesos
public function getType()
{
if ($this->vive_en_el_mar){
return "vive_en_el_mar";
}
else if ($this->vive_en_el_mar===falso){
return "no_vive_en_el_mar";
}else {return "";}
}
public function setType($vive_en_el_mar)
{
$this->vive_en_el_mar = $vive_en_el_mar;
//escrito en el atributo vive_en_el_mar
}
//método
public function nadar()
{
echo "Nado";
}
}
?>
De la misma manera, cree un archivo gato.class.php:
<?php
class Gato extends Animal
{
private $raza; //raza del gato
//accesos
public function getRaza()
{
return $this->raza; //devuelve la raza
}
public function setRaza($raza)
{
$this->raza = $raza; //escrito en el atributo raza
}
//método
public function maullar()
{
echo "Miau
";
}
}
?>
Las clases Gato y Pez, que heredan de la clase Animal, tienen acceso a los atributos
públicos de la clase Animal.
La página uso.php:
<?php
//carga de clases
include(’animal.class.php’);
include(’pez.class.php’);
include(’gato.class.php’);
//instanciar la clase Pez que llama al constructor de
//la clase Animal
$pez = new Pez("gris",8);
//instanciar la clase Gato que llama al constructor de la
//clase Animal
$gato = new Gato("blanco",4);
//leer el peso con el acceso de la clase madre
echo "El peso del pez es: ".$pez->getPeso()." kg
";
//leer el peso con el acceso de la clase madre
echo "El peso del gato es: ".$gato->getPeso()." kg
";
$pez->setType(true);
//leer el tipo con el acceso de su propia clase
echo "El tipo de pez es: ".$pez->getType()."
";
//llamada al método de la clase Pez
$pez->nadar();
$gato->setRaza("Angora");
//leer la raza con el acceso de su propia clase
echo "La raza del gato es: ".$gato->getRaza()."
";
//llamada al método de la clase gato
$gato->maullar();
//llamada al método estático
echo "Número de animales que se han instanciado:"
.Animal::getContador();
?>
Da como resultado:
Llamada al constructor.
Llamada al constructor.
El peso del pez es: 8 kg
El peso del gato es: 4 kg
El tipo de pez es: vive en el mar
Nado
La raza del gato es: Angora
Miau
Número de animales que se han instanciado:2
La clase Pez no tiene acceso a los atributos de la clase Gato y viceversa, ya que
una hereda de la otra. Las clases Pez y Gato no tienen directamente acceso a los
atributos privados color y peso de la clase Animal. Deben pasar por sus accesos
públicos.
Protected.
Este tipo de visibilidad equivale a private, salvo que las clases hijas puedan ver los
atributos protected de la clase madre.
Por ejemplo, vamos a añadir el atributo $edad de visibilidad protegida (protected)
en la clase madre Animal:
<?php
class Animal
{
// Declaración de atributos
private $color = "gris";
private $peso = 10;
protected $edad = 0;
etc.
Este atributo no tiene acceso público; por lo tanto, ninguna de las otras clases hijas
que heredan de Animal y de la clase Animal pueden modificarlo o leerlo.
Añada la función mostrarAtributos() en la clase Pez:
public function mostrarAtributos()
{
echo "Type:".$this->vive en el mar; // correcto ya que es
// privada de esta clase
echo "";
echo "Edad:".$this->edad; // correcto, ya que el atributo
// está protegido en la clase madre.
echo "";
echo "Peso:".$this->peso; // error, ya que el atributo es
//privado en la clase madre, el acceso está prohibido. Debe pasar
//por sus accesos públicos para modificar o leer su valor
echo "
";
}
Para probar este método, la página uso.php se convierte en:
<?php
//carga de clases
include(’animal.class.php’);
include(’pez.class.php’);
//instanciar la clase Pez que llama al constructor de
//la clase Animal
$pez = new Pez("gris",8);
//leer el peso con el acceso de la clase madre
echo "El peso del pez es:".$pez->getPeso()." kg
";
//actualizar el tipo de pez
$pez->setType(true);
//llamada al método mostrando los atributos de la clase Pez
//y Animal
$pez->VerAtributos();
?>
Da como resultado:
La clase Pez no tiene acceso al atributo peso de la clase Animal, ya que es privado.
En conclusión, se recomienda poner los atributos en visibilidad protected, ya que la
propia clase, las clases hijas y las que heredan tienen acceso a este atributo.
Sustitución.
Sirve para modificar un método que ya existe en una clase madre, con el objetivo
de cambiar el comportamiento. El método existe en dos clases diferentes y según
el contexto se ejecuta el de la clase hija o el de la clase madre.
Por ejemplo, para sustituir el método comer_animal(Animal $animal_comido) de la
clase Animal con el objetivo de inicializar el tipo de pez comido, debe añadir este
método en la clase Pez y aplicarlo de otra manera:
Añada en la clase pez.class.php:
//método sustituido
public function comer_animal(Animal $animal_comido)
{
if (isset($animal_comido->raza)){
$animal_comido->raza="";
}
if (isset($animal_comido->vive_en_el_mar)){
$animal_comido->vive_en_el_mar="")
}
}
El problema es que este método inicializa correctamente el atributo vive_ en_
el_mar del pez comido, pero ya no inicializa su peso y su color. No puede cambiar
aquí su peso y su color, ya que estos atributos son privados en la clase Animal.
La solución está en llamar al método comer_animal(Animal $animal_comido) de la
clase Animal en el método comer_animal(Animal $animal_comido) de la clase Pez:
//Método sustituido
public function comer_animal(Animal $animal_comido)
{
// al método comer_animal() de la clase padre,
// es decir Animal
padre::comer_animal($animal_comido);
if (isset($animal_comido->raza)){
$animal_comido->raza="";
}
if (isset($animal_comido->vive_en_el_mar)){
$animal_comido->vive_en_el_mar="")
}
}
padre es una palabra clave que designa la clase madre, es decir, la clase Animal.
La página uso.php:
<?php
//carga de clases
include(’animal.class.php’);
include(’pez.class.php’);
//instanciar la clase Pez que llama al constructor de la
//clase Animal
$pez = new Pez("gris",8);
//actualizar el tipo de pez
$pez->setType(true);
//instanciar la clase Pez que llama al constructor de la
//clase Animal
$otro_pez = new Pez("negro",5);
// el tipo de pez
$otro_pez->setType(falso);
//llamada al método que muestra los atributos de la clase Pez
//y Animal
$pez->comer_animal($otro_pez);
//leer el tipo por el acceso de su propia clase
echo "El tipo de pez comido es:".$otro_pez->getType()."
";
//leer el peso por el acceso de la clase madre
echo "El peso del pez comido es:".$otro_pez->getPeso()." kg
";
?>
Da como resultado:
Llamada al constructor.
Llamada al constructor.
El tipo de pez comido es:
El peso del pez comido es:0 kg
El peso se ha inicializado a 0 por el método comer_animal(Animal $animal_comido)
de la clase Animal.
En la clase Pez, el método comer_animal(Animal $animal_comido) puede cambiar
el atributo tipo en un objeto de tipo Animal, ya que Pez hereda de Animal y, en el
archivo uso.php, es un Pez lo que pasa como argumento, y no un Animal. Se trata
del polimorfismo de herencia.
Herencia en cascada
La herencia múltiple no existe en PHP. Una clase solo puede heredar de una única
clase, que a su vez puede heredar de una clase, etc.
Imagine unas nuevas clases Pez Espada y Carpa que heredan de la clase Pez, que
a su vez hereda de la clase Animal.
La clase Pez Espada accede a:
• Todos los atributos y métodos privados, protegidos y públicos por sí misma.
• Todos los atributos y métodos protegidos y públicos de la clase Pez.
• Todos los atributos y métodos protegidos y públicos de la clase Animal.
• Todos los atributos y métodos públicos de la clase Gato.
Las clases abstractas.
Se escriben con la palabra clave abstract delante de la palabra class. Una clase
abstracta no se puede instanciar, es decir, no permite crear una instancia. Puede
escribir métodos abstractos, que son métodos donde solo escribe la firma precedida
por la palabra clave abstract: abstract visibilidad function nombre_método (atributo
tipo_atributo...). Estas clases solo sirven para obligar, a las clases que heredan de
la clase abstracta, a reemplazar los métodos abstractos declarados en la clase
abstracta.
En el siguiente ejemplo, la clase Animal es abstracta, ya que no se quiere crear
(instanciar) animales, sino peces o gatos.
Añada también un método abstracto respira() en la clase Animal:
<?php
abstract class Animal
{
// Declaración de atributos
private $color = "gris";
private $peso = 10;
//constantes de clase
const PESO_LIGERO = 5;
const PESO_MEDIO = 10;
const PESO_PESADO = 15;
// Declaración de la variable estática $contador
private static $contador = 0;
public function __construct($color, $peso) // Constructor
//que solicita 2 argumentos.
{
echo ’Llamada al constructor.<br />’;
$this->color = $color; // Inicialización del color.
$this->peso = $peso; // Inicialización del peso.
self::$contador = self::$contador + 1;
}
//accesos
public function getColor()
{
return $this->color; //devuelve el color
}
public function setColor($color)
{
$this->color = $color; //escrito en el atributo color
}
public function getPeso()
{
return $this->peso; //devuelve el peso
}
public function setPeso($peso)
{
$this->peso = $peso; //escrito en el atributo peso
}
//métodos públicos
public function comer_animal(Animal $animal_comido)
{
//el animal que come aumenta su peso tanto como
//el del animal comido
$this->peso = $this->peso + $animal_comido->peso;
//el peso del animal comido y su color se restablecen a 0
$animal_comido->peso = 0;
$animal_comido->color = "";
}
public static function moverse()
{
echo "El animal se mueve.";
}
public function añadir_un_kilo()
{
$this->peso = $this->peso + 1;
}
// método estático que devuelve el valor del contador
public static function getContador()
{
return self::$contador;
}
//código no aplicado por el método abstracto
abstract public function respira();
}
?>
Observe que el método abstracto respira() no tiene cuerpo, es decir, no hay llaves
{} en la aplicación del método.
Como las clases Pez y Gato heredan de la clase Animal, está obligado a definir de
nuevo el método respira() en las clases Pez y Gato.
Debe añadir en la clase Pez lo siguiente:
public function respira()
{
echo "El pez respira.<br />";
}
Y en la clase Gato:
public function respira()
{
echo "El gato respira.<br />";
}
La página uso.php se convierte en:
<?php
//carga de clases
include(’animal.class.php’);
include(’pez.class.php’);
include(’gato.class.php’);
//instanciar la clase Pez, que llama al constructor de
//la clase Animal
$pez = new Pez("gris",8);
//instanciar la clase Gato, que llama al constructor de
//la clase Animal
$gato = new Gato("blanco",4);
//llamada al método respira()
$pez->respira();
$gato->respira();
?>
Da como resultado:
Llamada al constructor.
Llamada al constructor.
El pez respira.
El gato respira.
Las clases finales.
Cuando una clase es final, no se puede crear la clase hija que hereda de esta clase.
Esto tiene poco interés práctico.
Debe añadir la palabra clave final delante de la palabra clave class.
Por ejemplo, si no crea una clase que hereda de la clase Pez, puede escribir final:
<?php
final class Pez extends Animal
{
private $vive en el mar; //tipo de pez
//accesos
...
//método
public function nadar()
{
echo "Nado <br />";
}
public function respira()
{
echo "El pez respira.<br />";
}
}
?>
También puede declarar los métodos finales. Estos métodos no se podrán sustituir.
En el tópico de sustitución ya se ha visto un ejemplo donde el método
comer_animal(Animal $animal_comido) se ha sustituido en la clase Pez. Si este
método era final en la clase Animal:
final public function comer_animal(Animal $animal_comido)
{
//el animal que come aumenta su peso tanto como
//el del animal comido
$this->peso = $this->peso + $animal_comido->peso;
//el peso del animal comido y su color se restablecen a 0
$animal_comido->peso = 0;
$animal_comido->color = "";
}
Por lo tanto, es imposible sustituir este método en la clase Pez.
Métodos mágicos en PHP.
Es un método al que se llama automáticamente cuando se produce un
acontecimiento. Por ejemplo __construct es un método mágico. Se ejecuta
automáticamente cuando instancia la clase que contiene __construct. Los métodos
mágicos __get y __set permiten leer o modificar los atributos que no existen y en
los que el acceso está prohibido.
Retomando el ejemplo con la clase Animal. Esta vez, el atributo color es privado y
el atributo peso es público:
<?php
class Animal
{
// Declaración de atributos
private $color = "gris";
public $peso = 10;
public function __construct($color, $peso) // Constructor
//que solicita 2 argumentos.
{
echo ’Llamada al constructor.’;
$this->color = $color; // Inicialización del color.
$this->peso = $peso; // Inicialización del peso.
}
//métodos públicos
public function comer ()
{ }
public function moverse ()
{ }
}
?>
Cuando crea una instancia de la clase Animal, puede acceder al atributo peso
porque es público, pero no al atributo color porque es privado.
La página uso.php es:
<?php
//carga de clases
include(’animal.class.php’);
//instanciar la clase Animal
$perro = new Animal("gris",8);
$perro->color = "negro";
echo $perro→color."";
?>
Muestra un error porque intenta acceder directamente al atributo color, que es
privado:
Llamada al constructor.
Fatal error: Cannot access private property Animal::$color in C:Program
FilesEasyPHP-DevServer-13.1VC11datalocalwebObjeto uso.php on line 9
Ahora añada los métodos mágicos __get y __set en la clase Animal:
<?php
class Animal
{
// Declaración de atributos
private $color = "gris";
public $peso = 10;
private $tab_atributos = array();
public function __construct($color, $peso) // Constructor
//que solicita 2 argumentos.
{
echo ’Llamada al constructor.’;
$this->color = $color; // Inicialización del color.
$this->peso = $peso; // Inicialización del peso.
}
//métodos mágicos
public function __get($nombre)
{
echo "__get ";
if (isset ($this->tab_atributos[$nombre]))
return $this->tab_atributos[$nombre];
}
public function __set($nombre, $valor)
{
echo "__set ";
$this->tab_atributos[$nombre] = $valor;
}
public function __isset($nombre)
{
return isset ($this->tab_atributos[$nombre]);
}
//métodos públicos
public function comer ()
{
...
}
public function moverse ()
{
...
}
}
?>
Estos métodos se activan automáticamente si el atributo es privado o no existe.
Almacenan el valor en la tabla $tab_atributos, y en el índice, el nombre del atributo.
El método __isset($atributo) permite saber si existe el atributo.
La página uso.php:
<?php
//carga de clases
include(’animal.class.php’);
//instanciar la clase Animal
$perro = new Animal("gris",8);
if (isset($perro->color)) {
echo "El atributo color existe.";
}
else {
echo "El atributo color no existe.";
}
$perro->color = "negro";
echo $perro->color."";
if (isset($perro->peso)) {
echo "El atributo peso existe.
";
}
else {
echo "El atributo peso no existe.
";
}
$perro->peso = 25;
echo $perro->peso."
";
?>
Da como resultado:
Llamada al constructor.
El atributo color no existe.
__set
__get
Negro
El atributo peso existe.
25
Explicación:
$perro = new Animal("gris",8); da como resultado: Llamada al constructor.
isset($perro->color); devuelve falso, ya que no se puede acceder al atributo color,
que es privado; por lo tanto, muestra: El atributo color no existe.
$perro->color = "negro"; da como resultado: __set. El atributo color es privado; por
lo tanto, no se puede acceder a él y llama automáticamente a __set y el valor se
almacena en la tabla $tab_atributos.
echo $perro->color."<br />"; da como resultado: __get y negro. El atributo color
siempre es privado; por lo tanto, llama automáticamente a __get para mostrar el
color.
isset($perro->peso); devuelve verdadero porque el atributo peso es público, se
puede acceder a él y por lo tanto muestra: el atributo peso existe.
$perro->peso = 25; no muestra nada porque no llama a la función __set. El atributo
peso es público, puede acceder directamente a él.
echo $perro->peso."<br />"; da como resultado 25. El atributo peso es público y por
lo tanto puede acceder directamente a él.
Para eliminar un atributo que el método mágico __set ha añadido, debe ejecutar el
método mágico __unset($atributo), que eliminará el atributo de la tabla
$tab_atributos.
Añada este método en la clase Animal:
public function __unset($nombre)
{
if (isset($this->tab_atributos[$nombre]))
unset($this->tab_atributos[$nombre]);
}
Para terminar, los métodos mágicos __call y __callStatic permiten llamar a los
métodos privados o que no existen. La función method_exist() comprueba si un
método existe en un objeto. Toma como argumento el objeto y el nombre del
método. Devuelve true si el método existe y false si no. La clase Animal con un
método público comer() y un método privado moverse() se convierte en:
<?php
class Animal
{
// Declaración de atributos
private $color = "gris";
public $peso = 10;
private $tab_atributos = array();
public function __construct($color, $peso) // Constructor
//que solicita 2 argumentos.
{
echo ’Llamada al constructor.’;
$this->color = $color; // Inicialización del color.
$this->peso = $peso; // Inicialización del peso.
}
//métodos mágicos
public function __get($nombre)
{
echo "__get ";
if (isset ($this->tab_atributos[$nombre]))
return $this->tab_atributos[$nombre];
}
public function __set($nombre, $valor)
{
echo "__set ";
$this->tab_atributos[$nombre] = $valor;
}
public function __isset($nombre)
{
return isset ($this->tab_atributos[$nombre]);
}
public function __call($nombre, $argumentos)
{
echo "El método ".$nombre." no es accesible. Sus argumentos
eran los siguientes :".implode($argumentos, ’, ’)."";
if(method_exists($this, $nombre))
{
$this->$nombre(implode($argumentos, ’, ’));
}
}
public static function __callStatic($nombre, $argumentos)
{
echo "El método estático ".$nombre." no es accesible.
Sus argumentos eran los siguientes :".implode($argumentos, ’, ’) . "";
if(method_exists(__CLASS__, $nombre))
{
echo __CLASS__.’::’.$nombre.’ ’;
self::$nombre(implode($argumentos, ’, ’));
}
}
//método público
public function comer()
{
echo "Método público comer() ";
}
//método privado
private function moverse($lugar)
{
echo "Método privado moverse() ";
}
}
?>
La página uso.php:
<?php
//carga de clases
include(’Animal.class.php’);
//instanciar la clase Animal
$perro = new Animal("gris",8);
$perro->comer();
$perro->moverse("París");
?>
Da como resultado:
Llamada al constructor.
Método público comer()
El método moverse no es accesible. Sus argumentos eran los siguientes:París
Método privado moverse()
El código $perro->comer(); llama al método público comer(). Pero al método
moverse($lugar), que es privado, no se puede acceder directamente. Llama al
método mágico __call, comprueba que existe el método moverse($lugar)y llama al
método moverse ($lugar).
Si el método moverse ($lugar) es estático, la llamada a la página uso.php es:
Animal::moverse("París");
Entonces llama al método mágico __callStatic.
Namespaces en PHP
Cuando trabaja en proyectos grandes en equipo, es útil modularizar las clases y las
funciones. De esta manera, cada desarrollador puede trabajar con su propio
módulo. Desde PHP 5.3, las namespaces (espacio de nombres), permiten esta
modularización. Un namespace es una especie de carpeta virtual en la que
almacena sus objetos. De esta manera es posible usar clases o funciones con el
mismo nombre, en namespaces diferentes.
Un namespace se declara con la palabra clave namespace, seguido de su nombre,
al inicio del archivo.
Por ejemplo:
Espacio_nombre.php
<?php
// Definición del espacio de nombres.
namespace Biblioteca;
// Definición de una constante.
const PI = 3.1416;
// Definición de una función.
function miFuncion() {
echo "Hola <br />";
}
// Definición de una clase.
class miClase { /* … */ }
?>
Uso_espacio_nombres.php:
<?php include(’espacio_nombres.php’);
BibliotecamiFuncion(); //Llamada al namespace Biblioteca raíz
?>
Muestra:
Hola
La constante __NAMESPACE__ devuelve el nombre del espacio de nombres
actual.
Es posible crear sub-espacios de nombres escribiendo:
Namespace Espacio1/subespacio1;
Las rutas para encontrar una función, clase o constante en un espacio de nombres
son relativos si empieza por el namespace o absoluto si empieza con /.
Por ejemplo:
Espacio_nombres.php:
<?php
// Definición del espacio de nombres.
namespace Biblioteca;
// Definición de una constante.
const PI = 3.1416;
// Definición de una función.
function miFuncion() {
echo "Hola <br />";
}
// Definición de una clase.
class Animal
{
// Declaración de los atributos
private $color = "gris";
//accesos
public function getColor()
{
return $this->color; //devuelve el color
}
public function setColor($color)
{
$this->color = $color; //escribe en el atributo color
}
}
?>
Uso_espacio_nombres.php
<?php
namespace Project;
include(’espacio_nombres.php’);
// Muestra el espacio de nombres actual.
echo ’Espacio de nombres actual = ’, __NAMESPACE__,’<br />’;
BibliotecamiFuncion(); //Llamada al namespace Biblioteca raíz
echo BibliotecaPI."<br />";
$gato = new BibliotecaAnimal();
$gato->setColor("negro");
echo "El color del gato es:".$gato->getColor();
?>
Muestra:
Espacio de nombres actual:Project
Hola
3.1416
El color del gato es: negro
Para terminar, puede crear un alias en el espacio de nombres o en un objeto
contenido en el espacio de nombres.
Para esto basta con usar el operador use [namespace] as nombre_nuevo
Por ejemplo:
UseBiblioteca as biblio;
Con los alias, la página Uso_espacio_nombres.php, se convierte en:
<?php
namespace Project ;
include (´espacio_nombres.php’) ;
//Muestra el espacio de nombres actual.
echo ’Espacio de nombres actual = ’, _NAMESPACE_’<br />’;
BibliotecamiFuncion() ; llamada al namespace Biblioteca raíz
useBiblioteca as biblio; // alias de un namespace
echo BibliotecaPI., ”<br />”;
use Biblioteca|Animal as ani; // alias de una clase
$gato = new ani (); // Llamada al alias de la clase
//Animal$gato->setColor (”negro”),
echo ”El color del gato es : ”.$gato->getColor();
?>
Muestra:
Espacio de nombres actual=Project
Hola
3.1416
El color del gato es: negro
Supongamos que tenemos dos clases: Auto y Motocicleta, como se muestra en el
diagrama de clases UML la figura 12. Si se analiza detalladamente, ambas clases
son muy similares en atributos y métodos; la motocicleta no tiene el atributo
cantidad_puertas. Ambas son un tipo de vehículo. En este tipo de relación se habla
de herencia o generalización, donde se puede definir una clase padre denominada
Vehículo de la que toman características y comportamiento las clases anteriores
(Véase Figura 13).
En la herencia, las clases hijas extienden de la clase base, la cual debe tener
atributos protegidos; sin embargo, también pueden tener atributos y
comportamiento particulares. En PHP una clase sólo puede extender de una clase
base.
En el diagrama de clases siguiente, se observa que tanto Auto como Motocicleta
heredan los métodos y atributos de Vehículo.
Figura 12. Ejemplo de Diagrama de clases UML (Fuente: elaboración propia)
Figura 13. Ejemplo de Generalización en UML. (Fuente: elaboración propia a partir de
Gaitán, Fernando.)
En forma de código, esto se ve reflejado así:
<?php
namespace herencia;
class Vehiculo{
protected $motor_encendido=false;
protected $cantidad_ruedas;
protected $marca;
public function __construct($cRuedas,$marca) {
$this->cantidad_ruedas=$cRuedas;
$this->marca=$marca;
echo 'Se ha instanciado un vehículo de: '.$this-
>cantidad_ruedas.' ruedas'
.' Marca: '.$this->marca.'<br/>';
}
public function encenderMotor(bool $encendido){
$this->motor_encendido=$encendido;
}
public function arrancar(){
if ($this->motor_encendido) {
echo '¡Encendido!';
}
}
}
?>
Código 24. Clase vehículo. (Fuente: adaptado de Gaitán, Fernando)
<?php
namespace herencia;
class Auto extends Vehiculo{
private $cantidad_puertas;
public function getCantidadPuertas(){
return $this->cantidad_puertas;
}
public function setCantidadPuertas($cantidadPuertas){
$this->cantidad_puertas=$cantidadPuertas;
}
public function __construct($cRuedas, $marca, $cantidadPuertas) {
parent::__construct($cRuedas, $marca);
$this->cantidad_puertas=$cantidadPuertas;
echo 'Se ha instanciado un objeto Auto de: '
.$this->cantidad_ruedas.' ruedas y '.$cantidadPuertas.'
puertas <br/>';
}
}
?>
Código 25. Clase Auto. (Fuente: adaptado de Gaitán, Fernando)
Las 3 primeras clases ejemplifican una buena práctica: el uso de namespaces,
permite organizar los archivos, similar a rutas en un sistema de archivos. Es más
adecuado que la ruta coincida con el espacio de nombres, el cual debe de ser
declarado al inicio del archivo antes de cualquier otra instrucción excepto declare.
Para acceder a las clases de un espacio de nombres existen varias maneras: una
de ellas, es especificar el nombre completo de la clase al referenciarla, por ej.:
$carro=new herenciaAuto(); otra forma, es que el archivo index.php pertenezca al
mismo namespace.
La mejor manera es utilizar la palabra clave use. Ésta permite especificar el nombre
completo de una clase. También se puede asignar un alias con la palabra clave as
seguida de un nombre.
<?php
namespace herencia;
class Motocicleta extends Vehiculo{
public function __construct($cRuedas, $marca) {
parent::__construct($cRuedas, $marca);
echo 'Lo que ha instanciado es un objeto Motocicleta </br>';
}
}
?>
Código 27. Clase Motocicleta. (Fuente: adaptado de Gaitán, Fernando)
<?php
use herenciaAuto;
use herenciaMotocicleta as M;
require_once 'herencia/Vehiculo.php';
require_once 'herencia/Auto.php';
require_once 'herencia/Motocicleta.php';
$c=new Auto(4, 'Nissan', 3);
$c->encenderMotor(TRUE);
$c->arrancar();
echo '<br/><br/>';
$m=new M(2, 'Honda');
?>
Código 26. Archivo index.php. (Fuente: adaptado de Gaitán, Fernando)
En el archivo index.php se le indicó al servidor cómo evaluar y procesar el código
de las clases mediante require_once.
A como se indicó en el diagrama de clases de la Fig. 13, las clases Auto y
Motocicleta heredan de su clase base o padre, Vehículo. Esto se indica en PHP
mediante la palabra reservada extends. Tanto Auto como Motocicleta tienen los
atributos motor_encendido, cantidad_puertas y marca así como el
comportamiento establecido al declarar los métodos encender_motor, apagar, y
arrancar. Auto tiene un atributo propio: cantidad de puertas; es decir que las clases
hijas pueden tener atributos particulares diferentes a su clase base.
Para hacer referencia a un método o propiedad de la clase principal desde su hija,
se puede usar $this como si la propiedad o el método estuvieran en la misma clase.
Sin embargo, si se desea hacer referencia a la implementación en la clase padre,
se debe utilizar la palabra clave parent seguido del operador Paamayim
Nekudotayim (::) u operador de doble dos puntos seguido del nombre del método.
En la siguiente figura, se puede observar que se llama al constructor de la clase
base dejándolo hacer lo programado y luego ejecuta las instrucciones
especializadas en la clase hija.
Figura 14. Salida de la ejecución del código anterior.
Referencias bibliográficas:
http://www.4rsoluciones.com/blog/que-son-los-paradigmas-de-programacion-2/
https://es.ccm.net/contents/410-poo-encapsulacion-de-datos
https://es.wikipedia.org/wiki/Programaci%C3%B3n_orientada_a_objetos
https://es.wikipedia.org/wiki/Encapsulamiento_(inform%C3%A1tica)
Joyanes A., Luis. (2008). Fundamentos de programación. (4 Ed.). McGraw-HILL /
Interamericana de España.
http://www.tutorialesprogramacionya.com/phpya/poo/temarios/descripcion.php?co
d=35&punto=1&inicio=0
http://tutorialphp.net/php-7-orientado-a-objetos/
https://www.youtube.com/watch?v=r8w2wEj8ZyI&list=PLoNyKJJ130VF0ybSWkLgi
TGwePQ9cv-JL
https://styde.net/aprende-programacion-orientada-a-objetos-poo-con-php/
https://fernando-gaitan.com.ar/php-orientado-a-objetos-parte-6-herencia/
https://diego.com.es/programacion-orientada-a-objetos-en-php
http://anexsoft.com/p/149/que-son-y-ejemplo-de-namespaces-en-php

Weitere ähnliche Inhalte

Was ist angesagt?

Programacion Orientada a Eventos
Programacion Orientada a EventosProgramacion Orientada a Eventos
Programacion Orientada a Eventos
Laura
 
1. modelo entidad relacion ejemplo
1. modelo entidad relacion   ejemplo1. modelo entidad relacion   ejemplo
1. modelo entidad relacion ejemplo
univ of pamplona
 
Ventajas y desventajas de las bases de datos frente a los archivos
Ventajas y desventajas de las bases de datos frente a los archivosVentajas y desventajas de las bases de datos frente a los archivos
Ventajas y desventajas de las bases de datos frente a los archivos
Isabel
 

Was ist angesagt? (20)

Programacion Orientada a Eventos
Programacion Orientada a EventosProgramacion Orientada a Eventos
Programacion Orientada a Eventos
 
AD Unidad3: Tecnologías de aplicaciones distribuidas
AD Unidad3: Tecnologías de aplicaciones distribuidasAD Unidad3: Tecnologías de aplicaciones distribuidas
AD Unidad3: Tecnologías de aplicaciones distribuidas
 
Plan de desarrollo software
Plan de desarrollo softwarePlan de desarrollo software
Plan de desarrollo software
 
1. modelo entidad relacion ejemplo
1. modelo entidad relacion   ejemplo1. modelo entidad relacion   ejemplo
1. modelo entidad relacion ejemplo
 
Control de versiones
Control de versionesControl de versiones
Control de versiones
 
Linea de tiempo sistemas operativos
Linea de tiempo sistemas operativosLinea de tiempo sistemas operativos
Linea de tiempo sistemas operativos
 
Manual de instalacion
Manual de instalacionManual de instalacion
Manual de instalacion
 
Diagramas De Caso De Uso
Diagramas De Caso De UsoDiagramas De Caso De Uso
Diagramas De Caso De Uso
 
Ventajas y desventajas de las bases de datos frente a los archivos
Ventajas y desventajas de las bases de datos frente a los archivosVentajas y desventajas de las bases de datos frente a los archivos
Ventajas y desventajas de las bases de datos frente a los archivos
 
22 ejercicios base de datos
22 ejercicios base de datos 22 ejercicios base de datos
22 ejercicios base de datos
 
Ejercicios normalizacion
Ejercicios normalizacionEjercicios normalizacion
Ejercicios normalizacion
 
Sistemas operativos
Sistemas operativos Sistemas operativos
Sistemas operativos
 
Php ppt
Php pptPhp ppt
Php ppt
 
Generación de documentación con star UML
Generación de documentación con star UMLGeneración de documentación con star UML
Generación de documentación con star UML
 
¿QUE ES Y DONDE SE APLICA LA PROGRAMACION ORIENTADA A OBJETOS?
¿QUE ES Y DONDE SE APLICA LA PROGRAMACION ORIENTADA A OBJETOS?¿QUE ES Y DONDE SE APLICA LA PROGRAMACION ORIENTADA A OBJETOS?
¿QUE ES Y DONDE SE APLICA LA PROGRAMACION ORIENTADA A OBJETOS?
 
Introducción a NodeJS
Introducción a NodeJSIntroducción a NodeJS
Introducción a NodeJS
 
1 - Modelo Entidad Relacion
1 - Modelo Entidad Relacion1 - Modelo Entidad Relacion
1 - Modelo Entidad Relacion
 
Metodología WEB UWE
Metodología WEB UWEMetodología WEB UWE
Metodología WEB UWE
 
Normalización en Bases de datos
Normalización en Bases de datosNormalización en Bases de datos
Normalización en Bases de datos
 
tecnología de conectividad de datos
tecnología de conectividad de datostecnología de conectividad de datos
tecnología de conectividad de datos
 

Ähnlich wie Manual PHP 7 (20)

Guia 5
Guia 5Guia 5
Guia 5
 
Php
PhpPhp
Php
 
Programacion en php
Programacion en phpProgramacion en php
Programacion en php
 
3144
31443144
3144
 
Guiacursophp sql
Guiacursophp sqlGuiacursophp sql
Guiacursophp sql
 
Curso introduccionphp sql
Curso introduccionphp sqlCurso introduccionphp sql
Curso introduccionphp sql
 
Apuntes php
Apuntes phpApuntes php
Apuntes php
 
Programacion en php atavez de ejemplos
Programacion en php atavez de ejemplosProgramacion en php atavez de ejemplos
Programacion en php atavez de ejemplos
 
Apuntes php
Apuntes phpApuntes php
Apuntes php
 
Ensayo php
Ensayo phpEnsayo php
Ensayo php
 
Manual basico de PHP
Manual basico de PHPManual basico de PHP
Manual basico de PHP
 
Guia programacionwebbasicophp
Guia programacionwebbasicophpGuia programacionwebbasicophp
Guia programacionwebbasicophp
 
Introduccion A Php
Introduccion A PhpIntroduccion A Php
Introduccion A Php
 
Introduccion A Php
Introduccion A PhpIntroduccion A Php
Introduccion A Php
 
Introduccion A Php
Introduccion A PhpIntroduccion A Php
Introduccion A Php
 
Mini manual php
Mini manual phpMini manual php
Mini manual php
 
33 php
33 php33 php
33 php
 
Php02 fundamentos de php
Php02 fundamentos de phpPhp02 fundamentos de php
Php02 fundamentos de php
 
Mini manual php
Mini manual phpMini manual php
Mini manual php
 
Introducción a PHP
Introducción a PHPIntroducción a PHP
Introducción a PHP
 

Mehr von Facultad de Ciencias y Sistemas

Mehr von Facultad de Ciencias y Sistemas (20)

Ejercicios HTML 5
Ejercicios HTML 5Ejercicios HTML 5
Ejercicios HTML 5
 
CSS3
CSS3CSS3
CSS3
 
09 ordenamiento-en-vectores-en-c
09 ordenamiento-en-vectores-en-c09 ordenamiento-en-vectores-en-c
09 ordenamiento-en-vectores-en-c
 
08 mas-de-vectores-en-c
08 mas-de-vectores-en-c08 mas-de-vectores-en-c
08 mas-de-vectores-en-c
 
07 vectores-en-c final
07 vectores-en-c final07 vectores-en-c final
07 vectores-en-c final
 
06 clases-en-c
06 clases-en-c06 clases-en-c
06 clases-en-c
 
05 cadenas-de-caracteres-en-c
05 cadenas-de-caracteres-en-c05 cadenas-de-caracteres-en-c
05 cadenas-de-caracteres-en-c
 
04 mas-estructuras-iterativas-en-c
04 mas-estructuras-iterativas-en-c04 mas-estructuras-iterativas-en-c
04 mas-estructuras-iterativas-en-c
 
03 estructuras-iterativas-en-c
03 estructuras-iterativas-en-c03 estructuras-iterativas-en-c
03 estructuras-iterativas-en-c
 
02 mas-de-las-estructuras-de-programacion-en-c
02 mas-de-las-estructuras-de-programacion-en-c02 mas-de-las-estructuras-de-programacion-en-c
02 mas-de-las-estructuras-de-programacion-en-c
 
01 estructuras-de-programacion-en-c
01 estructuras-de-programacion-en-c01 estructuras-de-programacion-en-c
01 estructuras-de-programacion-en-c
 
Procesamiento del lenguaje natural con python
Procesamiento del lenguaje natural con pythonProcesamiento del lenguaje natural con python
Procesamiento del lenguaje natural con python
 
Actividades de aprendizaje en Moodle
Actividades de aprendizaje en MoodleActividades de aprendizaje en Moodle
Actividades de aprendizaje en Moodle
 
Creación de grupos en Moodle
Creación de grupos en MoodleCreación de grupos en Moodle
Creación de grupos en Moodle
 
Introducción a la progrogramación orientada a objetos con Java
Introducción a la progrogramación orientada a objetos con JavaIntroducción a la progrogramación orientada a objetos con Java
Introducción a la progrogramación orientada a objetos con Java
 
Como crear un diagrama de clases
Como crear un diagrama de clasesComo crear un diagrama de clases
Como crear un diagrama de clases
 
Diagrama de clases - Ejemplo monográfico 02
Diagrama de clases - Ejemplo monográfico 02Diagrama de clases - Ejemplo monográfico 02
Diagrama de clases - Ejemplo monográfico 02
 
Diagrama de clases - Ejemplo monográfico 01
Diagrama de clases - Ejemplo monográfico 01Diagrama de clases - Ejemplo monográfico 01
Diagrama de clases - Ejemplo monográfico 01
 
Otro ejemplo de diagrama de clases UML
Otro ejemplo de diagrama de clases UMLOtro ejemplo de diagrama de clases UML
Otro ejemplo de diagrama de clases UML
 
Un ejemplo de diagrama de clases
Un ejemplo de diagrama de clasesUn ejemplo de diagrama de clases
Un ejemplo de diagrama de clases
 

Kürzlich hochgeladen

Proyecto de aprendizaje dia de la madre MINT.pdf
Proyecto de aprendizaje dia de la madre MINT.pdfProyecto de aprendizaje dia de la madre MINT.pdf
Proyecto de aprendizaje dia de la madre MINT.pdf
patriciaines1993
 
2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx
2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx
2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx
RigoTito
 
5.- Doerr-Mide-lo-que-importa-DESARROLLO PERSONAL
5.- Doerr-Mide-lo-que-importa-DESARROLLO PERSONAL5.- Doerr-Mide-lo-que-importa-DESARROLLO PERSONAL
5.- Doerr-Mide-lo-que-importa-DESARROLLO PERSONAL
MiNeyi1
 

Kürzlich hochgeladen (20)

OCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VS
OCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VSOCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VS
OCTAVO SEGUNDO PERIODO. EMPRENDIEMIENTO VS
 
ACRÓNIMO DE PARÍS PARA SU OLIMPIADA 2024. Por JAVIER SOLIS NOYOLA
ACRÓNIMO DE PARÍS PARA SU OLIMPIADA 2024. Por JAVIER SOLIS NOYOLAACRÓNIMO DE PARÍS PARA SU OLIMPIADA 2024. Por JAVIER SOLIS NOYOLA
ACRÓNIMO DE PARÍS PARA SU OLIMPIADA 2024. Por JAVIER SOLIS NOYOLA
 
Tema 17. Biología de los microorganismos 2024
Tema 17. Biología de los microorganismos 2024Tema 17. Biología de los microorganismos 2024
Tema 17. Biología de los microorganismos 2024
 
Caja de herramientas de inteligencia artificial para la academia y la investi...
Caja de herramientas de inteligencia artificial para la academia y la investi...Caja de herramientas de inteligencia artificial para la academia y la investi...
Caja de herramientas de inteligencia artificial para la academia y la investi...
 
PIAR v 015. 2024 Plan Individual de ajustes razonables
PIAR v 015. 2024 Plan Individual de ajustes razonablesPIAR v 015. 2024 Plan Individual de ajustes razonables
PIAR v 015. 2024 Plan Individual de ajustes razonables
 
Proyecto de aprendizaje dia de la madre MINT.pdf
Proyecto de aprendizaje dia de la madre MINT.pdfProyecto de aprendizaje dia de la madre MINT.pdf
Proyecto de aprendizaje dia de la madre MINT.pdf
 
Tema 10. Dinámica y funciones de la Atmosfera 2024
Tema 10. Dinámica y funciones de la Atmosfera 2024Tema 10. Dinámica y funciones de la Atmosfera 2024
Tema 10. Dinámica y funciones de la Atmosfera 2024
 
SESION DE PERSONAL SOCIAL. La convivencia en familia 22-04-24 -.doc
SESION DE PERSONAL SOCIAL.  La convivencia en familia 22-04-24  -.docSESION DE PERSONAL SOCIAL.  La convivencia en familia 22-04-24  -.doc
SESION DE PERSONAL SOCIAL. La convivencia en familia 22-04-24 -.doc
 
Qué es la Inteligencia artificial generativa
Qué es la Inteligencia artificial generativaQué es la Inteligencia artificial generativa
Qué es la Inteligencia artificial generativa
 
Supuestos_prácticos_funciones.docx
Supuestos_prácticos_funciones.docxSupuestos_prácticos_funciones.docx
Supuestos_prácticos_funciones.docx
 
Infografía EE con pie del 2023 (3)-1.pdf
Infografía EE con pie del 2023 (3)-1.pdfInfografía EE con pie del 2023 (3)-1.pdf
Infografía EE con pie del 2023 (3)-1.pdf
 
2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx
2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx
2 REGLAMENTO RM 0912-2024 DE MODALIDADES DE GRADUACIÓN_.pptx
 
LA LITERATURA DEL BARROCO 2023-2024pptx.pptx
LA LITERATURA DEL BARROCO 2023-2024pptx.pptxLA LITERATURA DEL BARROCO 2023-2024pptx.pptx
LA LITERATURA DEL BARROCO 2023-2024pptx.pptx
 
Medición del Movimiento Online 2024.pptx
Medición del Movimiento Online 2024.pptxMedición del Movimiento Online 2024.pptx
Medición del Movimiento Online 2024.pptx
 
Prueba de evaluación Geografía e Historia Comunidad de Madrid 2º de la ESO
Prueba de evaluación Geografía e Historia Comunidad de Madrid 2º de la ESOPrueba de evaluación Geografía e Historia Comunidad de Madrid 2º de la ESO
Prueba de evaluación Geografía e Historia Comunidad de Madrid 2º de la ESO
 
5.- Doerr-Mide-lo-que-importa-DESARROLLO PERSONAL
5.- Doerr-Mide-lo-que-importa-DESARROLLO PERSONAL5.- Doerr-Mide-lo-que-importa-DESARROLLO PERSONAL
5.- Doerr-Mide-lo-que-importa-DESARROLLO PERSONAL
 
Tema 8.- PROTECCION DE LOS SISTEMAS DE INFORMACIÓN.pdf
Tema 8.- PROTECCION DE LOS SISTEMAS DE INFORMACIÓN.pdfTema 8.- PROTECCION DE LOS SISTEMAS DE INFORMACIÓN.pdf
Tema 8.- PROTECCION DE LOS SISTEMAS DE INFORMACIÓN.pdf
 
Procedimientos para la planificación en los Centros Educativos tipo V ( multi...
Procedimientos para la planificación en los Centros Educativos tipo V ( multi...Procedimientos para la planificación en los Centros Educativos tipo V ( multi...
Procedimientos para la planificación en los Centros Educativos tipo V ( multi...
 
ACTIVIDAD DIA DE LA MADRE FICHA DE TRABAJO
ACTIVIDAD DIA DE LA MADRE FICHA DE TRABAJOACTIVIDAD DIA DE LA MADRE FICHA DE TRABAJO
ACTIVIDAD DIA DE LA MADRE FICHA DE TRABAJO
 
Estrategia de prompts, primeras ideas para su construcción
Estrategia de prompts, primeras ideas para su construcciónEstrategia de prompts, primeras ideas para su construcción
Estrategia de prompts, primeras ideas para su construcción
 

Manual PHP 7

  • 1. Lenguajes de Script. En el servidor web: PHP. Universidad Nacional de Ingeniería FACULTAD DE CIENCIAS Y SISTEMAS Departamento de Informática
  • 3. Lenguaje PHP 7. Introducción: En esta sección aprenderás a desarrollar sistemas web (una aplicación web enlazada a un repositorio de datos) utilizando el Lenguaje PHP siguiendo el paradigma de Programación Orientada a Objetos. Primero necesitas entender los fundamentos de éstos: HTTP y sistemas cliente- servidor. El protocolo HTTP: El estándar RFC 2068 deja establecido al Hyper Text Transfer Protocol (Protocolo de Transferencia de Hipertexto) como un conjunto de normas para el intercambio de datos entre computadoras que permite buscar y recuperar recursos. Gracias a este protocolo en la Capa de Aplicación, el usuario al interactuar con el navegador web puede realizar sus actividades. HTTP se basa en el principio cliente-servidor: las solicitudes son generalmente enviadas al inicio por una entidad denominada agente de usuario (o un proxy a petición de uno) que puede ser un navegador web. Cada petición es dirigida a un servidor que al final la gestionará y responderá. Entre ellos hay varios intermediarios. Desde el punto de vista del cliente el flujo es así: 1. Abrir o reusar una conexión TCP. 2. Realizar la petición HTTP: Método Versión del protocolo
  • 4. 3. Leer la respuesta del servidor: GET / HTTP/1.1 Host: developer.mozilla.org Accept-Language: es HTTP/1.1 200 OK Date: Sat, 09 Oct 2010 14:28:02 GMT Server: Apache Last-Modified: Tue, 01 Dec 2009 20:18:22 GMT ETag: "51142bc1-7449-479b075b2891b" Accept-Ranges: bytes Content-Length: 29769 Content-Type: text/html <!DOCTYPE html... (here comes the 29769 bytes of the requested web page) Mensaje de estadoVersión del protocolo Código de estado Encabezado s Respuesta Figura 1. Ejemplo de petición HTTP. Enviada por el navegador Figura 2. Ejemplo de respuesta HTTP de un servidor
  • 5. El lenguaje PHP: PHP (acrónimo recursivo que significa PHP Hypertext Preprocesor), fue creado en 1995 por Rasmus Lerdorf. Según Cobo (2005), es un lenguaje open source interpretado del lado del servidor para ser robusto, versátil y modular cuyos programas ejecutados en el servidor son embebidos en el código HTML al enviar al cliente. Es multiplataforma y compatible con diferentes bases de datos.Los ficheros, para que puedan ser reconocidos por el intérprete, deberán de tener la extensión php. El código en este lenguaje debe estar encerrado entre las etiquetas <?php y ?>. Sintaxis de PHP: El código PHP debe estar delimitado por las etiquetas: <?php y ?> o bien <? ?> en caso de que el valor de la directiva short_open_tag sea “1” en el archivo php.ini, aunque la última etiqueta ?> es opcional. Las instrucciones deberán terminar con “;”. Los comentarios se deberán escribir posterior a // para el caso de los comentarios de una sola línea. En el caso de los comentarios multilínea, estos deberán escribirse entre las etiquetas /**/. <?php //Ejemplo de código php function haceAlgo(){ echo “Hello World!”; } haceAlgo(); ?> Código 1. Ejemplo de fichero PHP que imprime el mensaje en pantalla “Hola Mundo"
  • 6. Tipos de datos de PHP: En PHP el tipo de una variable es decido en tiempo de ejecución. PHP 7 admite 10 tipos primitivos, la mayoría similares a otros lenguajes de programación: Tiposdedatosprimitivos Escalares boolean integer float string Compuestos array: Estructura de datos en forma de mapa ordenado object Para las instancias de clase callable iterable Especiales resource Contiene referencia a recurso externo mantenido por funciones especiales null Figura 3. Tipos de datos en PHP
  • 7. Declaración, asignación de variables y operaciones: En PHP toda variable debe empezar con $ seguido del nombre de la variable, que puede empezar con _ (guión bajo) o letras. El resto de caracteres también puede ser alfanumérico. El operador de asignación es =. Precedencia de operadores: La siguiente tabla la detalla: Asociatividad Operadores Información adicional no asociativo clone new clone and new izquierda [ array() derecha ** aritmética derecha ++ - - ~ (int) (float) (string) (array) (object) (bool) @ tipos e incremento/decremento no asociativo instanceof tipos derecha ! lógico izquierda * / % aritmética izquierda + - . aritmética y string izquierda << >> bit a bit no asociativo < <= > >= comparación no asociativo == != === !== <> <=> comparación izquierda & bit a bit y referencias izquierda ^ bit a bit izquierda | bit a bit izquierda && lógico izquierda || lógico derecha ?? comparación izquierda ? : ternario derecha = += - = *= **= /= .= %= &= |= ^= <<= >>= asignación izquierda and lógico izquierda xor lógico izquierda or lógico Tabla 1. Precedencia de operadores en PHP. Fuente: PHP Group (2018) Manual de PHP: Precedencia de operadores recuperado de: https://secure.php.net/manual/es/language.operators.precedence.php el 18 de septiembre de 2018. En el siguiente código tomado de López (2016) se puede observar algunos de estos con mayor claridad:
  • 8. En el primer caso tenemos una operación de asignación, una aritmética, y una lógica. El operador con la mayor preferencia es la suma, así que primero se realiza 1+3 igual a 4, luego se realiza la comparación lógica, donde la expresión 4>5 resulta falsa, luego se evalúa la expresión false||$c (donde $c es true) lo que resulta en verdadero, valor que se asigna a la variable $e. En el segundo caso, el primer operador que vemos en la mesa es la negación, entonces la resolvemos: !$d es !falso, entonces es cierto. La expresión ahora es, $e == verdadero && verdadero. Primero tenemos que resolver la comparación $e == verdadero. Sabiendo que $e es verdadero, la comparación resulta verdadera. La operación final es el and lógico y resulta verdadero. En el último caso, debido a los paréntesis se realiza la sumatoria de $a y $b, esto a su vez se multiplica por 2, luego se realiza la multiplicación entre 3 y 4. Por último se realiza la suma. Por último, la función integrada var_dump muestra el tipo y valor de las variables. La salida en el navegador para este ejemplo es: <?php $a = 1; $b = 3; $c = true; $d = false; $e = $a + $b > 5 || $c; // true var_dump($e); $f = $e == true && !$d; // true var_dump($f); $g = ($a + $b) * 2 + 3 * 4; // 20 var_dump($g); ?> bool(true) bool(true) int(20) Código 2. Ejemplo de precedencia de operadores
  • 9. Algunos ejemplos de archivos en PHP: Como se mencionó anteriormente, para que el código fuente sea reconocido por el intérprete, los ficheros deben tener la extensión php, sin embargo esto no implica mantener el resto de código web. El intérprete de PHP ignora lo que no se encuentra en este lenguaje y lo devuelve al navegador en bruto. Por tanto si es código CSS, HTML o JS el navegador será el que lo procese. También es posible devolverlos utilizando los constructores echo o print. Las imágenes siguientes demuestran lo mencionado: Código 3. Ejemplo de archivo que combina PHP y HTML. (Fuente: elaboración propia para la empresa Maltez Ingenieros & Cía. Ltda.)
  • 10. <?php $s=$_SERVER['SERVER_NAME']; $p=$_SERVER['SERVER_PORT']; $url=$_SERVER['REQUEST_URI']; $referer=$_SERVER['HTTP_REFERER']; $dir= explode('/',$referer); $rutabase=$dir[0].'/'.$dir[1].'/'.$dir[2].'/'.$dir[3]; echo ' <div class="col-12"> <p>Contáctenos</p> </div> <div class="col-lg-1 datoContacto"> <a class="nav-link" href="https://api.whatsapp.com/send?phone=50588623846"> <img class="iconoSocial" src="'.$rutabase.'/img/icons/whatsapp.png" alt="Ícono WhatsApp"> </a> <a class="nav-link" href="https://www.facebook.com/krmaltez"> <img class="iconoSocial" src="'.$rutabase.'/img/icons/fb.png" alt="Ícono WhatsApp"> </a> </div> <div class="col-lg-2 datoContacto"> <img src="'.$rutabase.'/img/icons/telefono.png"> <a>(+505) 2252-4889</a> </div> <div class="col-lg-4 datoContacto"> <img src="'.$rutabase.'/img/icons/correo.png"> <a class="nav-link" href="mailto:maltezingrmc@hotmail.com">maltezingrmc@hotmail.com</a> </div> <div class="col-lg-5 datoContacto"> <img src="'.$rutabase.'/img/icons/direccion.png"> <a>Bo. Riguero, del Parque Bill Stewart 1 C al N y 1/2 C al E. Managua, Nicaragua.</a> </div> <div class="col-12"> <p>Sitio desarrollado por Gabriel Chavez Toruño, ©Maltez Ingenieros</p> </div> ’; Código 4. PHP también puede escribir código HTML (Fuente: elaborado por el autor para la empresa Maltez Ingenieros & Cia. Ltda.). Figura 4. Resultado del código anterior.
  • 11. Estructuras de control en PHP: Para el control de flujo en la ejecución de código, se dispone de varias estructuras: Ejemplo de bucle while <?php /* Factorial de un número */ $f=1; $n=5; while ($n>=1) { $f=$f*($n--); } echo $f; ?> Ejemplo de If, else y else if <?php if ($a > $b) { echo "a es mayor que b"; } else if ($a == $b) { echo "a es igual que b"; } else { echo "a es menor que b"; } ?> Código 5. Ejemplo de if, else y else if Código 6. Cálculo del factorial de un número. Ejemplo de bucle do-while <?php $f=1; $n=5; do { $f=$f*($n--); } while ($n>1); echo $f; ?> Código 7. Cálculo del factorial utilizando un bucle do-while. Ejemplo de bucle for <?php $marcas=['Vokswagen', 'Ford', 'Suzuki', 'GM ', 'Chevrolet']; for($i=0; $i<count($marcas); $i++){ echo $marcas[$i].'n'; } ?> Código 8. El bucle recorre el arreglo e imprime cada elemento mientras el índice sea menor a la longitud de aquel (obtenida mediante la función count())
  • 12. Código 9 y Figura 5 El bucle foreach permite iterar de forma fácil sobre arreglos y objetos realizando un recorrido completo sobre el mismo. En este ejemplo la salida es: Ejemplo de bucle foreach <!doctype html> <html lang="es"> <head> <meta charset="utf-8"/> <title>Ejemplo PHP</title> </head> <body> <h1> Ejemplo de bucle foreach </h1> <h3> Resultado: </h3> <div id="resPHP"> <?php $a = array( "primero" => 'Carlos', "segundo" => 'Enrique', "tercero" => 'Luisa', "quinto" => 'Agnes' ); foreach ($a as $k => $v) { echo "$a[$k] => $v<br/>"; } ?> </div> </body> </html>
  • 13. Ejemplo de switch <!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h3>Ingresa un número</h3> <form action="index.php" method="POST"> <input type="number" name="nb" placeholder="x"> <button type="submit">Enviar</button> </form> <?php // put your code here $x=filter_input(INPUT_POST, 'nb', FILTER_SANITIZE_NUMBER_FLOAT); $numero=($x!==false && $x!=='')?$x:'s'; switch ($numero) { case ($numero===0): echo "Este valor no es admitido"; break; case ($numero<0): echo "Este número es negativo"; break; case ($numero>0): echo "Este número es positivo"; break; default: break; } ?> </body> </html> Código 10. Ejemplo de estructura switch. En este código existe comunicación sincrónica, por lo que el resultado se mostrará después que la página recargue. Figura 6. Resultado del código anterior: la foto izq. muestra el mensaje cuando se ingresa 0; la del centro, cuando se ingresa un número positivo y la de la derecha, cuando es negativo
  • 14. Break y continue en PHP Las instrucciones Break y continue funcionan con las estructuras de control for, foreach, while, do-while o switch. Break finaliza la ejecución de toda la estructura mientras que continue, dentro los ciclos, permite saltar la ronda actual. Continue y Break pueden recibir como parámetro la cantidad de niveles de bucles encerrados a saltar o finalizar, respectivamente. while ( $x ) { continue; break; } El siguiente código es adaptado de la documentación de PHP en español. <?php for( $i = 0; $i < 3; ++ $i ) { echo ' [', $i, ']:<br>'; switch( $i ) { case 0: echo 'uno<br/>'; break; case 1: echo 'dos<br/>' ; XXXX; case 2: echo 'tres<br/>' ; break; } echo ' <' , $i, '><br/><br/> '; } ?> Salta aquí Vuelve aquí Figura 7. Si se reemplaza la expresión XXXX por continue o break se obtiene diferentes resultados: Izq. muestra el resultado si se reemplaza por continue o break (con parámetro 1); centro, utilizando continue 2 y der., utilizando break 2 Código 11. Ejemplo de break y continue
  • 15. Sintaxis alternativa de estructuras de control: Para if, else, elseif, while, for, foreach y switch existe una forma opcional en la cual se cambia la llave de apertura por dos puntos (:) y la llave de cierre por endif, endwhile, endfor, endforeach o endswitch, respectivamente seguido de punto y coma (;). La estructura do-while no tiene una forma sintáctica opcional. En el caso de switch, no debe haber salidas como espacios en blanco antes del primer case. En el ejemplo anterior el texto html se imprimirá solo si la variable $a es igual a 5. A continuación un ejemplo de condicionales: <?php if ($a == 5): ?> A es igual a 5 <?php endif; ?> <?php if ($a == 5): echo "a igual 5"; echo "..."; elseif ($a == 6): echo "a igual 6"; echo "!!!"; else: echo "a no es 5 ni 6"; endif; ?> Código 12. Ejemplo de if con sintaxis alternativa. Fuente: PHP Group (2018) Manual de PHP: Sintaxis alternativa de estructuras de control. Recuperado de: https://secure.php.net/manual/es/control-structures.alternative- syntax.php el 26 de septiembre de 2018. Código 13. Ejemplo de if, else, y else if con sintaxis alternativa. Fuente: PHP Group (2018) Manual de PHP: Sintaxis alternativa de estructuras de control. Recuperado de: https://secure.php.net/manual/es/control- structures.alternative-syntax.php el 26 de septiembre de 2018.
  • 16. Inclusión de ficheros: En un proyecto web no es buena idea mezclar PHP y HTML en un mismo documento; también se recomienda reutilizar todo el código que se pueda. Para ello se dispone de varias alternativas para tratar con ficheros existentes:  Include: esta sentencia busca y evalúa el fichero especificado cada vez que es invocada. Si el archivo no se encuentra, PHP arrojará una advertencia pero permitirá continuar la ejecución de la secuencia de instrucciones.  Require: similara a include, con la diferencia que arrojará un error fatal de nivel E_COMPILE_ERROR si el archivo no lo halla.  Include_once: Similar a include, con la diferencia que solo buscará y evaluará al fichero la primera vez que es invocado. El resto de llamadas será ignorado.  Require_once: funciona de forma similiar a require, excepto que es una sola vez después que es invocado. El resto de llamadas será ignorado. Contenido de “index.php” <?php echo 'Contenido de php'; include './externo.html'; ?> Contenido de “externo.html” <p>Este párrafo se incluyó mediante una invocación al método include de php.< /p> Código 14. Ejemplo de include en PHP Figura 8. Salida del código anterior en un navegador web
  • 17. Funciones en PHP: Una función puede ser definida mediante la sintaxis: Como se observa en la definición anterior, no es necesario declarar el tipo de los argumentos ni del valor devuelto. Para llamar a la función basta con llamarla: haceAlgo(). Cuando una función está definida dentro de una condición, sus definiciones deben ser procesadas antes de ser llamadas. PHP no admite la sobrecarga de funciones; además, sus nombres son insensibles a mayúsculas, a diferencia de las variables. Una función puede tener argumentos con valores predeterminados. Estos argumentos no necesitan ser pasados al llamar a la función pero deben ser escritos de último al definir la función. <?php function haceAlgo($arg_1, $arg_2, /* ..., */ $arg_m) { echo "Función de ejemplo.n"; return $valor_devuelto; } ?> Código 15. Sintaxis para definir una función. <?php function hacer_café($tipos = array("capuchino"), $fabricanteCafé = NULL) { $aparato = is_null($fabricanteCafé) ? "las manos" : $fabricanteCafé; return "Hacer una taza de ".join(", ", $tipos)." con $aparato.n"; } echo hacer_café(); echo hacer_café(array("capuchino", "lavazza"), "una tetera"); ?> Código 16. Ejemplo de argumentos con valores predeterminados. Fuente: PHP Group (2018) Manual de PHP: Argumentos de PHP. Recuperado de: https://secure.php.net/manual/es/functions.arguments.php el 26 de septiembre de 2018.
  • 18. Para pasar el parámetro por referencia, se debe de anteponer & antes del argumento en la declaración de la función. PHP tiene soporte para una cantidad variable de argumentos en las funciones definidas por el usuario. Esto se implementa mediante el token (…). Algunas funciones y variables incluidas PHP incluye algunas variables predefinidas muy útiles, denominadas superglobales muchas de las cuales veremos en las siguientes páginas. Función Descripción $GLOBALS Hace referencia a las variables disponibles en el ámbito global. $_SERVER Array que contiene información del entorno de ejecución y server $_GET Array asociativo de variables pasados via parámetros URL $_POST Array asociativo de variables pasadas al script mediante POST $_FILES Array asociativo de elementos subidos a través de POST $_COOKIE Array asociativo de variables pasadas a través de Cookies HTTP $_SESSION Array asociativo que contiene variables de sesión disponibles para el script actual $_REQUEST Array asociativo que por defecto contiene el contenido de $_GET, $_POST y $_COOKIE $_ENV Array asociativo de variables pasadas con información del entorno Tabla 2. Variables globales en PHP. Fuente: PHP Group (2018) Manual de PHP: Superglobales. Recuperado de: https://secure.php.net/manual/es/language.variables.superglobals.php el 26 de septiembre de 2018. function modificar(&$a) { $a *= 3; } Código 18. Ejemplo de paso por referencia de una variable como argumento de una función. <?php function sum(...$números) { $acc = 0; foreach ($números as $n) { $acc += $n; } return $acc; } echo sum(1, 2, 3, 4); ?> Código 17. Ejemplo de una lista de argumentos de longitud variable. Fuente: PHP Group (2018) Manual de PHP: Argumentos de PHP. Recuperado de: https://secure.php.net/manual/es/functions.arguments.php el 26 de septiembre de 2018.
  • 19. También su núcleo integra varias funciones para el manejo de cadenas y arreglos entre las que están: Función Descripción str_replace (search, replace, string) Permite reemplazar una expresión a buscar, con otra dentro de un string. strtoupper (string) Convierte un string a mayúsculas. strtolower (string) Convierte un string a minúsculas. trim (string, character_mask) Permite eliminar los caracteres en blanco u otros especificados mediante una máscara que se encuentren al inicio o al final explode (delimiter, string) Retorna un array de substrings al dividir la cadena con el delimitador implode (string = '', array) Contrario a explode, une un array de strings mediante un delimitador echo | print_r | var_dump Las 3 imprimen una cadena, echo puede imprmir más de un argumento, print_r devuelve la variable en forma entendible para humanos y var dump devuelve también el tipo de dato Is_string(variable) Devuelve true si el argumento es una cadena Tabla 3. Algunas funciones integradas de PHP para el manejo de cadenas Funcion Descripción array([mixed $...]) Crea un array array_push(array, arg1,…,argm) Inserta uno o más elementos al final de un array array_pop (array) Extrae el último elemento del final del array, acortando el arreglo array_push(array, arg1,…,argm) Añade al final del array uno o más elementos array_shift(array) Extrae el elemento del inicio del array, acortando el arreglo. array_unshift(array, arg1,…,argm) Añade al inicio de un array uno a más elementos count (array) Cuenta los elementos de un array o un objeto contable array_search (mixed aguja, array pajar, boolean strict) Busca un valor en un array devuelve la primera clave en caso de éxito; de lo contrario, devuelve false Tabla 4. Algunas funciones integradas de PHP para el manejo de arreglos El resto de las variables y funciones predefinidas se encuentran en el Anexo I. Información más detallada se encuentra en el sitio oficial de PHP.
  • 20. Ejemplos sencillos de PHP en aplicaciones web Estos son algunos ejemplos para ver cómo se usa lo expresado con anterioridad en este documento de forma práctica. 1. Obteniendo datos a partir del usuario Cuando un usuario navega en la web se puede observar en la URL los parámetros que el usuario ha ingresado previamente. Aquí se simulará eso con el siguiente código: Para cada petición, PHP almacena los parámetros enviados como parte de la URI en un arreglo llamado $_GET. El arreglo está estructurado de forma que cada una de las claves es el nombre del parámetro, emparejado con su valor correspondiente. <?php $busqueda= isset($_GET['titulo']) || isset($_GET['cantante']); ?> <html lang="es"> <head> <meta charset="UTF-8"> <title>Parametros get en PHP</title> </head> <body> <h1>Resultados de la búsqueda:</h1> <br> <p>Usted buscó <?php echo (int)$busqueda;?> título(s)</p> <ul> <li> <b>Título: </b><?php echo $_GET['titulo'];?> </li> <li> <b>Cantante: </b><?php echo $_GET['cantante'];?> </li> </ul> </body> </html> Código 19. Ejemplo de de lectura de parámetros mediante GET en PHP. Adaptado de López, Antonio (2016). Learning PHP 7. Packt Publishing. 1ra Ed.
  • 21. Si se envía los parámetros necesarios mediante la URL se reflejará una salida similar a la imagen anterior, de lo contrario y según la configuración del servidor, mostrará una advertencia al intentar obtener los valores de esos elementos. 2. Formulario HTML para el envío de correos con PHP En HTML, la etiqueta form tiene los atributos action, la url donde los datos serán enviados o procesados, y method, para indicar el verbo HTTP a utilizar (GET o POST). A continuación, un ejemplo real: Figura 9. La página imprime la información enviada a la URL
  • 22. <!DOCTYPE html> <html lang="es"> <head> <meta charset="utf-8" /> <meta name="description" content="Formulario de contacto Water Projects S.A, Nicaragua, servicios y proyectos hÃ-dricos"/> <title>Contactenos-Mi Empresa</title> <meta name="viewport" content="width=device-width initial-scale=1.0" /> <link href="css/bootstrap.css" type="text/css" rel="stylesheet" /> <link href="css/home.css" type="text/css" rel="stylesheet" /> <link href="css/comun.css" type="text/css" rel="stylesheet" /> <link href="css/contacto.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="js/jquery-3.1.1.min.js"></script> <script type="text/javascript" src="js/bootstrap.js"></script> <link href="css/leaflet.css" rel="stylesheet" type="text/css"/> <script src="js/leaflet.js" type="text/javascript"></script> </head> <body> <!--Barra de menú--> <?php include './includes/menu.php' ?> <div class="aplicarMargen container-fluid"> <div class="row"> <div class="headerPageContainer"> <h1> Contáctenos </h1> <hr /> </div> <h4 class="Descripcion">Si usted desea conocer más de nuestros servicios y productos no dude en escribirnos.</h4> </div> <div class="row"> <form method="post" enctype="multipart/form-data" action="enviarCorreo.php" role="form" class="col-md-8"> <div class="form-group"> <label for="inputNombre">Nombres:</label> <input id="inputNombre" class="form-control" type="text" name="Nombre" placeholder="Escriba su(s) nombre(s)" /> </div> <div class="form-group"> <label for="inputApellido">Apellidos:</label> <input id="inputApellido" class="form-control" type="text" name="Apellido" placeholder="Escriba su(s) apellido(s)" /> </div> <div class="form-group"> <label for="inputCorreo">Correo electrónico:</label> <input id="inputCorreo" class="form-control" type="email" name="Correo" placeholder="Ingrese un e-mail válido" /> </div> Código 20. Página web de contacto (parte 1). Fuente: Elaboración propia
  • 23. <div class="form-group"> <label for="inputAsunto">Asunto:</label> <input id="inputAsunto" class="form-control" type="text" name="Asunto" placeholder="Asunto del correo" /> </div> <textarea class="form-control" name="Mensaje" autocomplete="off" placeholder="Escriba aquí su mensaje" rows="10"></textarea> <div class="btnContainer"> <button type="submit" class="btn btn-default btnEnviar">Enviar</button> </div> </form> <aside id="mapa" class="col-md-4 map pequeno">Hola</aside> </div> </div> <script> var lat, long; lat=12.14132; long=-86.27753; var mymap = L.map('mapa').setView([lat, long], 18); L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' + '<a href="http://creativecommons.org/licenses/by- sa/2.0/">CC-BY-SA</a>, ' + 'Imagery © <a href="http://mapbox.com">Mapbox</a>', id: 'mapbox.streets' }).addTo(mymap); L.control.scale().addTo(mymap); var myIcon = L.icon({ iconUrl: '/img/iconos/marker.png', shadowUrl: '', iconSize: [38, 95], // size of the icon shadowSize: [50, 64], // size of the shadow iconAnchor: [22, 94], // point of the icon which will correspond to marker's location shadowAnchor: [4, 62], // the same for the shadow popupAnchor: [-3, -76] // point from which the popup should open relative to the iconAnchor }); L.marker([lat, long], {icon: myIcon}).addTo(mymap); </script> </body> </html> Código 21. Página web de contacto (parte 2). Fuente: Elaboración propia
  • 24. Los datos recopilados son procesados por enviarCorreo.php, <?php if(isset($_POST['Correo']) && !empty($_POST['Correo'])){ $para="contacto@empresa.net"; $asunto=null; $nombre=null; $apellido=null; $emisor=null; $mensaje=null; if(isset($_POST['Asunto']) && !empty($_POST['Asunto'])){ $asunto=$_POST['Asunto']; } if(isset($_POST['Nombre']) && !empty($_POST['Nombre'])){ $Nombre=$_POST['Nombre']; } if(isset($_POST['Apellido']) && !empty($_POST['Apellido'])){ $apellido=$_POST['Apellido']; } if(isset($_POST['Correo']) && !empty($_POST['Correo'])){ $emisor=$_POST['Correo']; } if(isset($_POST['Mensaje']) && !empty($_POST['Mensaje'])){ $mensaje=$_POST['Mensaje']; } if (is_string(validarFormatoCorreo($emisor))) { $cabecera='From: '.$nombre.''.$apellido.'<'.$emisor. '>'."rn". 'Reply-To: '.$emisor."rn". 'X-Mailer: PHP/'.phpversion(); $bool=mail($para, $asunto, $mensaje, $cabecera); if($bool){ $txt='¡Correo enviado satisfactoriamente!'; imprimirPagMensaje($txt); } else{ $txt='Error al enviar correo'; imprimirMensaje($txt); } } else{ $txt='Error al enviar correo'; imprimirMensaje($txt); } } function validarFormatoCorreo($correo_e){ $correo_e = filter_var($correo_e, FILTER_SANITIZE_EMAIL); return (filter_var($correo_e, FILTER_VALIDATE_EMAIL)) ? $correo_e : 0; } function imprimirMensaje($mensaje){ echo $mensaje; /*Aquí también se puede escribir código HTML*/ } ?> Código 22. EnviarCorreo.php. Fuente: Elaboración propia
  • 25. En el código anterior se definió el método de envío de los datos del formulario mediante el verbo POST; debido a esta razón, los parámetros no se muestran en la URL del navegador, aunque son visibles si se recurre al inspector de red. El correo se enviará si existe un valor para la clave “Correo” de la variable superglobal $_POST, la cual guarda las variables enviadas mediante este verbo; es decir, el email del emisor. Si existe, se verifica que también hayan sido enviados el nombre y apellido del remitente, el asunto y contenido del correo; de lo contrario se imprime un mensaje de error. Si el formato del email del emisor es correcto, se procede a declarar y asignar los valores adicionales para la cabecera como from, Cc, Bcc y el servidor que envía el correo, los cuales se deben de separarse con retorno de carro y salto de línea (“rn”). Una vez hecho esto, se procede a enviar el correo con la función mail() pasándole como argumentos el destinatario, asunto, contenido del mensaje y parámetros adicionales de la cabecera. Si no ocurre ningún error se indica al usuario; en caso de error, también. Las siguientes imágenes muestran las correspondientes pantallas: Figura 10. Página de contacto. Fuente: Elaboración propia
  • 26. Figura 11. Mensaje que se muestra al usuario cuando el correo se envió satisfactoriamente. Fuente: Elaboración propia
  • 27. Programación Orientada a Objetos en PHP: PHP es un lenguaje multiparadigma. Si bien se puede programar de forma estructurada o funcional, una aplicación compleja requiere de otro arquetipo para su ciclo de vida. La programación Orientada a Objetos (POO) surge como un modelo versátil que permite acercar la codificación al entendimiento de la realidad. PHP lo soporta de forma completa desde su versión 5. En POO, casi todo son objetos y todos los objetos interactúan entre sí. Un objeto tiene unas características, que son los atributos, y unas acciones, que son los métodos. Por ejemplo, el objeto Animal tiene como atributos el color y el peso, y tiene como métodos moverse y comer. Para construir estos objetos, debe utilizar una clase. Cuando se trabaja en php orientado a objeto hay que tener en cuenta que se va a trabajar en la creación de un objeto o mejor conocido en php como clases, donde le vamos a dar a este propiedades y métodos que describan al objeto y las acciones que realiza este. Al programar orientado a objeto hay que tener en cuenta que se tiene que pensar todo de forma abstracta hay que abstraer todo lo posible de este objeto para lograr crear un buen objeto. 1. Conceptos básicos: La programación Orientada a Objetos es un modelo de programación en el cual el comportamiento del programa es llevado a cabo por objetos, entidades que representan seres o conceptos en la vida real del problema a resolver. La POO es uno de los paradigmas más utilizados actualmente. Se sostiene en los siguientes conceptos:  Objeto: es una entidad que representa un elemento o concepto de la vida real y posee propiedades que lo diferencian del resto (atributos) y
  • 28. comportamiento (funcionalidad o métodos que operan sobre dichas propiedades).  Clase: es la descripción de un conjunto de objetos (una plantilla para objetos). Expresa las propiedades y comportamiento de un tipo de objetos concreto. La instanciación es la lectura de estas definiciones y la creación de un objeto a partir de ella.  Abstracción: se utiliza al momento de definir una clase, para que esta tenga los métodos y atributos relevantes. Existen diferentes grados de abstracción para determinar qué se hace y no cómo se hace. Estos niveles se ponen de al abstraer la escena de un conjunto de elementos del mundo real que aparecen una y otra vez con ligeras variantes en sistemas diferentes.  Encapsulamiento: es reunir todos los elementos que pueden considerarse pertenecientes a una misma entidad al mismo nivel de abstracción. Define los niveles de acceso para los elementos de esa clase: público, protegido y privado.  Ocultación: cada objeto expone una interfaz al exterior para que poder prestar sus servicios. Mientras la clase actúa como una caja negra y se puede modificar, la interfaz no cambia.  Herencia: modela el hecho de que los objetos tienden a organizarse en jerarquías. La clase base o padre es aquella de la hereda un objeto.  Polimorfismo: permite a una operación (función) tener el mismo nombre en clases diferentes y que actúe de modo diferente en cada una de ellas, por ejemplo en el caso de herencia. En este acápite, empezaremos con los códigos básicos para desarrollar con PHP orientado a objetos y desarrollaremos un ejemplo de aplicación web de agenda conectado a MySql en donde se abordarán los conceptos anteriores. 2. Definiciones de clases: Una clase se define mediante la palabra reservada class seguida del nombre y llaves ({}) que encierran las definiciones de los atributos y métodos. Se utiliza la palabra reservada class seguida del nombre de la clase y se abre una llave, de
  • 29. forma que todo lo que está dentro de estas llaves pertenece a todo este objeto, dentro de estas llaves que abren y cierran van todo lo que es propiedades y métodos del objeto. Para acceder a alguna de las propiedades no estáticas de la clase, se utiliza la seudovariable $this seguida del operador -> y el nombre de la variable. Es mejor mantener un nivel de acceso protected para todos los atributos de la clase. Para constantes, se usa self seguido de :: (doble dos puntos). Para crear un objeto a partir de una clase; es decir, instanciarla, se utiliza la palabra clave new seguida del nombre de la clase y (). Es correcto crear un método constructor para las clases y facilitar la instanciación de las mismas. Para ello se declara el método mágico __construct() como cualquier otro método. Si los atributos de la clase tienen un nivel de acceso protegido (acceso sólo desde la misma clase), que es lo más recomendado, entonces se deben crear métodos para leer y modificar dichos valores: getters y setters. Esta es una de las formas en que se cumple el principio de ocultación. Una clase sirve para fabricar objetos partiendo de un modelo. Estos objetos tienen sus propios atributos y ciertos métodos. Por ejemplo, la clase Animal tiene los atributos color y peso y los métodos comer y moverse. <?php class NombreClase { } ?>
  • 30. Cuando se crean ejemplares de animales en la clase Animal, se crea una instancia de esta clase. Crear una instancia de una clase significa que se crea un objeto de un tipo determinado (Animal) con ciertos atributos (color, peso). Se recomienda crear una clase por cada archivo PHP que tenga el mismo nombre que la clase. a. La encapsulación. Todos los atributos en POO deben estar ocultos de otros elementos que utilizan sus clases. Si trabaja en equipo y crea la clase Animal, los otros programadores no van a poder cambiar directamente los atributos de su clase. De esta forma, los atributos color y peso se ocultan en otras clases; se declaran privadas. La clase Animal tiene métodos para leer o escribir en estos atributos. Este es el principio de encapsulación, que permite proteger el código cuando trabaja en equipo. La clase Animal, que tiene como propiedades el color y el peso, dispone de un método para modificar su color, un método para leer el color, un método para modificar su peso, un método para leer su peso, así como otros métodos tales como comer o moverse. b. Propiedades de una clase. <?php class Animal /* palabra clave class seguida del nombre de la clase.*/ { // Declaración de atributos y métodos. } ?>
  • 31. Las propiedades de las clases son los atributos del objeto como por ejemplo: el tamaño de una persona, el peso de una mesa. En php hay 3 niveles de acceso tanto para las propiedades como para los métodos los cuales son:  Public: Cuando le damos este nivel de acceso a un atributo, este puede ser accedido desde cualquier parte, así sea dentro de su misma clase como desde otra.  Private: Cuando se le da el nivel de acceso private estamos quitándole la libertad de acceso a las demás que intenten acceder, solo puede ser accedida desde su propia clase donde este fue definido.  Protected: Cuando le damos el nivel de acceso protegido sigue restringiendo la libertad de acceso a los demás que no sean de la clase donde se esta declarando o de sus subclases. Ahora, un ejemplo de cómo se colocaría la propiedad dentro del objeto en php. <?php class NombreClase { public $a; private $b; protected $c; } ?> <?php class Animal // palabra clave seguida del nombre de la clase. { // Declaración de atributos. private $color = "gris"; private $peso = 10; } ?> c. Métodos de una clase.
  • 32. Los tipos de acceso también se utilizan en los métodos y son los mismos. Para comprender que es el método de una clase u objeto, sería un ejemplo el de un objeto persona que tiene el método caminar, o sentarse o comer. Método sería todo lo que es capaz de realizar el objeto, en PHP su sintaxis utiliza la palabra reservada function, ahora veamos un ejemplo: <?php class NombreClase { public $a; private $b; protected $c; public function A($a) { } private function B() { } protected function C() { } } ?> En el ejemplo se crearon 3 métodos dentro del objeto los cuales tienen cada uno de estos los distintos tipos de nivel de acceso, los métodos son más que funciones pero las funciones que realiza dicho objeto. <?php class Animal // palabra clave seguida del nombre de la clase. { // Declaración de atributos y métodos. private $color = "gris"; private $peso = 10; public function comer() { //Método posible para acceder a las propiedades //color y peso }
  • 33. public function moverse() { //Método posible para acceder a las propiedades //color y peso } } ?> d. Añadir un método en la clase Añadir código a la clase significa aplicar la clase. Para acceder a los atributos de su clase, debe utilizar la pseudovariable $this, que representa el objeto sobre el que va a escribir. Para acceder al atributo o al método del objeto, utilice el operador ->. Por ejemplo, para aplicar el método añadir_un_kilo() en la clase Animal: <?php class Animal // palabra clave seguida del nombre de la clase. { // Declaración de atributos y métodos. private $color = "gris"; private $peso = 10; public function comer() { //Método para acceder a las propiedades //color y peso } public function moverse() { //Método para acceder a las propiedades //color y peso } public function añadir_un_kilo() { $this->peso = $this->peso + 1;} } ?>
  • 34. Cuando llama al método añadir_un_kilo(), añadirá 1 al peso actual y por lo tanto el peso final será 11. Las propiedades se declaran con el símbolo $, pero se llaman con $this sin este símbolo.
  • 35. A continuación, un ejemplo: <?php class Foto { private $IdFoto; private $FkProyecto; private $Url_Foto; private $Eliminada; function getIdFoto() { return $this->IdFoto; } function getFkProyecto() { return $this->FkProyecto; } function getUrl_Foto() { return $this->Url_Foto; } function getEliminada() { return $this->Eliminada; } function setIdFoto($IdFoto) { $this->IdFoto = $IdFoto; } function setFkProyecto($FkProyecto) { $this->FkProyecto = $FkProyecto; } function setUrl_Foto($Url_Foto) { $this->Url_Foto = $Url_Foto; } function setEliminada($Eliminada) { $this->Eliminada = $Eliminada; } function __construct($IdFoto, $FkProyecto, $Url_Foto, $Eliminada) { $this->IdFoto = $IdFoto; $this->FkProyecto = $FkProyecto; $this->Url_Foto = $Url_Foto; $this->Eliminada = $Eliminada; } } $f = new Foto(1,2,'/imgs/proyectos/E/p1/01.jpg',false); ?> Código 23. Ejemplo de definición de una clase en PHP y su instanciación. (Fuente: elaboración propia). Definicióndeclase Atributos Getters y setters Constructor Métodos Instanciación
  • 36. e. Utilización de la clase Como primer paso, tenemos que crear un archivo que contenga un código PHP animal.class.php. Para utilizar la clase Animal, debe incluirla en la página donde la quiere llamar. En una página uso.php podría incluirla de la siguiente manera: <?php include(’Animal.class.php’); ?> Ahora que ha cargado la clase, puede instanciarla, es decir, crear un objeto que tenga como modelo la clase Animal: <?php //carga de la clase include(’animal.class.php’); //instanciar la clase Animal $perro = new Animal(); ?> La variable $perro es una instancia de la clase animal, con los atributos propios de color, peso; y como métodos comer, moverse, añadir_un_kilo. f. Actualizar y leer los atributos de la instancia. El principio de encapsulación requiere que todos los atributos sean privados. Por lo tanto, debe crear métodos públicos que permitan leer o escribir en sus atributos desde otra página PHP. Estos métodos son accesos. Generalmente sus nombres van precedidos del prefijo get para leer el valor del atributo y set para escribir el valor del atributo. La clase Animal con los accesos es:
  • 37. <?php class Animal // palabra clave seguida del nombre de la clase. { // Declaración de atributos private $color = "gris"; private $peso = 10; //accesos public function getColor() { return $this->color; //devuelve el color} public function setColor($color) { $this->color = $color; //escrito en el atributo color } public function getPeso() { return $this->peso; //devuelve el peso } public function setPeso($peso) { $this->peso = $peso; //escrito en el atributo peso } //métodos public function comer() { //método para acceder a las propiedades //color y peso } public function moverse() { //método para acceder a las propiedades //color y peso } public function añadir_un_kilo() { $this->peso = $this->peso + 1; } } ?> Los accesos son públicos y por lo tanto permiten leer o escribir en los atributos desde cualquier otra clase o página PHP. Ejemplo con la página uso.php: <?php //carga de la clase include(’animal.class.php’); //instanciar la clase Animal $perro = new Animal(); //leer el peso echo "El peso del perro es:".$perro->getPeso()." kg<br />"; //añadir un kilo al perro $perro->añadir_un_kilo(); //leer el peso echo "El peso del perro es:".$perro->getPeso()." kg<br />";
  • 38. //actualizar el peso del perro $perro->setPeso(15); //leer el peso echo "El peso del perro es:".$perro->getPeso()." kg<br />"; ?> Da como resultado:  El peso del perro es:10 kg  El peso del perro es:11 kg  El peso del perro es:15 kg En efecto, el peso del perro se inicializa a 10. A continuación el método añadir_un_kilo() añade 1; por lo tanto, su peso se convierte en 11. Para terminar, el método setPeso(15) ajusta el peso a 15. Por ejemplo, para crear un gato blanco de 5 kg y un perro negro de 18 kg: <?php //carga de la clase include(’Animal.class.php’); //instanciar la clase Animal $perro = new Animal(); //actualizar el peso del perro $perro->setPeso(18); echo "El peso del perro es:".$perro->getPeso()." kg<br />"; //leer el peso $perro->setColor("negro"); //actualizar el color del perro echo "El color del perro es:".$perro->getColor()."<br />"; //leer el color $gato = new Animal(); //instanciar la clase Animal $gato->setPeso(5); //actualizar el peso del gato echo "El peso del gato es:".$gato->getPeso()." kg<br />"; //leer el peso //actualizar el color del gato $gato->setColor("blanco"); //leer el color echo "El color del gato es:".$gato->getColor()."<br />"; ?> Da como resultado:
  • 39.  El peso del perro es:18 kg  El color del perro es:negro  El peso del gato es:5 kg  El color del gato es:blanco Paso como argumento de tipo objeto. Los métodos son como las funciones, pueden tomar argumentos de tipos diferentes (Integer, String…) e incluso de tipo Objeto. $gato y $perro son objetos de tipo Animal. Pueden pasar como argumento un método, siempre y cuando acepte este tipo de objeto. Para probar este ejemplo, cambie el método comer() de la clase Animal. Se convierte en comer_animal(Animal $animal_comido) y toma como argumento un objeto de tipo Animal. La página animal.class.php se convierte en: <?php class Animal { // Declaración de atributos private $color = "gris"; private $peso = 10; //Accesos public function getColor() { return $this->color; //devuelve el color } public function setColor($color) { $this->color = $color; //escrito en el atributo color } public function getPeso() { return $this->peso; //devuelve el peso } public function setPeso($peso) { $this->peso = $peso; //escrito en el atributo peso }
  • 40. //Métodos public function comer_animal(Animal $animal_comido) { /* El animal que come aumenta su peso tanto como el del animal comido */ $this->peso = $this->peso + $animal_comido->peso; /* El peso del animal comido y su color se restablecen a 0 */ $animal_comido->peso = 0; $animal_comido->color = ""; } public function moverse() { /*método que pueda acceder a las propiedades color y peso */ } public function añadir_un_kilo() { $this->peso = $this->peso + 1; } } ?> Para probar este método, la página uso.php se convierte en: <?php //carga de la clase include(’animal.class.php’); //instanciar la clase Animal $gato = new Animal(); //actualizar el peso del gato $gato->setPeso(8); //leer el peso echo "El peso del gato es:".$gato->getPeso()." kg<br />"; //actualizar el color del gato $gato->setColor("negro"); //leer el color echo "El color del gato es:".$gato->getColor()."<br />"; //instanciar la clase Animal $pez = new Animal(); //actualizar el peso del pez $pez->setPeso(1); //leer el peso echo "El peso del pez es:".$pez->getPeso()." kg<br />"; //actualizar el color del pez $pez->setColor("blanco"); //leer el color echo "El color del pez es:".$pez->getColor()."<br /><br />"; //el gato come al pez $gato->comer_animal($pez);
  • 41. //leer el peso echo "El nuevo peso del gato es:".$gato->getPeso()." kg<br />"; //leer el peso echo "El peso del pez es:".$pez->getPeso()." kg<br />"; //leer el color echo "El color del pez es:".$pez->getColor()."<br /><br />"; ?> Da como resultado:  El peso del gato es:8 kg  El color del gato es:negro  El peso del pez es:1 kg  El color del pez es:blanco  El nuevo peso del gato es:9 kg  El peso del pez es:0 kg  El color del pez es: El objeto $gato llama al método comer_animal ($pez) y pasa como argumento el objeto de tipo Animal $pez. Es decir, el objeto $pez con sus atributos y sus métodos se pasan como argumento. Esto permite pasar como argumento varios valores con un único parámetro. El método comer_animal(Animal $animal_comido) solo acepta un argumento de tipo Animal. Por lo tanto, no puede llamar al método de la siguiente manera: $gato->comer_animal("Rana"); Ni de esta manera: $gato->comer_animal(4); Ya que los tipos "Rana" (String) y 4 (Integer) no son de tipo Animal. g. Constructores. En la programación orientada a objetos (POO u OOP en Inglés) existe un método especial o mágico llamado método constructor. Este método se encarga de
  • 42. inicializar algunas variables --dentro de la clase se llaman propiedades o atributos- - que serán necesarias a la hora de crear una instancia de la clase o lo que es lo mismo, un objeto. Este método mágico usa la palabra reservada __construct El constructor, como su nombre indica, sirve para construir un objeto del tipo clase. Cuando escribe new Animal(), por defecto llama al constructor de la clase Animal. Puede crear sus propios constructores y así pasar como argumento el valor de los atributos que desea asignar a su objeto. El constructor se designa __construct y no tiene return. <?php class NombreClase { public $a; private $b; protected $c; function __construct() { $this->a = 'x'; $this->b = 'w'; $this->c = 'z'; } //...código } ?> De esta forma al momento de ser creado el objeto se van a inicializar las propiedades del objeto como en el ejemplo donde en el objeto a la propiedad a se le asigna x, a la propiedad b se le asigna w y a la propiedad c se le asigna z. La variable $this sirve para referirnos a este objeto. Al igual que hay un constructor existe un destructor que realiza todo el trabajo opuesto, que sería destruir todas las variables creadas.
  • 43. Para añadir un constructor que toma como argumentos el peso y el color, la página animal.class.php se convierte en: <?php class Animal { // Declaración de atributos private $color = "gris"; private $peso = 10; public function __construct ($color, $peso) //Constructor que solicita 2 argumentos. { echo ’Llamar al constructor.<br />’; $this->color = $color; // Inicialización del color. $this->peso = $peso; // Inicialización del peso. } /* Etc. */ } ?> Llamar al constructor en la página uso.php: <?php //carga de la clase include(’animal.class.php’); //instanciar la clase Animal con su constructor $perro = new Animal("beige",7); //leer el peso echo "El peso del perro es:" . $perro->getPeso() . " kg<br />"; //leer el color echo "El color del perro es:" .$perro->getColor() . "<br />"; //actualizar el color del perro $perro->setColor("negro"); //leer el color echo "El color del perro es:" . $perro->getColor() . "<br />"; ?> Da como resultado:  Llamar al constructor.  El peso del perro es:7 kg  El color del perro es:beige  El color del perro es:negro
  • 44. Se muestra en primer lugar "Llamar al constructor", ya que la instrucción echo que se ha escrito en el constructor __construct de su clase Animal se llama cada vez que ejecuta new Animal(). El constructor toma como argumento los valores de sus atributos. Esto evita llamar los métodos setColor() y setPeso(). En PHP no se puede declarar dos constructores en la misma clase. h. Destructor. El destructor destruye el objeto con el fin de liberarlo de la memoria junto con todas las variables creadas en el objeto, algo que no se utiliza mucho ya que PHP ya se encarga de liberar o eliminar todos los recursos utilizados al finalizar de ejecutar un script; sin embargo puede ser utilizado, su palabra reservada es __destruct() También puede destruir un objeto utilizando la función unset(). Esta función toma como argumento el objeto que hay que destruir. <?php //destrucción del objeto unset($perro); ?> Pero se recomienda añadir la función __destruct() en la clase. Por ejemplo, para destruir el objeto $perro: <?php class NombreClase {
  • 45. public $a; private $b; protected $c; function __construct() { $this->a = 'x'; $this->b = 'w'; $this->c = 'z'; } function __destruct() { echo "el atributo asignado " .$this->a . " ha sido eliminado por el destructor."; } //...código } ?> Otro ejemplo sería: <?php class Animal { // Declaración de atributos
  • 46. private $color = "gris"; private $peso = 10; public function __construct ($color, $peso) //Constructor que solicita 2 argumentos. { echo ’Llamar al constructor.<br />’; $this->color = $color; // Inicialización del // color. $this->peso = $peso; // Inicialización del peso. } public function __destruct() { echo ’Llamar al destructor’; } Etc. . . . } ?> Generalmente no es necesario aplicar el destructor en la clase. Ejemplo:
  • 47. Cree dos peces en la página uso.php: pez1, gris, 10 kg pez2, rojo, 7 kg Muestre su peso y a continuación el pez1 se come al pez2. Vuelva a mostrar su peso. <?php //carga de la clase include(’animal.class.php’); //instanciar la clase Animal con su constructor $pez1 = new Animal("gris",10); $pez2 = new Animal("rojo",7); //leer el peso echo "El peso del pez1 es:".$pez1->getPeso()." kg<br />"; //leer el peso echo "El peso del pez2 es:".$pez2->getPeso()." kg<br />"; //el pez1 se come al pez2 $pez1->comer_animal($pez2); //leer el peso echo "El nuevo peso del pez1 es:".$pez1->getPeso()." kg<br />";
  • 48. //leer el nuevo peso echo "El nuevo peso del pez2 es:".$pez2->getPeso()." kg<br />"; ?> Resultado: Llamada al constructor. Llamada al constructor. El peso del pez1 es:10 kg El peso del pez2 es:7 kg El nuevo peso del pez1 es:17 kg El nuevo peso del pez2 es:0 kg Llamada al destructor Llamada al destructor Las constantes de clase Una constante de clase es similar a una constante normal, es decir, un valor asignado a un nombre y que no cambia nunca. Por ejemplo: define(’PI’,3.1415926535); Una constante de clase representa una constante pero que está unida a esta clase.
  • 49. Para crear un animal con el constructor __construct ($color, $peso), escriba: $perro = new Animal("gris",10); Si lee el código, no puede saber inmediatamente que el número 10 representa el peso del animal. Utilice constantes que representen, cada una, un peso distinto: const PESO_LIGERO = 5; const PESO_MEDIO = 10; const PESO_PESADO = 15; Las constantes siempre están en mayúsculas, sin el símbolo $ y precedidas de la palabra clave const. La clase animal.class.php se convierte en: <?php class Animal { // Declaración de atributos
  • 50. private $color = "gris"; private $peso = 10; //constantes de clase const PESO_LIGERO = 5; const PESO_MEDIO = 10; const PESO_PESADO = 15; etc. . . . ?> Para llamar a esta constante desde la página uso.php, la sintaxis es algo peculiar. Debe escribir :: entre la clase y su constante: <?php //carga de la clase include(’Animal.class.php’); //instanciar la clase Animal con su constructor $pez1 = new Animal("gris",Animal::PESO_MEDIO); $pez2 = new Animal("rojo",Animal::PESO_LIGERO); //leer el peso echo "El peso del pez1 es:".$pez1->getPeso()." kg<br />";
  • 51. //leer el peso echo "El peso del pez2 es:".$pez2->getPeso()." kg<br />"; //el pez1 se come al pez2 $pez1->comer_animal($pez2); //leer el peso echo "El nuevo peso del pez1 es:".$pez1->getPeso()." kg<br />"; //leer el nuevo peso echo "El nuevo peso del pez2 es:".$pez2->getPeso()." kg<br />"; ?> Da como resultado: Llamada al constructor. Llamada al constructor. El peso del pez1 es:10 kg El peso del pez2 es:5 kg El nuevo peso del pez1 es:15 kg El nuevo peso del pez2 es:0 kg Animal::PESO_MEDIO siempre es 10, sea cual sea la instancia. Por lo tanto, la constante no está unida a la instancia, sino a la clase. Por este motivo la sintaxis es peculiar.
  • 52. Los atributos y los métodos. a. Método estático. El método estático está unido a la clase, pero no al objeto. En el ejemplo de la clase animal, un método estático está unido al Animal, y no a los perros, los gatos o los peces. Para convertir un método estático, debe añadir la palabra clave static delante de function. Por ejemplo, modifique el método moverse() para convertirlo en estático y muestre "El animal se mueve.". La clase animal.class.php se convierte en: <?php class Animal { // Declaración de atributos private $color = "gris"; private $peso = 10; //constantes de clase const PESO_LIGERO = 5;
  • 53. const PESO_MEDIO = 10; const PESO_PESADO = 15; public function __construct ($color, $peso) // Constructor que solicita 2 argumentos. { echo ’Llamada al constructor.<br />’; $this->color = $color; // Inicialización del color. $this->peso = $peso; // Inicialización del peso. } //accesos public function getColor() { return $this->color; //devuelve el color } public function setColor($color) { $this->color = $color; //escrito en el atributo color } public function getPeso() { return $this->peso; //devuelve el peso } public function setPeso($peso)
  • 54. { $this->peso = $peso; //escrito en el atributo peso } //métodos public function comer_animal(Animal $animal_comido) { //el animal que come aumenta su peso tanto como //el del animal comido $this->peso = $this->peso + $animal_comido->peso; //el peso del animal comido y su color se restablecen a 0 $animal_comido->peso = 0; $animal_comido->color = ""; } public static function moverse() { echo "El animal se mueve."; } public function añadir_un_kilo() { $this->peso = $this->peso + 1; } } ?>
  • 55. Es imposible escribir en un método estático la palabra clave $this, ya que representa el objeto, y el método estático está unido a la clase. Para llamar a este método desde la página uso.php, debe utilizar la misma sintaxis que en las constantes (también unidas a la clase), es decir, introducir :: entre la clase y su método estático: <?php //carga de la clase include(’Animal.class.php’); //llamada al método estático Animal::moverse() ?> Da como resultado: El animal se mueve. Puede llamar al método estático desde un objeto, pero el método estático no puede cambiar nada de este objeto: <?php //carga de la clase
  • 56. include(’animal.class.php’); //instanciar la clase Animal con su constructor $perro1 = new Animal("gris",Animal::PESO_MEDIO); //llamada al método estático $perro1->moverse(); ?> Da como resultado: Llamada al constructor El animal se mueve. b. Atributo estático. Un atributo estático es un atributo propio de la clase y no del objeto, al igual que en los métodos estáticos. Es el mismo principio que en una constante, salvo que el atributo está en una variable y puede cambiar su valor. Un atributo estático se escribe añadiendo la palabra clave static delante de su nombre. Por ejemplo, para añadir un atributo estático que representa a un contador que indica el número de veces que se instancia la clase:
  • 57. La clase animal.class.php se convierte en: <?php class Animal { // Declaración de atributos private $color = "gris"; private $peso = 10; //constantes de clase const PESO_LIGERO = 5; const PESO_MEDIO = 10; const PESO_PESADO = 15; // Declaración de la variable estática $contador private static $contador = 0; etc. . . . ?> Para cambiar el valor de este contador, no puede utilizar $this. De hecho, $this representa un objeto (perro, gato), y no la clase Animal. El contador es de tipo
  • 58. estático y por lo tanto está unido a la clase. Para llamar a este atributo en la clase, debe utilizar la palabra clave self, que representa la clase. Para añadir 1 al contador cada vez que vaya a instanciar la clase Animal, debe modificar el constructor. A continuación debe añadir un método que permita leer este atributo privado con ayuda de un método de tipo public static y getContador(). La clase animal.class.php se convierte en: <?php class Animal { // Declaración de atributos private $color = "gris"; private $peso = 10; //constantes de clase const PESO_LIGERO = 5; const PESO_MEDIO = 10; const PESO_PESADO = 15; // Declaración de la variable estática $contador private static $contador = 0; public function __construct ($color, $peso) // Constructor //que solicita 2 argumentos. {
  • 59. echo ’Llamada al constructor.<br />’; $this->color = $color; // Inicialización del color. $this->peso = $peso; // Inicialización del peso. self::$contador = self::$contador + 1; } // método estático que devuelve el valor del contador public static function getContador() { return self::$contador; } ... ?> La página uso.php: <?php //carga de la clase include(’Animal.class.php’); //instanciar la clase Animal $perro1 = new Animal("rojo",10); //instanciar la clase Animal $perro2 = new Animal("gris",5); //instanciar la clase Animal
  • 60. $perro3 = new Animal("negro",15); //instanciar la clase Animal $perro4 = new Animal("blanco",8); //llamada al método estático echo "Número de animales que se han instanciado: ".Animal:: getContador(); ?> Da como resultado: Llamada al constructor. Llamada al constructor. Llamada al constructor. Llamada al constructor. Número de animales que se han instanciado: 4
  • 61. Herencia en PHP. La herencia es un concepto muy importante en POO. Permite reutilizar el código de una clase sin necesidad de volver a escribirlo. Una clase hija hereda de una clase madre, es decir, accede a todos los atributos y los métodos públicos de la clase madre. Por ejemplo, la clase Mamífero hereda de la clase Animal, y la clase Coche hereda de la clase Vehículo. Si la clase A es una subcategoría de la clase B, entonces puede hacer que la clase A (Mamífero o Coche) herede de la clase B (Animal o Vehículo). Imagine como unas clases Pez y Gato serían ejemplos de herencia de la clase Animal. Para crear la clase Pez que hereda de la clase Animal, debe utilizar la palabra clave extends entre el nombre de la clase hija y el nombre de la clase madre. Cree un archivo pez.class.php y escriba el siguiente código: <?php class Pez extends Animal { } ?>
  • 62. Ahora añada un atributo privado que corresponda a la variable vive_en_el_mar y los accesos get y set. Para terminar, el método público nadar(). <?php class Pez extends Animal { private $vive_en_el_mar; //tipo de pez //accesos public function getType() { if ($this->vive_en_el_mar){ return "vive_en_el_mar"; } else if ($this->vive_en_el_mar===falso){ return "no_vive_en_el_mar"; }else {return "";} } public function setType($vive_en_el_mar) { $this->vive_en_el_mar = $vive_en_el_mar; //escrito en el atributo vive_en_el_mar }
  • 63. //método public function nadar() { echo "Nado"; } } ?> De la misma manera, cree un archivo gato.class.php: <?php class Gato extends Animal { private $raza; //raza del gato //accesos public function getRaza() { return $this->raza; //devuelve la raza } public function setRaza($raza) { $this->raza = $raza; //escrito en el atributo raza }
  • 64. //método public function maullar() { echo "Miau "; } } ?> Las clases Gato y Pez, que heredan de la clase Animal, tienen acceso a los atributos públicos de la clase Animal. La página uso.php: <?php //carga de clases include(’animal.class.php’); include(’pez.class.php’); include(’gato.class.php’); //instanciar la clase Pez que llama al constructor de //la clase Animal $pez = new Pez("gris",8); //instanciar la clase Gato que llama al constructor de la
  • 65. //clase Animal $gato = new Gato("blanco",4); //leer el peso con el acceso de la clase madre echo "El peso del pez es: ".$pez->getPeso()." kg "; //leer el peso con el acceso de la clase madre echo "El peso del gato es: ".$gato->getPeso()." kg "; $pez->setType(true); //leer el tipo con el acceso de su propia clase echo "El tipo de pez es: ".$pez->getType()." "; //llamada al método de la clase Pez $pez->nadar(); $gato->setRaza("Angora"); //leer la raza con el acceso de su propia clase echo "La raza del gato es: ".$gato->getRaza()." "; //llamada al método de la clase gato $gato->maullar(); //llamada al método estático echo "Número de animales que se han instanciado:" .Animal::getContador();
  • 66. ?> Da como resultado: Llamada al constructor. Llamada al constructor. El peso del pez es: 8 kg El peso del gato es: 4 kg El tipo de pez es: vive en el mar Nado La raza del gato es: Angora Miau Número de animales que se han instanciado:2 La clase Pez no tiene acceso a los atributos de la clase Gato y viceversa, ya que una hereda de la otra. Las clases Pez y Gato no tienen directamente acceso a los atributos privados color y peso de la clase Animal. Deben pasar por sus accesos públicos. Protected. Este tipo de visibilidad equivale a private, salvo que las clases hijas puedan ver los atributos protected de la clase madre.
  • 67. Por ejemplo, vamos a añadir el atributo $edad de visibilidad protegida (protected) en la clase madre Animal: <?php class Animal { // Declaración de atributos private $color = "gris"; private $peso = 10; protected $edad = 0; etc. Este atributo no tiene acceso público; por lo tanto, ninguna de las otras clases hijas que heredan de Animal y de la clase Animal pueden modificarlo o leerlo. Añada la función mostrarAtributos() en la clase Pez: public function mostrarAtributos() { echo "Type:".$this->vive en el mar; // correcto ya que es // privada de esta clase echo ""; echo "Edad:".$this->edad; // correcto, ya que el atributo
  • 68. // está protegido en la clase madre. echo ""; echo "Peso:".$this->peso; // error, ya que el atributo es //privado en la clase madre, el acceso está prohibido. Debe pasar //por sus accesos públicos para modificar o leer su valor echo " "; } Para probar este método, la página uso.php se convierte en: <?php //carga de clases include(’animal.class.php’); include(’pez.class.php’); //instanciar la clase Pez que llama al constructor de //la clase Animal $pez = new Pez("gris",8); //leer el peso con el acceso de la clase madre echo "El peso del pez es:".$pez->getPeso()." kg "; //actualizar el tipo de pez $pez->setType(true); //llamada al método mostrando los atributos de la clase Pez
  • 69. //y Animal $pez->VerAtributos(); ?> Da como resultado: La clase Pez no tiene acceso al atributo peso de la clase Animal, ya que es privado. En conclusión, se recomienda poner los atributos en visibilidad protected, ya que la propia clase, las clases hijas y las que heredan tienen acceso a este atributo. Sustitución. Sirve para modificar un método que ya existe en una clase madre, con el objetivo de cambiar el comportamiento. El método existe en dos clases diferentes y según el contexto se ejecuta el de la clase hija o el de la clase madre. Por ejemplo, para sustituir el método comer_animal(Animal $animal_comido) de la clase Animal con el objetivo de inicializar el tipo de pez comido, debe añadir este método en la clase Pez y aplicarlo de otra manera: Añada en la clase pez.class.php: //método sustituido
  • 70. public function comer_animal(Animal $animal_comido) { if (isset($animal_comido->raza)){ $animal_comido->raza=""; } if (isset($animal_comido->vive_en_el_mar)){ $animal_comido->vive_en_el_mar="") } } El problema es que este método inicializa correctamente el atributo vive_ en_ el_mar del pez comido, pero ya no inicializa su peso y su color. No puede cambiar aquí su peso y su color, ya que estos atributos son privados en la clase Animal. La solución está en llamar al método comer_animal(Animal $animal_comido) de la clase Animal en el método comer_animal(Animal $animal_comido) de la clase Pez: //Método sustituido public function comer_animal(Animal $animal_comido) { // al método comer_animal() de la clase padre, // es decir Animal padre::comer_animal($animal_comido); if (isset($animal_comido->raza)){ $animal_comido->raza="";
  • 71. } if (isset($animal_comido->vive_en_el_mar)){ $animal_comido->vive_en_el_mar="") } } padre es una palabra clave que designa la clase madre, es decir, la clase Animal. La página uso.php: <?php //carga de clases include(’animal.class.php’); include(’pez.class.php’); //instanciar la clase Pez que llama al constructor de la //clase Animal $pez = new Pez("gris",8); //actualizar el tipo de pez $pez->setType(true); //instanciar la clase Pez que llama al constructor de la //clase Animal $otro_pez = new Pez("negro",5); // el tipo de pez $otro_pez->setType(falso);
  • 72. //llamada al método que muestra los atributos de la clase Pez //y Animal $pez->comer_animal($otro_pez); //leer el tipo por el acceso de su propia clase echo "El tipo de pez comido es:".$otro_pez->getType()." "; //leer el peso por el acceso de la clase madre echo "El peso del pez comido es:".$otro_pez->getPeso()." kg "; ?> Da como resultado: Llamada al constructor. Llamada al constructor. El tipo de pez comido es: El peso del pez comido es:0 kg El peso se ha inicializado a 0 por el método comer_animal(Animal $animal_comido) de la clase Animal. En la clase Pez, el método comer_animal(Animal $animal_comido) puede cambiar el atributo tipo en un objeto de tipo Animal, ya que Pez hereda de Animal y, en el
  • 73. archivo uso.php, es un Pez lo que pasa como argumento, y no un Animal. Se trata del polimorfismo de herencia. Herencia en cascada La herencia múltiple no existe en PHP. Una clase solo puede heredar de una única clase, que a su vez puede heredar de una clase, etc. Imagine unas nuevas clases Pez Espada y Carpa que heredan de la clase Pez, que a su vez hereda de la clase Animal. La clase Pez Espada accede a: • Todos los atributos y métodos privados, protegidos y públicos por sí misma. • Todos los atributos y métodos protegidos y públicos de la clase Pez. • Todos los atributos y métodos protegidos y públicos de la clase Animal. • Todos los atributos y métodos públicos de la clase Gato. Las clases abstractas. Se escriben con la palabra clave abstract delante de la palabra class. Una clase abstracta no se puede instanciar, es decir, no permite crear una instancia. Puede escribir métodos abstractos, que son métodos donde solo escribe la firma precedida por la palabra clave abstract: abstract visibilidad function nombre_método (atributo tipo_atributo...). Estas clases solo sirven para obligar, a las clases que heredan de
  • 74. la clase abstracta, a reemplazar los métodos abstractos declarados en la clase abstracta. En el siguiente ejemplo, la clase Animal es abstracta, ya que no se quiere crear (instanciar) animales, sino peces o gatos. Añada también un método abstracto respira() en la clase Animal: <?php abstract class Animal { // Declaración de atributos private $color = "gris"; private $peso = 10; //constantes de clase const PESO_LIGERO = 5; const PESO_MEDIO = 10; const PESO_PESADO = 15; // Declaración de la variable estática $contador private static $contador = 0; public function __construct($color, $peso) // Constructor //que solicita 2 argumentos. {
  • 75. echo ’Llamada al constructor.<br />’; $this->color = $color; // Inicialización del color. $this->peso = $peso; // Inicialización del peso. self::$contador = self::$contador + 1; } //accesos public function getColor() { return $this->color; //devuelve el color } public function setColor($color) { $this->color = $color; //escrito en el atributo color } public function getPeso() { return $this->peso; //devuelve el peso } public function setPeso($peso) { $this->peso = $peso; //escrito en el atributo peso } //métodos públicos
  • 76. public function comer_animal(Animal $animal_comido) { //el animal que come aumenta su peso tanto como //el del animal comido $this->peso = $this->peso + $animal_comido->peso; //el peso del animal comido y su color se restablecen a 0 $animal_comido->peso = 0; $animal_comido->color = ""; } public static function moverse() { echo "El animal se mueve."; } public function añadir_un_kilo() { $this->peso = $this->peso + 1; } // método estático que devuelve el valor del contador public static function getContador() { return self::$contador; } //código no aplicado por el método abstracto
  • 77. abstract public function respira(); } ?> Observe que el método abstracto respira() no tiene cuerpo, es decir, no hay llaves {} en la aplicación del método. Como las clases Pez y Gato heredan de la clase Animal, está obligado a definir de nuevo el método respira() en las clases Pez y Gato. Debe añadir en la clase Pez lo siguiente: public function respira() { echo "El pez respira.<br />"; } Y en la clase Gato: public function respira() { echo "El gato respira.<br />"; }
  • 78. La página uso.php se convierte en: <?php //carga de clases include(’animal.class.php’); include(’pez.class.php’); include(’gato.class.php’); //instanciar la clase Pez, que llama al constructor de //la clase Animal $pez = new Pez("gris",8); //instanciar la clase Gato, que llama al constructor de //la clase Animal $gato = new Gato("blanco",4); //llamada al método respira() $pez->respira(); $gato->respira(); ?> Da como resultado: Llamada al constructor. Llamada al constructor.
  • 79. El pez respira. El gato respira. Las clases finales. Cuando una clase es final, no se puede crear la clase hija que hereda de esta clase. Esto tiene poco interés práctico. Debe añadir la palabra clave final delante de la palabra clave class. Por ejemplo, si no crea una clase que hereda de la clase Pez, puede escribir final: <?php final class Pez extends Animal { private $vive en el mar; //tipo de pez //accesos ... //método public function nadar() { echo "Nado <br />"; }
  • 80. public function respira() { echo "El pez respira.<br />"; } } ?> También puede declarar los métodos finales. Estos métodos no se podrán sustituir. En el tópico de sustitución ya se ha visto un ejemplo donde el método comer_animal(Animal $animal_comido) se ha sustituido en la clase Pez. Si este método era final en la clase Animal: final public function comer_animal(Animal $animal_comido) { //el animal que come aumenta su peso tanto como //el del animal comido $this->peso = $this->peso + $animal_comido->peso; //el peso del animal comido y su color se restablecen a 0 $animal_comido->peso = 0; $animal_comido->color = ""; }
  • 81. Por lo tanto, es imposible sustituir este método en la clase Pez. Métodos mágicos en PHP. Es un método al que se llama automáticamente cuando se produce un acontecimiento. Por ejemplo __construct es un método mágico. Se ejecuta automáticamente cuando instancia la clase que contiene __construct. Los métodos mágicos __get y __set permiten leer o modificar los atributos que no existen y en los que el acceso está prohibido. Retomando el ejemplo con la clase Animal. Esta vez, el atributo color es privado y el atributo peso es público: <?php class Animal { // Declaración de atributos private $color = "gris"; public $peso = 10; public function __construct($color, $peso) // Constructor //que solicita 2 argumentos. { echo ’Llamada al constructor.’; $this->color = $color; // Inicialización del color.
  • 82. $this->peso = $peso; // Inicialización del peso. } //métodos públicos public function comer () { } public function moverse () { } } ?> Cuando crea una instancia de la clase Animal, puede acceder al atributo peso porque es público, pero no al atributo color porque es privado. La página uso.php es: <?php //carga de clases include(’animal.class.php’); //instanciar la clase Animal $perro = new Animal("gris",8); $perro->color = "negro"; echo $perro→color.""; ?>
  • 83. Muestra un error porque intenta acceder directamente al atributo color, que es privado: Llamada al constructor. Fatal error: Cannot access private property Animal::$color in C:Program FilesEasyPHP-DevServer-13.1VC11datalocalwebObjeto uso.php on line 9 Ahora añada los métodos mágicos __get y __set en la clase Animal: <?php class Animal { // Declaración de atributos private $color = "gris"; public $peso = 10; private $tab_atributos = array(); public function __construct($color, $peso) // Constructor //que solicita 2 argumentos. { echo ’Llamada al constructor.’; $this->color = $color; // Inicialización del color.
  • 84. $this->peso = $peso; // Inicialización del peso. } //métodos mágicos public function __get($nombre) { echo "__get "; if (isset ($this->tab_atributos[$nombre])) return $this->tab_atributos[$nombre]; } public function __set($nombre, $valor) { echo "__set "; $this->tab_atributos[$nombre] = $valor; } public function __isset($nombre) { return isset ($this->tab_atributos[$nombre]); } //métodos públicos public function comer () { ... }
  • 85. public function moverse () { ... } } ?> Estos métodos se activan automáticamente si el atributo es privado o no existe. Almacenan el valor en la tabla $tab_atributos, y en el índice, el nombre del atributo. El método __isset($atributo) permite saber si existe el atributo. La página uso.php: <?php //carga de clases include(’animal.class.php’); //instanciar la clase Animal $perro = new Animal("gris",8); if (isset($perro->color)) { echo "El atributo color existe."; } else { echo "El atributo color no existe.";
  • 86. } $perro->color = "negro"; echo $perro->color.""; if (isset($perro->peso)) { echo "El atributo peso existe. "; } else { echo "El atributo peso no existe. "; } $perro->peso = 25; echo $perro->peso." "; ?> Da como resultado: Llamada al constructor. El atributo color no existe. __set __get Negro
  • 87. El atributo peso existe. 25 Explicación: $perro = new Animal("gris",8); da como resultado: Llamada al constructor. isset($perro->color); devuelve falso, ya que no se puede acceder al atributo color, que es privado; por lo tanto, muestra: El atributo color no existe. $perro->color = "negro"; da como resultado: __set. El atributo color es privado; por lo tanto, no se puede acceder a él y llama automáticamente a __set y el valor se almacena en la tabla $tab_atributos. echo $perro->color."<br />"; da como resultado: __get y negro. El atributo color siempre es privado; por lo tanto, llama automáticamente a __get para mostrar el color. isset($perro->peso); devuelve verdadero porque el atributo peso es público, se puede acceder a él y por lo tanto muestra: el atributo peso existe. $perro->peso = 25; no muestra nada porque no llama a la función __set. El atributo peso es público, puede acceder directamente a él.
  • 88. echo $perro->peso."<br />"; da como resultado 25. El atributo peso es público y por lo tanto puede acceder directamente a él. Para eliminar un atributo que el método mágico __set ha añadido, debe ejecutar el método mágico __unset($atributo), que eliminará el atributo de la tabla $tab_atributos. Añada este método en la clase Animal: public function __unset($nombre) { if (isset($this->tab_atributos[$nombre])) unset($this->tab_atributos[$nombre]); } Para terminar, los métodos mágicos __call y __callStatic permiten llamar a los métodos privados o que no existen. La función method_exist() comprueba si un método existe en un objeto. Toma como argumento el objeto y el nombre del método. Devuelve true si el método existe y false si no. La clase Animal con un método público comer() y un método privado moverse() se convierte en: <?php class Animal { // Declaración de atributos
  • 89. private $color = "gris"; public $peso = 10; private $tab_atributos = array(); public function __construct($color, $peso) // Constructor //que solicita 2 argumentos. { echo ’Llamada al constructor.’; $this->color = $color; // Inicialización del color. $this->peso = $peso; // Inicialización del peso. } //métodos mágicos public function __get($nombre) { echo "__get "; if (isset ($this->tab_atributos[$nombre])) return $this->tab_atributos[$nombre]; } public function __set($nombre, $valor) { echo "__set "; $this->tab_atributos[$nombre] = $valor; } public function __isset($nombre)
  • 90. { return isset ($this->tab_atributos[$nombre]); } public function __call($nombre, $argumentos) { echo "El método ".$nombre." no es accesible. Sus argumentos eran los siguientes :".implode($argumentos, ’, ’).""; if(method_exists($this, $nombre)) { $this->$nombre(implode($argumentos, ’, ’)); } } public static function __callStatic($nombre, $argumentos) { echo "El método estático ".$nombre." no es accesible. Sus argumentos eran los siguientes :".implode($argumentos, ’, ’) . ""; if(method_exists(__CLASS__, $nombre)) { echo __CLASS__.’::’.$nombre.’ ’; self::$nombre(implode($argumentos, ’, ’)); } } //método público
  • 91. public function comer() { echo "Método público comer() "; } //método privado private function moverse($lugar) { echo "Método privado moverse() "; } } ?> La página uso.php: <?php //carga de clases include(’Animal.class.php’); //instanciar la clase Animal $perro = new Animal("gris",8); $perro->comer(); $perro->moverse("París"); ?>
  • 92. Da como resultado: Llamada al constructor. Método público comer() El método moverse no es accesible. Sus argumentos eran los siguientes:París Método privado moverse() El código $perro->comer(); llama al método público comer(). Pero al método moverse($lugar), que es privado, no se puede acceder directamente. Llama al método mágico __call, comprueba que existe el método moverse($lugar)y llama al método moverse ($lugar). Si el método moverse ($lugar) es estático, la llamada a la página uso.php es: Animal::moverse("París"); Entonces llama al método mágico __callStatic. Namespaces en PHP Cuando trabaja en proyectos grandes en equipo, es útil modularizar las clases y las funciones. De esta manera, cada desarrollador puede trabajar con su propio módulo. Desde PHP 5.3, las namespaces (espacio de nombres), permiten esta modularización. Un namespace es una especie de carpeta virtual en la que
  • 93. almacena sus objetos. De esta manera es posible usar clases o funciones con el mismo nombre, en namespaces diferentes. Un namespace se declara con la palabra clave namespace, seguido de su nombre, al inicio del archivo. Por ejemplo: Espacio_nombre.php <?php // Definición del espacio de nombres. namespace Biblioteca; // Definición de una constante. const PI = 3.1416; // Definición de una función. function miFuncion() { echo "Hola <br />"; } // Definición de una clase. class miClase { /* … */ } ?>
  • 94. Uso_espacio_nombres.php: <?php include(’espacio_nombres.php’); BibliotecamiFuncion(); //Llamada al namespace Biblioteca raíz ?> Muestra: Hola La constante __NAMESPACE__ devuelve el nombre del espacio de nombres actual. Es posible crear sub-espacios de nombres escribiendo: Namespace Espacio1/subespacio1; Las rutas para encontrar una función, clase o constante en un espacio de nombres son relativos si empieza por el namespace o absoluto si empieza con /. Por ejemplo: Espacio_nombres.php:
  • 95. <?php // Definición del espacio de nombres. namespace Biblioteca; // Definición de una constante. const PI = 3.1416; // Definición de una función. function miFuncion() { echo "Hola <br />"; } // Definición de una clase. class Animal { // Declaración de los atributos private $color = "gris"; //accesos public function getColor() { return $this->color; //devuelve el color } public function setColor($color) { $this->color = $color; //escribe en el atributo color
  • 96. } } ?> Uso_espacio_nombres.php <?php namespace Project; include(’espacio_nombres.php’); // Muestra el espacio de nombres actual. echo ’Espacio de nombres actual = ’, __NAMESPACE__,’<br />’; BibliotecamiFuncion(); //Llamada al namespace Biblioteca raíz echo BibliotecaPI."<br />"; $gato = new BibliotecaAnimal(); $gato->setColor("negro"); echo "El color del gato es:".$gato->getColor(); ?> Muestra: Espacio de nombres actual:Project Hola 3.1416
  • 97. El color del gato es: negro Para terminar, puede crear un alias en el espacio de nombres o en un objeto contenido en el espacio de nombres. Para esto basta con usar el operador use [namespace] as nombre_nuevo Por ejemplo: UseBiblioteca as biblio; Con los alias, la página Uso_espacio_nombres.php, se convierte en: <?php namespace Project ; include (´espacio_nombres.php’) ; //Muestra el espacio de nombres actual. echo ’Espacio de nombres actual = ’, _NAMESPACE_’<br />’; BibliotecamiFuncion() ; llamada al namespace Biblioteca raíz useBiblioteca as biblio; // alias de un namespace echo BibliotecaPI., ”<br />”; use Biblioteca|Animal as ani; // alias de una clase $gato = new ani (); // Llamada al alias de la clase
  • 98. //Animal$gato->setColor (”negro”), echo ”El color del gato es : ”.$gato->getColor(); ?> Muestra: Espacio de nombres actual=Project Hola 3.1416 El color del gato es: negro
  • 99. Supongamos que tenemos dos clases: Auto y Motocicleta, como se muestra en el diagrama de clases UML la figura 12. Si se analiza detalladamente, ambas clases son muy similares en atributos y métodos; la motocicleta no tiene el atributo cantidad_puertas. Ambas son un tipo de vehículo. En este tipo de relación se habla de herencia o generalización, donde se puede definir una clase padre denominada Vehículo de la que toman características y comportamiento las clases anteriores (Véase Figura 13). En la herencia, las clases hijas extienden de la clase base, la cual debe tener atributos protegidos; sin embargo, también pueden tener atributos y comportamiento particulares. En PHP una clase sólo puede extender de una clase base. En el diagrama de clases siguiente, se observa que tanto Auto como Motocicleta heredan los métodos y atributos de Vehículo. Figura 12. Ejemplo de Diagrama de clases UML (Fuente: elaboración propia) Figura 13. Ejemplo de Generalización en UML. (Fuente: elaboración propia a partir de Gaitán, Fernando.)
  • 100. En forma de código, esto se ve reflejado así: <?php namespace herencia; class Vehiculo{ protected $motor_encendido=false; protected $cantidad_ruedas; protected $marca; public function __construct($cRuedas,$marca) { $this->cantidad_ruedas=$cRuedas; $this->marca=$marca; echo 'Se ha instanciado un vehículo de: '.$this- >cantidad_ruedas.' ruedas' .' Marca: '.$this->marca.'<br/>'; } public function encenderMotor(bool $encendido){ $this->motor_encendido=$encendido; } public function arrancar(){ if ($this->motor_encendido) { echo '¡Encendido!'; } } } ?> Código 24. Clase vehículo. (Fuente: adaptado de Gaitán, Fernando) <?php namespace herencia; class Auto extends Vehiculo{ private $cantidad_puertas; public function getCantidadPuertas(){ return $this->cantidad_puertas; } public function setCantidadPuertas($cantidadPuertas){ $this->cantidad_puertas=$cantidadPuertas; } public function __construct($cRuedas, $marca, $cantidadPuertas) { parent::__construct($cRuedas, $marca); $this->cantidad_puertas=$cantidadPuertas; echo 'Se ha instanciado un objeto Auto de: ' .$this->cantidad_ruedas.' ruedas y '.$cantidadPuertas.' puertas <br/>'; } } ?> Código 25. Clase Auto. (Fuente: adaptado de Gaitán, Fernando)
  • 101. Las 3 primeras clases ejemplifican una buena práctica: el uso de namespaces, permite organizar los archivos, similar a rutas en un sistema de archivos. Es más adecuado que la ruta coincida con el espacio de nombres, el cual debe de ser declarado al inicio del archivo antes de cualquier otra instrucción excepto declare. Para acceder a las clases de un espacio de nombres existen varias maneras: una de ellas, es especificar el nombre completo de la clase al referenciarla, por ej.: $carro=new herenciaAuto(); otra forma, es que el archivo index.php pertenezca al mismo namespace. La mejor manera es utilizar la palabra clave use. Ésta permite especificar el nombre completo de una clase. También se puede asignar un alias con la palabra clave as seguida de un nombre. <?php namespace herencia; class Motocicleta extends Vehiculo{ public function __construct($cRuedas, $marca) { parent::__construct($cRuedas, $marca); echo 'Lo que ha instanciado es un objeto Motocicleta </br>'; } } ?> Código 27. Clase Motocicleta. (Fuente: adaptado de Gaitán, Fernando) <?php use herenciaAuto; use herenciaMotocicleta as M; require_once 'herencia/Vehiculo.php'; require_once 'herencia/Auto.php'; require_once 'herencia/Motocicleta.php'; $c=new Auto(4, 'Nissan', 3); $c->encenderMotor(TRUE); $c->arrancar(); echo '<br/><br/>'; $m=new M(2, 'Honda'); ?> Código 26. Archivo index.php. (Fuente: adaptado de Gaitán, Fernando)
  • 102. En el archivo index.php se le indicó al servidor cómo evaluar y procesar el código de las clases mediante require_once. A como se indicó en el diagrama de clases de la Fig. 13, las clases Auto y Motocicleta heredan de su clase base o padre, Vehículo. Esto se indica en PHP mediante la palabra reservada extends. Tanto Auto como Motocicleta tienen los atributos motor_encendido, cantidad_puertas y marca así como el comportamiento establecido al declarar los métodos encender_motor, apagar, y arrancar. Auto tiene un atributo propio: cantidad de puertas; es decir que las clases hijas pueden tener atributos particulares diferentes a su clase base. Para hacer referencia a un método o propiedad de la clase principal desde su hija, se puede usar $this como si la propiedad o el método estuvieran en la misma clase. Sin embargo, si se desea hacer referencia a la implementación en la clase padre, se debe utilizar la palabra clave parent seguido del operador Paamayim Nekudotayim (::) u operador de doble dos puntos seguido del nombre del método. En la siguiente figura, se puede observar que se llama al constructor de la clase base dejándolo hacer lo programado y luego ejecuta las instrucciones especializadas en la clase hija. Figura 14. Salida de la ejecución del código anterior.
  • 103. Referencias bibliográficas: http://www.4rsoluciones.com/blog/que-son-los-paradigmas-de-programacion-2/ https://es.ccm.net/contents/410-poo-encapsulacion-de-datos https://es.wikipedia.org/wiki/Programaci%C3%B3n_orientada_a_objetos https://es.wikipedia.org/wiki/Encapsulamiento_(inform%C3%A1tica) Joyanes A., Luis. (2008). Fundamentos de programación. (4 Ed.). McGraw-HILL / Interamericana de España. http://www.tutorialesprogramacionya.com/phpya/poo/temarios/descripcion.php?co d=35&punto=1&inicio=0 http://tutorialphp.net/php-7-orientado-a-objetos/ https://www.youtube.com/watch?v=r8w2wEj8ZyI&list=PLoNyKJJ130VF0ybSWkLgi TGwePQ9cv-JL https://styde.net/aprende-programacion-orientada-a-objetos-poo-con-php/ https://fernando-gaitan.com.ar/php-orientado-a-objetos-parte-6-herencia/ https://diego.com.es/programacion-orientada-a-objetos-en-php http://anexsoft.com/p/149/que-son-y-ejemplo-de-namespaces-en-php