PHP-TUT-14 Reutilización de código

Facebooktwittergoogle_pluslinkedinmailFacebooktwittergoogle_pluslinkedinmail

En este artículo vamos a conocer las posibilidades que PHP incorpora para la reutilización de código. Este tema es breve, pero muy importante, por lo que le vamos a prestar, en este post, la atención que merece. La reutilización de código no sólo nos permite ahorrar gran cantidad de horas en el desarrollo de aplicaciones sino que, además, cuenta con la ventaja adicional de que un código que ya tenemos probado y funcionando no hay que repetirlo, evitando caer en la monotonía (uno de los peores enemigos de un desarrollador).

EJECUTANDO OTROS SCRIPTS

Cuando se escribe mucho código nos encontramos con que, a menudo, determinadas funciones o fragmentos del código están presentes, sin cambios, en distintos scripts. Por ejemplo, imáginate que vas a montar una tienda virtual. El acceso a la base de datos de los productos deberá estar incluido en, prácticamente, la totalidad de las páginas. Cuando se presenta una situación así, aparece un concepto conocido como reutilización de código. En realidad este concepto es mucho más amplio, ya que implica la posibilidad de que el código que hoy escribimos para, por ejemplo, crear una tienda, nos pueda servir, con muy pocos cambios, para que, dentro de dos meses, podamos crear otra diferente. Pero, por ahora, vamos a ver cómo podemos usar un fragmento de código en varios scripts diferentes, sin necesidad de re-escribirlo cada vez. La solución pasa por colocar el fragmento que será común en otro script, al que invocaremos cuando sea necesario. Para ello, PHP nos proporciona cuatro instrucciones que debemos conocer: include(), require(), include_once() y require_once(). Aunque el objetivo de las cuatro es similar, presentan algunas diferencias que debemos conocer, para aplicar la más adecuada en cada caso. A lo largo de este post, vamos a describir el proceso de incorporar un script dentro de otro con todas las posibilidades.

Vamos a suponer un script que contiene la definición de una función para el cálculo de amortización de un préstamo. Esta función recibirá tres argumentos, que serán el capital del préstamo, el tipo de interés aplicable y el plazo de amortización, en meses. A partir de ahí calculará el importe de las cuotas (considerando un interés simple) que se deben pagar y devolverá este valor. Es un script, que he llamado calculoIntereses.php, muy sencillo, cuyo código es el que aparece reproducido a continuación:

Ahora suponte que necesitas disponer de esta función en un script para que esté disponible para el usuario. No tienes que copiar el código de la función en el script. Basta con que incluyas una línea como la siguiente:

require ("calculoIntereses.php");

Veamos un ejemplo de uso. Para ello carga en el navegador el código de formularioIntereses.htm. No voy a reproducir aquí el listado, puesto que sólo es un formulario HTML, sin mayor interés. El caso es que los datos que introduzca el usuario se envían a formularioIntereses.php, que es el script encargado de procesarlos. Su código es el siguiente:

Fíjate en la primera línea resaltada, que hace uso de require() para incorporar el código de calculoIntereses.php dentro de formularioIntereses.php. A partir de este momento, la función calculaCuota (), que se ha definido en el primer script, está disponible en el segundo, y podemos llamarla, tal como se hace en la segunda línea que aparece resaltada. El uso, por tanto, de require() está muy claro: cuando tengamos un fragmento de código que vaya a ser incorporado a varios scripts de nuestro sitio web, lo grabaremos en un script externo y lo llamaremos cuando sea necesario, en lugar de copiar dicho fragmento en todas las páginas. En este ejemplo, el cuerpo de la función calculaCuota(), que está definida en un script externo, puede ser incorporado a cualquier script del sitio, con sólo hacer una llamada con require(), tal como hemos visto. Esto tiene una ventaja adicional, muy importante. Si necesitas cambiar el código que aparece en el script externo, sólo tienes que cambiarlo en dicho script. A partir de ahí, cuando se le requiera se cargará el código modificado.

Hasta la versión 4 de PHP, la sentencia require() presentaba ciertas limitaciones en su funcionamiento con condicionales. Sin embargo, éstas fueron subsanadas en la versión 5 y funciona perfectamente en la actual versión 7.

Existe una sentencia equivalente que es include(). Su uso y sintaxis son idénticos a los que acabamos de ver. Sin embargo, existe una diferencia de matiz en su operativa ante un error. Suponte que llamamos a un script externo que no existe (por ejemplo, por haber escrito mal el nombre). Veamos el comportamiento de ambas instrucciones ante esta eventualidad. Observa el script errorNoInclude.php, a continuación:

Como ves en la línea resaltada se llama a un script que no existe. Al ejecutarlo veremos en la página el siguiente resultado:

Warning: include(ficheroNoExistente.php): failed to open stream: No such file or directory in C:\xampp\htdocs\pruebas\errorNoInclude.php on line 2
Warning: include(): Failed opening ‘ficheroNoExistente.php’ for inclusion (include_path=’C:\xampp\php\PEAR’) in C:\xampp\htdocs\pruebas\errorNoInclude.php on line 2
EJECUCIÓN FINALIZADA

Como puedes comprobar, se lanzan un par de avisos (Warning) de que algo va mal, pero la ejecución continúa, mostrándose el contenido de la siguiente línea del script, que exhibe un texto en la página.

Ahora observa el listado de errorNoRequire.php, que es el siguiente:

Como ves, es el mismo que el anterior, sólo que la invocación a un script externo no existente se hace con require(), en lugar de con include(). Al ejecutarlo obtenemos el siguiente resultado en la página:

Warning: require(ficheroNoExistente.php): failed to open stream: No such file or directory in C:\xampp\htdocs\pruebas\errorNoInclude.php on line 2
Fatal error: require(): Failed opening required ‘ficheroNoExistente.php’ (include_path=’C:\xampp\php\PEAR’) in C:\xampp\htdocs\pruebas\errorNoInclude.php on line 2

Como ves, obtenemos un aviso (Warning) y un error fatal (Fatal error) que detiene la ejecución, no mostrándose en la página la siguiente línea del script.

¿Cuándo usar require() y cuándo usar include()? Es, principalmente, una cuestión de criterio personal. Yo me he acostumbrado a emplear include(), pero, como te digo, ése es mi criterio que no tiene, necesariamente, que coincidir con el tuyo. En versiones anteriores de PHP tenía importancia con el empleo de funciones de usuario, pero eso es ya meramente anecdótico. En la actualidad, ambas funciones operan igual.

Con el uso de estas instrucciones puede surgir un problema si el script externo contiene la definición de una función y la invocación forma parte, por ejemplo, de un bucle. Supongamos un script externo como cuadradoExterno.php:

Como ves, es una función muy sencillita, que ni siquiera devuelve resultado alguno, y que sólo recibe como argumento un número, lo eleva al cuadrado y lo muestra en la página. Ahora vamos a crear un script que llame a esta función para calcular el cuadrado de los números del 1 al 10. El código se llama mostrarCuadrados.php:

Cuando lo ejecutes verás que se te muestra en la página el cuadrado del primer valor del bucle (1) y, a continuación, se produce un error fatal que indica que se ha redeclarado una función.

Este error se produce porque, al estar la invocación en un bucle, se llama al script externo en cada iteración de dicho bucle. Sin embargo, PHP no permite cargar en un script la definición de una función más de una vez. Te lo repito, resaltado en negrita, porque esto da lugar a muchos errores.

En ningún script de PHP se puede definir una función más de una vez, bajo ningún concepto y de ninguna manera.

La solución a este problema puede ser, en este caso, colocar la sentencia include() antes del bucle. Sin embargo, si por el diseño de tu script, no te queda más remedio que colocarla dentro del bucle, utiliza, en su lugar, include_once (). Observa el script cuadradosCorrectos.php:

Observa la línea resaltada en el código. Esta función comprueba si ya se ha incluido previamente el script externo. Si es el caso, ya no efectúa la inclusión. De este modo, se evita el error de redeclarar una función.

PHP cuenta también con la correspondiente instrucción require_once(), equivalente a require(), pero con comprobación previa de haberse cargado ya el script externo a que se refiere.

Recuerda. Siempre que su script externo incluya la definición de una función, cárgalo con include_once() o con require_once(). De este modo, evitarás errores. Sin embargo, esto tiene una contrapartida. Si tu script externo declara variables que son usadas por el script principal, sólo se cargarán una vez. Si necesitas recargarlas, con los valores originales, mediante otra llamada al script externo, con require_once() e include_once() no podrás hacerlo, ya que estas dos instrucciones se ejecutan, siempre, previa comprobación de no haber sido ejecutadas anteriormente en el mismo script.

CONSIDERACIONES SOBRE SCRIPTS EXTERNOS

Es importante que tengas en cuenta un hecho. Hasta ahora todos los scripts externos que hemos cargado están en la misma ruta que aquéllos en los que se efectúa la invocación. Si los scripts externos se encuentran en otra carpeta o directorio es necesario especificar la ruta de acceso en la llamada. Por ejemplo. Supongamos que, dentro de tu directorio principal de trabajo tienes dos subdirectorios. El primero, llamado usoGeneral, contiene todos los scripts de tus páginas; el segundo, llamado archivosComunes, contiene los scripts externos que deberán ser cargados desde los principales. Para invocar un script externo desde una de las páginas deberás usar algo parecido a lo siguiente:

include ("../archivosComunes/scriptExterno.php");

Esto, si lo piensas, no es nada nuevo. Ocurre lo mismo que cuando se usa un enlace en HTML o se llama a un archivo en cualquier lenguaje. Te supongo lo suficientemente familiarizado con HTML y JavaScript como para que el asunto de las rutas no te suponga ningún problema.

Lo llamativo de este modo de incluir scripts externos es que puedes invocar, incluso, a scripts que se encuentren en otro servidor, accediendo a ellos de forma remota. Por ejemplo, tu código podría tener una línea como la siguiente:

include ("http://otrosScripts.com/scriptExterno.php");

Sin embargo, para que esto funcione es necesario que tengas activada la directiva allow_url_fopen en el fichero de configuración de PHP (php.ini). Hablaremos de la configuración de PHP en un artículo posterior.

Naturalmente, todo lo que hemos dicho en este breve apartado es válido, también, para las sentencias require(), include_once() y require_once(), cuyo funcionamiento, como has podido ver, es muy similar.

     

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *