Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
www.desarrolloweb.com
Calendario PHP
Aplicacin prctica de PHP en la que construimos un calendario que muestra el mes y ao actual
y permite moverse a otro mes y ao.
Director de DesarrolloWeb.com
http://www.desarrolloweb.com
(13 captulos)
Hctor A. Pinto F
Tomas Isasia
Parte 1:
Todos los archivos fuente del calendario se pueden descargar desde este enlace. Nos servirn para ponerlo en marcha en
nuestro propio servidor y utilizarlo para otras aplicaciones que lo requieran. En el archivo de la descarga encontraris varias
versiones del calendario, puesto que se han hecho varias modificaciones, tal como podris ver en el Manual del Calendario.
1.1.2.- Referencias
Para entender este ejercicio es fundamental que el lector tenga conocimientos sobre diversas reas del desarrollo de pginas
web. En DesarrolloWeb.com podemos aprender todo lo que nos hace falta. Aqu tenemos los enlaces:
Seccin sobre PHP. Con manuales y talleres que cubren los aspectos ms importantes aspectos del lenguaje.
Manual de CSS. Para el que desee aprender el manejo de las hojas de estilo.
Nota: Si lo deseamos, podemos acceder a un calendario con Javascript. Sera otra forma de realizar un calendario sin utilizar PHP
Para acabar, dejamos un enlace para ver el calendario en funcionamiento. Y os encaminamos al siguiente artculo, donde
veremos el archivo ndice del calendario.
Artculo por
Para empezar nos fijamos que en la cabecera, concretamente en la etiqueta <link> se incluye el archivo estilo.css como una
declaracin de archivos externa. No vamos a comentar aqu ni la hoja de estilos, que se puede descargar junto con los
archivos del calendario, ni la sintaxis y el modo de funcionamiento de las CSS, que se pueden aprender en el Manual de
Hojas de Estilo en Cascada.
Luego, ya en el cuerpo de la pgina, tenemos el cdigo PHP que se encarga de hacer el clculo de la fecha a mostrar y
muestra el calendario y el formulario.
Lo primero, se incluye, con la funcin require() de PHP, la librera calendario, que suponemos que est en el mismo
directorio que el archivo ndice.
Nota: Require es una funcin que sirve para incrustar dentro de un archivo PHP el texto o cdigo de otro archivo. Al incrustar nuestra
librera de funciones dentro del script index.php tenemos perfectamente disponibles todas las funciones de calendario.php.
Luego, con el if que se puede ver a continuacin, se comprueba si ha venido algo por POST o por GET.
En caso de que no venga nada por POST ni GET se obtiene el instante actual con un Timestamp Unix y lo
utilizamos para extraer el mes y el ao con la funcin date().
En caso de que recibamos por POST o GET algn dato inicializamos las variables mes y ao a lo que se est
recibiendo.
Para finalizar, se hace la llamada a la funcin mostrar_calendario() pasndole los valores del mes y ao que se desean
visualizar. Esto mostrara el calendario.
Nota: Puedes aprender ms sobre cmo se pasan variables por el formulario y por la URL en PHP.
Adems, hacemos una llamada a la funcin formularioCalendario(), tambin pasndole los valores del mes y ao, para que
presente en pantalla el formulario que nos permitir pasar de una fecha a otra.
Puedes ver el calendario en funcionamiento y pasar a la continuacin de estas explicaciones, donde comenzaremos a tratar la
funcin que hemos hecho para mostrar el calendario de un mes cualquiera.
Artculo por
Este ejemplo presenta una ligera complejidad, aunque esperamos que con nuestras explicaciones podis entender cmo
hemos resuelto el problema.
Escribo la cabecera de la tabla, indicando el mes y el ao que vamos a imprimir en la pgina. Para empezar utilizamos una
funcin que devuelve el nombre de un mes en castellano. Es muy fcil de construir y podemos verla en otro captulo ms
adelante.
Seguimos por colocar un poco de cdigo HTML, sin ms importancia. Luego calculamos el mes y ao anterior para
colocarlo en el enlace que habamos comentado con las flechita hacia atrs. El cdigo que inserta el enlace ser puede ver en
la siguiente lnea. Su atributo href tiene el valor index.php?nuevo_mes=$mes_anterior&nuevo_ano=$ano_anterior, donde
podemos observar que efectivamente se llama a index.php pasando los valores del mes y ao a mostrar.
Luego imprimimos en la pgina el valor del mes y ao y en las siguientes lneas podemos ver cmo se obtiene el mes y ao
siguientes para hacer la correspondiente flechita-enlace, de manera similar a como se hizo anteriormente.
//fila con todos los das de la semana
echo '
<tr>
<td width="14%" class="diasemana"><span>L</span></td>
<td width="14%" class="diasemana"><span>M</span></td>
<td width="14%" class="diasemana"><span>X</span></td>
<td width="14%" class="diasemana"><span>J</span></td>
<td width="14%" class="diasemana"><span>V</span></td>
<td width="14%" class="diasemana"><span>S</span></td>
<td width="14%" class="diasemana"><span>D</span></td>
</tr>';
Este trozo de cdigo sirve para escribir la siguiente fila de la tabla, con las iniciales de los das de la semana, desde el lunes al
domingo.
En el siguiente artculo continuaremos viendo la funcin que escribe el calendario.
Artculo por
Ahora tenemos toda la informacin necesaria para escribir la primera fila de das en el calendario. Recordar que varias de las
casillas de esta fila deben aparecer vacas porque el mes no tiene por qu empezar en lunes.
//escribo la primera fila de la semana
echo "<tr>";
for ($i=0;$i<7;$i++){
if ($i < $numero_dia){
//si el dia de la semana i es menor que el numero del primer dia de la semana no pongo nada en
la celda
echo '<td class="diainvalido"><span></span></td>';
} else {
echo '<td class="diavalido"><span>' . $dia_actual . '</span></td>';
$dia_actual++;
}
}
echo "</tr>";
Vemos que no encierra ningn misterio, simplemente hacemos un bucle que se repetir 7 veces, tantas como das de la
semana. Dentro del bucle comprobamos si el da de la semana actual es menor que $numero_dia, donde guardbamos el
nmero de la semana del primer da del mes.
Si no hay que escribir el da simplemente se coloca la celda vaca y si tengo que escribirlo se coloca el da actual en la celda y
se incrementa en uno dicho da actual.
Para continuar, debemos escribir en el calendario todos los dems das del mes, continuando por donde lo hubisemos
dejado. Para ello utilizamos un simple bucle que recorre esos das mientras que no lleguemos al ltimo da del mes.
//recorro todos los dems das hasta el final del mes
$numero_dia = 0;
while ($dia_actual <= $ultimo_dia){
//si estamos a principio de la semana escribo el <TR>
if ($numero_dia == 0)
echo "<tr>";
echo '<td class="diavalido"><span>' . $dia_actual . '</span></td>';
$dia_actual++;
$numero_dia++;
//si es el utimo de la semana, me pongo al principio de la semana y escribo el </tr>
if ($numero_dia == 7){
$numero_dia = 0;
echo "</tr>";
La nica complejidad que puede tener este trozo de cdigo es saber cundo debemos escribir el principio y el final de la fila,
con sus correspondientes <tr> y </tr>. Para llo, vamos a llevar la cuenta, con $numero_dia, del da de la semana que
estamos imprimiendo.
Si estamos al principio de la semana ($numero_dia = 0) entonces escribo el inicio de fila con <tr>; Si estamos al final de la
fila ($numero_dia = 7) entonces pongo el final de la fila con </tr>.
Entre medias de cada iteracin se incrementa el $da_actual (que lleva la cuenta de todos los das del mes) y el $numero_da
(que indicbamos que serva para saber en qu parte de la fila estamos).
Las ltimas lneas de cdigo de la funcin las vemos ahora.
//compruebo que celdas me faltan por escribir vacias de la ltima semana del mes
for ($i=$numero_dia;$i<7;$i++){
echo '<td class="diainvalido"><span></span></td>';
}
echo "</tr>";
echo "</table>";
Simplemente escribo celdas vacas para las ltimas casillas de la semana que acaba el mes donde no quedan das. Igual que al
principio del calendario el primer da no tena que estar en la primera casilla, el ltimo da del calendario no tiene porque
estar en la ltima casilla disponible.
echo "</tr>";
echo "</table>";
En el prximo artculo veremos la funcin que muestra el formulario para seleccionar otro mes y ao en el calendario. Si lo
deseamos, podemos Ver el calendario en funcionamiento.
Artculo por
Con esto imprimimos por pantalla la cabecera de la tabla donde vamos a alojar el formulario y la cabecera del propio
formulario. Nos fijamos que el atributo action del formulario lo tenemos dirigido hacia el archivo ndice.
echo '
<td align="center" valign="top">
Mes: <br>
<select name=nuevo_mes>
<option value="1"';
if ($mes==1)
echo "selected";
echo'>Enero</option>
<option value="2" ';
if ($mes==2)
echo "selected";
echo'>Febrero</option>
<option value="3" ';
if ($mes==3)
echo "selected";
echo'>Marzo</option>
<option value="4" ';
if ($mes==4)
echo "selected";
echo '>Abril</option>
<option value="5" ';
if ($mes==5)
echo "selected";
echo '>Mayo</option>
<option value="6" ';
if ($mes==6)
echo "selected";
echo '>Junio</option>
<option value="7" ';
if ($mes==7)
echo "selected";
echo '>Julio</option>
<option value="8" ';
if ($mes==8)
echo "selected";
echo '>Agosto</option>
<option value="9" ';
10
Estas lneas de cdigo sirven para escribir el <select> correspondiente al mes. Lo nico que lo hace complicado es
precisamente el hecho de que tenemos que comprobar si el mes que se va a imprimir es el mes que est mostrando el
calendario, pues en ese caso deberamos marcar como selected el <option> correspondiente. Esto se hace con los sucesivos
if que hay insertados entre cada etiqueta <option>.
echo '
<td align="center" valign="top">
Ao: <br>
<select name=nuevo_ano>
';
//este bucle se podra hacer dependiendo del nmero de ao que se quiera mostrar
//yo voy a mostar 10 aos atrs y 10 adelante de la fecha mostrada en el calendario
for ($anoactual=$ano-10; $anoactual<=$ano+10; $anoactual++){
echo '<option value="' . $anoactual . '" ';
if ($ano==$anoactual) {
echo "selected";
}
echo '>' . $anoactual . '</option>';
}
echo '</select>
</td>';
De manera parecida a como se ha realizado para los meses, se escribe tambin el ao, comprobando en cada ocasin si el
ao que se va a escribir corresponde con el del calendario. En este ejemplo ponemos aos desde el 2000 al 2004, cualquiera
de vosotros puede introducir ms o menos aos con pocos cambios.
echo '
</tr>
<tr>
<td colspan="2" align="center"><input type="Submit" value="[ IR A ESE MES ]"></td>
</tr>
</table><br>
<br>
</form>';
Para acabar mostramos el botn de submit del formulario y las etiquetas de cierre de tabla y formulario.
11
12
Si lo deseas, puedes ver el calendario en funcionamiento. En el captulo siguiente veremos otras funciones importantes de
esta librera PHP de calendario.
Artculo por
Primero obtenemos el nmero de da de la semana que nos ofrece PHP a travs de la funcin date(). Como PHP, al igual
que la mayora de los sistemas, est pensado en ingls, y para l, el numero de la semana correspondiente a domingo es el 0,
el del lunes es el 1. Por eso tenemos unas lneas de cdigo para convertir el nmero de la semana del "ingls al espaol".
13
Para hallar ese dato vamos a utilizar una pequea treta que consiste en suponer que el mes tiene 28 das como mnimo y
empezar a validar cada uno de los das siguientes hasta que la fecha que estamos construyendo sea incorrecta. En ese caso
querr decir que el nmero de das es 1 menos que los que tenemos en el momento de fallar la fecha.
Por poner un ejemplo, para enero, empezaramos por 28. Entonces validamos el da siguiente (29). Como es correcta la
fecha "29 de enero de una ao cualquiera", acumulamos 1 en la variable $ultimo_dia para situarnos en esa fecha vlida.
Posteriormente, validamos el 30 de enero, que tambin es correcta, entonces volvemos a acumular 1 en la variable para
situarnos en esa nueva fecha correcta... as hasta que intentemos validar la fecha "32 de enero" que ser la primera que falle.
Entonces paramos el bucle y dejamos de acumular a la fecha que tenamos, que era vlida. Esto funciona bien para cualquier
mes, incluso para febrero, sea el ao bisiesto o no.
Con esto hemos acabado el ejercicio del calendario PHP. Aunque seguro que habr hecho falta un esfuerzo por vuestra
parte, esperamos que las explicaciones hayan sido suficientes y podis entenderlo bien.
14
Artculo por
Parte 2:
Ampliacin de
funcionalidad en el
calendario PHP
Una vez que tenemos la base con la que podemos mostrar cualquier calendario de
cualquier mes, vamos a realizar algunas modificaciones encaminadas a mejorar las
funcionalidades del calendario. Especficamente veremos cosas como colorear das
festivos, usar el calendario para seleccionar una fecha dada, etc.
15
Ahora, para el que lo necesite, puede descargar los archivos del calendario modificado, para utilizarlo libremente es sus
creaciones.
Artculo por
No es necesario hacer un ciclo repetitivo para la funcin UltimoDia(), es un poco ms simple de resolver.
Los meses 1,3,5,7,8,10,12 siempre tienen 31 das, los meses 4,6,9,11 siempre tienen 30 das, el nico problema es el mes de
febrero dependiendo del ao puede tener 28 o 29 das, pero ese clculo tampoco es dificil.
Aqu envo el cdigo para la funcin UltimoDa(), que ojal les sirva...
Nota: Por favor, leer los comentarios que han enviado otros visitantes de DesarrolloWeb.com que proponen cdigos para hacer esta misma
funcionalidad pero de una manera muchsimo ms elegante, corta, sencilla y sin posibilidad de errores. Gracias a todas las personas que han
comentado y aportado algo ms a este artculo!!!!!
function UltimoDia($anho,$mes){
if (((fmod($anho,4)==0) and (fmod($anho,100)!=0)) or (fmod($anho,400)==0)) {
$dias_febrero = 29;
} else {
$dias_febrero = 28;
}
switch($mes) {
case 01: return 31; break;
16
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
return
return
return
return
return
return
return
return
return
return
return
$dias_febrero; break;
31; break;
30; break;
31; break;
30; break;
31; break;
31; break;
30; break;
31; break;
30; break;
31; break;
Artculo por
Hctor A. Pinto F
El campo de texto debe colocarse dentro de un formulario. Debemos nombrar tanto el formulario como el campo de texto
para luego poder acceder a ellos a partir de la ventana del calendario utilizando Javascript.
Al lado del campo de texto colocaremos tambin un botn para abrir el la ventana del calendario. Por comodidad, el botn
llamar a una funcin Javascript y esta ser la encargada de abrir el calendario en una ventana secundaria.
Artculo por
17
Otro detalle menos relevante para este ejercicio pero importante para no liarse con el cdigo Javascript es que la ventana del
calendario puede o no estar abierta cuando se pulsa el botn. En nuestro caso, si se detecta que est abierta, se ordena
cerrarse y luego se vuelve a abrir. As nos aseguramos que la ventana se queda siempre abierta en el mes actual y siempre
visible, al abrirse por encima de la ventana donde estaba el formulario.
En nuestro ejemplo vamos a colocar la funcin en un archivo a parte llamado javascripts.js, que incluiremos desde la
cabecera del documento HTML que pretenda utilizar el calendario. La manera de incluir scripts Javascript en archivos
externos la vimos en el primer manual de Javascript.
<script language="JavaScript" src="calendario/javascripts.js"></script>
Artculo por
18
Con los atributos href de los enlaces href=javascript:sentencia... se ejecuta una sentencia Javascript. En este caso, nuestra
sentencia es la llamada a la funcin que se encarga de copiar la fecha pulsada en el formulario de origen, pasndole los
valores que debe copiar, es decir, da, mes y ao de la fecha seleccionada.
Artculo por
19
Referencia: El tema de pasar variables de un lenguaje a otro lo habamos tratado en la FAQ Pasar variables de
ASP o PHP hacia Javascript o viceversa.
La tercera y ltima complicacin que queramos destacar consiste en la razn de la utilizacin de la funcin eval. Es tal vez la
complejidad ms complicada de explicar, y de comprender por las personas poco acostumbradas a Javascript. La funcin
eval() sirve para evaluar, o lo que es lo mismo: ejecutar, una sentencia Javascript. Lo que hay entre los parntesis de eval() es
la composicin de la sentencia que se debe ejecutar para colocar la fecha en el campo de formulario. Y en su caso, eval(),
despus de componerse la sentencia, la ejecuta, dando como resultado el efecto buscado.
Nota: La razn de utilizar eval() est bien clara. Nosotros podemos concatenar todos los elementos necesarios
para crear una sentencia Javascript, pero lo nico que podramos obtener como resultado es una variable que
contuviese un cdigo Javascript. Si queremos ejecutarlo necesitamos forzosamente de la ayuda de la funcin
eval(). Es difcil encontrar ejemplos tan interesantes donde la utilizacin de eval() es crucial para resolver un
problema. De todos modos, si no llegamos a entender puede ser interesante acceder al manual de Javascript II,
donde hablamos de la librera de funciones Javascript y de ejemplos de las mismas, donde encontraremos otro
ejemplo de uso de eval().
Artculo por
20
Esta era la recuperacin de las variables y se colocan en los enlaces hacia el mes siguiente o anterior del calendario:
echo "<a style=color:white;text-decoration:none href=index.php?
$parametros_formulario&nuevo_mes=$mes_anterior&nuevo_ano=$ano_anterior> << </a></td>";
Luego se ha creado una funcin que recibe el da que se pretende imprimir y devuelve el color, o mejor dicho, el estilo que
se le debe aplicar.
function dame_estilo($dia_imprimir){
global $mes,$ano,$dia_solo_hoy,$tiempo_actual;
//dependiendo si el da es Hoy, Domigo o Cualquier otro, devuelvo un estilo
if ($dia_solo_hoy == $dia_imprimir && $mes==date("n", $tiempo_actual) && $ano==date("Y",
$tiempo_actual)){
//si es hoy
$estilo = " class='hoy'";
}else{
$fecha=mktime(12,0,0,$mes,$dia_imprimir,$ano);
if (date("w",$fecha)==0){
//si es domingo
21
La funcin utiliza varias variables globales como son el mes y el ao del calendario que se est mostrando, el da que es hoy
en nmero (variable $dia_solo_hoy) y el timestamp del momento actual (variable $tiempo_actual).
Lo primero que se comprueba es si el nmero de da que se pretende imprimir es el mismo que el nmero de da de hoy y si
el mes y ao que se est imprimiendo es el mismo que el mes y ao actuales. En este caso es que el da, mes y ao
concuerdan con lo que devolver el estilo "hoy". Luego se comprueba si el da de la semana es domingo, devolviendo en ese
caso el estilo "domingo". En caso contrario devuelve el estilo "diario".
Artculo por
22
23
24
Tomas Isasia
25