Cómo crear una API de RESTful con PHP desde cero, para acceso a base de datos MySQL o MariaDB. Estos métodos permitirán acceder a nuestra base de datos desde cualquier dispositivo o aplicación y realizar tareas de inserción de registros, eliminación de registros, modificación de registros y selección de registros. Se incluye la descarga del código fuente completo en PHP de esta API RESTful de ejemplo.
- Definición de API de REST o API de RESTful.
- Seguridad del API RESTful.
- Base de datos MySQL o MariaDB.
- Servidor con Apache o Nginx para las peticiones PHP.
- Fichero PHP de conexión a la base de datos BaseDatos.php.
- Fichero PHP de métodos para el API RESTful Metodos.php con insertar.
- Fichero PHP para insertar registro en base de datos con API RESTful.
- Probar uso de API RESTful con Postman.
- Probar API RESTful con comando curl.
- Añadir método para modificar registros en fichero Metodos.php.
- Crear fichero PHP para modificar registros con API RESTful.
- Añadir método para listar registros en fichero Metodos.php.
- Crear fichero PHP para listar registros con API RESTful.
- Añadir método para eliminar registros en fichero Metodos.php.
- Crear fichero PHP para eliminar registros con API RESTful.
- Descarga del código fuente completo del ejemplo de API RESTful en PHP.
Definición de API de REST o API de RESTful
Se trata de una interfaz de programación de aplicaciones (API o web API) que se ajusta a los límites de la arquitectura REST (estilo de arquitectura software para sistemas hipermedia distribuidos como la World Wide Web) y permite la interacción con los servicios web de RESTful (servicio web que implementa la arquitectura REST).
Sus principios son:
- Arquitectura cliente-servidor: separación de responsabilidades. Cuanto menos conoce el servidor sobre el cliente más desacoplada está su interacción y más fácil resulta el cambio de componentes. Por definición, REST es una arquitectura diseñada para funcionar con sistemas distribuidos centralizados.
- Ausencia de estado: el estado se guarda y mantiene en el cliente y no en el servidor. Las solicitudes deben proveer toda la información necesaria para poder realizarse en un servidor que no mantiene estados, por lo que no guarda contexto entre llamadas para un mismo cliente.
- Habilitación y uso de la caché: todas las solicitudes deben declarar si son o no cacheables. Una forma estándar de hacerlo es con los encabezados cache-control de HTTP. De esta forma, se pueden enviar respuestas cacheadas desde cualquier punto de la red sin necesidad de que la petición llegue al servidor. Pese a que en el caso de una API dinámica esto puede parecer no tener sentido, puede ahorrar costes en casos de datos inmutables, como definiciones.
- Sistema por capas: tiene relación con la separación de responsabilidades anteriormente mencionada, y establece que un cliente debe conocer únicamente la capa a la que le está hablando. Es decir, no debe tener en cuenta aspectos concretos, como particularidades de la base de datos usada; o abstracciones como cachés, proxies o balanceadores de carga implicados. Si se necesita seguridad, esta se debe añadir encima de los servicios Web, permitiendo que la lógica y seguridad permanezcan separadas.
- Interfaz uniforme:
- Identificación de recursos en las peticiones: las solicitudes identifican a recursos individuales. Sin embargo, REST hace hincapié en que que los recursos están conceptualmente separados de las representaciones que son devueltas por el servidor (HTML, XML, JSON, etc.). El tipo de formato se puede especificar en las cabeceras HTTP y, mediante negociación de contenido, servidor y cliente pueden ponerse de acuerdo en la respuesta que mandará el primero y que espera el segundo.
- Manipulación de recursos a través de representaciones: la especificación de REST intenta economizar peticiones en todo lo que sea posible. Por ello, cuando un cliente posee la representación de un recurso, incluyendo cualquier metadato adjunto, tiene suficiente información para modificar o eliminar el estado del recurso. Es decir, mediante las herramientas que REST promueve (uso de API auto-documentada, descriptiva, verbos HTTP, etc.), el cliente puede saber predecir el resultado esperado de hacer cualquier operación sobre un recurso recibido primeramente con un GET.
- Mensajes auto-descriptivos: la idea de un mensaje auto-descriptivo es contener toda la información que el cliente necesita para entenderlo. Por lo tanto, no debería existir información adicional en una documentación separada o en otro mensaje.
- Hipermedia como motor del estado de la aplicación: una vez se ha accedido a la URI inicial de la aplicación, un cliente REST debería ser capaz de usar los enlaces proveídos dinámicamente por parte del servidor para descubrir todos los recursos disponibles que necesita. Según continúa el proceso, el servidor responde con texto que incluye enlaces a otros recursos que están actualmente disponibles. Esto elimina la necesidad de que el cliente tenga información escrita en el código (hard-codeada) con respecto a la estructura o referencias dinámicas a la aplicación.
Seguridad del API RESTful
En este caso, se trata de una prueba de concepto y no se aplicarán medidas de seguridad en el desarrollo del API RESTful. Únicamente de desarrollará una API básica y desde cero, con los procedimientos habituales de inserción, eliminación, selección y modificación de registros.
Para un uso en producción del API RESTful es muy conveniente aplicar determinadas medidas de seguridad:
- Las peticiones HTTP al servidor de Apache/Nginx deben ir siempre por HTTPS, con la información cifrada.
- Se deben usar validación de usuario y contraseña, pasando siempre la contraseña cifrada.
- Se deben usar tokens de conexión por sesión, variando con cada usuario y cada sesión.
Base de datos MySQL o MariaDB
El primer paso para el uso de un API RESTful es disponer de una base de datos, a la cual accederemos mediante el API. O bien ya tenemos una base de datos accesible o bien la creamos. En este tutorial usaremos una base de datos MariaDB versión 10, externa (en servidor externo), con la siguiente tabla de datos:
1 2 3 4 5 6 |
CREATE TABLE `facturas` ( `codigo` INT NOT NULL AUTO_INCREMENT, `fecha` DATE, `cliente` VARCHAR(100) NOT NULL, `importe` DECIMAL(10,2) NOT NULL, PRIMARY KEY (`codigo`)) ENGINE = InnoDB; |
El procedimiento que explicaremos a continuación, más optimizado, podría servir casi para cualquier motor de base de datos. Este sería el objetivo de una buena API RESTful, abstraerse del motor de base de datos. Pero no es objeto de este artículo, donde crearemos, desde cero, un API completo para insertar, eliminar, modificar y seleccionar registros de una tabla.
Servidor con Apache o Nginx para las peticiones PHP
Necesitaremos disponer de un servidor Apache o Nginx para recibir y procesar las peticiones PHP. En dicho servidor web será donde coloquemos los ficheros PHP para el API RESTful. Será el encargado de compilar estos ficheros y realizar el acceso a la base de datos, entre otras cosas.
En el siguiente artículo explicamos cómo montar un servidor web Apache con acceso a MySQL/MariaDB:
Fichero PHP de conexión a la base de datos BaseDatos.php
En primer lugar, crearemos el fichero PHP de conexión a base de datos. Los ficheros PHP del API RESTful los colocaremos en el servidor web Apache/Nginx anteriormente mencionado. Los situaremos en una carpeta de la raíz del servidor web. Por ejemplo, para nuestro caso, que usamos un servidor Apache en Linux, los colocaremos en:
/var/www/facturas
En esta carpeta, crearemos el primer fichero PHP, para la conexión con la base de datos MySQL/MariaDB. Lo llamaremos BaseDatos.php y tendrá este contenido:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php class BaseDatos { private $servidor = 'ajpdsoft.com'; private $usuario = 'usuario'; private $contrasena = "contraseña"; private $bd = "proyectoa_factura"; public function getConectarBD() { //Para activar captura de errores acceso MySQL mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); try { $conexion = new mysqli($this->servidor, $this->usuario, $this->contrasena, $this->bd); if($conexion->connect_errno) { die("Error al conectar a la base de datos MySQL/MariaDB: " . $conexion->connect_error); //echo json_encode(array("error" => "Error al conectar al servidor de BD MySQL/MariaDB: ".$conexion->connect_error)); } else { return $conexion; } } catch (Exception $err) { echo json_encode(array("error" => "Error al conectar al servidor de BD: ".$err->getMessage())); } } } //Ejemplo para instanciar clase /* $bd = new BaseDatos(); $bdConexion = $bd->getConectarBD(); echo "Conectado a BD"; */ ?> |
Como es lógico, cambiaremos los valores de conexión por los nuestros propios (servidor, usuario, contraseña y base de datos).
Este fichero tendría que optimizarse para permitir la conexión a otros motores de base de datos Oracle, PostgreSQL, SQL Server, etc.
Fichero PHP de métodos para el API RESTful Metodos.php con insertar
Crearemos un nuevo fichero PHP en la misma carpeta, llamado Metodos.php. Este fichero contendrá todos los métodos de manipulación de datos en la base de datos: insertar registro, modificar registro, eliminar registro y seleccionar (consultar/devolver) registros.
Empezaremos mostrando el contenido base de este fichero, con el método «insertar» (más adelante añadiremos el resto de métodos a este mismo fichero):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
<?php class Metodos { private $tablaFacturas = "facturas"; //nombre de la tabla facturas en MySQL/MariaDB public $cliente; //Atributo cliente (para nombre de cliente de la factura) public $importe; //Atributo importe (para el importe de la factura) public $fecha; //Atributo fecha (para la fecha de la factura) public $codigo; //Atributo codigo (para el código (clave primaria) del registro de la tabla factura) private $conexionBD; //Atributo para guardar la conexión con la base de datos //Establecemos el constructor de la clase, que recibirá la conexión con la BD public function __construct($bd) { $this->conexionBD = $bd; } //Método para insertar un registro en la tabla factura //Devolverá 1 = correcto, 0 = e, -1 = error function insertar() { //Consulta SQL que se ejecutará $sql = "INSERT INTO ".$this->tablaFacturas."(cliente, importe, fecha) VALUES(?, ?, ?)"; try { //Preparamos la conexión a la BD con el SQL que se ejecutará $sqlPreparada = $this->conexionBD->prepare($sql); //Formateamos las posibles etiquetas HTML de los atributos para evitar, //en la medida de lo posible, la inyección de SQL y otros ataques //No es un método infalible $this->cliente = htmlspecialchars(strip_tags($this->cliente)); $this->importe = htmlspecialchars(strip_tags($this->importe)); $this->fecha = htmlspecialchars(strip_tags($this->fecha)); //Rellenamos los parámetros del SQL (los valores ?) con los valores de los atributos //sds en bind_param es para el tipo de dato de cada parámetro, en este caso: //s -> string, d -> float, s -> string $sqlPreparada->bind_param("sds", $this->cliente, $this->importe, $this->fecha); //Ejecutamos la consulta SQL, devolverá true si se ha ejecutado correctamente $resultado = $sqlPreparada->execute(); if (!$resultado) { //Para depuración, mostrar error echo json_encode(array("error" => "Error al insertar registro: ".$sqlPreparada->error)); return -1; } else { //Devolvemos el número de registros afectados (1 = OK, 0 = error) return $sqlPreparada->affected_rows; } } catch (Throwable $err) { echo json_encode(array("error" => "Error al insertar registro: ".$err->getMessage())); return -1; } } //Método para modificar un registro existente (filtrado por el código) de la tabla factura //No se comentan las líneas porque son similares a las del método insertar(), cambiando el SQL //Devolverá 1 = correcto, 0 = no se ha encontado el registro, -1 = error function modificar() { $sql = "UPDATE ".$this->tablaFacturas." SET cliente = ?, importe = ?, fecha = ? WHERE codigo = ?"; try { $sqlPreparada = $this->conexionBD->prepare($sql); $this->cliente = htmlspecialchars(strip_tags($this->cliente)); $this->importe = htmlspecialchars(strip_tags($this->importe)); $this->fecha = htmlspecialchars(strip_tags($this->fecha)); $this->codigo = htmlspecialchars(strip_tags($this->codigo)); $sqlPreparada->bind_param("sdsi", $this->cliente, $this->importe, $this->fecha, $this->codigo); $resultado = $sqlPreparada->execute(); if (!$resultado) { //Para depuración, mostrar error echo json_encode(array("error" => "Error al modificar registro: ".$sqlPreparada->error)); return -1; } else { //Devolvemos el número de registros afectados (1 = OK, 0 = no encontrado) return $sqlPreparada->affected_rows; } } catch (Throwable $err) { //Para depuración, mostrar error echo json_encode(array("error" => "Error al modificar registro: ".$err->getMessage())); return -1; } } //Método para obtener los datos (codigo, cliente, importe y fecha) de un registro de la tabla factura //Filtrado por el código function listar() { try { if(!empty($this->codigo) && $this->codigo != "-1") { $sql = "SELECT * FROM ".$this->tablaFacturas." WHERE codigo = ?"; $sqlPreparada = $this->conexionBD->prepare($sql); $sqlPreparada->bind_param("i", $this->codigo); } else { $sqlPreparada = $this->conexionBD->prepare("SELECT * FROM ".$this->tablaFacturas); } $sqlPreparada->execute(); $resultado = $sqlPreparada->get_result(); if (!$resultado) { echo json_encode(array("error" => "Error al modificar registro: ".$sqlPreparada->error)); } return $resultado; } catch (Throwable $err) { //Para depuración, mostrar error echo json_encode(array("error" => "Error al listar registro: ".$err->getMessage())); return false; } } //Método para eliminar un registro (filtrado por código) de la tabla facturas //Devolverá 1 = correcto, 0 = no se ha encontado el registro, -1 = error function eliminar() { if(!empty($this->codigo) && $this->codigo != "-1") { $sql = "DELETE FROM ".$this->tablaFacturas." WHERE codigo = ?"; try { $sqlPreparada = $this->conexionBD->prepare($sql); $this->codigo = htmlspecialchars(strip_tags($this->codigo)); $sqlPreparada->bind_param("i", $this->codigo); $resultado = $sqlPreparada->execute(); if (!$resultado) { //Para depuración, mostrar error echo json_encode(array("error" => "Error al eliminar registro: ".$sqlPreparada->error)); return -1; } else { //Devolvemos el número de registros afectados (1 = OK, 0 = no encontrado) return $sqlPreparada->affected_rows; } } catch (Throwable $err) { //Para depuración, mostrar error echo json_encode(array("error" => "Error al eliminar registro: ".$err->getMessage())); return -1; } } else { //Para depuración, mostrar error //Aquí no debería entrar nunca porque se comprueba en eliminar.php si se ha introducido el código echo json_encode(array("error" => "Error al eliminar registro. No se ha indicado el código.")); return -1; } } } ?> |
Fichero PHP para insertar registro en base de datos con API RESTful
Crearemos otro fichero nuevo en la misma carpeta, en este caso el fichero insertar.php. Contendrá el procedimiento para insertar el registro en la base de datos (consulta SQL de inserción). Tendrá el siguiente contenido:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
<?php header("Access-Control-Allow-Origin: *"); header("Content-Type: application/json; charset=UTF-8"); header("Access-Control-Allow-Methods: POST"); header("Access-Control-Max-Age: 3600"); header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"); //Incluimos los ficheros BaseDatos.php y Metodos.php que contienen las clases //para conectar con la base de datos y para ejecutar los distintos métodos include_once "BaseDatos.php"; include_once "Metodos.php"; //Instanciamos la clase BaseDatos para realizar la //conexión con el servidor MySQL/MariaDB $bd = new BaseDatos(); $bdConexion = $bd->getConectarBD(); //Instancionamos la clase Metodos para pasarle los atributos (codigo) y ejecutar //el método insertar() $metodos = new Metodos($bdConexion); //Obtenemos los datos pasados en formato JSON con POST //Un ejemplo de cómo pasar los datos a la URL: //https://www.ajpdsoft.com/facturas/insertar.php /* { "cliente": "Cliente 1 ProyectoA", "importe": "152.78", "fecha": "2023-07-18" } */ //Ejemplo de ejecución con curl: //curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{"cliente":"Mi cliente","importe":"10.55","fecha":"2023-07-18"}' "http://localhost/facturas/insertar.php" $datos = json_decode(file_get_contents("php://input")); //Comprobamos que se hayan pasado todos los datos requeridos if(!empty($datos->cliente) && !empty($datos->importe) && !empty($datos->fecha)) { //Asignamos los datos obtenidos por JSON a su correspondiente //atributo en la clase Metodos $metodos->cliente = $datos->cliente; $metodos->importe = $datos->importe; /* //Si quisiéramos insertar la fecha actual si no se ha introducido fecha if (emtpy($datos->fecha)) $metodos->fecha = date('Y-m-d'); */ $metodos->fecha = $datos->fecha; //Ejecutamos el método insertar() de la clase Metodos //Si devuelve 1 la ejecución habrá sido correcta //Si devuelve 0 es porque ha habido algún error //Si devuelve -1 es porque también ha habido algún error $resultado = $metodos->insertar(); if ($resultado == 1) //OK { //http_response_code(200); echo json_encode(array("mensaje" => "Registro insertado correctamente.")); } else { if ($resultado == 0) //Error { //http_response_code(400); echo json_encode(array("error" => "No se ha podido insertar el registro. Error de datos.")); } else { //Error //http_response_code(503); echo json_encode(array("error" => "No se ha podido insertar el registro. Error del servidor.")); } } } else { //http_response_code(400); echo json_encode(array("error" => "No se ha podido modificar el registro. Faltan datos.")); } ?> |
Como podemos comprobar, el fichero anterior instancia dos clases:
- BaseDatos: la clase contenida en el fichero BaseDatos.php, la que conecta con el servidor de base de datos MySQL/MariaDB.
- Metodos: la clase contenida en el fichero Metodos.php, el que contiene los métodos que se usarán para el API RESTful: insertar, eliminar, modificar y listar.
Probar uso de API RESTful con Postman
Una vez creados estos tres ficheros iniciales: BaseDatos.php, Metodos.php y insertar.php, es el momento de hacer una primera prueba de nuestra API RESTful. Para ello, podemos usar el comando curl o bien algún sitio web online que permita ejecución de URL con API RESTful, como Postman (esta será la que usemos).
Para probar, podemos usar alguna web online que permita ejecutar API RESTful, como por ejemplo postman. Es posible que tentamos que registrarnos para poder usarla. Una vez registrados y dentro de nuestro My Workspace, pulsaremos en «New», eligiendo «HTTP»:
Introduciremos los siguientes datos:
- POST: elegiremos este método en el desplegable.
- URL: introduciremos la URL completa de ejecución del API, en nuestro caso https://ajpdsoft.com/facturas/insertar.php
- Elegiremos «Raw» para la introducción de datos, e introduciremos los siguientes datos:
1 2 3 4 5 |
{ "cliente": "Cliente 4 ProyectoA", "importe": "178.23", "fecha": "2023-07-07" } |
Pulsaremos en «Send» para enviar la petición API RESTful. Si todo es correcto, se insertará un registro en la base de datos MySQL/MariaDB y devolverá el resultado: message: Registro insertado correctamente.
Si listamos los registros de la base de datos para la tabla «facturas», podremos comprobar que se ha insertado el cliente «Cliente 4 ProyectoA»:
Probar API RESTful con comando curl
Si queremos probar el método insertar() con el comando curl, desde la línea de comandos (en Windows), ejecutaremos:
1 |
curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d "{\"cliente\":\"Mi cliente\",\"importe\":\"10.55\",\"fecha\":\"2023-07-18\"}" "htts://www.ajpdsoft.com/facturas/insertar.php" |
La ventaja de usar el comando curl es que podremos realizar todas las pruebas de nuestra API desde nuestro equipo, sin tener que acceder a un sitio web. Además, el comando curl es muy versátil e incluye infinidad de opciones para obtener estados, errores, resultados, tipos de consultas HTTP, etc.
Añadir método para modificar registros en fichero Metodos.php
Añadiremos el siguiente método, que será para modificar un registro existente, en el fichero Metodos.php. Este método necesitará que se le pase por parámetro el código del registro a modificar y los datos modificados (cliente, importe y fecha). Para ello, editaremos el fichero existente Metodos.php y, en el final, añadiremos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
//Método para modificar un registro existente (filtrado por el código) de la tabla factura //No se comentan las líneas porque son similares a las del método insertar(), cambiando el SQL //Devolverá 1 = correcto, 0 = no se ha encontado el registro, -1 = error function modificar() { $sql = "UPDATE ".$this->tablaFacturas." SET cliente = ?, importe = ?, fecha = ? WHERE codigo = ?"; try { $sqlPreparada = $this->conexionBD->prepare($sql); $this->cliente = htmlspecialchars(strip_tags($this->cliente)); $this->importe = htmlspecialchars(strip_tags($this->importe)); $this->fecha = htmlspecialchars(strip_tags($this->fecha)); $this->codigo = htmlspecialchars(strip_tags($this->codigo)); $sqlPreparada->bind_param("sdsi", $this->cliente, $this->importe, $this->fecha, $this->codigo); $resultado = $sqlPreparada->execute(); if (!$resultado) { //Para depuración, mostrar error echo json_encode(array("error" => "Error al modificar registro: ".$sqlPreparada->error)); return -1; } else { //Devolvemos el número de registros afectados (1 = OK, 0 = no encontrado) return $sqlPreparada->affected_rows; } } catch (Throwable $err) { //Para depuración, mostrar error echo json_encode(array("error" => "Error al modificar registro: ".$err->getMessage())); return -1; } } |
Y añadiremos también, al principio del fichero Metodos.php y dentro de la clase Metodos (al final de artículo mostraremos el contenido completo del fichero Metodos.php):
1 |
public $codigo; |
Crear fichero PHP para modificar registros con API RESTful
De la misma forma, crearemos el fichero PHP para modificar un registro, que llamaremos modificar.php, con el siguiente contenido:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
<?php header("Access-Control-Allow-Origin: *"); header("Content-Type: application/json; charset=UTF-8"); header("Access-Control-Allow-Methods: POST"); header("Access-Control-Max-Age: 3600"); header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"); //Incluimos los ficheros BaseDatos.php y Metodos.php que contienen las clases //para conectar con la base de datos y para ejecutar los distintos métodos include_once "BaseDatos.php"; include_once "Metodos.php"; //Instanciamos la clase BaseDatos para realizar la //conexión con el servidor MySQL/MariaDB $bd = new BaseDatos(); $bdConexion = $bd->getConectarBD(); //Instanciamos la clase Metodos para pasarle los atributos (codigo) y ejecutar //el método modificar() $metodos = new Metodos($bdConexion); //Obtenemos los datos pasados en formato JSON con POST //Un ejemplo de cómo pasar los datos a la URL: //https://www.ajpdsoft.com/facturas/modificar.php /* { "codigo":"3" "cliente": "Cambio nombre cliente 3", "importe": "152.78", "fecha": "2023-07-18" } */ $datos = json_decode(file_get_contents("php://input")); //Comprobamos que se hayan pasado todos los datos requeridos if (!empty($datos->codigo) && !empty($datos->cliente) && !empty($datos->importe) && !empty($datos->fecha)) { //Asignamos los datos obtenidos por JSON a su correspondiente //atributo en la clase Metodos $metodos->codigo = $datos->codigo; $metodos->cliente = $datos->cliente; $metodos->importe = $datos->importe; $metodos->fecha = $datos->fecha; //Ejecutamos el método modificar() de la clase Metodos //Si devuelve 1 la ejecución habrá sido correcta //Si devuelve 0 es porque no ha encontrado el registro a modificar //Si devuelve -1 es porque ha habido algún error $resultado = $metodos->modificar(); if ($resultado == 1) //OK { //http_response_code(200); echo json_encode(array("mensaje" => "Registro modificado correctamente.")); } else { if ($resultado == 0) //Registro no encontrado { //http_response_code(400); echo json_encode(array("error" => "No se ha encontrado el registro a modificar.")); } else { //Error //http_response_code(503); echo json_encode(array("error" => "No se ha podido modificar el registro. Error del servidor.")); } } } else { //http_response_code(400); echo json_encode(array("error" => "No se ha podido modificar el registro. Faltan datos.")); } ?> |
Para realizar la prueba, con Postman, introduciremos la URL: htts://www.ajpdsoft.com/facturas/modificar.php y los datos:
1 2 3 4 5 6 |
{ "codigo": "3", "cliente": "Cliente 3 modificado", "importe": "152.78", "fecha": "2024-11-11" } |
Esta API modificará el registro con código 3 de la tabla de facturas, estableciendo los nuevos datos pasados de cliente, importe y fecha.
Podremos hacer la prueba también con el comando curl, ejecutando, desde la línea de comandos:
1 |
curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d "{\"codigo\":\"3\",\"cliente\":\"Cliente 3 modificado\",\"importe\":\"152.78\",\"fecha\":\"2024-11-11\"}" "http://www.ajpdsoft.com/facturas/modificar.php" |
Añadir método para listar registros en fichero Metodos.php
Continuamos añadiendo métodos, en este caso el de listar registros: obtener los datos de un registro a partir de su código. Añadiremos al final del fichero Metodos.php el siguiente código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
//Método para obtener los datos (codigo, cliente, importe y fecha) de un registro de la tabla factura //Filtrado por el código function listar() { try { if(!empty($this->codigo) && $this->codigo != "-1") { $sql = "SELECT * FROM ".$this->tablaFacturas." WHERE codigo = ?"; $sqlPreparada = $this->conexionBD->prepare($sql); $sqlPreparada->bind_param("i", $this->codigo); } else { $sqlPreparada = $this->conexionBD->prepare("SELECT * FROM ".$this->tablaFacturas); } $sqlPreparada->execute(); $resultado = $sqlPreparada->get_result(); if (!$resultado) { echo json_encode(array("error" => "Error al modificar registro: ".$sqlPreparada->error)); } return $resultado; } catch (Throwable $err) { //Para depuración, mostrar error echo json_encode(array("error" => "Error al listar registro: ".$err->getMessage())); return false; } } |
Crear fichero PHP para listar registros con API RESTful
Crearemos el fichero listar.php. Este fichero contiene el procedimiento para hacer un select en la base de datos, filtrando por código, de la tabla factura, para devolver los datos del registro filtrado. En este caso, usaremos el paso de parámetros estándar por URL (GET):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
<?php header("Access-Control-Allow-Origin: *"); header("Content-Type: application/json; charset=UTF-8"); //Incluimos los ficheros BaseDatos.php y Metodos.php que contienen las clases //para conectar con la base de datos y para ejecutar los distintos métodos include_once "BaseDatos.php"; include_once "Metodos.php"; //Instanciamos la clase BaseDatos para realizar la //conexión con el servidor MySQL/MariaDB $bd = new BaseDatos(); $bdConexion = $bd->getConectarBD(); //Instancionamos la clase Metodos para pasarle los atributos (codigo) y ejecutar //el método listar() $metodos = new Metodos($bdConexion); //Obtenemos el código pasado por parámtro en método GET //Ejemplo: http://localhost/facturas/listar.php?codigo=2 //Ejemplo de ejecución con curl: //curl http://localhost/facturas/listar.php?codigo=3 //Guardamos el código en el atributo $codigo de la clase Metodos $metodos->codigo = (isset($_GET['codigo']) && $_GET['codigo']) ? $_GET['codigo'] : '0'; //Ejecutamos el método listar() de la clase Metodos $resultado = $metodos->listar(); //Según el resultado obtenido, si hemos obtenido más de un registro if($resultado->num_rows > 0) { //Recorremos los registros obtenidos y los guardamos en un array //para devolverlos en formato JSON $listaRegistros = array(); $listaRegistros["registros"] = array(); while ($registroActual = $resultado->fetch_assoc()) { extract($registroActual); $detalleRegistro = array( "codigo" => $codigo, "cliente" => $cliente, "importe" => $importe, "fecha" => $fecha ); array_push($listaRegistros["registros"], $detalleRegistro); } //Devolvemos los registros obtenidos en formato JSON //http_response_code(200); echo json_encode($listaRegistros); } else { //http_response_code(404); echo json_encode(array("mensaje" => "No se han encontrado registros.")); } ?> |
Para probar el método listar(), podemos ejecutar el siguiente comando curl (devolverá los datos del registro con código = 3):
1 |
curl http://localhost/facturas/listar.php?codigo=3 |
Añadir método para eliminar registros en fichero Metodos.php
Seguimos añadiendo métodos, en este caso, el método para eliminar un registro de la tabla facturas, filtrando por código. Añadiremos el siguiente código al final del fichero Metodos.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//Método para eliminar un registro (filtrado por código) de la tabla facturas function eliminar() { $sql = "DELETE FROM ".$this->tablaFacturas." WHERE codigo = ?"; $sqlPreparada = $this->conexionBD->prepare($sql); $this->codigo = htmlspecialchars(strip_tags($this->codigo)); $sqlPreparada->bind_param("i", $this->codigo); $resultado = $sqlPreparada->execute(); if (!$resultado) { echo json_encode(array("message" => "Error al eliminar registro: ".$sqlPreparada->error)); } return $resultado; } |
Crear fichero PHP para eliminar registros con API RESTful
El último fichero que crearemos, será el de eliminar registro, filtrando por código. Crearemos el fichero eliminar.php con el siguiente contenido:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<?php header("Access-Control-Allow-Origin: *"); header("Content-Type: application/json; charset=UTF-8"); header("Access-Control-Allow-Methods: GET"); header("Access-Control-Max-Age: 3600"); header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"); //Incluimos los ficheros BaseDatos.php y Metodos.php que contienen las clases //para conectar con la base de datos y para ejecutar los distintos métodos include_once "BaseDatos.php"; include_once "Metodos.php"; //Instanciamos la clase BaseDatos para realizar la //conexión con el servidor MySQL/MariaDB $bd = new BaseDatos(); $bdConexion = $bd->getConectarBD(); //Instanciamos la clase Metodos para pasarle los atributos (codigo) y ejecutar //el método eliminar() $metodos = new Metodos($bdConexion); //Obtenemos los datos pasados en formato JSON con GET //Un ejemplo de cómo pasar los datos a la URL: //curl http://localhost/facturas/eliminar.php?codigo=3 //Si no se obtiene un código pasado por parámetro GET en la URL, se establece a valor -1 $metodos->codigo = (isset($_GET['codigo']) && $_GET['codigo']) ? $_GET['codigo'] : '-1'; //Comprobamos que se hayan pasado todos los datos requeridos if ($metodos->codigo != "-1") { //Ejecutamos el método eliminar() de la clase Metodos //Si devuelve 1 la ejecución habrá sido correcta //Si devuelve 0 es porque no ha encontrado el registro a eliminar //Si devuelve -1 es porque ha habido algún error $resultado = $metodos->eliminar(); if ($resultado == 1) { //http_response_code(200); echo json_encode(array("mensaje" => "Registro eliminado correctamente.")); } else { if ($resultado == 0) { //http_response_code(400); echo json_encode(array("error" => "No se ha encontrado el registro a eliminar.")); } else { //http_response_code(503); echo json_encode(array("error" => "No se ha podido eliminar el registro. Error del servidor.")); } } } else { //http_response_code(400); echo json_encode(array("error" => "No se ha podido eliminar el registro. Faltan datos.")); } ?> |
Para probar el método eliminar() podremos ejecutar el siguiente comando curl (eliminará el registro con código = 3):
1 |
curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{\"codigo\":\"3\"}' "http://localhost/facturas/eliminar.php" |
Descarga del código fuente completo del ejemplo de API RESTful en PHP
A continuación, mostramos un enlace a la descarga gratuita del código fuente completo empleado en este ejemplo de API RESTful en PHP: