Capítulos
Ejercicios

ico php Sitios Dinámicos
(Apache, PHP y MySql)

Luis Felipe Ramírez Varela
https://luis.ramirez.cl
luis@ramirez.cl
luisfel

Conocimiento requerido
  • html
  • css

Pretender ser experto en PHP porque se lee un manual o asiste a clases es una ilusión, la experticia se logra "haciendo", el problema es por donde comenzar para "hacer" y esto requiere un par de conocimiento base que nos permitan tomar este rumbo.

Lo que es importante, por lo tanto, es definir de entrada los objetivos que nos planteamos con este material y así tener claro que se puede esperar:

  • Adquirir conocimientos de los elementos básicos de programación del lado del servidor diferenciando su estructura básica y elementos.
  • Adquirir conocimientos de estructura de una BD y sus consultas básicas.

Para lograr estos dos objetivos se ha preparado este material en función de un ejercicio concreto: "una tienda virtual", en la cual un usuario pueda ver una lista de productos, escoger de él un producto y agregarlo a un carro de compra si está identificado. Requerimiento que se entiende con mayor claridad en el diagrama de casos de uso, (levantamiento global de los requerimientos a desarrollar expresados en usuarios del sistema y sus acciones esperadas).

Casos de uso

Casos de Uso
Casos de Uso

Esto es más fácil entenderlo si lo vemos en un diagrama de actividad (Diagrama que expresa el comportamiento del sistema en su relación con el usuario):

Diagrama de actividad

Diagrama de actividad
Diagrama de actividad

Bien, entremos en materia, comencemos por el principio y terminemos por el final.

Objetivo del capítulo:
Entender la lógica de las páginas dinámicas y describir los servicios involucrados para que esto se pueda realizar, de tal manera que sepamos que software requerimos para realizar los ejercicio de este manual.

¿Por qué páginas dinámicas?

Las páginas dinámicas o páginas "activas" ya no son un lujo, sino un mal necesario para responder ante los crecientes requerimientos de respuestas más rápidas, sitios inteligentes y personalizados, servicios que aporten contenido cambiante y generen esa necesidad de "la segunda visita".

Ciclo de una página dinámica
Ciclo de una página dinámica

Vamos desde el principio: La "Web" nació como una necesidad militar, desarrollada por universitarios. Tanto los militares como los académicos sacaron provecho de este medio para difundir sus ideas, administrar sus comunicaciones o sus estrategias, hasta que llamó la atención de las grandes empresas, primero como una forma de comunicación dentro de la empresa, para pasar en corto tiempo, y con un poco de capital, a un medio propio de comunicación con los consumidores y proveedores.

Un sitio Web son dos o más páginas relacionadas entre ellas con hipervínculos. Primer paso de la interactividad, los hipervínculos permitieron relacionar temas y generar conceptos de comunicación más completos y complejos. Aunque en su primera etapa comercial, se le veía más como un adorno en la tarjeta de presentación de los grandes ejecutivos, poco a poco se dieron cuenta que podía utilizarse para "algo más". Y pasó a la etapa de la "vitrina". Un lugar donde poder exhibir los productos, tal cual lo hace la vitrina de un mall pero a nivel digital y con capacidad de acceder a mucha más gente.

Esta etapa de vitrina encuentra un creciente número de adeptos, por un lado los costos de Internet, el incremento de conectados a red, los programas de interfaz gráfica para el montaje de código HTML, pero sobre todo por su símil con el medio conocido de difusión, la prensa y los impresos.

Ahora los diseñadores y los comunicadores podían acceder a una nueva plataforma de comunicación, integrando, los medios digitales que ya estaban aprendiendo a manejar, a un lenguaje que hasta hace poco pertenecía al complejo mundo de los programadores e ingenieros.

Pero los requerimientos de sitios "vitrina" se quedaron cortos ante la demanda de mayor personalización, actualización y cambios que exigían los clientes. Sobre todo, y visto siempre desde el interés comercial, de la venta directa y el aprovechar la compra impulsiva.

La costumbre y confianza en la venta por catálogo, en países como Estados Unidos, encontraban en Internet todo lo que las publicaciones tradicionales no podían ofrecer: ampliarse a un mercado global, conocer al consumidor, reaccionar ante su historial y no ofrecerle algo que no existe en stock.

Pero para esto se requeriría entrar a otro tipo de páginas Web. No un lenguaje que reaccionara y se viera en el computador del usuario como las páginas estáticas, si no que preguntara al servidor cómo tenía que reaccionar y qué contenidos poner, y ahí es donde aparecen las páginas dinámicas, la programación del lado del servidor.

¿Qué es un servidor web?

Muchas veces se confunde un servidor con un computador caro, que si bien es ideal, no es totalmente necesario (nunca se tiene el RAM que uno quisiera). Un "servidor" no es el computador si no lo que sabe hacer y eso lo determinan los software que tiene instalado . Un servidor es un software capaz de relacionar una solicitud vía http con un directorio o un archivo Web específico, y de devolver al solicitante el resultado.

Hay diferentes software SERVIDOR o HTTPD, desde los más caros, hasta los de distribución gratuita. Dependiendo de los sistemas operativos utilizados, hay diferentes opciones, por ejemplo desde Windows 2000 que ya tiene instalado el IIS (Internet Information Servers) o el Os X de Apple, que viene de la familia Linux, con Apache, pasando por los servidores como el "planet DNS" o el "KF Webserver" que se pueden encontrar en download.com (http://www.download.com), hasta los servidores profesionales como el Windows NT Server o Apache.

The Apache Software Foundation
Página de The Apache Software Foundation

Y aquí una pausa. "Profesional" no es lo mismo que caro o pagado, ya que, de hecho, los servidores Apache (http://www.apache.org), son de la familia de los "open source" (código abierto), programas de distribución liberada y de código base abiertos, que, como la mayor parte de los programas para Linux, permiten la participación y mejora voluntaria por parte de los usuarios, lo que ha hecho de este software servidor, no sólo uno de los más robustos, rápidos y estables, si no que además uno de los más utilizados profesionalmente en el hosting de páginas WEB.

Estas características han hecho que este software trascienda del mundo Linux al mundo Windows y Apple. Sea cual sea el software que decidamos utilizar como servidor (aunque fuertemente recomendamos y hacemos referencia en este documento a Apache), todos los software hacen algo en común: servir páginas web.

Recibir e interpretar las solicitudes que se le hacen vía HTTP, leer los archivos y devolver contenido al solicitante es lo básico, pero no es todo lo que sabe hacer. En este proceso, es capaz de relacionar los contenidos o extensiones de los archivos con "módulos" capaces de interpretar y ejecutar los comandos escritos en lenguajes de programación.

¿Qué son los Lenguajes de programación ?

Lenguajes de programación hay varios, generalmente relacionados más con un sistema operativo, que con un servidor, aunque cada vez más esto es parte de ese "gran mito".

Como dijimos anteriormente, los lenguajes de programación dinámica van a ser interpretados por módulos especializados, que tienen definidas funciones específicas y que permiten relacionar las ordenes con acciones, a veces muy sencillas como preguntarle al servidor la hora, y otras un poco más complejas como seleccionar datos de una Base de dato, generar, o borrar archivos en el computador servidor.

Algunos de los lenguajes más conocidos son ASP (Active Server Page) de Microsoft, Cold Fusion y JSP (Java Server Page) de Adobe y PHP (Personal Home Page), desarrollado, dentro del concepto de "open source".

Página oficial de PHP
Página oficial de PHP

PHP (http://www.php.net) nació bajo el mundo Linux pero su versatilidad y sencillez ha invadido rápidamente el mundo de Windows y Apple, demostrando estabilidad y velocidad. Como es un lenguaje sencillo, una mezcla entre C++ y Perl, se puede dar el lujo de adaptarse fácilmente a la forma o estilo de programación que cada uno tenga, mientras se respeten un par de normas básicas.

Este documento está orientado principalmente a este último lenguaje, aunque los conceptos básicos son aplicables a cualquiera de los lenguajes mencionados anteriormente, claro que cada uno con sus propias mañas y estilos.

Lo importante es entender que hay un lenguaje de programación que tiene funciones definidas y que son interpretadas por módulos especializados en el servidor web. Este lenguaje habla con la máquina y con otras aplicaciones instaladas en ella, por ejemplo con Bases de Datos que contengan los "datos" que se va a poner en la página.

¿Qué son las Bases de Datos?

Si bien vamos a dedicar todo un capítulo de este documento al trabajo con bases de dato, es importante entender que nos referimos a un software especializado, aunque muchos programadores agregan que cualquier formato que tenga datos tabulados de manera constante ya es una base de dato. Personalmente, me tardé mucho tiempo en tratar de entenderlas, verlas y hasta con la necesidad de tocarlas. Y esta explicación es la que más conforme me ha dejado.

Al igual que en los casos anteriores, hay varios tipos de software para bases de dato y también relacionadas con los sistemas operativos. Las hay desde las más sencillas, con una cómoda interfaz gráfica, como el FileMaker, hasta las más complejas como Oracle.

Página oficial MySql
Página oficial MySql

En el caso de este documento, vamos a trabajar con MySql (http://www.mysql.com), otra vez, un software nacido en el mundo Linux y bajo el principio de "open source". Compatible con Windows y Apple, que se destaca por ser robusto, rápido, seguro, altamente configurable y compatible con SQL (Structured Query Language).

MySql es en sí un sistema complejo, y la mejor manera de "verla" es a través de una interfaz gráfica, por lo que también haremos referencia más adelante a phpMyAdmin (http://www.phpmyadmin.net), si bien no es un "software" como tal, ya que funciona con páginas dinámicas escritas en PHP, entrega la flexibilidad y la interfaz de un muy buen software.

En resumen, para que puedan existir las páginas dinámicas, se necesitan 3 elementos:

  • Un servidor que interprete la solicitud del cliente y que haga la relación con el módulo de programación dinámica.
  • Un lenguaje de programación que realice consultas y que ponga los contenidos en una página web
  • Una base de datos que contenga las informaciones de las cuales se va a seleccionar el contenido a poner.
Servicios AMP
Servicios AMP

Apache, PHP y MySql son una buena elección, primero por ser Open source, por ser robusto, contar con excelente material de apoyo y ser multiplataforma, además que se encuentra en la mayor parte de servidores profesionales.

Si bien no es necesario, es muy cómodo tener los tres servicios instalados en el computador de desarrollo, para probar localmente nuestro desarrollo antes de subirlo a Internet.

Objetivo del capítulo:
Revisar la instalación de los servicios requeridos para la ejecución de los ejercicios de este manual, tanto para el sistema operativo Windows de Microsoft, como para OsX de Apple.

Servicios AMP

El primer paso que vamos a dar es la instalación de los tres servicios necesarios para poder ver y ejecutar los programas que hagamos. Hay dos maneras de hacerlo:

La primera es ir a los 3 sitios de los servicios necesarios (apache.org, php.net y mysql.com) y bajar las últimas versiones de los distintos software. Hay que fijarse de bajar la versión para el sistema operativo en el que estamos trabajando.

Tiene varias ventajas, por un lado el tener las últimas versiones siempre permite sacar provecho de los nuevos desarrollos, aunque "muy nuevo" también significa que no ha sido probado lo suficiente, por otro lado, es una muy buena manera de saber lo que tenemos instalado en nuestro computador.

Cada uno de los instaladores viene con un README que tiene un paso a paso de cómo instalar y configurar dependiendo del sistema operativo, pero en su idioma original, inglés.

Hay que fijarse de instalar primero el Servidor Apache, después PHP y por último la Base de Dato Mysql, porque de lo contrario se puede complicar la configuración.

Si bien esta primera opción es la más lógica, también es cierto que puede ser un poco complicado para comenzar, aunque recomendable tarde o temprano.

Voy a partir del principio que se ésta trabajando en un PC con Windows o en un Apple con OsX. Como los sistemas operativos son distintos, vamos a enfrentar por separado las instalaciones en cada uno de los dos ambientes. Este es la única instancia donde haremos una diferencia entre ambos sistemas operativos, para el resto de los procesos tratados en este documento es transparente para ambas plataformas.

MAMP para Windows 7, 8.1, 10

logo-mamp

MAMP (https://www.mamp.info/) lleva varios años realizando la tarea de instalar los 3 servicios que requerimos, si bien nació para el mundo Apple, ha estado desarrollando versiones estables para Windows 7, 8.1, 10.

1Vamos a la página https://www.mamp.info/en/downloads/ y descargamos la últimaversión MAMP & MAMP PRO (en este caso la 4.11) para Windows

Página de descarga de MAMP
Página de descarga de MAMP

2Esta acción nos va a descargar un archivo EXE (software ejecutable) a nuestro directorio de Descarga, basta con hacer doble clic sobre el ícono para que comience el proceso de instalación.

Instalador de Windows
Instalador de Windows

3La primera ventana nos ofrece instalar MAMP PRO y Apple Bonjour (para poder utilizar el visor de la versión PRO), MAMP PRO es la versión de pago, y para este curso no es necesario, por lo que podemos deseleccionar ambas opciones. Si estamos de acuerdo apretemos el botón siguiente "Next".

Instalación de MAMP-Pro
Instalación de MAMP-Pro

4En esta ventana nos recuerda la licencia de uso de la aplicación. Aquí seleccionamos "I Accept the agreement" y el botón "Next".

Licencia de instalación
Licencia de instalación

5Aquí nos pregunta el lugar donde va a instalar el directorio "MAMP", salvo que tengamos un argumento claro, entendible y verbalizable por el cual no instalarlo en la raíz del disco principal, sugiero que lo dejes en la raíz de C:, tal como sugiere.

Directorio de instalación
Directorio de instalación

6Esta ventana nos cuenta que va a generar un acceso directo en la barra de tareas (siempre útil). Cuando estemos listos, seleccionamos la opción siguiente "Next".

Acceso directo en el menú de inicio
Acceso directo en el menú de inicio

7Esta ventana nos informa que va a generar un acceso directo a la aplicación en el escritorio. Si queremos el acceso directo lo dejamos seleccionado. Después seleccionamos el botón "Next".

Acceso directo en el escritorio
Acceso directo en el escritorio

8Esta ventana nos hace un resumen de los directorios y accesos rápidos que va a generar. Si estamos de acuerdo seleccionamos "Install", si no queremos alguno de los elementos, podemos ir para atrás con el botón "Back" y volver a seleccionar o deseleccionar los componentes extras y volver a este resumen.

Resumen de lo que se va a instalar
Resumen de lo que se va a instalar

9Comienza el proceso de instalación y nos muestra con la barra de estado el avance en el proceso y los archivos que está instalando.

Proceso de instalación
Proceso de instalación

10Una vez terminado el proceso nos muestra la pantalla final de instalación. Ahora seleccionamos el botón "Finish" y hemos terminado con la instalación en Windows.

Termino de instalación
Termino de instalación

MAMP para Apple OS X

logo-mamp

El sistema operativo OS X está basado en una de las distribuciones de BSD Linux, por lo que ya viene configurado el servicio de apache, pero los otros servicios hay que instalarlos.

Al igual que en windows, existen instaladores todo en uno, parecidos al XAMPP, como el MAMP ( http://www.mamp.info/ ). Esta aplicación se ejecuta de manera paralela a la aplicación Apache que viene configurado en el sistema.

1Vamos a la página https://www.mamp.info/en/downloads/ y descargamos la últimaversión MAMP & MAMP PRO (en este caso la 5.7) para Apple

Página de descarga de MAMP
Página de descarga de MAMP

2Esta acción nos va a descargar un archivo PKG (software packages), basta con hacer doble clic sobre el ícono para que comience el proceso de instalación.

Instalador de OsX
Instalador de OsX

3La primera ventana nos da la bienvenida y nos dice que el sistema nos guiará por los pasos necesarios para instalar la aplicación.

Pantalla de bienvenida
Pantalla de bienvenida

4En esta ventana nos advierte que se instalarán dos directorios: MAMP y MAM PRO y nos advierte que no debemos mover MAMP del directorio de aplicaciones o cambiarle el nombre ya que perdería todas las capacidades de conversación.'

MAMP PRO es la versión pagada de MAMP y sumamente dúctil si es que se quiere hacer la inversión y el MAMP, a secas, que es la versión de distribución liberada, un poco más limitada, pero perfecta para nuestros requerimientos.

Ruta de instalación y alerta
Ruta de instalación y alerta

5La siguiente ventana es la clásica ventana de acuerdo de licencia. Al darle continuar (continue), nos vuelve a pedir el acuerdo de licencia. Seleccionamos Agree y vamos al siguiente paso.

Acuerdo de licencia
Acuerdo de licencia

6Esta ventana nos permite seleccionar en qué unidad lo queremos instalar. Una vez seleccionado le damos continuar con "Continue".

Espacio de disco requerido y selección de unidad de  instalación.
Espacio de disco requerido y selección de unidad de instalación

7Esta ventana nos advierte del espacio de disco que va a ocupar. Aquí podemos comenzar el proceso de instalación directamente al decirle "install" o podemos personalizar la instalación al seleccionar "customize". Básicamente lo que podemos hacer es seleccionar si queremos que instale la versión PRO o no.

Espacio de disco requerido
Espacio de disco requerido

8Ya que el proceso va a instalar archivos en directorios protegidos, nos pide la clave de administrador de la máquina.

Introducimos la clave de usuario y seleccionamos el botón "Install Software"

Permiso de instalación
Permiso de instalación

9Comienza el proceso de instalación.

Proceso de instalación
Proceso de instalación

10Al terminar el proceso de instalación, finaliza con la ventana de resumen. Aquí seleccionamos "Close" para cerrar la aplicación de instalación.

Termino de instalación
Termino de instalación

Usando MAMP

Una vez que lo tengamos instalado, vamos al directorio dónde está nuestra instalación. en Windows está en c://MAMP y en OsX en /Applications/MAMP. Aquí se han instalado varios directorios y archivos, entre los más importantes (por ahora):

Archivos instalados
Archivos instalados
conf
Las configuraciones del sistema
htdocs
El directorio público que va a consultar Apache.
logs
Donde se va a registrar la actividad de Apache, PHP, y MySql en su interacción con el sistema y
MAMP
Ejecutable de la aplicación la que tiene el ícono del elefante.

Si hacemos doble clic sobre la aplicación se va a abrir una pequeña ventana y va a tratar de arrancar Apache y MySql (el módulo PHP está configurado y amarrado a apache).

Panel de control de MAMP
Panel de control de MAMP

Al mismo tiempo, MAMP abrirá el browser de navegación predeterminado con la página de inicio, indicando que esta corriendo y de manera correcta. Si nos fijamos en la dirección en la barra de URL es http://localhost:8888 , esto quiere decir que el apache de MAMP está respondiendo a las solicitudes hechas a localhost al puerto 8888.

Nota:
Puede generar confusión, pero es importante recordar que MAMP en apple, a diferencia de su versión Windows, trabaja contra el puerto 8888, esto quiere decir que a la dirección URL hacia el directorio público sería http://locahost:8888 y en Windows sería sólo http://localhost.

Página de bienvenida de MAMP
Página de bienvenida de MAMP

Hay varias personalizaciones que se pueden realizar a esta aplicación, por ejemplo: donde se va a alojar el directorio público.

Seleccionamos el menú de preferencias, y hay 4 parámetros que podemos configurar:

Panel de control MAMP - Preferencias
Panel de control MAMP - Preferencias
General
Permite definir si los servicios arrancan al iniciar la aplicación y terminan al cerrarla. Aquí también encontramos la ruta hacia la página de MAMP y si queremos que abra al momento de inicializar la aplicación
Ports
Son los puertos en los que va a trabajar Apache y MySql, a menos que tengamos una buena razón por la cual cambiarlo, es buena idea dejarlo en los puertos 8888 para apache y 8889 para MySql.
PHP
Permite seleccionar si queremos trabajar con la versión php7.3.9 o php7.4.2 (la última versión)
Web Server
Permite selecciona Apache o el servidor Nginx, además permite elegir cual va a ser la raíz del directorio público.
De manera predeterminada, el directorio público es htdocs.

Nota:
Puede generar confusión, pero es importante recordar que MAMP, a diferencia de XAMPP, trabaja contra un puerto 8888, esto quiere decir que http://locahost:8888 es la dirección hacia el directorio público.

Ejercicio:
  1. Instalar los servicios de servidor requeridos en nuestros equipos personales de desarrollo.

Objetivo del capítulo:
Establecer las bases mínimas para escribir y ejecutar código PHP y poder distinguirlo del resto del código html de una página.

PHP son las siglas para "Personal Home Page" un lenguaje que inventó Rasmus Lerdorf (http://www.zend.com) en el año 1994 fusionando C++ y Perl, sin la mayor pretensión de hacer un poco más dinámica su propia "página personal". Con el tiempo y el aporte de los usuarios PHP comenzó a significar "Hypertext Preprocessor" y a crecer en funciones y capacidad. A diferencia de otros lenguajes dinámicos, PHP nace para la Web y por la Web, por lo que toda su orientación y mejoras se proyectan a la generación de páginas dinámicas. Va en su versión 7 y por sus características de código abierto recibe muchos aportes de los usuarios y desarrolladores.

El código PHP se incorpora en una página Web para ser interpretado por el servidor, realiza operaciones y devuelve datos para ser incorporado en las páginas Web. En otras palabras es un lenguaje de scripting insertado entremedio del código HTML.

Requiere de 4 parámetros básicos para que pueda funcionar:

  • Extensión
  • Tags diferenciadores
  • Ordenes separadas
  • Funciones

Veamoslas por separado.

Extensión

El primer diferenciador, es que el archivo tiene que tener la extensión punto php (en algunos servidores antiguos todavía se maneja la extensión completa php3 o php4 dependiendo de las versiones de PHP en las que fueron escritas, pero desde el PHP4 no es necesario). La extensión es el primer elemento que considera el servidor para comenzar a procesar su código.

Tags diferenciadores

El segundo elemento diferenciador es que todo lo que se va a interpretar en el servidor tiene que diferenciarse de otros lenguajes de programación. Así como HTML se diferencia por tener tags entre los signos "mayor qué" y "menor qué" para que los browser los distingan del resto del texto ASCII de una página Web y lo interprete, PHP debe distinguirse del resto del código al ser filtrados e interpretados por los módulos PHP en el servidor, por eso es que el código debe de estar entre los caracteres <?php y ?>, es decir, que toda la programación tiene que estar encerrada entre estos tags, no importando si son varias líneas de ordenes.

Aquí es donde se ve la flexibilidad del lenguaje PHP, ya que también acepta los caracteres <% y %>, como en ASP, o simplemente <? ?> (sin el php), lo cual es bastante difundido y más cómodo.

Ejemplo:
<?php 
$var="Hola Mundo";
print($var);
?>

Resultado:

Hola Mundo

Ordenes separadas

Es interesante el ejemplo anterior, aunque todavía no tengamos claro de qué se trata, porque nos permite hablar de la tercera característica del PHP, compartida por la mayor parte de lenguajes de programación: Cada instrucción tiene que ir por separado, y generalmente para ordenarnos, está en líneas separadas, por lo que después de cada instrucción, siempre se termina con punto y coma (;). Muchas de las fallas que se producen al comenzar a programar es porque se mezclan dos ordenes al no separarlas con un punto y coma.

Funciones

Otra característica de PHP es que es un lenguaje de funciones pre-establecidas y que son muy fáciles de distinguir porque siempre terminan con paréntesis. La función phpinfo(), por ejemplo, entrega toda la información del servidor, del entorno y de las configuraciones de PHP.

Ejemplo:
<?php phpinfo();?>

Resultado:

phpinfo()
phpinfo()

Hay muchas funciones, y probablemente sería difícil recordarlas todas, por lo que es bueno tener a mano la dirección http://www.php.net. Ésta es la página oficial de PHP y siempre está actualizada con los últimos comandos y funciones incorporados, además de tener un excelente manual en línea con buscador por función y uso. En este documento vamos a ir viendo e integrando varias de ellas, lo básico es entender que los desarrolladores del PHP han considerado muchas de las acciones que se pueden hacer.

En resumen, básicamente, las páginas PHP tienen que terminar con la extensión .php, el código encerrado entre los tag <?php y ?>, cada orden separada por ; y utilizar las funciones que ya están escritas. Siguiendo estas cuatro normas básicas, más otras específicas que vamos a ir incorporando, PHP va a comenzar a tomar cuerpo.

Objetivo del capítulo:
Comprender y utilizar la función print() de PHP para escribir y mostrar el resultado de un proceso en el código html de una página web, así como comenzar a identificar el concepto de cadenas y posibles errores al momento de escribir un código.

Publicar

PHP es un lenguaje que funciona en idioma de computador, por muy ilógico que suene, es importante considerarlo si es que queremos "ver" el resultado de una operación con PHP.

print() es una función, (fácilmente distinguible porque termina con paréntesis), que te permite una impresión en pantalla. En nuestro caso, una impresión de texto ASCII en una página Web que va a ser interpretado por un browser. print() imprime cualquier cadena de caracteres que se encuentre dentro de los paréntesis.

Genera una página nueva con la siguiente línea en el body y guárdalo con el nombre print.php.

Ejemplo:
<?php 
print(luis); 
?>

Resultado:

luis

Aquí es bueno hacer un alto y hablar de las "cadenas" o los "string's" ya que nos vamos a topar con ellas con bastante frecuencia. El ejemplo anterior imprimía "luis", porque era lo que estaba entre los paréntesis, pero si hacemos el siguiente ejemplo:

Ejemplo:
<?php
print(mi nombre es luis);
?>

Resultado:

Parse error: parse error in /localhost/print.php on line 2

Error!!... calma que no es para llamar a los bomberos. Otra de las características de PHP es que cuando se topa con un problema inmediatamente se detiene y nos dice en qué línea se produjo el error y qué tipo de error es. En este caso nos está diciendo que no sabe qué hacer con los caracteres que están dentro de los paréntesis. Trata de imprimir "mi" pero no conoce la función "nombre" y colapsa.

Nota:
Si no aparece el error en pantalla, hay que revisar la configuración de "php.ini" si está configurado para mostrar errores en pantalla. En ambientes en desarrollo es bueno tenerlo activado, en ambientes de producción, por seguridad, es buena idea que no esté activado.
Busca la línea display_errors = Off y déjala en On para que muestre los errores en pantalla.

Cadenas

Para corregir esta falla cuando trabajemos con texto es importante tratar de "agruparlo" en un sólo elemento encerrando el contenido dentro de comillas dobles. Esto es lo que se conoce como "cadenas".

Ejemplo:
<?php
print("mi nombre es luis");
?>

Resultado:

mi nombre es luis

Si ya tienes un texto con "mi nombre es luis" (puedes usar otro nombre si el tuyo no es luis), felicidades! ya has hecho tu primera línea de programación PHP.

Aquí vamos a hacer otro alto para incorporar un concepto más comunicacional que de programación. Programación inversa lo llamo, y es hacer el proceso inverso partiendo del resultado. Cómo quiero que se vea para después ver cómo se obtiene.

Como nuestro texto lo queremos incluir en una página Web escribamos primero el texto con los tags y estilos que le den su formato.

Ejemplo:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Mi</title>
<style type="text/css">
body h1 {
text-align: center;
font-size: 59px;
color: #990000;
}
</style>
</head>
<body>
<h1> mi nombre es luis </h1>
</body>
</html>

Resultado:

mi nombre es luis

Y ahora sustituimos el texto "mi nombre es luis" por el código PHP que estábamos trabajando arriba:

Ejemplo:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Mi nombre es</title>
<style type="text/css">
body h1 {
text-align: center;
font-size: 59px;
color: #990000;
}
</style>
</head>
<body>
<h1> <?php 
print("mi nombre es luis");
?> </h1>
</body>
</html>

Resultado:

mi nombre es luis

Si, ya sé, el resultado es el mismo, el texto al centro de la página y en color rojizo, pero la forma de ser generado es distinta, es dinámica, el texto "mi nombre es luis" lo interpretó el módulo de PHP del servidor. Claro que no tiene mucha gracia con este ejercicio puntual, pero nos vamos acercando a generarlo dinámicamente a través de elementos variables.

Si vemos el código fuente en la ventana que se abre, nos daremos cuenta que el código que presenta es puro HTML y el tag PHP print("mi nombre es luis") que escribimos en el documento ya no existe y fue interpretado por el módulo PHP en el servidor Apache y se quedó ahí. mostrándonos sólo el resultado, por eso es que a php se le llama un código "empotrado", ya que se inserta en medio del código HTML, es interpretado y sólo muestra el resultado.

Objetivo del capítulo:
Entender y comenzar a utilizar variables para diferentes operaciones dentro de la programación de una página PHP, así como los posibles resultados de su interpretación dependiendo del contexto en que se usan.

Definición

Esta parte siempre me cuesta explicarla porque las variables "varían", (valga la redundancia), son intangibles y por otro lado son fundamentales en todo los lenguajes de programación.

Veámoslo como un contenedor de información, un lugar que va a contener ciertos datos, (números enteros, decimales, cadenas, booleanos), que pueden ser redefinidos y al cual se puedan "tutear". Las variables son únicas por página y tienen valor sólo para la consulta puntual, a menos que las traslademos de una página a otra.

La gracia de las variables es que sustituyen líneas fijas de código. Usando el mismo ejemplo anterior de imprimir "mi nombre es luis": - ¿Qué pasa si tu nombre no es luis?, ¿La próxima persona que visita nuestra página se llama pedro o juan? Para cada posible nombre tendríamos que hacer una línea de programación... una locura.

En este ejercicio hay un elemento que sigue siendo constante: "mi nombre es " lo único que varía es el nombre. Pues bien, inventemos que "nombre" es el contenedor en el cual vamos a depositar el nombre que corresponda. De esa manera sólo tenemos que escribir una línea en vez de una por cada nombre:

Ejemplo:
<?php 
print("mi nombre es $nombre");
?>

Resultado:

mi nombre es

En PHP todas las variables comienzan con el símbolo peso ($) y a diferencia de otros lenguajes, no es necesario crearlas, declararlas o definirle el tipo (número , cadena o buleano) y más adelante veremos que puede contener más de un elemento.

El ejemplo anterior no escribe la frase completa porque $nombre no tiene valor. Es muy sencillo asignarle valor, basta con decirle que es igual a algo:

Ejemplo:
<?php 
$nombre="luis";
print("mi nombre es $nombre");
?>

Resultado:

mi nombre es luis

Cuatro elementos son importantes de considerar al momento de trabajar con variables:

  1. Las variables son temporales, duran mientras exista programación, una vez entregada la página, las variables desaparecen para liberar espacio de memoria RAM de servidor que es donde se alojan.
  2. Las variables son altamente reconocibles porque parten con el caracter "$"
  3. El signo igual ("=") asigna valor a la variable.
  4. EL nombre de las variables tienen que comenzar con una letra y no pueden tener espacios en su nombre. Esto quiere decir que las variable no pueden comenzar con un número.
  5. Las variables son sensibles a las mayúsculas y las minúsculas, por lo que $nombre y $Nombre son dos variables distintas.

Nota:
Como estamos trabajando con texto, acuérdate que es buena idea dejarlo como una "cadena", ya que el nombre podría ser "luis felipe" y nos volvería a arrojar error.

Una cosa interesante de las variables es que se puede redefinir su contenido igual de fácil a como se le asigna un valor.

Ejemplo:
<?php 
$nombre = "luis";
$nombre = "juan";
print("mi nombre es $nombre");
?>

Resultado:

mi nombre es Juan

Pero seguimos con el mismo problema con el que comenzamos este capítulo, el texto sigue siendo fijo.

El contenido de la página, a menos que lo cambiemos en el código, siempre va a mostrar el mismo texto: "mi nombre es juan". Pero como ahora estamos imprimiendo una variable $nombre, ésta se la podemos pasar por "query" en vez de definirla en el código.

Un "query" es un complemento a la dirección Web de una página. El mejor ejemplo es yahoo. Cuando nosotros hacemos una consulta en http://www.yahoo.com, por ejemplo, cuando buscamos "cualquiercosa", en la barra de dirección aparece:

Ejemplo:
https://espanol.search.yahoo.com/search?p=cualquiercosa

Lo que está a continuación del signo de interrogación es lo que se llama un "query", le dice a "search" que la variable "p" es igual a "cualquiercosa". De la misma manera le podemos decir a nuestra página "print.php" que la variable "nombre" tiene cierto valor.

Nota:
En la mayor parte de los lenguajes de programación existen caracteres que evitan que el código sea interpretado, de tal manera que el programador puede escribir textos de referencia sobre el código que está generando o, sin borrar, evitar que una línea de código sea interpretada. Esto es lo que se llama un "Comentario".

Comenta en la página "print.php" el código que define las variables con dos signos slash (//) para que no sean interpretadas por el módulo de PHP:

Ejemplo:
<?php 
//$nombre="luis";
//$nombre="juan";
print("mi nombre es $nombre");
?>

Aprovechemos de determinar el "origen de la variable" que queremos mostrar. Como en este caso queremos mostrar la variable que viene por la URL, o sea por el método GET, usamos la variable global $_GET[ ] (con mayúscula). Ya lo explicaremos con más detención.

Ejemplo:
<?php 
//$nombre="luis";
//$nombre="juan";
print("mi nombre es $_GET['nombre']");
?>

Si abrimos la página en un browser con la dirección del localhost aplicando los valores por "query" nuestra página debería sustituir la variable con el contenido de su valor.

Ejemplo:
http://localhost/print.php?nombre=sutano

Resultado:

mi nombre es sutano

Origen de la variable

Desde la aparición de PHP4.2, y por motivos de seguridad, se optó por desactivar la directiva register_globals en el archivo php.ini, que controla el comportamiento de PHP en el servidor.

Como PHP no requiere que las variables se inicialicen ni determinar su tipo, esto se presta para que a través de la URL se pasen valores a una variable, lo cual suele ser muy cómodo, pero se presta para que también se introduzcan códigos maliciosos. El valor de una variable de sesión, por ejemplo de seguridad, puede ser fácilmente inducido por la URL.

El tener la directiva register_globals en Off exige determinar el origen de la variable para su uso a partir de las matrices superglobales predeterminadas, quedando sólo las variables locales sin definición de procedencia.

Ejercicio:
  • Busca el archivo php.ini en tu computador. Por lo general está en el directorio C:\Windows. Como es un archivo de texto simple, ábrelo con Notepad o cualquier editor de texto simple. En él, busca register_globals y asegurate que esté en Off.

Las variables disponibles de entorno son:

$_SERVER[ ]
Variables definidas por el servidor web ó directamente relacionadas con el entorno en donde el script se esta ejecutando. Análoga a la antigua matriz $HTTP_SERVER_VARS.
$_POST[ ]
Variables proporcionadas al script por medio de HTTP POST. Análoga a la antigua matriz $HTTP_POST_VARS.
$_GET[ ]
Variables proporcionadas al script por medio de HTTP GET o por la URL como el ejercicio aplicado antes. Análoga a la antigua matriz $HTTP_GET_VARS.
$_SESSION[ ]
Variables registradas en la sesión del script. Análoga a la antigua matriz $HTTP_SESSION_VARS.
$_COOKIE[ ]
Variables proporcionadas al script por medio de HTTP cookies. Análoga a la antigua matriz $HTTP_COOKIE_VARS.
$_REQUEST[ ]
Variables proporcionadas al script por medio de cualquier mecanismo de entrada del usuario y por lo tanto no se puede confiar en ellas. La presencia y el orden en que aparecen las variables en esta matriz es definido por la directiva de configuración variables_order. Esta matriz no tiene un análogo en versiones anteriores a PHP 4.1.0.
Una matriz asociativa que consiste en los contenidos de $_GET, $_POST, y $_COOKIE
$_FILES[ ]
Variables proporcionadas al script por medio de la subida de archivos via HTTP . Análoga a la antigua matriz $HTTP_POST_FILES.
$_ENV[ ]
Variables proporcionadas al script por medio del entorno. Análoga a la antigua matriz $HTTP_ENV_VARS.
$GLOBALS[ ]
Contiene una referencia a cada variable disponible en el espectro de las variables del script. Las llaves de esta matriz son los nombres de las variables globales. $GLOBALS existe desde PHP 3, aunque en PHP 5.6 su uso se a limitado.

Ocupemos una función de PHP parecida a la última utilizada: print_r(). Esta función nos permite ver el contenido de una Matriz, que ya estudiaremos más adelante.

Veamos los valores que se encuentran en la matriz global con la función de PHP print_r().

Ejemplo:
<pre>
<?php
print_r($GLOBALS)
?>
</pre>

Resultado:

Array
(
[_GET] => Array
(
)
[_POST] => Array
(
)
[_COOKIE] => Array
(
)
[_FILES] => Array
(
)
[GLOBALS] => Array
*RECURSION*
)

Operaciones con variables

Ahora que ya tenemos las variables y sabemos como asignarle valor, comenzamos a realizar operaciones matemáticas básicas con ellas. Sí, ya sé, las matemáticas no son el fuerte de los comunicadores. Muchos se deprimen rápidamente con este capítulo y se olvidan de seguir programando, (yo soy de los primeros en la fila). Vamos despacio, revisemos las cuatro operaciones matemáticas básicas y veremos que no es tan difícil.

Suma

Ejemplo:
<?php 
$a="10";
$b=5;
$c=$a+$b;
print($c);
?>

Resultado:

15

En este ejemplo se define un valor de 10 a la variable $a y un valor de 5 a la variable $b. La suma de $a más $b, o sea 10 más 5 le da valor de 15 a $c.

Nota:
Observemos que la variable $a es una cadena de texto 10 por estar encerrado entre comillas y la variable $b es un número entero, si bien en otros lenguajes de programación la operación de ambas variables no se puede realizar porque no se han definido como del mismo tipo, para PHP todas son cadenas y puede realizar operaciones matemáticas siempre y cuando su contenido sean números.

Resta

Ejemplo:
<?php 
$a="10";
$b=5;
print ($a-$b);
?>

Resultado:

5

No es necesario asignar el resultado de la operación a una variable. Se puede imprimir directamente la operación entre las dos variables definida al principio. De ésta manera se resuelve la operación y se escribe el resultado.

Multiplicación

Ejemplo:
<?php 
$a="10";
$b=5;
print $a * $b;
?>

Resultado:

50

Como print() no es completamente una función, si no más bien una orden, se acepta su uso sin paréntesis.

División

Ejemplo:
<?php 
$a="10";
$b=5;
echo $a / $b;
?>

Resultado:

2

Al igual que print(), la función echo(), permite una salida a pantalla. Muchos programadores la prefieren ya que se pueden imprimir, en una sola línea, varias cadenas separadas por coma.

Ejemplo:
<?php 
$a=10;
$b=5;
echo $c= $a / $b, "<br>", $a + $c, "<br>", ($a -$b) * $a + $c;
?>

Resultado:

2
12
52

Nota:
Nótese que en este ejemplo escribimos <br> que es un tag de HTML para hacer saltos de línea, de esta manera estamos incorporando en la salida a pantalla comando que el browser puede interpretar.

Después de haber paseado por las cuatro operaciones básicas, aprovechando de jugar con algunas formas de "imprimir" los resultados, salta la pregunta ¿y todo esto para qué?

Para darle algún sentido a las matemáticas y a la lógica del paso a paso que estamos dando en este manual, plantémonos una meta: Construyamos el sistema de Venta en Línea de una empresa.

La empresa Rayitas S.A., manufacturera nacional de rayas de todo tipo, está preparándose para exportar sus productos y te ha encargado la realización de un sistema de venta en línea sobre Internet para llegar a más clientes y sobre todo en el extranjero.

Como hemos estado trabajando con el sistema de "programación inversa", comencemos con el final del proceso: la boleta de la venta de dos rayas verticales a mil pesos.

Ejemplo:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Tienda Virtual - Rayitas S.A.</title>
</head>
          
<body>
<header>
<h1>Tienda Virtual<br>
<small>Rayitas S.A. </small></h1>
</header>
<table width="100%" border="0" cellspacing="0" cellpadding="2">
<thead>
<tr>
<th>Producto</th>
<th>Precio</th>
<th>Cantidad</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr>
<td>Rayas Verticales</td>
<td>1000</td>
<td>2</td>
<td>2000</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>IVA</td>
<td>380</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>TOTAL</td>
<td>2380</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
</body>
</html>
Boleta de compra en HTML
Boleta de compra en HTML

Primero diseñemos la tabla de un informe completo, para no causar confusión al posible comprador, donde se detalle el precio unitario, cantidades, total y los impuestos correspondientes de esta transacción y llamemos a ese archivo boleta.php.

Sin fijarse por el momento en el diseño, aunque es sumamente importante en nuestro trabajo final, hemos creado una tabla básica que entrega la compra final de dos rayas verticales a mil pesos cada una. Ahora convirtamos en variables todos los elementos que van a ser dinámicos y que por el momento los tenemos estáticos, por ejemplo el precio y las cantidades.

Seleccionemos el texto 1000 del precio y sustituyámoslo por una variable $_GET['precio'] (acordémonos de el origen de la variable), de la misma manera seleccionemos el texto 2 de la celda de cantidades y sustituyámoslo por un texto de variable $_GET['cantidad'] y como lo que queremos es hacer una salida a pantalla, aprovechemos de agregarle un texto echo antes de ambas variables.

Sustituyendo por variables
Sustituyendo por variables

De la misma manera que modificamos las cantidades por una variable. Ahora modifiquemos el subtotal a una variable. El subtotal es el resultado de la multiplicación de la cantidad de rayas verticales por el precio de ellas. Quedaría cómo:

Ejemplo:
echo $_GET['precio'] * $_GET['cantidad']; 

Ahora, para que sea interpretado por el servidor, encerremos los textos modificados en los tag de PHP <?php ?>.

Bien!, ya convertimos en código PHP la primera línea, y antes de seguir, es buena idea probar como vamos hasta el momento.

Visualización del código interpretado
Visualización del código interpretado

Si el resultado es 0 y no se ve nada en precio y cantidad, estamos bien, ya que no le hemos asignado valores ni a cantidad, ni a precio. Agreguemos los parámetros precio y cantidad, con sus valores, en la línea de query. Pongamos entonces precio = 1000, cantidad = 2 en el query de la dirección URL.

Ejemplo:
http://localhost:8888/boleta.php?precio=1000&cantidad=2

Y ahora, si activamos la vista en vivo o refrescamos, nos vamos a encontrar con que las variables se alimentan del "query" y nos entrega hasta la operación del subtotal.

Alimentando las variables por query
Alimentando las variables por query

Ahora vamos con la segunda línea, los no siempre bien apreciados impuestos. En Chile se aplica el 19% de IVA (impuesto al valor agregado), por lo que necesitaremos sacar el 19% al total del resultado entre la multiplicación del precio y la cantidad, variable que llamamos "subtotal".

Aquí una pausa y un poco de proyección. Si nos adelantamos un poco, la operación final del TOTAL de nuestra boleta va a ser algo cómo:

Ejemplo:
($_GET['precio'] + $_GET['cantidad'])*.19 + ($_GET['precio'] + $_GET['cantidad'])

Nos podemos facilitar un poco la vida si asignamos resultados de operaciones a variables que podamos usar después, en vez de tener que volver a realizar la operación matemática.

Quedaría algo como:

Ejemplo:
 <tr>
<td scope="row">Rayas Verticales</td>
<td><?php echo $precio=$_GET['precio']?></td>
<td><?php echo $cantidad=$_GET['cantidad']?></td>
<td><?php echo $subtotal=$precio * $cantidad?></td>
</tr>
<tr>

Ahora sí, de la misma manera que trabajamos las líneas superiores, primero sobre escribamos en el área de diseño la operación del IVA y después lo convertimos en código PHP.

Calculando el IVA
Calculando el IVA

Si volvemos a seleccionar el botón "Live" , vamos a tener el IVA del "subtotal". Otra vez hemos puesto el total del IVA en una variable porque en la siguiente línea lo vamos a utilizar en el total, ya que el total general de nuestra boleta es la suma del "subtotal" con el "IVA".

Nota:
Recuerda que la multiplicación por un decimal es con el "punto decimal" y no con la coma.

Ejercicio:
  • Utilizando el proceso anterior: completemos el cambio a variables de la fila "Total", dónde $total es igual a $subtotal más $iva.
Calculando el total
Calculando el total

¡Felicidades! ya tenemos una boleta que realiza y muestra las variables involucradas en la compra de 2 rayas verticales, pero que también pueden ser 9 rayas verticales a 900 pesos cada una, ya que está construido en base a variables que se pasan por la URL.

Ejercicio:
  • Agreguemos al mismo archivo boleta.php el precio de envío de las rayitas que es de $5,000 pesos antes del IVA y una línea de "subtotal" de la operación.

Concatenación

Hemos visto que no es tan complicado sumar dos variables numéricas o restarlas, pero ¿Qué pasa cuando lo que queremos es sumar dos cadenas de texto?.

Ejemplo:
<?php 
$a="abre";
$b="latas";
$d = $a + $b;
echo $d;
?>

Resultado:

0

Si da cero está bien, aunque no nos suene lógico, ya que el signo más (+) suma y su resultado es siempre matemático. Si queremos juntar dos cadenas se llama concatenarse, o sea unir, que no es lo mismo que sumar, y, a diferencia de otros lenguajes de programación, esto no se puede hacer con el signo más. Para concatenar dos variables en PHP se ocupa el caracter punto (.) .

Ejemplo:
<?php 
$a="abre";
$b=latas;
$d = $a . $b;
echo $d;
?>

Resultado:

abrelatas

Es importante entender el concepto de "concatenación" ya que probablemente vamos a querer unir varios procesos en una cadena de salida. Por ejemplo queremos explicar que la suma de dos variables $a y $b da 15.

Uso de comillas

Sin comillas

Ejemplo:
<?php 
$a=10;
$b=5; 
$c= $a + $b;
echo $a + $b = $c;
?>

Resultado:

25

25 está bien, ya que es 10 más 15 porque $b es igual a $c y $c es el resultado de $a más $b. Pero no resuelve el problema de tener que explicar que la suma de dos variables da otra.

Con comillas

Ejemplo:
<?php 
$a=10;
$b=5; 
$c= $a + $b;
echo "$a + $b = $c";
?>

Resultado:

10 + 5 = 15

Una variable dentro de comillas doble se interpreta pero no se opera, en este caso vemos los valores de las variables y además los caracteres más (+) e igual (=) porque no se está realizando operación. Es interesante manejar el concepto, pero no nos resuelve el problema puntual ahora, de querer mostrar que la suma de dos variables da 15.

Con comillas simples

Ejemplo:
<?php 
$a=10;
$b=5; 
$c= $a + $b;
echo '$a + $b = $c';
?>

Resultado:

$a + $b = $c

Por el contrario, una variable dentro de comillas simples se lee tal cual, no se interpreta. Para nuestro objetivo, tampoco resuelve completamente, por lo que vamos a tener que usar una combinación de los casos anteriores, donde trabajemos con comillas simple lo que queremos que se lea tal cual y con comillas dobles o sin comillas lo que queremos que se interprete. Para unir ambas características, tendremos que concatenar los dos fragmentos.

Ejemplo:
<?php 
$a=10;
$b=5; 
echo '$a + $b ='.  ($a + $b);
?>

Resultado:

$a + $b =15

O también podríamos hacer uso de los caracteres especiales o caracteres inversos.

Caracteres de escape

Los caracteres de escape o caracteres inversos, son caracteres que cuando están después de una barra invertida, dentro de comillas dobles, tienen una interpretación inversa.

En el ejemplo anterior. El signo $ seguido de la a es interpretado dentro de comillas doble como el valor de la variable, a menos que le digamos a PHP que lea el signo peso como carácter y no como una variable con la barra invertida.

Ejemplo:
<?php 
$a=10;
$b=5; 
$c= $a + $b;
echo "\$a + \$b = $c";
?>

Resultado:

$a + $b = 15

Nota:
El carácter inverso sólo funciona dentro de comillas dobles ya que tiene que ser "interpretado"

Tiene mucho más sentido si queremos construir una frase como:

Ejemplo:
<?php 
$a=10;
$b=5; 
echo "el valor de \$a es \"$a\"";
?>

Resultado:

el valor de $a es "10"

Donde las comillas dobles también están con la barra invertida para que no se interpreten, sino que se impriman.

Caracteres de escape

Secuencia

Significado

\n

Nueva línea

\r

Retorno de carro

\t

Tabulación horizontal

\\

Barra invertida

\$

Signo del dólar

\"

Comillas dobles
Ejercicio:
  1. Agreguemos el signo peso ($) en los resultados de la operación.
  2. Con la función number_format() démosle formato a los números, como no hemos hablado de ella, es buen momento de buscarla en http://www.php.net y aprender como es su uso y funcionalidad.

Objetivo del capítulo:
Entender y comenzar a utilizar estructuras de control en medio de un código PHP para la variabilización de los resultados.

Muchas de las cosas que vayamos a programar en PHP se leerán de manera secuencial, pero a veces estarán sujetas a valores pre existentes. Por ejemplo, el trato con el usuario será "Señor" o "Señora", dependiendo del género de nuestro cliente.

Dependemos entonces que una condición sea verdadera para que imprima una u otra opción. Una forma de hacerlo es comparando un elemento con otro y va a ser más fácil si lo hacemos con lógica matemática.

Operadores de comparación
Operador Nombre Uso Descripción

==

Igual $a == $b $a es igual $b

!=

Distinto $a != $b $a es distinto $b

<

Menor que $a < $b $a es menor que $b

>

Mayor que $a > $b $a es mayor que $b

<=

Menor o igual $a <= $b $a es menor o igual que $b

>=

Mayor o igual $a >= $b $a es mayor o igual que $b

Nota:
Suele pasar que usamos el operador "=" para comparar una igualdad en vez de "==", recuerda que con "=" asignábamos valor dentro de una variable, por lo que la variable tendría un "valor", y si tiene valor es siempre verdadera.

Condicionar

La función if() pertenece a las estructuras de control de un documento y va a realizar una acción si es que la condición a evaluarse (o sea lo que está entre los paréntesis) es verdadera.

Ejemplo:
<?php 
$a=10;
$b=5; 
if ($a > $b) echo "Es verdadero";
?>

Resultado:

Es verdadero

A veces es necesario ejecutar más de una acción bajo la misma condición. En vez de volver a condicionar para cada línea, se pueden agrupar en un sólo "bloque" de sentencias encerrando en corchetes estas acciones después de la condición.

Ejemplo:
<?php 
$a=10;
$b=5; 
if ($a > $b){
echo "\$a es mayor que \$b";
$c= $a * $b;
echo "<br> y la multiplicación da ".$c;
}
?>

Resultado:

$a es mayor que $b
y la multiplicación da 50

En este ejemplo se verificó que $a fuera mayor que $b, como la condición es verdadera, imprime en pantalla $a es mayor que $b, asigna a $c el resultado de la multiplicación de 10 por 5 y lo imprime después de un tag <br> de salto de línea en HTML.

Si no se cumple

Si la condición no se cumple en el ejemplo anterior, simplemente no imprime ningún contenido, a menos que le digamos que realice alguna acción si es que la consulta no es verdad, o sea un "si no" ( } else { ).

Ejemplo:
<?php 
$a=10;
$b=5; 
if ($a < $b){
echo "si es verdadero";
$c=$a+$b;
echo "\$c es igual a $c";
} else {
echo "no es verdadero";
}
?>

Resultado:

no es verdadero

Combinación

La función elseif() es una combinación de los tipos de las funciones anteriores if() y else.

Se ocupa para hacer una nueva evaluación en caso de que el if() inicial se evalúe como falsa y también va entre los corchetes que encierran bloques de acciones.

Ejemplo:
<?php 
$a=10;
$b=10; 
if ($a > $b) {
echo "\$a es mayor que \$b";
} elseif ($a == $b) {
echo "\$a es igual que \$b";
} else {
echo "\$a es menor que \$b";
}
?>

Resultado:

$a es igual que $b

Nota:
En caso de querer anidar muchas condicionales elseif() es preferible usar la función switch() que reacciona más rápido que muchos if() juntos.

Ahora que ya manejamos el concepto de condicionales, retomemos el archivo boleta.php.

Supongamos que nuestro cliente ha decidido lanzar una promoción en sus ventas y por la compra de más de $50,000 pesos va a asumir los costos del envío y sólo cargar $2,000 de envío por compras superiores a $25,000 pesos. Por lo tanto los "precio de envío" van a estar sujetos al subtotal de las ventas. Pongámoslo antes del impuesto.

Ejemplo:
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td align="right">env&iacute;o</td>
<td align="right"><?php 
if($subtotal > 50000){
$envio=0;
} elseif($subtotal >25000){
$envio=2000;
} else {
$envio=5000;
}
echo $envio;?> </td>
</tr>
Condicionando el costo de envío
Condicionando el costo de envío

Operadores lógicos

A veces dentro de una consulta queremos que se cumplan dos condiciones. Qué sea a y b al mismo tiempo, o que la condición sea a o b. La capacidad de poder incluir estás condiciones se llama operadores lógicos or y and.

&&

El operador && (and) se encarga de verificar que las dos condiciones a evaluarse sean verdaderas, o sea, si una de las dos condiciones es falsa, la expresión completa se considera falsa.

Ejemplo:
<?php 
$a= "abre";
$b= "lata";
if($a== "abre" && $b <> "lata"){
echo "las dos condiciones son verdaderas porque \$a es igual a  \"abre\" y \$b es $b que no es igual a \"lata\"";
} else {
echo "la condición no es verdadera porque \$b no es distinto a \"lata\"";
}
?> 

Resultado:

la condición no es verdadera porque $b no es distinto a "lata"

||

El operador || (or) se encarga de evaluar que una o la otra opción a evaluarse sea verdaderos para que toda la condición sea verdadera.

Ejemplo:
<?php 
$a= "abre";
$b= "lata";
if($a== "abre" || $b <> "lata"){
echo "la condición es verdadera  porque \$a es igual a  \"abre\" o \$b  no es igual a \"lata\"";
} else {
echo "la condición no es verdadera porque \$b no es distinto a \"lata\"";
}
?> 

Resultado:

la condición es verdadera porque $a es igual a "abre" o $b no es igual a "lata"
Ejercicio:
  • Agreguemos en boleta.php una fila más de descuento del 10% por compras superiores a 50,000 pesos, pero que no sea visible el concepto de descuento si es que la compra es inferior o sea que la fila completa no sea visible si es que no hay descuento. Recuerda ponerlo siempre antes del IVA.
Descuento
Descuento

Objetivo del capítulo:
Entender el concepto y usar las matrices o variables multidimensionales para tener varios valores en un contenedor dinámico.

Hemos hablado de las variables como contenedores de información. Esta información puede ser un número, un texto pero también pueden ser contenedores de "varios datos". O sea más de una cadena dentro de una variable. A esto se le llama Array, matrices o arreglos, en otros lenguajes de programación se los conoce como listas.

Arreglos

Las matrices o arreglos en PHP, a diferencia de otros lenguajes de programación dinámicos, se presentan igual que las variables, parte su nombre con un signo peso seguido de cualquier letra. Es el sistema el que distingue su contenido. Basta utilizar la función array() antes de los valores y separar los contenidos por coma. Al igual que las variables sencillas, las matrices son temporales y viven sólo en la ejecución.

Ejemplo:
<?php 
$var = array("uno", $dos=2, tres, "3+1", $dos+3, number_format(6,2));
echo $var;
?>

Resultado:

Array

Si el resultado es "Array" está bien, porque está diciendo que la variable "var" tiene varios elementos y hay que definir cuál de ellos se quiere imprimir. Como cada elemento dentro de un arreglo tiene una posición, se puede pedir que imprima una en específico, definiéndola entre corchetes cuadrados:

Ejemplo:
<?php 
$var= array("uno", $dos=2, tres, "3+1", $dos+3, number_format(6,2));
echo $var [1];
?>

Resultado:

2

Si nos fijamos en el ejemplo, las posiciones de elementos dentro de un arreglo parten por el 0, no por el 1 a que estamos acostumbrados. Otro elemento interesante es el hecho que dentro de un arreglo podemos meter cualquier tipo de cadena o número y hasta operaciones matemáticas dentro de un arreglo.

Ejercicio:
  1. Imprime todos los elementos del arreglo $var definido por su posición.
  2. Prueba imprimir el arreglo con la función print_r().

Elemento dentro de un arreglo

Todo arreglo está compuesto de dos elementos. Una clave o key, que si no es definida por el usuario, se va a numerar automáticamente según su posición, como vimos con el ejemplo del print_r(), y un valor para esa clave. Por ejemplo podemos definir en un arreglo cuantas rayas de nuestra empresa Rayita S.A. quedan en stock.

Ejemplo:
<?php 
$stock = array("horizontales" => 2, "verticales" => 4, "diagonales" =>5, "curvas" => 3);
print_r($stock);
echo "<p>", "quedan ".$stock['horizontales']." líneas horizontales";
?>

Resultado:

Array (
[horizontales] => 2
[verticales] => 4
[diagonales] => 5
[curvas] => 3
)
quedan 2 líneas horizontales

Como muestra el ejemplo anterior, podemos imprimir un valor de un arreglo directamente por el nombre de su clave. Y como tiene un nombre, también podemos resignar un valor a uno de los componentes:

Agregar

También podemos agregar elementos a un arreglo con una clave o sin ella, dejando que el sistema le auto asigne una clave.

Ejemplo:
<pre>
<?php 
$stock=array("horizontales" => 2, "verticales" => 4, "diagonales" =>5, "curvas" => 3);
print_r($stock);
echo "<p>";
$stock['punteada']=9;
print_r($stock);
?>
</pre>

Resultado:

Array (
[horizontales] => 2
[verticales] => 4
[diagonales] => 5
[curvas] => 3
)
Array (
[horizontales] => 2
[verticales] => 4
[diagonales] => 5
[curvas] => 3
[punteada] => 9
)

Modificar

Ejemplo:
<pre>
<?php 
$stock = array("horizontales" => 2, "verticales" => 4, "diagonales" =>5, "curvas" => 3);
print_r($stock);
echo "<p>";
$stock['verticales']=18;
print_r($stock);
?>
</pre>

Resultado:

Array (
[horizontales] => 2
[verticales] => 4
[diagonales] => 5
[curvas] => 3
)
Array (
[horizontales] => 2
[verticales] => 18
[diagonales] => 5
[curvas] => 3
)

Aquí hemos modificado el valor asignado a la clave "verticales" y de 4 le hemos reasignado el valor 18, dentro del arreglo $stock.

Eliminar

Si por el contrario, lo que queremos hacer es eliminar un elemento del arreglo, basta con usar la función unset():

Ejemplo:
<pre>
<?php 
$stock=array("horizontales" => 2, "verticales" => 4, "diagonales" =>5, "curvas" => 3);
print_r($stock);
echo "<p>";
unset($stock['horizontales']);
print_r($stock);
?>
</pre>

Resultado:

Array (
[horizontales] => 2
[verticales] => 4
[diagonales] => 5
[curvas] => 3
)
Array (
[verticales] => 4
[diagonales] => 5
[curvas] => 3
)

Nota:
La función unset() también se puede utilizar con variables que no son matrices.

Los arreglos son importantes en PHP porque las consultas a bases de dato siempre van a regresar como matrices. Es importante saber cómo llamar a un elemento en especial, agregar, modificar o eliminar elementos del arreglo. A esto le llamaremos CAME, y en general las páginas dinámica se orienta en entender estas cuatro acciones (Consultar, Agregar, Modificar, Eliminar).

Ejercicio:
  1. Define el resultado de la función count().
  2. Prueba la función array_keys() con el mismo arreglo y explícala.
  3. Prueba la función array_rand() en el mismo arreglo que hemos estado trabajando e imprime su resultado.

Objetivo del capítulo:
Conocer y utilizar algunas estructuras de control relacionadas con la repetición automatizada de pedazos de código en una página PHP.

Los bucles son condicionales que van a repetir una acción determinada mientras el valor a evaluar sea verdadero. Tiene la ventaja de ahorrar mucho en la escritura de un texto, al determinar las "constantes" de la operación.

Hay básicamente 3 tipos de bucles:

Función while()

Traducido al español significa "mientras". Mientras la condición a evaluarse sea verdadera se repetirá un bloque de acciones definidas. Como estamos hablando de bloque vamos a encerrar entre corchetes las acciones, { y }.

Ejemplo:
<?php 
$i=1;
while($i <= 10){
echo $i."<br>";
$i++;
}
?>

Resultado:

1
2
3
4
5
6
7
8
9
10

En este ejemplo, se va a imprimir el valor de $i mientras sea menor o igual a "10". Para que el bucle no sea eterno, se agrega el $i++ que está incrementando en uno el valor $i cada vuelta dentro del bucle.

Una pequeña variación sobre esta misma función, primero realiza el bucle con do y después consulta la condición a evaluar al final de cada iteración.

Ejemplo:
<?php 
$i=10;
do{
echo $i."<br>";
$i--;
} while($i >=1);
?>

Resultado:

10
9
8
7
6
5
4
3
2
1

Función for()

for() es una función un poco más compleja que la función while(), pero funciona de manera similar. for() plantea el punto de partida, los parámetros a evaluar y la modificación en una sola línea. Tiene la ventaja, por un lado, que es más difícil generar un bucle eterno, y por otro lado que se ahorra en código al escribir.

Ejemplo:
<?php 
for($i=1;$i<=10;$i++){
echo $i."<br>";
}
?>

Resultado:

1
2
3
4
5
6
7
8
9
10

Los tres parámetros que ocupa son:

  • Un punto de partida.
  • Un elemento a evaluar la condición.
  • El incremento.

O sea, léase: Desde que la variable $i es igual a 1, mientras que la variable $i sea menor o igual a 10,incrementándose de uno en uno.

Nota:
A diferencia de otras funciones, los parámetros en la función for() se separan siempre con punto y coma ;.

Ejercicio:
  • Hacer una salida a pantalla de 1000 veces de la frase "debo hacer más preguntas en clases o me ponen a hacer tareas ridículas". Utiliza la función for().

Usando las funciones for() o while() se podría imprimir en pantalla los elementos de una matriz.

Ejemplo:
<?php 
$stock = array('horizontales' => 2, 'verticales' => 4, 'diagonales' =>5, 'curvas' => 3);
$claves = array_keys($stock);
$i = 0;
$cantidad = count($stock);
while($i<$cantidad){
echo "quedan " . $stock[$claves[$i]] . " rayitas " .$claves[$i] . "<br>";
$i++;
}
?>

Resultado:

quedan 2 rayitas horizontales
quedan 4 rayitas verticales
quedan 5 rayitas diagonales
quedan 3 rayitas curvas

Función foreach()

foreach() es otra condicional interesante, aunque está orientado directamente a elementos de un arreglo. Esta función aplica un bloque de acciones para cada elemento de la matriz que se define como valor.

Ejemplo:
<?php 
$stock = array('horizontales' => 2, 'verticales' => 4, 'diagonales' =>5, 'curvas' => 3);
foreach ($stock as $valor) {
echo $valor, "<br>";
}
?>

Resultado:

2
4
5
3

Con los foreach() también se pueden sacar las claves de un arreglo al mismo tiempo de definir su valor usando el operador => igual que cuando definimos los contenidos de un key => value de un arreglo.

Ejemplo:
<?php 
$stock = array('horizontales' => 2, 'verticales' => 4, 'diagonales' =>5, 'curvas' => 3);
foreach ($stock as $clave => $valor) {
echo "quedan $valor rayitas $clave <br>";
}
?>

Resultado:

quedan 2 rayitas horizontales quedan 4 rayitas verticales quedan 5 rayitas diagonales quedan 3 rayitas curvas

Con la función foreach() hemos logrado lo mismo que con el ejemplo anterior de while(), pero sin necesitar tantas consultas.

Ejercicio:
  • Alimentemos boleta.php, a partir de una matriz en la misma página, en la cual se vendan 16 rayitas horizontales a 1000 pesos cada una, 7 rayitas verticales a 1200 pesos cada una y 13 rayitas curvas a 2500 pesos cada una.Boleta alimentada desde una matriz

Objetivo del capítulo:
Entender y utilizar las funciones para incorporar dentro de una programación el código generado en otra página.

Si bien no es parte de los elementos básicos de la programación como los capítulos anteriores, estas funciones se ocupan mucho en el proceso de realización de sitios grandes cuando se trabaja por fragmento y reciclando código.

El incluir un archivo dentro de otro con la función include() es muy útil a la hora de tener diseños comunes en una página o fragmentos de programación que se van a utilizar con frecuencia. Tiene la ventaja además de que, si se necesita modificar, es sólo uno el archivo que se tiene que afectar.

Por ejemplo, en la mayor parte de las páginas se suele poner un pie de página con la fecha de modificación, derechos de autor y contacto con el webmaster. Generemos una página HTML sencilla que se llame pie.php.

Pie de página
Pie de página
Ejemplo:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Untitled Document</title>
<link href="rayita.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="pie">2007 &copy; Rayitas S.A.<br />
<a href="mailto: webmaster@rayitas.cl">webmaster</a>
</div>
</body>
</html>

Función include()

Como esta página la queremos insertar dinámicamente en otras, tenemos que evitar que se repitan los tags HTML innecesarios. Eliminemos entonces, todos los tags HTML del head y body, de tal manera que queden sólo los tags correspondientes al pie de página.

Ejemplo:
<div id="pie">2007 &copy; Rayitas S.A.<br />
<a href="mailto: webmaster@rayitas.cl">webmaster</a>
</div>
Pie de página
Pie de página

Guardemos el archivo y abramos boleta.php. Al final de la página, después de todo el texto, antes del tag </body> escribe pie.php, en el área de código, entre comillas dobles.

En la paleta de objetos selecciona los objetos PHP. con el texto pie.php seleccionado, aprieta el botón "include". Este va a introducir un código php que va a incluir el contenido de la página dentro de la otra.

Incluir en archivo
Incluir en archivo

Nota:
Asegúrate de encerrar entre comillas, dobles o simples, el nombre del archivo y con la ruta relativa completa.

Ejemplo:
<? include("pie.php"); ?>
Pie de página
Pie de página

Si el documento a incluir estuviera en otro directorio, basta con dar la dirección relativa hasta él.

Función require()

La función require(), trabaja de manera similar a include() con la diferencia de la forma en que manejan las fallas al momento de no encontrar el archivo especificado entre paréntesis.

include() produce una advertencia (Warning) mientras que require() ante la falla produce un error fatal (fatal error). En otras palabras, include() advierte de la falla pero sigue el proceso mientras que require() detiene todos los procesos porque no encontró el archivo "requerido".

Funciones include_once() y require_once()

Los anexos once en ambas funciones, obligan a que se incluya o requiera una sola vez en el transcurso del script, quiere decir que si hacemos un include() al principio del documento, y por error lo volvemos a incluir al final de la página, el segundo no se va a procesar. Suele usarse cuando estamos incluyendo otros script PHP que pueden tener incluidos, a su vez, procesos que se requieren una sola vez.

Ejercicio:
  • Generemos 3 archivos e incorporar los 3 archivos en boleta.php:
    cabecera.php
    Que tenga toda la información de cabecera del documento (estructura, título y bajada de la página).
    pie.php
    Que tenga toda la información de contacto y derechos de autor.
    menu.php
    Que te permita recorrer el sitio y acceder a los archivos del sitio que construiremos (Hasta el momento tenemos la página boleta.php que lo requiere, pero ya iremos incorporándolos en más páginas).

Objetivo del capítulo:
Repasar y utilizar los elementos de formulario de HTML en la comunicación entre páginas PHP y la recuperación de información que el usuario nos entrega.

Alerta:
Tódo el capítulo de formularios y métodos se ha pasado al manual de HTML que es donde pertenece.
https://html.luisfel.com/

Hasta aquí un alto y resumen de lo que hemos revisado. Es importante, para lo que vamos a realizar más adelante que queden claro 4 conceptos:

  • Variables.
  • Condicionales.
  • Matrices.
  • Bucles.

Si estos 4 conceptos están claros y se entienden podemos seguir con la segunda parte de este manual, si no, es necesario repasar de nuevo los capítulos anteriores para tenerlos claros.

No es el objetivo ser experto en la materia, pero si saber distinguir una variable porque comienza con el signo peso ($) o diferenciar una función que termina con paréntesis (( )) de un bloque de acciones que ocupa los corchetes ({ }) o de un elemento de una matriz que se llama con los corchetes cuadrados ([ ]), el resto lo va a ir entregando la experiencia de estar haciendo y la disciplina de estar revisando el código y preguntando en http://www.php.net lo que no se conoce.

resumen 4x4
Resumen 4x4

Objetivo del capítulo:
Conocer, generar y administrar bases de dato y tablas desde una aplicación de entorno gráfico como phpMyAdmin entendiendo la necesidad de definir bien los tipos de campo a utilizar y algunos elementos de seguridad.

Entremos en otra materia. Hasta ahora tenemos resuelto la boleta de compra, pero no sabemos qué está comprando, lo ideal en nuestra tienda virtual y en el proceso de este manual es diseñar dos páginas más. Una que nos muestre la lista de productos que se ofrecen y otra que dé más detalles del producto.

En este sentido, vamos a partir diseñando nuestra primera página index.php, en la cual pondremos la lista de productos y algunos detalles promociónales, para luego armar la página de producto.php donde se desplegará la información del producto seleccionado y la instancia de compra que vincule a la boleta y formulario que ya tenemos. Recuerda incluir además del pie.php, el menu.php para poder navegar entre las páginas.

Master Detail Rayitas S.A.
Master Detail Rayitas S.A.

El diseñar estas dos páginas es una buena manera de poder saber qué datos vamos a necesitar administrar, por ejemplo, sabemos que necesitamos:

  • Nombre
  • Código
  • Categoría
  • Frase promocional
  • Descripción
  • Colores
  • Precio
  • Disponibilidad
  • Promoción
  • Fecha

Definición de Base de dato MySql

Estas páginas fijas que diseñamos las podríamos hacer dinámicas sacando los datos en archivos de texto, después de todo los datos tabulados son una "base de dato". La diferencia con una base de dato profesional, es que estos datos tabulados, además deberían estar indexados y con la capacidad de relacionarse con otros datos, para poder acceder a ellos y no sólo almacenarlos.

MySql es un servidor de base de datos relacionales que nace por necesidades de la empresa sueca TcX y que ahora se distribuye como "código abierto" por lo que generalmente es de distribución liberada.

Aunque viene del mundo Linux, ya son varios los sistemas operativos en los que se puede instalar, haciéndola multiplataforma por defecto.

La diferencia con los archivos de texto separado por punto coma, es que es capaz de aceptar lenguaje SQL standard (ANSI SQL92) para realizar búsquedas en dos ejes: por columnas de datos similares o dentro de filas a las que además se restringe el acceso sólo para usuarios identificados.

Las bases de dato no son una hoja Excel, pero es un excelente ejemplo para graficarlo. Los datos se ordenan por columnas, donde todos los datos de cada columna se ordenan bajo el mismo criterio. Al tener los datos ordenados reacciona más rápido ante consultas que se le hagan y permite relacionar los datos de dos o más columnas.

Estructura BD
Estructura BD

Cuando hablamos de datos relacionados, estamos diciendo que se pueden complementar los datos de una tabla con otra. Pongamos un ejemplo: en la acción de pagar impuestos somos usuarios únicos, y si queremos identificarnos para un trámite comercial usamos el mismo número único, el RUT. No es que las dos actividades se hagan en el mismo dato o se registren en la misma tabla, sólo usamos el RUT como llave única para hacer la relación en ambos trámites. En Bases de dato, esto es lo que se llama relacional.

Las Bases de dato están compuestas de tablas. Cada tabla aloja datos en filas únicas, dentro de cada fila hay campos que contienen los datos. Estos datos pueden ser de diferente tipo (números, fechas, texto). Al momento de crear las tablas, se define el "tipo" de columna para los datos que se van a alojar y esto ayuda a aumentar la velocidad de respuesta de MySql.

En resumen MySql no es una base de datos, sino un sistema de adminis-tración de bases de datos relacionales, robusta, rápida, multi-plataforma, segura y de distribución liberada.

Creación de BD, usuario y tablas con phpMyAdmin

Existen varias interfaces para generar, controlar y modificar una tabla en MySql. Una de ellas es phpMyAdmin. A diferencia de otras aplicaciones, phpMyAdmin no es un software sino una interfaz generada con PHP, de distribución gratuita, para administración de bases de dato MySql y viene con las instalaciones de XAMPP y MAMP. Es también probable que el servidor donde alojemos nuestra páginas tenga esta aplicación a disposición del desarrollador, y si no, es fácil de instalar en nuestro servidor remoto para administra la BD.

Podemos acceder a phpMyAdmin desde la página de inicio de XAMPP o desde la página de inicio de MAMP en el menú superior.

Nota:
En el caso del phpMyAdmin en pc, al abrir la página puede que nos solicite la clave que definimos al momento de la instalación del usuario root (mysqladmin).

Creación de usuarios y base de datos

Lo primero que nos vamos a encontrar al abrir el phpMyAdmin es la interfaz general de bienvenida. Al lado izquierdo un listado de las BD que existen y a las que se puede acceder, y al lado derecho, vínculos de control general de MySql.

Home phpMyAdmin
Home phpMyAdmin

Antes de continuar, es necesario crear un usuario que tenga los permisos para acceder a las tablas que vamos a generar para la BD "rayitas". Para esto seleccionamos, en el menú superior de la interfaz de phpMyAdmin las cuentas de usuarios (Users accounts).

Menú Cuenta de usuario
Menú Cuenta de usuario

Al seleccionar este menú, se desplegará la página con todos los usuarios que hay en el sistema y que tiene acceso a MySql.

Cuentas de usuario
Cuentas de usuario

Todos estos usuarios se administran en una base de datos que se llama mysql en la tabla user, pero desde está interfaz de usuarios con acceso y privilegio se puede controlar el GRANT, que apareció en MySql 4.3.

Debajo de la lista de usuarios, encontramos un vínculo para agregar usuarios (Add a new User) y se desplegará un formulario con los datos necesarios.

Menú agregar cuenta de usuario
Menú agregar cuenta de usuario

User name (nombre de usuario):

Aquí se define el nombre del usuario autorizado para hacer consultas a nuestra BD rayitas. Ingresamos "rayitas", que es el nombre de nuestro cliente y fácil de recordar.

Host (Servidor):

Se refiere a desde dónde, el usuario, va a acceder a la BD. Puede ser que alojemos las páginas en un servidor y la BD en otro, o que por seguridad, queramos restringir el acceso a la BD sólo si la solicitud viene de cierto IP. En nuestro caso, como las páginas y la BD están en el mismo servidor ingresemos "localhost".

Password (Contraseña):

Es la contraseña para verificar la identificación ante el sistema cuando se hagan las solicitudes y garantizar que uno es quien dice ser. Ingresemos "raya123" y repitámosla en el campo Re-type

En la parte inferior del formulario están los privilegios globales que tendrá el usuario al momento de acceder a MySql. En nuestro caso le diremos que aproveche la creación de usuario para crear una BD con el mismo nombre.

Formulario creación de usuario
Formulario creación de usuario

Nota:
Por razones de seguridad, es frecuente que los administradores del servicio de hosting no entreguen acceso a crear BD o usuario y que sean datos que nos entreguen al hacer el contrato. Es recomendable utilizar los mismos datos en local que el remoto y así tendremos menos archivos que modificar al momento de subir nuestro sitio.

Este es el camino más rápido para crear en un sólo paso tanto usuarios como la BD. Sin embargo se puede hacer por separado. Primero crear la base de datos, aprovechando el menú "Nueva" al lado izquierdo, arriba del listado de base de datos.

Menú creación de base de datos
Menú creación de base de datos

Esta acción nos llevara a una interfaz con todas las Bases de Datos en el sistema y un formulario para agregar una nueva Base de datos.

Listado bases de datos
Listado bases de datos
Si nos vamos por este camino, una vez creada la Base de datos y estando seleccionada, podemos acceder a los privilegios o quien tiene acceso a esta base de datos. Aquí podemos crear un nuevo usuario y darle los privilegios para que acceda a la Base de datos creada.

Creación de tablas y campos

En phpMyAdmin, si seleccionamos del menú la base de datos "rayitas", nos vamos a encontrar con una interfaz que nos muestra que no hay tablas en la base de dato, pero si espacio para la creación de una.

Creación de tablas y campos
Creación de tablas y campos

Donde dice "Crear tabla" escribamos el nombre de nuestra tabla "productos" en el campo nombre y definamos que vamos a utilizar 11 campos: Los 10 que definimos en nuestro diseño (Nombre, Codigo, Categoría, Fecha, Frase promocional, Descripción, Colores, Precio, Disponibilidad, Destacado) más uno de índice u orden para agilizar el trabajo de MySql que llamaremos "id".

Formulario creación campo de tabla
Formulario creación campo de tabla

Esto nos lleva a una interfaz que nos permitirá definir los parámetros de los campos en la tabla. Dicho sea de paso, es un poco más que definir nombres a los campos, ya que como mencionamos anteriormente, se trata de optimizar la construcción de las tablas para no utilizar espacio de más y poder mejorar las búsquedas y otras operaciones.

Existen básicamente 3 categorías de datos que se pueden almacenar:

  • Los datos numéricos, enteros o decimales, positivos o negativos.
  • Las cadenas de texto, números o mezcla de ambos.
  • Y las que son una mezcla de los dos anteriores, pero con funciones específicas, como la fecha.

Si bien todo se podría introducir en campos de texto, hay que tener presente que se puede hacer más eficiente la búsqueda y operaciones de consultas si los campos están bien definidos, por ejemplo: preguntar por todos los registros que tengan la fecha menor a hoy.

Datos tipo numérico

Datos tipo numérico
Nombre Espacio de Memoria Uso Frecuente
TINYINT 1 byte Número entero muy pequeño, abarca un rango de -128 al 127
SMALLINT 2 bytes Número entero pequeño, abarca un rango de -32768 al 32767
MEDIUMINT 3 bytes Número entero de mediano tamaño, abarca un rango del -8388608 al 8388607
INT 4 bytes Número entero normal, abarca un rango de -2147483648 al 2147483647
BIDINT 8 bytes Número entero grande, abarca del 9223372036854775808 al 9223372036854770000
FLOAT 4 bytes A small (single-precision) floating-point number
DOUBLE 8 bytes A normal-size (double-precision) floating-point number
DECIMAL 2 bytes An unpacked floating-point number

Datos tipo cadena:

Datos tipo cadena
Nombre Tamaño Uso Frecuente
CHAR 255 bytes Cualquier carácter, con un máximo de 255. Se puede definir menos.
VARCHAR 255 bytes Cualquier carácter, con un máximo de 255. Se puede definir menos.
TINYTEXT 255 bytes Espacio pequeño para cualquier tipo de carácter.
TINYBLOB 255 bytes Espacio pequeño para cualquier tipo de carácter.
TEXT 65535 bytes Espacio definido para un poco más de caracteres.
BLOB 65535 bytes Espacio definido para un poco más de caracteres.
MEDIUMTEXT 1.6 MB Espacio medio para caracteres.
MEDIUMBLOB 1.6 MB Espacio medio para caracteres.
LONGTEXT 4.2 GB Gran capacidad de caracteres.
LONGBLOB 4.2 GB Gran capacidad de caracteres.

Vale la pena aclarar la diferencia entre CHAR y VARCHAR, ya que es de los tipos más usados. Ambos tienen una capacidad de 255 caracteres, se pueden definir menos. En el caso de los VARCHAR, si se define un tamaño y no se ocupa la totalidad, limita el espacio a lo usado, mas 1 byte. En el caso de los CHAR, si se define un tamaño, siempre se ocupa ese espacio. Si bien VARCHAR ocupa menos espacio, los tipo "CHAR", como tienen tamaños fijos, pueden hacer búsquedas más rápidas.

Los BLOB y TEXT tienen comportamientos similares, pero el BLOB define objetos binarios, o sea que pueden alojar información de imágenes. A pesar de su gran capacidad, procesan los datos de manera muy lenta.

Datos varios

Datos varios
Nombre Formato Rango
ENUM ('value1', 'value2',…) Lista de la cual se puede seleccionar sólo uno para almacenar en el campo
SET ('value1', 'value2',…) Lista de la cual se puede seleccionar más de un valor
DATE YYYY-MM-DD 1000-01-01 al 9999-12-31
DATETIME YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 al 9999-12-31 23:59:59
TIMESTAMP YYYYMMDDHHMMSS 19700101000000 al 20231201000000
TIME HH:MM:SS - 838:59:59 al 838:59:59
YEAR [(2/4)] YYYY 1901 al 2155

El tipo ENUM permite definir valores predeterminados, de los cuales sólo va a almacenar uno de ellos, mientras que el tipo SET permite almacenar una lista de los valores, también predefinidos.

Modificadores de columnas

Modificadores de columnas
Nombre Tipo Uso
AUTO_INCREMENT todos los tipos INT Autoincrementará la numeración por sistema. En una tabla MySQL sólo puede haber un auto incrementado, y suele usarse para el campo de índice.
BINARY CHAR, VARCHAR Las columnas serán tratadas como binarias.
DEFAULT Todos excepto BLOB y TEXT Define un valor por defecto si no es definido al momento de ingresar los datos.
NULL todos Define si un campo puede quedar vacío. Por lo general es NOT NULL.
PRIMARY todos Toda table debe tener un campo primario que va a ser el que marcará el índice.
UNIQUE toda Define que un campo no puede repetirse en toda la tabla.

Entender para que sirve cada campo es importante, pero no arroja muchas luces sobre el tipo de campo que hay que usar, por lo que hace un tiempo logre llegar a un esquema que, a través de preguntas sencillas, me permite ir siguiendo bifurcaciones hasta llegar a establecer el mejor campo en relación a su objetivo.

Araña de MySql
Araña de MySql

Ahora que tenemos una lista de los tipos de datos que van en nuestra tabla y una estructura que nos permite seleccionar el más indicado, retomemos la lista de campos que tenemos y definamos cuales van a ser los tipos de cada una.

Datos para la tabla
nombre tipo opciones
id INT(6) NOT NULL AUTO_INCREMENT PRIMARY KEY,
nombre VARCHAR(50) NOT NULL
codigo CHAR(12) NOT NULL
categoria VARCHAR(20) NOT NULL
frase_promocional VARCHAR(250) NOT NULL
descripcion TEXT NOT NULL
colores SET('rojo','verde','azul','negro') NOT NULL
precio FLOAT NOT NULL
disponibilidad ENUM('1,'0') NOT NULL
promocion ENUM('1','0') NOT NULL
fecha TIMESTAMP NOT NULL,CURRENT_TIMESTAMP

Nota:
Es buena idea estandarizar el proceso de creación y definir los nombres de las tablas y campos en minúscula. Recordemos que no se pueden usar caracteres especiales ni espacios para separar palabras.
El campo indexador es buena idea definirlo como primer campo en la tabla.

Una vez creada la tabla, la podemos seleccionar del sub menú del lado izquierdo ya sea para ver su estructura o su contenido, enviar ordenes SQL o buscar dentro del contenido. Tambien está el menú para exportar e importar (que veremos en el siguiente capítulo), los privilegios específicos de la tabla, operaciones que se pueden hacer con la tabla seleccionada y seguimiento.

Tabla creada
Tabla creada

Insertar datos en una tabla con phpMyAdmin

Podemos ocupar phpMyAdmin para ingresar datos directamente a la tabla. Para eso seleccionamos la opción "insertar" del menú superior, que nos va a desplegar un formulario con todos los campos de nuestra tabla para que ingresemos valores. Donde cada campo del formulario va a depender del tipo de valor que hemos definido para el campo en la tabla.

Formulario para insertar datos en una tabla
Formulario para insertar datos en una tabla

Nota:
Un tema interesante es que phpMyAdmin nos presenta 2 formularios para acelerar el proceso de ingreso de datos. No es necesario llenar los 2 formularios si sólo voy a agregar una fila de datos.

Ejercicio:
  1. Llenar el contenido de la tabla "productos" con al menos 15 tipo de rayas distintas.
  2. Preparar 15 imágenes que representen estos 15 productos y fijarse que el nombre del archivo coincida con el código ingresado en la tabla para poder hacer la relación posterior.
  3. Diseñar y montar la página index.php con el listado de productos y la página producto.php con la ficha completa del producto y el formulario de compra en html estático.

Exportar e importar con phpMyAdmin

En nuestro trabajo con el servidor local y remoto, es probable que queramos evitarnos el trabajo de volver a crear las tablas en ambos, por lo que una vez creado podemos exportar la estructura y datos de una tabla en lenguaje SQL para poder importarla con posterioridad.

Exportar

Con la tabla productos seleccionado en phpMyAdmin, seleccionemos en el menú superior "exportar" (export). Esta acción abre un formulario que permite personalizar la exportación.

Formulario exportación de datos
Formulario exportación de datos

Aquí podemos seleccionar el modo "rápido" y el formato SQL, para que nos muestra en pantalla el código SQL de creación de tabla y los contenidos que tengamos, o podemos seleccionar "personalizado" que nos entregará más opciones para la exportación. con cualquiera de las dos opciones, phpMyAdmin, generará un SQL.

Ejemplo:
CREATE TABLE `productos` (
  `id` int(6) NOT NULL,
  `nombre` varchar(50) NOT NULL DEFAULT '',
  `codigo` varchar(12) NOT NULL DEFAULT '',
  `categoria` varchar(20) NOT NULL DEFAULT '',
  `frase_promocional` varchar(250) NOT NULL DEFAULT '',
  `descripcion` text NOT NULL,
  `colores` set('rojo','verde','azul','negro') NOT NULL DEFAULT '',
  `precio` float NOT NULL DEFAULT '0',
  `disponibilidad` enum('1','0') NOT NULL DEFAULT '1',
  `promocion` enum('1','0') NOT NULL DEFAULT '0',
  `fecha` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

ALTER TABLE `productos`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `codigo` (`codigo`);

ALTER TABLE `productos`
  MODIFY `id` int(6) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;

Importar

Para importar podemos realizar dos acciones, una es usar el proceso inverso al anterior. Teniendo seleccionado la base de datos "rayitas" elegimos el vínculo importar.

Formulario importación de datos a una tabla
Formulario importación de datos a una tabla

Esta acción despliega un formulario que nos permite escoger el archivo que contiene la sentencia SQL, por ejemplo productos.sql.

La otra opción es abrir éste archivo con una aplicación de texto simple como "notepad" en windows o TextEdit en OsX, copiar su contenido en una ventana SQL que también seleccionemos del menú de navegación.

Formulario para ingresar SQL
Formulario para ingresar SQL

Cualquiera de los dos métodos tomará como propio la sentencia SQL del archivo y la ejecutará para crear la tabla e introducir datos de productos ficticios con los cuales vamos a trabajar en este manual.

Objetivo del capítulo:
Conocer y utilizar las funciones PHP para conectarse a una Base de Datos y poder enviarle consultas SQL para realizar un CAME.

Ahora que ya tenemos creado el usuario, con privilegios para acceder a la base de datos "rayitas" y una tabla con al menos 15 productos, es un buen momento de generar una comunicación directecta entre nuestro archivo y el software MySql, lo primero que tenemos que hacer es generar una conexión o canal de comunicación con la BD.

Generar una conexión con la BD
Generar una conexión con la BD

Para acceder a una BD desde una página PHP, primero se debe generar un canal de comunicación entre la página dinámica y MySql, y después seleccionar la BD.

Para esto necesitamos saber 4 cosas:

  • Dirección de la BD
  • Usuario con privilegio para acceder a la BD
  • Clave para validar que es el usuario
  • Nombre de la BD

Con estos 4 datos podemos generar un archivo externo que requeriremos en todas las páginas que necesitan conectarse a la BD.

mysqli()

Para esto ocuparemos la función mysqli() (La "i" viene de " improved" o mejorado).

Ejemplo:
<?php
$hostname = "localhost";
$username = "rayitas";
$password = "raya123";
$database = "rayitas";
$conn = new mysqli($hostname, $username, $password, $database);
if ($conn ->connect_error) {
die('Error de Conexión (' . $conn->connect_errno . ') ' . $conn->connect_error);
}
?>

Revisemos un poco el código generado:

$hostname = "localhost";
$username = "rayitas";
$password = "raya123";
$database = "rayitas";

Las primeras cuatro líneas definen las variables necesarias para generar la conexión. No es necesario separarlo, pero es cómodo a la hora de reutilizar el archivo de conexión en próximos proyectos.

Ejemplo:
$conn = new mysqli($hostname, $username, $password, $database);

Aquí creamos un nuevo objeto PHP en la variable $conn, que usando la función mysqli() abre un canal de comunicación con la base de datos del cliente con los 4 datos que le pasamos.

Nota:
Cada vez que veamos la palabra "new" en la línea de código es que estamos generando un objeto de PHP.

En algunas instalaciones de MAMP en Windows, cuando se cambia el puerto de MySql predeterminado 3306 por el 8889, es necesario agregar este último parámetro en la función mysqli para saber dónde se encuentra la BD.

Ejemplo:
$hostname = "localhost";
$username = "rayitas";
$password = "raya123";
$database = "rayitas";
$puerto = "8889";
$conn = new mysqli($hostname, $username, $password, $database,$puerto);

Sigamos revisando el código. Las siguientes líneas no son parte de la conexión, pero nos ayudan a entender si la estamos haciendo correctamente.

if ($conn ->connect_error) {
die('Error de Conexión (' . $conn->connect_errno . ')' . $conn->connect_error);
}

Pregunta si es que hay un error en la conexión a la base de datos, entonces que pare todo proceso de PHP die() y muestre el número de error ($conn->connect_errno) y el error mismo ($conn->connect_error).

Nota:
Se puede encontrar una lista de los errores en de MySql en https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html

Si bien se recomienda no mostrar errores de conexión a los sitios en producción o al aire, para no dar pistas a posibles hackers, si es importante que en la etapa de desarrollo podamos ver si estamos o no generando una conexión.

Como es bastante probable que todas nuestras páginas quieran consultar a la base de datos para entregar contenido, es buena idea dejar este fragmenteo de código con la conexión en un archivo externo que pueda ser requerido por cualquier página que lo necesite y así nos evitamos repetir la conexión en cada página. Guardemos el archivo como conexion.php en la raíz del sitio.

Si corremos este archivo en el servidor y tenemos los 4 datos correctamente ingresados deberíamos ver una página en blanco. Por el contrario, si algunos de los datos no están correctos para MySql, éste devolverá el número de erros y el por qué no se puede conectar.

Si agregamos un else a nuestra condicional podemos ver información de la conexión con el parámetro ->host_info.

if ($conn ->connect_error) {
die('Error de Conexión (' . $conn->connect_errno . ') '. $conn->connect_error); } else {
echo $conn ->host_info;
}

Alerta:
No te olvides de comentar estas últimas líneas, una vez verificada la conexión, para que no se vea esta información de manera pública en nuestra página en desarrollo.

Nota:
Ya sabes que puedes recurrir a http://www.php.net si quieres conocer más de la función mysqli().

Para estar tranquilos de la seguridad, que suele ser un pregunta frecuente, no se puede acceder por la Web a esta información ya que es un archivo PHP que va a ser interpretado por el servidor antes de que se muestre.

mysqli_close()

Un tema que no es menor en la generación de la conexión, es que de manera predeterminada se mantiene activa hasta que se diga lo contrario. Para evitar dejar este recurso abierto y consumiendo memoria RAM del servidor, al final de nuestra página, cuando ya hemos utilizado el recurso, podemos cerrar este puente con la función mysqli_close().

Dentro del paréntesis pasamos el valor de la conexión que queremos cerrar, que en nuestro caso es la variable $conn. Esto nos permite abrir varias conexiones a diferentes bases de datos y cerrar la que ya no estemos utilizando.

Como todas nuestras páginas van a tener conexión a la BD, lo más práctico es incluir en el pie.phpel fragmento para cerrar la conexión.

Ejemplo:
<div  class="clearfix"></div>
<footer>
<div style="text-align: center"> Rayitas S.A. &copy; <?php echo date('Y')?><br>
<a href="mailto: info@rayitas.cl">contacto</a> </div> </footer> <?php mysqli_close($conn);?>

Objetivo del capítulo:
Entender y aplicar consultas desde el documento PHP a una tabla en la Base de Datos.

Ahora que ya tenemos el fragmento de código de conexión en el archivo conexion.php lo podemos vincular en nuestra página maestra index.php y usar la conexión para consultar a la tabla productos por los datos que requiere ésta página: nombre, frase promocional y precio.

MySql habla SQL (Structured Query Language), básicamente un lenguaje estructurado para consultar, agregar, modificar y eliminar los registros en la tabla de la base de datos (select, insert, update, delete).

La consulta estructurada de SQL parte con la orden a realizar y la tabla dónde la queremos realizar. Y se puede aumentar criterios para limitar lo afectado o rango o condiciónde lo que se quiere afectar.

SQL Select

Ejemplo:
SELECT <campo/s> FROM <tabla> [WHERE] [GROUP BY] [ORDER BY] [LIMIT]

Traduscamos la estructura de ejemplo: Seleccione <el o los campos> de la <tabla X> [donde condición] [agrupado por] y [ordenado por]. Entendiendo que lo que está en corchetes es optativo y lo que está entre etiquetas sustituible por el nombre del campo y nombre de la tabla que se quiere afectar.

Ejemplo:
SELECT * FROM `productos`

Si revisamos en phpMyAdmin está consulta, nos va a devolver todas las filas de la tabla y todos los campos ya que el asterisco es un comodin para decir "todos los campos"

Resultado de consulta SQL
Resultado de consulta SQL

Si en vez de todos los campos, queremos limitar sólo a los que necesitamos en esta página (nombre, frase_promosional, precio), entonces cambiamos el asterisco por el nombre de los campos:

Ejemplo:
SELECT nombre, frase_promocional,precio FROM `productos`
Resultado de consulta SQL
Resultado de consulta SQL

Ahora que ya consultamos por los datos con SQL, veamos como utilizar la consulta pero desde la página con PHP.

mysqli->query()

Aquí es donde comenzamos a mezclar los dos lenguajes, por un lado PHP para pedir y procesar los datos y por otro lado SQL para hacer la consulta a la base de datos.

Ejemplo:
<?php require_once('conexion.php'); ?>
<?php
$query=" SELECT nombre, frase_promocional, precio FROM productos ORDER BY fecha DESC";
$resource = $conn->query($query); 
$total = $resource->num_rows;
?>
<!doctype html>

Si bien no hay un lugar establecido en dónde se va a incorporar el código, si es importante que la consulta la hagamos antes de utilizarla y después de haber realizado la conexión.

Es limpio, pero no obligatorio, hacer las consultas en las primeras líneas del documento, incluso antes de la definición del tipo de documento.

Revisemos el código generado:

$query=" SELECT nombre, frase_promocional, precio FROM productos ORDER BY fecha DESC";

Primero definimos en SQL que necesitamos seleccionar los campos nombre, frase_promocional y precio de la tabla productos ordenado por la fecha de manera descendente y lo guardamos en la variable $query.

$resource = $conn->query($query);

La segunda línea es la que realmente toma la conexión que definimos en $conn y envía la consulta al servidor con el métodoquery().

El resultado de esta consulta se va a guardar en la variable $resource como recurso.

$total = $conn->num_rows;

Por último, con el métodonum_rows sabemos si la BD nos devolvió filas de datos y cuántas devolvió, y lo asignamos a una variable $total.

Ahora, que ya tenemos en $resource el resultado de la consulta a la base de datos, podemos ir a la sección en nuestra página dónde ocuparemos los datos.

Ejemplo:
<div class="col mb-4">
<div class="card"> <img class="card-img-top" src="images/dummy.png" alt="rayitas">
<div class="card-body">
<h5 class="card-title">Nombre Producto</h5>
<p class="card-text">frase promocional.</p>
<p class="text-right">$ precio</p>
<div class="text-center"><a href="producto.php" class="btn btn-primary">ver más</a></div>
</div>
</div>
</div>

fetch_assoc()

fetch_assoc() es el método que nos permite extraer una fila de datos del recurso entregado de manera asociativa.

Lo primero que vamos a hacer es aprovechar que sabemos cuantos resultados devolvió la consulta, por lo que condicionaremos la existencia de la tabla a que la variable $total tenga valor. Después, debemos sacar de la variable $resource las filas de datos y aprovechar de hacer un bucle para todas las filas si es que hay datos.

Ejemplo:
<?php if($total){?>
<?php  while ($row = $resource->fetch_assoc()){?>
<div class="col mb-4">
<div class="card"> <img class="card-img-top" src="images/dummy.png" alt="rayitas">
<div class="card-body">
<h5 class="card-title">Nombre Producto</h5>
<p class="card-text">frase promocional.</p>
<p class="text-right">$ precio</p>
<div class="text-center"><a href="producto.php" class="btn btn-primary">ver más</a></div>
</div>
</div>
</div> <?php }?> <?php }else{?> <p class="error"> No hay resultados para su consulta </p> <?php }?>

Revisemos la programación:

<?php if($total){?>

O sea, si la consulta ha devuelto al menos una fila de resultado mostramos la tabla, si no, mostramos un párrafo de error "No hay resultados para su consulta".

<?php while ($row = $resource->fetch_assoc()){?>

La segunda línea comienza un bucle con la función while() dónde asigna en la variable $row los valores de la fila que va extrayendo en cada vuelta con el métodofetch_assoc().

La variable $row, por lo tanto, tendría una matriz compuesta por el nombre del campo de la tabla en el key y el valor guardado en la base de datos en el value.

Si corremos este código, veremos que el bucle repite una fila para cada registro que viene como resultado de la consulta.

Bien, ahora que ya hemos repetido las filas, y sabemos que está funcionando el bucle, para ver los datos recogidos, sustituimos el texto estático de la fila por salidas a pantalla de los valores de la matriz $row usando como key los nombres d elos campos en la tabla.

Ejemplo:
<h5 class="card-title"><?php echo $row['nombre']?></h5>
<p class="card-text"><?php echo $row['frase_promocional']?>.</p>
<p class="text-right">$ <?php echo $row['precio']?></p>

Si todo se ha realizado correctamente y, tenemos datos en nuestra tabla productos, deberíamos ver cómo se construye la tabla en la página index.php con los nombres de los productos.

página alimentada por la consulta a MySql

Limitar la consulta

No es buena idea entregar todos los resultado de la consulta en la página que estamos mostrando. Cuando hay 15 productos, no hay problema, pero si estamos hablando de 200 o 300 productos en la tabla, el tiempo de extraerlo de la base de datos, incorporarlo en la página Web y que todo ese peso llegue al usuario, puede tomar su buen tiempo, dependiendo de la velocidad de la conexión del usuario y del servidor. Y aún así, es tanta la información entregada en pantalla que el usuario no va tener la capacidad de digerir toda esa información.

Por lo anterior es que es buena idea limitar la consulta o paginar la información de tal manera que la entrega de datos sea dosificada. Esto lo podemos hacer afectando la consulta SQL.

Ejemplo:
SELECT nombre, frase_promocional, precio FROM productos ORDER BY fecha DESC LIMIT 0,5

Esta nueva consulta SQL es igual a la que usamos anteriormente, salvo el LIMIT 0,5. Este complemento tiene dos parámetros, el primero le está diciendo que parta en la fila 0 (la primera de la tabla) y el segundo que extraiga y devuelva sólo 5 registros.

Si lo dejamos así, sólo nos va a traer los primeros 5 registros de la tabla, pero con PHP podemos variabilizar estos dos parámetros de tal manera que cambien según valores que vayamos entregando por la URL.

Ejemplo:
$max=5;
$pag=0;
if(isset($_GET['pag']) && $_GET['pag'] <>""){
$pag=$_GET['pag'];
}
$inicio=$pag * $max;
$query=" SELECT nombre, frase_promocional, precio FROM productos ORDER BY fecha DESC LIMIT $inicio,$max";
$resource = $conn->query($query); 
$total = $resource->num_rows;

Revisemos este código: la variable $max define la cantidad de registros que queremos recuperar de la tabla. La variable $pag define el número de página que queremos desplegar, y la variable $inicio es el resultado de operar el número de página por el máximo que estamos limitando.

if(isset($_GET['pag']) && $_GET['pag'] <>""){
$pag=$_GET['pag'];
}

Esta condicional pregunta si por la URL se ha definido la variable "pag" y si esta variable tiene valor, si es así, entonces reasigna el valor de la variable $pag y, por lo tanto, afecta el valor de la variable $inicio haciendo que la consulta SQL vaya variando su punto de inicio.

Si abrimos nuestra página Web en el browser y vamos variando la variable "pag" en la URL (Ej: index.php?pag=1) veremos como el contenido en la página cambia según el paquete de datos que se está consultando.

Como no le vamos a entregar un manual al usuario para que cambie él la dirección de la URL, construyamos un simple sistema de navegación anterior y siguiente, arriba de la tabla, incrementando o disminuyendo el valor de "$pag" que se va a transmitir por la URL para la paginación.

Ejemplo:
<ul class="pagination justify-content-center">
<li class="page-item previous "> <a class="page-link">&larr; Anterior</a> </li>
<li class="page-item"> <a class="page-link"> X a Y de Z </a> </li>
<li class="page-item next" style="float:right"> <a class="page-link">Siguiente &rarr;</a> </li>
</ul>

Hasta ahí, hemos logrado que avance y retroceda la página, hasta que llega un punto donde se pasa de los datos que puede entregar o resta menos de cero, por lo que el punto de partida en en la consulta es negativo y MySql no sabe qué datos devolver.

Para evitar esto, necesitamos saber cuantas páginas en total se puede mostrar. Esta es una operación sencilla, ya que sí sabemos el total de registros que coinciden con nuestra búsqueda y lo dividimos entre el total de los registros que se van a mostrar, tendremos el total de páginas que componen nuestra consulta.

Antes sabíamos la cantidad total de registros devueltos con la variable "$total", pero ahora, con la limitación de la consulta, esta variable siempre va a ser máximo 5, que es el máximo de campos a recuperar que hemos definido en "$max" (a menos que el resultado de la consulta sea menor).

Para saber cuantas filas son en total, y por lo tanto, la cantidad total de páginas, vamos a tener que hacer 2 consultas, una para saber el total de registros, y la otra limitada para los datos a mostrar por cada página.

Ejemplo:
<?php
$max=5;
$pag=0;
if(isset($_GET['pag']) && $_GET['pag'] <>""){
$pag=$_GET['pag'];
}
$inicio=$pag * $max;
$query=" SELECT nombre, frase_promocional, precio FROM productos ORDER BY fecha DESC";
$query_limit= $query ." LIMIT $inicio,$max";
$resource = $conn->query($query_limit);
if (isset($_GET['total'])) {
$total = $_GET['total'];
} else {
$resource_total = $conn -> query($query);
$total = $resource_total->num_rows;
}
$total_pag = ceil($total/$max)-1;
?>

En el código anterior, $resource sigue teniendo la consulta limita, ya que usa la variable $query_limit que concatena la consulta en la variable $query a la orden de limitar, por lo que no varía la presentación de nuestro contenido, pero agregamos una condicional para consultar por el total de filas de la consulta $query, sin limitar, si es que no viene por la URL la variable total, de esta manera consultamos una sola vez por el total de los registros y la siguiente vez nos basamos en lo que se pasa por los vínculos de navegación "siguiente" y "anterior" ahorrando consultas y recursos de servidor.

Ejemplo:
<ul class="pagination justify-content-center">
<li class="page-item previous "> <a href="index.php?pag=<?php echo $pag -1?>&total=<?php echo $total?>"class="page-link">&larr; Anterior</a> </li>
<li class="page-item"> <a class="page-link"> X a Y de Z </a> </li>
<li class="page-item next" style="float:right"> <a href="index.php?pag=<?php echo $pag +1?>&total=<?php echo $total?>" class="page-link">Siguiente &rarr;</a> </li>
</ul>

Por último, generamos la variable $total_pag que es igual al redondeo hacia arriba (función PHP ceil()) de la división del total de productos entre el máximo de productos que queremos limitar. A este resultado le restamos uno, ya que el punto de inicio en SQL es cero.

Con esta nueva variable, podemos condicionar nuestro sistema de navegación, de tal manera que no ofrezca "siguiente" si ya hemos llegado al final de la cantidad de registros que se pueden mostrar y lo mismo para "anterior" si es menor a cero.

Ejemplo:
<ul class="pagination justify-content-center">
<?php if($pag-1 >= 0){?>
<li class="page-item previous "> <a href="index.php?pag=<?php echo $pag -1?>&total=<?php echo $total?>"class="page-link">&larr; Anterior</a> </li>
<?php }?>
<li class="page-item"> <a class="page-link"> X a Y de Z </a> </li>
<?php if($pag +1 <= $total_pag ){?> <li>
<li class="page-item next" style="float:right"> <a href="index.php?pag=<?php echo $pag +1?>&total=<?php echo $total?>" class="page-link">Siguiente &rarr;</a> </li>
<?php }?>
</ul>

Bien, ahora que ya tenemos una navegación para paginar los resultados de nuestra consulta, es buena idea mostrar al usuario en qué numeración vamos, para saber cuántos más "siguientes" hay.

Para esto agregaremos el clásico "X a Y de Z" entremedio de "anterior" y "siguiente" indicando el punto de partida hasta el punto final de lo que se está mostrando de cuantos registros hay.

Ejemplo:

<ul class="pagination justify-content-center">
<?php if($pag-1 >= 0){?>
<li class="page-item previous "> <a href="index.php?pag=<?php echo $pag -1?>&total=<?php echo $total?>"class="page-link">&larr; Anterior</a> </li>
<?php }?>
<li class="page-item"> <a class="page-link"><?php echo ($inicio + 1) ?> a <?php echo min($inicio + $max, $total) ?> de <?php echo $total ?> </a> </li>
<?php if($pag +1 <= $total_pag ){?> <li>
<li class="page-item next" style="float:right"> <a href="index.php?pag=<?php echo $pag +1?>&total=<?php echo $total?>" class="page-link">Siguiente &rarr;</a> </li>
<?php }?>
</ul>

La variable "inicio" más uno nos da el punto de partida de los registros que se están mostrando.

El punto final de lo que se está mostrando hace uso de la función de PHP min() que se queda con el menor de los valores numéricos que se entreguen como parámetros dentro de los paréntesis. En este caso busca qué es menor: si la suma del valor de la variable $inicio más la variable $max o el total de los registros. Esto es para que en nuestra última página pueda reaccionar según el valor real de los datos que devuelve.

Por último hacemos uso de la variable $total para mostrar cuántos son los registros totales un coinciden con la consulta.

Vínculo a otra página

Bien, ya tenemos nuestra lista de productos en la página index.php, pero necesitamos, que cuando el usuario seleccione un producto que le interesa, éste se despliegue en la página producto.php que hemos diseñado con toda la información del producto. Para esto necesitamos llegar a esta segunda página con un valor que sea único para hacer la consulta a la base de datos y alimentarla dinámicamente.

En nuestra tabla tenemos dos campos que son únicos por productos: el "codigo" o el "id". En este caso vamos a usar el "id" para tener un punto de dónde agarrarnos para filtrar la consulta.

Los primero que debemos hacer es agregar a la consulta el campo "id" para contar con el dato que en la primera consulta no se consideraba.

Ejemplo:
$query=" SELECT id, nombre, frase_promocional, precio FROM productos ORDER BY fecha DESC";

Después debemos vincular el nombre del producto para que llegue a la página producto.php con esta variable como parte de la URL.

Ejemplo:
<a href="producto.php?id=<?php echo $row['id']?>"><?php echo $row['nombre']?></a>

Ahora que llegamos con un valor en "id" distinto para cada producto a la página producto.php tenemos de dónde agarrarnos para hacer una consulta filtrada a la tabla.

En la página producto.php agregamos la conexión a la base de datos que ya generamos y realizamos una nueva consulta filtrada afectando el WHERE de la sentencia SQL.

Ejemplo:
<?php require_once('conexion.php'); ?>
<?php
$query=" SELECT * FROM productos WHERE 1 AND id=$_GET[id]";
$resource = $conn->query($query); 
$total = $resource->num_rows;
$row = $resource->fetch_assoc();
?>

Si vemos la sentencia SQL, ya no estamos llamando a campos específicos de la tabla, si no que usamos el comodín "*" para decir que queremos todos los campos de la tabla.

La segunda diferencia es que ahora no queremos todos los registros, si no que sólo los registros que tengan en el campo "id" el valor igual a la variable "id" que le estamos pasando por método get.

Por último, como debería haber solo una fila de respuesta, no necesitamos meter en un bucle la recuperación de los datos con fetch_assoc(), si no que lo asignamos al tiro a la variable $row.

$row = $resource->fetch_assoc();

Ahora que tenemos los valores del producto consultado en la variable $row, la usamos para sustituir el texto estático por texto variable en la página en nuestra página de productos.

Ejemplo:
<?php require_once('conexion.php'); ?>
<?php
$query = " SELECT * FROM productos WHERE 1 AND id=$_GET[id]";
$resource = $conn->query( $query );
$total = $resource->num_rows;
$row = $resource->fetch_assoc();
?>
<!doctype html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Tienda Virtual Rayita S.A.</title>
	<link href="css/bootstrap.css" rel="stylesheet" type="text/css">
	<link href="styles.css" rel="stylesheet" type="text/css">
</head>
<body>
	<div class="container">
	<?php require("header.php");?>
	<?php include("menu.php");?>
	<div class="col-xs-4">
		<img src="images/ImgResponsive_Placeholder.png" class="img-fluid" alt="Placeholder image">
	</div>
	<div class="col-xs-8">
		<img src="images/promo.gif" width="99" height="80" class="float-end" alt=""/>
	<div>
		<h2>
			<?php echo $row['nombre'];?> -
			<small>
				<?php echo $row['codigo'];?>
			</small>
		</h2>
	</div>
	<div class="well  col-sm-4" id="destacado">
		<p>
			<?php echo $row['fecha'];?><br>
			<?php echo $row['categoria'];?><br>
			<?php echo $row['colores'];?>
		</p>
	</div>
	<blockquote>
		<p>
		<?php echo $row['frase_promocional'];?>
		</p>
	</blockquote>
	<p>
		<?php echo $row['descripcion'];?>
	</p>
	</div>
	</div>
	<form method="post" name="comprar" class="form-horizontal" id="comprar">
		<strong>$<?php echo $row['precio'];?></strong><br>
		<label for="number">Cantidad:</label>
		<input name="number" type="number" id="number" value="1">
		<input type="submit" name="comprar" id="comprar" value="Comprar"> &nbsp;
	</form>
	</div>
	<?php require("footer.php");?>
</body>
</html>

Interviniendo el código

Si nos fijamos en el documento, hay un par de resultados de la consulta que no son muy entendibles para la mayor parte de usuarios, el precio, la fecha del producto y si el producto está en promoción o destacado. Por otro lado, el texto de la descripción se junta en un solo párrafo porque HTML no sabe lo que es un salto de línea de un texto ASCII, a menos que se lo digamos.

Por ejemplo el precio que se muestra en la página es bastante complicado de entender sin la coma separadora de los miles. Tal como vimos en capítulos anteriores, se puede ocupar la función PHP number_format() para darle formato al número.

Ejemplo:
 <strong>$<?php echo number_format($row['precio']);?></strong>

Quiere decir que del valor entregado se puede alterar su presentación para mejorar la usabilidad del sitio.

Otro ejemplo de uso frecuente son los párrafos guardados en la tabla. Ya que los párrafos o salto de línea no son interpretados en HTML, si guardamos varios párrafos en un campo, por ejemplo el de descripción del producto, se va ver como un sólo gran "ladrillo" de contenido indigerible.

row descripción
row descripción

Para evitar esto se puede ocupar la función de PHP nl2br() que convierte los saltos de línea en etiquetas <br> de html.

Ejemplo:
<p><?php echo nl2br($row['descripcion']);?></p>
Función nl2br()
Función nl2br()

Otro tema frecuente es el uso de imágenes en nuestra página. Si bien las imágenes se pueden guardar dentro de la tabla como dato binario, esto genera 2 conflictos: Por un lado, aumenta el tamaño de la base de datos al guardar un pantano de 1 y 0 que puede hacer más lenta la consulta y, por otro lado, hay que reconvertir este dato binario en una imagen de vuelta, sabiendo qué formato es.

Hay varias opciones que podemos aplicar y la decisión va a depender de cada desarrollo, si cada producto lleva una sóla imagen podemos agregar un campo más a la tabla para dejar registro de la dirección o nombre de la imagen, si son varios productos, podemos generar, por ejemplo, una nueva tabla de "imagenes" relacionando cada entrada con el ID del producto.

En este caso vamos a optar por un método menos invasivo y nos aprovecharemos del campo único "codigo" registrado en la tabla de producto para asociarlo con el nombre de la imagen que también se llama igual que el código, de tal manera que al construir nuestra página de producto, la dirección de la imagen va a ser la misma para todos los productos pero variabilizamos el nombre en base al código del producto.

Ejemplo:
<img src="images/<?php echo $row['codigo']?>.gif" class="img-fluid" alt="<?php echo $row['nombre']?>">
Vincular imagenes
Vincular imagenes

Ahora sólo falta nombrar nuestras imágenes igual que el código de nuestros productos en el directorio de imágenes.

Otro ejemplo, es que podemos notificar al usuario con una gráfica o un texto si es que el producto está en promoción dependiendo de el valor registrado en el campo "promocion" en la tabla de productos.

Ejemplo:
<?php if($row['promocion']=="1"){?>
<img src="images/promo.gif" width="99" height="80" alt="/>
<?php }?>

Ahora sólo falta nombrar nuestras imágenes igual que el código de nuestros productos en el directorio de imágenes.

Cambiar el formato de la fecha requiere un poco de trabajo, ya que se registra y muestra el valor con la fecha y tiempo en formato "computador" por venir de un campo del tipo "timestamp".

2016-05-11 20:31:23

O sea año, mes, dia, hora, minutos, segundo.

Aquí vamos a tener que aplicar la función explode() para separar la cadena y la función list() para meter los valores "explotados" en una variable que podamos utilizar para la salida a pantalla de la fecha en formato "en español".

Ejemplo:
<?php 
$la_fecha=$row['fecha'];
list($fec,$hor) = explode(' ', $la_fecha);
list($ano, $mes, $dia) = explode('-', $fec);
echo "$dia/$mes/$ano";
?>
Construir la fecha
Construir la fecha
Ejercicio:
  1. Agregar imagen a la página index.php para relacionar los nombres con una imagen y vincularla al detalle del producto.
  2. Intervenir producto.php para generar una condicional que prevenga error 500 en la página cuando no recibe un valor en ID por la URL.
  3. Genera un buscador de productos en la página index.php alterando la query principal o generar una lista para navegar por categoría que altere la query de productos.

Objetivo del capítulo:
Entender y aplicar la sentencia SQL para agregar registros en una tabla.

Bien, ahora que ya estamos mostrando la descripción del producto, es momento de registrar la intención de compra de nuestro cliente y aprovechar de ver cómo SQL inserta datos en una tabla.

SQL Insert

En SQL, para agregar datos a una tabla se usa la orden "INSERT" (insertar). Su construcción es similar al SELECT.

Ejemplo:
INSERT INTO <tabla> (<campo/s>) VALUES (<valor/es>);

Si traducimos la instrucción del ejemplo, podemos leer: Insertar en la <tabla X> en los (campos Y) los valores (Y). Dónde el orden de los campos que queremos afectar es el mismo orden de los valores.

Ahora que ya vimos la estructura del SQL de la acción de agregar, pongamoslo en práctica en nuestro ejemplo. Para eso vamos a seguir el proceso de compra y registrar la intención de nuestro cliente.

En nuestra página productos tenemos un formulario sencillo para realizar la compra, para esto necesitaremos una nueva tabla que almacene las 4 preguntas básicas: quién está comprando, qué está comprando, cuánto está comprando y cuándo está comprando.

Agreguemos en la base de datos de rayitas una tabla que se llame "compras", que permita este registro, con los siguientes campos:

  • id
  • cliente
  • código
  • nombre
  • precio
  • cantidad
  • fecha
Ejemplo:
CREATE TABLE `compras` (
      `id` int(6) NOT NULL auto_increment,
      `cliente` int(6) NOT NULL,
      `codigo` varchar(12) NOT NULL default '',
      `nombre` varchar(50) NOT NULL default '',
      `precio` float NOT NULL default '0',
      `cantidad` int(3) NOT NULL default '0',
      `fecha` timestamp NOT NULL,
      PRIMARY KEY (`id`)
      );

En esta construcción, como siempre, debemos fijarnos en el espacio reservado o largo de los campos, además de el tipo de datos que va a alojar, recordando que mucho espacio reservado va a aumentar los requerimientos de disco duro y bajar el tiempo de respuesta en las consultas y que poco espacio puede truncar datos que se necesitan registrar.

Nota:
Un truco del que nos podemos aferrar es que hay campos que se repiten de la tabla del producto: el código, nombre y precio, por lo que su tamaño y formato no pueden ser distintos a los registrados.

Ahora que ya tenemos nuestra tabla de compras, aprovechemos de completar nuestro formulario de compra en la página producto.php de donde se recogerán los datos.

Por el momento el formulario sólo tiene el campo de "cantidad", por lo que agregaremos, como campo oculto del formulario, el nombre, código y precio del producto. También vamos a necesitar un campo oculto para registrar el cliente que lo está comprando. Como todavía no recogemos ese dato, le pondremos como valor 1, después lo modificaremos cuando el cliente se haya identificado.

Ejemplo:
<form id="compra" name="compra" method="post" action="boleta.php">
<strong>$<?php echo number_format($row['precio']);?></strong><br />
<label for="cantidad">cantidad</label>
<input name="cantidad" type="number" id="cantidad" value="1" size="3" maxlength="3" />
<input name="precio" type="hidden" id="precio" value="<?php echo $row['precio']; ?>" />
<input name="codigo" type="hidden" id="codigo" value="<?php echo $row['codigo']; ?>" />
<input name="nombre" type="hidden" id="nombre" value="<?php echo $row['nombre']; ?>" />
<input name="cliente" type="hidden" id="cliente" value="1" />
<input type="submit" name="comprar" id="comprar" value="comprar" />
</form>

Como definimos el atributo action del formulario apuntando a boleta.php, le agregaremos a ésta página la programación para recibir y procesar los datos que envía el formulario de compra.

Al inicio de la página boleta.php, después de la conexión a la base de datos, aprovechemos de realizar el "query" para insertar los datos.

Ejemplo:
<?php require_once('conexion.php'); ?>
<?php
      if(isset($_POST['comprar']) && $_POST['comprar']=="comprar"){
      $query="INSERT INTO compras (id,cliente,codigo,nombre, precio,cantidad,fecha) VALUES (NULL,'$_POST[cliente]','$_POST[codigo]','$_POST[nombre]','$_POST[precio]', '$_POST[cantidad]',NOW())";
      $conn->query($query); 
      $ID=$conn->insert_id;
      }
      ?>

Analicemos por partes estas nueva líneas de código.

if(isset($_POST['comprar']) && $_POST['comprar']=="comprar"){

Primero preguntamos si viene por la URL la variable comprar, y si esta variable es igual a él valor "comprar", esto lo obtiene del formulario de la página como valor del botón name="comprar". De esta manera nos aseguramos que no ejecute consulta contra la base de datos a menos que efectivamente venga con datos del formulario.

$query="INSERT INTO compras (id,cliente,codigo,nombre, precio,cantidad,fecha) VALUES (NULL,'$_POST[cliente]','$_POST[codigo]','$_POST[nombre]','$_POST[precio]','$_POST[cantidad]',NOW())";
$conn->query($query);
$ID=$conn->insert_id;

Aquí construimos la sentencia SQL para insertar con la orden "INSERT" en la tabla "compras" y listamos los campos que queremos afectar, separando los nombres de éstos con coma. A continuación definimos los valores que queremos agregar, en el mismo orden que listamos los nombres de campos, de la matriz que viene por método "POST".

La siguiente línea envía esta sentencia a nuestra conexión a la base de dato. A diferencia de cuando consultábamos por datos en las páginas anteriores, esta vez no necesitamos asignar la respuesta a una variable.

Por último recogemos en una variable el ID del último registro afectado en la base de datos por si se necesita más adelante.

Eliminemos todo el proceso de lectura del array con la que alimentábamos la boleta y el bucle foreach() con el que hacíamos que se repitiera en los ejercicios anteriores. Nada más, porque vamos a necesitar las operaciones que ya le habíamos incorporado y todo el resto de las variables.

Generemos una consulta a la tabla "compras" dónde acabamos de registrar una compra filtrando la consulta por el cliente que sea igual al valor entregado "1".

Ejemplo:
<?php require_once('conexion.php'); ?>
<?php
      $query=" SELECT * FROM compras WHERE 1 AND cliente='1' ORDER BY fecha DESC";
      $resource = $conn->query($query); 
      $total = $resource->num_rows;
      ?>

Al igual que en la página index.php", repitamos con un bucle la fila de la tabla de la compra y, en vez de alimentar nombre, precio y cantidad de la matriz, ahora lo hacemos del resultado de la consulta.

Ejemplo:
<tbody>
<?php  while ($row = $resource->fetch_assoc()){?>
<tr>
<td>Rayas <?php echo $row['nombre']?></td>
<td align="center">$<?php echo number_format($precio=$row['precio']);?></td>
<td align="center"><?php echo $cantidad=$row['cantidad']?></td>
<td align="right">$<?php echo number_format($sub=$precio*$cantidad); $subtotal+=$sub?></td>
</tr>
<?php }?>
Boleta completa
Boleta completa

Ahora basta que realicemos el proceso completo de compra, desde que se selecciona el producto en el home, hasta que lleguemos a la boleta de compra y veremos que los productos se van agregando en la tabla compra.

Ejercicio:
  1. Aprovechando que ya tenemos diseñado el formulario de registro (capítulo de formularios) diseñemos una tabla para registrar a los nuevos clientes.
  2. Aplicar los conocimientos adquiridos para agregar en esta nueva tabla los datos recogidos por el formulario.

Objetivo del capítulo:
Entender y aplicar la sentencia SQL para modificar registros en una tabla.

Siguiendo con el ejercicio, el siguiente proceso en nuestro CAME es modificar.

Supongamos que nuestro cliente se ha equivocado en la cantidad de rayitas que quiere comprar. En este caso tenemos que darle la capacidad de poder modificarlo.

SQL Update

En SQL, modificar se dice UPDATE (poner al día) y la idea es asignar el nuevo al campo o campos de una tabla.

Ejemplo:
UPDATE <tabla> SET campo1=valor1, campo2=valor2 [WHERE]

Traduciendo esta sentencia SQL: Poner al día la <tabla x> y define para el campo1 el valor 1 al capo 2 el valor 2, etc [dónde condición].

En nuestro ejercicio, una manera es vincular a una nueva página que tenga la información del producto seleccionado, pero que el campo cantidad se alimente de la cantidad que ya tenía seleccionada en la tabla de compras y la descripción de la tabla productos.

Llamemos a esta nueva página modificar.php y vinculémosla desde boleta.php con un texto modificar o una imagen, y al igual que hicimos para vincular index.php con producto.php, vamos a llevar variables en la dirección URL, sólo que esta vez llevemos 2, el id de la compra y el código del producto, ambos los podemos obtener de la consulta actual a la página boleta.php.

Columna modificar
Columna modificar
Ejemplo:
<a href="modificar.php?id=<?php echo $row['id'];?>&codigo=<?php echo $row['codigo'];?>">['modificar']</a>

Ahora hagamos la página modificar.php. Como queremos que sea igual a la página del producto.php, tomemos ésta página y guardemosla como modificar.php. A diferencia de productos.php, ésta página va a tener dos consultas, una limitada por el código del producto para alimentar los datos generales y otra consulta a la tabla compras con el parámetro id para saber cuanto había seleccionado.

De partida, eliminemos el query de agregar (INSERT) en las primeras páginas del documento. No eliminemos la consulta, ya que la vamos a modificar un poco.

Ejemplo:
 <?php require_once('conexion.php'); ?>
  <?php
        $query_p=" SELECT * FROM productos WHERE 1 AND codigo='$_GET[codigo]'";
        $resource_p = $conn->query($query_p); 
        $total_p = $resource_p->num_rows;
        $row_p = $resource_p->fetch_assoc();
        $query_c=" SELECT * FROM compras WHERE 1 AND id='$_GET[id]'";
        $resource_c = $conn->query($query_c); 
        $total_c = $resource_c->num_rows;
        $row_c = $resource_c->fetch_assoc();
        ?>

Si te fijas, ahora tenemos dos consultas a la base de datos. La primera consulta por los datos de un producto identificado por la variable que viene por la URL "codigo" y la segunda, consulta por lo datos en la tabla de compra donde el campo "id" es igual al valor de la variable "id" que viene como parte de la dirección con el método GET.

Para evitar conflictos de interpretación del origen de las variables, hemos agregado, a las variables involucradas en la consulta, los sufijos "_p" para la consulta por el producto y "_c" para la consulta a la compra.

Alimentemos ahora el contenido a mostrar en la página, pero esta vez desde la variable "$row_p".

Ejemplo:
<div class="codigo"><?php echo $row_p['codigo'];?></div>
<h2><?php echo $row_p['nombre'];?></h2>
<div id="producto"><img src="images/<?php  echo $row_p['codigo'];?>.gif" alt="<?php echo $row_p['nombre'];?>" width="150" height="150">
<div class="colder">
<?php 
      $la_fecha=$row_p['fecha'];
      list($fec,$hor) = explode(' ', $la_fecha);
      list($ano, $mes, $dia) = explode('-', $fec);
      echo "$dia/$mes/$ano";
      ?>
<br />
<em><?php echo $row_p['categoria'];?></em><br />
</div>
<p><em><?php echo $row_p['frase_promocional'];?></em> <span style="float:right">
<?php if($row_p['promocion']=="1"){?>
<img src="images/promo.gif" width="99" height="80" alt="/>
<?php }?>
</span><br />
<?php echo $row_p['colores'];?></p>
<p><?php echo nl2br($row_p['descripcion']);?></p>

Vamos al formulario. En esta página, ya no necesitamos los campos ocultos que teníamos en producto.php ya que lo único que vamos a modificar en la tabla "compras" es la cantidad que le pondremos como "value" el valor registrado en la tabla de compras.

Vamos a eliminar todos los campos ocultos del formulario y vamos a agregar un campo oculto "id" que se alimentará del "id" de la tabla compra, para tener un parámetro y saber que fila de la tabla queremos afectar con la modificación cuando el usuario apriete el botón "modificar".

Ejemplo:
<form id="compra" name="compra" method="post" action="boleta.php">
<strong>$<?php echo number_format($row_p['precio']);?></strong><br />
<label for="cantidad">cantidad</label>
<input name="cantidad" type="text" id="cantidad" value="<?php echo $row_c['cantidad']; ?>" size="3" maxlength="3" />
<input name="id" type="hidden" id="id" value="<?php echo $row_c['id']; ?>" />
<input type="submit" name="modificar" id="modificar" value="modificar" />
</form>

Nota:
Es común confundir el valor del "id" de las compras con el valor del "id" de los productos, recuerda que estamos modificando las compras realizadas, por lo que ese es el "id" que nos interesa.

Bien, ahora que ya estamos mostrando el mismo producto que nuestro cliente estaba comprando y el formulario refleja la cantidad que estaba comprando, podemos preparar nuestra consulta, para que, al apretar el botón "modificar", efectivamente modifique el registro en la tabla compras al recibir los datos en boleta.php.

Ejemplo:
<?php require_once('conexion.php'); ?>
<?php 
      if(isset($_POST['modificar']) && $_POST['modificar']=="modificar"){
      $query="UPDATE compras SET cantidad = '$_POST[cantidad]' WHERE `id` = '$_POST[id]'";
      $conn->query($query);
      }
      ?>

En las primeras líneas de la página boleta.php, al igual que con el formulario de compras de producto.php, primero condicionamos que exista el valor de la variable "modificar" que viene por el método post y lo obtiene del botón "modificar".

if(isset($_POST['modificar']) && $_POST['modificar']=="modificar"){

Si éste valor existe, entonces construye el SQL para actualizar o modificar los datos con UPDATE. Para no modificar el campo cantidad de todos los registros, usamos el filtraje WHERE para limitar el cambio a la fila que tiene en su campo id el valor que se está pasando por POST.

$query="UPDATE compras SET cantidad = '_POST[cantidad]' WHERE `id` = '$_POST[id]'";

Enviamos nuestra sentencia SQL al método query.

$conn->query($query);
Ejercicio:
  1. Generar una página, que se pueda acceder desde el menú, dónde el usuario pueda ver y modificar sus datos personales registrados.

Objetivo del capítulo:
Entender y aplicar la sentencia SQL para eliminar registros en una tabla.

El último proceso de nuestro CAME es eliminar registros de una tabla.

SQL Delete

En SQL, se eliminan los datos con la orden DELETE (eliminar).

Ejemplo:
DELETE FROM <tabla>  [WHERE];

Traducido dice más o menos: Eliminar de la <tabla X> [dónde condición].

Alerta:
Es importante destacar que cuando se elimina un registro de la tabla es permanente, por lo que el dato no se puede volver a recuperar

Pongamos en práctica esta última orden SQL. Una vez más, abramos nuestro archivo boleta.php y aprovechemos de agregar una opción para eliminar de la tabla de "compras" una compra con la que no estemos de acuerdo.

Agreguemos en la tabla una columna más para la opción "eliminar" o una imagen que lo represente.

Columna eliminar
Columna eliminar

Alerta:
La eliminación de un registro es permanente, por lo que si queremos asegurarnos que el usuario no borre sin querer una compra de la tabla, podemos pasar por una página de advertencia que le diga que se eliminarán los datos y que no son recuperables o usar un poco de javascript.

A este texto (o imagen) lo vinculamos a la misma página boleta.php pero agreguemos a la URL una variable de la cuál nos podamos agarrar para eliminar de la tabla y que sea único, en este caso el campo id, al cuál lo llamaremos idElm.

Ejemplo:
<a href="boleta.php?idElm=<?php echo $row['id'];?>">['eliminar']</a>

Ahora deberíamos estar recibiendo un valor para la variable idElm como parte de la dirección cuando el cliente elimine. Nos vamos al principio del documento y preguntamos si es que existe esta variable y su valor es distinto a nada para construir nuestra sentencia SQL.

Es importante recordar que PHP es un lenguaje lineal, por lo que primero queremos eliminar y después queremos preguntar por las compras para mostrar la boleta. Si lo hacemos al revés, se mostraría el dato eliminado en la compra.

Ejemplo:
<?php require_once('conexion.php'); ?>
<?php 
if(isset($_GET['idElm']) && $_GET['idElm']<>""){
$query="DELETE FROM compras WHERE id='$_GET[idElm]'";
$conn->query($query);
}
?>

Aquí construimos el query con la orden Eliminar (DELETE) de la tabla compras donde el campo id es igual al valor de la variable idElm que viene por el método get.

Si probamos nuestro sistema en un browser, nos daremos cuenta que tenemos construido un sistema rápido para consultar, agregar, modificar y eliminar compras de la tabla o sea CAME.

Ejercicio:
  • Generar una interfaz master/detail, en el directorio nuevo "admin" que permita la administración de los productos de la tienda (CAME).

Nota:
Subir archivos al servidor.

Objetivo del capítulo:
Conocer y usar la capacidad de guardar variables en el servidor para reutilizarlas en las páginas del Sitio en construcción.

Cada vez que nos conectamos a Apache con nuestro navegador generamos en el servidor una relación que se llama sesión (session en Inglés). Esta relación permite saber quién está preguntando (origen de la solicitud) y qué documento está solicitando para poder devolverle el resultado.

PHP se puede montar sobre esta relación para generar persistencia de los datos entre archivos usando el archivo físico de la relación en el servidor, de esta manera podemos traspasar el valor de una variable en sesión de una página a otra.

Creación de sesión

Para poder hacer uso de los valores guardados en la sesión, primero hay que arrancar la capacidad de interactuar con este archivo de texto. La función para partir la sesiones es: session_start().

Pongamos, por ejemplo, la capacidad de restringir el acceso a la página de producto.php o boleta.php a sólo usuarios que se hayan identificado en el sistema y así poder contar con la variable que diferencie quién es el que está comprando.

Para esto incluiremos en ambos archivos la siguiente línea de código:

Ejemplo:
<?php 
if(!isset($_SESSION))session_start();
if(!$_SESSION['user_id']){
$_SESSION['volver']=$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING'];
header("Location: login.php");
}
?>

Analicemos este pedazo de código.

if(!isset($_SESSION))session_start();

En esta primera línea preguntamos si está definida la variable global $_SESSIONS, si no está definida entonces arrancamos las sesiones.

Nota:
Solamente se puede arrancar una sesión por relación por lo que este método protege de gatillar 2 veces la función de iniciar la sesión.

$_SESSION['volver']=$_SERVER['PHP_SELF']."?".$_SERVER['QUERY_STRING'];

En esta línea consultamos a las variables globales de servidor ($_SERVER) por el nombre del documento actual (PHP_SELF) y le concatenamos los valores que tenemos como query en la URL ('QUERY_STRING') y guardándolo en una sesión de servidor que se va a llamar "volver".

header("Location: login.php");

Esta línea redirige la página producto.php o boleta.php a la página login.php si es que no existe la variables user_id registrada en las sesiones.

Nota:
Siempre podemos ver el contenido de la variable "$_SESSION" con la función print_r(), por ejemplo, en el pie de página.
Ej: echo "<pre>",print_r($SESSION,1),"</pre>";

Bien, el siguiente paso es construir la página de identificación ("login.php") dónde le pediremos las credenciales de autenticación al usuario para registrar la variable $_SESSION['user_id'].

Ejemplo:
<form method="post">
<label for="usuario"> usuario: </label>
<input type="text" name="usuario" id="usuario" />
<br />
<label for="clave"> clave: </label>
<input type="text" name="clave" id="clave" />
<br />
<input type="submit" name="ingresar" id="ingresar" value="ingresar" class="boton" />
</form>

Primero construimos un formulario que recoja los datos de autenticación (usuario y clave) y lo enviamos por método POST a la misma página.

Al igual que en los documentos anterior, insertamos en la primera línea del documento la conexión a las base de datos, el arranque de sesión y la consulta a la tabla de clientes para saber si hay registros dónde el usuario y la clave sean idénticos a los entregados.

Ejemplo:
<?php require_once('conexion.php'); ?>
<?php if(!isset($_SESSION))session_start();?>
<?php
	if((isset($_POST['usuario']) && $_POST['usuario']<>"") && (isset($_POST['clave']) && $_POST['clave']<>"") ){
		$query="SELECT * FROM clientes WHERE 1 AND usuario='$_POST[usuario]' AND clave='$_POST[clave]'";
		$resource=$conn->query($query);
		if($t=$resource->num_rows){
		$row=$resource->fetch_assoc();
		$_SESSION['user_id']=$row['id'];
		$_SESSION['nombre']=$row['nombre'];
		$_SESSION['email']=$row['email'];
		$_SESSION['telefono']=$row['telefono'];
		$_SESSION['pais']=$row['pais'];
		$_SESSION['direccion']=$row['direccion'];

		$volver=($_SESSION['volver'])?$_SESSION['volver']:"index.php";
	header("Location: ".$volver);
	} else {
		$error="Usuario/Clave no registrados";
	}
}
?>

Revisemos este fragmento de código.

<?php require_once('conexion.php'); ?>
<?php if(!isset($_SESSION))session_start();?>

Las primeras dos líneas, ya las conocemos, llaman a la conexión a la base de datos y arranca la sesión si no estaba definida antes.

if((isset($_POST['usuario']) && $_POST['usuario']<>"") && (isset($_POST['clave']) && $_POST['clave']<>"") ){

Esta línea pregunta si está definido por método POST las variables "usuario" y "clave" y si ambas tienen valor.

$query="SELECT * FROM clientes WHERE 1 AND usuario='$_POST[usuario]' AND clave='$_POST[clave]'";
$resource=$conn->query($query);

Aquí generamos la consulta SQL a la base de datos dónde el campo "usuario" en la tabla es igual al valor recogido por el campo de formulario "usuario" y los mismo para la "clave".

if($t=$resource->num_rows){
$row=$resource->fetch_assoc();
$_SESSION['user_id']=$row['id'];
$_SESSION['nombre']=$row['nombre'];
$_SESSION['email']=$row['email'];
$_SESSION['telefono']=$row['telefono'];
$_SESSION['pais']=$row['pais'];
$_SESSION['direccion']=$row['direccion'];

Si el resultado de enviar la consulta a la conexión devuelve al menos una fila de resultado ($t=$resource->num_rows) entonces registramos en sesión las variables conocidas del usuario: id, nombre, email, teléfono, país y dirección.

$volver=($_SESSION['volver'])?$_SESSION['volver']:"index.php";

Esta línea también es una condicional if() pero escrita en una sóla línea. La variable $volver siempre va tener valor, si es que existe un valor para la variables $_SESSION['volver'] entonces se queda con ese valor, sino le asigna el valor index.php.

Esta expresión es lo mismo que escribir:

Ejemplo:
if($_SESSION['volver']){
$volver= $_SESSION['volver'];
}else{
$volver="index.php";
}

Este tipo de condicional es muy eficiente en tiempo de escritura, pero siempre requiere dos valores por si es verdadero o no es verdadero.

header("Location: ".$volver);

Al final, reenviamos a la página de donde venía el usuario antes de la autentificación.

} else {
$error="Usuario/Clave no registrados";
}

Por último, si es que la consulta a la base de datos no arroja resultados, generamos una variable "$error" con un mensaje que podemos mostrar cuando se presente el formulario de identificación en blanco de nuevo.

Ejemplo:
<?php if($error){?>
<div class="alert alert-dismissible alert-danger" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
<div><?php echo $error;?></div>
</div> 
<?php }?>

Uso de sesión

Ahora que sabemos quién está viendo el producto o queriendo comprar, cambiemos en nuestro formulario de compra en producto.php el campo oculto de cliente que habíamos definido de manera estática como 1 por la variable del id del usuario registrado en la sesión.

Ejemplo:
<input name="cliente" type="hidden" id="cliente" value="<?php echo $_SESSION['user_id'];?>" />

De la misma manera, filtremos las consultas de la boleta.php para que construya el SQl según el id del usuario registrado en la sesión.

Ejemplo:
$query=" SELECT * FROM compras WHERE 1 AND cliente='$_SESSION[user_id]' ORDER BY fecha DESC";

Nota:
Como ya aplicamos la restricción de acceso a la página la sesión debería haber arrancado en ambas páginas.

Eliminación de sesión.

Para terminar el ciclo de usuario, sería bueno que cuente con la posibilidad de "cerrar" sesión o eliminar los datos en ella, muy útil si estamos en un computador compartido.

Incluyamos, de manera condicionada, en el menú un vínculo a la página logout.php.

Ejemplo:
<?php if($_SESSION['user_id']){?><a href="logout.php">Salir</a><?php }?>

Construyamos una página logout.php con las ordenes para matar la sesión y redirecciónar a la página indice.

Ejemplo:
<?php 
if(!isset($_SESSION))session_start();
foreach($_SESSION as $k => $v){  
$_SESSION[$k] = NULL;
}
session_destroy();
header("Location: login.php");
?>

Revisemos el código de esta página.

if(!isset($_SESSION))session_start();

Arrancamos la sesión si es que no existía.

foreach($_SESSION as $k => $v){
$_SESSION[$k] = NULL;
}

Reasignamos un valor "nulo" a cada variable de sesión usando la función foreach().

Nota:
Esta reasignación de valor es para versiones antiguas de PHP que no destruían bien la sesión, nunca está de más.

session_destroy();
header("Location: login.php");

Por último, usamos la función session_destroy() para destruir la sesión registrada y redireccionamos al archivo de identificación login.php para que el usuario esté claro que ya no está identificado en el sistema.

Ejercicio:
  1. Generar un sistema que permita agregar, modificar o eliminar registros de productos en el directorio admin.
  2. Restringir el acceso a el sistema de administración sólo a usuarios con rol de administradores.

Objetivo del capítulo:
Entender y utilizar la función de mail para enviar datos desde una página a un correo electrónico.

Perfecto, ahora si tenemos un sistema de compra completo, desde la selección del producto, pasando por la identificación del usuario, hasta la muestra de todas sus compras, falta que nosotros nos enteremos que el usuario ha terminado el proceso de compra, por lo que los datos recogidos en boleta.php y aprobado por el cliente, debería generar un par de e-mails, uno que nos avise de los datos del cliente y los productos que quiere comprar y otro que le confirme la solicitud de compra para que se quede tranquilo.

Enviar un mail

La función mail() envía un correo electrónico. Ya que ni Apache ni PHP son los encargados realizar este proceso, es necesario hablar con el servidor de correo electrónico instalado en nuestro sistema operativo.

Alerta:
Si bien muchos sistemas base linux viene son sendMail o Postfix instalados, esto no significa que estén configurados para poder enrutar correos electrónicos. Esta parte del ejercicio es probable que sólo funcione en un servidor que tenga configurado y vinculado un servicio de correo electrónico.

La función mail() está compuesto de 4 parámetros:

Ejemplo:
<?php 
mail(<destinatario>,<asunto>,<cuerpo>,<cabecera>);
?>

Destinatario

A quien va dirigido el e-mail. Generalmente un correo electrónico, pero se puede personalizar encerrando el e-mail dentro de signos menor qué y mayor qué (< y >) después del nombre del destinatario.

Ejemplo:
"Caperucita Roja <caperuza@deferoz.cl>"

Asunto o tema

Aquí se define el asunto del correo. Recordemos que el formato de un correo electrónico viene del concepto del memo y es el tema el que permite discriminar y dar prioridad a los correos entrantes. En los programas para leer correos electrónicos lo que se ve es el listado e-mails de quienes lo envían y el tema del correo.

Cuerpo

El cuerpo de un correo electrónico es dónde va el contenido del mensaje. En él se puede poner varias líneas de mensaje y, con el formato adecuado, hasta contenido HTML y adjuntar imágenes.

Cabecera

La cabecera de un correo electrónico lleva la información del remitente, copias, formatos, fecha de envío, dirección de respuesta y otros. Éste es un estándar de la web y lo que lo caracteriza es que el atributo parte siempre con mayúsculas y se separan por saltos de línea.

Ejemplo:
<?php 
$destinatario="Caperucita Roja <caperuza@deferoz.cl>";
$asunto="Contacto desde la página WEB";
$cuerpo="Este es el cuerpor del documeto.";
$cabecera = "From: $nombre<$email>\r\n";
$cabecera .= "Reply-To: $email\r\n";
$cabecera .= "Return-Path: $email\r\n";
$cabecera .= "Errors-To: $email";
mail("$destinatario", "$asunto", "$cuerpo", "$cabecera");
?>

Bien, ahora que ya sabemos como enviar un correo, agreguemos en boleta.php un botón de formulario "comprar" que se vincule en el action con una página nueva que vamos a llamar compra.php.

Vínculo a comprar
Vínculo a comprar

Diseñemos esta nueva página igual que boleta.php, pero sin las opciones de modificar la compra, se supone que ya realizó la compra a esta altura. A esta página habría que aplicar una restricción de acceso para que contemos con la variable del usuario que está comprando.

Esta página va a servir de confirmación de la compra, por lo que podemos agregar algunos datos del proceso, aparte de los productos que se están comprando, como el código de la orden de compra, los datos del cliente y la sugerencia de que lo imprima.

Para esto necesitamos realizar una segunda consulta para tener todos los datos de nuestro cliente basado en el nombre de usuario de la sesión.

Ejemplo:
$query="SELECT * FROM clients WHERE 1 AND id='$_SESSION[user_id]'";
$resource=$conn->query($query);
$row=$resource->fetch_assoc();

Ahora que ya estamos mostrando un documento más formal, al inicio de la página compra.php, después de ambas consultas, construyamos el cuerpo del mail que vamos a enviar al encargado de compras de la empresa Rayita S.A. y al dueño de la empresa cuando se cargue la página, con suficiente información para que sepan que hubo una compra, quién la hizo y qué compró.

Ejemplo:
<?php 
$cuerpo="El usuario ".$row['nombre']." ha realizado una compra en el sitio web:
Nombre: ".$row['nombre']."
Email: ".$row['email']."
Teléfono: ".$row['telefono']."
Dirección de entrega: ".$row['direccion']."
Pais: ".$row['pais']."
_______________________________________________
";
?>

Ahora necesitamos construir la cabecera del correo electrónico:

Ejemplo:
<?php 
$cabecera = "From: ".$row['nombre']."<".$row['email'].">\n";
$cabecera .= "Reply-To: ".$row['email']."\n";
$cabecera .= "Cc: gerente@rayita.cl\n";
?>

Nota:
En el ejemplo puedes ver que estamos aprovechando de incrementar la variable cabecera con la concatenación punto igual (.=)

Y por último enviamos el correo:

Ejemplo:
<?php
$destinatario="ventas@rayitas.cl";
$asunto="Venta de rayitas desde el sitio WEB";
mail("$destinatario", "$asunto", "$cuerpo", "$cabecera");
?>

El resultado de esta función no la podemos ver en la página, pero si cuando nos llegue el correo, como ya sabemos quien nos envía el correo, podemos ir a nuestra base de datos y ver que fue lo que el usuario compró.

Código correo
Código correo
Ejercicio:
  1. Agreguemos un vínculo nuevo al menú que nos lleve a una página contacto.php que permita al cliente mandar un correo a contacto@rayitas.cl con copia a tu correo personal.

Realizar páginas dinámicas utilizando la interacción entre el servidor, base de dato y lenguaje de programación no es difícil - como lo hemos demostrado- si tenemos los servicios necesarios instalados en nuestro equipo (Apache, PHP y MySql) y si contamos con una idea general de qué hacen éstos y cómo se interrelacionan.

Los pasos utilizados para la aplicación de este ejemplo son replicables para otros lenguajes de programación del lado del servidor, como ASP, ColdFusion o JSP, lo único que varían son algunos programas necesarios en la máquina donde estamos desarrollando y la sintaxis, pero la lógica es la misma.

Sistema rayitas
Sistema rayitas

El ejemplo tratado en este manual, muestra un sencillo sistema de CAME, fácilmente "migrable" a otros requerimientos, por ejemplo: un libro de visita donde hay que mostrar datos de una consulta y/o agregar datos a una tabla. Una agenda personal donde hay que "mostrar datos", "agregar datos", "modificar datos" o "eliminar datos", etc. Lo que varía son las complejidades de los verificadores de estos pasos sencillos y la presentación.

Puede ser interesante como ejercicio y práctica de los conocimientos adquiridos, el realizar un sistema sencillo de administración para que nuestro cliente Rayitas S.A. pueda administrar el contenido de la tabla de productos, clientes y compras.

Sobre Apache, PHP y MySql se han escrito muchos tratados, si queremos hacer consultas más complejas a una BD, operaciones más finas en la programación, o alteraciones al dominio o subdominio de nuestro servidor, hay varios sitios dónde comenzar a buscar, lo primero es ponerse una meta, entender que elementos lo componen y dónde estamos más débiles para comenzar.

Y por último, la experticia está en la experiencia. Entre más hagamos, más rápido nos saldrá y más claro tendremos lo que estamos haciendo.

Bibliografía

  • "PHP"
    Larry Ullman.
    Editorial Prentice Hall
    Guia de aprendizaje
  • "PHP advanced for the World Wide Web"
    Larry Ullman.
    Visual quickpro guide
    Editorial Peachpit Press
  • "PHP and MySQL for dynamic web sites"
    Larry Ullman
    Editorial Peachpit Press
    Visual quickpro guide
  • "Aprendiendo MySQL en 21 días"
    Mark Maslakowski
    Prentice Hall
  • "Programación : Ajax, Javascript Y PHP"
    Ballard, Phil
    Anaya Multimedia

Webliografía