Vous êtes sur la page 1sur 201

1

!
!
!
!
!
!
!
programacIon web
!
CuIllermo Alejandro Zabala
!
"#$%&'#!()'*%+,'-.+'#!
/01!1'&$#!23

2

456/"0!
!

Pcync
ntroduccIon
J
Esquema general
4


SItuacIon ProfesIonal 1
5
"SerWeb"

HerramIentas

AutoevaluacIon 1
14
AutoevaluacIon 2
25
AutoevaluacIon J
JZ
AutoevaluacIon 4
Z
EjercIcIo resuelto
Z8
EjercIcIo por resolver
88
Fespuesta a las autoevaluacIones
8


SItuacIon ProfesIonal 2
4
"ECD SDFT"

HerramIentas
5
AutoevaluacIon 1
111
AutoevaluacIon 2
118
AutoevaluacIon J
12
EjercIcIo resuelto
1J1
EjercIcIo por resolver
142
Fespuesta a las autoevaluacIones
14J


SItuacIon ProfesIonal J
148
"Caleria dInmIca"

HerramIentas
148
AutoevaluacIon 1
152
AutoevaluacIon 2
155
AutoevaluacIon J
1
EjercIcIo resuelto
18
EjercIcIo por resolver
1Z4
Fespuesta a las autoevaluacIones
1Z5


SItuacIon ProfesIonal 4
181
"Caleria dInmIca "

HerramIentas
181
AutoevaluacIon 1
184
AutoevaluacIon 2
18
EjercIcIo resuelto
11
EjercIcIo por resolver
15
Fespuesta a las autoevaluacIones
1


CIerre
201

J

/57896(""/:5!

En la actualIdad, nternet ha dejado de ser un recurso InformatIvo, para convertIrse en una
herramIenta de trabajo y ocIo, usada por mIllones de personas en todo el mundo. La vertIgInosa
evolucIon de este medIo de comunIcacIon, ya Incorporado como componente de muchas
socIedades, genera un excelente nIvel de competencIa entre sItIos web.

Afrontar la competencIa no es una tarea fcIl y requIere el conocImIento y estudIo de lenguajes
que permItan crear sItIos dInmIcos. Concluyeron los tIempos de entornos esttIcos, pocas
actualIzacIones y falta de InteraccIon con el usuarIo. Los vIejos objetIvos de dIseo para web se
reemplazaron por otros ms sofIstIcados que comprenden las compras en linea, actualIzacIones
dIarIas, mensajeria Instantnea, busquedas IntelIgentes, IntercambIo de InformacIon, espacIos
vIrtuales, comunIdades colaboratIvas, herramIentas de escrItorIo en linea, y muchos otros.
Este renacImIento y evolucIon de la web que brInda solucIones a usuarIos fInales no solo
comprende la multIplIcacIon de servIcIos, sIno tambIn, la mejora de funcIones para facIlItar
usos y manejos de aplIcacIones web, la tecnologia de redes con velocIdades de transferencIa
superIor, y la mejora del software y aplIcacIones que dIsmInuyen los tIempos de actualIzacIon de
datos y gestIones complejas.

En este texto, aprender a programar aplIcacIones dInmIcas del lado del servIdor; logrando
optImIzar, agIlIzar y automatIzar actualIzacIones y procesos de los nuevos servIcIos web.
EstudIar la gestIon de datos, dIrectorIos, archIvos, usuarIos y la generacIon de grfIcos desde el
servIdor de aplIcacIones, componIendo una salIda de texto HT|L descIfrable por cualquIer
navegador web.

El Autor


4

%,;<%=.!&%)%+.$!
>89?8@A@"/:5!B0C!
!
!

5

1'-<.D'E)!>+#F%,'#).$!3G!1%+B%H!!

SerWeb es una empresa proveedora de servIcIos de hostIng que est comenzando con planes
bsIcos de alojamIento para sItIos web. Le han solIcItado a la agencIa de dIseo en la que usted
se desempea, la programacIon del sItIo, con la fInalIdad de mostrar los planes ofrecIdos y
facIlItar la contratacIon de servIcIos "onlIne" de usuarIos, permItIendo una mejor via de
contacto.
Adems, le pIden que realIce un sIstema de banners o anuncIos publIcItarIos, para generar vIsItas
desde sItIos afIlIados, como estrategIa de posIcIonamIento en buscadores.
Su mIsIon ser programar el sItIo, a partIr del dIseo aprobado por el comItente, tenIendo en
cuenta los sIguIentes requerImIentos:

- Cada plan de hostIng mostrado en la pgIna de InIcIo debe dIreccIonar al usuarIo a un
formularIo para su contratacIon.
- Cuando el usuarIo completa y envia el formularIo de contratacIon de servIcIo, debe
mostrarle la confIrmacIon del envio con los datos ms relevantes (plan contratado, forma
de pago, medIo de pago).
- Los datos del formularIo se envian a una casIlla de correo electronIco del encargado de
ventas de la empresa.
- Los banners de afIlIados se mostrarn aleatorIamente durante la navegacIon por el sItIo.


6

I%++.='%)-.,!
!
1 nternet
1.1 Drdenadores, servIdores y clIentes
1.2 FuncIonamIento bsIco de la WWW
1.J Estructura ClIente/ServIdor
1.4 TIpos de servIdores
1.5 FuncIonamIento de C/S
1.6 Lenguajes del lado del clIente y del lado del servIdor
1.7 PgInas dInmIcas -Web 2.0

2 Fepaso de HT|L
2.1 PrIncIpIo de escrItura
2.2 Estructura de una pgIna
2.J Fesumen de etIquetas
2.4 Tablas
2.5 FormularIos

J Abordando PHP 5
J.1 ntroduccIon a PHP 5
J.2 HerramIentas necesarIas para comenzar con PHP 5
J.J PrIncIpIos bsIcos de programacIon

4 ProgramacIon en PHP 5
4.1 La sIntaxIs elemental
4.2 7arIables y tIpos de datos
4.J Dperadores
4.4 Estructuras de control
4.5 AnIdamIento de estructuras de control
4.6 SalIendo del analIzador de PHP
4.7 Constantes del sIstema y personalIzadas
4.8 FuncIones personalIzadas
4.9 AmbIto de varIables
4.10 FuncIones predefInIdas
4.11 LIbrerias
4.12 |atrIces
4.1J Acceso a varIables de formularIo y UFL
4.14 FuncIon maIl
4.15 7arIables del servIdor

7

3!/)-%+)%-!
nternet es el medIo que permIte la conexIon global de un gran numero de redes y ordenadores
en todo el mundo para el IntercambIo de datos de todo tIpo, mejorando la InteraccIon entre
usuarIos y empresas.
Una forma de IntercambIar InformacIon a travs de este medIo, son los sItIos alojados en
servIdores web. Los sItIos estn constItuIdos por una o ms pgInas a las que accede el usuarIo
por medIo del navegador. En la sItuacIon profesIonal actual, debe crear o programar pgInas
web, y antes de aprender un lenguaje de programacIon es necesarIo conocer como se
transmItIrn los datos que contengan estas pgInas. A contInuacIon, vamos a dIstInguIr
elementos bsIcos que IntervIenen durante una comunIcacIon en nternet.


3J3!9+K%).K#+%,L!,%+*'K#+%,!M!D$'%)-%,!
En nternet exIsten dos tIpos de ordenadores segun la conexIon, los servIdores y los clIentes.
Los servIdores estn conectados a la red y funcIonan permanentemente, recIbIendo los pedIdos
de los clIentes. En ellos se encuentra la InformacIon que se transmIte al clIente.
Los clIentes acceden a la red de forma recurrente y realIzan los pedIdos de pgInas web a los
servIdores. Por ejemplo, cada vez que un usuarIo se conecta e Ingresa a la pgIna de un sItIo.


3J2!N<)D'#).='%)-#!HO,'D#!K%!$.!BBB!
7Imos que en la red exIsten servIdores y clIentes que Interactuan entre ellos. Estos ordenadores
pueden ser de dIferentes tIpos y se encuentran dIstrIbuIdos en todo el mundo.

Para que los ordenadores puedan encontrarse y conectarse entre si, deben dIsponer de una
dIreccIon P. La P de cada ordenador es exclusIva y lo dIstIngue de cualquIer ordenador en el
mundo. ConsIste en un numero de J2 bIts que se puede descomponer por comodIdad en 4
numeros de 8 bIts. Ejemplo: para acceder al buscador 6ooyle podemos hacerlo a travs de
66.102.7.99. Entonces, los servIdores y clIentes conectados a la red tendrn dIreccIones de P
unIcas para que puedan dIstInguIrse unos de otros.
Los servIdores tendrn dIreccIones P fIjas o InvarIables para que los clIentes puedan
encontrarlos cada vez que se conecten y solIcIten InformacIon a uno de ellos.
Los clIentes pueden tener P dInmIcas o varIables. Una vez que un clIente accede a la red,
recIbe una P que perdura durante la conexIon y que seguramente ser dIferente de la P que
recIbIo en conexIones anterIores.

Una vez que los ordenadores clIente y servIdor se encuentran, el clIente, por ejemplo, realIzar
un pedIdo o petIcIon de pgIna al servIdor y ste le devolver la pgIna solIcItada sI exIste. Todo
este acuerdo que se produce entre los ordenadores ImplIca el uso de un lenguaje comun. Para
ello exIsten los protocolos que rIgen la comunIcacIon en nternet, hacen que los ordenadores
hablen el mIsmo IdIoma. Para las conexIones a Internet, el protocolo ms utIlIzado es el TCP/P,
protocolo de control de transmIsIon y protocolo de nternet.

Lo expresado anterIormente, ImplIcaria que cada vez que un usuarIo Ingrese a un determInado
sItIo web por medIo de un ordenador clIente, deberia escrIbIr la P de dIcha web en la barra de
dIreccIones de su navegador.
Usted ya sabe que esto no es asi, normalmente escrIbImos la dIreccIon del sItIo, con letras o
palabras. Esta dIreccIon con letras o palabras la llamamos nombre de domInIo. Afortunadamente
exIsten los servIdores de nombres de domInIo o 0NS.
Los servIdores 0NS son un tIpo de servIdor que almacenan tablas en las que se relacIonan
numeros de P con sus respectIvos nombres de domInIo.
Entonces, cuando Ingresamos el domInIo de un sItIo en la barra de dIreccIones del navegador, de
un modo sImplIfIcado, se Invoca al servIdor de 0NS para que busque la dIreccIon P relacIonada
al nombre de domInIo Ingresado y, a partIr de ella, podamos acceder al servIdor solIcItado.

8


El nombre de domInIo corresponde a la dIreccIon prIncIpal de un sItIo web, como por ejemplo
yooyle.com. TambIn se puede especIfIcar una determInada pgIna del servIdor web, como en
este otro ejemplo: http://www.yooyle.com/ndex.html. Esta ultIma forma de acceder a un
contenIdo, la llamamos UFL (UnIform Fesource Locator), localIzador unIforme de recurso.
La UFL est formada por el protocolo de carga, en este caso protocolo de transferencIa de
hIpertexto o HTTP (HyperText Transfer Protocol), el formato de pgIna (www), el nombre del
domInIo y la pgIna a petIcIonar dentro del servIdor.
El protocolo de transferencIa de hIpertexto o HTTP, defIne la sIntaxIs y la semntIca que utIlIzan
los elementos de la arquItectura web (clIentes, servIdores y otros) para comunIcarse. Todos los
protocolos reglan algun tIpo de comunIcacIon.
Adems del protocolo TCP/P que permIte la transmIsIon de datos entre redes de computadoras
y el protocolo HTTP para la transferencIa de hIpertexto, exIsten muchos otros que IntervIenen
en una comunIcacIon, algunos de ellos son N7>! , 50B1! , 70P507! , N/P0! , B@/1! , >9>!
, 1A7>! , etc.


Ayuda ahora
1A7> o SImple |aIl Transfer Protocol para transmItIr correo.
N7> (FIle Transfer Protocol), sIrve para la transferencIa de archIvos entre ordenadores conectados a una
red TCP, basado en la arquItectura clIenteservIdor.
50B1, es un protocolo usado para la lectura y publIcacIon de articulos de notIcIas.
70P507, es un protocolo que sIrve para acceder medIante una red a otro ordenador para operarlo como
sI estuvIera delante de l.
N/P0, sIrve para acceder a fIcheros del sIstema.
B@/1, es acronImo de WIde Area nformatIon Servers, es un sIstema de busqueda de texto.
>9> o Protocolo de DfIcIna de Correos es necesarIo para la recepcIon de de mensajes de correo.


3JQ!0,-+<D-<+.!"$'%)-%R1%+*'K#+!
Hasta ahora hablamos de ordenadores clentes y servdores, pero debemos consIderar a ambos
como so]twcre o proyrcmcs que funcIonan en computadoras. Aunque a veces utIlIcemos estos
trmInos para referIrnos a los ordenadores fisIcos que ocupan.
La Web trabaja sIguIendo el modelo o arquItectura clIente/servIdor. ExIste un software clIente
que pIde un servIcIo, un software servIdor que lo provee, y luego el clIente lo recIbe.

El clIente es un software que el usuarIo utIlIza para solIcItar a un servIdor web el envio de
pgInas de InformacIon. Estas pgInas se transfIeren medIante el protocolo HTTP. El software
clIente recIbe archIvos de texto en lenguaje HT|L o cualquIer otro lenguaje que pueda
Interpretar, como por ejemplo JavaScrIpt o 7Isual 8asIc ScrIpt. Una vez que el clIente recIbe
estos archIvos, los procesa para mostrrselos al usuarIo en el formato grfIco adecuado.
Adems de recIbIr archIvos de texto HT|L, tambIn puede recIbIr otros formatos de archIvos,
como por ejemplo vIdeo o sonIdo. En estos casos, el navegador clIente debe actIvar aplIcacIones
externas que los procesen.
Entre los clIentes de Internet ms conocIdos estn: nternet Explorer, |ozIlla, Netscape
NavIgator, Dpera, SafarI y muchos otros.

El servIdor web es un software que est permanentemente atendIendo los pedIdos de los
clIentes. Cuando recIbe una petIcIon, busca en su sIstema de archIvos el documento HT|L
solIcItado y lo envia al clIente. SI el documento no exIste, envia una pgIna con un codIgo de
error.



9

3JS!7'T#,!K%!,%+*'K#+%,!
Hasta ahora hablamos de servIdores en forma genrIca y a veces nos referImos a los servIdores
web. ExIsten numerosos tIpos de servIdores, clasIfIcados segun el servIcIo que ofrecen. 7eamos
algunos de ellos:

1%+*'K#+!B%H: ya nombrado anterIormente, bsIcamente sIrve el contenIdo esttIco a un
navegador. Envia un archIvo a travs de la red al navegador (clIente) que lo solIcIto. Este
IntercambIo entre el navegador y el servIdor es medIado por el protocolo HTTP que provee
un mIsmo lenguaje para que ellos se comunIquen.
Los servIdores web pueden ser:
CompartIdos (HostIng): espacIo donde hay varIas cuentas de otros clIentes que
comparten el mIsmo dIsco y la mIsma conexIon.
0edIcados (HousIng): es un ordenador conectado a la red, dedIcado al usuarIo que lo
contrata, solo se comparte la conexIon. |ejora la segurIdad, es de uso IntensIvo, la
empresa o usuarIo que lo contrata tIene control completo y puede Instalar las
aplIcacIones que desee. Adems, es ms economIco al alojar numerosos sItos.

1%+*'K#+! K%! @T$'D.D'#)%,: es el encargado de ejecutar cIertas aplIcacIones. ConsIderado
un tIpo de ='K$%U.+%! , que proporcIona InterconexIon entre otros programas de servIcIos
como bases de datos, Intrpretes de secuencIas de comandos con sus Interfaces de
programacIon y otros.


Ayuda ahora
A'KK$%U.+% es un software de computadora que conecta componentes de software o aplIcacIones
para que puedan IntercambIar datos entre stas.

1%+*'K#+%,! K%! C.,%! K%! 6.-#,: dedIcado a servIr de gestor entre la base de datos y las
aplIcacIones.

1%+*'K#+%,!K%!1-+%.=')&: permIten mostrar a los usuarIos contenIdos multImedIa de sItIos
web, en forma de flujo contInuo desde el servIdor.

1%+*'K#+%,! K%! "V.-: permIten el IntercambIo de InformacIon entre una gran cantIdad de
usuarIos ofrecIendo la posIbIlIdad de llevar a cabo dIscusIones en tIempo real.

1%+*'K#+%,! N7>: sIrven para mover uno o ms archIvos entre dIstIntos ordenadores,
proporcIonando la gestIon y el control de la transferencIa.

1%+*'K#+%,!K%!"#++%#: son tan recurrIdos como los servIdores web, los servIdores de correo
mueven y almacenan el correo electronIco a travs de las redes corporatIvas y a travs de
nternet.


3JW!N<)D'#).='%)-#!K%!"R1!
0esde que un usuarIo solIcIta una pgIna web hasta que el navegador se la muestra, se orIgIna el
proceso que se detalla a contInuacIon:
!

10

!

1. El usuarIo escrIbe la dIreccIon UFL de la pgIna que desea vIsualIzar en el navegador clIente.
2. El clIente envia la petIcIon, a travs de nternet, al servIdor web solIcItando la pgIna
deseada.
J. El servIdor busca la pgIna que ha sIdo solIcItada en su sIstema de archIvos. SI la encuentra, la
envia al clIente; en caso contrarIo, devuelve una pgIna de error.
4. El clIente Interpreta la pgIna HT|L, la muestra al usuarIo y se cIerra la conexIon.

Las petIcIones son IndependIentes y no se mantIene una memorIa entre ellas. En muchas
aplIcacIones esta memorIa es fundamental, como por ejemplo las operacIones de compra a
travs de la Web. ExIsten mecanIsmos para resolver este problema, los estudIaremos en la
herramIenta 4 de la presente sItuacIon profesIonal y en la sItuacIon profesIonal 4.
SIempre se establece una unIca conexIon para cada archIvo que se transmIte. Es decIr, sI una
pgIna contIene, por ejemplo, tres Imgenes, entonces se establecen cuatro conexIones
IndependIentes: una para la pgIna y otras tres para las Imgenes.
Puede ocurrIr, y de hecho es asi en la mayoria de los casos, que la pgIna solIcItada por el
usuarIo no exIste fisIcamente en el servIdor web, sIno que debe ser creada o generada en el
momento de su petIcIon. Por ejemplo, cuando se requIere InformacIon de una base de datos. En
este caso, el servIdor web cede el control al servIdor de aplIcacIones. ste procesar la
solIcItud, construIr la pgIna y la transmItIr al servIdor web, que a su vez la envia al clIente.
Estamos ante una solIcItud de pgIna dInmIca y el esquema de funcIonamIento para este caso,
es el sIguIente:



11

1. El usuarIo detalla la dIreccIon UFL de la pgIna que desea vIsualIzar en el navegador clIente.
2. El clIente envia la petIcIon, a travs de nternet, al servIdor web solIcItando la pgIna
deseada.
J. Una vez que llega la petIcIon al servIdor web, ste la evalua y al ser un pedIdo de pgIna
dInmIca debe derIvarlo al servIdor de aplIcacIones.
4. El servIdor de aplIcacIones recIbe el pedIdo de la pgIna dInmIca y procesa su codIgo. SI el
procesado exIge consulta a datos externos, el servIdor de aplIcacIones envia la consulta a la base
de datos para completar el procesado.
5. El servIdor de la base de datos ejecuta la consulta pedIda por el servIdor de aplIcacIones y le
devuelve los resultados.
6. El servIdor de aplIcacIones recIbe los datos de la consulta, genera una pgIna con codIgo
HT|L a partIr de esos datos y se la envia al servIdor web.
7. El servIdor web envia la pgIna HT|L resultante a la aplIcacIon clIente.
8. El clIente Interpreta la pgIna HT|L, la muestra al usuarIo y se cIerra la conexIon.


3JX!P%)&<.Y%,!K%$!$.K#!K%$!D$'%)-%!M!K%$!$.K#!K%$!,%+*'K#+!
El software clIente es la unIca aplIcacIon capaz de Interpretar el codIgo HT|L de una pgIna web
y representarla en un formato grfIco comprensIble para el usuarIo.
Cuando el clIente realIza una petIcIon de pgIna a un servIdor web, ste le envia el archIvo
HT|L pedIdo sIn realIzar nInguna lectura o InterpretacIon sobre ella. Podriamos decIr que el
servIdor web solamente se lImIta a transferIr los archIvos solIcItados por el clIente a travs del
protocolo HTTP. SI la petIcIon que realIza el clIente es de un archIvo dIstInto de HT|L, el
servIdor web sIgue funcIonando de la mIsma manera: busca el archIvo solIcItado y lo envia al
clIente que lo petIcIona. El clIente recIbe el archIvo que solIcIto, lo Interpreta y lo muestra al
usuarIo; pero sI el archIvo solIcItado no corresponde a una pgIna HT|L, debe ejecutar una
aplIcacIon externa que lo Interprete. SI no exIste dIcha aplIcacIon, lo consIderar como una
descarga de archIvo.
En referencIa a lo anterIor, podemos hablar de lenguajes del lado del clIente. El software clIente
solamente Interpreta codIgo de lenguajes para los que est preparado, uno de ellos es HT|L.
Dtros lenguajes que Interpretan la mayoria de los clIentes son el JavaScrIpt y 7Isual 8asIc ScrIpt.

SI la pgIna solIcItada por el clIente requIere una InterpretacIon prevIa por parte del servIdor, en
el caso de pgInas dInmIcas, no es el servIdor web el que realIza esta InterpretacIon sIno el
servIdor de aplIcacIones, como se estudIo en el esquema clIente/servIdor. Fecuerde que el
servIdor web no es capaz de Interpretar nIngun lenguaje y solamente se lImIta a transferIr
petIcIones.
Entonces, cuando el servIdor web recIbe una petIcIon de pgIna dInmIca, debe transferIr la
InterpretacIon de dIcha pgIna al servIdor de aplIcacIones. Este ultImo procesar el codIgo de la
pgIna y le devolver al servIdor web un archIvo HT|L para que se lo envie al clIente. Ahora
estamos hablando de lenguajes del lado del servIdor, que son aquellos que solamente puede
Interpretar un servIdor de aplIcacIones, y el resultado ser un archIvo HT|L totalmente
compatIble con el Intrprete del clIente.

Dtra cuestIon Importante a tener en cuenta es que los codIgos de lenguajes del servIdor son
InvIsIbles para el clIente, a dIferencIa de los del lado del clIente. Esto quIere decIr que el scrIpt
se ejecuta en el servIdor, y su resultado ser un sencIllo codIgo HT|L para el clIente, quedando
oculto su programa.

Los lenguajes del lado del servIdor ms amplIamente utIlIzados para el desarrollo de pgInas
dInmIcas son >I>! L!@1>! L!@1>J507! L!Z1>! L!>08P! !M!"#$KN<,'#)! .



12


Ayuda ahora
>I>L!@1>L!@1>J507L!Z1>L!>08P!M!"#$KN<,'#) son lenguajes de programacIon utIlIzados para la creacIon
de pgInas dInmIcas.
>I> es un acronImo recursIvo que sIgnIfIca PHP Hypertext Preprocessor.
@1> o ActIve Server Pages (ASP) es una tecnologia del lado del servIdor de |Icrosoft.
@1>J507 forma parte de la plataforma .NET de |Icrosoft y es la sucesora de la tecnologia ASP. La
tecnologia .NET pone nfasIs en transparencIa de redes, con IndependencIa de plataforma de hardware,
y permIte un rpIdo desarrollo de aplIcacIones.
Z1> permIte la utIlIzacIon de codIgo Java del lado del servIdor. Java es un lenguaje de programacIon
orIentado a objetos, desarrollado por Sun |Icrosystems.
>08P o Lenguaje PrctIco para la ExtraccIon e nforme es un lenguaje de programacIon dIseado por
Larry Wall, creado en 1987.
"#$KN<,'#) se basa en etIquetas sImIlares al HT|L por lo que es fcIl de aprender.
!
Hasta ahora hablamos de HT|L como sI fuera un lenguaje de programacIon, pero en realIdad es
un lenguaje de marcas que descrIbe como debe verse la InformacIon en la pantalla. Por lo tanto,
no entraria en el grupo de lenguajes de programacIon del lado del clIente, aunque ste lo
Interprete.

Una pgIna generada desde el servIdor de aplIcacIones, es legIble por todos los navegadores. En
contrapartIda, una pgIna que contIene lenguaje de programacIon del lado del clIente puede
presentar IncompatIbIlIdades al ser Interpretado por dIferentes navegadores.


3J[!>O&').,!K')O='D.,!\B%H!2J]!
Actualmente las pgInas web ya no estn unIcamente enfocadas para ser vIsIonadas, sIno que
cada vez son ms InteractIvas permItIendo que el vIsItante partIcIpe en ellas medIante menus
contextuales, encuestas, votacIones, comentarIos, subIda o descarga de fIcheros, compras en
linea, busquedas IntelIgentes, etc.
7Imos que el lenguaje HT|L no es de programacIon sIno, ms bIen, se trata de un lenguaje que
descrIbe al navegador la manera de representar la InformacIon en la pantalla del usuarIo. En
defInItIva, HT|L le permIte al dIseador web, maquetar y darle formato vIsual a todos los
elementos de una pgIna. Pero HT|L no admIte la ejecucIon de procesos ms complejos como
clculos matemtIcos o consultas a bases de datos entre otros. Para poder ejecutar estos
procesos, el dIseador web, necesIta aprender lenguajes de programacIon que admItan una
experIencIa InteractIva a la que llamamos "dInmIca". Un contenIdo dInmIco puede cambIar en
respuesta a dIferentes contextos o condIcIones, esto ImplIca un grado de automatIzacIon y
vItalIdad en sItIos actIvos.

SI el sItIo que queremos programar es relatIvamente pequeo y no requIere actualIzacIon
contInua, el empleo de pgInas dInmIcas puede resultar InservIble. Pero sI el sItIo es extenso y
sus contenIdos cambIan dIarIamente, ser mejor automatIzar las tareas.

|uchas pgInas, generalmente las comercIales, Implementaron bases de datos y codIgos
ejecutables por el servIdor de aplIcacIones. Con esto salIeron de su estatIsmo y se convIrtIeron
en pgInas dInmIcas, es decIr, un usuarIo puede Interactuar con el servIdor, por ejemplo las
puede modIfIcar y esa modIfIcacIon estar presente para los dems usuarIos que la consulten
posterIormente; un ejemplo de esto son los foros, alguIen deja un comentarIo y las personas que
luego Ingresen lo pueden leer y contestar.

Los sItIos dInmIcos permIten el manejo de grandes volumenes de InformacIon y su fcIl
almacenamIento, recuperacIon y modIfIcacIon gracIas a las bases de datos.


1J

PgInas que requIeren cIerta complejIdad usan bases de datos, por ejemplo cuando hacemos una
busqueda en 6ooyle, el sIstema Interno de 6ooyle busca dentro de su base de datos y devuelve
una pgIna creada en ese Instante con los resultados. TambIn esto sucede cuando buscamos un
producto en Amczon, esta lIbreria tIene mIllones de productos. Los servIcIos de web maIl
tambIn utIlIzan bases de datos, Ingresamos nuestro nombre de usuarIo y contrasea y se
generar una pgIna especIalmente dIseada para nosotros con nuestra confIguracIon (nuestros
maIls, nuestras carpetas, los colores y estIlos que confIguramos para ver el sItIo), y sI estamos,
por ejemplo, en un cIber a la persona que est en la computadora de al lado se le generar una
pgIna dIstInta a la nuestra con sus propIas confIguracIones.
Dtra gran utIlIdad es la posIbIlIdad de Insertarse en el rea del ecommerce para la venta de
productos y servIcIos onlIne, las reservas de vIajes y hoteles, la gestIon de las cuentas bancarIas
a travs de nternet, tambIn se est extendIendo la compraventa de accIones por nternet, ya
que las operacIones son ms rpIdas y economIcas.

Las pgInas dInmIcas han marcado una Innovadora percepcIon referIda a la tendencIa del dIseo
web y desarrollo, una Idea de segunda generacIon de comunIdades basadas en la web y servIcIos
de alojamIento (como los sItIos de redes socIales, U'^', ,! H$#&,! , y F#$^,#)#='%,! ) que
pretenden facIlItar la creatIvIdad, la colaboracIon y el IntercambIo entre usuarIos. Estamos
hablando del concepto "WE8 2.0", trmIno que fue IntroducIdo por prImera vez en el ao 2004
en una conferencIa de 9_8%'$$M! .


Ayuda ahora
B'^'L!es un sItIo web colaboratIvo que puede ser edItado por varIos usuarIos.
C$#& o bItcora, es un sItIo web perIodIcamente actualIzado que recopIla cronologIcamente textos o
articulos de uno o varIos autores.
N#$^,#)#='% es un sIstema de autoclasIfIcacIon de objetos. Son los propIos usuarIos quIenes clasIfIcan
los contenIdos de algun modo, de forma natural, democrtIca y cambIante.
9_8%'$$M es fundador y presIdente de la edItorIal D'FeIlly |edIa, es un fuerte Impulsor del software lIbre
y uno de los autores del concepto Web 2.0, tambIn ha partIcIpado en el desarrollo del lenguaje Perl.

Aunque el trmIno apunta a una nueva versIon de la World WIde Web, no se refIere a una
actualIzacIon de las especIfIcacIones tcnIcas, pero si a cambIos en la manera de desarrollar
software y la utIlIzacIon de las webs.
Segun TIm D'FeIlly:

Web 2.0 es la empresa revolucIonada en la IndustrIa de las computadoras, causada por el paso a
la nternet como plataforma, y un Intento de entender las reglas para lograr el xIto en esa
nueva plataforma.

Este nuevo concepto marca la evolucIon de las aplIcacIones web tradIcIonales hacIa los usuarIos
fInales. Se trata de aplIcacIones que generan colaboracIon, y de los servIcIos que reemplazan a
las aplIcacIones de escrItorIo.

La programacIon de pgInas dInmIcas requIere el conocImIento del lenguaje HT|L, ya que las
pgInas generadas, sIempre llegan al clIente como codIgo HT|L para que el navegador lo
Interprete. En la proxIma herramIenta aprender a Interpretar y escrIbIr pgInas esttIcas.


14

@<-#%*.$<.D'E)!3!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!

3 0os ordenadores servIdores conectados a Internet y que tIenen la mIsma dIreccIon P, podrian
recIbIr, sImultneamente, las mIsmas petIcIones de los clIentes.

` ` 7erdadero ` ` Falso

!
2 Todos los archIvos que recIbe el clIente, son procesados para ser mostrados al usuarIo a travs
del navegador web.

` ` 7erdadero ` ` Falso


Q Las petIcIones de los clIentes se transfIeren a travs del protocolo HTTP.

` ` 7erdadero ` ` Falso


S Un navegador web petIcIona una pgIna HT|L que contIene tres Imgenes, un formularIo de
contacto y una anImacIon SWF. Entonces se establecen cInco conexIones IndependIentes.

` ` 7erdadero ` ` Falso

!
W El servIdor web es capaz de Interpretar el codIgo HT|L de una pgIna web y representarla en
un formato grfIco comprensIble para el clIente.

` ` 7erdadero ` ` Falso


X Para programar una pgIna dInmIca no necesIta conocer HT|L ya que el servIdor se encargar
de generarlo.

` ` 7erdadero ` ` Falso



Las respuestas las encontrar al fInal de la sItuacIon profesIonal.


15

2!8%T.,#!K%!I7AP!
Antes de comenzar a programar pgInas dInmIcas, es absolutamente necesarIo que comprenda
la InterpretacIon que realIza el navegador sobre el codIgo HT|L, ya que usted debe crear un
programa que genere este codIgo en la sItuacIon planteada.
Para crear pgInas web con HT|L, necesItar un edItor de texto que pueda ser tan sencIllo como
NotePad, o avanzado como Adobe 0reamweaver.
HT|L es el lenguaje que puede Interpretar un navegador web, entonces necesItar uno como
nternet Explorer, FIrefox, Dpera o cualquIer navegador web del mercado que le permIta probar
las pgInas que realIce.
A contInuacIon, estudIar la sIntaxIs de escrItura de este lenguaje.


2J3!>+')D'T'#!K%!%,D+'-<+.!
El HT|L es un lenguaje de marcas, es decIr que basa su escrItura en un elemento bsIco llamado
etIqueta.
Ceneralmente la etIqueta se compone de dos partes: Una apertura de forma general
<etiqueta> y un cIerre </ etiqueta>.

Por ejemplo:

<b> Esto es HTML </b>

Todo lo IncluIdo en el InterIor de esa etIqueta estar sujeto a las modIfIcacIones vIsuales que la
especIfIcan. En el ejemplo, las etIquetas <b> y </b> defInen un texto en negrIta. El texto
"Esto es HTML" que se encuentra entre dIchas etIquetas, aparecer en la pantalla del
navegador, formateado con su tIpografia en negrIta.
SIguIendo con otro ejemplo, las etIquetas <p> y </p> defInen un prrafo. SI en nuestro
documento HT|L escrIbImos:

<p>Hola, estamos en el primer prrafo.</p><p>Ahora en el segundo prrafo.</p>

El resultado es:

Hola, estamos en el primer prrafo.
Ahora en el segundo prrafo.

TambIn se puede aplIcar ms de una etIqueta a un mIsmo contenIdo, por ejemplo:

<p><b>Hola, estamos en el primer prrafo.</b></p><p>Ahora en el segundo
prrafo.</p>

El resultado es:

Hola, estamos en el primer prrafo.
Ahora en el segundo prrafo.

0ebe tener cuIdado de no entrelazar etIquetas debIdo a que una etIqueta debe termInar antes
de que se cIerre el nodo que la contIene. En el ejemplo anterIor, <b> est dentro de <p> por lo
que deberia termInar antes de </p>:

<p><b>contenido del nodo</b></p>

El sIguIente ejemplo muestra una escrItura mal formada:


16

<p><b>contenido del nodo</p></b>

Estos prIncIpIos no son estrIctamente necesarIos, muchos navegadores mostrarian correctamente
una pgIna HT|L que no cumpla claramente con ellos, pero otros no. Y sI se tratara de pgInas
XHT|L, deberia cumplIr estrIctamente las reglas de escrItura. XHT|L es la evolucIon de HT|L y
est pensado para sustItuIr el estndar actual.

|uchas etIquetas admIten atrIbutos o propIedades, estos servIrn para especIfIcar mejor el
comportamIento o el formato vIsual de los elementos de una pgIna.

Por ejemplo:

<a href="http://www.w3.org">World Wide Web Cosortium</a>

El resultado es:

World Wide Web Cosortium

En el ejemplo se escrIbIo un enlace de hIpertexto hacIa la pgIna prIncIpal de BQ" . Dbserve
el atrIbuto href cuyo valor es el vinculo HTTP que debe petIcIonar el navegador. Todos los
valores de atrIbutos se encIerran entre comIllas.


Ayuda ahora
BQ" o World WIde Web ConsortIum, es un consorcIo InternacIonal que produce estndares para la
World WIde Web. En ella se pueden consultar los documentos tcnIcos con estndares actuales para la
escrItura de pgInas HT|L. Fespetando estos estndares, no cometer errores en sus pgInas y las
mIsmas se vern correctamente en cualquIer navegador.

HT|L no dIstIngue entre mayusculas y mInusculas, es lo mIsmo una etIqueta b que una 8.
Actualmente, en la WJC aconsejan escrIbIr los nombres de etIquetas en mayusculas y los
atrIbutos en mInusculas, pero es solo una cuestIon de agIlIzar la lectura para el dIseador de
pgInas. Los navegadores web leern el codIgo correctamente, IndIstIntamente de esta
recomendacIon.

Los navegadores no toman en cuenta las tabulacIones, saltos de linea nI los espacIos en blanco.
Esto es una ventaja que nos facIlIta la comprensIon del codIgo. 7olvIendo al tercer ejemplo,
podriamos haber escrIto:

<p>
<b>Hola, estamos en el primer prrafo.</b>
</p>
<p>
Ahora en el segundo prrafo.
</p>

El resultado hubIera sIdo el mIsmo en la pantalla del usuarIo, pero para nosotros es un poco ms
legIble o comprensIble. Esto lo notar, especIalmente, cuando tenga numerosas lineas de codIgo
HT|L.


2J2!0,-+<D-<+.!K%!<).!TO&').!
Toda pgIna HT|L debe comenzar con la etIqueta <html> y fInalIzar con el cIerre de la mIsma:
</html>.
0entro de estas etIquetas exIsten otras dos: <head> y <body>:

17


<html>
<head>
<title>Ttulo del documento</title>
</head>

<body>
Cuerpo del documento
</body>
</html>

La etIqueta <head> contIene InformacIon que no ser vIsIble en la pantalla prIncIpal del
navegador. Esta etIqueta corresponde a la cabecera del documento, contIene sus caracteristIcas
y prIncIpalmente el titulo del mIsmo.

El titulo dentro de la cabecera ser vIsIble en la parte superIor IzquIerda del navegador. 0ebe
ser corto y sencIllo, pero muy descrIptIvo de la InformacIon que contIene el cuerpo de la pgIna.
El titulo es el que se mostrar en el menu de favorItos del navegador cuando un usuarIo agregue
nuestra pgIna a sus sItIos favorItos. Adems, es el que utIlIzan los buscadores, entre otros, para
encontrar nuestro sItIo.

La etIqueta <body>, contIene toda la InformacIon o contenIdo que se va a vIsualIzar en la
pantalla del usuarIo, como textos o Imgenes. Es decIr que contendr otras etIquetas como las
que hemos vIsto anterIormente.

El resultado del ejemplo en el navegador es:






2JQ!8%,<=%)!K%!%-';<%-.,!
En el cuadro de abajo se aprecIan algunas de las etIquetas y atrIbutos ms conocIdos para crear
y formatear los contenIdos de una pgIna:

18


0-';<%-.! @-+'H<-#R,! 6%,D+'TD'E)! 0Y%=T$#!
.!
href
name
target
0,-.H$%D%!<)!*a)D<$#J!
0IreccIon del vinculo.
Establece un ancla.
Establece el destIno del vinculo:
_blank, _self, _top, _parent, o
"defInIdo".
a href=http://www.wJ.org
target=_blankWJC/a
H! 7%b-#!%)!)%&+'-.J!TambIn se
puede usar strong!
bTexto/b
strongTextostrong
H#KM!

alInk

background

bgcolor

lInk

vlInk
>.+-%!*','H$%!%)!T.)-.$$.!K%$!
K#D<=%)-#J!
|odIfIca el color del vinculo
cuando est actIvado.
Para colocar una Imagen de fondo.
Para establecer un color de fondo.
|odIfIca el color del vinculo antes
de estar actIvado.
|odIfIca el color del vinculo
cuando ya ha sIdo vIsItado.
body alInk=#CC0000
vlInk=#CCCC66 lInk=#CC6600
background=fondo.jpg
bgcolor=#CCCCCCContenIdo del
cuerpo/body
H+! 1.$-#!K%!$a)%.J El cIerre de esta
etIqueta se realIza dentro de la
mIsma, al Igual que hr e Img.!
Texto de la prImera lInea
br/
Texto de la segunda lInea
D%)-%+! "%)-+.!%)!V#+'c#)-.$J! centerTexto al centro/center
F#)-!
sIze
color
face
N#+=.-%.!$.!F<%)-%J!
Tamao de la fuente.
Color.
TIpo de letra.
font color=#JJJJ99 face=7erdana,
ArIal, HelvetIca, sansserIf
sIze=4Texto/font
F#+=!
actIon

method
enctype
N#+=<$.+'#!
ndIca quIn procesa el formularIo.
El mtodo de envio.
La forma de envio.
form actIon=
maIlto:Info@empresa.com: subject =
Asunto del mensaje method= post
enctype= text/plaIn elementos del
formularIo /form
V3! 7%b-#!K%!%)D.H%c.K#.
Hay otros 5: h2 hJ h4 h5
h6
h1Encabezado/h1
V+!
alIgn
noshade
sIze
wIdth
Pa)%.!V#+'c#)-.$J!
AlIneacIon de la linea.
SIn efecto de sombra.
Crosor de la linea.
Anchura de la linea.
hr color=#0066CC
noshade=noshade sIze=1
wIdth=J00 /
'! P%-+.!D<+,'*.. TambIn se puede
utIlIzar em
ICursIva/I
'=&!
alt
border

heIght
wIdth
src
/),%+-.!<).!'=.&%)J!
Texto alternatIvo a la Imagen.
Establece sI va a tener borde o no,
cuando sIrva de vinculo.
Altura de la Imagen.
Ancho de la Imagen.
Establece qu Imagen se va a
Insertar.
Img alt=|I Imagen border=0
heIght=100 wIdth=120
src=Imagen.jpg /
T! >O++.F#!)<%*#J! pNuevo parrafo/p
-.H$%!
alIgn

bgcolor

6'H<Y.!<).!-.H$.J!
AlInea la tabla: center, rIght, left
Establece el color de fondo de la
tabla.
Establece un borde a la tabla
table alIgn=center
bgcolor=#CC66JJ border=0
cellpaddIng=4 cellspacIng=0
wIdth=400trtd alIgn=justIfy
bgcolor=#CCJJJJ heIght=21

19

border
cellpaddIng

cellspacIng
wIdth
SeparacIon entre el borde de la
tabla y el contenIdo.
SeparacIon entre las celdas.
Establece el ancho de la tabla.
valIgn=baselIne wIdth=100 Celda
/td /tr /table
-K!
alIgn


bgcolor

colspan

heIght
rowspan

valIgn

wIdth
"%$K.!K%!<).!-.H$.J!
Establece la alIneacIon del texto
dentro de la celda: left, center,
rIght.
Establece el color de fondo para la
celda.
ExtIende la celda sobre varIas
columnas.
Establece la altura de la celda.
ExtIende la celda sobre varIas
fIlas.
Establece la alIneacIon vertIcal:
top, mIddle, bottom.
Establece el ancho de la celda.
dem a table
-+! N'$.!K%!<).!-.H$.J! dem a table
<! 1<H+.M.K#J! uTexto/u

SI quIsIramos mostrar una Imagen que, a su vez, tenga un enlace a otra pgIna, combInamos las
etIquetas <img> y <a>:

<a href="inicio.html" target="_blank"><img alt="Mi imagen" border="0"
height="100" width="120" src="imagen.jpg" /></a>

En el ejemplo, el enlace abrIr una nueva ventana del navegador cuando el usuarIo presIone
sobre la Imagen, porque se especIfIca el atrIbuto target con el valor "_blank".


2JS!7.H$.,!
Una tabla nos permIte representar datos ordenados por fIlas y columnas, sern muy utIles, por
ejemplo para consultar una base de datos y mostrar los resultados organIzados en el navegador.
Las tablas HT|L se arman IndIcando fIlas y celdas dentro de ellas. A su vez, en las celdas se
encontrarn los datos y contenIdos que desea ordenar.
En el cuadro anterIor vImos las etIquetas y atrIbutos de una tabla con un ejemplo, ahora
veremos ms en detalle como se arma una tabla.
Tenga en cuenta que:

<table> comIenza la tabla (table: tabla)
<tr> comIenza una fIla (tr: table row o fIla de la tabla)
<td> comIenza una celda (td: table data o datos de la tabla)

Una fIla debe estar dentro de la tabla y una celda dentro de la fIla. 0entro de una tabla puede
haber varIas fIlas y dentro de una fIla puede haber varIas celdas. La cantIdad de celdas defInIr
la cantIdad de columnas.
TambIn puede haber tablas dentro de otras tablas, lo que llamamos tablas anIdadas.

A contInuacIon construIremos una tabla muy sencIlla como la que se ve en la fIgura de abajo:




20

Para comenzar a construIr la tabla, prImero abrImos la etIqueta <table> con sus
correspondIentes atrIbutos y dentro de ella abrImos una fIla, <tr>:

<table border="1">
<tr>


0entro de <tr> se dIbujarn las celdas de esa prImera fIla.
La prImera celda se abre con <td> y, luego de que se agregue su contenIdo, se cIerra con
</td>:

<table border="1">
<tr>
<td> contenido de la fila 1 celda 1 </td>


Ahora se podr abrIr una nueva celda en la mIsma fIla. Hasta que la fIla no tenga completa la
totalIdad de celdas, no debe cerrarse:

<table border="1">
<tr>
<td> contenido de la fila 1 celda 1 </td>
<td> contenido de la fila 1 celda 2 </td>


Una vez completas las celdas de la prImera fIla, podemos cerrarla y abrIr una nueva:

<table border="1">
<tr>
<td> contenido de la fila 1 celda 1 </td>
<td> contenido de la fila 1 celda 2 </td>
</tr>
<tr>


21


Ahora se repIten los pasos anterIores para agregar las celdas a la segunda fIla:

<table border="1">
<tr>
<td> contenido de la fila 1 celda 1 </td>
<td> contenido de la fila 1 celda 2 </td>
</tr>
<tr>
<td> contenido de la fila 2 celda 1 </td>
<td> contenido de la fila 2 celda 2 </td>
</tr>

Una vez que la tabla tIene todas sus fIlas, se cIerra con </table>:

<table border="1">
<tr>
<td> contenido de la fila 1 celda 1 </td>
<td> contenido de la fila 1 celda 2 </td>
</tr>
<tr>
<td> contenido de la fila 2 celda 1 </td>
<td> contenido de la fila 2 celda 2 </td>
</tr>
</table>



El resultado en el navegador ser el sIguIente:



Adems de las etIquetas <td>, tambIn exIsten las etIquetas de encabezado de una tabla:
<th>.
Esta etIqueta funcIona como cabecera y la unIca dIferencIa con la etIqueta <td> es que le da
formato de negrIta al texto:

<table border="1">
<tr>
<th> contenido de la fila 1 celda 1 </th>
<th> contenido de la fila 1 celda 2 </th>
</tr>
<tr>

22

<td> contenido de la fila 2 celda 1 </td>
<td> contenido de la fila 2 celda 2 </td>
</tr>
<tr>
<td> contenido de la fila 3 celda 1 </td>
<td> contenido de la fila 3 celda 2 </td>
</tr>
</table>

Y en el navegador se ver de la sIguIente manera:




2JW!N#+=<$.+'#,!
Los formularIos nos sIrven para IntercambIar InformacIon con los vIsItantes del sItIo. Son los
elementos ms utIlIzados en sItIos que apuntan al concepto de Web 2.0, ya que permIten a los
usuarIos realIzar gran cantIdad de accIones: comprar un articulo, rellenar una encuesta, envIar
un comentarIo, etc.
En el presente texto sern de prImordIal ImportancIa para la creacIon de pgInas InteractIvas y
dInmIcas.
Los formularIos se defInen entre las etIquetas <form> y </form>. 0entro de ellas se
encontrarn todos los campos, botones y objetos que componen al mIsmo.
Los datos de un formularIo se envian para que sean procesados. No entraremos en detalles sobre
el procesado, ya que lo estudIaremos en las proxImas herramIentas.
Las etIquetas <form> tIenen atrIbutos que IndIcan al formularIo quIn lo procesar, como ser
el envio de datos y de qu forma. Todos los campos que se encuentren dentro de estas etIquetas
y sus valores, sern los que se envien para su posterIor tratamIento. Los valores de los campos
sern los que IndIque el usuarIo al momento de completarlos.
Los atrIbutos ms Importantes de <form> son: action, method y enctype. 7eamos un
ejemplo de la etIqueta completa:

<form action="procesa.php" method="post" enctype= "application/x-www-form-
urlencoded">

El atrIbuto action es el que IndIca quIn va a recIbIr los datos del formularIo, su valor es
opcIonal. En l se escrIbe la UFL de la pgIna que lo procesar. SI no escrIbe nInguna UFL, los
datos se envIarn, por defecto, a la mIsma pgIna del formularIo.

El atrIbuto method IndIca el mtodo segun el cual se transfIeren los datos, puede ser GET o
POST. Los desarrollaremos en las proxImas herramIentas.

El atrIbuto enctype del elemento <form> especIfIca el tIpo de contenIdo usado para codIfIcar
el conjunto de datos para su envio al servIdor.
En pocas palabras, especIfIca la codIfIcacIon de los datos al ser envIados. Su valor por defecto es
"application/x-www-form-urlencoded". En la sItuacIon profesIonal J amplIaremos este
tema.

Los objetos ms usados del formularIo pueden ser de entrada (Input) o de seleccIon (select); los
objetos Input a su vez pueden ser de dIversos tIpos. Dbserve en el cuadro sIguIente algunos tIpos
de objetos de entrada:


2J

7'T#!K%!d')T<-e! f',-.!%)!%K'-#+! 0Y%=T$#!K%!DEK'&#!
-%b-: campo de texto.

Input type=text name=apellIdo /
-%b-.+%.: rea de texto. textarea name=mensaje cols=45
rows=57alor InIcIal/textarea
DV%D^H#b: casIlla de
verIfIcacIon.

Input name=consolas type=checkbox
value=W /
+.K'#: boton de opcIon.

Input type=radIo name=formapago
value=efectIvo /
V'KK%): campo oculto.

Input name=Info type=hIdden
value=valor oculto/
F'$%: campo de archIvo.

Input type=fIle name=archIvo/
,<H='-: boton de envio.!

Input type=submIt name=button
value=EnvIar /

Dbserve que todos los objetos comIenzan con la etIqueta <input> y tIenen atrIbutos en comun:
type y name. SI bIen, el objeto "textarea" no comIenza con la etIqueta <input>, no deja de
ser un objeto de entrada.

El atrIbuto type IndIca el tIpo de objeto de entrada y name es el nombre que podemos asIgnar
para IdentIfIcar los datos Ingresados por el usuarIo.
Adems del atrIbuto name, exIste el atrIbuto id que especIfIca un IdentIfIcador unIco para el
elemento, lo que facIlIta dar estIlos vIsuales especifIcos a cada elemento, entre otras cosas.

El atrIbuto value es opcIonal y puede aplIcarse a algunos elementos. Este valor es el que
recupera la pgIna que procesa el formularIo una vez envIada. Lo recupera medIante el nombre
del elemento, esto sIgnIfIca que no debe haber atrIbutos name repetIdos.

Cuando un usuarIo completa los campos text y textarea, se modIfIca el atrIbuto value, por los
datos tIpeados. Lo mIsmo ocurre al Interactuar con los dems elementos del formularIo.

El campo de entrada hIdden es un campo que no ser vIsIble en el navegador y el usuarIo no
podr modIfIcar su valor. Es utIl cuando se quIere transmItIr InformacIon extra del formularIo.

Los campos checkbox sIrven para presentar una o varIas opcIones al usuarIo que podr marcar
una, nInguna o todas ellas.

Los campos de radIo sIempre se encuentran en grupos y el usuarIo solamente podr elegIr uno de
todos ellos.

La transmIsIon de archIvos a un servIdor se realIza con el campo fIle. SI el usuarIo presIona sobre
el boton examInar, se abre el cuadro de dIlogo de su sIstema operatIvo para que seleccIone el
archIvo que va a cargar.

El objeto submIt es el boton que realIza el envio del formularIo una vez que se completaron los
datos.

El campo de seleccIon comIenza con la etIqueta <select> y presenta una lIsta de opcIones del
tIpo menu que permIte seleccIonar una (o varIas) de las multIples opcIones que propone.
Un select puede ser de dos tIpos: menu y lIsta.
El select del tIpo menu presenta opcIones desplegables. Y el tIpo lIsta las muestra como un
lIstado, cuya altura se fIja en el atrIbuto size. 7eamos ejemplos:

24



7'T#! f',-.!%)!).*%&.K#+! 0Y%=T$#!K%!DEK'&#!
A%)g

normcl

despleycdo
select name=cIudades
optIon value=CDCordoba/optIon
optIon value=|E|endoza/optIon
optIon value=SJSan Juan/optIon
/select
P',-.

select name=cIudades sIze=J
optIon value=CDCordoba/optIon
optIon value=|E|endoza/optIon
optIon value=SJSan Juan/optIon
/select

Ahora que ya sabe como se escrIbe el codIgo HT|L, en las proxImas herramIentas aprender a
generarlo desde un scrIpt del lado del servIdor, y amplIar lo aprendIdo sobre formularIos con
una vIsIon ms global de su uso para transmItIr datos.

25

@<-#%*.$<.D'E)!2!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!

3 Dbserve el codIgo HT|L sIguIente:

<p>Esto es HTML!...</p>

Este codIgo mostrar el resultado que est a contInuacIon en la pantalla de un navegador:

Esto es HTML!...

` ` 7erdadero ` ` Falso


2 El sIguIente codIgo HT|L representa una estructura vlIda:

<html>
<body>
<head>
<title>Ttulo del documento</title>
Esto se ve en el navegador.
</head>
Cuerpo del documento
</body>
<html/>

` ` 7erdadero ` ` Falso


Q El codIgo del punto 2 mostrar el sIguIente resultado en la pantalla de un navegador:

Esto se ve en el navegador. Cuerpo del documento

` ` 7erdadero ` ` Falso


S El atrIbuto action de una etIqueta de formularIo es el que IndIca quIn va a recIbIr los datos
envIados, su valor es opcIonal y, sI este atrIbuto no se especIfIca, los datos son envIados a la
mIsma pgIna del formularIo.

` ` 7erdadero ` ` Falso



Las respuestas las encontrar al fInal de la sItuacIon profesIonal.

26

Q!@H#+K.)K#!>I>!W
En la sItuacIon profesIonal que se le plantea, debe programar pgInas dInmIcas para poder
cumplIr con los requerImIentos solIcItados. Para ello debe aprender a programar en un lenguaje
que funcIone del lado del servIdor. ExIsten muchos lenguajes de scrIpt del servIdor, pero uno de
los ms dIfundIdos y estndar del mercado es PHP, que estudIaremos a contInuacIon.


QJ3!/)-+#K<DD'E)!.!>I>!W!
PHP es el acronImo de Hypertext PreProcessor y consIste en un lenguaje Interpretado IncluIdo en
pgInas web, y ejecutado en el servIdor. Es una herramIenta para realIzar sItIos dInmIcos y
tIene la ventaja, sobre otros lenguajes, de ser un software de codIgo abIerto, lIbre y gratuIto
para uso comercIal. Adems, posee la mayor comunIdad de desarrolladores y soportes en linea,
con una amplIa documentacIon en su pgIna ofIcIal: www.php.net
Es un software multIplataforma, puede ejecutarse en los prIncIpales sIstemas operatIvos del
mercado: LInux, UnIx (Incluyendo HPUX, SolarIs y Dpen8S0), |Icrosoft WIndows, |ac DS, FSC
DS. Soporta la mayoria de servIdores web de hoy en dia, Incluyendo Apache, |Icrosoft nternet
nformatIon Server, Personal Web Server, Netscape e IPlanet, DreIlly WebsIte Pro server,
CaudIum, XItamI, DmnIHTTPd y muchos otros.
Cuenta con una extensa lIbreria de funcIones que facIlItan formIdablemente el trabajo de los
desarrolladores.

Qu podemos hacer con PHP:

- Funcones de correo electronco: podemos envIar un emaIl a una persona o lIsta
parametrIzando toda una serIe de aspectos tales como el emaIl de procedencIa, asunto,
persona a responder, entre otras.
- 6eston de bcses de dctos: a partIr de las cuales podremos edItar el contenIdo de nuestro
sItIo con extrema facIlIdad y rapIdez.
- CestIon de archIvos: crear, borrar, mover, modIfIcar, leer... cualquIer tIpo de operacIon
puede ser realIzada a partIr de una amplIa lIbreria de funcIones para la gestIon de
archIvos.
- Trctcmento de mcyenes: evIdentemente resulta mucho ms sencIllo utIlIzar un edItor
grfIco para el tratamIento de Imgenes, pero por ejemplo, sI tenemos que tratar mIles
de Imgenes envIadas dIarIamente por los usuarIos, puede resultar muy tedIoso unIformar
en tamao y formato. Todo esto puede ser tambIn automatIzado efIcazmente medIante
PHP. TambIn puede parecer utIl el crear botones dInmIcos, es decIr, botones en los
que utIlIzamos el mIsmo dIseo y solo cambIamos el texto.
- Muchcs otrcs ]uncones pensadas para nternet como el tratamIento de D##^'%,! ,
accesos restrIngIdos, comercIo electronIco o para proposIto general como funcIones
matemtIcas, explotacIon de cadenas, de fechas, correccIon ortogrfIca, compresIon de
archIvos. A esta Inmensa lIbreria cabe ahora aadIr todas las funcIones personales que la
comunIdad de PHP va creando por necesIdades propIas y que, luego, son reutIlIzadas en
otros sItIos e IntercambIadas u obtenIdas en foros o sItIos especIalIzados.


Ayuda ahora
"##^'%,G!es un fragmento de InformacIon que se almacena en el dIsco duro del vIsItante de una pgIna
web a travs de su navegador, y contIene InformacIon que puede ser recuperada por el servIdor.

Una breve hIstorIa:

En 1994 Fasmus Lerdorf, IngenIero de software mIembro del equIpo Apache, crea un sIstema
programado en Perl para monItorear las vIsItas a su sItIo.

27

En 1995, debIdo a la demanda del scrIpt lIbera PHP, llamado Personal Home Page Tools, con
algunas pocas funcIones elementales: un analIzador de codIgo muy sencIllo, lIbro de vIsItas,
contador y algunas macros que facIlItaban el trabajo de los dIseadores.
A medIados de 1995 lanza PHP/F v2 (Form nterpreter) que Incluia un procesador de formularIos
y conexIon a una base de datos.
En 1997 se transforma en un proyecto de codIgo abIerto y se Incluyeron nuevas funcIonalIdades,
como el soporte a nuevos protocolos de nternet y el soporte a la gran mayoria de las bases de
datos comercIales. Todas estas mejoras sentaron las bases de PHP versIon J.
Poco despus, AndI Cutmans y Zeev SuraskI comenzaron a trabajar en la reescrItura del nucleo
de PHP. Los objetIvos de dIseo fueron mejorar la ejecucIon de aplIcacIones complejas, y
mejorar la modularIdad del codIgo base de PHP y el apoyo de una gran varIedad de bases de
datos.
Se crea el nuevo motor en 1999, apodado '|otor Zend' (comprImIdo de sus nombres, Zeev y
AndI), aportaba modularIdad, clarIdad y herramIentas de optImIzacIon para pgInas de gran
escala.
En el 2000 nace PHP 4.0, basado en este motor que mejora la ejecucIon y, adems, Incluia otras
caracteristIcas clave como el soporte para la mayoria de los servIdores web, manejo de fIcheros,
dIrectorIos, cadenas, X|L, grfIcos y muchas nuevas construccIones de lenguaje.
PHP 5 nace en el 2004, utIlIzando el motor Zend EngIne (o Zend EngIne 2) que mejora el
soporte para la >+#&+.=.D'E)! 9+'%)-.K.! .! 9HY%-#,! que, en versIones anterIores, era
extremadamente rudImentarIo, con PHP 0ata Dbjects.
|ejora el rendImIento, el soporte para AM1hP! , el soporte a iAP! ( XPath, 0D|, etc.). TIene
soporte natIvo para 1hP'-%! y muchas otras mejoras.
Est prevIsto el lanzamIento en breve de la versIon 6 de PHP, cuando esto pase, quedarn solo
PHP 5 y 6, se ha comunIcado que PHP 4 ha sIdo dIscontInuado desde el 1J de julIo de 2007.


Ayuda ahora
>+#&+.=.D'E)! 9+'%)-.K.! .! 9HY%-#,! #! >99! es un paradIgma de programacIon que usa objetos y sus
InteraccIones para dIsear aplIcacIones.
AM1hP!es un sIstema de gestIon de base de datos.
iAP (ExtensIble |arkup Language) es un lenguaje de marcas como el HT|L pero extensIble, no tIene
etIquetas predefInIdas sIno que las crea el programador, y sIrve para organIzar o estructurar datos. Fue
desarrollado por WJC.
1hP'-% es un sIstema de gestIon de bases de datos.!


QJ2!I%++.='%)-.,!)%D%,.+'.,!T.+.!D#=%)c.+!D#)!>I>!W!
El prImer paso para programar en PHP 5 es dIsponer de un servIdor para hacer pruebas antes de
publIcar los scrIpts a los usuarIos.
PHP 5 se dIstrIbuye como codIgo abIerto, lIsto para D#=T'$.+! %)! %$! ,',-%=.! #T%+.-'*#! que
quIera, pero su InstalacIon es complIcada sI nunca ha compIlado un programa. Por ello,
utIlIzaremos paquetes ya compIlados que solo necesItan ser Instalados para comenzar a
funcIonar en un sIstema de WIndows.


Ayuda ahora
"#=T'$.+! %)! %$! ,',-%=.! #T%+.-'*#G! es el proceso de traduccIon de un codIgo fuente (escrIto en un
lenguaje de programacIon de alto nIvel) a lenguaje mquIna (codIgo objeto), para que pueda ser
ejecutado por la computadora.

Uno de los paquetes ms completos y fcIles de Instalar es el AppServ, ste confIgura las
aplIcacIones del servIdor de manera automtIca. Se puede descargar de su sItIo ofIcIal:

28


www.appservnetwork.com

Dtro paquete muy completo y sencIllo es XA|PP, que puede funcIonar desde cualquIer
dIsposItIvo portable US8. Se puede descargar de:

www.apachefrIends.org/en/xamppwIndows.html.

En este caso, descargamos AppServ 2.5.9 para su InstalacIon. 7eamos qu componentes Incluye
este paquete:

- Apache 2.2.4
- PHP 5.2.J
- |ySQL 5.0.45
- php|yAdmIn2.10.2

Apache 2.2.4: es el servIdor web que gestIona las petIcIones HTTP de los clIentes.
PHP 5.2.J: la versIon del Intrprete.
|ySQL 5.0.45: es un sIstema de gestIon de base de datos, en la proxIma sItuacIon profesIonal
conocer ms en detalle esta herramIenta.
php|yAdmIn 2.10.2: es una herramIenta programada en PHP para manejar la admInIstracIon de
|ySQL a travs de pgInas webs. Al Igual que |ySQL, tambIn la estudIar ms adelante.

Una vez que descargue el paquete de AppServ, ejecutelo, y sIga los sIguIentes pasos:



1 Pantalla de bIenvenIda: PresIone "Next "


29



2 Acuerdo de lIcencIa: AppServ es de dIstrIbucIon bajo lIcencIa CNU/CPL. 0ebe leer. SI est de
acuerdo con la lIcencIa, haga clIc en " Agree" para Ir al paso sIguIente.



J SeleccIon del dIrectorIo de InstalacIon: la ubIcacIon predetermInada es C:\AppServ. SI quIere
cambIar de destIno haga clIc en "8rowse.", elIja otra carpeta y a contInuacIon, haga clIc en
"Next " para Ir al paso sIguIente.


J0



4 SeleccIon de componentes que desea IncluIr en la InstalacIon: por defecto estn seleccIonados
todos los componentes del paquete.
En nuestro caso, Instalaremos todos los componentes asi que haga clIc en el boton "Next ".



5 ConfIguracIon de Apache: debe especIfIcar la confIguracIon del servIdor web Apache.
En "Server Name" escrIba la UFL del servIdor, para este caso escrIbImos localhost ya que lo
Instalamos en modo local.
En "AdmInIstrator's EmaIl Address" escrIba su dIreccIon de emaIl.
En "Apache HTTP Port" especIfIque el puerto HTTP de Apache Web Server, por defecto es 80
pero sI tIene Instalado otro servIdor escrIba un numero dIferente, por ejemplo 88. Luego
presIone "Next ".


J1



6 ConfIguracIon de |ySQL: debe especIfIcar la contrasea para acceder a la base de datos
|ySQL. Por defecto la contrasea es root. El resto lo dejamos como est. PresIone "Next ".



7 Ahora comenzar la InstalacIon. SI aparece un mensaje emergente como el de abajo:


J2



PresIone "Unblock" o "0esbloquear".



8 nstalacIon de AppSerrv completada: sI deja seleccIonadas ambas casIllas, se InIcIar el
servIdor y la base de datos. Asi haremos.
Haga clIc en "FInIsh" para poner fIn a esta InstalacIon y se InIcIar AppServ.

Para comprobar que est funcIonando el servIdor, debe Ingresar la UFL de su sItIo local en la
barra de dIreccIones del navegador web:

http://localhost o 127.0.0.1

SI elIgIo un puerto dIstInto del 80 (paso 5), debe escrIbIr a contInuacIon de la UFL, dos puntos y
el numero de puerto seleccIonado. Por ejemplo:

http://localhost:88 o 127.0.0.1:88

Esta dIreccIon lo llevar a la pgIna "Index.php" del servIdor. Habr notado que no est
especIfIcada la pgIna en la UFL de los ejemplos de arrIba. Esto se debe a que los servIdores,

JJ

por confIguracIon predetermInada, buscan el "Index.php", "Index.html", "default.php",
"default.html", etc., cuando no se especIfIca una pgIna en la UFL.
SI el servIdor funcIona, se mostrar la pgIna de InIcIo de AppServ:



Esta pgIna contIene InformacIon sobre el paquete Instalado. El prImer enlace corresponde al
acceso al admInIstrador web de la base de datos, ms adelante Ingresaremos a l para crear una
base de datos.
El segundo enlace "PHP nformatIon." conduce a la InformacIon del Intrprete de PHP que est
corrIendo en Apache:



En ella encontrar las especIfIcacIones sobre el estado actual de PHP. Esto Incluye InformacIon
sobre las opcIones de compIlacIon y extensIones de PHP, la versIon PHP, InformacIon y entorno
del servIdor, el entorno PHP, InformacIon sobre la versIon del S.D., rutas, opcIones de
confIguracIon maestras y locales, cabeceras HTTP, y la LIcencIa PublIca CNU. A medIda que
avancemos en el presente texto, Iremos notando las opcIones de confIguracIon ms relevantes
para el uso de cIertas funcIones del lenguaje.


J4

Para acceder al dIrectorIo de archIvos del servIdor, Ingresamos a la carpeta de InstalacIon de
AppServ. En este caso es "C:\AppServ". En ella encontrar los sIguIentes fIcheros:


La carpeta "www", pertenece a la raiz de su servIdor y en ella
colocar todos los archIvos del sItIo que programe.
Cada vez que Ingrese a localhost desde el navegador, el protocolo
HTTP de Apache, buscar la pgIna petIcIonada, dentro de esta
carpeta.

El servIdor Instalado en su ordenador, es solamente para realIzar pruebas antes de Instalar el
sItIo completo en un servIdor remoto. 0eber tener en cuenta la compatIbIlIdad de funcIones
entre versIones de aplIcacIones del servIdor local y las del servIdor remoto.

SI ya Instalo el servIdor local, ahora necesIta un edItor de texto para escrIbIr sus pgInas en PHP.
Podria utIlIzar un edItor sencIllo como el NotePad de WIndows pero lo recomendable es dIsponer
de uno que minImamente destaque con color la sIntaxIs del codIgo fuente, para facIlItar su
escrItura, lectura y depuracIon. El ms sencIllo de ellos es el NotePad 2. Dtros edItores ms
avanzados pueden ser EdItPlus y Zend StudIo. En nuestro caso utIlIzaremos Adobe 0reamweaver
que, adems de permItIrnos la escrItura del codIgo, nos facIlIta el maquetado de sItIos web a
travs de una Interfaz grfIca.

Ahora que ya tIene su servIdor en modo local y un edItor de codIgo, aprender algunos prIncIpIos
muy bsIcos sobre programacIon, para luego comenzar a estudIar el lenguaje PHP.


QJQ!>+')D'T'#,!HO,'D#,!K%!T+#&+.=.D'E)!
La programacIon consIste en escrIbIr detalladamente las InstruccIones que debe seguIr un
ordenador para realIzar una tarea, en un lenguaje comprensIble para l.
Los ordenadores carecen de sentIdo comun, entonces los programadores no deben dejar nada
lIbrado al azar, deben cubrIr todos los posIbles casos que puedan ocurrIr. SI por ejemplo,
queremos que un ordenador se encargue de alImentar una mascota, tendriamos que darle las
sIguIentes InstruccIones:

1. Tomar la bolsa de alImento para mascotas.
2. Agregar 200 gramos al comedero de la mascota.
J. 0ejar la bolsa en su lugar de orIgen.
4. Fecoger el bebedero de la mascota.
5. 7erter medIo lItro de agua en el bebedero.
6. 0ejar el bebedero en su lugar de orIgen.

Estas InstruccIones parecen sufIcIentes como para que un ordenador, pueda seguIrlas. SIn
embargo, hay sItuacIones que no estn prevIstas y que podrian ocasIonar algun problema. Por
ejemplo, sI el recIpIente para el agua de la mascota estuvIera lleno, una persona con el minImo
uso de la razon sabria que no debe verter ms agua en l. Lo mIsmo ocurre con la cantIdad de
comIda que hay en el comedero.
Es por eso que los programas deben prever cualquIer eventualIdad. Entonces, el conjunto de
InstruccIones anterIores deberia quedar de la sIguIente forma:

J5


1. SI no hay alImento en el comedero de la mascota:
Tomar la bolsa de alImento para mascotas.
Agregar 200 gramos al comedero de la mascota.
0ejar la bolsa en su lugar de orIgen.
2. SI no hay agua en el bebedero de la mascota:
Fecoger el bebedero de la mascota.
7erter medIo lItro de agua en el bebedero.
0ejar el bebedero en su lugar de orIgen.

0e esta manera, le estamos dando al programa la capacIdad de decIdIr. Cuantas menos
probabIlIdades tenga nuestro programa de fallar, ms efIcIente ser. Podriamos consIderar en las
InstruccIones anterIores, la antIguedad del agua del bebedero, la lImpIeza de los recIpIentes, la
cantIdad de comIda de la bolsa, etc.
Esta es la tarea ms dIficIl del programador, prever las posIbles fallas.

magInemos que las InstruccIones del prImer ejemplo son escrItas para que las ejecute el
Intrprete de PHP. ste las leer una a una de prIncIpIo a fIn; es decIr desde el paso 1 hasta el
paso 6, ejecutando cada una de las ordenes dadas. Este conjunto de InstruccIones forman una
estructura secuencIal, ya que son procesadas en el mIsmo orden en el que se presentan.
En cambIo, en la estructura del segundo ejemplo, no ocurre lo mIsmo. SI bIen, se procesan los
pasos 1 y 2, no se ejecutan las InstruccIones IntermedIas sI no se cumplen las condIcIones de
estos pasos. Esta estructura de InstruccIones suele llamarse de decIsIon, ya que PHP deber
decIdIr la ejecucIon de los pasos IntermedIos segun el cumplImIento de la condIcIon Impuesta.

En PHP exIsten estructuras que permIten la secuencIa, la decIsIon y la IteracIon. La prImera de
ellas IndIca que las InstruccIones del codIgo se leern de prIncIpIo a fIn; la segunda IndIca que
segun cIertas condIcIones se ejecutarn o no un conjunto de InstruccIones; y la tercera IndIca
que, segun cIerta condIcIon, un numero de InstruccIones podrian repetIrse un numero
determInado de veces.
Para que pueda comprender la IteracIon, podemos cambIar el ejemplo de InstruccIones
anterIores de la sIguIente manera:

1. SI no hay alImento en el comedero de la mascota:
a. Tomar la bolsa de alImento para mascotas.
b. |Ientras no est lleno de alImento el comedero:
Agregar alImento al comedero de la mascota.
c. 0ejar la bolsa en su lugar de orIgen.
2. SI no hay agua en el bebedero de la mascota:
a. Fecoger el bebedero de la mascota.
b. |Ientras no est lleno de agua el bebedero:
7erter agua en el bebedero.
c. 0ejar el bebedero en su lugar de orIgen.

Para este caso "Ideal", observe que en 1 y 2, PHP debe tomar una decIsIon y en 1.b y 2.b, debe
realIzar una IteracIon.
En 1.b PHP, debe agregar alImento hasta llenar el comedero. Una vez lleno el comedero,
contInua con el paso 1.c.
En 2.b PHP, debe verter agua hasta llenar el bebedero. Cuando el bebedero est lleno, contInua
con el paso 2.c.

|s adelante amplIaremos este tema y aprender la sIntaxIs de las estructuras de control para
PHP.


J6

Como hemos vIsto en los ejemplos "ImagInarIos" anterIores, el Intrprete de PHP sIgue las
InstruccIones especIfIcadas. Pero en la realIdad esas InstruccIones tIenen que trabajar sobre
cIertos datos. PHP procesa una InstruccIon a la vez, por lo que necesIta guardar o deposItar en la
memorIa del ordenador, los dIversos datos con los que trabaja. El problema se resuelve con el
uso de varIables.
Una varIable consIste en una InformacIon que se guarda en la memorIa del ordenador y puede
ser accedIda a ella medIante un IdentIfIcador.
0e este modo, podriamos escrIbIr en un lenguaje fIctIcIo:

a=ProgramacIon
b= Web

Aqui tenemos dos varIables, a y b. Cada una de ellas contIene InformacIon de un determInado
tIpo. La varIable "a" posee un elemento de InformacIon de tIpo texto que es ProgramacIon.
AsImIsmo, la varIable b contIene el valor Web, tambIn del tIpo texto.

Podriamos defInIr una tercera varIable que fuese la suma de estas dos:

c=a+b

SI escrIbImos una InstruccIon para ImprImIr en la pantalla esta varIable, en nuestro lenguaje
fIctIcIo quedaria de la sIguIente manera:

mprImIr (c)

El resultado podria ser:

ProgramacIon Web

TambIn podriamos trabajar con varIables numrIcas de la sIguIente forma:

a=J
b=4
c=a+b
mprImIr (c)

El resultado en la pantalla seria:

7

La utIlIdad de las varIables quedar asentada en el transcurso de la sIguIente herramIenta.


J7

@<-#%*.$<.D'E)!Q!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!

3 PHP es el acronImo de Hypertext PreProcessor y consIste en un lenguaje Interpretado IncluIdo
en pgInas web, y ejecutado en el servIdor web.

` ` 7erdadero ` ` Falso

!
2 Antes de subIr archIvos a un servIdor remoto, es convenIente probar las aplIcacIones web de
PHP en un servIdor local.

` ` 7erdadero ` ` Falso


Q Los paquetes precompIlados como AppServ permIten Instalar fcIlmente el servIdor web, el
Intrprete de PHP, la base de datos y el servIdor de correo.

` ` 7erdadero ` ` Falso


S Una vez Instalado el servIdor local, podr acceder a una pgIna del mIsmo escrIbIendo, por
ejemplo C:/AppServ/www/mIpagIna.html en la barra de dIreccIones del navegador.

` ` 7erdadero ` ` Falso


W Dtra forma de Ingresar a una pgIna web del servIdor local, es escrIbIendo, por ejemplo
http://localhost/mIpagIna.html en la barra de dIreccIones del navegador clIente.

` ` 7erdadero ` ` Falso


X Podria crear una pgIna con codIgo PHP o HT|L utIlIzando el bloc de notas de su sIstema
operatIvo wIndows.

` ` 7erdadero ` ` Falso


[ Una varIable se almacena en la memorIa del ordenador clIente para que el servIdor web pueda
acceder a ella, medIante su IdentIfIcador, al procesar el codIgo PHP de la pgIna solIcItada.

` ` 7erdadero ` ` Falso



Las respuestas las encontrar al fInal de la sItuacIon profesIonal.

J8

S!>+#&+.=.D'E)!%)!>I>!W!
En las herramIentas anterIores conocIo las caracteristIcas del lenguaje PHP, se famIlIarIzo con
algunos prIncIpIos de programacIon y aprendIo a Instalar un servIdor de pruebas.
Para comenzar a programar las pgInas del sItIo solIcItado en la sItuacIon profesIonal, debe
aplIcar los prIncIpIos de programacIon en un lenguaje comprensIble para el servIdor de
aplIcacIones.
TambIn podr realIzar pruebas en su servIdor local, antes de Instalar el sItIo termInado en un
servIdor remoto.
Ahora veremos como escrIbIr comandos PHP para que el servIdor de aplIcacIones los ejecute y
sIga cada una de las InstruccIones que usted le IndIque, obtenIendo como resultado fInal, una
pgIna HT|L para el clIente o navegador web.


SJ3!P.!,')-.b',!%$%=%)-.$!
Antes de comenzar, tenga en cuenta que todas las pgInas que contengan codIgo PHP, deben
termInar con la extensIon ".php", para que sean reconocIdas como tal. Una pgIna con dIcha
extensIon, no ImplIca que no lleve codIgo HT|L o que solamente contenga InstruccIones en PHP.
0e hecho, generalmente se puede encontrar el codIgo PHP combInado con codIgo HT|L y hasta
JavascrIpt.

El servIdor de aplIcacIones de PHP ejecuta cada InstruccIon o comando de una pgIna PHP, en un
orden secuencIal. Las secuencIas de comandos se escrIben en bloques de codIgo que pueden ser
embebIdos dentro de un codIgo HT|L. Para Incrustar InstruccIones de PHP en una pgIna, se
debe IndIcar al Intrprete el InIcIo y fInal del bloque de comandos que deber procesar.
El InIcIo del bloque se IndIca con la etIqueta <?php y el fInal del mIsmo con ?>. Por ejemplo:

<html>
<head>
<title>Primer ejemplo de PHP</title>
</head>
<body>
<?php
echo "Comandos o instrucciones de PHP.";
//Forma general de embeber cdigo PHP
?>
</body>
</html>

Entre las etIquetas de InIcIo y cIerre se escrIben los comandos de PHP.
Dtra forma de hacer lo mIsmo de manera sImplIfIcada seria:

<html>
<head>
<title>Segundo ejemplo de PHP</title>
</head>
<body>
<?
echo "Comandos o instrucciones de PHP.";
//Forma simplificada de embeber cdigo PHP
?>
</body>
</html>

Ambos ejemplos causan el mIsmo resultado, pero la prImera es la forma ms comun de IndIcar
los bloques de PHP. ExIsten otras formas pero dependen de la confIguracIon del servIdor. Por
ahora nos manejaremos con las IndIcadas.

J9


En los ejemplos anterIores la palabra echo, es el comando bsIco para ImprImIr contenIdos en el
navegador. Esta sentencIa la utIlIzaremos cada vez que tengamos que mostrar algun dato o
resultado HT|L en el clIente, es decIr, cuando quIera generar contenIdo HT|L desde PHP. Su
nombre se orIgIna en la palabra eco en Ingles (se da eco de.).
Note que, adems, las InstruccIones fInalIzan con punto y coma.
En la tercera linea de los ejemplos, no se est IndIcando nInguna InstruccIon, en realIdad se ha
Insertado un comentarIo dentro del codIgo. Los comentarIos no son procesados por PHP, son
pasados por alto y sIrven como guia para los programadores, con ellos pueden IndIcar, por
ejemplo, de qu se trata el bloque. Son utIles para depuracIones de numerosas lineas de codIgo.
ExIsten comentarIos de una sola linea IndIcados con doble barra al comIenzo de la mIsma, y
comentarIos de varIas lineas IndIcados con /* al comIenzo y */ al fInal, por ejemplo:

<html>
<head>
<title>Tercer ejemplo de PHP</title>
</head>
<body>
<?php
echo "Comandos o instrucciones de PHP.";
/*
Este es
un comentario de
varias lneas y
es pasado por alto sin
ocasionar ningn efecto en
el resultado.
*/
?>
</body>
</html>

Dbserve el resultado del ejemplo en el navegador clIente:



Como puede aprecIar en el resultado, se produce la salIda del texto que se encuentra entre las
comIllas de la sentencIa echo y no se muestran los comentarIos aadIdos.
SI vIsualIza el codIgo fuente desde el navegador, observar que no hay nIngun codIgo PHP, solo
es HT|L puro, tal como lo IndIcamos durante el desarrollo de las herramIentas anterIores:

40


<html>
<head>
<title>Tercer ejemplo de PHP</title>
</head>
<body>
Comandos o instrucciones de PHP.</body>
</html>

El codIgo PHP queda oculto al usuarIo, el navegador clIente solamente recIbe HT|L, como
resultado del procesado de la pgIna dInmIca petIcIonada.


SJ2!f.+'.H$%,!M!-'T#,!K%!K.-#,!
Los ejemplos anterIores no efectuan nada que no pueda hacerse con HT|L estndar. Para
aprovechar la potencIa de PHP, necesItar aprender a manejar las varIables.
Como ya se IndIco anterIormente, una varIable es un contenedor que almacena un contenIdo en
la memorIa del ordenador servIdor. Las varIables en PHP comIenzan con el sIgno peso (S),
seguIdo del nombre de la varIable (contenedor) y, opcIonalmente, su valor (contenIdo). Por
ejemplo:

<?php
$mivariable="Esto es una variable";
?>

Luego del sIgno peso, el nombre de la varIable debe comenzar con cualquIer letra del alfabeto
Ingls o un sIgno de subrayado vlIdo. En el sIguIente ejemplo se muestran varIables InvlIdas:

<?php
$-mivariable="Esto no es una variable";
$1156="Esto no es una variable";
$5variable="Esto no es una variable";
$/mivariable="Esto no es una variable";
$.mivariable="Esto no es una variable";
?>

Dtro aspecto Importante a tener en cuenta sobre la escrItura de PHP, es que se trata de un
lenguaje sensIble a mayusculas y mInusculas. Entonces, una varIable llamada $mensaje es
totalmente dIferente a otra llamada $Mensaje, $menSaje, o $mensajE.

Hasta ahora hemos vIsto ejemplos de varIables que contIenen texto. A este tIpo de datos se los
denomIna cadenas de texto o strIng. Las cadenas de texto sIempre se encuentran entre comIllas
dobles o sImples. La dIferencIa entre una cadena con comIllas dobles y una con comIllas sImples
es que la prImera es analIzada por PHP. Este anlIsIs se basa en la busqueda de varIables y el
reemplazo de ellas por sus respectIvos valores. 7eamos un ejemplo:

<?php
$minombre="Alejandro";
$mensaje="Hola, mi nombre es $minombre.";
echo $mensaje;
?>

El resultado ser:

Hola, mi nombre es Alejandro.


41

Dbserve que, en la segunda linea, PHP reemplazo la varIable $minombre por su respectIvo
valor. En la tercera linea se ImprIme $mensaje con la varIable reemplazada.
SI en vez de utIlIzar comIllas dobles en el valor de $minombre, utIlIzamos comIllas sImples:

<?php
$minombre="Alejandro";
$mensaje='Hola, mi nombre es $minombre.';
echo $mensaje;
?>

El resultado ser:

Hola, mi nombre es $minombre.

Como puede ver, en este caso, PHP no ha reemplazado el valor de la varIable $minombre en la
segunda linea. Esto es asi ya que PHP no analIza las cadenas de texto que se encuentran entre
comIllas sImples.
Las cadenas entre comIllas dobles, permIten la utIlIzacIon de caracteres de escape. Los
caracteres de escape son necesarIos para poder representar caracteres especIales que, de otra
forma, no se podrian utIlIzar dentro de la cadena analIzada.
Por ejemplo, las comIllas dobles. SI quIsIramos ImprImIrlas en pantalla no podriamos ya que la
cadena comIenza y termIna con ellas. Al Insertar una comIlla doble dentro de la cadena, PHP la
daria por fInalIzada:

<?php
$mensaje="Estoy aprendiendo "PHP".";
echo $mensaje;
?>

Esto nos devolver en la pantalla del navegador:

Parse error: syntax error, unexpected T_STRING in D:\appserv\www\prueba.php on line 2

Un error de sIntaxIs en la linea de la varIable. La forma correcta de ImprImIr comIllas dentro de
la cadena del ejemplo seria con el carcter de escape o barra InvertIda delante de cada comIlla:

<?php
$mensaje="Estoy aprendiendo \"PHP\".";
echo $mensaje;
?>

El resultado ser:

Estoy aprendiendo "PHP".

0e la mIsma forma utIlIzariamos el carcter de escape para dar salIda al sIgno peso, sIn que PHP
lo consIdere una varIable:

<?php
$n="PHP";
$mensaje="La variable \$n vale $n";
echo $mensaje;
?>

Dbtendremos:


42

La variable $n vale PHP

Dtros caracteres de escape son:

\n alImentacIon o salto de linea.
\r retorno de carro (ENTEF)
\t tabulacIon
\\ se reemplaza por una barra InvertIda ('\').

En defInItIva, cada vez que escrIba cadenas de texto entre comIllas dobles, PHP la analIzar en
busca de varIables para reemplazarlas por su valor, y sustItuIr los caracteres de escape que
encuentre por los caracteres especIales que correspondan.

Adems de las cadenas de texto, exIsten otros tIpos de datos que puede contener una varIable.
A contInuacIon se muestran ejemplos de datos numrIcos que, a dIferencIa de las cadenas de
texto, no se delImItan por comIllas:

Numeros enteros o Integer:
<?php
$entero=25;
?>

Numeros decImales o de coma flotante, llamados double o float:
<?php
$decimal=25.5;
?>

Dtro tIpo de dato sImple muy utIlIzado son los valores booleanos o boolean que admIten dos
posIbles valores: verdadero o falso.
Los datos booleanos son utIlIzados para comprobar condIcIones, sI se cumplen o no. Por ejemplo:

<?php
$varboolean=true;
if ($varboolean){
echo "se cumple la condicin";
}
?>

En el ejemplo de arrIba, se muestra una estructura de control de decIsIon. Aunque todavia no
estudIo este tIpo de estructuras, advIerta que la mIsma permIte a PHP tomar una decIsIon segun
el valor booleano de la condIcIon que se encuentre entre los parntesIs de la mIsma. SI
$varboolean es verdadera (true) como en el ejemplo, PHP procesa la secuencIa de comandos
que se halla entre las llaves. En el caso contrarIo, sI tuvIera el valor false, sIgnIfIca que la
condIcIon no se cumple y PHP no procesa la secuencIa de comandos entre las llaves de la
estructura. |s adelante amplIaremos sobre estructuras de control.

ExIsten otros tIpos de datos que estudIaremos a medIda que avancemos con el aprendIzaje de
PHP.


SJQ!9T%+.K#+%,!
Los operadores, como su nombre lo IndIca, permIten realIzar dIversas operacIones con varIables
dentro del codIgo PHP. A contInuacIon estudIaremos los operadores dIsponIbles segun el tIpo de
datos con el que estemos trabajando.

( )

4J


9T%+.K#+%,!@+'-=j-'D#,!
9T%+.K#+! 6%,D+'TD'E)!
+ suma
- resta
* multIplIcacIon
/ dIvIsIon
% modulo

Con ellos podremos realIzar clculos matemtIcos, tal como se efectuan con una calculadora y
los utIlIzaremos para valores numrIcos:

<?php
$a=10;
$b=2;
$sumar=$a+$b; //12
$restar=$a-$b; //8
$multiplicar=$a*$b; //20
$dividir=$a/$b; //5
$modulo=$a%$b; //el resto de la divisin es 0
?>

9T%+.K#+!K%!"#)D.-%).D'E)!
!!"#$%&#'($%("#)#"*%)%'(+('*),&-'.!
9T%+.K#+! 6%,D+'TD'E)!
. concatenar (unIr) dos cadenas

Este operador se utIlIza para concatenar o unIr cadenas de texto:

<?php
$a="Programacin";
$b=" Web";
$cadena=$a.$b; //$cadena ahora vale "Programacin Web"
?>

Dtro ejemplo:

<?php
$a=' Web';
$cadena='Programacin'.$a; //$cadena ahora vale 'Programacin Web'
?>


9T%+.K#+%,!K%!"#=T.+.D'E)!
9T%+.K#+! 6%,D+'TD'E)!
== gual
=== gual y del mIsmo tIpo
!= 0IstInto
<> 0IstInto
< |enor
<= |enor o Igual
> |ayor
>= |ayor o Igual

Los operadores de comparacIon le permItIrn a PHP, realIzar comparacIones entre varIables o
valores, y a partIr de ellas, tomar decIsIones. Una comparacIon devuelve un valor booleano

44

(true o false) en caso de cumplIrse o no la condIcIon. |s adelante, estudIar estructuras de
control y comprender mejor el uso de stos.
Se debe dIferencIar entre el operador =, que se usa para asIgnar un valor a una varIable, y el
operador ==, usado para comparar dos varIables.

<?php
$num=10; //asigna el valor 10 a la variable $num

if ($num=="10"){ //compara el valor de $num con el valor"10", si son iguales, se
cumple la condicin y se procesa la lnea de abajo.
echo "se cumple la condicin";
}
//en este caso si se cumple

if ($num==="10"){ //compara el valor de $num con el valor "10", si son iguales
en valor y tipo de dato, se cumple la condicin y se procesa la lnea de abajo.
echo "se cumple la condicin";
}
//en este caso no se cumple porque el tipo de dato difiere.
?>


9T%+.K#+%,!K%!f.$#+%,!C##$%.)#,!!/0-,"+'.!
9T%+.K#+! 6%,D+'TD'E)!
|| o
&& y
! negacIon
XOR D exclusIvo

Puede encontrarse con sItuacIones en las que necesIte hacer varIas comparacIones seguIdas para
que se cumpla una determInada condIcIon. Los operadores logIcos permIten escrIbIr todas las
comparacIones en una sola. Cuando tenemos varIas condIcIones o varIables booleanas, podemos
operar de la sIguIente manera:

El operador o, representado por los caracteres ||, devuelve true sI al menos una es true.

El operador y, representado por los caracteres &&, devuelve true sI todas tIenen el valor
true.

El operador no, representado por el caracter !, cambIa el valor de una, de true a false o
vIceversa.

El operador XOR devuelve true sI una es true y la otra es false.

<?php
$num=10;

if ($num<15 && $num>5){ //si $num es menor que 15 y mayor que 5, se cumplen las
condiciones y se ejecuta la lnea de abajo.
echo "se cumplen las dos condiciones";
}
?>



el primer 10 es numerico, el segundo es string

45

9T%+.K#+%,!D#=H').K#,! ! !
9T%+.K#+! 6%,D+'TD'E)! 0Y%=T$#! 0;<'*.$%)D'.!
++ ncremento en uno Sn++ Sn=Sn+1
-- 0ecremento en uno Sn Sn=Sn1
+= suma Sa += Sb Sa = SaSb
-= resta Sa = Sb Sa = SaSb
*= multIplIcacIon Sa *= Sb Sa = Sa*Sb
/= dIvIsIon Sa /= Sb Sa = Sa/Sb
.= concatenacIon Sa .= Sb Sa = Sa.Sb

Los operadores combInados son una forma sImplIfIcada de operar sobre varIables.

<?php
$num=10;
$num++; //$num ahora vale 11
$cadena="Esto es";
$cadena.=" una concatenacin";//$cadena ahora vale "Esto es una concatenacin"
?>

A medIda que avancemos en los contenIdos del texto, comprender mejor el uso y aplIcacIon de
los operadores.


SJS!0,-+<D-<+.,!K%!D#)-+#$!
En la herramIenta J, estudIo prIncIpIos de programacIon y aprendIo que exIsten estructuras que
permIten al programa, decIdIr e Iterar sobre eventualIdades que puedan ocurrIr durante su
ejecucIon. Ahora aprender a escrIbIr estas estructuras, en lenguaje PHP, tambIn llamadas
sentencIas.
stas permIten elegIr, a PHP, dIferentes camInos en funcIon de los datos que evalua durante la
ejecucIon. ExIsten dos tIpos de estructuras de control:

- Estructuras de decIsIon.
- Estructuras de repetIcIon.

Las estructuras de decIsIon permIten evaluar una o varIas condIcIones y elegIr el camIno
correcto. EstudIaremos dos estructuras de decIsIon: if y switch.
Las de repetIcIon repIten un numero determInado de veces un conjunto de InstruccIones.
7eremos tres estructuras: for, while y do while. ExIste otra llamada foreach que estudIar
ms adelante.


SJSJ3!"#)K'D'#).$!'F!
Para comprender el condIcIonal if, comenzamos con un ejemplo cotIdIano:

"S el clumno termnc de estudcr lc herrcmentc 4, puede resolver lc stuccon pro]esoncl
cctucl."

Esta frase, puede ser escrIta en el lenguaje de PHP medIante la sIntaxIs del condIcIonal if.
EstudIemos prImero la sIntaxIs en PHP para luego traducIrla a dIcho lenguaje:

if (condicin){
instrucciones
}

+

46

La palabra if se refIere al "sI" condIcIonal de nuestra gramtIca. Las llaves serian la expresIon
"ejecutar esto". Solo sI se cumple la condIcIon, se ejecutarn las InstruccIones a contInuacIon
de las llaves. SI la condIcIon no se cumple, PHP no leer el codIgo escrIto entre las llaves.
La condIcIon se refIere a cualquIer expresIon evaluada como valor booleano.
Con if podemos construIr estructuras ms complejas:

if (condicin){
instrucciones
} else {
otras instrucciones
}

En este caso, sI se cumple la condIcIon se ejecutarn una serIe de InstruccIones, y sI no se
cumple se ejecutarn otras.
Y, de otra manera, podemos complejIzar un poco ms:

if (condicin 1){
primer grupo de instrucciones
} else if (condicin 2) {
segundo grupo de instrucciones
} else if (condicin 3) {
tercer grupo de instrucciones
} else {
cuarto grupo de instrucciones
}

El else es una parte opcIonal de la estructura y est dIcIendo: "sI no se cumplen las condIcIones
anterIores entonces ejecute las sIguIentes InstruccIones". Solo se puede usar un else por cada
estructura if.
El else if est dIcIendo: "sI no se cumple la condIcIon anterIor, y se cumple la condIcIon
actual, entonces ejecute el sIguIente grupo de InstruccIones".
SI no se cumple la condIcIon 1, entonces PHP no ejecuta el prImer grupo de InstruccIones y
contInua leyendo la estructura hasta que se cumpla alguna de las condIcIones y, en tal caso,
ejecutaria el grupo de InstruccIones correspondIente.
7olvamos al ejemplo de la frase IndIcada al prIncIpIo. Su traduccIon al PHP seria:

<?php
$HE_vistas=4;
if ($HE_vistas==4){
echo "Puede resolver la situacin profesional 1";
}
?>

En el ejemplo, PHP evalua la varIable $HE_vistas, sI tIene asIgnado el valor 4, entonces se
ejecuta la InstruccIon dando salIda al mensaje IndIcado y concluye el condIcIonal.
SI esta condIcIon no se cumple, PHP concluye la estructura condIcIonal sIn ejecutar la
InstruccIon.
Dbserve el uso de los operadores de comparacIon estudIados anterIormente.

Cada condIcIon Involucrada en una estructura de decIsIon devuelve un valor booleano. Esto es, sI
se cumple la condIcIon escrIta entre los parntesIs, PHP reemplaza esa condIcIon por el valor
booleano que corresponda, y el if sImplemente verIfIca sI hay un true o false para tomar la
decIsIon.
Como en el ejemplo anterIor, la varIable $HE_vistas tIene el valor 4, la condIcIon se cumple y
el codIgo anterIor seria equIvalente a:


47

<?php
if (true){
echo "Puede resolver la situacin profesional 1";
}
?>

Ahora probemos de cambIar la frase por esta otra:

"S el clumno termnc de estudcr lc herrcmentc 4, puede resolver lc stuccon pro]esoncl
cctucl, s no, debe termncr de estudcrlc."

Y en PHP quedaria de la sIguIente manera:

<?php
$HE_vistas=4;
if ($HE_vistas>=4){
echo "Puede resolver la situacin profesional 1";
}else{
echo "Debe terminar de estudiar la herramienta 4";
}
?>

En este caso, PHP evalua la varIable $HE_vistas, sI tIene asIgnado el valor 4 o cualquIer valor
superIor a 4, entonces se ejecuta la InstruccIon dando salIda al mensaje IndIcado y concluye el
condIcIonal.
SI esta condIcIon no se cumple, PHP, ejecuta las InstruccIones del else y concluye la estructura
condIcIonal. El else es la alternatIva para cuando todos los condIcIonales de la estructura
devuelven booleanos false.


SJSJ2!"#)K'D'#).$!,U'-DV!
Dtra estructura condIcIonal vlIda es switch, usada para ejecutar InstruccIones determInadas,
dependIendo del cumplImIento de casos muy especifIcos. En el sIguIente ejemplo se muestra la
sIntaxIs:

switch (expresin){
case posibleResultado1:
primer grupo de instrucciones
break;
case posibleResultado2:
segundo grupo de instrucciones
break;
case posibleResultado3:
tercer grupo de instrucciones
break;
default:
cuarto grupo de instrucciones
break;
}

Esta estructura comIenza recIbIendo una expresIon en la que podemos IncluIr el nombre de una
varIable, una comparacIon, etc. Cada vez que expresamos case IndIcamos los dIstIntos posIbles
resultados y, cuando se cumple alguno de stos, se ejecutan las accIones correspondIentes al
case.
Podemos decIr que switch evalua la expresIon y compara el resultado de dIcha expresIon con
los posIbles casos.

48

La sentencIa break sIrve para evItar el paso al sIguIente caso. La sentencIa default es el caso
predetermInado o por defecto, en caso de no cumplIrse nInguno de los casos anterIores.
Por ejemplo:

<?php
$HE_vistas=2;
switch ($HE_vistas) {
case 1:
echo "Le faltan 3 herramientas.";
break;
case 2:
echo "Le faltan 2 herramientas.";
break;
case 3:
echo "Le falta 1 herramienta.";
break;
default:
echo "Puede resolver la situacin profesional.";
}
?>

En el ejemplo, la sentencIa switch evalua la varIable $HE_vistas y verIfIca los posIbles casos,
hasta que encuentra el caso que coIncIda con el valor de ella, y ejecuta las InstruccIones
correspondIentes al mIsmo.
Dbserve que la varIable $HE_vistas InIcIalmente tIene asIgnado el numero 2, cuando switch
comIenza con el prImer caso, no ejecuta las InstruccIones del mIsmo porque no hay coIncIdencIa
entre el valor de la varIable y 1. Luego, contInua con el sIguIente caso en el que encuentra
coIncIdencIa entre el valor de ella y el valor especIfIcado en el caso, por lo tanto ejecuta las
InstruccIones que se encuentran dentro del caso. La sentencIa break evIta que switch contInue
la lectura de los dems casos.
SI la estructura switch no encontrara coIncIdencIa entre los posIbles casos, entonces ejecutaria
las InstruccIones de la sentencIa default.

A contInuacIon veremos estructuras repetItIvas de PHP, tambIn llamadas bucles. Cada una de
ellas se comporta de forma lIgeramente dIstInta, por lo que resultan utIles en sItuacIones
dIferentes.


SJSJQ!C<D$%!F#+!
Es utIlIzado cuando se sabe de antemano cuntas veces queremos repetIr las InstruccIones
contenIdas por el mIsmo:

for (valorInicial; condicin; incremento) {
grupo de instrucciones a repetir;
}

0onde "valornIcIal" es el valor de una varIable que se Ir Incrementando durante la ejecucIon
del bucle, dependIendo del Incremento especIfIcado. La condIcIon, referente a "valornIcIal", es
evaluada y el bucle se ejecuta mIentras se mantenga la verdad de la condIcIon.

Por ejemplo, supongamos que queremos ImprImIr en la pantalla todos los numeros del 1 al 5:

<?php
for ($i=1; $i<=5; $i++) {
echo "$i <br />";
}
?>

49


En el prImer parmetro del bucle declaramos una varIable $i con el valor InIcIal 1. El bucle se
ejecutar mIentras $i sea menor o Igual a 5. En cada repetIcIon de InstruccIones contenIdas
dentro del bucle, se Incrementa el valor de $i en una unIdad.
En defInItIva, el bucle ejecutar las InstruccIones cInco veces. El resultado vIsIble en el
navegador ser:

1
2
3
4
5


SJSJS!C<D$%!UV'$%!
El bucle while repIte las accIones contenIdas en la estructura del mIsmo, mIentras sea
verdadera su condIcIon:

while (condicin) {
grupo de instrucciones;
}

SI la condIcIon entre los parntesIs devuelve true, el bucle ejecuta el grupo de InstruccIones
contenIdas en el mIsmo. Luego vuelve a evaluar la condIcIon y sI nuevamente devuelve true,
volver a ejecutar las InstruccIones hasta que la condIcIon devuelva false.
Por ejemplo:

<?php
$i=1;
while ($i <= 5) {
echo "$i <br />";
$i++;
}
?>

En la prImera linea le asIgnamos el numero 1 a $i. Al comenzar el bucle, while evalua la
condIcIon, en este caso $i vale 1 ya que fue declarada con este valor. Entonces $i es menor
que 5, por lo tanto, se cumple la condIcIon y el bucle ejecuta las InstruccIones contenIdas en l.
Dbserve al fInal del bucle que la varIable $i se Incrementa en una unIdad, por lo que va a
cambIar su valor orIgInal a 2. Luego, while vuelve a evaluar la condIcIon, 2 menor que 5,
devolvIendo true, y ejecuta las InstruccIones hasta que la condIcIon deje de cumplIrse. El
resultado vIsIble en la pantalla ser el sIguIente:

1
2
3
4
5


SJSJW!C<D$%!K#!UV'$%!
Es sImIlar al bucle while, con la dIferencIa de que las InstruccIones contenIdas en l se
ejecutan una vez, y luego realIza la evaluacIon InIcIal de la condIcIon.


50

do {
grupo de instrucciones;
} while (condicin);

En este caso se ejecuta al grupo de InstruccIones, antes de comprobar la condIcIon. Es decIr,
que sI la condIcIon no se cumple, las InstruccIones sern ejecutadas solo una vez.

Por ejemplo:

<?php
$i=4;
do {
echo "$i <br />";
$i++;
} while ($i < 5)
?>

A $i le asIgnamos el numero 4. Al comenzar la estructura, se ejecutan las InstruccIones
contenIdas en ella, Incrementando $i en una unIdad, por lo que $i ahora vale 5. Luego while
evalua la condIcIon y sta le devuelve el valor false ya que $i vale 5, no es menor que 5, es
Igual. Por lo tanto, no ejecuta nInguna otra InstruccIon. El resultado vIsIble en la pantalla ser:

4

!
SJSJX!0,D.T.+!K%!<).!%,-+<D-<+.!
La sentencIa break dentro de cualquIer parte de un bucle o un condIcIonal, provoca la salIda
InmedIata de la estructura, tal como se estudIo en sentencIas condIcIonales. El sIguIente
ejemplo usa break para salIr de un bucle InfInIto:

<?php
$i=1;
while (true) {
if ($i>=5){
break;
}
echo "$i <br />";
$i++;
}
?>

En el ejemplo, se est devolvIendo true constantemente a la condIcIon del bucle, por lo que la
unIca manera de salIr del mIsmo seria a travs del condIcIonal que IndIcar cuntas veces se
desean repetIr las accIones. Cuando $i vale 5 se produce la escapatorIa del bucle.


SJW!@)'K.='%)-#!K%!%,-+<D-<+.,!K%!D#)-+#$!
En la prctIca, es normal encontrar o resolver problemas utIlIzando el anIdamIento de
estructuras, un ejemplo muy claro es el mostrado en la herramIenta anterIor, en l podr
observar una estructura condIcIonal dentro de una repetItIva. TambIn podr colocar
condIcIonales dentro de condIcIonales o bucles dentro de bucles o dentro de condIcIonales y
vIceversa. Usted podr anIdar tantas estructuras como sea necesarIo en su proyecto. 7eamos un
ejemplo sencIllo:
Supongamos que queremos mostrar en la pantalla del navegador todos los numeros pares del 1 al
200. Para ello podemos escrIbIr el sIguIente codIgo:


51

<?php
$i=1;
while ($i<=200) {
if (($i%2)==0){
echo "$i es divisible por 2<br />";
}
$i++;
}
?>

Y sI quIsIramos que se muestren los numeros dIvIsIbles por 2 y por J, del 1 al 200:

<?php
$i=1;
while ($i<=200) {
if (($i%2)==0){
if (($i%3)==0){
echo "$i es divisible por 2 y 3<br />";
}
}
$i++;
}
?>

Dbserve que estamos anIdando dentro del bucle, un condIcIonal y dentro de l, otro condIcIonal.
Aunque esta solucIon funcIona, exIsten mtodos mejores basados en operadores logIcos de
multIples condIcIones, unIndolas en un solo valor booleano.
Podemos transformar el codIgo anterIor:

<?php
$i=1;
while ($i<=200) {
if (($i%2)==0 && ($i%3)==0){
echo "$i es divisible por 2 y 3<br />";
}
$i++;
}
?>

En el ejemplo utIlIzamos el operador logIco "y". SI ambas condIcIones de cumplen, entonces el
condIcIonal encontrar un true y se ejecutarn las InstruccIones. SI una de las dos no se
cumple, entonces el condIcIonal encontrar un false y saltear las InstruccIones.
SI quIsIramos mostrar todos los numeros dIvIsIbles por 2 + por J, tendriamos que cambIar el
operador logIco "y" por "o" (||):

<?php
$i=1;
while ($i<=200) {
if (($i%2)==0 || ($i%3)==0){
echo "$i es divisible por 2 o 3<br />";
}
$i++;
}
?>

Podr utIlIzar tantos operadores logIcos como condIcIones quIera evaluar.
7eamos otro ejemplo, sI quIsIera mostrar todos los numeros del 1 al 200 que no sean dIvIsIbles
por 2 y por J, el codIgo anterIor seria:

52


<?php
$i=1;
while ($i<=200) {
if (!(($i%2)==0 && ($i%3)==0)){
echo "$i no es divisible por 2 y 3<br />";
}
$i++;
}
?>

Dbserve que se agrego el operador de negacIon, el cual InvIerte el resultado de la condIcIon.
TambIn se agrego un juego de parntesIs a toda la expresIon para que el operador de negacIon
la afecte a toda.
Entonces, cuando exIsta un numero dIvIsIble por 2 y por J, la expresIon arrojar un true, pero
ser InvertIdo por el operador de negacIon, por lo tanto el resultado ser false y la condIcIon
del if no se cumplIr.
En el caso de que el numero en cuestIon no sea dIvIsIble por 2 y por J, la expresIon arrojar un
false que ser InvertIdo por el operador de negacIon y el condIcIonal if recIbIr un true,
ejecutando la InstruccIon.


SJX!1.$'%)K#!K%$!.).$'c.K#+!K%!>I>!
Hasta ahora hemos vIsto las estructuras de control con ejemplos de bloques de PHP puro sIn la
posIbIlIdad de combInarlo con HT|L. Ahora veremos como Incrustar PHP dentro del codIgo HT|L
salIendo del analIzador sIntctIco del Intrprete.
Por ejemplo, supongamos que queremos mostrar una Imagen sI el valor de una varIable llamada
$mostrar es true. 0e acuerdo a lo aprendIdo, para usted, la solucIon correcta seria:

<?php
if ($mostrar){
echo '<img src="images/Imagen.jpg" />';
}
?>

Esta solucIon es vlIda pero no es clara. En PHP exIste una forma de realIzar lo mIsmo salIndose
del analIzador sIntctIco:

<?php if ($mostrar):?>
<img src="images/Imagen.jpg" />
<?php endif; ?>

Esta es una sIntaxIs alternatIva, aplIcable a todas las estructuras de control. La llave ( [ ) es
reemplazada por ( : ), y la llave ( ] ) por endif (o endwhile, endfor, etc., segun la
estructura).
El ejemplo anterIor, tambIn puede ser escrIto, salIendo del analIzador, con la sIntaxIs
tradIcIonal:

<?php if ($mostrar){?>
<img src="images/Imagen.jpg" />
<?php } ?>


SJ[!"#),-.)-%,!K%$!,',-%=.!M!T%+,#).$'c.K.,!
En PHP, adems de las varIables cuyos valores pueden cambIar, exIsten constantes que podemos
defInIr y otras que ya estn defInIdas por el sIstema.

5J

Las constantes del sIstema podemos Invocarlas con el comando echo sI conocemos el
IdentIfIcador de ellas:

<?php
echo PHP_VERSION; //versin actual de PHP
echo "<br />";
echo PHP_OS; //versin del sistema operativo donde corre PHP
echo "<br />";
echo PHP_LIBDIR; //carpeta en la que se encuentran instaladas las libreras de
PHP 5
?>

Estas devuelven valores referentes al nucleo del sIstema y del motor Zend. ExIsten muchas
constantes del sIstema que puede consultar en el sItIo ofIcIal de PHP:
http://cr2.php.net/mcnucl/es/reserved.constcnts.php

Las constantes personalIzadas son las que podemos defInIr y, a dIferencIa de las varIables,
mantIenen su valor durante toda la ejecucIon de una pgIna y no pueden ser modIfIcadas. En la
vIda real exIsten muchas constantes, tales como nombres de empresas, puntos de congelacIon y
ebullIcIon del agua, el numero pI ( ), etc.
Para defInIr una constante, utIlIzaremos la funcIon define() que acepta dos parmetros. El
prImero es el nombre de la constante, que se utIlIzar para referIrse a su valor. El segundo
parmetro es el valor de la mIsma:

define("NOMBRE_CONSTANTE","Valor");

Por ejemplo:

<?php
define("CARRERA","Diseo de Multimedios");
define("MATERIA","Programacin Web");
echo CARRERA;
echo "<br />";
echo MATERIA;
?>

Dbserve que se Invoca el nombre de las constantes para mostrar su valor medIante el comando
echo y su IdentIfIcador no lleva el sIgno $ delante de ellas.
En el ejemplo anterIor se utIlIzaron valores del tIpo texto, pero tambIn se pueden utIlIzar
numrIcos o booleanos.


SJk!N<)D'#)%,!T%+,#).$'c.K.,!
Una funcIon es un grupo de InstruccIones, bajo un mIsmo nombre, utIlIzada para realIzar una
tarea. Cada vez que necesIte ese grupo de InstruccIones, puede llamar a la funcIon que las
contIene, en vez de escrIbIr la mIsma tanda de InstruccIones.
Podemos dIvIdIr el proceso de aplIcacIon de funcIones en dos etapas: la creacIon de la funcIon
con sus InstruccIones y la ejecucIon o llamada de la funcIon creada.

La sIguIente sIntaxIs es utIlIzada para la creacIon de la funcIon:

function nombreDeFuncion(){
grupo de instrucciones
};


54

La palabra function es utIlIzada para construIr la funcIon, seguIda del nombre que le
asIgnamos para IdentIfIcarla. 0entro de la funcIon escrIbImos todas las InstruccIones que sean
necesarIas ejecutar al momento de llamarla.

Para ejecutar las InstruccIones de una funcIon, debemos llamarla por su IdentIfIcador seguIdo de
los parntesIs:

nombreDeFuncion();

Las funcIones pueden recIbIr valores de varIables medIante el uso de parmetros y, de esta
manera, aadImos la capacIdad de modIfIcar su comportamIento:

function nombreDeFuncion(parametro1, parametro2,){
grupo de instrucciones
};

Dbserve que los parmetros se encuentran entre parntesIs y separados por comas. Estos valores
recIbIdos en la funcIon son utIlIzados por las InstruccIones contenIdas en la mIsma.

Para llamar a una funcIon con parmetros, debe escrIbIr el IdentIfIcador seguIdo de los
parntesIs, dentro de los cuales, escrIbIr los parmetros:

nombreDeFuncion(parametro1, parametro2, ...);

Por ejemplo, sI necesIta calcular el volumen de una esfera varIas veces, es convenIente crear
una funcIon que lo calcule en vez de escrIbIr el codIgo cada vez que requIera este clculo. La
formula del volumen de una esfera es cuatro tercIos de pI ( ) por el radIo al cubo, entonces la
funcIon quedar de la sIguIente manera:

<?php
function volumen($r){
$v=(4/3)*M_PI*pow($r,3);
return $v;
}
?>

Dbserve que la funcIon recIbIr el parmetro $r, el radIo de la esfera, necesarIo para calcular el
volumen. Una vez calculado, devolver el valor medIante el comando return.
Entonces, cada vez que requIera calcular el volumen de una esfera, Invocar a la funcIon
creada, pasando el valor del radIo de la esfera en cuestIon:

<?php
echo volumen(6);
?>

Puede crear funcIones que no requIeran parmetros o que no estn oblIgadas a devolver un valor
medIante return.

La utIlIzacIon de las funcIones nos ofrece muchos benefIcIos al momento de programar: el codIgo
es ms fcIl de escrIbIr y leer, sIn duplIcacIones InnecesarIas. Adems, sI desea hacer cambIos,
solo hace falta realIzarlos en la funcIon y no en cada grupo de InstruccIones. Podemos reutIlIzar
porcIones de codIgo, abrevIar y ordenar la programacIon y muchas otras ventajas que Ir
descubrIendo a medIda que avance en el estudIo de la materIa.




55

SJl!m=H'-#!K%!*.+'.H$%,!
Ya estudIamos como escrIbIr varIables y funcIones, pero debemos tener en cuenta el "lugar"
donde se encuentra cada varIable para su acceso.
El mbIto de una varIable se refIere al rea en la que se conoce la varIable, es decIr, el lugar
donde fue declarada, desde donde podr acceder a ella.
Las varIables de un archIvo PHP permanecen accesIbles en todo el codIgo a partIr de la linea en
la que fueron defInIdas, pero las varIables declaradas dentro de una funcIon, solo sern vIsIbles
por ella, es decIr en el mbIto de la funcIon que las contIenen. A su vez, las funcIones tampoco
podrn acceder a las varIables defInIdas fuera de ellas.
Esto nos permIte tener varIables con el mIsmo nombre en dIferentes funcIones, hacIendo el
codIgo reutIlIzable. Pero hay ocasIones en las que se necesIta acceder a varIables de una
funcIon, para ello exIste la sentencIa global que modIfIca el mbIto de una varIable a global.
Su sIntaxIs es la sIguIente:

global $variable1, $variable2, , $variablen;

Las varIables que se convIerten a global, no necesarIamente deben estar declaradas, esto nos
permIte crear varIables dentro de funcIones y pasarlas al mbIto global.
Para comprender mejor el mbIto de varIables, veamos un ejemplo:

<?php
$a=6;
$b=5;
function suma(){
$resultado=$a+$b;
echo $resultado;
}
suma();
?>

En el ejemplo se declaran las varIables $a y $b. Luego creamos una funcIon que calcula la suma
de las varIables $a y $b. Cuando se Invoca la funcIon suma(), el resultado en la pantalla ser 0
(cero).
Esto se debe a que las varIables $a y $b estn defInIdas fuera de la funcIon y ella no puede
accederlas. Entonces la funcIon suma() no encuentra los valores de $a y $b, por lo tanto,
asume que su valor es cero. Las varIables $a y $b que estn declaradas fuera de la funcIon,
sern varIables dIferentes de las que utIlIza su mbIto.

Para que la funcIon pueda acceder a las varIables externas, debe aplIcar la sentencIa global:

<?php
$a=6;
$b=5;
function suma(){
global $a, $b;
$resultado=$a+$b;
echo $resultado;
}
suma();
?>

Ahora si, el resultado ser la suma de $a y $b: 11.
SI en algun lugar del codIgo, fuera de la funcIon suma(), quIsIramos utIlIzar a la varIable
$resultado, creada dentro de la funcIon, no tendria acceso ya que la mIsma ha sIdo creada en
el mbIto de la funcIon. Para ello, debe globalIzarla:


56

<?php
$a=6;
$b=5;
function suma(){
global $a, $b, $resultado;
$resultado=$a+$b;
echo $resultado;
}
suma();
echo "<br />";
echo $resultado;
?>


SJ3]!N<)D'#)%,!T+%K%F')'K.,!
Al Igual que las funcIones personalIzadas, las predefInIdas son funcIones que, al ser llamadas,
tambIn ejecutan una tarea concreta. La dIferencIa con respecto a las funcIones personalIzadas,
es que stas ya estn defInIdas y lIstas para ser usadas.
Cada funcIon tIene sus propIas caracteristIcas y algunas necesItan que se les pasen cIertos
valores.
En PHP exIsten mIles de funcIones agrupadas segun su aplIcacIon. Usted ya ha utIlIzado funcIones
predefInIdas en las herramIentas anterIores. Por ejemplo, cuando aprendIo a escrIbIr funcIones
personalIzadas, en el clculo del volumen de una esfera, utIlIzo la funcIon pow(). Esta funcIon
sIrve para realIzar clculos exponencIales y pertenece al grupo de funcIones matemtIcas.
0entro del grupo de estas funcIones, encontrar constantes matemtIcas como el valor del
numero pI ( ) con el IdentIfIcador M_PI. En cada grupo de funcIones puede encontrar
constantes predefInIdas relacIonadas a ellas.
Para darse una Idea de la cantIdad de grupos de funcIones que exIsten en PHP, puede Ingresar a:
http://www.php.net/mcnucl/es/]uncre].php
En esta pgIna de PHP encontrar un lIstado de todos los grupos de funcIones dIsponIbles.
A lo largo del presente texto estudIar dIversas funcIones, desde el manejo de varIables y
cadenas hasta funcIones para manejo de bases de datos, Imgenes, sesIones, etc.

Antes de ver algunas funcIones es convenIente que aprenda a Interpretar la defInIcIon de
funcIones del manual de PHP, ya que cada funcIon documentada est preparada para una
comprensIon rpIda de su uso y aplIcacIon sIn requerIr de ejemplos. Una vez que se acostumbre
a esta InterpretacIon, podr avanzar vertIgInosamente en el aprendIzaje de PHP.
Por ejemplo, sI necesIta una funcIon que verIfIque la exIstencIa de una varIable, seguramente y
por logIca, se dIrIgIr al grupo de funcIones de manejo de varIables. ConocIendo un poco de
Ingls, en este grupo encontrar la funcIon isset() y en su referencIa observar lo sIguIente:

sset - 0etermncr s unc vcrcble estc de]ndc

Esta es precIsamente la funcIon que necesIta para saber sI su varIable est declarada en el
codIgo de su pgIna. ngresando a la referencIa encontrar lo sIguIente:

(PHP 4, PHP 5)

Esta prImera referencIa IndIca en qu versIones de PHP est dIsponIble la funcIon en cuestIon.
Luego, en la descrIpcIon, encontrar la sIntaxIs de uso:

bool isset ( mixed $var [, mixed $var [, $... ]] )

La prImera palabra es bool, ella IndIca el valor que devolver la funcIon al ser aplIcada, en este
caso es un valor booleano. Esto sIgnIfIca que sI la varIable est defInIda, obtendr un true.
pero

57

Luego de bool se especIfIca el nombre de la funcIon. A contInuacIon del IdentIfIcador, se abre
parntesIs, esto supone que dentro de los parntesIs estarn las IndIcacIones de los parmetros
necesarIos para que la funcIon trabaje correctamente.
0entro de los parntesIs podr observar la palabra mixed y $var. Esto sIgnIfIca que debe pasar
como parmetro una varIable y su tIpo de dato puede ser cualquIera.
Dbserve adems, que dentro de los corchetes ( [ ] ) tambIn hay parmetros, todos ellos
separados por comas. Estos corchetes dIcen que opcIonalmente podr pasar los parmetros
IndIcados entre ellos. En este caso puede analIzar la exIstencIa de ms de una varIable.
7eamos como funcIona en la prctIca:

<?php
$miVariable="valor de mi variable";
if (isset($miVariable)) {
echo '$miVariable est definida';
}else{
echo '$miVariable no est definida';
}
?>

En este ejemplo el resultado ser:

$miVariable est definida

Este resultado se debe a que la funcIon isset() devuelve true para la condIcIon del if, ya
que la varIable est defInIda en la prImera linea.
SI por ejemplo, necesItara una funcIon que devuelva el numero de caracteres que tIene una
cadena de texto, deberia buscar dentro del grupo de funcIones de cadenas. ConocIendo un poco
de IdIoma Ingls, y con un poco de prctIca, puede deducIr el nombre de una funcIon que
obtenga la longItud de una cadena. PIense lo sIguIente: cadena en Ingls es "strIng" y longItud
es "length", la composIcIon coherente de estas dos palabras podrian formar algo asi como
"strlen" y, de hecho, exIste la funcIon strlen() que devuelve la longItud de una cadena de
texto. ngresando a su referencIa encontrar lo sIguIente:

(PHP 4, PHP 5)

Es decIr que estar dIsponIble para estas dos versIones de PHP.
En su descrIpcIon observar:

int strlen ( string $cadena )

SIempre, la prImera palabra IndIca el tIpo de dato devuelto por la funcIon, en este caso ser un
numero entero (Integer). Este numero corresponde a la cantIdad de caracteres de la cadena.
Entre los parntesIs obtendr la InformacIon de los parmetros que debe proporcIonar a la
funcIon. Como era de esperarse, por logIca, debe IndIcar la cadena a analIzar. A dIferencIa del
ejemplo anterIor, solamente admIte un parmetro y debe ser del tIpo strIng o texto.
7eamos un ejemplo de su aplIcacIon prctIca:

<?php
$miVariable="valor de mi variable";
$longitud=strlen($miVariable);
echo $longitud;
?>

En este ejemplo el resultado ser:

20

58


Esto sIgnIfIca que la cadena analIzada contIene 20 caracteres.
El ejemplo anterIor se podria haber escrIto de otra forma, producIendo el mIsmo resultado:

<?php
$longitud=strlen("valor de mi variable");
echo $longitud;
?>

Ahora veremos algunas funcIones utIles extraidas del manual de php.net, para que comprenda su
aplIcacIon, luego podr experImentar con otras funcIones y comprobar que el uso es sImIlar en
todos los casos, solamente debe tener en cuenta las IndIcacIones del manual para aplIcarlas, ya
que algunas tIenen cIertos requerImIentos, como por ejemplo, la InstalacIon de extensIones o
lIbrerias dll para su uso.

N<)D'#)%,!K%!=.)%Y#!K%!*.+'.H$%,!
Estas no requIeren bIblIotecas externas y su aplIcacIon es ms que obvIa. 7eamos algunas de
ellas:

1')-.b',!M!K%,D+'TD'E)! 0Y%=T$#!
bool ',,%- ( mIxed Svar [, mIxed Svar [, S... ]] )

0etermIna sI una varIable est defInIda.
if (isset($var)) {
echo '$var est definida';
}
bool %=T-M ( mIxed Svar )

0etermIna sI una varIable es consIderada vacia.
if (empty($var)) {
echo '$var es 0, una variable vaca, o no
est definida';
}
strIng &%--MT% ( mIxed Svar )

0evuelve el tIpo de la varIable Svar.
$var="valor de mi variable";
echo gettype($var);
voId <),%- ( mIxed Svar [, mIxed Svar [, mIxed
S... ]] )

0estruye las varIables especIfIcadas
unset($var);

Pruebe los ejemplos, amplie la InformacIon sobre estas funcIones en el manual de PHP, y
consulte por otras no especIfIcadas en esta tabla.

!
N<)D'#)%,!K%!D.K%).,!
No requIeren bIblIotecas externas y su aplIcacIon est dIrIgIda al manejo de cadenas de texto o
strIngs. 7eamos algunas de ellas:


1')-.b',!M!K%,D+'TD'E)! 0Y%=T$#!
Int ,-+$%) ( strIng Scadena )

0evuelve la longItud de la cadena IndIcada.
$cadena = 'abcdef';
echo strlen($cadena); // 6

$cadena = ' ab cd ';
echo strlen($cadena); // 7
Int ,-+T#, ( strIng Scadena , strIng Scaracter [,
Int SdesplazamIento ] )

0evuelve la posIcIon numrIca de la prImera
aparIcIon del caracter en la cadena.
$mi_cadena = 'abc';
$caracter = 'a';
$posicion = strpos($mi_cadena, $caracter);
echo $posicion;
strIng ,-+-#$#U%+ ( strIng Scadena )

0evuelve la cadena con todas sus letras en
mInusculas.
$cadena = "El vEloZ mUrcilAgo Hind ComA feliZ
CardillO y KiWi";
$cadena = strtolower($cad);
echo $cadena; //Salida: el veloz murcilago hind
coma feliz cardillo y kiwi

59

strIng ,-+-#<TT%+ ( strIng Scadena )

0evuelve la cadena con todas sus letras en
mayusculas.
$cadena = "El vEloZ mUrcilAgo Hind ComA feliZ
CardillO y KiWi";
$cadena = strtoupper ($cadena);
echo $cadena; //Salida: EL VELOZ MURCILAGO HIND
COMA FELIZ CARDILLO Y KIWI
strIng ,<H,-+ ( strIng Scadena , Int ScomIenzo
[, Int SlongItud ] )

0evuelve la porcIon de Scadena especIfIcada
por los parmetros ScomIenzo y SlongItud.
echo substr('abcdef', 1); // bcdef
echo substr('abcdef', 1, 3); // bcd
echo substr('abcdef', 0, 4); // abcd
echo substr('abcdef', 0, 8); // abcdef
echo substr('abcdef', -1, 1); // f

Pruebe los ejemplos, amplie la InformacIon sobre estas funcIones en el manual de PHP, y
consulte por otras no especIfIcadas en esta tabla.

N<)D'#)%,!K%!F%DV.!M!V#+.!
No requIeren bIblIotecas externas y su aplIcacIon est dIrIgIda al manejo de la fecha y hora del
servIdor en el que se ejecutan los scrIpts de PHP. 7eamos algunas de ellas:

1')-.b',!M!K%,D+'TD'E)! 0Y%=T$#!
Int -'=% ( voId )

0evuelve la hora actual medIda en numero de
segundos desde el Epoch UnIx (Enero 1 1970
00:00:00 C|T).
echo time();
strIng K.-% ( strIng Sformato [, Int
Smarca_de_tIempo ] )

0evuelve una cadena con formato de acuerdo a la
cadena de formato dada, usando el entero
Smarca_de_tIempo entregado o la hora actual sI no
se da una marca de tIempo. En otras palabras,
Smarca_de_tIempo es opcIonal y su valor
predetermInado es el valor de tIme().
echo date("d/m/Y");//imprime el da, mes y ao:
16/02/2008
echo date("H:i:s");//devuelve horas minutos y
segundos.
strIng ,-+F-'=% ( strIng Sformato [, Int
Smarca_de_tIempo ] )

0a formato a una hora/fecha local de acuerdo a
valores de localIdad.
setlocale(LC_TIME,"sp");
echo strftime("Este es el mes de %B y el da %A
en espaol");


Pruebe los ejemplos, amplie la InformacIon sobre estas funcIones en el manual de PHP, y
consulte por otras no especIfIcadas en esta tabla.

Dbserve el parmetro de la funcIon time(), "void", sIgnIfIca que no recIbe parmetros
"vacio".


N<)D'#)%,!=.-%=O-'D.,!
No requIeren bIblIotecas externas y su aplIcacIon est dIrIgIda al manejo de numeros enteros o
de coma flotante. 7eamos algunas de ellas:

1')-.b',!M!K%,D+'TD'E)! 0Y%=T$#!
number .H, ( mIxed Snumero )

0evuelve el valor absoluto de Snumero.
$abs = abs(-4.2);//4.2; (double/float)
$abs2 = abs(5);//5; (integer)
$abs3 = abs(-5);//5; (integer)
float ,') ( float Sarg )

0evuelve el seno del parmetro Sarg . El parmetro Sarg
se encuentra en radIanes.
echo sin(deg2rad(60));//0.866025403 ...

60

float K%&2+.K ( float Snumero )

ConvIerte a Snumero desde grados a su equIvalente en
radIanes.
echo deg2rad(45); // 0.785398163397
float F$##+ ( float Svalor )

0evuelve el sIguIente valor entero ms bajo,
redondeando Svalor sI es necesarIo.
echo floor(4.3); // 4
echo floor(9.999); // 9
echo floor(-3.14); // -4
float D%'$ ( float Svalor )

0evuelve el sIguIente valor entero mayor, redondeando
Svalor sI es necesarIo.
echo ceil(4.3);//5
echo ceil(9.999);//10
echo ceil(-3.14);//-3
float +#<)K ( float Sval [, Int SprecIsIon ] )

0evuelve el valor de Sval redondeado a la SprecIsIon
especIfIcada (numero de digItos despus del punto
decImal). SprecIsIon puede ser tambIn un valor
negatIvo o cero (el valor predetermInado).
echo round(3.4);//3
echo round(3.5);//4
echo round(3.6);//4
echo round(3.6, 0);//4
echo round(1.95583, 2);//1.96
echo round(1241757, -3);//1242000
echo round(5.045, 2);//5.05
echo round(5.055, 2);//5.06
Int +.)K ([ Int SmIn ], Int Smax )

SI es llamada sIn los argumentos opcIonales SmIn , Smax
, rand() devuelve un entero pseudoaleatorIo entre 0 y
FAN0_|AX. SI desea un numero aleatorIo entre 5 y 15
(InclusIve), por ejemplo, use rand (5, 15).
echo rand();//7771
echo rand(5, 15);//11
mIxed =.b ( mIxed Svalor1 , mIxed Svalor2 [, mIxed
SvalorJ... ] )

0evuelve el mayor de estos valores.
echo max(1, 3, 5, 6, 7);//7
echo max(0, 'hola');//0
echo max('hola', 0);//hola
echo max(-1, 'hola');//hola
mIxed =') ( mIxed Svalor1 , mIxed Svalor2 [, mIxed
SvalorJ... ] )

0evuelve el menor de estos valores.
echo min(2, 3, 1, 6, 7);//1
echo min(0, 'hola');//0
echo min('hola', 0);//hola
echo min('hola', -1);//-1

Pruebe los ejemplos, amplie la InformacIon sobre estas funcIones en el manual de PHP, y
consulte por otras no especIfIcadas en esta tabla.

!
N<)D'#)%,!K%!=',D%$O)%.!
No requIeren bIblIotecas externas y segun el manual de PHP, fueron colocadas aqui debIdo a que
no parecen ajustarse a nInguna otra categoria. 7eamos algunas de ellas:


1')-.b',!M!K%,D+'TD'E)! 0Y%=T$#!
bool K%F')% ( strIng Snombre , mIxed Svalor [,
bool SInsensIble_mayusculas_mInusculas ] )

0efIne una constante por nombre en tIempo de
ejecucIon. Esta funcIon fue estudIada
anterIormente, aprecIe la sIntaxIs del manual de
PHP.
define("CONSTANTE", "Hola mundo.");
echo CONSTANTE; // imprime "Hola mundo."
echo Constante; // imprime "Constante" y genera
una noticia.

define("SALUDO", "Hola tu.", true);
echo SALUDO; // imprime "Hola tu."
echo Saludo; // imprime "Hola tu." ($cadena); // 7
bool K%F')%K ( strIng Snombre )

Chequea sI la constante dada exIste y est
defInIda.
/* Note el uso de comillas, esto es importante.
Este ejemplo verifica si
la cadena 'CONSTANTE' es el nombre de una
constante llamada CONSTANTE */
if (defined('CONSTANTE')) {
echo CONSTANTE;
}
voId %b'- ([ strIng Sstatus ] )

FInalIza la ejecucIon del scrIpt.
exit("no se puede continuar.");

61

voId K'% ([ strIng Sstatus ] )

FInalIza la ejecucIon del scrIpt, es equIvalente a
exIt().
$comprobar=isset($submit) or die ("no se puede
continuar.");
mIxed %*.$ ( strIng Scadena_codIgo )

Evalua la cadena dada en Scadena_codIgo como
codIgo PHP. Entre otras cosas, esto puede ser
utIl para almacenar codIgo en un campo de texto
en una base de datos para su ejecucIon
posterIor.

ExIsten algunos factores a tener en cuenta
cuando se usa eval(). Fecuerde que la cadena
pasada debe ser codIgo PHP vlIdo, Incluyendo
cosas como la termInacIon de sentencIas con un
puntoycoma de modo que el Intrprete no falle
en la linea sIguIente al llamado a eval(), y
escapar apropIadamente las cosas en
Scadena_codIgo . Para mezclar salIda HT|L y
codIgo PHP, es posIble usar una etIqueta de
cIerre PHP para abandonar el modo PHP.

Fecuerde tambIn que las varIables que recIben
valores bajo eval() conservarn esos valores en
el scrIpt prIncIpal ms adelante.
$cadena = 'taza';
$nombre = 'caf';
$cad = 'Esta es una $cadena con mi $nombre en
ella.';
echo $cad. "\n";
eval("\$cad = \"$cad\";");
echo $cad. "\n";

/*Esta es una $cadena con mi $nombre en ella.
Esta es una taza con mi caf en ella.*/

Pruebe los ejemplos, amplie la InformacIon sobre estas funcIones en el manual de PHP, y
consulte por otras no especIfIcadas en esta tabla.

Usted puede contInuar consultando el manual de php.net sobre los grupos de funcIones. En el
presente texto, seguIremos estudIando otras funcIones Importantes para resolver las sItuacIones
profesIonales.


SJ33!P'H+%+a.,!
Ceneralmente ocurre que se utIlIzan las mIsmas secuencIas de comandos de PHP en varIas
pgInas de un sItIo web. Esto ImplIca tener que escrIbIr varIas veces los mIsmos codIgos en cada
pgIna. El problema se resuelve con el uso de sentencIas que permIten crear lIbrerias de codIgos
reutIlIzables cada vez que se requIeran en una pgIna.
La prIncIpal ventaja de las lIbrerias externas es la modularIzacIon del codIgo, en efecto, sI por
ejemplo, tuvIera que corregIr una funcIon, solamente haria las correccIones en la lIbreria y los
cambIos afectarian a todas las pgInas en las que se Incluye dIcha lIbreria. 0e otro modo,
tendria que realIzar correccIones en cada pgIna afectada.
Dtra ventaja es que podemos colocar archIvos de lIbrerias en carpetas dIferentes a la de la
pgIna que los precIsa, lo que nos permIte protegerlos medIante algun sIstema de acceso.
Una lIbreria no es ms que una pgIna con codIgo que puede ser IncluIda en cualquIer otra
pgIna PHP.

Para Incorporar una pgIna externa, utIlIzamos las sentencIas include, include_once,
require o require_once.

La sIntaxIs de las sentencIas include y require son las sIguIentes:

include "archivo.php";
require "archivo.php";


62

include_once "archivo.php";
require_once "archivo.php";

En cada sentencIa, el "archivo.php" puede ser cualquIer archIvo PHP, NC o HT|L.
Un archIvo NC, "archivo.inc", est preparado para ser IncluIdo ms que para ser ejecutado
dIrectamente por PHP. Su contenIdo es sImplemente codIgo PHP como el de cualquIer otro
archIvo punto php.

7eamos un ejemplo muy bsIco. Supongamos que en la pgIna "test.php" IncluImos la pgIna
"lIb.php":

CodIgo para "lIb.php":

<?php
$mensaje="Funcin para nmeros aleatorios.";
function random($a,$b){
return rand($a,$b);
}
?>

CodIgo para "test.php":

<?php
include "lib.php";
echo $mensaje;
echo "<br />";
echo random(2,10);
?>

El resultado en la pantalla del navegador podria ser:

Funcin para nmeros aleatorios.
3

El codIgo de "test.php", es equIvalente al sIguIente:

<?php
$mensaje="Funcin para nmeros aleatorios.";
function random($a,$b){
return rand($a,$b);
}
echo $mensaje;
echo "<br />";
echo random(2,10);
?>

Al Incorporar el codIgo de una lIbreria externa, el Intrprete analIza todas las secuencIas de
comando en lenguaje PHP que pueda contener dIcha lIbreria, y su efecto es sImIlar a escrIbIr el
codIgo de la lIbreria en la pgIna que se Incluye.

Las sentencIas include y require funcIonan de la mIsma manera y sI el archIvo que se Intenta
abrIr no exIste, ambos arrojan un mensaje de error pero include permIte seguIr ejecutando la
secuencIa de comandos, mIentras que require fInalIza la ejecucIon.
ExIste otra pequea dIferencIa entre include y require: en la prImera, no se procesa el
codIgo de la lIbreria hasta que el Intrprete no llega la linea en la que se Incluye el archIvo. Por

6J

el contrarIo, con require, se procesa el codIgo de la lIbreria cuando se ejecuta la pgIna que la
solIcIta, IndependIentemente de la linea en la que se encuentre.

La prIncIpal dIferencIa entre include/require y include_once/require_once es que en
los dos ultImos, el archIvo que se especIfIque, solamente se podr abrIr una vez por cada pgIna
e Ignorar los dems Intentos de abrIr el mIsmo. Esto se debe a que en PHP no se permIte defInIr
la mIsma funcIon varIas veces dentro de una mIsma pgIna.


SJ32!A.-+'D%,!
Las matrIces, tambIn llamadas arrays, son una coleccIon de dIferentes varIables bajo un mIsmo
nombre. Los arrays corresponden a un tIpo de varIable de PHP y pueden contener dIferentes
tIpos de datos. Cada valor almacenado en una matrIz, es referencIado con un indIce o clave.
En defInItIva, las matrIces sIrven para guardar y manIpular grupos de varIables.
Segun John Coggeshall en su obra "Php 5 Unleashed", tcnIcamente, las matrIces representan un
mapa ordenado que asIgna valores clave a elementos de datos varIables:


FepresentacIon grfIca de una matrIz, segun John Coggeshall en su obra "Php 5 Unleashed".

Esta defInIcIon es muy sImIlar a la que se encuentra en el manual ofIcIal de PHP (php.net).
Al prIncIpIo, pueden parecer poco amIstosas y complejas pero en la medIda que avance en el
estudIo de este lenguaje, encontrar la utIlIdad y sern ImprescIndIbles para sus proyectos.

El camIno ms sImple para crear una matrIz es asIgnar valores cuando se necesIten. La prImera
vez que asIgnemos un valor, el array se crear en el entorno:

<?php
$matriz[1] = 23; //Asignacin directa
?>

0e esta forma tenemos un valor asIgnado al indIce 1 de la matrIz. Puede asIgnar cualquIer indIce
en la creacIon de este tIpo de dato, e Incluso no asIgnar nInguno, de forma que PHP se encargue
de asocIar un indIce dIstInto para cada valor:

<?php
$matriz[] = 23; //empieza en el ndice 0
$matriz[] = 54; //ndice 1
echo $matriz[0]; //devuelve 23
?>
?
se usan corchetes
[ ]

64


Dbserve en el ejemplo, como se recupera el valor del indIce cero. A cada valor le corresponde
un indIce o clave que podemos utIlIzar para recuperarlos.

Ahora, veamos otro ejemplo:

<?php
$matriz[1] = 23; //empieza en el ndice 1
$matriz[] = "texto"; //ndice 2
$matriz[4] = 54; //ndice 4
$matriz[] = true; //ndice 5
?>

En el ejemplo, creamos una matrIz llamada $matriz y le asIgnamos valores de dIstIntos tIpos de
datos.
El prImer valor cargado a la matrIz, se asIgna al indIce 1 porque est especIfIcado entre los
corchetes. El segundo valor "texto", no especIfIca el indIce, por lo tanto, PHP detecta el
indIce mxImo de la matrIz, en este caso es 1, y le asIgna un indIce InmedIatamente superIor a
ste.
Para el valor 54 se asIgna al indIce 4 y el booleano true al 5, porque es el indIce
InmedIatamente superIor al mxImo.
En este caso, la matrIz tendr vacio los indIces 0 y J.

Dtra forma de crear matrIces es utIlIzando el constructor array(). 7eamos la sIntaxIs:

array $var=array( mixed $... )

En la sIntaxIs anterIor, observe que se devuelve una varIable del tIpo array. El argumento
mixed representa valores de dIversos tIpos.

Aclaremos esto con un ejemplo:

<?php
$matriz = array(45,"texto",23,true);
echo $matriz[0];
echo "<br />";
echo $matriz[1];
echo "<br />";
echo $matriz[2];
echo "<br />";
if ($matriz[3]]) {
echo 'verdadero';
}
?>

El resultado en la pantalla ser:

45
texto
23
verdadero

Para el codIgo del ejemplo anterIor, la asIgnacIon de claves es automtIca y comIenza desde
cero.
La matrIz del ejemplo contIene cuatro claves: 0, 1, 2, J. A cada clave le corresponde un valor y,
para recuperarlos, se nombra la matrIz con la correspondIente clave entre corchetes.

65

La creacIon de la matrIz del ejemplo anterIor es equIvalente al sIguIente codIgo:

<?php
$matriz[] = 45; //empieza en el ndice 0
$matriz[] = "texto"; //ndice 1
$matriz[] = 23; //ndice 2
$matriz[] = true; //ndice 3
?>

El constructor array tambIn permIte aadIr indIces o claves a los valores que se asIgnan. Para
ello se utIlIza el operador =>, y la matrIz toma un cIerto numero de parejas clave/valor
separadas por coma. Este tIpo de matrIces suelen denomInarse .++.M,! .,#D'.-'*#, cuando la
clave es un valor del tIpo cadena de texto:

array $var=array(clave => valor,
clave => valor,
...
)


Entonces, clave puede ser un Integer o strIng y valor puede ser de cualquIer tIpo.

Por ejemplo:

<?php
$matriz = array("a" => "cadena",
12 => true,
"b" => 52,
0 => 21);

echo $matriz["a"];
echo "<br />";
if ($matriz[12]){
echo "verdadero";
}
echo "<br />";
echo $matriz["b"];
echo "<br />";
echo $matriz[0];
?>

El resultado en la pantalla ser:

cadena
verdadero
52
21

La matrIz del ejemplo anterIor contIene cuatro claves: "a", 12, "b", 0. A cada clave le
corresponde un valor y para recuperarlos, se nombra la matrIz con la correspondIente clave
entre corchetes. Las claves del tIpo strIng deben estar sIempre entre comIllas sImples o dobles.
En este caso no se produce una asIgnacIon automtIca de claves ya que se especIfIcan en el
constructor.

La creacIon de la matrIz del ejemplo anterIor es equIvalente al sIguIente codIgo:



66

<?php
$matriz["a"] = "cadena"; //empieza en el ndice "a"
$matriz[12] = true; //ndice 12
$matriz["b"] = 52; //ndice "b"
$matriz[0] = 21; //ndice 0
?>

SI quIsIera modIfIcar algun valor de un indIce puede hacerlo como sI se tratara de una varIable:

<?php
$matriz["a"] = "cadena"; //empieza en el ndice "a"
$matriz[12] = true; //ndice 12
$matriz["b"] = 52; //ndice "b"
$matriz[0] = 21; //ndice 0
$matriz["a"] = "cadena modificada";
?>

Para agregar nuevos valores, podria hacerlo de la mIsma forma, especIfIcando un nuevo indIce o
permItIendo a PHP que lo asIgne automtIcamente.

Hasta ahora hemos creado matrIces con tIpos de datos sImples, pero una matrIz puede contener
datos del tIpo array, es decIr que puede contener otra matrIz. Este tIpo de matrIces se
denomInan =<$-'K'=%),'#).$%, y no son ms complejas que las anterIores. Puede crearlas con la
sIntaxIs de corchetes o con el constructor array. Por ejemplo:

<?php
//con el constructor array:
$matriz = array("a" => "cadena",
12 => true,
"b" => 52,
0 => array(22, true, 1, 6));

//usando corchetes:
$sub_matriz[] = 22;
$sub_matriz[] = true;
$sub_matriz[] = 1;
$sub_matriz[] = 6;

$otra_matriz["a"] = "cadena";
$otra_matriz[12] = true;
$otra_matriz["b"] = 52;
$otra_matriz[0] = $sub_matriz;
?>

Para recuperar valores de una matrIz multIdImensIonal, debe referencIar las claves o indIces de
manera apIlada:

echo $otra_matriz[0][2]; //devuelve 1
echo $otra_matriz[0][3]; //devuelve 6
echo $otra_matriz["a"]; //devuelve "cadena"

Como pudo aprecIar, las matrIces pueden ser tratadas como varIables. 7eamos que ocurre
cuando queremos darle salIda a una cadena de texto analIzada que contIene una matrIz con
indIces o claves alfanumrIcos:

<?php
$matriz["a"] = "cadena";
$matriz["b"] = 15;
$matriz["c"] = 52;

67

echo "El valor de \$matriz[\"a\"] es $matriz[a]."; //El valor de $matriz['a']
es cadena.
echo "El valor de \$matriz[\"a\"] es {$matriz['a']}."; //El valor de
$matriz['a'] es cadena.
?>

Dbserve que hay dos formas de lograr que PHP reemplace la matrIz por el valor del indIce
especIfIcado. La prImera es quItando las comIllas al indIce de la matrIz, y la segunda utIlIzando
comIllas sImples y llaves dentro de la cadena. Ambas formas son vlIdas y de cualquIer otra
manera podria obtener un mensaje de error.

Cuando estudIo "estructuras de repetIcIon", vIo que exIsten cuatro bucles pero solamente
estudIo tres de ellos. El cuarto bucle que veremos es la sentencIa foreach, y sIrve para
recorrer varIables del tIpo array. Este bucle repetIr sus InstruccIones hasta que termIne de
recorrer todas las claves y valores de la matrIz a la que se aplIca. 7eamos un ejemplo:

<?php
$ciudades = array("Crdoba", "Mendoza", "Rosario");
foreach ($ciudades as $valor) {
echo ("El valor es: $valor<br />");
}
?>

El resultado en pantalla ser:

El valor es: Crdoba
El valor es: Mendoza
El valor es: Rosario

En el ejemplo, foreach toma el array a recorrer y sus valores los va almacenando en la varIable
$valor a medIda que el bucle se ejecuta. ExIste una segunda construccIon que permIte
recuperar el indIce y el valor:

<?php
$ciudades = array("Crdoba", "Mendoza", "Rosario");
foreach ($ciudades as $clave => $valor) {
echo ("El ndice $clave tiene el valor: $valor<br />");
}
?>

El resultado en pantalla ser:

El ndice 0 tiene el valor: Crdoba
El ndice 1 tiene el valor: Mendoza
El ndice 2 tiene el valor: Rosario

SI quIsIera salIr del analIzador utIlIzando la sIntaxIs alternatIva:

<?php foreach ($ciudades as $valor): ?>
El valor es:<?=$valor?><br />
<?php endforeach; ?>


Y con la sIntaxIs tradIcIonal:


?
A todos los valores de $ciudades los paso a la variable $valor
tomo de la matriz $ciudades el indice para $clave y el valor del indice para $valor

68

<?php foreach ($ciudades as $valor){ ?>
El valor es:<?=$valor?><br />
<?php }; ?>

En PHP, exIsten muchas funcIones para controlar y manIpular arrays, consulte el grupo de
"FuncIones de matrIces" en:

http://www.php.net/mcnucl/es/re].crrcy.php

Fecuerde como Interpretar la sIntaxIs de PHP y realIce pruebas con ellas.


SJ3Q!@DD%,#!.!*.+'.H$%,!K%!F#+=<$.+'#!M!(8P!
Hasta ahora hemos vIsto algunos comandos o funcIones de PHP en forma aIslada, y conceptos
que de nInguna manera han sIdo aplIcados a casos prctIcos que le sIrvan para reconocer el
alcance del lenguaje. Ahora veremos como aplIcar lo aprendIdo generando varIables que se
transmItan entre scrIpts de PHP para entrar a los prImeros pasos de la InteraccIon y dInamIasmo.

En la presente sItuacIon profesIonal, debe crear formularIos HT|L que puedan envIar datos a una
cuenta de correo, lo que en realIdad sIgnIfIca que los datos no sern envIados dIrectamente por
el formularIo a dIcho correo, sI no que deben ser envIados a una pgIna PHP que los procese y se
encargue del envio.

Usted estudIo como generar un formularIo en HT|L, en esta herramIenta aprender a recIbIr los
datos, en PHP, envIados por dIcho formularIo, y ms adelante ver como dIrIgIrlos a una cuenta
de correo electronIco.

Comencemos con un ejemplo muy sencIllo:

<form name="form1" method="post" action="procesa.php">
Nombre:
<input type="text" name="nombre" />
<br /><br />
Mensaje:
<textarea name="mensaje" cols="45" rows="5"></textarea>
<br /><br />
<input type="submit" name="Enviar" value="Enviar" />
</form>

El codIgo de arrIba pertenece a un formularIo de dos campos como el que se muestra a
contInuacIon:



69



Dbserve en la etIqueta form, que el atrIbuto action tIene el valor "procesa.php". Esta pgIna
a la que hace referencIa el formularIo, ser la que recIbIr los datos Ingresados por un usuarIo,
al presIonar el boton "EnvIar", una vez que lo haya completado.
En PHP exIsten varIos mtodos para recuperar datos, en esta herramIenta, veremos dos de ellos.
0ependIendo del mtodo de envio especIfIcado en el atrIbuto method de la etIqueta <form>,
ser el que utIlIzaremos para recuperar las varIables del formularIo a travs de dos matrIces
super globales. UtIlIzaremos la matrIz $_POST o $_GET segun corresponda. Estas varIables del
tIpo array contIenen una lIsta de claves que representan los nombres de los elementos del
formularIo, tal como se los especIfIco en el atrIbuto name de cada uno, y los valores Ingresados
por el usuarIo. Por lo tanto, en el ejemplo anterIor, el valor del mensaje, se podr recuperar
con $_POST['mensaje'].
SI el usuarIo rellena el formularIo de la sIguIente manera:



Al presIonar el boton "EnvIar", podemos recuperar los datos con el sIguIente codIgo de
"procesa.php":

<?php
echo $_POST['nombre'];
echo "<br />";
echo $_POST['mensaje'];
?>

Y el resultado en pantalla, ser:

Alejandro
Hola, estoy probando el formulario.

SI en vez de envIar los datos del formularIo con el mtodo PDST, lo hacemos con el mtodo CET:

<form name="form1" method="get" action="procesa.php">

El codIgo de "procesa.php" seria:

<?php
echo $_GET['nombre'];
echo "<br />";
echo $_GET['mensaje'];
?>

Y el resultado en pantalla seria el mIsmo que con PDST:

Alejandro
Hola, estoy probando el formulario.

70


Con el mtodo PDST, el formularIo oculta las claves y valores en la matrIz $_POST, mIentras
que con CET, las claves y valores son pasadas por medIo de una dIreccIon UFL y sern
recuperadas por $_GET. Dbserve la barra de dIreccIones cuando se realIza el envio medIante
CET:



El caracter de InterrogacIon "?", que se encuentra luego de la dIreccIon de la pgIna que
procesa los datos, IndIca que a partIr de ahi, se escrIbIrn una serIe de pares clave/valor. Estos
pares corresponden a los datos del formularIo y deben estar separados por & y sus valores
codIfIcados para la UFL.
En el ejemplo estamos pasando las claves nombre y mensaje con sus respectIvos valores, que
corresponden a los datos Ingresados por el usuarIo. TambIn se agrega el valor del boton de
envio con su respectIva clave, esto se debe a que el boton es un elemento del formularIo.
Dbserve que los valores se codIfIcan para la UFL.

Por lo tanto, sI los valores que debe envIar ImplIcan una operacIon Importante o requIeren un
nIvel de segurIdad, como por ejemplo un Ingreso de datos a un servIdor de base datos, debe
utIlIzar PDST.

En referencIa a lo anterIor, podriamos Ingresar a la pgIna "procesa.php" medIante pares de
clave/valor sIn la necesIdad de pasar por el formularIo, sIempre y cuando, dIchos datos se
recIban medIante $_GET. Por ejemplo:

procesa.php?nombre=Yo&mensaje=Estoy+usando+la+URL.

Y el resultado seria:

Yo
Estoy usando la URL.

Tanto $_POST como $_GET son matrIces o arrays, y puede aplIcar los mIsmos comandos que
utIlIzo para trabajar con matrIces, anterIormente. Por ejemplo, sI aplIca el bucle foreach:

<?php
foreach ($_GET as $clave => $valor) {
echo ("La clave $clave tiene el valor: $valor<br />");
}
?>

El resultado para el ejemplo del formularIo con CET, ser:

La clave nombre tiene el valor: Alejandro
La clave mensaje tiene el valor: Hola, estoy probando el formulario.
La clave Enviar tiene el valor: Enviar

0e esta manera, se recorre toda la matrIz.

Hasta ahora vImos como recuperar los datos de un formularIo o las varIables envIadas por UFL,
pero aun no los procesamos de una manera utIl para usted. El procesado consIste en "hacer algo
con los datos recIbIdos" como por ejemplo, envIarlos a una cuenta de emaIl, guardarlos en una
base de datos, realIzar una consulta a una base de datos, armar una pgIna dInmIca con ellos,

71

confIgurar propIedades, InIcIar una sesIon, mostrar una Imagen, etc. En la proxIma herramIenta
estudIar como envIar un mensaje de emaIl con estos datos y ms adelante, en este mIsmo
texto, ver como realIzar otras operacIones con ellos.


SJ3S!N<)D'E)!=.'$!
En la herramIenta anterIor, aprendIo a recuperar datos de un formularIo, ahora estudIar el
envio de los datos recuperados a una casIlla de correo electronIco:



Afortunadamente, en PHP exIste la funcIon mail() que podemos utIlIzar para realIzar el envio
de datos. Esta funcIon trabaja, sIempre y cuando, PHP tenga acceso a un servIdor de correo
prevIamente Instalado. En servIcIos de hostIng remoto, normalmente este tIpo de servIdor ya
est en funcIonamIento; pero en modo local, deber Instalarlo usted mIsmo ya que no est
IncluIdo en el paquete AppServ que Instalo en herramIentas anterIores.

Consulte "FuncIones de correo" en el manual de php.net:

http://www.php.net/mcnucl/es/re].mcl.php

La sIntaxIs de la funcIon mail() es la sIguIente:

bool mail ( string $para , string $asunto , string $mensaje [, string
$cabeceras_adicionales [, string $parametros_adicionales ]] )

Esta funcIon devuelve un valor booleano, true en caso de ser exItoso el envio, y false en caso
de que ocurra algun error. SI el envio es exItoso, no asegura que el destInatarIo recIba el
mensaje, pero si afIrma que fue envIado por PHP al servIdor de correo.
ExIsten tres valores que debe especIfIcar oblIgatorIamente:

$para (destInatarIo/s): la dIreccIon de correo o dIreccIones de correo que han de
recIbIr el mensaje. SI Incluye varIas dIreccIones debe separarlas por coma.

$asunto: es el asunto del correo electronIco a envIar.

$mensaje: el cuerpo del mensaje, lo que quIera que tenga escrIto el correo.

Dtros valores que pueden especIfIcarse son las cabeceras y los parmetros adIcIonales.
Las cabeceras del correo pueden ser datos como la dIreccIon de respuesta, las posIbles
dIreccIones que recIbIrn copIa del mensaje, las dIreccIones que recIbIrn copIa oculta, el
formato del mensaje, etc.

7eamos un ejemplo de uso muy sencIllo:

<?php
mail("email@destino.com", "Asunto", "Este es el mensaje")
?>


72

SI quIsIera envIar el mensaje a varIos destInatarIos:

<?php
mail("email@destino1.com, email@destino2.com, email@destino3.com", "Asunto",
"Este es el cuerpo del mensaje")
?>

Esta funcIon devolver un valor true sI no ocurren errores, por lo tanto, puede controlar la
efIcacIa del envio aplIcando una estructura condIcIonal de la sIguIente manera:

<?php
if (mail("email@destino.com", "Asunto", "Este es el mensaje")){
echo "Enviado.";
}else{
echo "No se pudo enviar";
}
?>

D bIen, de la sIguIente forma:

<?php
$envio=mail("email@destino.com", "Asunto", "Este es el mensaje");
if ($envio){
echo "Enviado.";
}else{
echo "No se pudo enviar";
}
?>

El codIgo de los ejemplos, no tIene demasIada utIlIdad ya que sIempre se efectua el mIsmo envio
al acceder a la pgIna que lo contIene. 7eamos un ejemplo de un formularIo de contacto en el
que los usuarIos puedan rellenar los valores que se envian:

<form name="form1" method="post" action="procesa.php">
Nombre:
<input type="text" name="nombre" />
<br /><br />
Email:
<input type="text" name="email" />
<br /><br />
Mensaje:
<textarea name="mensaje" cols="45" rows="5"></textarea>
<br /><br />
<input type="submit" name="Enviar" value="Enviar" />
</form>

Y la pgIna "procesa.php" podria tener el sIguIente codIgo:

<?php
$nombre=$_POST['nombre'];
$email=$_POST['email'];
$mensaje=$_POST['mensaje'];
$envio=mail("email@destino.com", "Mensaje de $nombre ($email)", $mensaje);
if ($envio){
echo "Enviado.";
}else{
echo "No se pudo enviar";
}
?>

7J

Dbserve que en el codIgo de anterIor, se recuperan los valores de las claves de la matrIz $_POST
y se asIgnan a las varIables $nombre, $email y $mensaje, respectIvamente.
SI todo funcIona correctamente, este codIgo permItIr que PHP envie el emaIl a travs del
servIdor de correo. El correo salIente del servIdor ser un texto plano por defecto.
SI quIsIramos especIfIcar otros parmetros y envIar el mensaje en formato HT|L, modIfIcamos
el codIgo anterIor de la sIguIente forma:

<?php
$nombre=$_POST['nombre'];
$email=$_POST['email'];
$mensaje=$_POST['mensaje'];

$cabeceras = "MIME-Version: 1.0\r\n".
"Content-type: text/html; charset=iso-8859-1\r\n".
"Reply-To: $email\r\n".
"From: $nombre <$email>\r\n".
"Cc: info@destino.com\r\n".
"Bcc: jefe@destino.com\r\n";

$envio=mail("email@destino.com", "Mensaje de $nombre ($email)", $mensaje,
$cabeceras);

if ($envio){
echo "Enviado.";
}else{
echo "No se pudo enviar";
}
?>

El envio en formato HT|L, sIgnIfIca que el mensaje podria formatearse con etIquetas HT|L y
stas serian reconocIdas por el clIente de correo; aunque algunos no permIten recIbIr mensajes
en este formato, sobre todo los ms obsoletos o los que requIeren cIertos nIveles de segurIdad.
Dbserve en el codIgo anterIor que se especIfIca la dIreccIon de respuesta, que es la que se
utIlIza cuando el destInatarIo decIda responder.
TambIn se especIfIco el orIgen (From), la copIa (Cc) y la copIa oculta (8cc).
Ahora veamos un poco ms de cerca las dos prImeras lineas de la varIable $cabeceras:

$cabeceras = "MIME-Version: 1.0\r\n".
"Content-type: text/html; charset=iso-8859-1\r\n".

El protocolo S|TP (para la transmIsIon de mensajes de correo electronIco) solo soporta
caracteres @1"// !de 7 bIt. Esto ImplIca una lImItacIon Importante al momento de envIar correo
electronIco, ya que Incluye solamente un numero reducIdo de caracteres, prIncIpalmente los del
alfabeto Ingls.


Ayuda ahora
@1"//G! AmerIcan Standard Code for nformatIon nterchange o CodIgo EstadounIdense Estndar para el
ntercambIo de nformacIon, es un codIgo de caracteres basado en el alfabeto latIno. El codIgo ASC
utIlIza 7 bIts para representar los caracteres.

Las extensIones multIproposIto de correo de Internet, conocIdas como ||E, defInen
mecanIsmos para envIar otros tIpos de InformacIon en un emaIl, Incluyendo texto con caracteres
dIstIntos del Ingls, archIvos de Imgenes, sonIdos, peliculas, y programas. Los servIdores de
correo, antes de envIar el mensaje, lo convIerten automtIcamente a formato 7bIt ASC
medIante los estndares de ||E y los clIentes de correo, antes de presentarlos, los convIerten
de 7bIt ASC al formato adecuado medIante las mIsmas reglas.

74


||E defIne una coleccIon de encabezados: el "content-type" que especIfIca el tIpo de datos
que se Incluyen en un mensaje y el "transfer-encodings" que IndIca como ha sIdo
codIfIcado el mensaje para su transmIsIon por emaIl. TambIn especIfIca reglas (charset) para
codIfIcar caracteres no ASC, permItIendo asi que contengan caracteres de dIferentes IdIomas
adems del Ingls.

En el ejemplo se especIfIco la versIon ||E. Luego se IndIca el encabezado "content-type"
con el valor text/html. Para envIar texto sIn formato, tendr que especIfIcar text/plain, y
sI Incluyera una Imagen podria especIfIcar el tIpo de contenIdo de acuerdo al tIpo de Imagen,
como por ejemplo, image/jpeg.
El encabezado "charset" especIfIca que los caracteres del mensaje estarn codIfIcados de
acuerdo al estndar ',#nkkWln3 .
!

Ayuda ahora
/,#nkkWln3G! es una extensIon que utIlIza 8 bIts para proporcIonar caracteres adIcIonales usados en
IdIomas dIstIntos al Ingls.
!
!
SJ3W!f.+'.H$%,!K%$!,%+*'K#+!
Usted estudIo matrIces tales como $_POST y $_GET, stas corresponden al grupo de varIables
super globales. Una varIable super global es aquella que puede ser accedIda desde cualquIer
pgIna PHP del servIdor.
0entro de este grupo, exIsten adems, las varIables del servIdor que pueden ser recuperadas
medIante $_SERVER. Esta matrIz contIene InformacIon tal como cabeceras, rutas y ubIcacIones
de scrIpts.
Segun la documentacIon de php.net, las entradas de esta matrIz son creadas por el servIdor
web. No exIsten garantias de que cada servIdor vaya a proveer alguno de estos valores; puede
que los servIdores omItan algunos, o provean otros que no se lIstan aqui.
Es decIr que, el acceso a sus valores depende de la confIguracIon del servIdor en el que se
ejecute el codIgo PHP.
Para consultar InformacIon extra sobre la matrIz $_SERVER, puede acceder a la documentacIon
de PHP, en:

http://www.php.net/mcnucl/es/reserved.vcrcbles.php

Antes de ver la utIlIdad de esta matrIz, observaremos qu datos hay dIsponIbles en el servIdor
medIante el sIguIente codIgo:

<?php
foreach($_SERVER as $clave => $valor){
echo " $clave=$valor<br />";
}
?>

El codIgo del ejemplo realIza una IteracIon sobre la matrIz $_SERVER y muestra en pantalla los
elementos del array con sus respectIvos valores. Estos elementos, podrian varIar de acuerdo a la
confIguracIon del servIdor en el que se ejecute.
El resultado en la pantalla podria ser:

HTTP_ACCEPT=*/*
HTTP_ACCEPT_LANGUAGE=es-ar
HTTP_UA_CPU=x86

75

HTTP_ACCEPT_ENCODING=gzip, deflate
HTTP_USER_AGENT=Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.2; .NET CLR
1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648)
HTTP_HOST=localhost
HTTP_CONNECTION=Keep-Alive
HTTP_COOKIE=fontSize=80
PATH=C:\\WINDOWS\\system32;C:\\WINDOWS;C:\\WINDOWS\\System32\\Wbem;C:\\Archivos de
programa\\QuickTime\\QTSystem\\;C:\\Archivos de programa\\Unifier
SystemRoot=C:\\WINDOWS
COMSPEC=C:\\WINDOWS\\system32\\cmd.exe
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
WINDIR=C:\\WINDOWS
SERVER_SIGNATURE=
Apache/2.0.59 (Win32) PHP/4.4.7 Server at localhost Port 80

SERVER_SOFTWARE=Apache/2.0.59 (Win32) PHP/4.4.7
SERVER_NAME=localhost
SERVER_ADDR=127.0.0.1
SERVER_PORT=80
REMOTE_ADDR=127.0.0.1
DOCUMENT_ROOT=D:/appserv/www
SERVER_ADMIN=admin@email.com
SCRIPT_FILENAME=D:/appserv/www/ejemplos/procesa.php
REMOTE_PORT=3426
GATEWAY_INTERFACE=CGI/1.1
SERVER_PROTOCOL=HTTP/1.1
REQUEST_METHOD=GET
QUERY_STRING=var=hola
REQUEST_URI=/ejemplos/procesa.php?var=hola
SCRIPT_NAME= /ejemplos/procesa.php
PHP_SELF= /ejemplos/procesa.php
PATH_TRANSLATED=D:/appserv/www/ejemplos/procesa.php
argv=Array
argc=1

Por lo estudIado anterIormente, usted ya sabe que estos elementos son los indIces de la matrIz
$_SERVER y sus respectIvos valores.
SI por ejemplo, quIsIera recuperar el nombre de archIvo del scrIpt que se est ejecutando
actualmente, relatIvo a la raiz de documentos, escrIbIria el sIguIente codIgo:

<?php
echo $_SERVER['PHP_SELF'];
?>

El codIgo anterIor dar como resultado:

/ejemplos/procesa.php

Esta es la UFL relatIva del archIvo que contIene el scrIpt que se ejecuta.
Cada uno de los elementos de la matrIz representa un valor que podria ser de utIlIdad en sus
proyectos de PHP.
Por ejemplo, sI quIsIera Incorporar un contador de vIsItas a un sItIo web necesItar conocer la
dIreccIon P de los usuarIos que Ingresen a la pgIna para almacenarlas en una coleccIon, y
determInar sI ya estuvIeron antes. Con esto puede evItar que el contador aumente ante un
mIsmo acceso. Para ello utIlIzaria $_SERVER['REMOTE_ADDR'].

76

@<-#%*.$<.D'E)!S!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!

3 Las sIguIentes lineas de codIgo son equIvalentes:

$a=' Web';
$cadena='Programacin'.$a;
$a=' Web';
$cadena="Programacin $a";

` ` 7erdadero ` ` Falso

!
2 El sIguIente codIgo mostrar la frase "son Iguales" en la pantalla del navegador:

$a=20;
if ($a=33){
echo "son iguales";
}

` ` 7erdadero ` ` Falso


Q El bucle while ejecuta sus InstruccIones mIentras su condIcIon sea true. Cuando la condIcIon
es false, el bucle ejecuta sus InstruccIones por ultIma vez y fInalIza el procesado de la pgIna
PHP.

` ` 7erdadero ` ` Falso


S El anIdamIento de sentencIas del codIgo de abajo es correcto, y mostrar en la pantalla el
resultado de la fIgura de al lado:

<table>
<?php
$n=1;
while ($n<=4) {
$a=$i+10;
echo '<tr>';
while ($i<=$a) {
if ($i%2==0){
echo '<td bgcolor="#000000">'.$i.'</td>';
}else{
echo '<td bgcolor="#ffffff">'.$i.'</td>';
}
$i++;
}
echo '</tr>';
$n++;
}
?>
</table>


! ! Verdadero ! ! Falso



77


W El codIgo de abajo produce en la pantalla del navegador el resultado que se observa:

<?php
define("MES",09);
echo MES;
define("MES",11);
echo MES;
?>
Fesultado:

0911

` ` 7erdadero ` ` Falso


X El codIgo que se muestra a contInuacIon, permIte vIsualIzar una Imagen seleccIonada al azar
entre las que se encuentran en la matrIz de $imagenes:

<?php
$imagenes=array("familia.jpg", "amigos.jpg", "vacaciones.jpg", "navidad.jpg");
$cual=rand(1,4);
?>
<img src="<?=$imagenes[$cual];?>" />

` ` 7erdadero ` ` Falso


[ Segun el codIgo de abajo, los valores de los campos del formularIo "nombre", "emaIl" y
"mensaje", llegan a esta pgIna por medIo del mtodo PDST:

<?php
$nombre=$_POST['campo_nombre'];
$email=$_POST['campo_email'];
$mensaje=$_POST['campo_mensaje'];
$envio=mail("email@destino.com", "Mensaje de $nombre ($email)", $mensaje, $cabeceras);
if ($envio){
echo "Enviado.";
}else{
echo "No se pudo enviar";
}
?>

` ` 7erdadero ` ` Falso



Las respuestas las encontrar al fInal de la sItuacIon profesIonal.

78

0Y%+D'D'#!8%,<%$-#!
En la sItuacIon profesIonal planteada, la empresa SerWeb, le solIcIta la programacIon de un sItIo
web destInado a mostrar los planes de hostIng y facIlItar la contratacIon de sus servIcIos.
TambIn, le pIden que realIce un sIstema de banners o anuncIos publIcItarIos.
Para efectuar el trabajo solIcItado debe tener en cuenta los sIguIentes requerImIentos:

- Cada plan de hostIng mostrado en la pgIna de InIcIo debe dIreccIonar al usuarIo a un
formularIo para su contratacIon.
- Cuando el usuarIo completa y envia el formularIo de contratacIon de servIcIo, debe
mostrarle la confIrmacIon del envio con los datos ms relevantes (plan contratado, forma
de pago, medIo de pago).
- Los datos del formularIo se envian a una casIlla de correo electronIco del encargado de
ventas de la empresa.
- Los banners de afIlIados se mostrarn aleatorIamente durante la navegacIon por el sItIo.


FIgura 1: Index.php

Una vez resuelto el dIseo de la Interfaz y
aprobado por el comItente, debe comenzar
a programar cada una de las pgInas del
sItIo.
La fIgura de la IzquIerda pertenece a la
pgIna prIncIpal. Dbserve que se muestran
los planes de hostIng de la empresa en la
zonc medc.
En la parte InferIor se puede vIsualIzar un
anuncIo o banner, a partIr de ahora lo
llamaremos pe de pgIna.
En la zona superIor se encuentra el Isologo y
debajo de l, el menu de navegacIon, a
partIr de ahora llamaremos a esta zona
ccbecerc de la pgIna.
TambIn podr observar la columnc
zquerdc con InformacIon extra.
UtIlIce un edItor de pgInas web para
generar el dIseo en formato HT|L. Luego
embeber el codIgo PHP en l.




















79


FIgura 2: contratar.php:plan=8asIco
En la segunda fIgura se puede ver el modelo
de la pgIna de contratacIon de uno de los
planes ofrecIdos.
Como puede aprecIar, exIsten zonas que se
mantIenen fIjas dentro del dIseo. Estas
zonas corresponden a la cabecera y pIe de
la pgIna. SI bIen, el banner cambIo con
respecto a la pantalla anterIor, la estructura
del pIe permanece Igual.

En la zona medIa se encuentra el plan de
hostIng seleccIonado y, debajo de l, el
formularIo de contratacIon con todas las
opcIones y formas de pago para dIcho plan.
SI no exIstIeran las pgInas dInmIcas,
deberia efectuar un formularIo por cada
plan de hostIng. Pero esto seria una tarea
dIficIl que le InsumIria mucho tIempo sI la
empresa aumentara la cantIdad de planes y,
peor aun, sI se plateara un redIseo del
sItIo.

Por lo tanto, lo Ideal seria resolver la programacIon, desde un unIco formularIo flexIble, es
decIr, un formularIo que se adapte a cada plan de la empresa.
En referencIa a la planIfIcacIon anterIor, podemos determInar los archIvos necesarIos para que el
sItIo sea funcIonal:


FIgura J: Faiz del sItIo.

En la fIgura de arrIba se muestran las pgInas que deber programar. En la presente sItuacIon
profesIonal, nos avocamos a la programacIon de las pgInas correspondIentes a la seccIon
prIncIpal y los formularIos de contratacIon de planes.
La carpeta "banners" es donde se guardan las Imgenes de cada anuncIo, y la carpeta "Images"
corresponde a las Imgenes utIlIzadas en el dIseo de la Interfaz. El archIvo "estIlos.css" ser
enlazado desde cada pgIna para que se aplIquen los formatos de vIsualIzacIon de los objetos
HT|L.

80

La pgIna "Index.php" es la prImera pantalla del sItIo y corresponde a la fIgura 1, dentro de ella
se IncluIrn las pgInas "cabecera.html" y "pIe.php".
La pgIna "contratar.php" es el formularIo de pedIdo de la fIgura 2, y dentro de l, se IncluIrn
las pgInas "cabecera.html" y "pIe.php".
El archIvo "procesa.php" contIene el codIgo necesarIo para procesar los datos recIbIdos del
formularIo de pedIdo "contratar.php" y tambIn Incluye los archIvos de la cabecera y el pIe.
En cada seccIon restante del sItIo deberia IncluIr la cabecera y el pIe para mantener el mIsmo
formato de la Interfaz.


FIgura 4: cabecera.html

La pgIna "cabecera.html", mostrada en la fIgura 4, est creada en formato HT|L, ya que no es
necesarIo IncluIr en la mIsma, nIngun codIgo PHP.


FIgura 5: pIe.php

En la fIgura 5 se muestra el pIe de la pgIna con su Imagen del banner. Fecuerde que esta
Imagen debe ser seleccIonada por el servIdor, de manera aleatorIa; por lo tanto, debe
programarla hacIendo uso del lenguaje PHP.

7eamos el codIgo de la pgIna "T'%JTVT":


CodIgo de la pgIna pIe.php (1/1)


81

En el codIgo de esta pgIna no se especIfIcan las etIquetas de apertura y cIerre de HT|L,
tampoco el body y el head, ya que este bloque de codIgo se IncluIr dentro del body de otras
pgInas medIante la funcIon include().

En la linea 2, se crea la varIable $b y se le asIgna un valor al azar, entre 0 y 2. SuponIendo que,
InIcIalmente, exIsten tres sItIos afIlIados.
Entre las lineas J y 9 se evalua el valor de $b y se crea $url, cuyo valor pertenece a una cadena
con la dIreccIon UFL del sItIo afIlIado.

En la linea 16, se especIfIca la UFL del banner y la Imagen que le corresponde a dIcho banner. El
valor del atrIbuto href se obtIene de $url.
La Imagen del banner se especIfIca en el valor del atrIbuto src de la etIqueta img. Este valor se
obtIene de la varIable $b, declarada en el codIgo PHP que se encuentra en las prImeras lineas. SI
por ejemplo, $b vale 2, entonces la UFL del banner ser "http://www.joomla.org" y la UFL de
la Imagen a mostrar ser "banners/b2.gIf", esto supone que las Imgenes de cada banner se
guardan en la carpeta "banners", sern nombradas con la letra "b" y un numero: b0.gIf, b1.gIf y
b2.gIf para este caso.

Ya se defInIeron las pgInas "cabecera.html" y "pIe.php", ahora puntualIzamos el "')K%bJTVT",
cuyo codIgo lo veremos en dos porcIones:


CodIgo de la pgIna Index.php (1/2)

0e acuerdo al codIgo de arrIba, en la linea 11, se Incluye la pgIna "cabecera.html" dentro de
una celda de la prImera tabla del dIseo orIgInal.


82

CodIgo de la pgIna Index.php (2/2)

En las lineas J7, 40 y 4J, estn las Imgenes que corresponden a la InformacIon de cada uno de
los planes de hostIng ofrecIdos. Dbserve que los enlaces de estas Imgenes envian la varIable
plan a la pgIna del formularIo, y su valor corresponde al plan de hostIng solIcItado. Esta
varIable ser procesada por "contratar.php" y, a partIr del valor de ella, se establecern las
opcIones de vIsualIzacIon.

Ahora creamos la pgIna "D#)-+.-.+JTVT", mostrada en las sIguIentes porcIones de codIgo:


CodIgo de la pgIna contratar.php (1/6)

En la linea 2 se verIfIca que la varIable plan recIbIda por UFL no est vacia. La funcIon de
manejo de varIables, empty(), recIbe como parmetro la varIable que se va a verIfIcar. Esta

8J

funcIon devuelve un valor booleano, true sI se trata de una varIable vacia, con un valor Igual a
cero o InexIstente.
En el caso de no recIbIr el valor del plan de contratacIon, el Intrprete de PHP, ejecuta la linea
J. En esta linea se redIrIge al usuarIo a la pgIna de InIcIo del sItIo. SI la varIable plan est
defInIda, esta linea no tIene efecto y contInua el procesado del codIgo.
En las lineas 5 y 6, se establecen las varIables $plan y $titulo. La prImera toma el valor
recIbIdo de la cadena de UFL y la segunda varIable corresponde al titulo de la pgIna que se
establece en la linea 1J.


CodIgo de la pgIna contratar.php (2/6)

En la linea 19, se Incluye la cabecera de la pgIna, tal como lo hIcImos en el "Index.php".
Luego, en la estructura switch se evalua la varIable $plan y se establece el costo mensual del
servIcIo en la varIable $mensual. SI por ejemplo, $plan vale "Avanzado", entonces el costo
mensual del plan de hostIng avanzado ser 19. Esta varIable la utIlIzaremos para confIgurar la
forma de pago del formularIo de contratacIon.


CodIgo de la pgIna contratar.php (J/6)

En la linea 4J se mostrar la Imagen que corresponde al plan solIcItado. Dbserve que una parte
del valor del atrIbuto src, de la etIqueta img, se obtIene de la varIable $plan. SI el usuarIo

84

elIgIo el plan "ProfesIonal", entonces se muestra la Imagen "profesIonal.gIf" de la carpeta
"Images". La funcIon de cadenas, strtolower(), permIte pasar a mInusculas el valor de
$plan.
A partIr de la linea 45 hasta la linea 12J se presenta el formularIo completo.
El atrIbuto action de la etIqueta form en la linea 45, tIene el valor "procesa.php". Esta ser la
pgIna que procese los datos del formularIo transmItIdos por el mtodo PDST, IndIcado en el
atrIbuto method.


CodIgo de la pgIna contratar.php (4/6)

Entre las lineas 46 y 89 solo hay codIgo HT|L, correspondIente a los campos del formularIo.

85


CodIgo de la pgIna contratar.php (5/6)

Dbserve en los botones de radIo el atrIbuto value. Est formado por una cadena HT|L y la
varIable $mensual, calculada prevIamente en la lineas 20 a 29. En el caso del pago trImestral
se aplIca un pequeo descuento de ms del 6.5 y en los pagos anuales se descuentan 2 meses.


CodIgo de la pgIna contratar.php (6/6)

En la linea 120 se encuentra un campo oculto en el que se asIgna el valor de $plan.
FInalIzando el codIgo de "contratar.php", en la linea 127, se Incluye el pIe de pgIna.

7eamos como se procesarn los datos envIados por el formularIo en "T+#D%,.JTVT":

86



CodIgo de la pgIna procesa.php (1/2)

En la linea 12, se Incluye la cabecera de la pgIna, tal como lo hIcImos con las dems.
Entre las lineas 1J y 28, se recIben los datos del formularIo. Esto se podria haber resumIdo en
tres lineas, reemplazndolas, con el sIguIente codIgo:

foreach($_POST as $nombre_campo => $valor){
eval("\$$nombre_campo=$valor;");
}

El bucle foreach, recorre el array del $_POST y asIgna a cada indIce el valor correspondIente.
Este bucle fInalIza cuando ya no exIsten indIces en el $_POST.
0entro del bucle, la funcIon eval(), evalua la cadena como sI fuera codIgo PHP.
AutomtIcamente se declaran las varIables del formularIo con sus respectIvos valores.
Por ejemplo, en la prImera vuelta del bucle, se recIbe el indIce nombre y su valor, que
corresponde al prImer campo del formularIo. Entonces la segunda linea seria equIvalente a
escrIbIr lo sIguIente:
$nombre="Pepe";
0e esta manera, se generarian todas las varIables recIbIdas.


87


CodIgo de la pgIna procesa.php (2/2)

ContInuando con el anlIsIs del presente codIgo, vemos que en la linea 29 se declara $fecha
que contIene la fecha tomada del servIdor por la funcIon date(). Luego se crean las varIables
$destino, $asunto y el $mensaje. Este ultImo ser una concatenacIon de las varIables
recIbIdas.
La varIable $cabeceras, declarada entre las lineas JJ y J6, corresponde a la cabecera del
emaIl que se envIar, no la confunda con la cabecera de la pgIna.

En la linea J7, se ejecuta la funcIon de envio del emaIl, cuyos parmetros sern las varIables que
se declararon anterIormente. Fecuerde que la funcIon mail() devuelve un valor booleano. Este
valor ser true en el caso de un envio exItoso.
SI el mensaje se envia correctamente, se muestra al usuarIo el resultado con la InformacIon ms
Importante: el plan solIcItado, forma y medIo de pago; todo a travs de las varIables anterIores.
En caso de que ocurra algun error con el envio de los datos, se muestra un mensaje IndIcando el
mIsmo, en la linea J8.
En la linea 51 se Incluye el pIe de pgIna de la mIsma forma que en las dems pgInas.

88

0Y%+D'D'#!T#+!+%,#$*%+!

0esarrolle la seccIon de contacto del ejercIcIo anterIor, segun lo sIguIente:

- ncluya las pgInas "cabecera.html" y "pIe.php".
- Los datos del formularIo deben ser procesados por la mIsma pgIna de contacto.
- 0ebe escrIbIr el codIgo PHP necesarIo para controlar el relleno de todos los campos. En
caso contrarIo, muestre nuevamente el formularIo con los campos rellenados que se
completaron en el prImer Intento, e IndIque al usuarIo los datos faltantes y el fracaso del
envio.
- UtIlIce el bucle foreach para recIbIr los datos.
- Una vez que el usuarIo ha completado el formularIo correctamente, se debe envIar a una
casIlla de correo del contacto del sItIo e IndIcar al usuarIo el xIto de la operacIon,
mostrando el formularIo con los campos vacios.

Este ejercIcIo deber ser resuelto y envIado a su autor cuando ste se lo IndIque.

89

8%,T<%,-.,!.!$.,!.D-'*'K.K%,!K%!.<-#%*.$<.D'E)!
!
@<-#%*.$<.D'E)!3G!8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!

3 0os ordenadores servIdores conectados a Internet y que tIenen la mIsma dIreccIon P, podrian
recIbIr, sImultneamente, las mIsmas petIcIones de los clIentes.

` ` 7erdadero ! Falso

Ccdc dspostvo que se conectc c nternet lo hcce con unc lP d]erente del resto. No exsten
dspostvos con lc msmc lP en unc msmc red.

!
2 Todos los archIvos que recIbe el clIente, son procesados para ser mostrados al usuarIo a travs
del navegador web.

` ` 7erdadero ! Falso

El so]twcre clente solcmente procesc los crchvos petconcdos que son reconocdos por l. Los
crchvos no reconocdos son procescdos por cplcccones externcs y, s stcs no exsten, son
consdercdos como desccryc.


Q Las petIcIones de los clIentes se transfIeren a travs del protocolo HTTP.

! 7erdadero ` ` Falso


S Un navegador web petIcIona una pgIna HT|L que contIene tres Imgenes, un formularIo de
contacto y una anImacIon SWF. Entonces, se establecen cInco conexIones IndependIentes.

! 7erdadero ` ` Falso

En e]ecto, se estcblece unc conexon pcrc lc pcync HTML que contene el ]ormulcro, unc pcrc
el SWF y tres mcs, unc pcrc ccdc mcyen.

!
W El servIdor web es capaz de Interpretar el codIgo HT|L de una pgIna web y representarla en
un formato grfIco comprensIble para el clIente.

` ` 7erdadero ! Falso

El servdor web no nterpretc nnyn codyo. Es el so]twcre clente quen nterpretc el HTML
pcrc representcrlo en ]ormcto vsucl cl usucro.


X Para programar una pgIna dInmIca no necesIta conocer HT|L ya que el servIdor se encargar
de generarlo.

` ` 7erdadero ! Falso

0nc pcync dncmcc permte que el servdor de cplcccones lc nterprete pcrc yenercr unc
scldc de codyo HTML hccc el clente, por lo tcnto, s proyrcmc pcyncs dncmccs debe
conocer como yenercr HTML desde ellcs.

90

@<-#%*.$<.D'E)!2G!8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!

3 Dbserve el codIgo HT|L de abajo:

<p>Esto es HTML!...</p>

Este codIgo mostrar el sIguIente resultado en la pantalla de un navegador:

Esto es HTML!...

` ` 7erdadero ! Falso

Los espacios entre caracteres del cdigo no son tenidos en cuenta ms de una sola vez. Para
obtener el resultado mostrado, debe utilizar un cdigo HTML que representa los espacios: &nbsp;
Debe escribir este cdigo tantas veces como espacios requiera.


2 El sIguIente codIgo HT|L, representa una estructura vlIda:

<html>
<body>
<head>
<title>Ttulo del documento</title>
Esto se ve en el navegador.
</head>
Cuerpo del documento
</body>
<html/>

` ` 7erdadero ! Falso



Q El codIgo del punto 2 mostrar el sIguIente resultado en la pantalla de un navegador:

Esto se ve en el navegador. Cuerpo del documento


! 7erdadero ` ` Falso

Lc estructurc del codyo del punto 2 es ncorrectc, pero el resultcdo serc el que se muestrc en
este punto.


4 El atrIbuto action de una etIqueta de formularIo es el que IndIca quIn va a recIbIr los datos
envIados, su valor es opcIonal y, sI no se especIfIca, los datos son envIados a la mIsma pgIna del
formularIo.

! 7erdadero ` ` Falso

91

@<-#%*.$<.D'E)!QG!8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!

3 PHP es el acronImo de Hypertext PreProcessor y consIste en un lenguaje Interpretado IncluIdo
en pgInas web, y ejecutado en el servIdor web.

` ` 7erdadero ! Falso

PHP es nterpretcdo por el servdor de cplcccones de PHP.
!
!
2 Antes de subIr archIvos a un servIdor remoto, es convenIente probar las aplIcacIones web de
PHP en un servIdor local.

! 7erdadero ` ` Falso


Q Los paquetes precompIlados como AppServ permIten Instalar fcIlmente el servIdor web, el
Intrprete de PHP, la base de datos y el servIdor de correo.

` ` 7erdadero ! Falso

AppServ no ncluye un servdor de correo, pcrc nstclcr uno en modo loccl, debe recurrr c otro
medo como sendmcl, mnRelcy, lnternet ln]ormcton Server, etc.


S Una vez Instalado el servIdor local, podr acceder a una pgIna del mIsmo escrIbIendo, por
ejemplo, C:/AppServ/www/mIpagIna.html, en la barra de dIreccIones del navegador.

` ` 7erdadero ! Falso

En este ccso solcmente cccederc cl crchvo sn utlzcr el protocolo HTTP. 0e estc ]ormc no
podrc vsuclzcr correctcmente lc pcync. Este es un error yrcve y muy comn entre los
prncpcntes.


W Dtra forma de Ingresar a una pgIna web del servIdor local, es escrIbIendo, por ejemplo,
http://localhost/mIpagIna.html en la barra de dIreccIones del navegador clIente.

! 7erdadero ` ` Falso


X Podria crear una pgIna con codIgo PHP o HT|L utIlIzando el bloc de notas de su sIstema
operatIvo wIndows.

! 7erdadero ` ` Falso


[ Una varIable se almacena en la memorIa del ordenador clIente para que el servIdor web pueda
acceder a ella, medIante su IdentIfIcador, al procesar el codIgo PHP de la pgIna solIcItada.

` ` 7erdadero ! Falso

Lcs vcrcbles de unc pcync dncmcc se clmccencn en lc memorc del servdor de cplcccones
que estc procescndo dchc pcync.

92

@<-#%*.$<.D'E)!SG!8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!
!
3 Las sIguIentes lineas de codIgo son equIvalentes:

$a=' Web';
$cadena='Programacin'.$a;
$a=' Web';
$cadena="Programacin $a";


! 7erdadero ` ` Falso

!
2 El sIguIente codIgo mostrar la frase "son Iguales" en la pantalla del navegador:

$a=20;
if ($a=33){
echo "son iguales";
}

! 7erdadero ` ` Falso

Esto se debe c que no se reclzc unc compcrccon sno que se estc csyncndo el vclor JJ c lc
vcrcble $a. Recuerde que cero (0) es equvclente c false y cuclquer otro vclor no vcco es
trcns]ormcdo c boolecno por lc estructurc. S un vclor dstnto de cero o dstnto de vcco es
trcns]ormcdo c boolecno, se obtene un true, estc es lc rczon por lc que se cumple lc
condcon.


Q El bucle while ejecuta sus InstruccIones mIentras su condIcIon sea true. Cuando la condIcIon
es false, el bucle ejecuta sus InstruccIones por ultIma vez y fInalIza el procesado de la pgIna
PHP.

` ` 7erdadero ! Falso

El ntrprete de PHP no e]ecutc lcs nstruccones de while s su condcon es false y contnc
con lc nterpretccon del resto del codyo.


S El anIdamIento de sentencIas del codIgo de abajo es correcto y mostrar en la pantalla el
resultado de la fIgura de al lado:

<table>
<?php
$n=1;
while ($n<=4) {
$a=$i+10;
echo '<tr>';
while ($i<=$a) {
if ($i%2==0){
echo '<td bgcolor="#000000">'.$i.'</td>';
}else{
echo '<td bgcolor="#ffffff">'.$i.'</td>';
}
$i++;
}
echo '</tr>';
$n++;
}
?>
</table>



9J


! 7erdadero ` ` Falso


W El codIgo de abajo produce en la pantalla del navegador el resultado que se observa:

<?php
define("MES",09);
echo MES;
define("MES",11);
echo MES;
?>
Fesultado:

0911

` ` 7erdadero ! Falso

0nc constcnte permcnece "constcnte" lueyo de ser declcrcdc con define. Por lo tcnto, el
resultcdo serc: 0909


6 El codIgo que se muestra a contInuacIon permIte vIsualIzar una Imagen seleccIonada al azar
entre las que se encuentran en la matrIz de $imagenes:

<?php
$imagenes=array("familia.jpg", "amigos.jpg", "vacaciones.jpg", "navidad.jpg");
$cual=rand(1,4);
?>
<img src="<?=$imagenes[$cual];?>" />

` ` 7erdadero ! Falso

S $cual ndcc el ndce de lc mctrz, lc ]uncon rand, selecconcrc un nmero cl czcr entre 1
y 4, por lo tcnto estcrc busccndo entre "cmyos.]py" y un vclor nde]ndo. Pcrc que este codyo
]uncone correctcmente, debe ccmbcr los pcrcmetros de rand por 0 y J. En e]ecto, el ndce 0
corresponde cl prmer vclor de lc mctrz.


[ Segun el codIgo de abajo, los valores de los campos del formularIo "nombre", "emaIl" y
"mensaje", llegan a esta pgIna por medIo del mtodo PDST:

<?php
$nombre=$_POST['campo_nombre'];
$email=$_POST['campo_email'];
$mensaje=$_POST['campo_mensaje'];
$envio=mail("email@destino.com", "Mensaje de $nombre ($email)", $mensaje, $cabeceras);
if ($envio){
echo "Enviado.";
}else{
echo "No se pudo enviar";
}
?>


` ` 7erdadero ! Falso

Los vclores de los ccmpos que lleycn por lc mctrz PDST son: "ccmpo_nombre", "ccmpo_emcl"
y "ccmpo_mensc]e".

94

1'-<.D'E)!>+#F%,'#).$!2G!0"9!19N7

ECD SDFT es una joven empresa dedIcada al desarrollo de software contable para PY|ES, posee
un sItIo web para la muestra y descarga de su producto. Actualmente el sItIo est elaborado en
HT|L "puro" y la actualIzacIon se realIza mensualmente sIn requerIr grandes cambIos; pero
surge la necesIdad de mostrar, a los usuarIos y clIentes, InformacIon relevante sobre
actualIzacIones del software, promocIones y nuevas normatIvas contables.
Para resolver el problema decIden recurrIr a sus servIcIos de programador web y le solIcItan que
realIce un sIstema de notIcIas de acuerdo a las sIguIentes caracteristIcas:

- Se reserva un espacIo en la pgIna de InIcIo del sItIo para la muestra de las notIcIas.
- Por cada Informe se muestra el titulo, la fecha de edIcIon, un resumen y un enlace que
permIta dIrIgIr al usuarIo a otra pgIna en la que se muestre la notIcIa completa.
- 0ebe realIzar una pgIna que permIta al personal de la empresa, admInIstrar los Informes
rpIdamente.
- El admInIstrador debe poder agregar, elImInar y actualIzar las notIcIas.

La fIgura de abajo pertenece al dIseo de la Interfaz de la pgIna de InIcIo del sItIo y el espacIo
para las novedades que corresponde a la columna derecha:



Su trabajo consIstIr en programar la aplIcacIon solIcItada sIn tener en cuenta los detalles de
dIseo, ya que los mIsmos sern aplIcados medIante la hoja de estIlos del sItIo actual.

95

I%++.='%)-.,!


1 ServIdor de base de datos
1.1 |ySQL
1.2 AdmInIstracIon de una base de datos con php|yAdmIn

2 El lenguaje de consultas estructurado SQL
2.1 SeleccIon de datos
2.2 ngresar InformacIon
2.J ActualIzar o modIfIcar campos
2.4 ElImInar regIstros

J PHP y |ySQL
J.1 ConexIon al servIdor de la base
J.2 SeleccIon de la base de datos
J.J Consultas
J.4 Procesado de datos
J.5 LIberacIon de memorIa y cIerre de conexIon

96

3!1%+*'K#+!K%!H.,%!K%!K.-#,!
En la sItuacIon planteada usted debe programar pgInas dInmIcas que permItan la
admInIstracIon de las novedades que desea mostrar ECD SDFT a sus vIsItantes. Esta
admInIstracIon estar planIfIcada de manera tal que los responsables del sItIo puedan agregar,
edItar y elImInar notIcIas.
Para realIzar estas tareas con los contenIdos de InformacIon, debe dIsponer un sIstema que
permIta almacenarlos y tratarlos segun las especIfIcacIones que se plantearon. Esto lo lograr
con el uso del servIdor de bases de datos.

Un servIdor de bases de datos es un software que almacena datos estructurados en forma de
tablas. 0e esta manera, PHP podr conectarse al servIdor de bases de datos y consultar la
InformacIon almacenada en l. Esta consulta puede ser, por ejemplo, para obtener datos,
elImInarlos, agregar nuevos o edItar los almacenados.
Los datos de una base se almacenan en tablas, las cuales organIzan la InformacIon en fIlas y
columnas. Semejante a las tablas a una planIlla de datos de |Icrosoft Excel. Las bases de datos,
tambIn pueden tener ms de una tabla y a su vez, las tablas pueden relacIonarse por medIo de
sus datos. Por ejemplo, puede tener una tabla de clIentes, una de productos y una de productos
vendIdos que relacIone los clIentes con los productos que compro cada uno. En base a esta
relacIon de tablas, podemos decIr que una base de datos es una coleccIon de InformacIon
relacIonada y organIzada.

Una tabla de base de datos podria representarse grfIcamente como en el sIguIente ejemplo:

7.H$.!d"#)-.D-#,e!
5#=H+%!M!.T%$$'K#! 6'+%DD'E)! 7%$jF#)#! "'<K.K!
DrtIz Cabrera C/|ayor, 12 4458962 Cordoba
Ana Carcia Avda. Arroyos, 54 45962J9 Cordoba
Jose Lopez A. |. 8arros 78 0J546456554 Santa Fosa

La tabla del ejemplo, llamada "Contactos", representa una agenda de personas con sus
respectIvos datos, necesarIos para contactarlas. 0e ella puede observar que una tabla est
formada por columnas, fIlas, valores y tIpos de datos.
Cada columna tIene un nombre de campo y corresponde a un conjunto de valores del mIsmo
tIpo. En el ejemplo, el campo "Nombre y apellIdo" tIene una serIe de valores del tIpo texto, que
forman la columna.
Una fIla de la tabla, corresponde a una unIdad de InformacIon, que para el ejemplo cItado, seria
la InformacIon correspondIente a una persona. A partIr de ahora, llamaremos regIstro a esta
unIdad de InformacIon.
Entonces, la tabla del ejemplo, est formada por sIete campos y contIene tres regIstros
almacenados. Y adems, tIene nombre: "Contactos".
Esta tabla podria estar almacenada en una base de datos, que podriamos llamar, "Agenda". En
esta base de datos de ejemplo, podrian exIstIr otras tablas adems de "Contactos".

Este concepto de almacenamIento en tabla es el mIsmo que se utIlIza en los servIdores de bases
de datos y su dIseo estructural est basado en el sentdo comn.
Aunque la tabla del ejemplo es efIcaz, no es relacIonal. Una base de datos relacIonal debe
mantener un vinculo entre sus elementos. Entonces, a modo de ejemplo IntroductorIo,
podriamos crear otra tabla en la mIsma base de datos "Agenda", con los datos personales de
cada contacto como en el sIguIente ejemplo:



97

7.H$.!d6.-#,!T%+,#).$%,e!
5#=H+%!M!.T%$$'K#! 9D<T.D'E)! 0K.K!
DrtIz Cabrera ng. ndustrIal 42
Ana Carcia ArquItecta J1
Jose Lopez ServIcIo tcnIco 27

Las tablas "Contactos" y "0atos personales" son dos tablas dIstIntas, pero exIste relacIon entre
ambas en la base de datos a travs del campo "Nombre y apellIdo". Esto permIte relacIonar los
datos de contacto con los datos personales de cada persona.

En la presente materIa no se estudIarn tablas relacIonadas pero es Importante que usted
conozca la exIstencIa de ellas y la posIbIlIdad de tenerlas en cuenta para sus proyectos
profesIonales.

A contInuacIon, ver uno de los servIdores de base de datos sItuado entre los ms populares y un
panel de admInIstracIon de base de datos. Ellos se Incluyen en el paquete de AppServ que usted
ha Instalado prevIamente, en la sItuacIon profesIonal 1.


3J3 AM1hP!
|ySQL es un servIdor de base de datos relacIonales que permIte crear base de datos y tablas,
Insertar datos, modIfIcarlos, elImInarlos, ordenarlos, hacer consultas, busquedas y muchas otras
operacIones para admInIstrar bases de datos.
Este servIdor se puede manejar medIante secuencIa de comandos Ingresados desde la $a)%.! K%!
D#=.)K#,! del mIsmo o desde PHP.
En esta materIa no estudIaremos el Ingreso de comandos desde la linea de |ySQL, lo haremos
desde PHP.


Ayuda ahora
Pa)%.!K%!D#=.)K#, es la Interfaz de usuarIo para comunIcarlo con el sIstema de |ySQL medIante una
ventana que espera ordenes escrItas usando el teclado. SI ha Instalado AppServ, puede acceder desde el
menu InIcIo programas AppServ |ySQL Command LIne ClIent.

|ySQL fue creado por la empresa sueca |ySQL A8, la cual tIene el copyrIght de su codIgo
fuente, asi como tambIn de la marca.
Es un software de codIgo abIerto, lIcencIado bajo la ?>P ! de la ?5(! , aunque |ySQL A8
dIstrIbuye una versIon comercIal, en lo unIco que se dIferencIa de la versIon lIbre, es en el
soporte tcnIco que se ofrece, y la posIbIlIdad de Integrar este gestor en un software
propIetarIo, ya que de otra manera, se vIolaria la lIcencIa CPL.


Ayuda ahora
?>PL! es una lIcencIa publIca general de ?5(! oCeneral PublIc LIcense) o CNU CPL, creada por la Free
Software FoundatIon a medIados de los 80, y est orIentada a proteger la lIbre dIstrIbucIon,
modIfIcacIon y uso de software. Su proposIto es declarar que el software cubIerto por esta lIcencIa es
software lIbre y protegerlo de Intentos de apropIacIon que restrInjan esas lIbertades a los usuarIos.

El lenguaje de programacIon que utIlIza |ySQL es Structured Query Language (SQL) que fue
desarrollado por 8| en 1981 y desde entonces es utIlIzado de forma generalIzada en las bases
de datos relacIonales.

98

|s adelante estudIar el lenguaje de consulta estructurada o SQL, para realIzar operacIones
con la base de datos de la sItuacIon profesIonal actual.

ExIsten muchos servIdores de bases de datos, pero |ySQL sIgue sIendo el ms utIlIzado por la
comunIdad de programadores web. Este servIdor ofrece ventajas como:

! El uso de |ySQL es gratuIto.
! |ySQL A8 ofrece contratos de asIstencIa a precIos razonables y exIste una nutrIda y
actIva comunIdad de |ySQL.
! Es mucho ms rpIdo que la mayor parte de sus rIvales.
! 0Ispone de muchas de las funcIones que exIgen desarrolladores profesIonales.
! Se puede ejecutar en la Inmensa mayoria de los sIstemas operatIvos y, la mayor parte de
los casos, los datos se pueden transferIr de un sIstema a otro sIn dIfIcultad.
! Fesulta fcIl de utIlIzar y de admInIstrar. Cran parte de las vIejas bases de datos
presentan problemas por utIlIzar sIstemas obsoletos, lo que complIca InnecesarIamente
las tareas de admInIstracIon.
! Las herramIentas de |ySQL son potentes y flexIbles, sIn sacrIfIcar su capacIdad de uso.


3J2!@K=')',-+.D'E)!K%!<).!H.,%!K%!K.-#,!D#)!TVTAM@K=')!
php|yAdmIn es un programa de lIbre dIstrIbucIon, bajo lIcencIa CNU CPL, creado por una
comunIdad sIn nImo de lucro. Es una herramIenta muy completa que permIte acceder a todas
las funcIones tipIcas de la base de datos |ySQL a travs de una Interfaz web muy IntuItIva y sIn
necesIdad de conocImIentos avanzados para la creacIon y admInIstracIon de bases de datos. Est
dIsponIble en 54 IdIomas y puede obtener InformacIon o descargarlo desde
www.phpmyadmIn.net. SI ha Instalado AppServ, no necesItar descargarlo, ya que est IncluIdo
en el paquete.
Este panel de admInIstracIon est basado en pgInas dInmIcas programadas en PHP que agIlIzan
el trabajo de programadores prIncIpIantes.
|ySQL puede ser admInIstrada desde su propIa linea de comandos, pero php|yAdmIn permIte
una admInIstracIon ms sencIlla y grfIca, por lo que le ser de gran ayuda para comenzar a
IntroducIrse en el uso del servIdor |ySQL.

A contInuacIon, veremos algunas de las operacIones ms Importantes que debe aprender para
poder resolver la sItuacIon profesIonal actual.

@DD%,#!.$!T.)%$!TVTAM@K=')!
Para acceder al panel de admInIstracIon de sus bases de datos en modo local, debe Ingresar al
servIdor:

http://locclhost
o
http://locclhost:88 sI ha Instalado su servIdor en el puerto 88.

Aparecer la pgIna de InIcIo de AppServ, Ingrese al prImer enlace como se IndIca en la fIgura:


99



Luego Ingrese su nombre de usuarIo y contrasea, correspondIentes a los datos proporcIonados
durante la InstalacIon de AppServ.



Una vez Ingresado al panel de admInIstracIon, aparecer la pantalla prIncIpal de php|yAdmIn:


100



En esta pgIna, obtendr InformacIon del servIdor, podr cambIar alguna confIguracIon como el
IdIoma o el D#-%Y.='%)-#! K%! $.,! D#)%b'#)%,! K%! AM1hP! . TambIn le permIte vIsualIzar las
bases de datos Instaladas y acceder a una de ellas desde el menu desplegable de la IzquIerda.


Ayuda ahora
"#-%Y.='%)-#! K%! $.,! D#)%b'#)%,! AM1hPL! se refIere al tratamIento de caracteres especIales de un
lenguaje natural durante la conexIon de un servIdor de aplIcacIones que consulta a la base de datos.
Este tratamIento consIste en la codIfIcacIon de dIchos caracteres en simbolos estandarIzados que |ySQL
pueda manejar.

0esde esta pantalla podr crear una nueva base de datos, como se descrIbe a contInuacIon.

"+%.D'E)!K%!<).!H.,%!K%!K.-#,!M!<).!-.H$.!
7amos a crear una base de datos de ejemplo, llamada "agenda" como se muestra a
contInuacIon:

7.H$.!dD#)-.D-#,e!
/6! )#=H+%! %K.K! -%$%F#)#! %=.'$!
1 DrtIz Cabrera 42 4458962 cortIz@gmaIl.com
2 Ana Carcia J1 45962J9 garcIa_ana@hotmaI.com


101

ngrese el nombre de la base de datos en el campo "Crear nueva base de datos", luego
seleccIone el cotejamIento adecuado a la codIfIcacIon de caracteres que necesItar para la
InformacIon que almacene en la mIsma.



En este caso seleccIonamos "utf8_general_cI" para mayor compatIbIlIdad con todos los IdIomas.
PresIone el boton "Crear" para generar la nueva base. Aparecer el sIguIente mensaje:




102

En la Imagen de arrIba, php|yAdmIn le confIrma el xIto de la operacIon y muestra un
formularIo para crear la prImera tabla de la base "agenda".
En el campo "Nombre" escrIba el nombre de la tabla. Para este caso creamos una tabla llamada
"contactos" que tendr 5 campos, como se IndIca arrIba.
Una vez que presIone "ContInuar", se carga la pantalla de confIguracIon de campos para la
tabla:



En la columna "Campo" debe escrIbIr los nombres de los campos de la tabla. En la columna
"TIpo" debe IndIcar el tIpo de datos que se almacenan por cada campo. |ySQL soporta J
categorias de datos: numrIcos, fecha y hora, y cadenas de caracteres. Es Importante resolver el
tIpo de dato que utIlIzar cada campo para mejorar el rendImIento Interno del servIdor y
optImIzar las operacIones que realIce en cada consulta entre otras. A contInuacIon veremos
algunos de los tIpos de datos ms utIlIzados de cada categoria:

NumrIcos
NT Numeros enteros.
FLDAT Numeros decImales.
0DU8LE Numeros decImales de doble precIsIon.
8DDL 8ooleanos, un valor de cero se consIdera falso. 7alores dIstIntos a cero se
consIderan verdaderos.
Fecha y hora
0ATE SIrve para almacenar una fecha en formato 'YYYY||00'. El rango
soportado es de '10000101' a '999912J1'.
0ATET|E Para almacenar una fecha y hora en formato 'YYYY||00 HH:||:SS'. El
rango soportado es de '10000101 00:00:00' a '999912J1 2J:59:59'.
Cadenas de caracteres
CHAF Cadenas de longItud fIja con una longItud mxIma de 255 caracteres.
7AFCHAF Cadenas de longItud varIable con una longItud mxIma de 255 caracteres.
TEXT Cadenas de longItud superIor a 255 caracteres, hasta 655J5 caracteres.

Un numero de coma flotante con precIsIon sencIlla (FLDAT) tIene una precIsIon de 7 decImales
aproxImadamente; un numero de coma flotante de doble precIsIon (0DU8LE) tIene una precIsIon
aproxImada de 15 decImales.
La prIncIpal dIferencIa entre CHAF y 7AFCHAF es que el prImero ocupar el tamao mxImo que
se haya fIjado en la propIedad "LongItud/7alores" aunque el tamao del dato cargado sea
menor, ste es completando con espacIos. 7AFCHAF solo almacena la longItud del dato

10J

cargado, permItIendo que el tamao de la base de datos sea menor, pero la velocIdad de acceso
a los datos es mayor en CHAF.
Puede consultcr sobre otros tpos de dctos en www.mysql.com.

En "LogItud/7alores", debe Ingresar el numero de caracteres mxImo que puede contener el
campo, esto no hace falta para los del tIpo 8DDL, 0ATE, 0ATET|E y TEXT pero para los NT,
FLDAT, 0DU8LE y 7AFCHAF es necesarIo.
En el caso de FLDAT y 0DU8LE, esta propIedad debe IndIcarse con el formato (|,0) en donde |
es la longItud total y 0 es la cantIdad de decImales. SI por ejemplo especIfIca un campo del tIpo
FLDAT con un entero y dos decImales, escrIbIr "J,1". Al almacenar un valor como 1.J987679,
este valor es redondeado por |ySQL y quedar 1.40 como valor defInItIvo.
La propIedad "AtrIbutos" permIte especIfIcar sI los valores numrIcos admIten numeros
negatIvos. SI se especIfIca "UNSCNE0", no admItIrn valores negatIvos.
Cuando se usa ZEFDFLL, el relleno por defecto de espacIos se remplaza por ceros. Por ejemplo,
para una columna declarada como NT(5) ZEFDFLL, un valor de 4 se muestra como 00004. Los
valores ZEFDFLL no admIten numeros negatIvos.
En "Nulo", puede elegIr Null o Not Null dependIendo sI quIere que el campo pueda estar vacio
(sIn datos) o no.

En "PredetermInado", puede poner un valor predefInIdo en el caso de que no se rellenen los
datos o que se rellene de forma Incorrecta.

ContInuando con el ejemplo, el prImer campo "0", corresponde a un IdentIfIcador unIco que
evItar futuros errores durante consultas a la base en el caso de que algun regIstro de la tabla se
repIta. ste debe ser auto Incrementable ya que el mIsmo ser generado por la base de datos
cuando se carguen los regIstros. Esta propIedad la establecemos en la columna "Extra" como
auto_Increment y en la columna de al lado seleccIonamos el boton de opcIon, debajo del Icono
con la llave "PrImarIa", para IndIcarle a |ySQL que se trata de una clave prIncIpal. 0e esta
forma cada vez que se Ingrese un nuevo regIstro en este campo, se le sumar 1 a la mxIma "0"
exIstente o valdr 1 sI es el prImer regIstro que Ingresa a la tabla. 0e forma que podremos tener
un orden de Ingreso.
Las claves prImarIas son de utIlIdad al trabajar con tablas relacIonadas y permIten ubIcar
regIstros sIn que |ySQL consuma mayores recursos del servIdor por tener que revIsar toda la
tabla.

En la fIgura de abajo, se muestran los nombres de los dems campos y sus propIedades:


Una vez que fInalIce la confIguracIon de todos los campos de la tabla "contactos", presIone
"ContInuar" para Implementarla a la base "agenda". Aparecer la sIguIente pantalla:

104



En esta pantalla se muestra el mensaje de confIrmacIon de la operacIon y debajo de l, la
consulta realIzada en codIgo SQL que estudIaremos ms adelante. SI no contara con
php|yAdmIn, deberia realIzar la consulta con dIcho codIgo SQL desde la linea de comandos.
Por ultImo se puede vIsualIzar la estructura de la tabla creada.

Dbserve que en zona IzquIerda hay un enlace a la tabla "contactos", debajo de la base de datos
"agenda". Este enlace conduce a la pantalla de admInIstracIon de la tabla, como se muestra en
la fIgura de abajo.
Por defecto, se mostrar la estructura de la tabla y en la zona superIor encontrar el menu de
solapas para realIzar dIversas operacIones sobre ella:


105



El enlace "ExamInar", permIte vIsualIzar los datos cargados en la tabla, pero como ha sIdo
creada recIentemente, todavia no hay regIstros cargados y sI presIona sobre "ExamInar", se
mostrar un mensaje IndIcando que la tabla est vacia:



7olvIendo a la solapa de "Estructura", podr modIfIcar o elImInar los campos de la tabla de
varIas formas, una de ellas es seleccIonando los campos y presIonando sobre el icono "edItar"
o "elImInar" , segun la operacIon que desee realIzar:




106

Dtra forma de hacer lo mIsmo, pero en un solo campo, es pulsando sobre el icono "edItar"
o "elImInar" , pero esta vez en alguno de los que se encuentran en la columna "AccIon",
sobre la fIla del campo que quIera afectar.
Por ejemplo, sI queremos edItar el campo "0", debemos pulsar sobre el icono "edItar" que
se encuentre en la mIsma fIla de dIcho campo. Aparecer la pantalla de edIcIon del campo "0",
con las mIsmas opcIones que se presentaban cuando creo la tabla:



/),%+-.+!K.-#,!%)!<).!-.H$.!
Para Insertar datos en una tabla, desde php|yAdmIn, presIone en la solapa "nsertar". Se
mostrar la sIguIente pgIna:



Tendr la posIbIlIdad de Ingresar dos regIstros a la tabla "contactos". El campo "0", no debe
rellenarlo porque el mIsmo es completado automtIcamente por la base de datos, recuerde que
es auto Incrementable y de clave prImarIa.
Una vez completados los campos, presIone "ContInuar" para agregar los regIstros, php|yAdmIn
le mostrar la pantalla de confIrmacIon:

107



SI presIona en la solapa "ExamInar", ver que aparecen los regIstros Ingresados:



0bT#+-.+!$.!H.,%!K%!K.-#,!T.+.!<)!,%+*'K#+!+%=#-#!
El proceso de creacIon de un sItIo web, requIere que este sea realIzado en modo local, como se
IndIco en la sItuacIon profesIonal 1. Una vez fInalIzada la programacIon y puesta a punto del sItIo
en modo local, debe Instalarlo en un servIdor de hostIng remoto. Esto ImplIcaria la subIda de
fIcheros y la creacIon de la base de datos.

108

magIne por ejemplo, que est trabajando en una base de datos local que contIene decenas de
tablas y a su vez, cada tabla contIene centenares de regIstros Ingresados, seria muy tedIoso
tener que construIr una rplIca en el servIdor remoto, y su consecuente prdIda de tIempo.
Para evItar el proceso de creacIon de tablas y la InsercIon manual de regIstros,
afortunadamente, php|yAdmIn, dIspone de la automatIzacIon de este proceso.
El proceso de mIgracIon consIste en exportar la base de datos a un archIvo de extensIon ".sql" y
luego, desde la base del servIdor remoto, la ImportacIon de l.
El archIvo exportado contendr toda la InformacIon de la base de datos y generar de manera
automtIca, una rplIca de la base local.
7amos a exportar la base del ejemplo que estamos desarrollando en esta herramIenta, para ello,
Ingresamos a la base de datos presIonando el enlace con el nombre "agenda" en la zona
IzquIerda, luego en la solapa "Exportar" se mostrar la pgIna de exportacIon de bases de datos.
En esta pantalla, mantenemos los valores por defecto de php|yAdmIn y seleccIonamos la casIlla
de verIfIcacIon "EnvIar", como se muestra en la fIgura:



Esta casIlla permIte descargar un archIvo cuyo nombre pertenece al de la base de datos. En este
caso se llamar "agenda.sql". Cuarde este archIvo en su ordenador para luego Importarlo desde
el panel de base de datos del servIdor remoto.

109

El archIvo que acaba de guardar, es un sImple documento de texto que puede ser vIsualIzado
desde un procesador de texto como el "8loc de Notas" de WIndows.

SI abre el archIvo "agenda.sql" con un edItor, ver algunas lineas de texto que corresponden a
InstruccIones del lenguaje SQL, que en este caso descrIben la base de datos del ejemplo:



/=T#+-.+!<).!H.,%!K%!K.-#,!.$!,%+*'K#+!+%=#-#!
Para Importar la base de datos, debe Ingresar al panel de php|yAdmIn de su servIdor remoto y
crear la base de datos agenda de la mIsma forma que se realIzo anterIormente. Luego presIone
en la solapa "mportar", se mostrar la sIguIente pantalla:




110

PresIone el boton "8rowse." y seleccIone el archIvo "agenda.sql" en su ordenador. Luego
presIone "ContInuar" y se mostrar la sIguIente pgIna:



En esta pantalla se muestra la confIrmacIon de la operacIon de ImportacIon realIzada. SI
examIna la zona IzquIerda, encontrar la tabla "contactos" y dentro de ella, los regIstros
cargados en el servIdor local.

Dbserve que cada vez que realIza alguna modIfIcacIon sobre la base de datos, ya sea para crear
una tabla, Insertar datos, vIsualIzar regIstros, Importar o exportar la base, etc., se muestra un
mensaje con la confIrmacIon del xIto de la operacIon y debajo de l, un recuadro con una
consulta SQL equIvalente a la operacIon realIzada por php|yAdmIn.
En las proxImas herramIentas estudIar el lenguaje SQL para operar base de datos desde pgInas
dInmIcas PHP.

111

@<-#%*.$<.D'E)!3!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!

3 Una base de datos |ySQL puede contener una o ms tablas, cada tabla contIene regIstros y
cada regIstro est constItuIdo por campos. A su vez, cada campo contIene valores que deben
corresponder con el tIpo de dato asIgnado a dIcho campo.
!
` ` 7erdadero ` ` Falso


2 php|yAdmIn es un servIdor de base de datos relacIonales que permIte crear base de datos y
tablas, Insertar datos, modIfIcarlos, elImInarlos, ordenarlos, hacer consultas, busquedas y
muchas otras operacIones para admInIstrar bases de datos.
!
` ` 7erdadero ` ` Falso


Q Un campo confIgurado como clave prImarIa del tIpo numrIco entero (NT) y auto
Incrementable (auto_Increment), ser un IdentIfIcador unIco de cada regIstro que Ingrese a una
tabla y su valor no podr ser modIfIcado.
!
` ` 7erdadero ` ` Falso


S Un archIvo con extensIon ".sql" es una base de datos exportada desde el panel de
admInIstracIon php|yAdmIn.
!
` ` 7erdadero ` ` Falso


W Para especIfIcar la longItud de un campo del tIpo FLDAT con un entero y tres decImales
escrIbIr "1,J" en la propIedad "logItud" del panel de pnp|yAdmIn.
!
` ` 7erdadero ` ` Falso



Las respuestas las encontrar al fInal de la sItuacIon profesIonal.

112

2!0$!$%)&<.Y%!K%!D#),<$-.,!%,-+<D-<+.K#!1hP!
En la herramIenta anterIor estudIo los conceptos bsIcos sobre bases de datos y como utIlIzar el
panel de admInIstracIon php|yAdmIn. Ahora, estudIar el lenguaje necesarIo para realIzar
consultas a la base de datos.

La manIpulacIon de datos de una base requIere el conocImIento del "Lenguaje Estructurado de
Consultas" o "SQL". ste es un lenguaje unIversal, comun a todas las bases de datos y puede
tener lIgeras varIacIones de un tIpo de base de datos a otra. En este texto, nos enfocaremos a
realIzar consultas sImples de manIpulacIon de datos (6AP! ) que le permItan resolver la
sItuacIon profesIonal y avanzar con el aprendIzaje sIn mayores esfuerzos.


Ayuda ahora
6APG!en SQL se pueden realIzar operacIones sobre la estructura de una base de datos (00L) o sobre los
datos mIsmos (0|L).
El lenguaje de defInIcIon de datos (en Ingls 0ata 0efInItIon Language, o 00L), es el que se encarga de
la operar sobre la estructura de los objetos de la base de datos.
Un lenguaje de manIpulacIon de datos (0ata |anIpulatIon Language, o 0|L en Ingls) es un lenguaje
proporcIonado por el sIstema de gestIon de base de datos que permIte realIzar tareas de consulta o
manIpulacIon de los datos.

SQL permIte realIzar operacIones sobre una base de datos, en efecto, cuando aprendIo a utIlIzar
php|yAdmIn, usted realIzo operacIones sobe |ySQL de una manera sImple y vIsualmente
agradable. Estas operacIones podrian haberse realIzado de otra forma medIante consultas en
lenguaje SQL.
Una consulta no es ms que un conjunto de InstruccIones que se envian a una base de datos para
que sta realIce una operacIon sobre la InformacIon que contIene. Las operacIones que
realIzaremos medIante este lenguaje, sern: seleccIon de datos, Ingreso de nuevos datos,
modIfIcacIon de datos, y borrado de InformacIon.

En la herramIenta J veremos como realIzar las consultas SQL desde PHP utIlIzando las funcIones
para |ySQL. Por ahora las probaremos en php|yAdmIn, en el campo de texto que aparece al
Ingresar a la pestaa SQL:






11J

2J3!1%$%DD'E)!K%!K.-#,!
La seleccIon de datos consIste en consultar regIstros de una tabla segun un crIterIo determInado.
UtIlIzaremos el comando SELECT cuya sIntaxIs es la sIguIente:

SELECT campos FROM tabla

Las palabras SELECT y FROM, son propIas del lenguaje SQL. La prImera es un comando que
permIte la seleccIon de regIstros y FROM es una clusula que IndIca la tabla sobre la que se
realIza la consulta.
0elante de SELECT se IndIcan los campos que se van a obtener en el resultado de la consulta.
En la herramIenta anterIor, usted creo una base de datos llamada "agenda" y dentro de ella la
tabla "contactos", luego Ingreso algunos regIstros. 7eamos ejemplos basados en esta tabla:

SELECT nombre FROM contactos

Esta linea de InstruccIon devolver el lIstado de nombres almacenados en la tabla "contactos":

nombre
DrtIz Cabrera
Ana Carcia

Para obtener un resultado con ms campos como por ejemplo el "nombre" y "edad" de los
contactos, debe escrIbIrlos separados por coma:

SELECT nombre, edad FROM contactos

El resultado ser:

nombre edad
DrtIz Cabrera 42
Ana Carcia J1

Los campos que se quIeran obtener deben estar separados por comas. Y sI quIsIera obtener todos
los campos de los regIstros, puede utIlIzar el asterIsco (*) en lugar de escrIbIr todos los campos
uno por uno:

SELECT * FROM contactos

SI analIza la InstruccIon anterIor, podria traducIrla de la sIguIente manera:

"SeleccIone todos los campos de la tabla contactos".

El resultado de dIcha consulta ser una lIsta de todos los campos de los regIstros que hay en la
tabla contactos:

0 nombre edad telefono emaIl
1 DrtIz Cabrera 42 4458962 cortIz@gmaIl.com
2 Ana Carcia J1 45962J9 garcIa_ana@hotmaIl.com

Puede ocurrIr, por ejemplo, que exIstan centenares de regIstros en una tabla y su proyecto
requIera el fIltrado de los mIsmos. Para ello debe establecer un crIterIo de busqueda de regIstros
utIlIzando la clusula WHERE. Luego de esta clusula se especIfIcan las condIcIones para la
seleccIon de datos, a contInuacIon se muestra la sIntaxIs con el uso de esta clusula:

SELECT campos FROM tabla WHERE condiciones

114


Para especIfIcar las condIcIones podr utIlIzar operadores logIcos y de comparacIon, propIos del
lenguaje SQL pero con cIerta sImIlItud a los estudIados en PHP. 7eamos un ejemplo:

Supongamos que quIere fIltrar los contactos mostrando solamente los que sean mayores de 40
aos:

SELECT * FROM contactos WHERE edad>40

El resultado ser:

0 nombre edad telefono emaIl
1 DrtIz Cabrera 42 4458962 cortIz@gmaIl.com

Dbserve que los datos seleccIonados cumplen con las condIcIones Impuestas por WHERE.

SI quIsIera obtener los datos de una persona especifIca, la consulta seria como la que se muestra
a contInuacIon:

SELECT * FROM contactos WHERE nombre= 'Ana Garca'

0 nombre edad telefono emaIl
2 Ana Carcia J1 45962J9 garcIa_ana@hotmaIl.com

Dbserve el uso de las comIllas en el ejemplo; cuando se trata de un campo no numrIco o del
tIpo texto, el valor comparado se escrIbe entre comIllas, de lo contrarIo no sern necesarIas.

A contInuacIon se muestran algunos de los operadores ms utIlIzados:

Dperadores de comparacIon
Dperador 0escrIpcIon Ejemplo
|enor. SELECT * FFD| contactos WHEFE
edad=40;
Selecconc todos los ccmpos de lc tcblc
contcctos cuyc edcd sec 40.

SELECT nombre FFD| contactos WHEFE
telefono='45962J9';
Selecconc el nombre de los reystros de
lc tcblc contcctos que concdcn con el
tel]ono 452J.
|ayor.
! =

0IstInto.
= |enor o Igual.
= gual.
LKE Para comparar cadenas. SELECT * FFD| contactos WHEFE nombre
LKE 'Cabrera';
Selecconc todos los ccmpos que
contenycn lc pclcbrc 'Ccbrerc' en el
ccmpo nombre de lc tcblc contcctos.




Dperadores logIcos
Dperador 0escrIpcIon Ejemplo
AN0
EE
Es equIvalente a "y" logIco de nuestro lenguaje. SELECT * FFD| contactos WHEFE edad40
AN0 telefono LKE '9';
Selecconc todos los ccmpos de lc tcblc
contcctos que secn menores de 40 y sus
tel]onos ]nclcen en .

115

DF

Es equIvalente a "o" logIco de nuestro lenguaje. SELECT * FFD| contactos WHEFE emaIl
LKE 'hotmaIl.com' DF emaIl LKE
'yahoo.com';
Selecconc todos los ccmpos de lc tcblc
contcctos cuyos emcls ]nclcen en
hotmcl.com o ychoo.com.
NDT
!
Es equIvalente a una negacIon y devuelve un
valor contrarIo al de la expresIon.
SELECT * FFD| contactos WHEFE NDT
edad40;
SeleccIona todos los campos de la tabla
contactos que no sean menores de 40.

Adems de las clusulas WHERE y FROM, exIste otra, como por ejemplo ORDER BY. sta permIte
ordenar los resultados de una consulta segun el campo que se le IndIque. En el ejemplo de
abajo se presentarn los resultados ordenados alfabtIcamente por nombre:

SELECT * FROM contactos ORDER BY nombre

Y sI quIsIera tener un orden alfabtIco Inverso:

SELECT * FROM contactos ORDER BY nombre DESC

DESC los ordenar de manera descendente y ASC ascendente. SI no se especIfIca nada, por
defecto, ser ASC.
LogIcamente podemos combInar con la clusula WHERE:

SELECT * FROM contactos WHERE edad>40 ORDER BY nombre DESC

El resultado ser un lIstado de contactos mayores de 40 y en orden alfabtIcamente Inverso.
7eamos otro ejemplo:

SELECT * FROM contactos WHERE edad>40 ORDER BY edad

En este caso se lIstarn los contactos mayores de 40, ordenados por edad. Este orden ser
numrIco ascendente.


2J2!/)&+%,.+!')F#+=.D'E)!
En la herramIenta 1 de la presente sItuacIon profesIonal, usted Ingreso regIstros a la tabla
"contactos" utIlIzando el panel de admInIstracIon de |ySQL. Ahora deber hacerlo medIante
consultas en lenguaje SQL para que luego pueda utIlIzar la InstruccIon en una pgIna de PHP.
Esto se consIgue aplIcando el comando INSERT. Este comando permIte Insertar regIstros a una
tabla, veamos su sIntaxIs:

INSERT INTO tabla (campo1, campo2, campo_n) VALUES (valor1, valor2, valor_n)

El comando INSERT tIene dos partes claramente defInIdas, la prImera en donde se nombran los
campos que se van a agregar y la segunda, delante de VALUES, es en donde se especIfIcan los
valores de cada campo mantenIendo el mIsmo orden que la prImera. 0elante de INTO se debe
especIfIcar el nombre de la tabla que se va a operar.
7eamos como Ingresar un nuevo regIstro en la tabla "contactos" del ejemplo anterIor:

INSERT INTO contactos (nombre, edad, telefono, email) VALUES ('Ramn Perez', 27,
'4555636 ', 'pramon27@email.com ')


116

SI realIzamos una traduccIon de esta InstruccIon SQL, estariamos dIcIendo a |ySQL que Inserte
dentro de la tabla "contactos", en los campos "nombre", "edad", "telefono" y "emaIl", los
valores: "Famon Perez", "27", "45556J6" y "pramon@emaIl.com", respectIvamente.
Para este tIpo de InsercIon, es Importante que se mantenga el mIsmo orden de campos
nombrados y valores Insertados en la InstruccIon, pero no es necesarIo que ese orden coIncIda
con el de los campos de la tabla en |ySQL porque los est nombrando.
Dbserve que todos los valores de los campos no numrIcos deben especIfIcarse entre comIllas.

En el ejemplo, no se ha Insertado el campo "0". Fecuerde que este campo fue confIgurado en
la tabla, como un campo auto Incrementable de clave prImarIa y debe ser unIco por lo tanto
|ySQL se encargar de generarlo automtIcamente.

Puede comprobar la InsercIon del nuevo regIstro hacIendo una consulta de seleccIon:

SELECT * FROM contactos

El resultado ser:

0 nombre edad telefono emaIl
1 DrtIz Cabrera 42 4458962 cortIz@gmaIl.com
2 Ana Carcia J1 45962J9 garcIa_ana@hotmaIl.com
J Famon Perez 27 45556J6 pramon27@emaIl.com


2JQ!@D-<.$'c.+!#!=#K'F'D.+!D.=T#,!
El comando UPDATE permIte actualIzar o modIfIcar campos de los regIstros en la base de datos.
Su sIntaxIs es la sIguIente:

UPDATE tabla SET campo1=valor1, campo2=valor2, campo_n=valor_n WHERE condicin

En la sItuacIon profesIonal utIlIzar este comando para programar las pgInas que permItan
edItar o modIfIcar las notIcIas guardadas en la base de datos.

Por ejemplo:

UPDATE contactos SET edad=32 WHERE ID=2

En el ejemplo de arrIba estamos actualIzando a J2, la edad de "Ana Carcia", de la tabla
"contactos".
SI no se especIfIca un crIterIo o condIcIon con la clusula WHERE, el comando actualIzaria todos
los regIstros de la tabla.

7eamos otro ejemplo:

UPDATE contactos SET email= 'cabortiz@yahoo.com ', edad=43 WHERE nombre= 'Ortiz
Cabrera'

En este caso se modIfIca el emaIl de "DrtIz Cabrera" y su edad. Dbserve que se utIlIzan comIllas
para los valores de "emaIl" y "nombre", ya que se trata de datos del tIpo texto.
SI exIstIeran dos o ms personas con el mIsmo nombre, la consulta modIfIcaria los campos
"emaIl" y "edad" de todos ellos. Esto se puede evItar sI utIlIzamos un crIterIo ms precIso:

UPDATE contactos SET email= 'cabortiz@yahoo.com ', edad=43 WHERE nombre= 'Ortiz
Cabrera AND email= 'cortiz@gmail.com ' AND telefono= '4458962'


117

Dtra forma seria utIlIzando el "0", tal como se lo hIzo en el prImer ejemplo, ya que ste no
tIene posIbIlIdades de repetIrse:

UPDATE contactos SET email= 'cabortiz@yahoo.com', edad=43 WHERE ID=1

SI quIsIera actualIzar las edades de todos los contactos, Incrementando su valor en una unIdad,
la consulta seria:

UPDATE contactos SET edad=edad+1


2JS!0$'=').+!+%&',-+#,!
Para suprImIr regIstros de una tabla utIlIzar el comando DELETE. ste ser de Inters en la
sItuacIon profesIonal para que los edItores de ECD SDFT puedan elImInar notIcIas desde el panel
de admInIstracIon que usted programar.
La sIntaxIs del comando DELETE es la sIguIente:

DELETE FROM tabla WHERE condicin

7eamos un ejemplo:

DELETE FROM contactos WHERE ID=3

En el ejemplo, se elImIna de la tabla "contactos", el regIstro de "Famon Perez". Dbserve que no
se especIfIcan los campos ya que este comando elImIna regIstros completos.
SI no utIlIza la clusula WHERE, elImInar todos los regIstros de la tabla.

Para elImInar todos los contactos mayores de J0 aos, utIlIzar la sIguIente consulta:

DELETE FROM contactos WHERE edad>30

En este caso se elImInaron los contactos "DrtIz Cabrera" y "Ana Carcia".




118

@<-#%*.$<.D'E)!2!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#L!-%)'%)K#!%)!D<%)-.!$.!,'&<'%)-%!-.H$.!K%!K.-#,G!
!
7.H$.!d=<,'D.e!
0 artIsta tItulo genero
1 ACF8NELL D8FAS PAFA 7DLN, 8AN0DNEDN Y DFQUESTA TANCD
2 ACF8NELL |E|DFA Y TANCD TANCD
J ACUFFE SAN0FA S FDLKLDFE
4 ACUFFE SAN0FA EL HD|8FE 0E 8AFFD FDLKLDFE
5 ALCHDUFFDN FD0DLFD PAFA8DLA JAZZ
6 ALDNSD AF|AN0D 0E| FUSDN
7 AN0EFS JDFCE L7E N 8UENDS AFES 199J JAZZ
8 AFTSTAS 7AFDS CU8A CDN 7DZ 0E |UJEF 7AFDS
9 AFTSTAS 7AFDS LD |EJDF 0EL JAZZ AFCENTND JAZZ
10 8HAFES FAPSD00YA ALCD ESTA CA|8AN0D... 7AFDS
11 |DNTDLU TETE 8FASL CLASCDS JAZZ
12 |DNTDLU TETE EN 77D EN EL SAN JUAN JAZZ
1J |DFENTE ENFQUE 7DZ E AL|A 0EL FLA|ENCD FLA|ENCD
14 |DFCA0D ESTE8AN EL SUEND 0EL 0UEN0E FUSDN
15 |USCA SECFETA |USCA 0E LAS |SDNES 0E CHQUTDS 7AFDS
16 |USCA SECFETA |USCA 0E 0DS |UN0DS 7AFDS

3 La sIguIente consulta permIte obtener el artIsta, tItulo y genero del regIstro cuyo 0 sea 1.

SELECT artista FROM musica WHERE ID=1
!
` ` 7erdadero ` ` Falso


2 La sIguIente consulta muestra todos los titulos de los gneros "tango" o "jazz".
!
SELECT titulo FROM musica WHERE genero='TANGO' OR genero='JAZZ'
!
` ` 7erdadero ` ` Falso


Q La consulta de InsercIon que se muestra abajo, agrega un nuevo regIstro a la tabla "musIca".
!
INSERT INTO musica (ID, artista, titulo, genero) VALUES (17, 'ALONSO ARMANDO', POESIA,
FUSION)
!
` ` 7erdadero ` ` Falso


S En la consulta de abajo, se elImInan todos los regIstros de la tabla por no IndIcar un crIterIo
de seleccIon medIante la clusula WHERE.
!
DELETE FROM musica
!
` ` 7erdadero ` ` Falso


W La sIguIente consulta cambIa los regIstros del artIsta "ACF 8NEF" por "ACF8NELL" en el
campo "artIsta".
!
UPDATE musica SET artista='AGRI BINER' WHERE artista='AGRI-BINELLI'
!
` ` 7erdadero ` ` Falso


Las respuestas las encontrar al fInal de la sItuacIon profesIonal.

119

Q!>I>!M!AM1hP!
Para programar el sIstema de notIcIas de la sItuacIon profesIonal, deber aplIcar consultas SQL a
la base de datos medIante lenguaje de programacIon PHP.
En la herramIenta 1 aprendIo a crear y admInIstrar una base de datos desde el panel
php|yAdmIn, y en la herramIenta 2 estudIo el lenguaje SQL para generar consultas sImples.
Ahora veremos como realIzar consultas a |ySQL desde pgInas PHP, utIlIzando el lenguaje SQL.
ExIsten gran varIedad de funcIones predefInIdas en PHP que permIten operar dIrectamente con
|ySQL, veremos las ms Importantes y luego usted podr consultar la seccIon de "|ySQL
FunctIons", en la documentacIon ofIcIal de php.net para obtener un lIstado sobre otras
funcIones que puedan serle de utIlIdad.
Todas las funcIones de |ySQL sIempre comIenzan con la palabra "mysql", seguIda de un guIon
abajo y luego la operacIon que realIza en Ingls, por ejemplo, la funcIon necesarIa para
conectarse seria: mysql_connect().

El proceso de comunIcacIon entre PHP y |ySQL, por lo general, suele efectuarse de acuerdo a
los sIguIentes pasos:

a. ConexIon entre PHP y |ySQL.
b. SeleccIon de la base de datos.
c. Consulta.
d. Procesado de datos.
e. LIberacIon de memorIa del servIdor y cIerre de conexIon.

A contInuacIon, se detallan cada uno de ellos.


QJ3!"#)%b'E)!.$!,%+*'K#+!K%!$.!H.,%!
El prImer paso para comenzar una transaccIon con una base de datos desde PHP es conectarse
con ella. UtIlIzaremos la funcIon mysql_connect() de PHP, para establecer el enlace entre
PHP y |ySQL. Su sIntaxIs es la sIguIente:

mysql_connect("servidor", "usuario ", "contrasea");

Los parmetros de esta funcIon son ms que evIdentes, el prImero es el nombre del servIdor en
el que se encuentra alojada la base de datos, por lo general suele encontrarse en el mIsmo
ordenador que el servIdor web por lo tanto, su valor, ser "localhost".
Los dos parmetros sIguIentes corresponden al nombre de usuarIo y contrasea necesarIos para
acceder a la base de datos. Ceneralmente suele proporcIonarlos el proveedor del servIcIo de
hostIng pero a veces pueden ser establecIdos desde un panel de creacIon de bases de datos en el
caso de D<%)-.,!+%,%$$%+,! .


Ayuda ahora
"<%)-.,! +%,%$$%+,! o+%*%)K%K#+%,pG! es un servIcIo de alojamIento que est pensado para grandes
usuarIos o personas que venden el servIcIo de hostIng a otras. Estos paquetes cuentan con gran cantIdad
de espacIo y de domInIos dIsponIbles para cada cuenta.
7eamos un ejemplo:

mysql_connect("localhost", "root", "root");

En el caso de estar trabajando en un puerto concreto, debe especIfIcar el mIsmo:

mysql_connect("localhost:88", "root", "root");


120

Esta funcIon al ser ejecutada devuelve un valor booleano true sI se produjo la conexIon y en
caso contrarIo ser false. Por lo tanto podriamos controlar el proceso de comunIcacIon
medIante algun mecanIsmo que ImpIda la ejecucIon del resto del codIgo en caso de no poder
conectarse a la base de datos:

if (!mysql_connect("localhost", "root", "root")){
die ("no es posible conectarse");
}

Segun el codIgo anterIor, se ejecuta la funcIon mysql_connect() y sI la conexIon no es
posIble, sta funcIon devuelve false. Este valor es InvertIdo por el operador logIco "!" por lo
tanto la estructura recIbe true en su condIcIon y se ejecutan sus InstruccIones.
Fecuerde que la funcIon die() fInalIza la ejecucIon del codIgo PHP de la pgIna y emIte el
mensaje IndIcado en ella. 0Icha funcIon fue especIfIcada en la herramIenta 4 de la sItuacIon
profesIonal 1.
En efecto, sI no es posIble conectarse a la base de datos, de nada servIr el resto del codIgo del
scrIpt de PHP.

Este codIgo puede sImplIfIcarse utIlIzando un operador logIco, como se muestra a contInuacIon:

mysql_connect("localhost", "root", "root") or die ("no es posible conectarse");

Los dos codIgos anterIores son equIvalentes, causando el mIsmo efecto.


QJ2!1%$%DD'E)!K%!$.!H.,%!K%!K.-#,!
Una vez creada la conexIon con el servIdor de datos, debemos especIfIcar la base de datos con la
cual va a operar el scrIpt.
Un servIdor de bases de datos puede contener ms de una base de datos, por lo tanto
utIlIzaremos la funcIon mysql_select_db() para IndIcar el nombre de la base a seleccIonar.
La sIntaxIs es la sIguIente:

mysql_select_db("nombre de la base");

LogIcamente, el parmetro de esta funcIon es el nombre de la base de datos que desea
seleccIonar para operar.
En la herramIenta 1 de la presente sItuacIon profesIonal, creamos una base de datos desde
php|yAdmIn y la llamamos "agenda". 7eamos un ejemplo de seleccIon de ella:

mysql_select_db("agenda");

Esta funcIon, al Igual que mysql_connect(), devuelve un valor booleano true en caso de una
seleccIon exItosa y false en caso contrarIo, por lo cual, podriamos aplIcar la funcIon die():

mysql_select_db("agenda") or dIe (no es posIble seleccIonar la base);

0e esta manera se Interrumpe la ejecucIon del resto del codIgo en el caso de no poder
seleccIonar la base de datos.


QJQ!"#),<$-.,!
HabIendo creado la conexIon con |ySQL y seleccIonado la base de datos, PHP podr realIzar
consultas en lenguaje SQL medIante la funcIon mysql_query(), veamos su sIntaxIs:


121

$resultado=mysql_query("consulta SQL");

Esta funcIon recIbe como parmetro una consulta SQL, tal como las realIzo en la herramIenta
anterIor. El resultado de la consulta ser almacenado en la varIable $resultado. Por ejemplo:

$resultado=mysql_query("DELETE FROM contactos WHERE ID=3");

El valor de $resultado depender del tIpo de consulta. Para consultas del tIpo "accIon" como
INSERT, UPDATE y DELETE, se obtIene un valor booleano true sI se realIzo correctamente y
false sI hubo un error.
En el caso de consultas del tIpo "seleccIon" como SELECT, el valor devuelto ser un false sI
hubo error o un recurso con datos obtenIdos de la consulta. 0Icho recurso permanecer en la
memorIa del servIdor para ser procesado medIante otras funcIones que accedern a los datos de
la consulta.

7eamos un ejemplo completo para consultas de %$'=').D'E):

<?php
mysql_connect("localhost", "root", "root") or die ("no es posible conectarse");
mysql_select_db("agenda") or die ("no es posible seleccionar la base");
$resultado=mysql_query("DELETE FROM contactos WHERE ID=3");
if ($resultado){
echo "Se elimin el registro ID=3";
}else{
echo "ocurri un error al intentar eliminar el registro ID=3";
}
?>

En el ejemplo se efectua la conexIon, luego se seleccIona la base de datos, y en la tercera linea
se realIza la consulta. Por ultImo controlamos sI la consulta se realIza exItosamente y generamos
el mensaje correspondIente.

Este ejemplo por si solo no es del todo dInmIco ya que sIempre que sea petIcIonada esta
pgIna, se tratar de elImInar el mIsmo regIstro.
Para evItar este InconvenIente, podemos hacer que esta pgIna sea ms funcIonal sI el "0" del
regIstro a elImInar se recIbe externamente. Por ejemplo, supongamos que realIzamos un
formularIo HT|L en el que se pueda IntroducIr el "0" del regIstro que desee elImInar y luego
envie ese valor a la pgIna dInmIca. Tendremos dos pgInas para este ejemplo: "elImInar.html"
y "elImInar.php". La prImera ser la que contenga el formularIo como se muestra a
contInuacIon:



Este formularIo envIar sus datos a "elImInar.php" medIante el mtodo PDST.

122

La segunda pgIna "elImInar.php", ser la que procese los datos del formularIo, y tendr el
sIguIente codIgo PHP:

<?php
$ID=$_POST['id'];
mysql_connect("localhost", "root", "root") or die ("no es posible conectarse");
mysql_select_db("agenda") or die ("no es posible seleccionar la base");
$resultado=mysql_query("DELETE FROM contactos WHERE ID=$ID");
if ($resultado){
echo "Se elimin el registro ID=3";
}else{
echo "ocurri un error al intentar eliminar el registro ID=3";
}
?>

Dbserve que solamente se agrego la varIable $ID que recIbe el valor IntroducIdo en el
formularIo, tambIn se reemplazo el valor "J" por la mIsma varIable $ID.
0e esta forma podremos utIlIzar "elImInar.php" para suprImIr cualquIer regIstro de la tabla
"contactos".

7eamos ahora un ejemplo para '),%+-.+ datos:

En este caso tambIn tendremos dos pgInas, "Insertar.html" y "Insertar.php". 7eamos la
prImera:



Fecuerde IdentIfIcar cada campo con los mIsmos nombres que utIlIzar para recuperarlos. Aqui
no utIlIzamos el campo "0" porque se genera automtIcamente.
La pgIna "Insertar.php", que procesar los datos del formularIo, tendr la sIguIente forma:

<?php
$nombre=$_POST['nombre'];
$edad=$_POST['edad'];
$telefono=$_POST['telefono'];
$email=$_POST['email'];

mysql_connect("localhost", "root", "root") or die ("no es posible conectarse");

12J

mysql_select_db("agenda") or die ("no es posible seleccionar la base");
$resultado=mysql_query("INSERT INTO contactos (nombre, edad, telefono, email)
VALUES ('$nombre', $edad, '$telefono', '$email')");
if ($resultado){
echo "Se agreg nuevo registro de $nombre.";
}else{
echo "ocurri un error al intentar agregar a $nombre";
}
?>

Este codIgo dIfIere del prImer ejemplo en su consulta y algunas varIables extras, pero el
funcIonamIento es el mIsmo. Dbserve en la consulta el uso de comIllas sImples para los valores
de tIpo texto.

7eamos ahora un ejemplo de .D-<.$'c.D'E) o modIfIcacIon de regIstros con UPDATE:

Al Igual que en los ejemplos anterIores, tendremos dos pgInas, "modIfIcar.html" y
"modIfIcar.php", vemos la prImera:



Dbserve que es sImIlar a la de "Insertar.html" pero esta vez se agrega el campo "0", ya que se
debe IndIcar, para este caso, el 0 del regIstro que se va a modIfIcar. 7eamos el codIgo de
"modIfIcar.php":

<?php
$ID=$_POST['ID'];
$nombre=$_POST['nombre'];
$edad=$_POST['edad'];
$telefono=$_POST['telefono'];
$email=$_POST['email'];

mysql_connect("localhost", "root", "root") or die ("no es posible conectarse");
mysql_select_db("agenda") or die ("no es posible seleccionar la base");
$resultado=mysql_query("UPDATE contactos SET nombre='$nombre', edad=$edad,
telefono='$telefono', email='$email' WHERE ID=$ID");
if ($resultado){

124

echo "Se actualiz el registro $ID.";
}else{
echo "ocurri un error al intentar modificar el registro $ID";
}
?>

Como puede aprecIar, los tres ejemplos anterIores son sImIlares y trabajan de la mIsma forma
pero varIando los datos a tratar y las consultas. Dbserve que se repIten sIempre las lineas de
codIgo para la conexIon y seleccIon de la base de datos. SI cambIara algun valor como por
ejemplo la contrasea o el nombre de la base de datos, tendria que modIfIcar todas las pgInas
PHP en las que se encuentran las conexIones o seleccIones de la base de datos.
Para evItar este InconvenIente es recomendable realIzar la conexIon y seleccIon de base de
datos medIante el uso de lIbrerias, estudIadas en la herramIenta 4 de la sItuacIon profesIonal 1.
Por ejemplo, creamos la pgIna "conexIon.php" con el codIgo sIguIente:

<?php
mysql_connect("localhost", "root", "root") or die ("no es posible conectarse");
mysql_select_db("agenda") or die ("no es posible seleccionar la base");
?>

Luego cambIamos estas lineas en las dems pgInas por require("conexion.php");
7eamos como quedaria en el ultImo ejemplo:

<?php
$ID=$_POST['ID'];
$nombre=$_POST['nombre'];
$edad=$_POST['edad'];
$telefono=$_POST['telefono'];
$email=$_POST['email'];

require("conexion.php");

$resultado=mysql_query("UPDATE contactos SET nombre='$nombre', edad=$edad,
telefono='$telefono', email='$email' WHERE ID=$ID");
if ($resultado){
echo "Se actualiz el registro $ID.";
}else{
echo "ocurri un error al intentar modificar el registro $ID";
}
?>

SI realIza este cambIo en todas las pgInas que requIeran una conexIon y seleccIon de base de
datos, podr sImplIfIcar el codIgo, y no tendr que edItar cada una de ellas cuando cambIe algun
valor de conexIon o el nombre de la base de datos. Solo se lImItar a edItar la "conexIon.php".

A contInuacIon, veremos un ejemplo con el comando SELECT:

<?php
require("conexion.php");
$resultado=mysql_query("SELECT * FROM contactos");
if ($resultado){
echo "ocurri un error.";
}else{
//procesa datos
}
?>


125

En el ejemplo mostrado, se realIza una consulta de todos los regIstros de la tabla "contactos" y
sI ocurre algun error $resultado ser false, en caso contrarIo no devuelve true! sIno que se
obtIene una tabla en memorIa con datos que podr procesar medIante las funcIones de
procesado que veremos a contInuacIon.


QJS!>+#D%,.K#!K%!K.-#,!
Una vez efectuada la consulta de seleccIon, podr procesar el resultado para generar la pgIna
HT|L resultante que se envIar al navegador del ordenador clIente.
El resultado de una consulta SELECT queda en la memorIa del servIdor a la espera de su
tratamIento. La InformacIon que se obtIene, por lo general, toma la forma de una tabla.
PHP ofrece varIas funcIones para procesar los datos obtenIdos de una consulta. En el presente
texto estudIaremos las ms Importantes y usted podr experImentar con las restantes sIn
mayores dIfIcultades.

Para obtener los regIstros del resultado de una consulta, utIlIzaremos la funcIon
mysql_fetch_array(). Esta funcIon genera una matrIz o array asocIatIvo sobre el resultado.
Su sIntaxIs es la sIguIente:

$registros=mysql_fetch_array($resultado);

El parmetro recIbIdo corresponde al resultado de la consulta. La varIable $registros tendr
el valor booleano false en caso de no exIstIr los regIstros consultados. SI exIsten regIstros, ser
del tIpo array, una matrIz asocIatIva como las estudIadas en la herramIenta 4 de la sItuacIon
profesIonal 1, que contIene los campos del prImer regIstro encontrado en la consulta.
Los arrays asocIatIvos permIten acceder a sus valores medIante claves, que en este caso
corresponden a los nombres de los campos seleccIonados en la consulta.
7eamos un ejemplo para aclarar esto:

<?php
require("conexion.php");
$resultado=mysql_query("SELECT * FROM contactos");
if (!$resultado){
echo "ocurri un error.";
}else{
$registro=mysql_fetch_array($resultado);
echo $registro['nombre']."<br/>";
}
?>

En el ejemplo, $registro es un array que contIene los valores de los campos del prImer
regIstro encontrado, dIchos valores pueden obtenerse medIante el nombre del campo asocIado,
tal como se hace en la ante ultIma linea de codIgo.
0e esta manera se ImprIme en pantalla el nombre del prImer regIstro encontrado en la consulta.
El sIguIente codIgo ImprIme todos los campos del prImer regIstro:

<?php
require("conexion.php");
$resultado=mysql_query("SELECT * FROM contactos");
if (!$resultado){
echo "ocurri un error.";
}else{
$registro=mysql_fetch_array($resultado);
echo $registro['ID']."<br/>";
echo $registro['nombre']."<br/>";
echo $registro['edad']."<br/>";
extrae
r

126

echo $registro['telefono']."<br/>";
echo $registro['email']."<br/>";
}
?>

Solo podr operar con los campos seleccIonados en la consulta SELECT, en este caso se utIlIzo el
comodin * para seleccIonar todos los campos.

Seguramente se preguntar qu ocurre con los dems regIstros, ya que la consulta debe obtener
todos los regIstros de la tabla y en el ejemplo anterIor mostramos solamente el prImero. Para
ello, debemos aplIcar un bucle que recorra el $resultado y asIgne los campos de cada regIstro
de uno en uno a la matrIz $registro:

<?php
require("conexion.php");
$resultado=mysql_query("SELECT * FROM contactos");
if (!$resultado){
echo "ocurri un error.";
}else{
while($registro=mysql_fetch_array($resultado)){
echo $registro['nombre']."<br/>";
}
}
?>

El bucle while asIgna uno a uno los valores de mysql_fetch_array() a $registro. Las
accIones de while obtIenen el campo "nombre" del regIstro actual y se repetIrn hasta que
fInalIce el recorrIdo de mysql_fetch_array().
En defInItIva, el array $registro va tomando dIferentes valores en cada repetIcIon y a su vez,
se da salIda a esos valores dentro del bucle.

El sIguIente ejemplo, sImIlar al anterIor, muestra todos los campos y los regIstros de la consulta,
de manera ordenada en una tabla HT|L:

<?php
require("conexion.php");
$resultado=mysql_query("SELECT * FROM contactos");
if (!$resultado){
echo "ocurri un error.";
}else{
echo '<table border="1" cellpadding="6" cellspacing="0">';
while($registro=mysql_fetch_array($resultado)){
echo "<tr>
<td>$registro[ID]</td>
<td>$registro[nombre]</td>
<td>$registro[edad]</td>
<td>$registro[telefono]</td>
<td>$registro[email]</td>
</tr>";
}
echo '</table>';
}
?>

Dbserve que al colocar la matrIz $registro dentro de la cadena de texto, debe quItar las
comIllas de las claves ya que no son necesarIas por encontrarse dentro de una cadena. Esto evIta
tener que concatenar $registro, cada vez que se obtenga el valor de una clave.
?

127


Dtras funcIones de utIlIdad son mysql_num_rows() y mysql_num_fields() para obtener la
cantIdad de regIstros y campos de una consulta. 7emos un ejemplo:

$cant_reg=mysql_num_rows($resultado);
$cant_camp=mysql_num_fields($resultado);

echo "se encontraron $cant_reg de registros<br/>";
echo "hay $cant_camp campos";

7eamos otro ejemplo ms prctIco que el anterIor:

<?php
$ID=$_POST['ID'];
$nombre=$_POST['nombre'];
$edad=$_POST['edad'];
$telefono=$_POST['telefono'];
$email=$_POST['email'];
require("conexion.php");

$resultado=mysql_query("SELECT * FROM contactos WHERE ID=$ID");

if (!$resultado){
echo "ocurri un error.";
}else{
$cant_reg=mysql_num_rows($resultado);
if ($cant_reg>0){
$resultado=mysql_query("UPDATE contactos SET nombre='$nombre',
edad=$edad, telefono='$telefono', email='$email' WHERE ID=$ID");
if ($resultado){
echo "Se actualiz el registro $ID.";
}else{
echo "ocurri un error al intentar modificar el registro
$ID";
}else{
echo 'El ID $ID no existe.';
}
}
?>

En este caso se realIza una consulta para comprobar la exIstencIa del regIstro que se desea
actualIzar y asi evItamos que el servIdor muestre un mensaje de error al realIzar la consulta de
actualIzacIon de un regIstro InexIstente.


QJW!P'H%+.D'E)!K%!=%=#+'.!M!D'%++%!K%!D#)%b'E)!
Los datos de cada consulta se guardan en la memorIa del servIdor hasta que fInalIza la ejecucIon
del codIgo de la pgIna, pero puede ocurrIr que se trabaje muy seguIdo con el comando SELECT
en una mIsma pgIna PHP y sI los resultados son de gran amplItud, es recomendable Ir lIberando
la memorIa a medIda que deje de usarse cada consulta del scrIpt PHP.
Para lIberar la memorIa del servIdor utIlIzamos la funcIon mysql_free_result() como se
muestra en el sIguIente ejemplo:

mysql_free_result($resultado);

Esta funcIon debe escrIbIrse despus de procesar $resultado, ya que, de lo contrarIo estaria
elImInando los resultados de la consulta y no podr procesarlos.


128

Dtra buena prctIca es cerrar la conexIon con |ySQL cuando no haga falta realIzar otra consulta,
aunque la mIsma se cerrar automtIcamente al fInalIzar la ejecucIon del scrIpt de PHP. Para
ello empleamos la funcIon mysql_close() como se muestra en el ejemplo de abajo:

<?php
require("conexion.php");
$resultado=mysql_query("SELECT * FROM contactos");
if (!$resultado){
echo "ocurri un error.";
}else{
echo '<table border="1" cellpadding="6" cellspacing="0">';
while($registro=mysql_fetch_array($resultado)){
echo "<tr>
<td>$registro[ID]</td>
<td>$registro[nombre]</td>
<td>$registro[edad]</td>
<td>$registro[telefono]</td>
<td>$registro[email]</td>
</tr>";
}
echo '</table>';
}
mysql_free_result($resultado);
mysql_close();
?>



129

@<-#%*.$<.D'E)!Q!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!


3 El codIgo de abajo conecta a PHP con la base de datos "productos".

mysql_select_db("productos");
mysql_connect("localhost", "root", "root");
!
` ` 7erdadero ` ` Falso


2 El sIguIente codIgo muestra un lIstado de productos de la tabla "hardware".
!
<?php
require("conexion.php");
$sql=mysql_query("SELECT * FROM hardware");
if (!$sql){
echo "ocurri un error.";
}else{
echo '<table border="1" cellpadding="6" cellspacing="0">';
while($registro=mysql_fetch_array($resultado)){
echo "<tr>
<td>$registro['descripcion']</td>
<td>$registro['precio']</td>
</tr>";
}
echo '</table>';
}
?>
!
` ` 7erdadero ` ` Falso


Q En el codIgo de abajo se recIben datos de un formularIo, que luego son Insertados a la tabla
"clIentes".
!
<?php
$nombre=$_POST['nombre'];
$email=$_POST['email'];
require("conexion.php");
$resultado=mysql_query("INSERT INTO clientes (nombre, email) VALUES ('$nombre',
'$email')");
if (!$resultado){
echo "Se agreg nuevo registro de $nombre.";
}else{
echo "ocurri un error al intentar agregar a $nombre";
}
?>
!
` ` 7erdadero ` ` Falso


S El codIgo de abajo muestra los nombres y emaIls de los clIentes.
!
!

1J0

<?php
require("conexion.php");
$sql=mysql_query("SELECT * FROM clientes");
echo '<table border="1" cellpadding="6" cellspacing="0">';
while($reg=mysql_fetch_array($sql)){
echo "<tr>
<td>$reg[nombre]</td>
<td>$reg[email]</td>
</tr>";
}
echo '</table>';
?>
!
` ` 7erdadero ` ` Falso


W El sIguIente codIgo muestra los nombres y emaIls de los clIentes, luego cIerra la conexIon
lIberando la memorIa.
!
<?php
require("conexion.php");
$sql=mysql_query("SELECT * FROM clientes");
echo '<table border="1" cellpadding="6" cellspacing="0">';
while($reg=mysql_fetch_array($sql)){
echo "<tr>
<td>$reg[nombre]</td>
<td>$reg[email]</td>
</tr>";
}
echo '</table>';
mysql_close();
mysql_free_result($sql);
?>
!
` ` 7erdadero ` ` Falso




Las respuestas las encontrar al fInal de la sItuacIon profesIonal.

1J1

0Y%+D'D'#!8%,<%$-#
En la presente sItuacIon profesIonal, ECD SDFT, empresa dedIcada al desarrollo de software
contable para PY|ES, posee un sItIo web para la muestra y descarga de su producto y le solIcIta
que realIce un sIstema de notIcIas.


FIgura 1: pgIna de InIcIo.


FIgura 2: pgIna de notIcIa extendIda.

La fIgura de al lado
pertenece al dIseo de la
Interfaz de la pgIna de
InIcIo del sItIo. En la
columna de la derecha, se
encuentra marcado el
espacIo para el sIstema de
notIcIas que debe crear.
Una vez programado el
sIstema, se IncluIr en la
pgIna de InIcIo medIante la
funcIon include().
Dbserve que cada novedad,
est compuesta por un
titulo, la fecha de
publIcacIon, un resumen del
Informe y el enlace "Leer
ms.".

Cuando el usuarIo pulse
sobre el enlace "Leer
ms.", de una notIcIa, se
mostrar el texto completo
dentro del mIsmo dIseo de
la Interfaz.
En la fIgura 2 se muestra la
notIcIa extendIda.
TambIn, debe programar el admInIstrador que permIta agregar, modIfIcar y elImInar las
notIcIas.

Conforme a lo anterIor, determInamos los archIvos que hay que crear para el funcIonamIento del
sIstema.
En la fIgura J, se muestran los archIvos que se agregarn a los ya exIstentes en la raiz del sItIo.
En la pgIna de InIcIo del sItIo (no mostrada en esta carpeta) se IncluIr "notIcIas.php", que
contIene el codIgo para mostrar las notIcIas.

1J2

La pgIna "leer_mas.php" es la que muestra la notIcIa completa, seleccIonada por el usuarIo
desde el enlace "Leer ms." de la pgIna "notIcIas.php".


FIgura J: Faiz del sItIo.

En la fIgura 4 vemos la carpeta "admIn", donde colocaremos todas las pgInas necesarIas para la
admInIstracIon de las novedades:


FIgura 4: Carpeta "admIn".

El archIvo "admIn.php" es la pgIna prIncIpal de admInIstracIon de notIcIas, y en ella se podrn
vIsualIzar todas las novedades y los enlaces necesarIos para admInIstrarlas.
Las pgInas "agregar.php", "edItar.php" y "elImInar.php", son las que permItIrn realIzar las
operacIones de admInIstracIon.
Para sImplIfIcar la escrItura del codIgo de cada pgIna, IncluIremos en ellas la confIguracIon de
conexIon al servIdor de base de datos, medIante el archIvo "conexIon.php".

Ya tenemos resuelta la estructura de dIrectorIos de la aplIcacIon, ahora debe crear la base de
datos desde php|yAdmIn.
Cree una nueva base de datos llamada "bd_notIcIas" y en ella, una tabla con 5 campos, llamada
"notIcIas", como se muestra en la fIgura 5.

FIgura 5: Tabla "notIcIas" de la base "bd_notIcIas".

El campo "Id" debe ser auto Incrementable y clave unIca.

El codIgo de la pgIna "D#)%b'#)JTVT" contIene las funcIones necesarIas para establecer y
comprobar la conexIon y seleccIon de la base "bd_notIcIas".


1JJ


CodIgo de admIn/conexIon.php (1/1)

Ya podemos comenzar a programar la pgIna ".K=')JTVT", cuya forma en el navegador clIente
es sImIlar a la de la fIgura de abajo:


PgIna admIn/admIn.php

Dbserve que aparecen todas las notIcIas y en cada una de ellas, los enlaces para leer ms, edItar
y elImInar. Al pIe de la pgIna se ubIca el enlace para Ir al formularIo de InsercIon de notIcIas.
7eamos el codIgo de "admIn.php":


1J4


CodIgo de admIn/admIn.php (1/1)

En la linea 9 se Incluye la conexIon creada anterIormente.
La varIable $resultado es la consulta de las notIcIas que hay en la base de datos, ordenadas
por Id. Cuando se agregan las notIcIas, cada una tendr un numero de "Id", el cual IndIcaria el
orden en fueron Insertadas. 0e esta forma se pueden representar ordenadas por antIguedad,
desde la ultIma hasta la prImera que se aadIo.
El bucle while de la linea 11, escrIbe el codIgo HT|L con las notIcIas encontradas en la consulta
anterIor. ste recorre el array $campos hasta el ultImo indIce. Estos indIces y sus valores se
cargan en la funcIon mysql_fetch_array() aplIcada a los resultados de la consulta anterIor.
En la linea 12, PHP, da salIda al titulo, en la 1J la fecha y en la 15 el resumen de la notIcIa.
En la linea 16 a 18, se escrIben los enlaces para admInIstrar la notIcIa en cuestIon. Cada enlace
envia por UFL la varIable id con su valor, el cual ser utIlIzado para ejecutar las operacIones
que correspondan por las pgInas "leer_mas.php", "edItar.php" y "elImInar.php".
Fecuerde que la pgIna "leer_mas.php" se encuentra en la raiz del sItIo, es por eso que se
agrega "../" al prIncIpIo del mIsmo, para IndIcar al servIdor que dIcha pgIna est a un nIvel
relatIvamente superIor respecto al dIrectorIo actual.
En la linea 22 est el enlace a la pgIna "agregar.php", para Insertar nuevas notIcIas.

La pgIna ".&+%&.+JTVT" tendr J campos: tItulo, resumen y texto. Su forma es la sIguIente:


1J5


PgIna admIn/agregar.php

Antes de analIzar el codIgo de esta pgIna, cabe aclarar que el procesado de los datos lo har
ella mIsma, por lo tanto se debe comprobar el envio del formularIo.
El codIgo PHP de "agregar.php", lo analIzamos a contInuacIon:


CodIgo de admIn/agregar.php (1/2)

En la linea 9 IncluImos la conexIon y en la 10 se comprueba el envio del formularIo.
SI el formularIo no ha sIdo envIado, se mostrar, de lo contrarIo se ejecuta la consulta de
InsercIon. Esta decIsIon la toma el if de la linea 10, que recIbe un valor booleano. 0Icho valor
se obtIene de InvertIr el resultado de la funcIon isset(). Esta funcIon verIfIca sI la varIable del
formularIo submit est declarada. La varIable submit se envia al ser presIonado el boton
"Agregar notIcIa" del formularIo, observe que el valor del atrIbuto name de la etIqueta Input en
la linea 20, es submit.
En resumen, sI el formularIo es vIsualIzado por prImera vez, no exIste la varIable submit, por lo
tanto, en la linea 10, la funcIon isset() devuelve false. Este valor, es InvertIdo por el
operador "!" y el if leer un true, ejecutando el codIgo que est entre las lineas 11 y 22.

1J6

SI por el contrarIo, el formularIo, ha sIdo completado y envIado, entonces la funcIon isset()
encuentra declarada la varIable submit, devolvIendo true. Este valor de true se InvIerte con
el operador "!" y se obtIene un false para el if. Consecuentemente no se procesa el codIgo
entre las lineas 11 y 22, y al exIstIr un else en la linea 2J, se procesar el codIgo entre las
lineas 24 y JJ.

En la linea 1J, el valor del atrIbuto action de la etIqueta form, se obtIene automtIcamente
del resultado de la varIable predefInIda $_SERVER['PHP_SELF'], que devuelve la UFL de la
pgIna en cuestIon.

ContInuando con la sIguIente porcIon de codIgo de "agregar.php", vemos que ocurre al ser
envIados los datos del formularIo:


CodIgo de admIn/agregar.php (2/2)

Entre las lineas 24 y 26, se recIben los datos, en 27 se genera la consulta y se asIgna el resultado
a $resultado.
El resultado de la InsercIon ser controlado por el if de la linea 28, sI fue correcta se mostrar
un mensaje IndIcando el xIto de la operacIon durante 4 segundos y luego se redIrIge al usuarIo a
la pgIna de admInIstracIon. 0e lo contrarIo, se muestra un mensaje de error.

7eamos la pgIna "%K'-.+JTVT":

PgIna admIn/edItar.php

1J7


Esta pgIna tendr J campos, al Igual que la anterIor. Dbserve que aparecen los campos
rellenados. Estos datos se obtIenen de una consulta prevIa a la base de datos.
Fecuerde que en la pgIna "admIn.php, precIsamente en la linea 16, se escrIbe el enlace a esta
pgIna y se agrega la varIable id con su valor. Esta varIable ser utIlIzada para generar la
consulta que permIta mostrar los campos del formularIo rellenados con los valores actuales de la
notIcIa.

AnalIcemos la prImera porcIon de codIgo de la mIsma:


CodIgo de admIn/edItar.php (1/J)

El if de la linea 2 verIfIca el resultado de la funcIon empty() que analIza sI exIste valor para la
varIable id. SI exIste valor para ella, se procesa el codIgo PHP de la pgIna.
En caso de no exIstIr el id o su valor, if recIbe un true y se redIrIge a la pgIna "admIn.php".
LogIcamente, sIn el valor de id, no se podria determInar cul es la notIcIa que se desea edItar.

ContInuamos con el resto del codIgo:


CodIgo de admIn/edItar.php (2/J)

En la linea 14 se Incluye la conexIon a la base de datos y en la 15 se recIbe el valor de id.
En la linea 16, tenemos una estructura de decIsIon sImIlar a la de la linea 10 de la pgIna
"agregar.php". SI el formularIo aparece por prImera vez, no exIste la varIable submit, por lo
tanto, se muestra (lineas 17 a J1). Y sI el formularIo se completo y fue envIado por el usuarIo,
entonces se actualIzan los datos de la notIcIa (lineas JJ a 42).

1J8

En la linea 17, se genera la consulta a la base de datos, fIltrando los resultados de acuerdo al
valor del id recIbIdo. El resultado de esta consulta se asIgna a $resultado.
La varIable $campos es una matrIz asocIatIva del resultado de la consulta, la utIlIzaremos para
recuperar los valores de cada campo de la notIcIa.
Entre las lineas 21 a J0, se encuentra el formularIo, cuyo atrIbuto action se recupera de la
concatenacIon de dos varIables predefInIdas del servIdor y corresponde a la UFL de la pgIna
actual y la varIable id con su valor. TambIn podriamos haber escrIto lo sIguIente:
action=editar.php?id="<?=$id?>"

En las lineas 2J, 25 y 27, se rellenan los contenIdos de los campos con los valores
correspondIentes al id, recIbIdos de la consulta a la base de datos.

Ahora vemos que ocurre sI se envia el formularIo:


CodIgo de admIn/edItar.php (J/J)

PrImero se recIben las varIables del formularIo entre las lineas JJ y J5. Luego se genera la
consulta de actualIzacIon con los datos recIbIdos. Fecuerde fIltrar la consulta utIlIzando el id
recIbIdo en la linea 15 para que no se actualIcen todos los regIstros juntos. El resultado de la
consulta se asIgna a $resultado.
En la linea J7, se controla el valor de $resultado y a partIr del mIsmo, el if toma la decIsIon
que corresponda. En caso de ser exItosa la consulta, se muestra un mensaje de confIrmacIon
durante 4 segundos y luego se redIrIge a "admIn.php". SI ocurre algun error durante la consulta,
se muestra el mensaje de error.

Ya tenemos "conexIon.php", "admIn.php", "agregar.php" y "edItar.php". ContInuamos con la
pgIna "%$'=').+JTVT":


1J9


CodIgo de admIn/elImInar.php (1/1)

Fecuerde que en la pgIna "admIn.php", precIsamente en la linea 18, se escrIbe el enlace a esta
pgIna y se agrega la varIable id con su valor. Esta varIable ser utIlIzada para generar la
consulta que permIta elImInar el regIstro que coIncIda con ella.

El if de la linea 2 verIfIca el resultado de la funcIon empty() que analIza sI exIste valor para la
varIable id. SI exIste valor para ella, se procesa el codIgo PHP de la pgIna.
En caso de no exIstIr el id o su valor, if recIbe un true y se redIrIge a la pgIna "admIn.php".
LogIcamente, sIn el valor de id, no se podria determInar cul es la notIcIa que se desea
elImInar, corrIendo el rIesgo de elImInar todos los regIstros de la base de datos.

En la linea 14, se Incluye la conexIon. Luego se declara $id y se asIgna el valor recIbIdo.
La consulta de la linea 16, elImIna la notIcIa cuyo id coIncIda con el que se recIba por UFL.
El resultado de la consulta se asIgna a $resultado y es controlado por la estructura que
comIenza en la linea 17. En caso de ser exItosa la consulta, se muestra un mensaje de
confIrmacIon durante 4 segundos y luego se redIrIge a "admIn.php". SI ocurre algun error
durante la consulta, se muestra el mensaje de la linea 21.

Hasta aqui tenemos todas las pgInas de la carpeta "admIn", ahora comenzamos con las pgInas
de la raiz. 7emos el codIgo de ")#-'D'.,JTVT":


CodIgo de notIcIas.php (1/1)

140


Esta pgIna ser IncluIda (include "noticias.php";) dentro de la de InIcIo del sItIo actual,
es por eso que no presenta una estructura vlIda de HT|L, ya que la estructura ser completada
por la pgIna mIsma que la Incluya.

En la linea 2, se Incluye la conexIon, esta vez cambIa la ruta, ya que la pgIna "conexIon.php",
la habiamos creado dentro de la carpeta "admIn".
La varIable $resultado de la linea J, guarda el resultado de la consulta de seleccIon que se
realIza. Los resultados son ordenados por id en modo descendente.

El bucle while de la linea 4 a 10, escrIbe el codIgo HT|L que muestra los resultados de la
consulta. Cada notIcIa tendr un enlace para dIrIgIrse a "leer_mas.php", en donde se amplIar
la InformacIon de la mIsma. La UFL de cada enlace, contIene la varIable id, necesarIa para que
el codIgo de "leer_mas.php" pueda buscar la notIcIa que el usuarIo desee amplIar.

En la fIgura de abajo se muestra el codIgo de "leer_mas.php":


CodIgo completo de leer_mas.php

Dbserve que el codIgo PHP est marcado con en el rectngulo, el resto corresponde al HT|L del
dIseo de la pgIna que actualmente se encuentra en el servIdor de la empresa. La forma de
esta pgIna seria como la de la fIgura 2, mostrada al comIenzo del ejercIcIo resuelto.
Ahora analIzamos el codIgo PHP de esta pgIna:


141


CodIgo parcIal de leer_mas.php

En la linea J6, se Incluye la conexIon, al Igual que en "notIcIas.php", cambIa la ruta, ya que la
pgIna "conexIon.php", la habiamos creado dentro de la carpeta "admIn".
En la linea J7, se recIbe el id de la notIcIa seleccIonada por el usuarIo. Fecuerde que este valor
se crea en la linea 9 de "notIcIas.php".
La varIable $resultado de la linea J8, guarda el resultado de la consulta de seleccIon que se
realIza. Los resultados son fIltrados por el correspondIente valor de id, de esta manera se
obtIene un unIco regIstro.

En la linea J9, se crea $campos, una matrIz asocIatIva con los datos de la consulta. Esta matrIz
es utIlIzada para mostrar los campos del regIstro consultado en las lineas 40 a 4J.


142

0Y%+D'D'#!T#+!+%,#$*%+!

La empresa SEFWE8 de la sItuacIon profesIonal 1, proveedora de servIcIos de hostIng, ha tenIdo
un gran crecImIento en el ultImo tIempo y le pIde que haga los sIguIentes cambIos en el sIstema
de contratacIones de servIcIos:

- Cuando los usuarIos contraten un servIcIo, debe almacenar los datos del formularIo en
una base de datos y envIar un mensaje de correo al admInIstrador de ventas, con el
nombre de la persona que realIza la contratacIon, el plan contratado, la forma y medIo
de pago.
- 0ebe IncluIr en el mensaje, un enlace dIrecto a una pgIna llamada "mostrar.php", que
exponga los datos completos del usuarIo que solIcIta el servIcIo. 0Ichos datos sern
consultados a la base de datos.
- Cree una pgIna de admInIstracIon, llamada "admIn.php", que consulte todos los usuarIos
que contrataron el servIcIo, mostrando el nombre de la persona que contrata el servIcIo,
el plan contratado, la forma y medIo de pago. En cada regIstro mostrado, agregue un
enlace que se dIrIja a la pgIna "mostrar.php", que exponga los datos completos del
usuarIo que solIcIto el servIcIo.
- Agregue tambIn, en "admIn.php", enlaces en cada regIstro que se dIrIjan a formularIos
que permItan edItarlo o elImInarlo.
- Cree una pgIna llamada "agregar.php", para dar de alta a nuevos usuarIos. Coloque el
enlace de dIcha pgIna, en "admIn.php".

Este ejercIcIo deber ser resuelto y envIado a su autor cuando ste se lo IndIque.


14J

8%,T<%,-.,!.!$.,!.D-'*'K.K%,!K%!.<-#%*.$<.D'E)!
!
@<-#%*.$<.D'E)!3!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!

3 Una base de datos |ySQL puede contener una o ms tablas, cada tabla contIene regIstros y
cada regIstro est constItuIdo por campos. A su vez, cada campo contIene valores que deben
corresponder con el tIpo de dato asIgnado a dIcho campo.
!
! 7erdadero ` ` Falso


2 php|yAdmIn es un servIdor de base de datos relacIonales que permIte crear base de datos y
tablas, Insertar datos, modIfIcarlos, elImInarlos, ordenarlos, hacer consultas, busquedas y
muchas otras operacIones para admInIstrar bases de datos.
!
` ` 7erdadero ! Falso

phpMyAdmn no es unc bcse de dctos, es un sstemc proyrcmcdo en PHP que ]ccltc lc
cdmnstrccon de MySQL.


Q Un campo confIgurado como clave prImarIa del tIpo numrIco entero (NT) y auto
Incrementable (auto_Increment), ser un IdentIfIcador unIco de cada regIstro que Ingrese a una
tabla y su valor no podr ser modIfIcado.
!
! 7erdadero ` ` Falso


S Un archIvo con extensIon ".sql" es una base de datos exportada desde el panel de
admInIstracIon php|yAdmIn.
!
` ` 7erdadero ! Falso

0n crchvo con extencon ".sql" es un crchvo de texto que contene nstruccones SQL pcrc
completcr unc bcse de dctos.


W Para especIfIcar la longItud de un campo del tIpo FLDAT con un entero y tres decImales
escrIbIr "1,J" en la propIedad "logItud" del panel de pnp|yAdmIn.
!
` ` 7erdadero ! Falso

En el ccso de FLDAT y 0D08LE, estc propedcd debe ndccrse con el ]ormcto (M,0) en donde M
es lc lonytud totcl y 0 es lc ccntdcd de decmcles. Pcrc el e]emplo, lc respuestc correctc
serc: "4,J".

144

@<-#%*.$<.D'E)!2!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#L!-%)'%)K#!%)!D<%)-.!$.!,'&<'%)-%!-.H$.!K%!K.-#,G!
!
7.H$.!d=<,'D.e!
0 artIsta tItulo genero
1 ACF8NELL D8FAS PAFA 7DLN, 8AN0DNEDN Y DFQUESTA TANCD
2 ACF8NELL |E|DFA Y TANCD TANCD
J ACUFFE SAN0FA S FDLKLDFE
4 ACUFFE SAN0FA EL HD|8FE 0E 8AFFD FDLKLDFE
5 ALCHDUFFDN FD0DLFD PAFA8DLA JAZZ
6 ALDNSD AF|AN0D 0E| FUSDN
7 AN0EFS JDFCE L7E N 8UENDS AFES 199J JAZZ
8 AFTSTAS 7AFDS CU8A CDN 7DZ 0E |UJEF 7AFDS
9 AFTSTAS 7AFDS LD |EJDF 0EL JAZZ AFCENTND JAZZ
10 8HAFES FAPSD00YA ALCD ESTA CA|8AN0D... 7AFDS
11 |DNTDLU TETE 8FASL CLASCDS JAZZ
12 |DNTDLU TETE EN 77D EN EL SAN JUAN JAZZ
1J |DFENTE ENFQUE 7DZ E AL|A 0EL FLA|ENCD FLA|ENCD
14 |DFCA0D ESTE8AN EL SUEND 0EL 0UEN0E FUSDN
15 |USCA SECFETA |USCA 0E LAS |SDNES 0E CHQUTDS 7AFDS
16 |USCA SECFETA |USCA 0E 0DS |UN0DS 7AFDS

3 La sIguIente consulta permIte obtener el artIsta, tItulo y genero del regIstro cuyo 0 sea 1.

SELECT artista FROM musica WHERE ID=1
!
` ` 7erdadero ! Falso

Solcmente podrc obtener los ccmpos selecconcdos, ndccdos delcnte de SELECT. Pcrc el
e]emplo, obtendrc el ccmpo "crtstc" con l0=1.


2 La sIguIente consulta muestra todos los titulos de los gneros "tango" o "jazz".
!
SELECT titulo FROM musica WHERE genero='TANGO' OR genero='JAZZ'
!
! 7erdadero ` ` Falso


Q La consulta de InsercIon que se muestra abajo, agrega un nuevo regIstro a la tabla "musIca".
!
INSERT INTO musica (ID, artista, titulo, genero) VALUES (17, 'ALONSO ARMANDO',
POESIA, FUSION)
!
` ` 7erdadero ! Falso

S el ccmpo l0 es cuto ncrementcble y de clcve prmcrc, no debe nsertcrlo yc que MySQL se
enccrycrc de dcrle el vclor que correspondc.
Los ccmpos "ttulo" y "yenero" son del tpo texto por lo tcnto debe coloccr los vclores de los
msmos entre comllcs. El codyo correcto serc:

INSERT INTO musica (artista, titulo, genero) VALUES ('ALONSO ARMANDO', 'POESIA',
'FUSION')



145

S En la consulta de abajo, se elImInan todos los regIstros de la tabla por no IndIcar un crIterIo
de seleccIon medIante la clusula WHEFE.
!
DELETE FROM musica
!
! 7erdadero ` ` Falso


W La sIguIente consulta cambIa los regIstros del artIsta "ACF 8NEF" por "ACF8NELL" en el
campo "artIsta".
!
UPDATE musica SET artista='AGRI BINER' WHERE artista='AGRI-BINELLI'
!
` ` 7erdadero ! Falso

Lc consultc de crrbc ccmbc los reystros del crtstc "A6Rl8lNELLl" por "A6Rl 8lNER" en el
ccmpo "crtstc".

146

@<-#%*.$<.D'E)!Q!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!


3 El codIgo de abajo conecta a PHP con la base de datos "productos".

mysql_select_db("productos");
mysql_connect("localhost", "root", "root");
!
` ` 7erdadero ! Falso

Pcrc conectcrse c lc bcse de dctos "productos", prmero de reclzcr lc conexon con el servdor
y lueyo lc seleccon de lc bcse de dctos, como se muestrc cbc]o:

mysql_connect("localhost", "root", "root");
mysql_select_db("productos");


2 El sIguIente codIgo muestra un lIstado de productos de la tabla "hardware".
!
<?php
require("conexion.php");
$sql=mysql_query("SELECT * FROM hardware");
if ($sql){
echo "ocurri un error.";
}else{
echo '<table border="1" cellpadding="6" cellspacing="0">';
while($registro=mysql_fetch_array($resultado)){
echo "<tr>
<td>$registro['descripcion']</td>
<td>$registro['precio']</td>
</tr>";
}
echo '</table>';
}
?>
!
` ` 7erdadero ! Falso

Lc ]uncon mysql_fetch_array() estc recbendo un pcrcmetro nexstente, debe ndccr en
ellc el pcrcmetro correcto que serc lc consultc reclzcdc: $sql.
Lcs comllcs de lcs clcves csocctvcs de lc mctrz $reystros no son necescrcs porque yc se
encuentrcn dentro de unc ccdenc de texto. El codyo correcto serc:

<?php
require("conexion.php");
$sql=mysql_query("SELECT * FROM hardware");
if ($sql){
echo "ocurri un error.";
}else{
echo '<table border="1" cellpadding="6" cellspacing="0">';
while($registro=mysql_fetch_array($sql)){
echo "<tr>
<td>$registro[descripcion]</td>
<td>$registro[precio]</td>
</tr>";
}
echo '</table>';
}
?>


147

Q En el codIgo de abajo se recIben datos de un formularIo, que luego son Insertados a la tabla
"clIentes".
!
<?php
$nombre=$_POST['nombre'];
$email=$_POST['email'];
require("conexion.php");
$resultado=mysql_query("INSERT INTO clientes (nombre, email) VALUES ('$nombre',
'$email')");
if ($resultado){
echo "Se agreg nuevo registro de $nombre.";
}else{
echo "ocurri un error al intentar agregar a $nombre";
}
?>
!
! 7erdadero ` ` Falso


S El codIgo de abajo muestra los nombres y emaIls de los clIentes.
!
<?php
require("conexion.php");
$sql=mysql_query("SELECT * FROM clientes");
echo '<table border="1" cellpadding="6" cellspacing="0">';
while($reg=mysql_fetch_array($sql)){
echo "<tr>
<td>$reg[nombre]</td>
<td>$reg[email]</td>
</tr>";
}
echo '</table>';
?>
!
! 7erdadero ` ` Falso


W El sIguIente codIgo muestra los nombres y emaIls de los clIentes, luego cIerra la conexIon
lIberando la memorIa.
!
<?php
require("conexion.php");
$sql=mysql_query("SELECT * FROM clientes");
echo '<table border="1" cellpadding="6" cellspacing="0">';
while($reg=mysql_fetch_array($sql)){
echo "<tr>
<td>$reg[nombre]</td>
<td>$reg[email]</td>
</tr>";
}
echo '</table>';
mysql_close();
mysql_free_result($sql);
?>
!
` ` 7erdadero ! Falso

0nc vez cerrcdc lc conexon, no podrc cplccr ]uncones de MySQL por lo tcnto obtendrc un
error cl e]ecutcr lc ]uncon mysql_free_result(). Lc ]ormc correctc en lcs ltmcs dos
lnecs serc:

mysql_free_result($sql);
mysql_close();

148

1'-<.D'E)!>+#F%,'#).$!QG!?.$%+a.!6')O='D.!

Un grupo de fotografos profesIonales le solIcItan la programacIon de un sItIo web para mostrar
una seleccIon de sus mejores fotografias. La galeria de Imgenes tendr una renovacIon dIarIa,
para lo cual, requIeren una aplIcacIon que les posIbIlIte la actualIzacIon en el menor tIempo
posIble.
Para proteger los derechos de autor de cada fotografia expuesta y evItar el robo de las mIsmas,
requIeren que sean mostradas con "marca de agua".
Su tarea ser programar el sItIo tenIendo en cuenta lo sIguIente:

- La galeria debe exponerse con las fotografias en mInIaturas, en un tamao que no supere
los 80 pixeles de ancho, y las mIsmas deben generarse automtIcamente, a partIr de la
lectura del dIrectorIo en el que se alojan las de tamao normal.
- Cuando el usuarIo pulse sobre una de las mInIaturas, se mostrar la Imagen de tamao
normal y con la marca de agua Incrustada como parte de la mIsma Imagen.
- 0ebe programar una pgIna para los fotografos que permIta la subIda de las Imgenes al
servIdor, sIn necesIdad de que realIcen retoques prevIos en el tamao de ellas.
- Las Imgenes cargadas por los fotografos en el servIdor, deben redImensIonarse
automtIcamente a un tamao que no supere los 640 pixeles de ancho, mantenIendo la
relacIon de aspecto.


!
I%++.='%)-.,!

1 SubIda de archIvos al servIdor
2 Lectura de dIrectorIos
J CestIon de Imgenes


3n!1<H'K.!K%!.+DV'*#,!.$!,%+*'K#+!
En la sItuacIon profesIonal actual debe facIlItar a los fotografos una pgIna para la subIda de
Imgenes al servIdor. Para ello, debe utIlIzar un formularIo que contenga un campo de archIvo.
Un campo de archIvo es un objeto del formularIo que permIte al usuarIo del navegador examInar
el ordenador clIente y seleccIonar un fIchero para cargarlo en el servIdor web. 7eamos un
ejemplo desde la vIsta del dIseo de dreamweaver:





149

El codIgo HT|L del formularIo anterIor es:

<form action="upload.php" method="post" enctype="multipart/form-data"
name="form1" id="form1">
<input name="archivo" type="file" id="archivo" />
<br /><br />
<input type="submit" name="Submit" value="Enviar" />
</form>

Para la subIda de fIcheros es Importante que los datos del formularIo sean envIados con el
mtodo PDST y su valor ||E sea establecIdo en multipart/form-data para el transporte de
multIples tIpos de contenIdo.

Dbserve en el ejemplo de arrIba que al ser envIado el formularIo, los datos sern procesados por
"upload.php". El archIvo cargado se guardar en un dIrectorIo temporal del servIdor.

En la herramIenta 4 de la sItuacIon profesIonal 1 vImos como recuperar datos medIante las super
globales $_POST y $_GET, ahora utIlIzaremos la super global $_FILES, necesarIa para
recuperar archIvos subIdos al servIdor desde un formularIo.
Esta varIable del tIpo array contIene una clave que representa el nombre del "campo de
archIvo" del formularIo, tal como se lo especIfIco en el atrIbuto name del ejemplo, en el que su
valor es "archIvo". La mIsma contIene InformacIon sobre el fIchero cargado como se muestra a
contInuacIon:

name: el nombre del archIvo orIgInal. Ej. $_FILES['archivo']['name'].

type: el tIpo ||E del archIvo. Ej. $_FILES['archivo']['type'].

size: el tamao en bytes. Ej. $_FILES['archivo']['size'].

tmp_name: el nombre temporal del archIvo cuando se carga en el servIdor. Ej.
$_FILES['archivo']['tmp_name'].

error: el error que pudIera producIrse durante la subIda. Ej.
$_FILES['archivo']['error'].


SI el archIvo se ha subIdo correctamente debemos moverlo de la ubIcacIon temporal a una
defInItIva, pero prImero hay que comprobar sI es verdad que la operacIon fue exItosa. Para ello
utIlIzaremos la funcIon is_uploaded_file() cuya sIntaxIs es la sIguIente:

is_uploaded_file($_FILES['archivo']['tmp_name']);

Esta funcIon devuelve false sI ocurrIo algun error o true sI no hubo fallos al subIr el archIvo,
por lo tanto podremos confIrmar la subIda medIante un condIcIonal.

Para mover el archIvo temporal a una ubIcacIon defInItIva dentro del servIdor, utIlIzamos la
funcIon move_uploaded_file() que admIte dos parmetros como se muestra en la sIntaxIs:

move_uploaded_file($_FILES['archivo']['tmp_name'], "/directorio/nuevo_nombre");



150

El prImer parmetro es el nombre del archIvo temporal y el segundo IndIca el nuevo nombre y la
carpeta en donde se ubIcar fInalmente. 0Icha carpeta debe tener permIsos de escrItura "IA96!
777 sI se est trabajando en modo remoto.


Ayuda ahora
"IA96G! change mode o cambIar modo es un comando asocIado al sIstema operatIvo UNX que
permIte cambIar los permIsos de acceso a fIcheros.
Para cambIar permIsos de un archIvo o dIrectorIo de servIdor UNX remoto puede utIlIzar un gestor de
FTP como CuteFTP (www.cuteftp.com) desde las propIedades del fIchero seleccIonado. TambIn podr
hacerlo desde un panel de admInIstracIon de fIcheros de su servIcIo de hostIng.
Dtra forma seria utIlIzando funcIones de PHP:
Int chmod ( strIng Snombre_archIvo , Int Smodo )
Consulte la documentacIon de php.net para ms InformacIon.

ContInuando con el ejemplo anterIor, veamos el codIgo de "upload.php":

<?php
$nombre_archivo=$_FILES['archivo']['name'];
if (is_uploaded_file($_FILES['archivo']['tmp_name'])){
move_uploaded_file($_FILES['archivo']['tmp_name'],
"/imagenes/$nombre_archivo");
}
?>

El codIgo de arrIba mueve el archIvo envIado por el formularIo desde el dIrectorIo temporal
hasta el dIrectorIo "Imgenes del servIdor. SI hubIera otro archIvo con el mIsmo nombre seria
reemplazado por el nuevo. Para evItar esto podemos verIfIcar la exIstencIa del mIsmo medIante
la funcIon file_exists() cuya sIntaxIs es la sIguIente:

file_exists($nombre_archivo);

Esta funcIon recIbe como parmetro el nombre del archIvo del cual desea verIfIcar la exIstencIa.
La mIsma devuelve un valor booleano que ser true en caso de exIstIr y false en caso
contrarIo. 7eamos como queda el codIgo de "upload.php":

<?php
$nombre_archivo=$_FILES['archivo']['name'];
if (file_exists($nombre_archivo)){
die ("El archivo ya existe.");
}
if (is_uploaded_file($_FILES['archivo']['tmp_name'])){
move_uploaded_file($_FILES['archivo']['tmp_name'],
"/imagenes/$nombre_archivo");
}
?>

0e esta manera controlamos sI el archIvo exIste y de ser asi se Interrumpe la ejecucIon del
codIgo envIando un mensaje de advertencIa.

TambIn podemos lImItar la subIda de fIcheros a un tIpo ||E especifIco, como por ejemplo
Imgenes JPEC. En el sIguIente cuadro se muestran algunos tIpos ||E de Imgenes:






151

Formato de Imagen ||
JPEC Image/jpeg
PNC Image/png
CF Image/gIf
8|P Image/bmp

Sobre la base del cuadro anterIor, sI queremos que el usuarIo pueda subIr solamente Imgenes
JPEC, el codIgo de upload.php ser como el que se muestra a contInuacIon:

<?php
$nombre_archivo=$_FILES['archivo']['name'];
$tipo=$_FILES['archivo']['type'];
if ($tipo!='image/jpeg'){
die ("El archivo no es una imagen JPEG.");
}
if (file_exists($nombre_archivo)){
die ("El archivo ya existe.");
}
if (is_uploaded_file($_FILES['archivo']['tmp_name'])){
move_uploaded_file($_FILES['archivo']['tmp_name'],
"/imagenes/$nombre_archivo");
}
?>

Algunos navegadores envian los archIvos JPEC con el tIpo ||E "pjpeg", por lo que puede
preveer este InconvenIente como se muestra en el codIgo de abajo:

<?php
$nombre_archivo=$_FILES['archivo']['name'];
$tipo=$_FILES['archivo']['type'];
if ($tipo!='image/jpeg' || $tipo!='image/pjpeg'){
die ("El archivo no es una imagen JPEG.");
}
if (file_exists($nombre_archivo)){
die ("El archivo ya existe.");
}
if (is_uploaded_file($_FILES['archivo']['tmp_name'])){
move_uploaded_file($_FILES['archivo']['tmp_name'],
"/imagenes/$nombre_archivo");
}
?>

152

@<-#%*.$<.D'E)!3!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!

3 La porcIon de codIgo de abajo corresponde a un formularIo que puede envIar un archIvo al
servIdor remoto:

<form action="upload.php" method="get" name="form1">
<input name="archivo" type="file" id="archivo" /><br /><br />
<input type="submit" name="Submit" value="Enviar" />
</form>
!
` ` 7erdadero ` ` Falso


2 SI un archIvo llamado "mIfoto.jpg" es envIado al servIdor, la porcIon de codIgo de abajo
devuelve el tIpo ||E "Image/jpg":

echo $_FILES['archivo']['type'];
!
` ` 7erdadero ` ` Falso


Q La porcIon de codIgo de abajo mueve un fIchero cargado en el servIdor a la carpeta de la raiz
prIncIpal del sItIo y mantIene el mIsmo nombre que el archIvo orIgInal:

move_uploaded_file($_FILES['archivo']['tmp_name'], $_FILES['archivo']['name']);
!
` ` 7erdadero ` ` Falso


S La porcIon de codIgo de abajo mueve un fIchero cargado en el servIdor a la carpeta "Im" y se
asegura de no sobrescrIbIr otro archIvo que tenga el mIsmo nombre:

move_uploaded_file($_FILES['archivo']['tmp_name'],
"im/".time().$_FILES['archivo']['name']);
!
` ` 7erdadero ` ` Falso


W El codIgo de abajo mueve un fIchero cargado en el servIdor a la carpeta "archIvosonlIne",
sIempre y cuando sea un archIvo de Imagen JPEC, CF o PNC y adems, su tamao no supere los
100.000 bytes:

<?php
$tipo = $_FILES['archivo']['type'];
$extension = substr($tipo, (strpos($tipo, "/")) + 1);
$tipoarch = substr($tipo, 0, (strpos($tipo, "/")));
$tiposPermitidos=array("pjpeg","jpeg","gif","png");
if ($_FILES['archivo']['size'] <= 100000 && in_array($extension, $tiposPermitidos)){
move_uploaded_file($_FILES['archivo']['tmp_name'],
"archivosonline/".$_FILES['archivo']['name']);
}else{
echo "imagen no valida!";
}
?>
!
` ` 7erdadero ` ` Falso


Las respuestas las encontrar al fInal de la sItuacIon profesIonal.

15J

2n!P%D-<+.!K%!K'+%D-#+'#,!
En la sItuacIon profesIonal debe programar una galeria de Imgenes que tendr una actualIzacIon
dIarIa. Para automatIzarla es convenIente aplIcar un mecanIsmo que genere la galeria
Instantneamente a medIda que se vayan agregando Imgenes.
ExIsten muchos mecanIsmos que podriamos aplIcar a la automatIzacIon, pero en este caso
aprovecharemos las funcIones de gestIon de dIrectorIos para tomar lectura del dIrectorIo del
servIdor en el cual se guardan las fotografias. Luego podremos generar la galeria a partIr de los
datos obtenIdos.

En esta herramIenta veremos tres funcIones de dIrectorIo bsIcas:

opendir();
readdir();
closedir();

La prImera funcIon carga una referencIa al dIrectorIo especIfIcado, su sIntaxIs es la sIguIente:

$referencia=opendir($directorio);

En donde $directorio es el dIrectorIo que desea leer dentro del servIdor y puede ser una ruta
absoluta o relatIva.
La varIable $referencia contIene las entradas del dIrectorIo sI el mIsmo exIste y tIene
permIsos de lectura CH|D0 adecuados (sI trabaja en modo remoto), de lo contrarIo podria
producIrse un error y la mIsma ser false. Por ejemplo:

<?php
$directorio="imagenes/";
$referencia=opendir($directorio);
?>

En el ejemplo se carga el gestor de dIrectorIos de la carpeta "Imgenes" que se encuentra
dentro de la mIsma carpeta que el scrIpt del ejemplo.

La funcIon readdir() realIza una lectura de la sIguIente entrada encontrada en $referencia
de opendir(), y devuelve una cadena con el nombre del archIvo encontrado. Cada vez que
ejecute esta funcIon, se obtIene la sIguIente entrada encontrada hasta que ya no exIstan ms
archIvos y, en tal caso, devuelve false. 7eamos su sIntaxIs:

readdir($referencia);

El parmetro $referencia corresponde a las entradas obtenIdas por opendir(). 7eamos un
ejemplo:

<?php
$directorio="imagenes/";
$referencia=opendir($directorio);
while ($entrada = readdir($referencia)) {
echo $entrada;
echo "<br/>";
}
?>

En el ejemplo de arrIba se aplIca un bucle para mostrar cada uno de los archIvos que hay en el
dIrectorIo "Imgenes". El bucle while se ejecuta mIentras exIstan archIvos en dIcho dIrectorIo
y en caso de no exIstIr entradas o archIvos, readdir() devuelve false fInalIzando el bucle. SI

154

bIen esta forma de trabajar con readdir() es correcta, puede ocurrIr que un dIrectorIo o
carpeta que se encuentre dentro de "Imgenes" tenga el nombre "0" o "false". En tal caso
fInalIza el bucle al encontrar dIcha entrada y no permItIr leer las restantes.
Para evItar este InconvenIente, la forma correcta de leer las entradas es utIlIzando un operador
de comparacIon que verIfIque sI el valor devuelto es dIstInto y del mIsmo tIpo que el booleano
false, o sea true:

<?php
$directorio="imagenes/";
$referencia=opendir($directorio);
while (false !== ($entrada = readdir($referencia))) {
echo $entrada;
echo "<br/>";
}
?>

Una vez completadas las operacIones con el dIrectorIo, es buena prctIca cerrar el gestor
medIante la funcIon closedir(), cuya sIntaxIs es la sIguIente:

closedir($referencia);

En donde $referencia corresponde a las entradas obtenIdas por el gestor opendir().
Entonces, el ejemplo completo seria:

<?php
$directorio="imagenes/";
$referencia=opendir($directorio);
while (false !== ($entrada = readdir($referencia))) {
echo $entrada;
echo "<br/>";
}
closedir($referencia);
?>



155

@<-#%*.$<.D'E)!2!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!


3 El codIgo de abajo realIza la lectura del dIrectorIo "fotos" y muestra un enlace a cada Imagen
JPEC encontrada:

<?php
$dir="fotos/";
$ref=opendir($directorio);
while (false !== ($file = readdir($ref))) {
if (substr($file,-3,3)=="jpg"){
echo "<a href='$dir$file' target='_blank'>$file</a><br/>";
}
}
closedir($referencia);
?>
!
` ` 7erdadero ` ` Falso


2 El codIgo de abajo realIza la lectura del dIrectorIo "fotos" y muestra los nombres de los tres
prImeros fIcheros encontrados:

<?php
$dir="fotos/";
$ref=opendir($dir);
$file = readdir($ref);
echo "$file<br/>";
$file = readdir($ref);
echo "$file<br/>";
$file = readdir($ref);
echo "$file";
closedir($ref);
?>
!
` ` 7erdadero ` ` Falso


Q El sIguIente codIgo realIza la lectura del dIrectorIo "paIsajes" y muestra el nombre del
segundo fIchero encontrado:

<?php
$ref=opendir("paisajes/");
$file = readdir($ref);
$file = readdir($ref);
closedir($ref);
echo "$file";
?>
!
` ` 7erdadero ` ` Falso


S El codIgo de abajo realIza la lectura del dIrectorIo "txt", muestra el nombre del prImer
fIchero, luego realIza lectura de la carpeta "pdf", muestra el nombre del prImer fIchero y, por
ultImo, cIerra los gestores de ambos dIrectorIos:

<?php
$ref=opendir("txt/");
$file = readdir($ref);
echo "$file<br />";
$ref=opendir("pdf/");

156

$file = readdir($ref);
echo "$file";
closedir($ref);
closedir($ref);
?>
!
` ` 7erdadero ` ` Falso


W El sIguIente codIgo realIza la lectura del dIrectorIo "categorias" y sI encuentra algun dIrectorIo
dentro del mIsmo, InIcIa nuevamente el gestor para mostrar los fIcheros en l:

<?php
$ref1=opendir("categorias/");
while (false !== ($file1 = readdir($ref1))) {
if (is_dir($file1)){
$ref2=opendir("categorias/$file");
while (false !== ($file2 = readdir($ref2))) {
echo "$file1/$file2<br/>";
}
closedir($ref2);
}
}
closedir($ref1);
?>
!
` ` 7erdadero ` ` Falso



Las respuestas las encontrar al fInal de la sItuacIon profesIonal.

157

Qn!?%,-'E)!K%!'=O&%)%,!
En la presente sItuacIon profesIonal debe proveer un sIstema que permIta la carga de Imgenes
al servIdor, para ello podr aplIcar lo estudIado en la herramIenta 1. TambIn deber
automatIzar el ramado de la galeria de Imgenes que vern los usuarIos, tal como se estudIo en
la herramIenta 2.
Ahora debe programar un scrIpt del servIdor que prepare las Imgenes cargadas por los
fotografos a un tamao adecuado sIn que ellos tengan que edItarlas en un software de
tratamIento de Imgenes. TambIn deber generar las mInIaturas presentadas en la galeria y las
Imgenes protegIdas con marca de agua, de forma dInmIca a partIr de las Imgenes cargadas.
Todo esto podemos lograrlo con el uso de la bIblIoteca de grfIcos C0.

La lIbreria de grfIcos dInmIcos C0 o "0ynamIc CraphIcs LIbrary" (www.lbyd.ory) es una
extensIon de PHP. En PHP 5 se Incorpora C0 en versIon 2, es gratuIta, de codIgo abIerto y sIrve
para crear y manIpular archIvos de Imgenes con extensIones JPEC, CF, PNC, y otras. Todo ello
en la memorIa del servIdor y con salIda al navegador, es decIr, de manera dInmIca.
En efecto, PHP no se lImIta solamente a generar pgInas HT|L, tambIn puede generar otros
formatos de salIda dIrectamente al navegador. Esto se logra cambIando el tIpo de salIda o ||E
que crea PHP.

El estndar ||E se puede utIlIzar para descrIbIr el tIpo de archIvo que se transfIere a travs de
nternet. Ceneralmente, el servIdor envia una cabecera con el tIpo de contenIdo que recIbIr el
software clIente: Content-Type.
PHP, por defecto, envia el tIpo ||E text/html (documento HT|L) en la cabecera HTTP.
Podemos cambIarla utIlIzando la funcIon header(), que se encuentra dentro del grupo de
funcIones de red (Network FunctIons) en la documentacIon de php.net y sIrve para especIfIcar
una cabecera HTTP al software clIente.
SI por ejemplo, el servIdor debe generar una Imagen JPEC, la prImera linea de codIgo seria como
la que se muestra a contInuacIon:

header('Content-Type: image/jpeg');

Fecuerde los tIpos ||E para Imgenes que se mostraron en la herramIenta anterIor.

ExIsten muchas funcIones para crear o manIpular Imgenes en el servIdor pero en esta
herramIenta nos avocaremos a las necesarIas para resolver la sItuacIon profesIonal. Consulte el
manual de php.net en la seccIon de "mage FunctIons" para obtener un lIstado completo de
funcIones relacIonadas.

8sIcamente, el proceso de manIpulacIon de Imgenes consta de los sIguIentes items:

1 ndIcar a PHP el tIpo de Imagen a generar.
2 Crear una Imagen vacia o a partIr de otra en la memorIa del servIdor.
J AsIgnar contenIdo a la Imagen anterIor sI est vacia.
4 0ar salIda a la Imagen con su contenIdo.
5 ElImInar la Imagen de la memorIa del servIdor.

/)K'D.+!.!>I>!%$!-'T#!K%!'=.&%)!.!&%)%+.+J!
El prImer paso se logra por medIo de la cabecera HTTP usando la funcIon header(), tal como se
mostro en el ejemplo anterIor.

"+%.+!<).!'=.&%)!*.Da.!#!.!T.+-'+!K%!#-+.!%)!$.!=%=#+'.!K%$!,%+*'K#+J!
El segundo paso puede ser de dos formas dependIendo del resultado que se quIera obtener.
Podemos crear una Imagen vacia para luego asIgnarle un contenIdo desde otra Imagen, o
podemos crear una Imagen a partIr de otra exIstente en el servIdor.

158


Para crear una Imagen vacia utIlIzaremos la funcIon imagecreatetruecolor(), la mIsma
genera una Imagen en color real. 7eamos un ejemplo:

$img = imagecreatetruecolor($ancho,$alto);

En el ejemplo $img es la nueva Imagen que se genera en la memorIa del servIdor y cuyas
dImensIones estn dadas por los parmetros $ancho y $alto de la funcIon.

Para crear una Imagen a partIr de otra exIstente en el servIdor puede utIlIzar las funcIones:

imagecreatefromjpeg()
imagecreatefrompng()
imagecreatefromgif()

7eamos un ejemplo de uso:

$img = imagecreatefromjpeg($url);

El ejemplo es aplIcable a cualquIera de las tres funcIones nombradas, en donde $img es la
nueva Imagen que se genera en la memorIa del servIdor a partIr del archIvo de Imagen
especIfIcada en el parmetro $url. 0Icho parmetro puede ser la UFL de una Imagen alojada en
el servIdor. En el caso de que ocurra algun error o falla, $img ser una cadena vacia.

@,'&).+!D#)-%)'K#!.!$.!'=.&%)!.)-%+'#+!,'!%,-O!*.Da.J!
Este paso consIste en colocar contenIdo o "pIntar" la Imagen vacia creada por
imagecreatetruecolor(). ExIsten muchas funcIones que asIgnan contenIdos como fuentes de
textos, colores, sombras, formas, etc. En este caso veremos como copIar el contenIdo de una
Imagen en otra vacia con las funcIones imagecopy() o imagecopyresampled().
La functIon imagecopy() copIa parte de una Imagen dentro de otra Imagen que puede estar
vacia o no.

Supongamos, por ejemplo, que queremos copIar una porcIon de la prImera Imagen que se
muestra en la fIgura de abajo, en la segunda Imagen:



El resultado podria ser el sIguIente:


159



La functIon imagecopy(), tendr la sIguIente sIntaxIs:

imagecopy($im_dest, $im_orig, $im_dest_x, $im_dest_y, $im_orig_x, $im_orig_y,
$im_orig_w, $im_orig_h);

$im_dest es la Imagen de destIno en la cual se pega la porcIon copIada de $im_orig.
$im_orig es la Imagen de orIgen desde la cual se copIa una porcIon de la mIsma.
$im_dest_x es la coordenada en el eje de las "x" del destIno a partIr de la cual se va a pegar
$im_orig.
$im_dest_y es la coordenada en el eje de las "y" del destIno a partIr de la cual se va a pegar
$im_orig.
$im_orig_x es la coordenada en el eje de las "x" del orIgen a partIr de la cual se va a copIar la
porcIon del mIsmo.
$im_orig_y es la coordenada en el eje de las "y" del orIgen a partIr de la cual se va a copIar la
porcIon del mIsmo.
$im_orig_w es el ancho que ocupa la porcIon copIada de la Imagen de orIgen.
$im_orig_h es el alto que ocupa la porcIon copIada de la Imagen de orIgen.

Para guIarse mejor en los parmetros de la funcIon imagecopy() observe la fIgura de abajo:



Esta funcIon devuelve true sI la operacIon fue exItosa y false en caso de error o fallo.
El codIgo PHP del ejemplo tendria la sIguIente forma:

<?php
header('Content-Type: image/jpeg');

$im_orig=imagecreatefromjpeg("origen.jpg");
$im_dest=imagecreatefromjpeg("destino.jpg");

160

$im_dest_x=110;
$im_dest_y=70;
$im_orig_x=105;
$im_orig_y=15;
$im_orig_w=100;
$im_orig_h=60;

imagecopy($im_dest, $im_orig, $im_dest_x, $im_dest_y, $im_orig_x, $im_orig_y,
$im_orig_w, $im_orig_h);

imagejpeg($im_dest);
imagedestroy($im_dest);
imagedestroy($im_orig);
?>

Mcs cdelcnte veremos de qu se trctcn lcs ltmcs tres lnecs de codyo del e]emplo.

La funcIon imagecopyresampled() copIa y redImensIona parte de una Imagen dentro de otra
Imagen permItIendo remuestrear la copIa. Al redImensIonar una Imagen, sta puede perder
calIdad por lo tanto es aconsejable utIlIzar un mtodo que Interpole los pixeles para retener el
detalle. La InterpolacIon es operada por la funcIon cItada al remuestrear. Esta aclaracIon se
debe a que exIste otra funcIon llamada imagecopyresized() cuyos parmetros son IdntIcos
a los de imagecopyresampled() pero no realIza un remuestreo.
Los parmetros de imagecopyresampled() son los mIsmos que imagecopy() pero se
agregan las dImensIones de la Imagen copIada. 7eamos un ejemplo:

Supongamos que vamos a copIar la Imagen $im_orig sobre $im_dest, redImensIonada, como
se muestra en las fIguras de abajo:



Fesultado:


161


La sIntaxIs de la funcIon es la sIguIente:

imagecopyresampled($im_dest, $im_orig, $im_dest_x, $im_dest_y, $im_orig_x,
$im_orig_y, $im_orig_w, $im_orig_h, $im_orig_nw, $im_orig_nh);

$im_dest es la Imagen de destIno en la cual se va a pegar la porcIon de la Imagen
redImensIonada de $im_orig. La zona que se va a copIar est delImItada por un rectngulo
cuyo punto InIcIal est marcado por las coordenadas $im_orig_x y $im_orig_y con un ancho
y alto de $im_orig_w y $im_orig_h respectIvamente.
Esta Imagen copIada en la memorIa del servIdor es pegada sobre $im_dest a partIr de las
coordenadas $im_dest_x y $im_dest_y, y redImensIonada a un ancho y alto de
$im_orig_nw y $im_orig_nh, respectIvamente.
Para comprender mejor los parmetros de esta funcIon observe la fIgura de abajo:



SI bIen la funcIon imagecopyresampled() permIte copIar una porcIon de la Imagen, en este
ejemplo copIaremos toda la Imagen de orIgen (esto es aplIcable a la generacIon de mInIaturas o
thumbnaIls).
El codIgo PHP del ejemplo es el sIguIente:

<?php
header('Content-Type: image/jpeg');

$im_orig=imagecreatefromjpeg("origen.jpg");
$im_dest=imagecreatefromjpeg("destino.jpg");
$im_dest_x=110;
$im_dest_y=60;
$im_orig_x=0;
$im_orig_y=0;
$im_orig_w=240;
$im_orig_h=180;
$im_orig_nw=100;
$im_orig_nh=75;
imagecopyresampled($im_dest, $im_orig, $im_dest_x, $im_dest_y, $im_orig_x,
$im_orig_y, $im_orig_w, $im_orig_h, $im_orig_nw, $im_orig_nh);

imagejpeg($im_dest);
imagedestroy($im_dest);
imagedestroy($im_orig);
?>

Mcs cdelcnte veremos de qu se trctcn lcs ltmcs tres lnecs de codyo del e]emplo.

162

En el ejemplo anterIor se supone que los valores de ancho y alto de la Imagen orIgInal son
conocIdos. 7eamos como realIzar lo mIsmo sIn necesIdad de conocer estos valores y
establecIendo un ancho fIjo sIn perder el aspecto de la relacIon entre el ancho y el alto para no
deformar la Imagen:

<?php
header('Content-Type: image/jpeg');

$im_orig=imagecreatefromjpeg("origen.jpg");
$im_dest=imagecreatefromjpeg("destino.jpg");
$datos = getimagesize("origen.jpg");
$im_orig_nw=100;
$relacion = $datos[0]/$im_orig_nw;
$im_orig_nh= $datos[1]/$relacion;

$im_dest_x=110;
$im_dest_y=60;
$im_orig_x=0;
$im_orig_y=0;
$im_orig_w=$datos[0];
$im_orig_h=$datos[1];

imagecopyresampled($im_dest, $im_orig, $im_dest_x, $im_dest_y, $im_orig_x,
$im_orig_y, $im_orig_w, $im_orig_h, $im_orig_nw, $im_orig_nh);

imagejpeg($im_dest);
imagedestroy($im_dest);
imagedestroy($im_orig);
?>

Mcs cdelcnte veremos de qu se trctcn lcs ltmcs tres lnecs de codyo del e]emplo.

En este ejemplo aplIcamos la funcIon getimagesize(), la cual, nos devuelve un array con
InformacIon sobre la Imagen especIfIcada en el parmetro de la mIsma. SI ocurre un error o fallo
devuelve false.
El array $datos tendr cInco valores que podemos utIlIzar en el codIgo. Los prImeros dos
valores corresponden al ancho y alto de la Imagen es decIr que $datos[0] es el ancho y
$datos[1] el alto.
En la sIguIente linea defInImos el ancho que queremos para redImensIonar la porcIon de la
Imagen orIgInal que se va a copIar. Luego establecemos la relacIon medIante $relacion para
no deformar la Imagen.
La altura $im_orig_nh es calculada a partIr de la dIvIsIon entre la altura orIgInal y la relacIon
$relacion por regla de tres sImple.
Dbserve que aprovechamos estos valores para establecer $im_orig_w y $im_orig_h.

Dtra forma de realIzar lo mIsmo seria utIlIzando las funcIones imagesx() e imagesy(), las
cuales devuelven el ancho y alto de una Imagen generada en la memorIa del servIdor, en vez de
obtenerlas dIrectamente desde el archIvo de Imagen:

<?php
header('Content-Type: image/jpeg');

$im_orig=imagecreatefromjpeg("origen.jpg");
$im_dest=imagecreatefromjpeg("destino.jpg");

$im_orig_w=imagesx($im_orig);
$im_orig_h=imagesy($im_orig);

16J

$im_orig_nw=100;
$relacion = $im_orig_w/$im_orig_nw;
$im_orig_nh= $im_orig_h/$relacion;

$im_dest_x=110;
$im_dest_y=60;
$im_orig_x=0;
$im_orig_y=0;

imagecopyresampled($im_dest, $im_orig, $im_dest_x, $im_dest_y, $im_orig_x,
$im_orig_y, $im_orig_w, $im_orig_h, $im_orig_nw, $im_orig_nh);

imagejpeg($im_dest);
imagedestroy($im_dest);
imagedestroy($im_orig);
?>

Mcs cdelcnte veremos de qu se trctcn lcs ltmcs tres lnecs de codyo del e]emplo.

Las funcIones imagesx() e imagesy() recIben como parmetro una Imagen generada en la
memorIa del servIdor, devuelven el ancho y alto de dIcha Imagen, respectIvamente. En el caso
de producIrse algun error o fallo devuelven false.

7eamos otro ejemplo, pero esta vez vamos a centrar la Imagen copIada sobre la Imagen de
destIno como se muestra en la sIguIente fIgura:



El codIgo del ejemplo seria el sIguIente:

<?php
header('Content-Type: image/jpeg');

$im_orig=imagecreatefromjpeg("origen.jpg");
$im_dest=imagecreatefromjpeg("destino.jpg");

$im_orig_w=imagesx($im_orig);
$im_orig_h=imagesy($im_orig);
$im_orig_nw=100;
$relacion = $im_orig_w/$im_orig_nw;
$im_orig_nh= $im_orig_h/$relacion;

$im_dest_x=(imagesx($im_dest)-$im_orig_nw)/2;
$im_dest_y=(imagesy($im_dest)-$im_orig_nh)/2;
$im_orig_x=0;
$im_orig_y=0;


164

imagecopyresampled($im_dest, $im_orig, $im_dest_x, $im_dest_y, $im_orig_x,
$im_orig_y, $im_orig_w, $im_orig_h, $im_orig_nw, $im_orig_nh);

imagejpeg($im_dest);
imagedestroy($im_dest);
imagedestroy($im_orig);
?>

Mcs cdelcnte veremos de qu se trctcn lcs ltmcs tres lnecs de codyo del e]emplo.

Dbserve que la ubIcacIon horIzontal en la coordenada $im_dest_x se calcula a partIr de la
mItad de la dIferencIa entre el ancho del destIno y el ancho fInal del orIgen. Para la coordenada
vertIcal se determIna $im_dest_y a partIr de la mItad de la dIferencIa entre el alto del destIno
y el alto fInal del orIgen.

6.+!,.$'K.!.!$.!'=.&%)!D#)!,<!D#)-%)'K#J!
Todas las funcIones estudIadas para manIpular Imgenes generan grfIcos en la memorIa del
servIdor, pero no producen la Imagen de salIda por si solas. Para lograr una salIda de Imagen a la
pantalla del navegador clIente o como archIvo al servIdor, debe aplIcar las funcIones
imagejpeg(), imagepng() o imagegif(), dependIendo del formato y tIpo ||E que quIera
generar para el navegador clIente. 7eamos la sIntaxIs de imagejpeg():

imagejpeg($im, $url, $calidad);

El prImer parmetro se refIere a la Imagen creada en la memorIa del servIdor y es un parmetro
oblIgatorIo. Los dems parmetros son opcIonales. $url es la ruta y el nombre completo del
archIvo que se genera y $calidad es la compresIon que tendr la Imagen fInal, dIrectamente
relacIonada a la calIdad de la mIsma.
SI se omIten los parmetros $url y $calidad, la Imagen es envIada al navegador clIente pero
no se guarda dentro del servIdor, se estaria generando una "Imagen al vuelo", lo mIsmo que
ocurre en los ejemplos anterIores.
Esta funcIon devuelve true sI se ejecuto con xIto o false en caso de producIrse algun error o
fallo.
Ahora veamos qu sucede sI, por ejemplo, quIsIera guardar una Imagen JPEC que acaba de ser
subIda al servIdor, pero con un tamao en ancho y alto dIferente del orIgInal:

<?php
$nombre_archivo=$_FILES['archivo']['name'];
$temporal=$_FILES['archivo']['tmp_name'];
if (is_uploaded_file($temporal)){
$im_carg=imagecreatefromjpeg($temporal);
$im_carg_w=imagesx($im_carg);
$im_carg_h=imagesy($im_carg);
$nw=100;
$relacion = $im_carg_w/$nw;
$nh=$im_carg_h/$relacion;
$imagenvacia = imagecreatetruecolor($nw,$nh);
imagecopyresampled($imagenvacia, $im_carg, 0, 0, 0, 0, $im_carg_w,
$im_carg_h, $nw, $nh);

imagejpeg($imagenvacia, "fotos/$nombre", 60);
imagedestroy($im_carg);
imagedestroy($imagenvacia);
}
?>

Mcs cdelcnte veremos de qu se trctcn lcs ltmcs dos lnecs de codyo del e]emplo.

165


En el ejemplo copIamos la Imagen cargada o subIda al servIdor dentro de una Imagen vacia pero
redImensIonada a 100 pixeles de ancho, mantenIendo la relacIon de aspecto para no deformarla.
Luego se guarda en la carpeta "fotos" con el mIsmo nombre que el archIvo subIdo al servIdor y a
una calIdad del 60.
Para este caso )# se utIlIzo la funcIon move_uploaded_file() estudIada en la herramIenta 1,
ya que no deseamos guardar la Imagen cargada con sus propIedades orIgInales sIno que la
guardamos redImensIonada. Tampoco es necesarIo especIfIcar la cabecera HTTP con la funcIon
header(), porque no estamos dando salIda a una Imagen para la pantalla del navegador sIno
para un archIvo.

0$'=').+!$.!'=.&%)!K%!$.!=%=#+'.!K%$!,%+*'K#+J!
Al fInalIzar el procesado de cada scrIpt que contenga funcIones de creacIon de Imgenes es
convenIente lIberar la memorIa del servIdor porque de lo contrarIo podria saturarse generando
errores Indeseados. Para ello utIlIzamos la funcIon imagedestroy() como se muestra a
contInuacIon:

imagedestroy($imagen);

El parmetro $imagen corresponde a una Imagen generada en la memorIa del servIdor por las
funcIones de creacIon como imagecreatefromjpeg(), imagecreatetruecolor(),
imagecreate() o cualquIer otra funcIon que las genere en memorIa.
Esta funcIon debe aplIcarse a cada una de los IdentIfIcadores de los grfIcos que se crearon en
memorIa.
Dbserve los ejemplos anterIores para guIarse en el uso de la mIsma.
!

166

@<-#%*.$<.D'E)!Q!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!


3 El codIgo de abajo genera una Imagen en formato CF redImensIonada a partIr de "foto.gIf" y
la envia al navegador clIente:

<?php
header('Content-Type: image/gif');
$im=imagecreatefromgif("foto.gif");
$im_w=imagesx($im);
$im_h=imagesy($im);
$rel = $im_w/120;
$nh=$im_h/$rel;
$imagenvacia = imagecreatetruecolor(120,$nh);
imagecopyresampled($imagenvacia, $im, 0, 0, 0, 0, $im_w, $im_h, 120, $nh);
imagegif();
imagedestroy($im);
imagedestroy($imagenvacia);
?>
!
` ` 7erdadero ` ` Falso


2 El sIguIente codIgo genera una Imagen en formato JPEC a partIr de "foto.gIf" y la envia al
navegador clIente:

<?php
header('Content-Type: image/jpg');
$im=imagecreatefromgif("foto.gif");
imagejpeg($im);
imagedestroy($im);
?>
!
` ` 7erdadero ` ` Falso


Q La funcIon de abajo puede ser utIlIzada para redImensIonar Imgenes y guardarlas en la
carpeta "modIfIcadas" del servIdor:

<?php
function miniatura($archivo){
$im=imagecreatefromgif($archivo);
$datos = getimagesize($archivo);
$rel = $datos[0]/120;
$nh=$datos[1]/$rel;
$imagenvacia = imagecreatetruecolor(120,$nh);
imagecopyresampled($imagenvacia, $im, 0, 0, 0, 0, $datos[0], $datos[1], 120, $nh);
imagegif($im,"modificadas/$archivo");
imagedestroy($im);
imagedestroy($imagenvacia);
}
miniatura($_GET['file']);
?>
!
` ` 7erdadero ` ` Falso





167

S El codIgo de abajo comprueba la dIsponIbIlIdad de la lIbreria C0 2:

<?php
$im = @imagecreatetruecolor(100, 50) or die("Error al iniciar GD");
?>
!
` ` 7erdadero ` ` Falso


W El sIguIente codIgo devuelve 640 en la pantalla del navegador:

<?php
$im = imagecreatetruecolor(640, 480);
echo imagesx($img);
?>
!
` ` 7erdadero ` ` Falso



Las respuestas las encontrar al fInal de la sItuacIon profesIonal.
!
!

168

0Y%+D'D'#!8%,<%$-#
En la sItuacIon profesIonal propuesta, le solIcItan la construccIon de una galeria de Imgenes de
actualIzacIon rpIda y constante.
Para proteger los derechos de autor de cada Imagen expuesta y evItar el robo de las mIsmas
debe aplIcarles una "marca de agua".
Al programar la galeria, tenga en cuenta lo sIguIente:

- Las fotografias en mInIatura, no deben superar los 80 pixeles de ancho y las mIsmas
deben generarse automtIcamente, a partIr de la lectura del dIrectorIo en el que se
alojan las de tamao normal.
- Cuando el usuarIo clIquea una de las mInIaturas, se mostrar la Imagen de tamao normal
y con la marca de agua Incrustada como parte de la mIsma Imagen.
- 0ebe programar una pgIna para los admInIstradores de la galeria, que permIta la subIda
de Imgenes, sIn Importar el tamao de las mIsmas.
- Las Imgenes cargadas por los fotografos, deben redImensIonarse automtIcamente a un
tamao que no supere los 640 pixeles de ancho, mantenIendo la relacIon de aspecto.



!
FIgura 1: Index.php


FIgura 2: Foto marcada

En la fIgura 1 se muestra el aspecto de la
galeria.
Todas las mInIaturas sern generadas por
el servIdor a partIr de las Imgenes de
tamao normal.
La aplIcacIon tendr que leer los archIvos
de la carpeta en la que se alojan las
Imgenes y armar la galeria con todas las
fotos de dIcha carpeta.






Cuando el usuarIo accede a una de las
Imgenes, se abrIr una ventana en la
que se muestre la Imagen de tamao
normal y con la marca de agua, como se
aprecIa en la fIgura 2.
















169


FIgura J: marca.png

En la fIgura J, se muestra la marca de
agua que debe crear. Esta marca tendr
fondo transparente para no cubrIr toda la
fotografia y su tamao ser el adecuado
como para proteger la Imagen orIgInal.

Sobre la base de lo anterIor, la raiz del sItIo deber tener los sIguIentes archIvos:


FIgura 4: Faiz del sItIo

El dIrectorIo "fotos" es la carpeta en la que se subIrn los archIvos de Imgenes JPEC, debe
tener permIsos de escrItura "CH|D0 777" en caso de utIlIzar un servIdor remoto. TambIn debe
verIfIcar que el servIdor tenga Instaladas las lIbrerias de Imgenes C0 2.0.1 o superIor para que
funcIonen todos los scrIpts.
La carpeta "Images" es donde guardar las Imgenes necesarIas para el dIseo de la Interfaz del
sItIo.
En "marca" estar la Imagen de marca de agua, "marca.png", que utIlIzar PHP para Incrustarla
al crear las Imgenes de tamao normal.

El archIvo "estIlos.css" es el que se aplIca a la galeria para darle el formato vIsual a las Imgenes
y dems elementos de la Interfaz.

La pgIna "upload.html" contIene el formularIo para la subIda de Imgenes al servIdor, que
utIlIzarn los fotografos. Los datos de este formularIo, sern procesador por "upload.php", quIen
se encargar de modIfIcar el tamao de las Imgenes a 640 pixeles de ancho y luego las grabar
en la carpeta "fotos".

El "Index.php", es la pgIna prIncIpal, muestra las mInIaturas de las Imgenes guardadas en
fotos. FealIza una lectura de todos los archIvos que hay en "fotos" y envia las UFL de cada una a
"thumb.php". Este ultImo genera las mInIaturas de cada Imagen "al vuelo", en la memorIa del
servIdor. Una vez armada la galeria, se envia al usuarIo que accede a ella y se lIbera la memorIa
del servIdor.

El codIgo del archIvo "marcaagua.php" es el encargado de generar una Imagen que ser la
combInacIon de la "marca.png" y la Imagen seleccIonada por el usuarIo en el "Index.php".

Comenzamos a analIzar "')K%bJTVT":


170


CodIgo completo de Index.php

Entre las lineas 22 y J1 se desarrollan las mInIaturas de la galeria, el resto corresponde al dIseo
vIsual de la Interfaz.
En $carpeta se especIfIca el dIrectorIo de las fotografias cargadas por los fotografos.
En la linea 24 se asIgna a $dir la gestIon del dIrectorIo anterIor.
El bucle while realIza una IteracIon sobre el dIrectorIo abIerto, leyendo cada uno de sus
archIvos. En cada IteracIon del bucle se almacena la UFL de cada archIvo en la varIable
$archivo.
En la linea 26 comIenza la estructura de decIsIon que evalua $archivo. SI esta varIable
contIene la cadena "jpg" en sus ultImos tres caracteres, se procesar la linea 27. Esto evIta que
se procesen dIrectorIos o archIvos dIstIntos de Imgenes JPEC.
La linea 27 genera la Imagen pequea de la UFL obtenIda por $carpeta y $archivo. Dbserve
que se genera desde "thumb.php", la cual recIbe la varIable imagen con el valor de la UFL de la
foto a procesar. El atrIbuto href necesarIo para crear el vinculo a la Imagen de tamao normal
est dado por "marcaagua.php" y la varIable i, que le IndIcar cual Imagen procesar con la
marca de agua.
Una vez que while ha fInalIzado, en la linea J0, se cIerra el gestor de dIrectorIos de la carpeta
"fotos".

7eamos ahora el codIgo de "-V<=HJTVT", encargado de crear las mInIaturas:


171


CodIgo completo de thumb.php

En la linea 2 se declara $ancho, con el ancho de cada mInIatura. Luego se recIbe el nombre de
la Imagen a tratar, asIgnado a $nombre.
La varIable $datos es una matrIz que contIene la altura y anchura de la Imagen orIgInal.
En la varIable $relacion, en la linea 5, se establece la relacIon de aspecto. Esta nos servIr
para calcular la proporcIon de altura que hay que reducIr, sIn perder el aspecto de proporcIones
de la Imagen. Por lo tanto, la nueva altura, ser la relacIon entre la altura orIgInal y
$relacion, asIgnada a $alto, en la linea 6.
En la linea 7 se crea $miniatura, es la Imagen vacia cuyo tamao fue calculado en las lineas
anterIores.
La varIable $img de la linea 8 es la nueva Imagen que se crea a partIr de la UFL especIfIcada en
$nombre.
Hasta aqui tenemos una Imagen vacia, $miniatura, con el tamao necesarIo y la Imagen
orIgInal $img. Ahora debemos utIlIzar estas dos, para generar una Imagen que tenga el tamao
de $miniatura y la Imagen de $img. Esto se logra con la funcIon imagecopyresampled(),
de la linea 9. El prImer parmetro de esta funcIon es la Imagen del tamao necesarIo para la
mInIatura, el segundo es la Imagen orIgInal. Esta funcIon copIar la Imagen orIgInal, dentro de la
Imagen $miniatura reducIndola a su tamao.
En la linea 10 se especIfIca la cabecera del archIvo que generar el presente scrIpt. En este
caso, una Imagen JPEC. Luego se da salIda a la Imagen con una calIdad del 40, en la linea 11.
Por ultImo, se destruye la Imagen $miniatura para lIberar la memorIa del servIdor.

Para mostrar las Imgenes en tamao orIgInal, pero con la marca de agua, utIlIzamos
"=.+D..&<.JTVT", llamada en el enlace de cada mInIatura. A contInuacIon veamos su codIgo:


CodIgo completo de marcaagua.php

PrImero se recIbe la UFL de la Imagen a tratar y se asIgna a $imagen.
En la linea J se crea la Imagen desde la UFL de $imagen. TambIn se comprueba que la
creacIon sea correcta. SI ocurre algun error durante este proceso, se muestra el mensaje del
mIsmo y se fInalIza la ejecucIon del codIgo.

172

En la linea 7 se declara $im y su valor es la Imagen de la marca de agua. Luego se copIa la
Imagen "marca.png" sobre la Imagen orIgInal, en la linea 8. Dbserve que la marca de agua se
centrar en la Imagen orIgInal.
En la linea 9 se especIfIca la cabecera del archIvo que generar el presente scrIpt. En este caso,
una Imagen JPEC. Luego se da salIda a la Imagen con una calIdad por defecto del 75, en la
linea 10.
Por ultImo, se destruyen las Imgenes $im y $im2 para lIberar la memorIa del servIdor.
El resultado ser una Imagen sImIlar a la Imagen orIgInal especIfIcada en $imagen, pero con la
marca de agua sobre ella. Todo en una unIca Imagen.

Ya tenemos los archIvos necesarIos para la galeria que ver el publIco. Ahora veremos como
sern los codIgos para que los fotografos puedan subIr Imgenes a la carpeta "fotos", sIn tener
que procesarlas en un edItor externo. Comencemos por el formularIo de subIda, "<T$#.KJV-=$":


FIgura 5: upload.html

En la fIgura 5 se muestra el aspecto del formularIo y abajo vemos el codIgo del mIsmo:

CodIgo completo de upload.html

Se agrego un campo de archIvo y un boton al formularIo. En el atrIbuto action se especIfIca la
pgIna que va a procesar los datos: "upload.php". Asegurese que el atrIbuto enctype tenga el
valor "multipart/form-data" para que el archIvo se transmIta correctamente.

7eamos como se procesan los datos envIados por "upload.html" en la pgIna "<T$#.KJTVT":


17J


CodIgo completo de upload.php

En la linea 9 se declara la carpeta en la que se guardarn las Imgenes. Luego, en $imagen se
recIbe el archIvo del formularIo.
En $nomTemp asIgnamos el archIvo temporal.
La varIable $nombre de la linea 12 es la UFL en la que se guardar la Imagen fInal.
El if de la linea 1J controla que no exIsta una Imagen con el mIsmo nombre, para evItar
sobrescrIbIrla.
Fecuerde que todos los archIvos que se suben al servIdor, prImero se guardan en una carpeta
temporal del mIsmo, antes de ser manIpulados por PHP. En la linea 16 se crea una Imagen en
memorIa, con la Imagen del archIvo temporal dentro de $nuevaimagen.
En la linea 17 se obtIene una matrIz $datos, con el ancho y alto de la Imagen temporal. Luego,
entre las lineas 18 y 20, se calcula la altura que tendr la Imagen defInItIva, sIn perder su
relacIon de proporcIon ancho/altura.
En la linea 21 se crea una Imagen vacia con el tamao adecuado, y en la 22 se le aplIca la nueva
Imagen redImensIonada a su tamao.
En la linea 2J se da salIda a $imagenvacia, que ahora tendr la Imagen orIgInal en su
composIcIon, esta ser guardada en la UFL de $nombre y a una calIdad del 60.
Por ultImo, se destruye la Imagen de la memorIa y se muestra la Imagen fInal.
En la linea 26 se agrego un enlace para volver al formularIo.

174

0Y%+D'D'#!T#+!+%,#$*%+!

Los fotografos del ejercIcIo anterIor, le pIden que haga los cambIos necesarIos para que el
servIdor no est tan exIgIdo durante la vIsIta de los usuarIos a la galeria.
0ebIdo a que la mayoria de las Imgenes que se vIsualIzan en la galeria son generadas en tIempo
real o "al vuelo", al recIbIr demasIadas vIsItas sImultneas, el servIdor es exIgIdo al limIte de su
rendImIento. Esto tambIn depende del hardware dIsponIble en el servIdor.

En el ejercIcIo resuelto modIfIque los codIgos para que, al subIr las Imgenes, se guarden las
mInIaturas dentro de una carpeta llamada "thumbs", y las de 640 pixeles de ancho se graben con
la marca de agua Incrustada en ellas en la carpeta "fotos".
Haga las correccIones en todos los codIgos de PHP y HT|L para que funcIone la galeria.

Este ejercIcIo deber ser resuelto y envIado a su autor cuando ste se lo IndIque.

175

8%,T<%,-.,!.!$.,!.D-'*'K.K%,!K%!.<-#%*.$<.D'E)!
!
@<-#%*.$<.D'E)!3!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!


3 La porcIon de codIgo de abajo corresponde a un formularIo que puede envIar un archIvo al
servIdor remoto:

<form action="upload.php" method="get" name="form1">
<input name="archivo" type="file" id="archivo" />
<br /><br />
<input type="submit" name="Submit" value="Enviar" />
</form>
!
` ` 7erdadero ! Falso

Pcrc que el crchvo se trcns]erc cl servdor correctcmente debe espec]ccr lc propedcd
enctype del ]ormulcro con el vclor "multipart/form-data" y el mtodo de envo debe ser
PDST. El codyo HTML correcto serc:

<form action="upload.php" method="post" name="form1" enctype="multipart/form-data">
<input name="archivo" type="file" id="archivo" />
<br /><br />
<input type="submit" name="Submit" value="Enviar" />
</form>


2 SI un archIvo llamado "mIfoto.jpg" es envIado al servIdor, la porcIon de codIgo de abajo
devuelve el tIpo ||E "Image/jpg":

echo $_FILES['archivo']['type'];
!
` ` 7erdadero ! Falso

El tIpo ||E devuelto es "Image/pjpeg" sI es progresIva, de lo contrarIo devuelve "Image/jpeg".


Q La porcIon de codIgo de abajo mueve un fIchero cargado en el servIdor a la carpeta de la raiz
prIncIpal del sItIo y mantIene el mIsmo nombre que el archIvo orIgInal:

move_uploaded_file($_FILES['archivo']['tmp_name'], $_FILES['archivo']['name']);
!
` ` 7erdadero ! Falso

El crchvo es movdo c lc msmc ccrpetc en lc que se encuentrc el scrpt que contene dcho
codyo. En clyunos ccsos puede ]cllcr cucndo se ntentc mover un ]chero c lc msmc ccrpetc en
lc que se encuentrc el scrpt que se estc e]ecutcndo.


S La porcIon de codIgo de abajo mueve un fIchero cargado en el servIdor a la carpeta "Im" y se
asegura de no sobrescrIbIr otro archIvo que tenga el mIsmo nombre:

move_uploaded_file($_FILES['archivo']['tmp_name'],
"im/".time().$_FILES['archivo']['name']);
!
! 7erdadero ` ` Falso

176



W El codIgo de abajo mueve un fIchero cargado en el servIdor a la carpeta "archIvosonlIne",
sIempre y cuando sea un archIvo de Imagen JPEC, CF o PNC y adems, su tamao no supere los
100.000 bytes:

<?php
$tipo = $_FILES['archivo']['type'];
$extension = substr($tipo, (strpos($tipo, "/")) + 1);
$tipoarch = substr($tipo, 0, (strpos($tipo, "/")));
$tiposPermitidos=array("pjpeg","jpeg","gif","png");
if ($_FILES['archivo']['size'] <= 100000 && in_array($extension, $tiposPermitidos)){
move_uploaded_file($_FILES['archivo']['tmp_name'],
"archivosonline/".$_FILES['archivo']['name']);
}else{
echo "imagen no valida!";
}
?>
!
! 7erdadero ` ` Falso





177


@<-#%*.$<.D'E)!2!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!


3 El codIgo de abajo realIza la lectura del dIrectorIo "fotos" y muestra un enlace a cada Imagen
JPEC encontrada:

<?php
$dir="fotos/";
$ref=opendir($directorio);
while (false !== ($file = readdir($ref))) {
if (substr($file,-3,3)=="jpg"){
echo "<a href='$dir$file' target='_blank'>$file</a><br/>";
}
}
closedir($referencia);
?>
!
` ` 7erdadero ! Falso

Lc vcrcble $directorio y el yestor de drectoro $referencia no exsten. Lc ]ormc correctc
serc:

<?php
$dir="fotos/";
$ref=opendir($dir);
while (false !== ($file = readdir($ref))) {
if (substr($file,-3,3)=="jpg"){
echo "<a href='$dir$file' target='_blank'>$file</a><br/>";
}
}
closedir($ref);
?>


2 El codIgo de abajo realIza la lectura del dIrectorIo "fotos" y muestra los nombres de los tres
prImeros fIcheros encontrados:

<?php
$dir="fotos/";
$ref=opendir($dir);
$file = readdir($ref);
echo "$file<br/>";
$file = readdir($ref);
echo "$file<br/>";
$file = readdir($ref);
echo "$file";
closedir($ref);
?>
!
! 7erdadero ` ` Falso


Q El sIguIente codIgo realIza la lectura del dIrectorIo "paIsajes" y muestra el nombre del
segundo fIchero encontrado:

<?php
$ref=opendir("paisajes/");
$file = readdir($ref);

178

$file = readdir($ref);
closedir($ref);
echo "$file";
?>
!
! 7erdadero ` ` Falso


S El codIgo de abajo realIza la lectura del dIrectorIo "txt", muestra el nombre del prImer
fIchero, luego realIza lectura de la carpeta "pdf", muestra el nombre del prImer fIchero y por
ultImo cIerra los gestores de ambos dIrectorIos:

<?php
$ref=opendir("txt/");
$file = readdir($ref);
echo "$file<br />";
$ref=opendir("pdf/");
$file = readdir($ref);
echo "$file";
closedir($ref);
closedir($ref);
?>
!
` ` 7erdadero ! Falso

S utlzc el msmo dent]ccdor pcrc dstntos yestores, en este ccso, debe cerrcr el prmero
cntes de nccr el syuente. EL codyo correcto serc:

<?php
$ref=opendir("txt/");
$file = readdir($ref);
echo "$file<br />";
closedir($ref);
$ref=opendir("pdf/");
$file = readdir($ref);
echo "$file";
closedir($ref);
?>


W El sIguIente codIgo realIza la lectura del dIrectorIo "categorias" y sI encuentra algun dIrectorIo
dentro del mIsmo, InIcIa nuevamente el gestor para mostrar los fIcheros del en l:

<?php
$ref1=opendir("categorias/");
while (false !== ($file1 = readdir($ref1))) {
if (is_dir($file1)){
$ref2=opendir("categorias/$file");
while (false !== ($file2 = readdir($ref2))) {
echo "$file1/$file2<br/>";
}
closedir($ref2);
}
}
closedir($ref1);
?>
!
! 7erdadero ` ` Falso


179

@<-#%*.$<.D'E)!Q!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!


3 El codIgo de abajo genera una Imagen en formato CF redImensIonada a partIr de "foto.gIf" y
la envia al navegador clIente:

<?php
header('Content-Type: image/gif');
$im=imagecreatefromgif("foto.gif");
$im_w=imagesx($im);
$im_h=imagesy($im);
$rel = $im_w/120;
$nh=$im_h/$rel;
$imagenvacia = imagecreatetruecolor(120,$nh);
imagecopyresampled($imagenvacia, $im, 0, 0, 0, 0, $im_w, $im_h, 120, $nh);
imagegif();
imagedestroy($im);
imagedestroy($imagenvacia);
?>
!
` ` 7erdadero ! Falso

Lc ]uncon imagegif() es lc que yenerc lc scldc cl ncveycdor y debe espec]ccr un
pcrcmetro oblyctoro que ndque el recurso de mcyen de lc memorc del servdor que desec
mostrcr:

imagegif($imagenvacia);


2 El sIguIente codIgo genera una Imagen en formato JPEC a partIr de "foto.gIf" y la envia al
navegador clIente:

<?php
header('Content-Type: image/jpg');
$im=imagecreatefromgif("foto.gif");
imagejpeg($im);
imagedestroy($im);
?>
!
! 7erdadero ` ` Falso


Q La funcIon de abajo puede ser utIlIzada para redImensIonar Imgenes y guardarlas en la
carpeta "modIfIcadas" del servIdor:

<?php
function miniatura($archivo){
$im=imagecreatefromgif($archivo);
$datos = getimagesize($archivo);
$rel = $datos[0]/120;
$nh=$datos[1]/$rel;
$imagenvacia = imagecreatetruecolor(120,$nh);
imagecopyresampled($imagenvacia, $im, 0, 0, 0, 0, $datos[0], $datos[1], 120, $nh);
imagegif($im,"modificadas/$archivo");
imagedestroy($im);
imagedestroy($imagenvacia);
}
miniatura($_GET['file']);
?>
!
! 7erdadero ` ` Falso

180



S El codIgo de abajo comprueba la dIsponIbIlIdad de la lIbreria C0 2:

<?php
$im = @imagecreatetruecolor(100, 50) or die("Error al iniciar GD");
?>
!
! 7erdadero ` ` Falso


W El sIguIente codIgo devuelve 640 en la pantalla del navegador:

<?php
$im = imagecreatetruecolor(640, 480);
echo imagesx($img);
?>
!
` ` 7erdadero ! Falso

El recurso ndccdo en lc ]uncon imagesx() es nexstente. El codyo correcto serc:

<?php
$im = imagecreatetruecolor(640, 480);
echo imagesx($im);
?>



181

1'-<.D'E)!>+#F%,'#).$!SG!?.$%+a.!6')O='D.!//!
!
Los mIsmos fotografos de la sItuacIon profesIonal anterIor, en la que usted programo la galeria
dInmIca, vuelven a recurrIr a sus servIcIos para pedIrle que Incorpore a ella, un sIstema de
usuarIos regIstrados con el objeto de permItIrles vIsualIzar las fotografias sIn marca de agua a los
que ellos consIderen.
Para ello debe agregar un formularIo de Ingreso, pIdIendo nombre de usuarIo y contrasea; los
usuarIos vlIdos, podrn ver las Imgenes sIn la marca de agua.



I%++.='%)-.,!

1 |anejo de SesIones
1 |anejo de CookIes
!
!
3n!A.)%Y#!K%!1%,'#)%,!
En la sItuacIon profesIonal actual debe Implementar a la galeria de fotografias realIzada en la
anterIor sItuacIon profesIonal, un sIstema que permIta, a determInados usuarIos, la vIsualIzacIon
de fotografias sIn proteccIon, es decIr, sIn la marca de agua.

0ebemos aplIcar un codIgo PHP que sea capaz de dIstInguIr dos tIpos de usuarIos, los usuarIos
regIstrados que tengan permItIdo ver fotografias sIn proteccIon y los no regIstrados que
vIsualIzan las mIsmas pero con proteccIon. A su vez, para que un usuarIo pertenezca al grupo de
los regIstrados tendr su propIa contrasea para InIcIar sesIon, por lo tanto el servIdor debe
IdentIfIcar a cada uno de ellos durante el tIempo que permanezcan sesIonados.

Una sesIon permIte mantener un IdentIfIcador en el servIdor de cada navegador clIente
conectado, y perdura durante todas las solIcItudes o petIcIones que realIza el clIente mIentras
dure la mIsma.

El protocolo HTTP no tIene forma de IdentIfIcar a cada navegador clIente y mucho menos
mantener un IdentIfIcador perdurable entre petIcIones. ExIsten mecanIsmos que trasladan
IdentIfIcadores medIante la matrIz CET pero no son seguros debIdo a que cualquIera puede ver
los datos por UFL. Esto se resuelve en parte con el uso de PDST pero deberiamos colocar un
formularIo por cada pgIna.
Todos estos InconvenIentes se solucIonan con el uso de sesIones que permIten pasar datos entre
pgInas sIn necesIdad de usar formularIos o de comprometer la InformacIon.

La manera de mantener varIables entre pgInas, durante una sesIon, es utIlIzando el array super
global $_SESSION tal como utIlIzamos $_GET o $_POST, pero antes debe estar InIcIada la
sesIon medIante la funcIon session_start().
Esta funcIon regIstra una sesIon en el servIdor y la IdentIfIca con una cadena de J2 caracteres
que dIfIere de cualquIer otro navegador clIente que se conecte e InIcIe sesIon.
La prImera vez que se ejecuta session_start() se InIcIa una sesIon. Para que funcIone
correctamente, debe estar en cada pgIna del sItIo ya que una vez InIcIada, debe mantener la
mIsma sesIon con las mIsmas varIables de $_SESSION durante todo el proceso de navegacIon del
clIente.


7eamos un ejemplo:

182


<?php
session_start();
?>
<html>
<head>
<title>Sesiones</title>
</head>
<body>
<?php
echo "El identificador de la sesin es: ".session_id();
?>
</body>
</html>

Dbserve que session_start() debe ejecutarse antes de envIar cualquIer tIpo de contenIdo ya
que la sesIon envia InformacIon utIlIzando las cabeceras HTTP.
En el ejemplo InIcIamos sesIon y obtenemos el IdentIfIcador de la mIsma medIante la funcIon
sesion_id(). Este IdentIfIcador permanecer durante todas las pgInas que sean accedIdas
por el clIente y que a su vez contengan session_start(). El resultado del ejemplo puede ser
como el que se muestra a contInuacIon:

El identificador de la sesin es: 2d91db259177d70a6f88fecb0e2a209c

SI session_start() encuentra una sesIon actIva recupera el IdentIfIcador y las varIables
asocIadas a l, dentro de $_SESSION, de lo contrarIo InIcIa la sesIon nuevamente.

7eamos un ejemplo con varIables en $_SESSION entre las pgInas "pagIna1.php" y
"pagIna2.php":

"pagIna1.php"
<?php
session_start();
?>
<html>
<head>
<title>Pgina 1</title>
</head>
<body>
<?php
$_SESSION['color1'] = "#0033CC";
$_SESSION['color2'] = "#FFCC00";
?>
<p><a href="pagina2.php">ir a pgina 2</a></p>
</body>
</html>


"pagIna2.php"
<?php
session_start();
$color1=$_SESSION['color1'];
$color2=$_SESSION['color2'];
?>
<html>
<head>
<title>Pgina 2</title>
</head>

18J

<body>
<table width="100" border="0" cellspacing="0" cellpadding="0">
<tr>
<td bgcolor="<?php echo $color1;?>">&nbsp;</td>
<td bgcolor="<?php echo $color2;?>">&nbsp;</td>
</tr>
</table>
</body>
</html>

En la prImera pgIna se InIcIa la sesIon con session_start() y se guardan las varIables super
globales "color1" y "color2" dentro del array $_SESSION. Cuando el usuarIo Ingrese a la
segunda pgIna, se recupera el IdentIfIcador de la sesIon medIante session_start() y se
obtIenen las varIables guardadas en $_SESSION que correspondan al IdentIfIcador de la sesIon
actual. Estas varIables son utIlIzadas en el codIgo para establecer colores.

0e esta manera podemos mantener las varIables a lo largo del proceso de navegacIon del
clIente, como por ejemplo, nombre de usuarIo, contrasea, datos personales, etc.
Esto ocurre en sIstemas de ventas onlIne en los cuales, los usuarIos seleccIonan productos y una
vez fInalIzada la seleccIon confIrman la compra. Los productos seleccIonados quedan en
varIables de sesIon permItIendo al usuarIo navegar de pgIna en pgIna y a la vez mantener la
cesta de productos.

Para elImInar todas las varIables de sesIon puede utIlIzar la funcIon session_unset(). Al
ejecutarse esta funcIon no se cIerra la sesIon, solo se elImInan todas las varIables de
$_SESSION.
SI quIsIera cerrar la sesIon, es decIr destruIrla, utIlIce session_destroy(), esta funcIon
devuelve true sI se ha destruIdo correctamente o false en caso contrarIo.
En el sIguIente ejemplo se cIerra la sesIon destruyendo las varIables sI se recIbe la varIable super
global "salIr":

<?php
session_start();
if (isset($_GET["salir"])){
session_unset();
session_destroy();
}
?>
<html>
<head>
<title>Index</title>
</head>
<body>
<?php
$_SESSION['color1'] = "#0033CC";
$_SESSION['color2'] = "#FFCC00";
?>
<p><a href="index.php?salir=ok">Salir</a></p>
</body>
</html>




184

@<-#%*.$<.D'E)!3!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!


3 El codIgo de abajo InIcIa sesIon sI no exIste una actIva:

<html>
<head>
<title>Sesiones</title>
</head>
<body>
<?php
session_start();
?>
</body>
</html>
!
` ` 7erdadero ` ` Falso


2 El sIguIente codIgo crea las varIables de sesIon "edad" y "dnI":

<html>
<head>
<title>Pgina 1</title>
</head>
<body>
<?php
$_SESSION['edad'] = $_POST['edad'];
$_SESSION['dni'] = $_POST['dni'];
?>
</body>
</html>
!
` ` 7erdadero ` ` Falso


Q La sIguIente pgIna PHP recIbe los valores "usuarIo" y "pass" con los que verIfIca la exIstencIa
de un regIstro en una base de datos que coIncIda con ellos para defInIr la varIable de sesIon
"estado":

<?php
session_start();
?>
<html>
<head>
<title>Pgina 1</title>
</head>
<body>
<?php
$usuario = $_POST['usuario'];
$pass = $_POST['pass'];
include("conexion.php");
$consulta = mysql_query("SELECT * FROM usuarios WHERE usuario='$usuario' AND
pass='$pass'");
if (mysql_fetch_array($consulta)){
$_SESSION['estado'] = "logeado";
echo "Bienvenido $usuario.";
} else {
echo "Usuario o contrasea incorrectos!";
}
?>

185

</body>
</html>
!
` ` 7erdadero ` ` Falso


S El codIgo de abajo permIte elImInar las varIables de la sesIon sI se recIbe
"elImInar_varIables=1" pero no cIerra la sesIon:

<?php
session_start();
if ($_GET["eliminar_variables"]){
session_unset();
}
?>
!
` ` 7erdadero ` ` Falso


W El sIguIente codIgo fInalIza una sesIon e IndIca el resultado:

<?php
session_unset();
$cierre=session_destroy();
?>
<html>
<head>
<title>Pgina 1</title>
</head>
<body>
<?php
if ($cierre){
echo "Sesin finalizada.";
} else {
echo "Imposible finalizar la sesin.";
}
?>
</body>
</html>
!
` ` 7erdadero ` ` Falso

Las respuestas las encontrar al fInal de la sItuacIon profesIonal.

186

2n!A.)%Y#!K%!D##^'%,!
Una cookIe es un archIvo de texto que contIene un conjunto de varIables con sus respectIvos
valores, se almacena en el ordenador clIente y puede ser consultada por el servIdor que la
genero cada vez que el usuarIo accede a l.
Algo sImIlar ocurre en algunos sItIos en los que el usuarIo puede personalIzar la Interfaz, por
ejemplo en Ychoo! Mcl, en el que podemos confIgurar el dIseo de la Interfaz de la vIsta de
correo electronIco y cada vez que InIcIe sesIon para revIsar los mensajes de correo se
mantendrn las confIguracIones establecIdas gracIas a las cookIes almacenadas en el ordenador
del usuarIo.

Para defInIr una cookIe se utIlIza la funcIon setcookie() antes de producIr cualquIer salIda al
clIente ya que trabaja con las cabeceras HTTP. La mIsma admIte dos parmetros oblIgatorIos: el
nombre de la varIable y el valor. TambIn podemos IndIcarle seIs parmetros opcIonales: fecha
de expIracIon o caducIdad, ruta del servIdor, nombre de domInIo, conexIon segura y sI puede ser
accedIda solamente desde el protocolo HTTP. 7eamos la sIntaxIs:

setcookie ($nombre, $valor, $caducidad, $ruta, $dominio, $seguro, $solohttp)

7eamos un ejemplo:

<?php
setcookie("color1", "#0033CC");
setcookie("color2", "#FFCC00");
?>
<html>
<head>
<title>Cookies</title>
</head>
<body>
<p><a href="cookie2.php">ir a pgina 2</a></p>
</body>
</html>

En el ejemplo se defInen dos cookIes y sus valores. Estas cookIes pueden ser recuperadas
medIante el array super global $_COOKIE de la mIsma forma que cuando aplIcamos $_SESSION,
$_POST y $_GET, ya estudIados en herramIentas anterIores.
Tenga en cuenta que no podr recuperar una cookIe defInIda en la mIsma pgIna ya que no
tIenen efecto hasta la proxIma vez que el navegador clIente petIcIone una pgIna.
Dbserve que se agrego un enlace a "cookIe2.php", en esta pgIna recuperaremos los valores de
las cookIes cargadas en el ordenador clIente como se muestra a contInuacIon:

<html>
<head>
<title>Cookies</title>
</head>
<body>
<table width="100" border="0" cellspacing="0" cellpadding="0">
<tr>
<td bgcolor="<?php echo $_COOKIE['color1'];?>">&nbsp;</td>
<td bgcolor="<?php echo $_COOKIE['color2'];?>">&nbsp;</td>
</tr>
</table>
</body>
</html>

Podemos especIfIcar el tIempo de vIda de una cookIe IndIcando el parmetro de caducIdad como
se muestra en el ejemplo:

187


setcookie("color2", "#FFCC00", time()+3600);

En este caso la cookIe "color2" tendr una duracIon de una hora. La forma de especIfIcar dIcha
duracIon en segundos es sumando al tIempo actual del servIdor el tIempo en segundos que
queremos que dure la cookIe.
SI no se especIfIca el tIempo de caducIdad, por defecto, la cookIe es elImInada cuando el usuarIo
cIerra el navegador clIente.

Para elImInar una cookIe solo basta con especIfIcar un valor de tIempo InferIor al tIempo actual:

setcookie("color2", "", time()-3600);

En el ejemplo le decImos al navegador clIente que la cookIe ha expIrado hace una hora por lo
tanto la elImInar. Dbserve que no es necesarIo asIgnar valor a la cookIe, puede tener una
cadena vacia, ya que la estamos elImInando.

Hay que tener en cuenta que el navegador clIente puede tener desactIvada la escrItura de
cookIes, en ese caso no podrn escrIbIrse. Para comprobar sI un navegador acepta las cookIes es
convenIente escrIbIr una y redIreccIonar el navegador a la mIsma pgIna que Intente
recuperarla. SI logra obtener el valor de la cookIe obvIamente las acepta.

En el sIguIente ejemplo se muestra como comprobar la habIlItacIon de las cookIes del navegador
clIente:

<?php
if (!$_GET['redirect']){
setcookie('cookie', 'habilitadas');
header('Location: comprobar.php?redirect=1');
}
?>
<html>
<head>
<title>Comprobar cookies</title>
</head>
<body>
<?php
if ($_GET['redirect']){
if ($_COOKIE['cookie']=='habilitadas'){
echo 'cookies habilitadas';
}else{
echo 'cookies deshabilitadas';
}
}
?>
</body>
</html>

Dbserve que la pgIna del scrIpt de arrIba debe llamarse "comprobar.php".


1%,'#)%,!M!"##^'%,!
Llegado a este punto cabe aclarar que al InIcIar una sesIon, como se estudIo en la herramIenta 1,
el IdentIfIcador de la mIsma es guardado en el ordenador clIente dentro de una cookIe. El
problema que puede ocurrIr es que el usuarIo del ordenador clIente tenga, por segurIdad,
desactIvada la opcIon de permItIr cookIes en su navegador. Por lo tanto, el navegador, no podr
guardar el IdentIfIcador de la sesIon y cada vez que petIcIone una pgIna, el servIdor no

188

conseguIr recuperar las varIables. Para solucIonar este problema debe propagar el IdentIfIcador
de la sesIon medIante UFL con el formato nombre_sesion=id_sesion, tal como se muestra
en el fragmento de codIgo del sIguIente ejemplo:

<a href="sesiones2.php?<?php echo session_name()."=".session_id();?>">ir a
pgina 3</a>

La funcIon session_name() se puede utIlIzar para obtener el nombre de la sesIon que por lo
general suele ser PHPSESS0.
Esta solucIon parece correcta e Incluso podemos preverla para todos navegadores pero el abuso
de ella sufre un pelIgroso error de segurIdad ya que todos los IdentIfIcadores de sesIones serian
vIsIbles en la UFL de los navegadores. UtIlIce esta forma sI es realmente necesarIo y solamente
para navegadores que no tengan actIvada la opcIon de guardar cookIes, no la utIlIce sI va a
comprometer datos Importantes.

Los arrays $_SESSION y $_COOKIE sIrven para que sus varIables perduren de una pgIna a otra
ya que el protocolo HTTP carece de estado. Es decIr que una petIcIon es IndependIente de otra,
por lo tanto las varIables se perderian en cada petIcIon de pgIna al servIdor sI no exIstIeran las
super globales.
Segun lo anterIor, tanto las sesIones como las cookIes sIrven para mantener varIables
perdurables durante las sucesIvas petIcIones de un navegador. La dIferencIa est en quIen tIene
el control sobre cada una de ellas. En el caso de las cookIes, al ser guardadas en el ordenador
clIente, cualquIer usuarIo del mIsmo podria elImInarlas o modIfIcarlas mIentras que las varIables
de sesIon son guardadas en el servIdor por lo tanto solamente el admInIstrador tendria acceso a
ellas, adems no dependen de las restrIccIones del navegador para ser guardadas.
Esto supone un mejor nIvel de segurIdad para las sesIones ya que no se estarn transmItIendo
datos del navegador al servIdor sIno que solamente se transmIte el IdentIfIcador de la sesIon y a
partIr de l, el servIdor obtIene Internamente las varIables que le correspondan. No hay
posIbIlIdad de que se Intercepten datos Importantes mIentras vIajan al servIdor ya que lo unIco
que vIaja es el IdentIfIcador de la sesIon. Esto tampoco es una garantia de segurIdad pero
sIempre es ms seguro trabajar con sesIones que con cookIes.
Y entonces porqu usar cookIes sI las sesIones son ms seguras: La razon es sencIlla: las cookIes
permanecen en el ordenador clIente y cada vez que el usuarIo Ingresa al sItIo, el servIdor puede
consultarlas mantenIendo las mIsmas varIables IndependIentemente de la hora, dia o ao
transcurrIdos del ultImo Ingreso. En el caso de las sesIones, las varIables se destruyen cuando el
usuarIo cIerra el navegador o fInalIza la sesIon y ya no habr posIbIlIdad de recuperarlas durante
un nuevo Ingreso. Adems, con las cookIes podemos controlar el tIempo de caducIdad que tendr
cada una.

Lo Ideal es trabajar con la combInacIon de sesIones y cookIes, guardando varIables menos
Importantes en cookIes y las ms Importantes en las sesIones.

No es convenIente abusar de cookIes ya que los navegadores suelen tener lImItada la cantIdad
por domInIo, generalmente permIten hasta 20 cookIes por domInIo. En el caso de las sesIones
tampoco hay que abusar en cantIdad de varIables ya que al ser guardadas en el servIdor, stas
ocupan espacIo y pueden afectar a la velocIdad de procesamIento con la consecuente lentItud de
respuesta a las petIcIones.

El uso de sesIones y cookIes debe acompaarse con bases de datos, lo normal es mantener un
IdentIfIcador por clIente y a partIr de l obtener varIables desde la base de datos, de esta forma
evItamos que los datos vIajen por la red y dIsmInuImos la cantIdad de cookIes o varIables de
sesIon.


189

@<-#%*.$<.D'E)!2!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!


3 El codIgo de abajo crea la cookIe "usuarIo" y luego la recupera para mostrar un mensaje con
su valor:

<?php
setcookie("usuario", $_POST['user']);
?>
<html>
<head>
<title>LOGIN</title>
</head>
<body>
<p><?php echo "Bienvenido ".$_COOKIE['usuario'];?></p>
</body>
</html>
!
` ` 7erdadero ` ` Falso


2 El sIguIente codIgo declara la cookIe "color1", luego la recupera mostrando un mensaje, y por
ultImo cambIa su valor y la vuelve a recuperar:

<?php
setcookie("color1", "#0033CC");
?>
<html>
<head>
<title>Cookies</title>
</head>
<body>
<p><?php echo "el color1 es ".$_COOKIE['color1'];?></p>
<?php
setcookie("color1", "#FFCC00");
?>
<p><?php echo "el color1 ahora es ".$_COOKIE['color1'];?></p>
</body>
</html>
!
` ` 7erdadero ` ` Falso


Q A contInuacIon se muestran dos pgInas PHP. La prImera declara la cookIe "producto" y
muestra un enlace a la segunda pgIna. En "verproducto.php" se obtIene el valor de la cookIe
declarada anterIormente para mostrarlo en el mensaje:

"productos.php"
<?php
setcookie("producto", "112345");
?>
<html>
<head>
<title>Productos</title>
</head>
<body>
<p><a href="verproducto.php">Ver producto seleccionado</a></p>
</body>
</html>
!

190

"verproducto.php"
<html>
<head>
<title>Mi carrito</title>
</head>
<body>
Usted ha seleccionado: "<?php echo $_COOKIE['producto'];?>"
</body>
</html>
!
` ` 7erdadero ` ` Falso


S La porcIon de codIgo de abajo declara una cookIe que caduca a los 10 mInutos:

setcookie("usuario", "logeado", time()+600);
!
` ` 7erdadero ` ` Falso


W Las lineas de codIgo que se muestran abajo son equIvalentes:

setcookie("color2", "", time()-3600);
deletecookie("color2");
!
` ` 7erdadero ` ` Falso



Las respuestas las encontrar al fInal de la sItuacIon profesIonal.

191

0Y%+D'D'#!8%,<%$-#!
En la presente sItuacIon profesIonal se le pIde que Incorpore a la galeria de la sItuacIon
profesIonal J, un sIstema de usuarIos regIstrados con el objeto de permItIrles vIsualIzar
fotografias sIn marca de agua.
Para ello debe agregar un formularIo de Ingreso, pIdIendo nombre de usuarIo y contrasea; los
usuarIos vlIdos, podrn ver las Imgenes sIn la marca de agua.


FIgura 1: Index.php


FIgura 2: Index.php


FIgura J: Index.php
En la fIgura 1 una se muestra el
formularIo de InIcIo de sesIon. Dbserve
que el resto de la pgIna se permanece
Igual que en la sItuacIon profesIonal J.












Cuando un usuarIo Ingresa con su nombre
y contrasea, desaparece el formularIo
de la fIgura 1 y en su lugar se muestra el
mensaje de bIenvenIda con un enlace
para desconectarse o cerrar la sesIon,
como se aprecIa en la fIgura 2.









SI el nombre de usuarIo o la contrasea
Ingresada, no son vlIdos, se mostrar un
mensaje de error como en la fIgura J.


192

Para comenzar, debe crear una base de datos llamada "usuarIos" y en ella una tabla
"regIstrados", con J campos, como se muestra en la fIgura 4.


FIgura 4: Tabla "regIstrados" de la base "usuarIos".

El campo "Id", debe ser autoIncrementable y clave unIca.

El codIgo de conexIon del archIvo "D#)%b'#)JTVT", ser el sIguIente:


CodIgo completo de conexIon.php

Ahora realIzaremos las modIfIcacIones en el archIvo "')K%bJTVT", para agregar el formularIo de
Ingreso y procesar sus datos para el InIcIo de sesIones:

CodIgo de Index.php (1/J)

En la prImera linea del codIgo orIgInal, se agrega el que se muestra entre las lineas 1 y 7.
PrImero se InIcIalIzan los datos de la sesIon. Luego, en el if, se verIfIca sI el usuarIo ha pulsado
sobre el enlace de cIerre de sesIon. Esto ocurrIr solamente sI ha InIcIado la sesIon
correctamente.


19J


CodIgo de Index.php (2/J)

El codIgo entre las lineas 2J y 48 se agrego en el espacIo de la celda entre las lineas 15 y 16 del
codIgo orIgInal de la sItuacIon profesIonal J.
Entre la linea 24 y 47, la estructura decIde sI mostrar el formularIo o alguno de los mensajes, el
de bIenvenIda o el de error. 0Icha decIsIon la toma segun la exIstencIa de la varIable submit.
Esta varIable exIste cuando se presIona el boton de Ingreso del formularIo. SI submit no exIste,
se muestra el formularIo entre las lineas J9 y 45, observe que el atrIbuto action tIene como
valor la mIsma pgIna "Index.php".
SI el boton de envio de datos del formularIo fue presIonado, en la linea 24 se produce una
condIcIon verdadera y se procesa el codIgo de las lineas 25 a J6. Consecuentemente el
formularIo no aparece y en su lugar surge alguno de los mensajes.
En la linea 25 y 26 se recIben los datos y en la 27 se Incluye la conexIon a la base de datos.
La varIable $consulta, es el resultado de la consulta SQL que pIde los regIstros coIncIdentes
con el usuarIo y contrasea proporcIonados.
La $respuesta ser el numero de regIstros obtenIdos de la consulta anterIor.
La estructura de decIsIon, entre las lineas J0 y J5, decIde sI mostrar un mensaje de error o darle
la bIenvenIda al usuarIo. SI $respuesta vale cero, es decIr que el usuarIo o la contrasea no se
encontraron en algun regIstro de la base, se procesa la linea J4. En el caso de que $respuesta
sea superIor a cero, es decIr que se encontro al menos un regIstro en la base, se procesa la linea
J1 y J2.
En la linea J1 se guarda la sesIon estado con su valor logeado. Este valor lo utIlIzaremos para
controlar el estado de la sesIon en "marcaagua.php".
Dbserve que en la linea J2, el atrIbuto href del enlace de salIda, contIene la varIable salIr con
el valor ok. Podria haber sIdo cualquIer valor, ya que en la linea J se controla la exIstencIa de la
varIable y no su valor.


194


CodIgo de Index.php (J/J)

El resto del codIgo se mantIene Igual que antes. Ahora veremos como cambIar el codIgo de
"=.+D..&<.JTVT":

!
CodIgo completo de marcaagua.php

Al codIgo orIgInal, se agregaron las lineas 2, 8, 9, 10 y 11. En 2, se InIcIalIzan los datos de la
sesIon.
En la linea 9, se evalua sI el usuarIo est logeado. En caso de no estarlo, se procesa la linea 10,
que coloca la marca de agua. 0e lo contrarIo no se procesa dIcha linea y la Imagen ser
mostrada sIn la marca.

195

0Y%+D'D'#!T#+!+%,#$*%+!

La galeria del ejercIcIo anterIor, tuvo un gran crecImIento y recIbe muchas vIsItas dIarIas. En los
ultImos dias, un bromIsta Ingreso al formularIo de subIda de fIcheros y agrego fotografias
obscenas a la galeria. Por esta razon, los dueos del sItIo fueron penalIzados con la suspensIon
del servIcIo de hostIng hasta dar una solucIon al problema.
Ahora le pIden que aplIque un formularIo de Ingreso a la pgIna de subIda de Imgenes, para
evItar Ingresos no autorIzados a esta seccIon. Esto ImplIca que podria elImInar el "upload.html"
y escrIbIr el codIgo del formularIo y el control de la sesIon dentro del mIsmo "upload.php".
Tenga en cuenta que debe crear una nueva tabla en la base de datos, para separar los usuarIos
regIstrados de los fotografos admInIstradores.

Este ejercIcIo deber ser resuelto y envIado a su autor cuando ste se lo IndIque.

196

8%,T<%,-.,!.!$.,!.D-'*'K.K%,!K%!.<-#%*.$<.D'E)!

@<-#%*.$<.D'E)!3!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!


3 El codIgo de abajo InIcIa sesIon sI no exIste una actIva:

<html>
<head>
<title>Sesiones</title>
</head>
<body>
<?php
session_start();
?>
</body>
</html>
!
` ` 7erdadero ! Falso

Lcs sesones deben nccrse cntes de cuclquer envo de dctos cl ncveycdor yc que lcs msmcs
deben envcr unc ccbecerc HTTP. El codyo correcto serc:

<?php
session_start();
?>
<html>
<head>
<title>Sesiones</title>
</head>
<body>
</body>
</html>


2 El sIguIente codIgo crea las varIables de sesIon "edad" y "dnI":

<html>
<head>
<title>Pgina 1</title>
</head>
<body>
<?php
$_SESSION['edad'] = $_POST['edad'];
$_SESSION['dni'] = $_POST['dni'];
?>
</body>
</html>
!
` ` 7erdadero ! Falso

No podrc crecr vcrcbles de seson s no se espec]cc lc msmc en lc ccbecerc HTTP. El codyo
correcto serc:

<?php
session_start();
?>
<html>
<head>
<title>Pgina 1</title>

197

</head>
<body>
<?php
$_SESSION['edad'] = $_POST['edad'];
$_SESSION['dni'] = $_POST['dni'];
?>
</body>
</html>


Q La sIguIente pgIna PHP recIbe los valores "usuarIo" y "pass" con los que verIfIca la exIstencIa
de un regIstro en una base de datos que coIncIda con ellos para defInIr la varIable de sesIon
"estado":

<?php
session_start();
?>
<html>
<head>
<title>Pgina 1</title>
</head>
<body>
<?php
$usuario = $_POST['usuario'];
$pass = $_POST['pass'];
include("conexion.php");
$consulta = mysql_query("SELECT * FROM usuarios WHERE usuario='$usuario' AND
pass='$pass'");
if (mysql_fetch_array($consulta)){
$_SESSION['estado'] = "logeado";
echo "Bienvenido $usuario.";
} else {
echo "Usuario o contrasea incorrectos!";
}
?>
</body>
</html>
!
! 7erdadero ` ` Falso


S El codIgo de abajo permIte elImInar las varIables de la sesIon sI se recIbe
"elImInar_varIables=1" pero no cIerra la sesIon:

<?php
session_start();
if ($_GET["eliminar_variables"]){
session_unset();
}
?>
!
! 7erdadero ` ` Falso


W El sIguIente codIgo fInalIza una sesIon e IndIca el resultado:

<?php
session_unset();
$cierre=session_destroy();
?>
<html>
<head>
<title>Pgina 1</title>
</head>
<body>

198

<?php
if ($cierre){
echo "Sesin finalizada.";
} else {
echo "Imposible finalizar la sesin.";
}
?>
</body>
</html>
!
!
` ` 7erdadero ! Falso

Seyn el codyo de crrbc, lc seson yc ]ue ]nclzcdc o nuncc ]ue nccdc por no espec]ccr en
lc ccbecerc HTTP lc ]uncon session_start(). Lc ]ormc correctc serc:

<?php
session_start();
session_unset();
$cierre=session_destroy();
?>
<html>
<head>
<title>Pgina 1</title>
</head>
<body>
<?php
if ($cierre){
echo "Sesin finalizada.";
} else {
echo "Imposible finalizar la sesin.";
}
?>
</body>
</html>

199


@<-#%*.$<.D'E)!2!
!
8%,T#)K.!T#+!*%+K.K%+#!#!F.$,#J!


3 El codIgo de abajo crea la cookIe "usuarIo" y luego la recupera para mostrar un mensaje con
su valor:

<?php
setcookie("usuario", $_POST['user']);
?>
<html>
<head>
<title>LOGIN</title>
</head>
<body>
<p><?php echo "Bienvenido ".$_COOKIE['usuario'];?></p>
</body>
</html>
!
` ` 7erdadero ! Falso

No podrc recupercr unc cooke declcrcdc en lc msmc pcync. Solo se podrc recupercr en lc
syuente petcon que reclce el clente.


2 El sIguIente codIgo declara la cookIe "color1", luego la recupera mostrando un mensaje, y por
ultImo cambIa su valor y la vuelve a recuperar:

<?php
setcookie("color1", "#0033CC");
?>
<html>
<head>
<title>Cookies</title>
</head>
<body>
<p><?php echo "el color1 es ".$_COOKIE['color1'];?></p>
<?php
setcookie("color1", "#FFCC00");
?>
<p><?php echo "el color1 ahora es ".$_COOKIE['color1'];?></p>
</body>
</html>
!
` ` 7erdadero ! Falso

En este codyo exsten dos errores mportcntes:
1 Al yucl que en el e]ercco cnteror no podrc recupercr unc cooke declcrcdc en lc
msmc pcync. Solo se podrc recupercr en lc syuente petcon que reclce el clente.
2 Lcs cookes deben ser declcrcdcs cntes de reclzcr cuclquer envo de n]ormccon yc que
]ormcn pcrte de lc ccbecerc HTTP. Por lo tcnto en el codyo cnteror no puede ccmbcr
el vclor de "color1" y en su luycr obtendrc un mensc]e de error.


Q A contInuacIon se muestran dos pgInas PHP. La prImera declara la cookIe "producto" y
muestra un enlace a la segunda pgIna. En "verproducto.php" se obtIene el valor de la cookIe
declarada anterIormente para mostrarlo en el mensaje:

200


"productos.php"
<?php
setcookie("producto", "112345");
?>
<html>
<head>
<title>Productos</title>
</head>
<body>
<p><a href="verproducto.php">Ver producto seleccionado</a></p>
</body>
</html>
!
"verproducto.php"
<html>
<head>
<title>Mi carrito</title>
</head>
<body>
Usted ha seleccionado: "<?php echo $_COOKIE['producto'];?>"
</body>
</html>
!
! 7erdadero ` ` Falso


S La porcIon de codIgo de abajo declara una cookIe que caduca a los 10 mInutos:

setcookie("usuario", "logeado", time()+600);
!
! 7erdadero ` ` Falso


W Las lineas de codIgo que se muestran abajo son equIvalentes:

setcookie("color2", "", time()-3600);
deletecookie("color2");
!
` ` 7erdadero ! Falso

No exste nnyunc ]uncon prede]ndc llcmcdc deletecookie().

201

"'%++%!

En el recorrIdo del presente texto, aprendIo a crear pgInas web con lenguaje del lado del
servIdor, generando asi, una salIda de texto HT|L compatIble con todos los navegadores.
EstudIo el lenguaje PHP como scrIpt de servIdor para acceder a |ySQL como motor de bases de
datos. Logro generar contenIdos dInmIcos con funcIones de |ySQL para el acceso y
manIpulacIon de datos; acudIo a funcIones de archIvos y dIrectorIos para su lectura; se Instruyo
en el procesado dInmIco de grfIcos e Imgenes; y consIguIo aplIcar sIstemas de permIsos y
segurIdad a los usuarIos de sus contenIdos web.
|uchas funcIones quedan por aprender en este extenso lenguaje, pero el uso de todas ellas le
resultar relatIvamente sImIlar a las ya estudIadas. Ahora usted debe aplIcar lo aprendIdo,
contInue amplIando y actualIzando sus conocImIentos para competIr en el mercado de los
servIcIos web sIn lImItacIones.

El cutor

Vous aimerez peut-être aussi