PHP y el scripting de servidor
La otra mitad de la aplicación: qué lenguajes se usan en el servidor y con qué ecosistema, la sintaxis y la orientación a objetos de PHP, cómo se mantiene el estado con sesiones y cookies, cómo se ejecuta PHP dentro de un servidor web y qué pilas y frameworks lo rodean.
Qué es el scripting de servidor y con qué lenguajes se hace
Los lenguajes de scripting son lenguajes interpretados: no se compilan a un ejecutable, sino que un intérprete los lee y los ejecuta en el momento. Cuando ese intérprete está en el servidor, se habla de scripting de servidor o back-end: el código se ejecuta en la máquina que sirve la aplicación y el usuario nunca lo ve, solo recibe su resultado.
Cada lenguaje del servidor viene acompañado de un ecosistema que hay que saber emparejar, porque las preguntas suelen mezclar las columnas: un gestor de paquetes con su fichero de dependencias y su repositorio, y uno o varios frameworks web.
| Lenguaje | Gestor de paquetes | Fichero | Frameworks web |
|---|---|---|---|
| PHP | Composer | composer.json | Laravel, Symfony, CakePHP, CodeIgniter |
| Ruby | Gems | Gemfile | Ruby on Rails, Roda, Cuba |
| Python | Pip | setup.py | Django, Pyramid, Flask |
| Perl | PPM | - | Catalyst |
| JavaScript | npm | package.json | Express, sobre Node.js |
El fichero de dependencias es siempre la pieza central: declara qué librerías necesita el proyecto y con qué versiones, y el gestor se encarga de descargarlas junto con las dependencias transitivas, es decir, las que a su vez necesitan esas librerías. Composer las deja en un directorio llamado vendor y npm en node_modules.
Cada lenguaje se ejecuta sobre su propio motor. En PHP es el Zend Engine, que juega el papel que la máquina virtual juega en Java. En el JavaScript de servidor es V8, dentro de Node.js.
Composer va con composer.json y el directorio vendor; npm va con package.json y node_modules. Es el emparejamiento que más se pregunta de esta tabla.
Para el examen
Composer: composer.json y el directorio vendor
npm: package.json y node_modules
PHP: sintaxis, tipos y variables superglobales
El código PHP se intercala dentro del HTML entre las marcas de apertura y cierre. El servidor ejecuta lo que hay entre ellas y sustituye ese trozo por su salida, de modo que al navegador solo le llega HTML. Las variables llevan siempre un dólar delante y no se declara su tipo.
<?php
$curso = 'largo';
$aciertos = 18;
$total = $aciertos . ' de 20'; // el punto concatena, no el +
$temas = array('HTML', 'XML', 'Scripting');
$notas = ['q1' => 8.5, 'q2' => 4.0]; // array asociativo: se accede por clave
// Comillas simples: NO resuelve la variable -> imprime $curso
echo 'Curso: $curso';
// Comillas dobles: SÍ la resuelve -> imprime Curso: largo
echo "Curso: $curso";
echo $notas['q1']; // 8.5
?>Los tipos de dato de PHP son Integer, Float, String, Array, Object, Boolean, NULL y Resource. Este último es peculiar: representa un recurso externo abierto, como el manejador que devuelve fopen al abrir un fichero, y no se puede inspeccionar como los demás.
| Operador | Qué hace |
|---|---|
| . | Concatena cadenas. En PHP el signo más es solo suma |
| == | Compara solo el valor, convirtiendo tipos |
| === | Compara valor y tipo, como en JavaScript |
| <=> | Operador nave espacial: devuelve -1, 0 o 1 según el primero sea menor, igual o mayor que el segundo |
| ?? | Fusión de null: devuelve el primer operando si existe y no es null, y si no el segundo |
Las variables superglobales son arrays que PHP crea solos en cada petición y que están accesibles desde cualquier ámbito sin declararlos. Son la puerta de entrada de todo lo que llega del cliente, y por eso son el sitio exacto donde hay que desconfiar y validar.
| Superglobal | Qué contiene |
|---|---|
| $_GET | Los parámetros que viajaron en la URL |
| $_POST | Los datos enviados en el cuerpo de un formulario |
| $_REQUEST | La mezcla de los anteriores más las cookies |
| $_FILES | Los ficheros subidos por el usuario |
| $_COOKIE | Las cookies que ha mandado el navegador |
| $_SESSION | Los datos guardados en la sesión del usuario |
| $_SERVER | Información del servidor y de la propia petición |
<?php
// Fusión de null: si no viene el parámetro, valor por defecto
$curso = $_GET['curso'] ?? 'express';
// Equivale exactamente a esto, que es la forma antigua:
$curso = isset($_GET['curso']) ? $_GET['curso'] : 'express';
// Nunca dar por bueno lo que llega del cliente
if (!in_array($curso, ['express', 'mediano', 'largo'], true)) {
http_response_code(400);
exit('Curso no válido');
}
// Comentarios: // o # en una línea, /* ... */ en varias
?>Para el examen
Las variables: llevan dólar delante y no se declara su tipo
Superglobales: arrays que PHP crea en cada petición
Por qué importan: son la puerta de entrada de lo que llega del cliente: ahí hay que validar
PHP orientado a objetos: clases, herencia, magic methods y traits
PHP incorpora un modelo de objetos muy parecido al de Java, con algunas diferencias de nomenclatura que conviene tener claras porque son las que se preguntan.
| Concepto | En PHP | Equivalente en Java |
|---|---|---|
| Constructor | __construct() | El método con el nombre de la clase |
| Destructor | __destruct() | finalize() |
| Referencia al propio objeto | $this-> | this |
| Referencia a la clase padre | parent:: | super |
| Acceso a un miembro estático | Clase::metodo() y self:: desde dentro | Clase.metodo() y this para lo no estático |
| Comprobar el tipo de un objeto | instanceof | instanceof |
<?php
class Tema {
public $titulo;
protected $nivel;
private $slug;
public function __construct($titulo, $nivel) {
$this->titulo = $titulo;
$this->nivel = $nivel;
}
public function ficha() {
return $this->titulo . ' (nivel ' . $this->nivel . ')';
}
}
final class TemaOficial extends Tema { // final: nadie puede heredar de esta
public function ficha() {
return 'BOE: ' . parent::ficha();
}
}
$t = new TemaOficial('Aplicaciones web', 1);
echo $t->ficha();
var_dump($t instanceof Tema); // true
unset($t); // elimina el objeto
?>PHP no admite herencia múltiple: una clase solo puede extender a otra. Los tres niveles de visibilidad son public, accesible desde cualquier sitio; protected, accesible desde la clase y sus descendientes; y private, accesible solo desde la propia clase. La palabra final impide sobrescribir un método o heredar de una clase.
Los magic methods son métodos cuyo nombre empieza por dos guiones bajos y que PHP invoca solo cuando sucede determinado evento sobre el objeto. Sirven sobre todo para interceptar el acceso a propiedades que no son accesibles directamente. Los más citados son __construct y __destruct, __get y __set para leer y escribir propiedades inaccesibles, __call para llamadas a métodos que no existen, y __sleep y __wakeup para la serialización.
Los traits, o rasgos, son la respuesta de PHP a la falta de herencia múltiple. Un trait es un paquete de métodos que se le puede dar a una clase sin que exista relación de herencia: es programación por composición. Cuando dos traits aportan métodos que se llaman igual, la ambigüedad se resuelve de forma explícita eligiendo cuál prevalece, y se pueden crear alias. El orden de precedencia es fijo: gana el método de la propia clase, después el del trait y en último lugar el heredado del padre.
<?php
trait Cronometrable {
public function iniciar() { return 'Contando el tiempo del intento'; }
}
trait Puntuable {
public function iniciar() { return 'Preparando el marcador'; }
}
class Test {
use Cronometrable, Puntuable {
Cronometrable::iniciar insteadof Puntuable; // se elige uno
Puntuable::iniciar as prepararMarcador; // y se le da alias al otro
}
}
$test = new Test();
echo $test->iniciar(); // Contando el tiempo del intento
echo $test->prepararMarcador(); // Preparando el marcador
?>Precedencia en PHP: método de la clase, luego método del trait, luego método heredado. Si un método del trait choca con uno de la clase, gana el de la clase.
Para el examen
Orden de precedencia: método de la clase, luego del trait y luego el heredado
Si un método del trait choca con uno de la clase: gana el de la clase
Cómo se ejecuta PHP dentro de un servidor web
Un servidor web como Apache sabe servir ficheros estáticos, pero no sabe interpretar PHP. Para que una petición a una página PHP funcione hay que enchufarle un intérprete, y hay dos formas de hacerlo que se comportan igual de cara al usuario y muy distinto en rendimiento.
La primera es el módulo incrustado, mod_php: el intérprete de PHP vive dentro del propio Apache. Cada vez que llega una petición de una página PHP, Apache crea una réplica de sí mismo para atenderla, lo que significa que hasta las peticiones de imágenes o de hojas de estilo arrastran el peso del intérprete.
La segunda es el proxy FastCGI, mod_proxy_fcgi. Aquí Apache no interpreta nada: reenvía la petición a un proceso externo, el gestor FPM (FastCGI Process Manager), que mantiene una reserva de procesos intérpretes de PHP ya arrancados y le pasa el trabajo a uno de ellos. Apache se queda solo con los recursos estáticos.
| mod_php | mod_proxy_fcgi con FPM | |
|---|---|---|
| Dónde vive el intérprete | Dentro del proceso de Apache | En procesos externos gestionados por FPM |
| Qué se replica en cada petición | El propio Apache, con el intérprete dentro | Solo un proceso intérprete de la reserva |
| Recursos estáticos | Los sirve Apache cargando también PHP | Los sirve Apache sin intérprete |
| Resultado funcional | El mismo: HTML tras ejecutar el PHP | El mismo |
| Rendimiento | Peor, sobre todo con mucha carga estática | Mejor: reserva de procesos y separación de tareas |
A nivel funcional las dos hacen lo mismo: servir HTML después de ejecutar el código PHP. La diferencia está en el rendimiento y en qué proceso se replica.
Para el examen
Módulo del servidor y PHP-FPM: hacen lo mismo a nivel funcional
Dónde está la diferencia: en el rendimiento y en qué proceso se replica
Arquitecturas JavaScript de extremo a extremo: MEAN, MERN y MEVN
El problema que estas arquitecturas atacan es el coste de traducir. En una aplicación cliente-servidor clásica, un mismo dato cambia de forma varias veces en un solo viaje: de filas de SQL a objetos, de objetos a JSON para mandarlo al navegador, y de JSON a objetos otra vez al llegar. Cada traducción cuesta tiempo y es una fuente de errores.
La idea de estas pilas es usar JavaScript y JSON de punta a punta para que no haga falta traducir en ningún tramo. Por eso se las llama arquitecturas de extremo a extremo, o end to end.
| Sigla | M | E | Tercera letra | N |
|---|---|---|---|---|
| MEAN | MongoDB | Express | Angular | Node.js |
| MERN | MongoDB | Express | React | Node.js |
| MEVN | MongoDB | Express | Vue.js | Node.js |
- MongoDB es una base de datos NoSQL documental que guarda los datos ya en forma de documentos JSON.
- Express es el framework web que corre sobre Node.js en el servidor.
- Angular, React o Vue.js son el framework del navegador, y manejan JSON de forma nativa.
- Node.js es el entorno de ejecución de JavaScript en el servidor.
El resultado es que la información viaja en JSON entre la base de datos y el servidor, y otra vez en JSON entre el servidor y el front-end, sin transformarse en ningún punto del recorrido. Lo único que cambia entre las tres pilas es el framework de cliente, que es lo que da la tercera letra.
Para el examen
Lo que comparten las tres: MongoDB, Express y Node.js
Su ventaja: JavaScript y JSON de extremo a extremo
Lo único que cambia: la tercera letra: Angular, React o Vue
Pilas de instalación, productos hechos en PHP y Laravel
Montar a mano un entorno de PHP obliga a instalar el servidor web, habilitar el módulo de PHP, instalar la base de datos y configurarlo todo. Para ahorrárselo existen paquetes que traen todo preinstalado y que se nombran con siglas de cuatro o cinco letras, en las que cada letra ocupa siempre la misma posición.
| Posición | Qué designa | Valores |
|---|---|---|
| Primera | El sistema operativo | L de Linux, W de Windows, M de Mac, X si es multiplataforma |
| Segunda | El servidor web | A de Apache, E de Nginx, I de IIS |
| Tercera | La base de datos | M de MySQL o MariaDB |
| Cuarta | El lenguaje | P de PHP, y también de Perl o Python |
| Quinta | Un segundo lenguaje | P: la pila trae a la vez PHP y Perl |
Así, LAMP es Linux con Apache, MySQL y PHP; WAMP es la misma pila sobre Windows; MAMP sobre Mac; LEMP cambia Apache por Nginx; WIMP es Windows con IIS; y XAMPP es la versión multiplataforma con las dos pes. EasyPHP es otro paquete de la misma idea.
Buena parte de la web funciona con productos escritos en PHP, y conviene saber a qué se dedica cada uno: Moodle es una plataforma de cursos en línea, phpBB un gestor de foros, Alfresco un gestor documental, Magento, OSCommerce y Prestashop son tiendas en línea, y WordPress, Joomla y Drupal son gestores de contenido para portales y noticias.
El framework de PHP más extendido hoy es Laravel. Su reparto de herramientas es paralelo al de Angular: un comando crea el proyecto y otro, la interfaz de línea de comandos llamada artisan, se encarga de todo lo demás.
| Componente de Laravel | Para qué sirve |
|---|---|
| laravel new / php artisan serve | Crear el proyecto y levantarlo, igual que ng new y ng serve |
| Model | Las clases de negocio: alumnos, temas, intentos |
| Controller | Recibe las peticiones HTTP; hace el papel de un servlet |
| Seeder | Llena la base de datos con datos de prueba escritos a mano |
| Factory | Llena la base de datos de forma masiva, con datos inventados por la librería Faker |
| Migrations | Versiona los cambios del esquema de base de datos |
Las migraciones merecen atención aparte porque son la pieza que hace reproducible una base de datos. Cada migración programa dos métodos: up, que aplica el cambio, y down, que lo deshace. Ejecutar php artisan migrate aplica todas las migraciones que aún no se hayan ejecutado, de modo que cualquier entorno puede ponerse al día con un solo comando.
Para hablar con la base de datos sin escribir SQL a mano, cada framework trae su motor de persistencia u ORM: Laravel usa Eloquent y Symfony usa Doctrine.
Para el examen
Orden de las letras: sistema, servidor web, base de datos y lenguaje
LAMP: Linux, Apache, MySQL y PHP
WAMP y LEMP: sobre Windows, y con Nginx en vez de Apache
XAMPP: la pila multiplataforma
Laravel: el framework PHP más extendido