Desarrollo Web en Entorno Servidor
Desarrollo Web en Entorno Servidor
Desarrollo Web en Entorno Servidor
Para que nuestro servidor pueda saber qué documentos tiene que compilar
debemos indicarlo mediante la extensión de los archivos que contienen
nuestras páginas web. Hasta el momento hemos visto documentos con formato
.html que se podían abrir directamente desde el navegador. Ahora, sin
embargo, deberemos crear documentos con extensiones .php, .asp o .jsp. De
esta manera el compilador abrirá estos archivos y los ejecutará internamente
mostrando el contenido que hayamos querido servir al usuario. Lo malo que
hay que tener en cuenta es que, una vez empezamos a construir una
aplicación que interviene lenguaje del lado del servidor, dejamos de poder
visualizar los archivos simplemente con nuestro navegador, ya que cuando
tienen esas extensiones han de ser procesados por un servidor (Figura 2).
Figura 2. Podemos instalar un servidor Apache/PHP para poder ejecutar
archivos .php desde nuestro ordenador.
Módulo. Desarrollo web en entorno
servidor
/www/ciudades/barcelona/personas/alex.php
Puede que para el SEO esta dirección penalice en los buscadores, ya sea
porque es demasiado larga o porque los conceptos ciudades y personas son
tan genéricos que no proporcionan información relevante. En estos casos
podemos crear un archivo en nuestro servidor que traduzca determinadas
direcciones en rutas internas utilizando expresiones regulares (Figura 3).
Figura 3. Ejemplo de expresiones regulares.
http://www.pagina.com/personas?nombre=Alex
<?php
$servername = "localhost";
$username = "username";
$password = "password";
$dbname = "myDB";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
if ($result->num_rows > 0) {
// Imprimimos todos los nombres
while($row = $result->fetch_assoc()) {
echo "id: " . $row["id"]. " - Name: " . $row["firstname"].
" " . $row["lastname"]. "<br>";
}
} else {
echo "0 results";
}
$conn->close();
?>
$.ajax({
method: "GET",
url: "http://www.pagina.com/personas",
data: { nombre : ‘Alex’},
dataType: "html"
});
Es evidente que el 90% de las veces seremos nosotros los que nos
encarguemos tanto de crear el formulario en HTML como de procesar la
información que enviamos al servidor. Por lo tanto, seremos los que mejor
sabremos cómo esperamos recibir la información. Pero, ¿y si queremos crear
un sistema que procese las peticiones independientemente del formato en el
que nos llegan GET o POST?
<?php
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'PUT': break;
case 'POST':
$nombre=$_POST[‘nombre’];
$apellido=$_POST[‘apellido’];
break;
case 'GET':
$nombre=$_GET[‘nombre’];
$apellido=$_GET[‘apellido’];
?>
<?php
//recibimos la información
$nombre=$_REQUEST[‘nombre’];
$apellido=$_REQUEST[‘apellido’];
?>
<?
//1. Entorno de trabajo
define('DEV_ENV', 1);
define('STAGING_ENV', 2);
define('PRODUCTION_ENV', 0);
2. Como cada uno de estos entornos tendrá una URL diferente, y la mejor
manera de saber si estamos trabajando en un entorno u otro es detectando las
diferencias en la URL. Si hacemos que el subdominio “desarrollo” esté
vinculado al entorno de pruebas, basta con detectar esta palabra en la
dirección. Posteriormente podremos guardar el entorno en el que estamos en
una constante “ENVIRONMENT” para utilizarla a lo largo de la aplicación. Para
poner un ejemplo, imaginad que implementamos un gestor de usuarios y
queremos testear si funciona la opción de borrar usuarios. Nuestra intención no
será borrar usuarios reales y activos, por lo tanto con la constante
ENVIRONMENT podremos decidir si ejecutar las opciones en la base de datos
de producción o en la de testeo.
5. Así como pasa con los diseños, los idiomas suelen ser archivos separados
del resto del programa, donde se almacenan en arrays todas aquellas frases y
palabras que se visualizan en la web. De esta manera, si incorporamos nuevos
idiomas, solo tenemos que cambiar estas palabras creando en la carpeta de
idiomas archivos que las contengan. Por ejemplo, english.php, spanish.php,
etc. Cuando el usuario seleccione un idioma en la página web, nuestro sistema
simplemente cargará el archivo correspondiente.
Por lo tanto, cuando hablamos de acceder a datos desde una aplicación web,
nos referimos realmente a que la página web hace una petición a un
documento dentro del servidor, que será el encargado de gestionar dicha
petición y devolver el resultado, ya sea mediante código HTML, que se
escribirá directamente en la página, o a través de una cadena JSON, que será
procesada desde el lado del cliente con JavaScript.
La librería PDO de PHP hace que podamos gestionar las bases de datos,
orientado a un objeto principal del que se desprenden todas las sentencias,
desde la conexión hasta la ejecución de queries. Además, gestiona las
conexiones de forma autónoma, así que ya no tendremos que preocuparnos de
abrir y cerrar conexiones cuando realizamos consultas. Simplemente
configuramos la conexión la primera vez y luego solo hacemos operaciones de
SELECT, INSERT, etc.
<?php
//antiguamente para acceder a la base de datos se hacía así:
$link = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('testdb', $link);
mysql_set_charset('UTF-8', $link);
$result = mysql_query("SELECT * FROM table", $link) or die(mysql_error($link));
$num_rows = mysql_num_rows($result);
while($row = mysql_fetch_assoc($result)) {
echo $row['field1'].' '.$row['field2']; //etc...
}
mysql_close($link);
Recordemos que una sesión es una conexión entre el navegador del usuario y
nuestro servidor y que dura desde el momento en el que se establece la
conexión hasta que se cierra el navegador. Estas conexiones son únicas, es
decir, no se pueden suplantar ni se pueden transferir a otro navegador o
usuario, lo que garantiza un nivel de seguridad necesario para la autenticación
de dicho usuario.
Imaginemos una aplicación web que gestiona los usuarios de una empresa. Lo
primero que solicitará será un nombre de usuario y contraseña en un formulario
que enviará a nuestro código dentro del servidor y comparará con nuestra base
de datos (operación de lectura), donde podrá comprobar el nivel de seguridad
que tiene ese usuario (empleado, administrador, técnico, etc.). Si el usuario y la
contraseña son correctos, definiremos en la sesión un parámetro que
llamaremos “rol”, en el que guardaremos el nivel de seguridad de ese usuario.
Este parámetro se mantendrá guardado siempre que el usuario no cierre la
ventana de su navegador.
Por lo tanto, cuando este usuario va a la sección de administrar usuario y pide
modificar alguna información, desde nuestro código lo primero que tendremos
que hacer será comprobar la sesión “rol” y ver si tiene los permisos necesarios.
Si es así, nuestro programa seguirá ejecutando la petición sin problema. Si por
el contrario el usuario no tiene permisos o no tiene definido este parámetro en
sus variables de sesión, simplemente pararemos la ejecución y avisaremos al
usuario de que no tiene permisos para realizar dicha acción. Veamos a
continuación un ejemplo de cómo acceder a la variable de sesión para verificar
los permisos de un usuario que esté intentando realizar modificaciones en
nuestra base de datos desde el navegador web.
Módulo. Desarrollo web en entorno
servidor
[T1] Transacciones
En el módulo de bases de datos tratamos con profundidad el tema de las
transacciones a nivel de bases de datos. En este capítulo volveremos a hablar
de ellas haciendo un repaso para recordar su funcionalidad y desarrollaremos
en profundidad cómo utilizarlas, no desde el propio motor de la base de datos,
sino desde el lenguaje de programación.
<?php
try {
$mbd = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2', array(PDO::ATTR_PERSISTENT => true));
echo "Conectado\n";
} catch (Exception $e) {
die("No se pudo conectar: " . $e->getMessage());
}
try {
$mbd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$mbd->beginTransaction();
$mbd->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')");
$mbd->exec("insert into salarychange (id, amount, changedate) values (23, 50000, NOW())");
$mbd->commit();
Podemos ver como PDO, que funciona como una clase, permite el método
beginTransaction(). Todo lo que venga después de esa sentencia será
procesado de manera “temporal” hasta que se llame al método commit(). Este
último, así como ocurría en las transacciones MySQL, era el encargado de
convertir en permanentes los cambios realizados por las sentencias dentro de
la transacción.
Pero ¿qué ocurre si alguna de ellas falla? Por definición, cuando ocurre un
error, la base de datos devuelve un código de error. Es en ese momento
cuando es capturado por la sentencia try-catch, que detiene la ejecución en ese
el punto en el que se produce el error y continúa la ejecución en el bloque del
catch().
Dentro de las llaves del catch(), podemos ver una nueva sentencia que
conocemos del tema de bases de datos: rollBack(). Esta será la encargada de
decirle a la base de datos que todo lo que hizo después de haber llamado al
método beginTransaction() ha de ser eliminado.
Módulo. Desarrollo web en entorno
servidor
2. Los mensajes deben ser XML, excepto para datos anexos binarios.
<?xml version="1.0"?>
<definitions name="AritmeticaServicio"
targetNamespace="urn:Aritmetica"
xmlns:tns="urn:Aritmetica"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
<message name="AritmeticaPeticion">
<part name="operando1" type="xsd:float" />
<part name="operando2" type="xsd:float" />
</message>
<message name="AritmeticaRespuesta">
<part name="respuesta" type="xsd:float" />
</message>
<portType name="AritmeticaPort">
<operation name="sumar">
<input message="tns:AritmeticaPeticion" />
<output message="tns:AritmeticaRespuesta" />
</operation>
<operation name="restar">
<input message="tns:AritmeticaPeticion" />
<output message="tns:AritmeticaRespuesta" />
</operation>
</portType>
<service name="AritmeticaServicio">
<port name="AritmeticaPort" binding="tns:AritmeticaBinding">
<soap:address location="http://ejemplo.com/test/wsdl/aritmetica_server.php" />
</port>
</service>
</definitions>
<?php
if(!extension_loaded("soap")){
dl("php_soap.dll");
}
ini_set("soap.wsdl_cache_enabled","0");
$server = new SoapServer("aritmetica.wsdl");
function sumar($operando1,$operando2){
return $operando1+$operando2;
}
function restar($operando1,$operando2){
return $operando1-$operando2;
}
$server->AddFunction("sumar");
$server->AddFunction("restar");
$server->handle();
?>
<?php
try{
$clienteSOAP = new SoapClient('http://ejemplo.com/test/wsdl/aritmetica.wsdl');
echo "la suma de 2.7 mas 3.5 es: " . $resultado_suma . "<br/>";
echo "la diferencia de 2.7 menos 3.5 es: " . $resultado_resta . "<br/>";
} catch(SoapFault $e){
var_dump($e);
}
?>
La instancia del cliente SOAP se construye de una manera muy similar a como
lo hicimos en el ejemplo de código Perl, pasándole como argumento la URL en
la que se encuentra el documento que contiene la especificación wsdl (que
previamente deberemos haber copiado al servidor).