Mostrando las entradas con la etiqueta PHP. Mostrar todas las entradas
Mostrando las entradas con la etiqueta PHP. Mostrar todas las entradas

jueves, 20 de octubre de 2011

SIP en la Web

Super interesante artículo que nos comparte Saúl Ibarra desde su blog ...


Marcad el día que os enterasteis de esto en el calendario. Se trata de la innovación más importante tras el pan de molde. Es SIP en la Web. Vamos a ver cómo funciona, dadle al play que yo espero:


lunes, 10 de octubre de 2011

Asterisk y Arduino: la unión software-hardware perfecta


Por todo lado hay gente haciendo cosas ingeniosas, en esta ocasión Elio Rojano nos comparte el trabajo de uno de sus colegas, mezclando la electronica con Asterisk, super interesante.

martes, 12 de julio de 2011

Benchmarking AGI performance in C, PHP, and Perl

En Venture Voip nos hallamos un artículo de unas pruebas de Benchmarking entre varios lenguajes de programación para determinar su rendimiento con AGI, aquí el artículo en ingles:thumnail

jueves, 26 de mayo de 2011

Cómo programar un AGI en PHP sin librerías raras

Un excelente artículo que Elio Rojano nos comparte en su blog de Sinologic. Una de las personas que más respeto en este ambito de la voz ip


 


Muchas personas que están aprendiendo Asterisk y que ya conocen las posibilidades de esta aplicación, quieren 


 


 


 


empezar a desarrollar sus propias soluciones para que Asterisk pueda interactuar con bases de datos, archivos del sistema de ficheros y en función de algún valor, conseguir que Asterisk haga una llamada, reproduzca una locución, o mil cosas más.


 


 


Esto se realiza gracias a un concepto en Asterisk llamado AGI (Asterisk Gateway Interface) y que viene a ser un programa desarrollado por nosotros (o por otro usuario) que Asterisk ejecuta (importante esto último) y que sirve para que interactúe Asterisk con el sistema Linux, pudiendo acceder a archivos locales, puertos físicos (usb, puertos series, paralelos, etc.), bases de datos, páginas webs, y prácticamente cualquier otra cosa que pueda manejar nuestro sistema Linux.


 


No voy a entrar en la “profundidad” en la que se entra en el curso Asterisk Advanced, pero sí ofrecer un esqueleto básico de un AGI programado en PHP sin necesidad de librerías externas y utilizando una programación muy sencilla (ideal para empezar a familiarizarse con este tipo de sistemas de integración Asterisk-*)


A continuación tenéis un ejemplo ultra-básico sobre cómo puede ser un AGI programado en PHP y sin necesidad de librerías tipo “php-agi” ni “AstPHPAGI”, ni ninguna otra, tan solo tu Asterisk, tú y PHP con sus modulitos.


Debo decir que este ejemplo no lo he programado yo, pero para ilustrar el ejemplo sirve igualmente.


Los comentarios sí son míos y creo que ayudan bastante a entender cómo funciona y qué precauciones debemos tomar antes, durante y después de programar un AGI.


También sé que para muchos, programar un AGI no tiene ninguna ciencia, pero hay que entender que muchos lectores se consideran muy, muy novatos, así que para seguir aprendiendo, aquí tenéis este ejemplo:


#!/usr/bin/php
<?php

// Lo primero es entrar en el Asterisk y ejecutar el comando: "agi set debug on" para ver 
// qué va haciendo el AGI.

// Hay que evitar enviar por la "salida estandar" nada, salvo los comandos para el Asterisk.

// El Asterisk nada más ejecutar el AGI, nos envía información para aburrir...
$agivars = array();
while (!feof(STDIN)) {
$agivar = trim(fgets(STDIN));
if ($agivar === '') {
break;
}
$agivar = explode(':', $agivar);
$agivars[$agivar[0]] = trim($agivar[1]);
}

// la variable $agivars es un array bidimensional con los datos recogidos por el Asterisk
// Un ejemplo de esto puede ser:
// exten=>00,1,AGI(prueba.php,600123456)
/*
Array
(
[agi_request] => prueba.php    ;; Nombre del archivo que contiene el AGI que está ejecutando.
[agi_channel] => SIP/100-00000008   ;; Canal SIP que llama al AGI. (canal, que no usuario)
[agi_language] => en           ;; Idioma por defecto del canal
[agi_type] => SIP              ;; tipo de Tecnología utilizada para llamar al AGI
[agi_uniqueid] => 1305795790.9 ;; UniqueID de la "llamada al AGI"
[agi_version] => 1.8.4         ;; Versio? del sistema AGI utilizado. ¿coincide con el Asterisk?
[agi_callerid] => 100          ;; CallerID del usuario que ejecuta el AGI
[agi_calleridname] => 100      ;; CallerIDname del usuario que ejecuta el AGI
[agi_callingpres] => 0         ;; ...
[agi_callingani2] => 0         ;; ...
[agi_callington] => 0          ;; ...
[agi_callingtns] => 0          ;; ...
[agi_dnid] => 00               ;; Número marcado en el dialplan para llamar al AGI
[agi_rdnis] => unknown         ;; ...
[agi_context] => salientes     ;; Contexto donde se ejecuta el AGI
[agi_extension] => 00          ;; Extensión donde se ejecuta el AGI
[agi_priority] => 1            ;; Prioridad donde se ejecuta el AGI
[agi_enhanced] => 0.0          ;; Agi "mejorado" 
[agi_accountcode] =>           ;; El AccountCode (si lo hemos definido)
[agi_threadid] => -1239581840  ;; ...
[agi_arg_1] => 600123456       ;; Argumento 1 del AGI (el Argumento 0 es el nombre del AGI)
[agi_arg_2] =>                 ;; Argumento 2 del AGI
...                     ;; ...
)
*/

// Vamos a decirle a Asterisk que haga un Dial al número que le hemos pasado por parámetro:

echo "EXEC Dial DAHDI/g1/".$agivars[agi_arg_1];

// Podemos usar los comandos propios de los AGI (como hemos usado el 'EXEC') que podemos obtener
// ejecutando en la consola "agi show commands" o "agi show commands topic <comando>" para una
// información más detallada de cada comando.

// Importante... despues del "?" y el ">" del 'fin del PHP' no debe haber ni siquiera un [ENTER]... 
// ya que en caso contrario, Asterisk devolverá un error del tipo:
// ERROR[24598]: utils.c:1133 ast_carefulwrite: write() returned error: Broken pipe
?>

El código no puede ser más sencillo, quizá lo más interesante pueden ser los comentarios que explican el comienzo y los comandos básicos para programar un AGI.


Sin más me queda agradecer de nuevo a Elio Rojano por sus grandes aporte a la comunidad de Asterisk


Fuente: Sinologic.net

martes, 15 de marzo de 2011

10 Extensiones de Firebug que deberias conocer

 


Logo Firebug


Si estas en el mundo del Desarrollo Web, es muy probable que ya conozcas Firebug.


Este popular plugin de Firefox nos permite, entre otras cosas, hacer debug del Javascript, cambiar el CSS de tus paginas en tiempo real y ver el trafico de red de tu pagina.

martes, 25 de enero de 2011

40 Clean, Fresh and Amazing Free WordPress Themes

 


Clean, Fresh and Amazing Free WordPress Themes


Some of the best free WordPress themes will take the design of your blog or website to a whole new level. All of them are really professional designed and look that we feel had a little something extra that made tham stand out from the crowd.

In this article, I selected 40 amazing, free WordPress Themes to help everyone out. The selection include both newly released, and older themes. This is not the long list with all the available free wordpress themes on the internet but its an exclusive collection of free wordpress themes.


Just make sure to read the license agreements and installation instruction carefully as they can change from time to time.


Irresistible

Irresistible

domingo, 23 de enero de 2011

WordPress Plugins that Every Website Need

Un excelente artículo publicado en 39articles.net super util para todos los que trabajamos con wordpress. 


 


Wordpress Plugins that Every Website Need


One of the reasons that I’m so madly in love with WordPress is the thousands of plugins available. It doesn’t matter what you want to accomplish on your blog, there’s probably a plugin that will allow you to do it.This list is the 15 most incredible WordPress plugins. Only the best plugins have made it while anything less than amazing has been kicked to the street.

Each of these plugins are used at Site Sketch 101 and I personally recommend each of them to you. The following plugins are posted in the order that I recommend them. To handle a blog these days can be quite difficult if you are not well-organized and you don’t spend enough time managing it. That’s why there are plugins for WordPress. They literally make your job lot easier and if you work well with them you can put them to work for you.

There are tons of plugins designed to do the job I’ve just mentioned and is pretty difficult to find the plugins you really need. That’s why, in today’s post I’ve selected some of the Powerful WordPress Plugins For Every Website.


All in One SEO Pack


This plugin is streamlined for some best practices for WordPress SEO. While it gives you many options the defaults reflect the settings I recommend using.

viernes, 14 de enero de 2011

Codigo Captcha con PHP


Un pequeño, corto y conciso tutorial de como agregar codigo Captcha a nuestros sitios, en 9lessons nos dan un buen ejemplo.


Flickr Like Edit Title


Debo decir que me encanto la foto del Guasón :P


Download Script Live Demo


Captcha.php


<?php
session_start();
$ranStr = md5(microtime());
$ranStr = substr($ranStr, 0, 6);
$_SESSION['cap_code'] = $ranStr;
$newImage = imagecreatefromjpeg("cap_bg.jpg");
$txtColor = imagecolorallocate($newImage, 00, 0);
imagestring($newImage, 555, $ranStr, $txtColor);
header("Content-type: image/jpeg");
imagejpeg($newImage);
?>


viernes, 7 de enero de 2011

Video Curso - Crear aplicaciones para Facebook

El negocio de desarrollo de aplicaciones para Facebook es uno de los más rentables del momento, y esta siendo explotado por muchos jóvenes al rededor del mundo cuyo único capital para empezar a ganar dinero fue el "Know How".

Si tu también quieres formar parte de este negocio que diariamente mueve millones de dolares, aquí les comparto un buen video-tutorial, creado porPolin, que te enseñara paso a paso a crear aplicaciones para Facebook.

jueves, 6 de enero de 2011

Release de AppKonference 1.6

En VentureVOIP nos comentan que ya esta lista la nueva release de la aplicación appkonference la cual según su autor trae los siguientes cambios:

* Deprecated input smoothing and output packing because packet size is fixed at 20 milliseconds so these functions are unnecessary.

* Added a compiler flag, CACHE_CONTROL_BLOCKS, for conference and member block reuse. To disable control block reuse edit the Makefile or clear it on the command line: make CACHE_CONTROL_BLOCKS=0.

* Changed the conference event privilege to user to reduce the number of events an application has to monitor to support a conference.

Si quieren probarlo lo pueden bajar de source forge: sourceforge.net/projects/appkonference

viernes, 3 de diciembre de 2010

Phono - Integracion Voip a nuestro Website

De vuela por estos rumbos pero siempre en el mundo de la voz ip :P un poco ajetreado con la empresa Voip Systems he dejado de lado lo que es el blog pero trataré de retomarlo de nuevo. Saludos a todos los visitantes y gracias por sus comentarios :)

Bueno empecemos con la carnita leyendo en Sinologic.net nos muestran un sitio que nos ayuda a integrar un boton click to call a nuestras webs.

Hace tiempo que tenía pendiente hablar sobre un servicio de la empresa Voxeo llamado phono.com y que permite integrar telefonía VoIP (pstn/sip) mediante código HTML y Javascript que, unido a un poco de Flash integrado de forma transparente por el servicio, nos permite crear click2call fácilmente en nuestras webs.

En la web de Saúl podéis leer un estupendo artículo con un ejemplo sobre cómo programar con JQuery y un poco de HTML un Click2Call para poder hacer una llamada sin necesidad de que el usuario tenga que poner su número de teléfono si no que pueda hablar desde la propia web como si estuviese conectado a un softphone. De hecho, aprovechando el artículo de Saúl, me he animado a comentarlo por aquí también.

Para que este servicio de Voxeo pueda funcionar, se requiere que el navegador sea compatible con Flash :( he de decir que lo he probado unas cuantas veces y con un resultado bastante satisfactorio, tanto en calidad de sonido como en usabilidad y es que el código que hay que añadir tan solo requiere de una conexión a Internet y tener acceso al sistema de Phono.com (si, por desgracia es dependiente de un servicio externo).

Para que veáis lo fácil que es, además de poder ver una demo en el artículo de Saúl

Fuente: http://www.sinologic.net/blog/2010-12/phono-com-te-ayuda-a-integrar-voip-con-tu-website/

sábado, 17 de abril de 2010

Cbt nuggets - Zend php5 certificacion

Hola esta vez les traigo un excelente video tutorial para la certificacion de php5 de zend, espero que les guste mucho recién los subí a 4shared.

Videos
26:00 Intro to PHP

29:20 PHP Language Basics

25:24 PHP and Forms

23:01 PHP Web Features

21:47 Strings and Regular expressions

33:29 Working with Arrays

27:29 Working with Databases

27:58 PHP Functions

23:35 Object-Oriented PHP

33:28 Handling Exceptions

23:54 Managing Files

24:51 Streams and Sockets

28:07 XML

27:04 Web Services

25:42 PHP Security




Descargar:


Mirror por 4shared 1 ilnk:

http://www.4shared.com/file/9VazN4hg/CNtsZendPHP5.htm

viernes, 19 de marzo de 2010

Tips para Programar en PHP (la funcion extract)

Bien pues puede que esta no sea la solucion a los problemas de todos los programadores del mundo, pero igual puede ser util para quien comienza a programar en este lenguaje, los lenguajes de script para desarrollo web, suelen tener muchas funciones que desconocemos y son de mucha utilidad, recientemente en una visita a puebla con un buen cuate, me toco ver como una persona a su cargo estaba realizando un formulario enorme y me refiero a enorme con mas de 40 campos en el dicho formulario, el objetivo era que ese formulario al ser procesado se enviara por correo a una cuenta determinada, hasta ese punto un tipico trabajo de una forma de contacto en internet, como para variar soy muy curioso (en ocasiones hasta metiche) en los asuntos de programacion, me toco ver que el formulario una vez enviado lo recibia un script de PHP y que lo que ellos estaban haciendo era incializar variables una por una desde el objeto $_POST para despues concatenarlas y pasarlas una funcion que enviara el mail, zaz me vinieron a la mente entre recuerdos de mis primeras clases de programacion y una obsesion que tengo con querer hacer las cosas mas simples pero a la vez faciles, despues de pegar el grito en el cielo por lo que estaban haciendo y preguntar si les podia dar un tip les dije que habia una manera de simplificar eso, de dibujar el formulario casi nadie se salva eso es inevitable pero de procesar las variables mas sencillo y usar un pequeño ciclo para concatenar era lo mas viable.
Primero les explique la susodicha funcion extract que segun la descripcion de la documentacion de PHP hace esto:
Descripción
void extract ( array $matriz_vars [, int $tipo_extraccion [, string $prefijo ]] )
Esta función se utiliza para importar variables desde una matriz a la tabla de símbolos actual. Toma la matriz asoiativa matriz_vars y trata las claves como nombres de variable y los valores como los valores de éstas. Para cada par clave/valor creará una variable en la tabla de símbolos actual, sujeto a los parámetros tipo_extraccion y prefijo .
Como vemos la definicion es algo mmmmmm…… indigerible pero si le buscamos un enfoque practico resulta sencilla veamos
Tenemos la situacion anteriormente descrita, en lugar de inicializar variables asi:

Se podria usar la funcion extract y resultaria mas facil:

Como ven la funcion extract toma el array $_POST donde vienen todos los valores del formulario y automaticamente las convierte y asigna sus valores a variables con el mismo nombre de las que venian del formulario, esto nos evita estar inicializando variables y perder tiempo valioso en la programacion, esta fue una de las utilidades que encontre en esta funcion y que en ese momento comparti con mi cuate.
Ademas como todo ejejej siempre hay muchos caminos para lograr el resultado final, me preguntaba y bueno que la concatenada de las variables no se podia hacer mas facil y le dije claro, solo que aqui en lugar de extract vamos a usar un pequeño truco con un bucle For Each, el resultado fue el siguiente:
$value){
$todaslasvariables.="$key - $value
";
}
echo $todaslasvariables;
?>
Que fue lo que paso aqui, sencillo tome el Array $_POST con todos sus valores y nombres, recorri con un ciclo en ocasiones poco explotado que es el Foreach y las concatene automaticamente en una sola variable, y listo ya teniamos una variable con todos los datos de campo y valor listos para ser enviados por correo.
Se que no es la quinta maravilla del mundo pero a como son utiles los tips cuando uno esta empezando a conocer un lenguaje, este se los comparto como en su momento un buen cuate y compañero lo hizo, el buen Omar Cobos desde su blog Pragmatic fue el que me dio a mi ese tip.
FUENTE: AQUÍ

Presentación: "Buenas Prácticas de Desarrollo en PHP"

Como en estos dias he vuelto a repasar algunos conceptos de PHP y formas nuevas de programación me puse a refrescar las buenas practicas de programación y encontre este artículo aquí, espero que les sea de utilidad

Hace un tiempo que vengo recomendando esta presentación como punto de partida para definir un estándar de desarrollo en una empresa. En ambientes Java no se discute quién define los estándares, es la empresa Sun y a nadie se le ocurriría inventar el suyo propio. Además, en el mundo Java existen estándares para todo, desde la codificación, forma de programar, etc.
LINK
php development best practices


En el lado opuesto del mundo estamos nosotros, los del "Mundo PHP", donde cada cual tiene su propio estándar y programa "como quiere" (con todos los problemas que esto acarrea). Para evitarlo, lo mejor que podemos hacer es seguir los lineamientos generales que se desprenden de los documentos de Zend.

Y esta es una buena presentación por donde empezar.

jueves, 18 de marzo de 2010

Creando Webs Modulares

En esta ocasión les traigo un excelente articulo que tome de ZonaPhp, el cual estoy seguro les ayudará a todos los que programamos, ya sea para enseñarnos o refrescarnos algunos conocimientos vitales a la hora de programar.

Después de embeber código PHP entre el HTML por un tiempo, cualquier principiante que esté en planes de dejar de serlo, ve cierto patrón que se repite y piensa... ¿No habrá otra manera mejor, más ordenada de hacer esto?. Pues si, si la hay. Y en este artículo aprenderemos una de estas maneras.

Lo habitual
Cuando aprendemos nuestros primeros pasos con PHP, cualquier tutorial o manual que leemos, nos enseña y vanagloria las bondades de poder incluir el código PHP directamente entre el HTML. Entonces, es muy habitual ver ejemplos del tipo:

PHP:



  1. <html>


  2. <head><title>Ejemplo de PHP embebido</title></head>


  3. <body>


  4. <?php


  5. echo "Este texto se hace con PHP";


  6. ?>


  7. </body>


  8. </html>



Y como la mente y el alma de un principiante de cualquier tema, está preparada para aprender todo lo que pueda, en el menor tiempo que pueda, toma este tipo de ejemplos como "verdades universales" y comenzamos a ver código PHP embebido entre el HTML por TODOS lados. Pero no hay que preocuparse, esto no es necesariamente malo, y todos lo hicimos en menor o mayor medida al comenzar. Es un paso necesario que hay que aprender a superar. :D

Luego de un tiempo, y después de haber leido un poco más, aprendemos que todas las partes comunes de código que son repetitivas, pueden residir en archivos separados y ser "Incluidas" en nuestro código con tan solo el uso de una función:



  1. <html>


  2. <head><title>Ejemplo de PHP embebido</title></head>


  3. <body>


  4. <? include('includes/header.php'); ?>


  5. <table>


  6. <tr>


  7. <td width="120"><? include('includes/menu.php'); ?></td>


  8. <td>Aqui va el contenido del sitio web propiamente dicho. Recordar que es terriblemente MALO y PERJUDICIAL para la salud de su sitio, utilizar archivos externos con extensión ".inc"</td>


  9. </tr>


  10. <? include('includes/footer.php'); ?>


  11. </table>


  12. </body>


  13. </html>



Entonces, ese es el momento en que include() se convierte en nuestro mejor amigo y descubrimos, fascinados, como podemos lograr una verdadera mejora en el mantenimiento de nuestros sitios, al tener que modificar 1 solo archivo y que este cambio, se vea reflejado en TODAS las páginas que incluyan ese archivo. Hemos, señoras y señores, alcanzado el Nirvana.

Pero, lamento decepcionarlos, ningún estado de felicidad suprema es permanente. Luego de un tiempo, y a medida que seguimos utilizando este método, de repente nos vamos dando cuenta que algo simplemente no cuadra. Si bien el anterior método del include() nos salvó en su debido momento, nos vamos dando cuenta que para crear una nueva página, es necesario repetir muchas veces los include() que llaman a las partes comunes de nuestro sitio. Esto sin contar que si, por arte de magia o capricho de un jefe/cliente, la cabecera de nuestro sitio pasa de ser header.php a cabecera.php, deberiamos modificar uno a uno todos los archivos que hagan un llamado a "header.php" y hacer el reemplazo.

Es en este punto, donde cientos de programadores, todos los años se hacen la misma pregunta: ¿No habrá una manera mejor de hacer esto?

Una Mejor Manera

Y si. Siempre existe una mejor manera de hacer las cosas. Y este caso no es la excepción.

Después de mucho pensar, y de mirar constantemente el código, una y mil veces, uno termina siempre preguntándose : ¿Y si hiciéramos las cosas al revés? ¿Qué pasaría si en vez de incluir todas las partes comunes de nuestro sitio (Header/Footer/etc), solamente incluyéramos el contenido?

Pero que buena pregunta! Veamos que sucedería.

La primera cuestión que nos llega a la mente, es que sería necesario indicarle a nuestro archivo.php, qué página queremos cargar. Veamos como podemos hacer esto :



  1. <?php


  2. // Leemos la variable que indica que página queremos cargar.


  3. if(empty($_GET['modulo']))


  4. $pagina='home.php';


  5. else


  6. $pagina=$_GET['modulo'];


  7. include('includes/header.php');


  8. include('modulos/'.$pagina);


  9. include('includes/footer.php');


  10. ?>



De esta manera, si llamáramos a este archivo index.php, para cargar algún "modulo" de nuestro sitio web, tan sólo deberíamos indicarlo en el URL, de esta manera : http://www.nuestrositio.com/index.php?modulo=foro.php.

Pero de este método se desprenden varias cuestiones, a saber:

  • Si un usuario "distraido" pusiera en la variable modulo un nombre de archivo inexistente, aparecería un mensaje de error (si PHP está configurado para mostrar errores, lo que es lo más común) indicando que el archivo no existe. Así que es necesario primero, identificar si el archivo que el usuario intenta acceder, existe.

  • Cuestiones de Diseño : Es muy posible, que no todos los "módulos" utilicen el mismo "diseño base" del sitio, o sea, que no siempre sea necesario mostrar la misma estructura, o el mismo sistema de navegación. Sería necesario de alguna manera, indicarle a nuestro sitio que "diseño base" utilizará cada módulo.

  • ÿltimo pero no menos importante, la Seguridad. Dejar al descubierto una variable que indica que archivo incluir, es una de las fallas de seguridad más serias que posee un sitio web. ¿Se imaginan que sucedería si un usuario, no ya tan "distraido" sino un poco más malicioso, llamara a nuestro sitio web de esta manera : http://www.nuestrositio.com/index.php?modulo=../../../../../etc/passwd ?
    Sirenas de Emergencia por todos lados !!! De esto se desprende que hay que encontrar una manera de controlar que la página que sea pedida, esté dentro de las opciones permitidas.


Vistas todas las desventajas de este primer acercamiento, veremos de que manera las podemos solucionar con un poco de ingenio y mucho PHP.

Modularizando nuestro sitio

Teniendo las consideraciones de seguridad y diseño en cuenta, vamos a desarrollar un sistema que nos permita modularizar nuestro sitio, manteniendo cierta flexibilidad para poder indicar que Diseño ( o Layout, como lo llamaremos en el código ) utilizarán nuestros módulos. Además, mantendremos un listado de todas las páginas que pueden ser invocadas, de manera que evitaremos que cualquier archivo de los que el Webserver tenga acceso de lectura, pueden terminar "sin querer" en el navegador de nuestro visitante.

Este listado podriamos guardarlo de diferentes maneras : archivos de texto con algún formato estandar o propio, en una Base de Datos, en un archivo XML (como es costumbre en algunas aplicaciones más complejas) o con tipos de datos propios del PHP (en este caso, arreglos). "Yo escogo este último porque me place, vosotros podéis escoger el tipo que queráis" (los fanáticos de Cha-Cha-Cha estarán esbozando una sonrisa). Y justifico mi decisión:

  • No tengo personalmente nada en contra de los archivos de texto plano, pero parsear los contenidos de uno, con el tipo de formato que sea, incluye cierta lógica de programación extra innecesaria, ya que la idea es hacer las cosas lo más sencillas posibles y no al revés.

  • Una base de datos definitivamente haría más sencillas las cosas, pero limitaría la utilidad de este método a aquellos servidores que no posean bases de datos. Se que los servidores que no poseen bases de datos hoy por hoy son escasos, pero prefiero no basarme en esa solución para hacer la aplicación lo más compatible posible.

  • Muchos ven en el formato XML al "santo grial" de las soluciones para almacenar datos o utilizarlos como sistemas de configuración. Y posiblemente para aplicaciones de escritorio esto no sea tan errado, ya que el archivo XML se parsea una vez y luego se mantienen sus datos en memoria durante toda la "vida" del programa. Pero en un ambiente web, sería necesario no solo que el PHP tenga activada alguna de las opciones para trabajar con XML, sino que se tendría que parsear el archivo XML ( con el gasto de recursos que esto conlleva ) una vez POR CADA pedido de página que se le hiciera el servidor. Definitivamente, NO. Aparte, es un tutorial para principiantes, asi que vamos a hacer las cosas sencillas.


Así es que para nuestro sistema de configuración, vamos a utilizar los viejos y queridos arreglos asociativos de PHP. El siguiente es un ejemplo básico para un sitio web realmente pequeño, pero ya veremos de extenderlo a medida que nuestro ejemplo "evolucione".

conf.php



  1. <?php


  2. /*


  3. * Archivo de configuración para nuestra aplicación modularizada.


  4. * Definimos valores por defecto y datos para cada uno de nuestros módulos.


  5. */


  6. define('MODULO_DEFECTO', 'home');


  7. define('LAYOUT_DEFECTO', 'layout_simple.php');


  8. define('MODULO_PATH', realpath('./modulos/'));


  9. define('LAYOUT_PATH', realpath('./layouts/'));


  10. $conf['home'] = array(


  11. 'archivo' => 'home.php',


  12. 'layout' => LAYOUT_DEFECTO );


  13. $conf['articulo'] = array(


  14. 'archivo' => 'art.php' );


  15. ?>



Aqui vemos, como en la primera parte de nuestro archivo, definimos algunas constantes que nos van a servir: MODULO_DEFECTO, indicando cuál de los módulos cargar si no se indicó ninguno, LAYOUT_DEFECTO que indica que "diseño" se utilizará por defecto en los módulos, MODULO_PATH y LAYOUT_PATH, indicando directorios en los cuales vamos a almacenar nuestros módulos y layouts. En el ejemplo, quedarán en dos directorios separados, pero podrían ser el mismo sin problema.

Aqui vemos, que tenemos dos "módulos" en nuestra aplicación; "home" y"articulo". Estos nombres de índices, son los que le vamos a pasar a nuestra variable modulo, indicando a que sección de nuestro sitio queremos acceder.

Como vemos, cada "sección" contiene ( o deberia indicar ) dos directivas:"archivo""layout". El primer valor es el nombre del archivo que efectivamente vamos a incluir, asociado con el nombre del indice del arreglo. Esto soluciona en gran parte el problema de seguridad que nombramos anteriormente, ya que no se indica directamente el nombre del archivo a incluir, sino que se indica a través de un nombre ficticio, un alias.

El segundo valor, layout, es el nombre del archivo que contiene el diseño "base" de la aplicación. Aqui tenemos dos opciones, indicar en el archivo de configuración el nombre del archivo de layout, o expresar, mediante la constante definida antes, que cierto módulo utiliza el layout por defecto ( esto ayuda a la claridad luego cuando se quiera revisar el archivo de configuración y se aconseja ). Como podemos ver en el módulo "articulo", en este caso no se indica ningun archivo de layout. Esto nosotros lo tomaremos como que al no indicarse, se desea utilizar el layout por defecto (Esta es una opción realmente buena para los programadores holgazanes como yo, que no quieren escribir grandes archivos de configuración).

Programando las bases

Ya tenemos listo nuestro archivo de configuración, que servirá como columna vertebral de nuestra nueva aplicación modularizable. Ahora veremos como lo utilizamos. Pero primero, veamos un poco como organizaremos nuestro árbol de directorios en nuestra nueva aplicación, para tener todo bien ordenado.

  • includes/

  • layouts/

  • modulos/

  • index.php


Así, vemos como tendremos un directorio para nuestros includes, uno para los módulos que componen nuestra aplicación y otro para los distintos layouts. Recordemos que ahora, nuestro archivo index.php será el único punto de entrada para nuestro sitio. Esto representa una ventaja ya que podemos colocar alli todas las tareas repetitivas (inicialización de variables, conexión a una base de datos, lectura de otros archivos de funciones o configuración, etc.). Otra de las ventajas es que ante 1 cambio que afectaría a todo el sitio web, solo hay que realizarlo en 1 solo archivo, solucionando alguno de los problemas que la metodología de varios archivos incluyendo partes comunes acarreaba.

Nuestro archivo index.php comienza de esta manera

index.php



  1. <?php


  2. // Primero incluimos el archivo de configuración


  3. include('conf.php');


  4. /** Verificamos que se haya escogido un modulo, sino


  5. * tomamos el valor por defecto de la configuración.


  6. * También debemos verificar que el valor que nos


  7. * pasaron, corresponde a un modulo que existe.


  8. */


  9. if (!empty($_GET['mod']))


  10. $modulo = $_GET['mod'];


  11. else


  12. $modulo = MODULO_DEFECTO;


  13. /** También debemos verificar que el valor que nos


  14. * pasaron, corresponde a un modulo que existe, caso


  15. * contrario, cargamos el modulo por defecto


  16. */


  17. if (empty($conf[$modulo]))


  18. $modulo = MODULO_DEFECTO;


  19. /** Ahora determinamos que archivo de Layout tendrá


  20. * este módulo, si no tiene ninguno asignado, utilizamos


  21. * el que viene por defecto


  22. */


  23. if (empty($conf[$modulo]['layout']))


  24. $conf[$modulo]['layout'] = LAYOUT_DEFECTO;


  25. ?>



Como bien explican los comentarios, lo que hacemos primero es incluir el archivo de configuración, sin él no podríamos saber si un módulo está permitido o no, y que Layouts utilizar. Luego, validamos que la variable "mod" contenga algo. De estar vacía o con un nombre de algún módulo inexistente (segundo if()), entonces hacemos que cargue el módulo por defecto, que está indicado en la constante MODULO_DEFECTO. Lo mismo hacemos para el Layout a cargar, si no está indicado en el archivo de configuración, tomamos por defecto el valor contenido en LAYOUT_DEFECTO. Continuamos con nuestro index.php

index.php



  1. <?php


  2. /** Aqui podemos colocar todos los comandos necesarios para


  3. * realizar las tareas que se deben repetir en cada recarga


  4. * del index.php - En el ejemplo, conexión a la base de datos.


  5. *


  6. * include('clases/class.DB.php');


  7. * $db = new DB();


  8. * $db->conectar();


  9. */


  10. /** Finalmente, cargamos el archivo de Layout que a su vez, se


  11. * encargará de incluir al módulo propiamente dicho. si el archivo


  12. * no existiera, cargamos directamente el módulo. También es un


  13. * buen lugar para incluir Headers y Footers comunes.


  14. */


  15. $path_layout = LAYOUT_PATH.'/'.$conf[$modulo]['layout'];


  16. $path_modulo = MODULO_PATH.'/'.$conf[$modulo]['archivo'];


  17. if (file_exists($path_layout))


  18. include( $path_layout );


  19. else


  20. if (file_exists( $path_modulo ))


  21. include( $path_modulo );


  22. else


  23. die('Error al cargar el módulo <b>'.$modulo.'</b>. No existe el archivo <b>'.$conf[$modulo]['archivo'].'</b>');


  24. ?>



Aqui vemos algo que comentábamos antes. Encerrado en comentarios, hay cierto código que podemos incluir en nuestro index.php que, al ser ahora el único punto de entrada a todas las páginas de nuestro sitio, será ejecutado para cada página. Ya no hay que repetirlo en todas las páginas PHP, tan solo se coloca en el index.php. Esto es bueno, porque mientras menos repetición de código haya, más sencillo de mantener es todo. Vemos alli como ejemplo, el código para incluir e instanciar algún objeto de conexión a base de datos, pero podría ser cualquier otro código que necesitemos ejecutar cada vez que se vea una página, como por ejemplo, algún Validador de Usuarios registrados o el código necesario para dar seguimiento a las sesiones de Usuario.

Finalmente, nuestro archivo verifica que el archivo de Layout que se quiere incluir, exista primero. De existir, entonces se incluye y ya veremos en un ejemplo, como nuestro archivo Layout debe incluir luego, al archivo del módulo. Si no existiera el archivo de Layout, se intenta incluir directamente el archivo del módulo que se pidió, sin Layout, y si éste archivo tampoco existiera ( ¿demasiadas cosas que salen mal, no? ) entonces se muestra un error en la pantalla, indicando el nombre del módulo y el archivo que no se pudo hallar.

Perfecto, ya tenemos todo listo para cargar los módulos que necesitemos. Ahora, veamos como será un módulo de ejemplo y su archivo de Layut.

Tenemos dos opciones a la hora de crear un archivo de layout. Son las siguientes:

  • Incluir Headers y Footers comunes a todas las páginas dentro del index.php, ANTES y DESPUES de incluir el archivo de Layout, en el que dejaremos solo el diseño propio de la página para que albergue al módulo. Esto es útil en el caso de que un archivo de Layout no se encuentre o no sea necesario, y al incluir el Módulo, ya esté cargado el Header y luego sea incluido el Footer.

  • Hacer que el archivo de Layout, aparte de incluir el archivo del Módulo, sea el encargado de incluir Headers y Footers, lo cuál puede ser útil si el diseño general de varias secciones del sitio cambia drásticamente, como distintas subsecciones con Headers y Footers diferentes, o en el caso de "Versiones para Imprimir" o la creación de versiones en PDF de ciertos artículos.


Yo voy a elegir en este caso la segunda opción. Haré que el archivo de Layout'layout_simple.php' (el Layout por defecto, según el archivo dFe configuración) sea el encargado de incluir los archivos que hacen de Header y ooter en la aplicación. Esto es preferible a la primera opción ya que si, por ejemplo, queremos que un módulo específico de nuestra aplicación, devuelva un archivo .GIF como resultado ( utilizando GD ), entonces de esta manera, podremos indicar para ESE módulo, un archivo de Layout que se encargue de enviar los Headers correctos y luego incluir el archivo del módulo. Pero no se preocupen por estas consideraciones, ahora, veamos un ejemplo de Layout, que guardaremos en el directorio /layouts:

layout_simple.php



  1. <html>


  2. <head>


  3. <title>Tu Sitio Modular</title>


  4. </head>


  5. <body bgcolor="#9999cc">


  6. <basefont color="white" face="Verdana" />


  7. <?php include('includes/header.html'); ?>


  8. <table width="100%" border="0" cellspacing="1"cellpadding="1">


  9. <tr>


  10. <td width="140" bgcolor="#5b69a6"> </td>


  11. <td>


  12. <?


  13. if (file_exists( $path_modulo )) include($path_modulo );


  14. else die('Error al cargar el módulo <b>'.$modulo.'. No


  15. existe el archivo <b>'.$conf[$modulo]['archivo'].'</b>');


  16. ?>


  17. </td>


  18. </tr>


  19. </table>


  20. <?php include('includes/footer.html'); ?>


  21. </body>


  22. </html>



Ven? es un simple archivo HTML con la estructura básica de las páginas de nuestro sitio, incluyendo el Header, el Footer y el código necesario para llamar al módulo pedido por el usuario. Por favor noten el uso de la variable$path_modulo, para indicarle al Layout el nombre del módulo que queremos cargar, variable creada en el index.php y propagada al archivo de Layout por estar éste, incluido en el primero.

Entonces, ya tenemos nuestro index.php, tenemos el Layout que se encarga de incluir el módulo... ¿Qué nos falta? ¡Pues el módulo! ÿstos pueden ser tan complejos o tan simples como el usuario quiera. En el ejemplo siguiente, un módulo "home" bien simple, que se carga por defecto en nuestra aplicación :

home.php



  1. <h3>Bienvenido al Home</h3>


  2. <p>Este es un ejemplo de un sitio modular, como vemos, las páginas que


  3. componen los módulos, pueden ser tanto archivos.php como archivos.html,


  4. todo dependiendo de si necesitamos interactividad o no con el Servidor.


  5. La hora actual es : <b><?=date("H:m:s");?></b></p>


  6. <p>Para ver el contenido de un artículo, por favor, seguir el


  7. <a href="?mod=articulo">siguiente link</a>.</p>



De nuevo, un poco de HTML por aquí, un poco de PHP por allá. Cabe notar, eso si, la manera en la que hicimos un link hacia OTRA página de nuestro sitio: "?mod=articulo". Con esto, le indicamos al navegador, que queremos cargar el mismo archivo que tenemos actualmente, solo que con este nuevo "querystring". Si la página actual fuera algo como:

http://localhost/modulares/index.php

Indicando un link como recién, al hacerle click cambiaría a :

http://localhost/modulares/index.php?mod=articulo

O sea, queremos cargar OTRO módulo, esta vez llamado "articulo". Como ya todo el trabajo árduo está hecho, solo tenemos que crear un archivo llamadoart.php (ya que así lo indica el archivo de configuración) en el directorio/modulos/.

art.php



  1. <h3>Título del Artículo</h3>


  2. <p>Aqui tenemos el ejemplo de un artículo cargado en nuestra Web Modularizada.


  3. En este ejemplo simple, el artículo o nota, está escrito en HTML directamente,


  4. pero podría estar siendo sacado de la base de datos si quisiéramos, no tenemos


  5. limitación al respecto.</p>


  6. <p><a href="?mod=imp_art" target="_blank">Versión para Imprimir</a> |


  7. <a href="?mod=home">Volver al Home</a>.</p>



Así vemos, como crear un nuevo módulo es tan sencillo como crear el archivo pertinente, dejarlo en el directorios de Módulos, y actualizar el archivo de configuración para que permita accederlo. ÿste módulo, al no indicarse que Layout utiliza, vemos como toma el Layout por Defecto, o sea, el mismo que el Home. Cómo último paso, al final del artículo, tenemos dos links, uno, que nos regresa al Home del Sitio y el otro, el que nos interesa ahora, que ofrece una "Versión para Imprimir" del artículo. Modifiquemos nuestro archivo de configuración y agreguemos un nuevo módulo, que nos permita ofrecer una versión "Imprimible" del Artículo. Luego de editarlo, quedaría asi :

conf.php



  1. <?php


  2. /*


  3. * Archivo de configuración para nuestra aplicación modularizada.


  4. * Definimos valores por defecto y datos para cada uno de nuestros módulos.


  5. */


  6. define('MODULO_DEFECTO', 'home');


  7. define('LAYOUT_DEFECTO', 'layout_simple.php');


  8. define('MODULO_PATH', realpath('./modulos/'));


  9. define('LAYOUT_PATH', realpath('./layouts/'));


  10. $conf['home'] = array(


  11. 'archivo' => 'home.php',


  12. 'layout' => LAYOUT_DEFECTO );


  13. $conf['articulo'] = array(


  14. 'archivo' => 'art.php' );


  15. $conf['imp_art'] = array(


  16. 'archivo' => $conf['articulo']['archivo'],


  17. 'layout' => 'imprimir.php' );


  18. ?>



¿Llamamos al mismo módulo? Así es. Pero la sutil diferencia es que lo incluimos con un Layout distinto, más limpio, apto para salir por impresora. Aqui un ejemplo de este Layout, que utiliza Cascading Style Sheets :

imprimir.php



  1. <?


  2. $uri ="http://".$_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];


  3. ?>


  4. <html>


  5. <head>


  6. <title>Versión para Imprimir</title>


  7. </head>


  8. <style type="text/css">


  9. .imprimir {


  10. margin: 3%;


  11. border: 2px solid black;


  12. padding: 2%;


  13. }


  14. #pie {


  15. font-size: 8pt;


  16. }


  17. </style>


  18. <body>


  19. <div class="imprimir">


  20. <?


  21. if (file_exists( $path_modulo )) include($path_modulo );


  22. else die('Error al cargar el módulo <b>'.$modulo.'. No existe el archivo <b>'.$conf[$modulo]['archivo'].'</b>');


  23. ?>


  24. <i id="pie">Este artículo se puede encontrar en : <a href="<?=$uri?>"><?=$uri?></a></i>


  25. </div>


  26. </body>


  27. </html>



Finalizando

Ya finalizando con este artículo, logramos tener una aplicación web que posee la capacidad de cargar distintos módulos y diseños dependiendo de los parámetros recibidos. Esto se parece mucho a un Patrón de Diseño llamadoFront Controller. Para los curiosos, ahi tienen dos links en los que Google les puede enseñar un par de cositas.

Hoy aprendimos como centralizar el funcionamiento de un sitio a través de un archivo de configuración. También como modularizar nuestro sitio web con la ventaja de poder aplicar distintos diseños a los diferentes módulos que lo componen. Y sobre todo, a hacerlo de una manera sencilla, eficiente y segura. ¿Qué más se puede pedir?

Bueno, un montón de cosas, estas son las que se me ocurren en este momento. Estoy seguro que a Uds. se les ocurrirán muchas más :

  • Podríamos incluir en el Layout por Defecto, un menú de opciones en la celda izquierda, de manera de facilitar la navegación del sitio.

  • Una modificación interesante, sería que al pedir un usuario, un módulo inexistente en el arch. de configuración, se cargara un módulo determinado ( y no el “home” ) indicando el error y mostrando una página “símil” ERROR 404.

  • Se podría agregar en el arch. de configuración, un dato más para cada módulo, que indique el título de la página. Y que el Layout se encargue de utilizar ese valor dentro del tag .

  • Recomendable sería que tanto los directorios de Layouts, Includes y Modulos, no estén disponibles en el mismo nivel que el Directorio DocumentRoot del WebServer, ya que de esa manera, por quien conozca el árbol de directorios, podría ejecutar los archivos llamándolos directamente. Para evitar esto, podemos tanto mover los directorios un nivel hacia arriba y modificar el archivo de configuración para que encuentre estos directorios ( y como vemos, no tendriamos que tocar nada en el código de la aplicación ) o bien utilizar algún método para proteger esos directorios por contraseña, como puede ser un archivo .htaccess de Apache.

  • Tener un solo punto de entrada en nuestro sitio web, implica el paso de varios parámetros a un solo archivo de nuestro sitio. Lo que hace que nuestras chances de ser indexados por un buscador tipo Google se vean reducidas. Pero para esto hay varias soluciones, y bien lo explica nuestro amigo Nok en Optimizando las URLs para las búsquedas.


Para los poco pacientes ( y para el resto también ) que no quieran estar copiando y pegando el contenido de estos ejemplos en los archivos, aqui les dejo un archivo ZIP con todos los archivos del artículo. Recuerden, no es código apto para producción, si quieren utilizarlo directamente en sus sitios Web, lo hacen bajo su propia responsabilidad. ¡No digan que no les avisé! ;)

Esto ha sido todo por este momento, espero que lo que hayan leido en este artículo les sea deutilidad en sus sitios web y les ayude a programar menos y más rápidamente

En lo personal me gusto mucho el artículo, además trataré de colgar mas artículos con respecto a lo que es programación estandares y más. Una vez más mis agradecimientos a zona PHP.