Desarrollo de aplicaciones web con PHP y MySQL
Módulos en PHP
Sergio Sáez y José Luis Poza
E.T.S. de Ingeniería Informática
Módulos en PHP
- Permiten incluir código externo desde un fichero dentro de tu script PHP.
- Usando require() e include()
- Incluyen un fichero que puede contener cualquier cosa que iría en un script PHP.
<?php // sentencia.php
echo "Una sentencia simple<br>\n";
?>
<?php
echo "Éste es el fichero principal<br>\n";
require "sentencia.php";
echo "Y termina aquí<br>\n";
?>
Éste es el fichero principal<br>
Una sentencia simple<br>
Y termina aquí<br>
Módulos en PHP (cont.)
- Cuando se incluye un fichero el interprete sale del modo PHP y entra en el modo HTML.
- Aunque se invoque desde dentro del código PHP, si el fichero incluido tiene código en PHP, las etiquetas deberán estar presentes.
- Si las etiquetas no están presentes el código se mostrará tal cual en el navegador.
// incorrecto.php
echo "Una sentencia simple<br>\n";
<?php
echo "Éste es el fichero principal<br>\n";
require "incorrecto.php";
echo "Y termina aquí<br>\n";
?>
Éste es el fichero principal<br>
// incorrecto.php
echo "Una sentencia simple<br>\n";
Y termina aquí<br>
Ámbito de las variables
- En el módulo estarán disponibles las mismas variable que hubiera disponibles en la línea en la que estaba la construcción include() o require().
- Las variables que se crean en el módulo están disponibles en el ámbito en el que está la orden de inclusión.
- Las variables externas que se utilizan en los módulos se deben haber creado con anterioridad.
- No hay un mecanismo para pasarle una variable de forma explícita a un módulo.
|
<?php // muestra.php echo "Muestra \$a: '$a'\n"; $b= "Saludo desde el módulo"; ?>
|
<?php $a= "Un valor"; include "muestra.php"; echo "Muestra \$b: '$b'\n"; ?>
|
Muestra $a: 'Un valor'
Muestra $b: 'Saludo desde el módulo'
Extensiones de los ficheros
- No se requiere que los ficheros tengan ninguna extensión concreta.
- Hay que ponerles extensiones lógicas, v.g., ".php"
- ".html" no parece una buena idea para un fichero que contiene código PHP.
- Si no tiene una extensión reconocida por el servidor web, como ".php", y el fichero está en el árbol del servidor, podría ser accedido desde el exterior sin procesar, por lo que el código, claves, etc. quedarían expuestos.
- Los módulos deberían guardarse fuera del árbol de fuentes del servidor, al igual que los ficheros con datos sensibles.
Inclusiones múltiples
- Con las ordenes include() y require() nada impide que un fichero sea incluido más de una vez.
- Las ordenes include_once() y require_once() aseguran que cada fichero sólo se incluye una vez.
- Evitan colisión con los valores de las variables y los nombres de funciones.
<?php // utiles.php
function causaError() {
return "Esta función va a causar error!";
}
?>
|
<?php // biblioteca.php require "utiles.php"; function muestra_valor($var) { echo $var; } ?>
|
<?php require "biblioteca.php"; // La siguiente inclusión fallará require "utiles.php"; ?>
|
Restricciones
- Al ser una construcción del lenguaje, y no una función, se debe encerrar dentro de un bloque de sentencias si queremos que se comporte como un bloque.
|
<?php // archivo.php echo "Sentencia uno!"; echo "Sentencia dos!";
|
<?php // otro.php echo "Otra sentencia uno!"; echo "Otra sentencia dos!";
|
|
<?php /* Esto es ERRÓNEO y no funcionará como se desea. */ if ($condicion) include "archivo.php"; else include "otro.php";
/* Esto es CORRECTO. */ if ($condicion) { include "archivo.php"; } else { include "otro.php"; }
|
<?php // Equivale a esto if ($condicion) echo "Sentencia uno!"; echo "Sentencia dos!"; else echo "Otra sentencia uno!"; echo "Otra sentencia dos!";
/* Esto es CORRECTO. */ if ($condicion) { echo "Sentencia uno!"; echo "Sentencia dos!"; } else { echo "Otra sentencia uno!"; echo "Otra sentencia dos!"; }
|
- PHP permite no terminar con ?> los ficheros que no tienen texto al final para evitar la inserción de espacios en blanco no deseados.
Diferencias entre require e include
- include() y require() son idénticas, salvo por el modo de actuar ante un error.
- Si el fichero no está, include() da un warning, mientras que require() produce un error fatal.
- Si estamos seguros de que el fichero debe estar, y si no está debe detenerse el script PHP, se utilizará require().
- A partir de aquí, hablaremos sólo de include().
<?php include "noexiste.php"; ?>
PHP Warning: include(noexiste.php): failed to open stream: No such file or directory in Standard input code on line 1
PHP Warning: include(): Failed opening 'noexiste.php' for inclusion (include_path='.:/usr/share/php') in Standard input code on line 1
<?php require "noexiste.php"; ?>
PHP Warning: require(noexiste.php): failed to open stream: No such file or directory in Standard input code on line 1
PHP Fatal error: require(): Failed opening required 'noexiste.php' (include_path='.:/usr/share/php') in Standard input code on line 1
Volviendo de un fichero incluido
- La construcción return te permite terminar de ejecutar código del fichero incluido.
|
<?php // fichero-con-return.php echo "Esto se muestra"; return; echo "Esto no se muestra";
|
<?php include "fichero-con-return.php";
|
- También puede utilizarse para devolver un valor. Es raro, pero se usa.
|
<?php // config.php return [ "path" => "/una/ruta", "debug" => true, ];
|
<?php $config = require "ejemplos/config.php"; var_dump($config);
|
array(2) {
["path"]=>
string(9) "/una/ruta"
["debug"]=>
bool(true)
}
Modificando la ruta de inclusión
- La ruta de inclusión se puede manipular con las funciones:
- get_include_path
- Devuelve la ruta de inclusión definida en este momento, por ejemplo:
.:/usr/share/php:/usr/share/pear.
- set_include_path
- Establece la nueva ruta de inclusión.
- PATH_SEPARATOR
- Esta constante define el separador de directorios en la ruta de inclusión sobre esta plataforma.
Ejemplo
<?php
$phplib= "/home/cursophp/lib/php";
set_include_path(get_include_path() . PATH_SEPARATOR . $phplib);
?>
Patrones para aplicaciones web
- Cuando se requiere un aspecto homogeneo a lo largo de toda una aplicación web, el aspecto de todas las páginas mostradas debe ser similar, así como su estructura.
Patrones para aplicaciones web (cont.)
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>Tienda de recambios de Bob</title>
<link rel="stylesheet" TYPE="text/css" href="style.css">
</head>
<body>
<table class="page" cellpadding="12" cellspacing="12" width="100%">
<tr valign="middle">
<td class="header"> <img src="titulo.png"> </td>
</tr>
<tr> <td class="content">
<h1>Bienvenidos a la tienda de recambios de Pep!</h1>
<p>Nos alegramos de volver a verle!</p>
</td> </tr>
<tr> <td class="footer">
<center>
<address>
<small>Tienda de Recambios de BOB.</small>
<small>Hora: <?php echo date("H:i:s"); ?></small>
<small>Fecha: <?php echo date("j/m/Y"); ?></small><br>
<small>Webmaster:
<a href="mailto:ssaez@disca.upv.es">ssaez@disca.upv.es</a></small>
</address>
</center>
</td> </tr>
</table>
</body>
</html>
Patrones para aplicaciones web (cont.)
- Se pueden incluir los ficheros de cabecera y pie en cada página de la aplicación.
<?php require "header.php"; ?>
<h1>Bienvenidos a la tienda de recambios de Pep!</h1>
<p>Nos alegramos de volver a verle!</p>
<?php require "footer.php"; ?>
- Se pueden añadir a todas las páginas del sistema configurando el interprete de PHP.
auto_prepend_file = "/home/ssaez/php/include/header.php"
auto_append_file = "/home/ssaez/php/include/footer.php"
- Si colocamos las definiciones en el fichero .htaccess de un directorio, el servidor apache sólo aplicará las definiciones a dicho directorio.
php_value auto_prepend_file = "/home/ssaez/php/include/header.php"
php_value auto_append_file = "/home/ssaez/php/include/footer.php"
Inclusión dinámica de módulos
- El nombre del módulo que se debe incluir no tiene porque venir dado por una cadena constante.
- Ejemplo de formulario de petición:
<h1>Cesta de la comprar</h1>
<form action="peticion.php" method="post">
<table>
<tr><td>Producto</td><td>Cantidad</td></tr>
<tr><td>Ruedas</td><td>4</td></tr>
<tr><td>Aceite</td><td>2</td></tr>
<tr><td>Bujias</td><td>6</td></tr>
</table>
<input type="submit" name="facturar" value="Facturar">
<input type="submit" name="cancelar" value="Cancelar">
</form>
Inclusión dinámica de módulos (cont.)
<?php // peticion.php
if (isset($_POST["facturar"))) {
$accion= "facturar";
} elseif (isset($_POST["cancelar"))) {
$accion= "cancelar";
} else {
$accion= "error";
} // endif
include "ejecutar_{$accion}.php";
?>
- Se carga el fichero que muestra el estado actual.
Inclusión dinámica de módulos (cont.)
- Una versión un poco más flexible
<h1>Cesta de la comprar</h1>
<form action="peticion.php" method="post">
<table>
<tr><td>Producto</td><td>Cantidad</td></tr>
<tr><td>Ruedas</td><td>4</td></tr>
<tr><td>Aceite</td><td>2</td></tr>
<tr><td>Bujias</td><td>6</td></tr>
</table>
<input type="submit" name="boton[facturar]" value="Facturar">
<input type="submit" name="boton[cancelar]" value="Cancelar">
</form>
Inclusión dinámica de módulos (cont.)
- El análisis del formulario es más sencillo
<?php // peticion.php
if (isset($_POST["boton"]))) {
$accion= key($_POST["boton"]);
} else {
$accion= "error";
} // endif
include "ejecutar_{$accion}.php";
?>
- Ahora el número de acciones se puede cambiar dinámicamente sin tocar este código.
- Sólo hace falta añadir el fichero ejecutar_loquesea.php correspondiente a la nueva acción.