MySQL y PHP con PDO: CRUD (create, read, update, delete)

Introducción

Aunque ya hay millones de tutoriales sobre esto, me decidí a hacer el mío pero en una forma muy muy simple. Antes de comenzar, debes tener un conocimiento básico en MySQL. Si no tienes instalado esto, pásate por este post para instalar XAMPP.

Cabe mencionar que aquí no veremos buenas prácticas de bases de datos, relaciones, etcétera. Nos dedicaremos a usar las tablas que aparecen, sin fijarnos en la normalización, o cosas de ese estilo.

Nota: este tutorial utiliza PDO, pero recuerda que igualmente podemos usar las funciones mysqli. Personalmente recomiendo PDO, pues es orientado a objetos. Sin embargo, espero escribir un tutorial sobre mysqli en el futuro.

Si te interesa saber cómo hacer un CRUD con SQLite3, PDO y PHP haz click aquí

Actualización 2019

Ya se encuentra disponible la parte 2 de este tutorial en donde vemos cómo saber si un elemento existe en la tabla y recorremos los datos con un cursor. Míralo aquí.

También he puesto el código en GitHub.

Actualización marzo

De nuevo he añadido otro tutorial para saber cómo realizar búsquedas, míralo aquí.

Estructura de la tabla

Como lo dije, esto será simple. Utilizaremos una tabla de personas, en donde guardamos el id, el nombre, apellidos y género. Queda así:

Con esto vamos a comenzar a trabajar.

Conexión

Para interactuar con la base de datos necesitamos conectarnos a la misma. Para ello, usamos un archivo y  después simplemente lo incluimos en donde queramos usarlo. Voy a poner el código aquí, y lo explicaré más abajo.

Como podemos ver, el código es demasiado simple. Simplemente creamos un objeto PDO y le pasamos 3 parámetros:

  1. Nombre del origen de datos
  2. El usuario
  3. La contraseña

PDO permite cambiar de gestor de base de dato en una sola línea, sólo tendríamos que cambiar el primer parámetro. Aquí dejo la lista de gestores de bases de datos soportadas. Por otro lado, aquí dejo la documentación oficial de la clase.

Lo ponemos en un try/catch porque en algunas ocasiones puede que nos equivoquemos de usuario, contraseña, base de datos, etcétera.

Nota: recuerda que la base de datos debe existir, así como la tabla “personas”. Puedes cambiar el usuario, la contraseña o el nombre de la base de datos como tú desees.

Formulario para crear datos

Comencemos insertando datos. Para ello, necesitamos un simple formulario en HTML. Dejaré esta vez sin explicar el código HTML, si deseas estudiarlos más a fondo aquí te dejo un link.

Lo único que quiero que se note es el atributo action, en donde ponemos el nombre del archivo php que recibirá los datos.

Ese archivo debe estar en la misma carpeta que el formulario. Si cambiamos nuevaPersona.php de ubicación o nombre, basta con cambiarlo en el formulario para que las cosas sigan funcionando.

Por ejemplo, si muevo el archivo nuevaPersona a la carpeta “foo” (que está en donde está el formulario), tengo que cambiar el action, así:

action=”foo/nuevaPersona.php”

Si lo cambio a una carpeta que está arriba, puedo ponerlo así:

action=”../carpeta/nuevaPersona.php”

Y puedo tener miles de carpetas:

action=”una/carpeta/otra/otra/otroNombre.php”

Recibiendo datos del formulario

Antes de recibirlos, por favor observa el atributo “name” de cada input. Ese nombre será el que usaremos para acceder a los datos, distinguiendo mayúsculas y minúsculas. Veamos ahora el archivo nuevaPersona.php, que será en donde recibiremos los datos introducidos en el formulario.

Si todo va bien, al visitar el formulario y enviarlo se mostrará un “Insertado correctamente”.

Listar datos – Tabla estática

Una vez que ya insertamos, vamos a mostrar a las personas. Para ello, usaremos una tabla. Antes de confundir al lector con la creación de la tabla, veamos una de ellas en su forma estática. Así luce el código: (obviamente es escrito a mano)

Si observas bien, puedes ver que la estructura se conserva y sólo cambia en tr. Es decir, se repite la parte del código en donde dice <tr><td>…

La tabla, al mostrarla, se ve así:

Pero eso lo puede hacer cualquiera, y además, ¿qué beneficio trae, si tenemos que hacerla a mano? mejor deberíamos hacer que PHP la genere por nosotros, o bueno, darle sólo una pequeña ayuda. Veamos entonces cómo podemos hacer eso.

Listar datos – Tabla dinámica

Ahora sí vamos a ver cómo listar datos traídos de MySQL. Para ello vamos a utilizar código PHP. El archivo que lista los datos, al menos en su primer versión, se ve así:

Nota: El parámetro que pasamos a fetchAll es una constante estática pública de la clase PDO, (PDO::FETCH_OBJ) y permite acceder a las filas de la tabla como si fuera un objeto nativo de PHP. Es decir, podemos acceder al nombre de la persona usando $persona->nombre en lugar de (es la opción que está por defecto) $persona[1]. Hay más constantes, pero las veremos en otro post.

Recordemos que el código, entre más expresivo, mejor.

Bueno, con todo esto tendremos un arreglo que se ve así al visitar la página:

Esto es porque sólo he registrado a una persona. Registraré a otras:

Pero sigue sin verse bonito, aquí es en donde combinamos HTML y PHP para convertir ese arreglo en una tabla bonita, o al menos más bonita que ese arreglo no entendible. El código queda así:

Por cierto, no es un error dejar sin punto y coma el echo. Pero recordemos que si estamos en donde las etiquetas se cierran (?>) no es necesario poner punto y coma. Ojo: sólo en la última expresión, no en todas.

Al visitar la página ahora sí da gusto:

Agregando enlaces

Para eliminar o actualizar vamos a necesitar el id de la persona. Si no, ¿a qué persona eliminaremos o editaremos?.

Gracias al poder de la combinación de HTML podemos crear un link que dirija a cierto archivo, pasándole el id. Y luego leer ese id.

Por el momento sólo hay que crear los enlaces, no hace falta explicar el funcionamiento. Así que la versión 3 de la tabla queda así:

Y la tabla se ve así:

Si acercas el cursor en donde dice “Eliminar” verás que te va a dirigir a un enlace como “eliminar.php?id=1”. Pero ese id va cambiando en cada fila. Si le das click te dirá que no se ha encontrado el archivo, pues tenemos que crearlos a ambos: editar.php y eliminar.php.

Eso lo veremos más abajo.

Actualizando o editando

De todas las operaciones, esta es la que menos me gusta, ya que en primer lugar debemos saber el id, luego tenemos que recuperar los datos para mostrarle al usuario lo que ya existe. Finalmente realizar la consulta UPDATE en la base de datos.

Pero bueno, este paso es necesario. Así que vamos allá.

¿recuerdas que mandamos un id dentro del link en la tabla? ahora vamos a recuperarlo. Crearemos el archivo editar.php y pondremos esto dentro de él:

Si te fijas bien, ahora estamos recibiendo el id por medio del arreglo superglobal $_GET. Y accedemos a él a través de su posición como cadena, así:

$_GET[“id”]

¡Justo como leíamos a $_POST! Luego, hacemos una búsqueda en donde el id sea igual al proporcionado. Si no existe nada con ese id (porque un usuario puede cambiar ese id a 4654654, cosa que en teoría no existe) entonces lo advertimos.

Veamos ahora el formulario, HTML provee una forma de dar valores por defecto a los campos utilizando el atributo “value” así que llenamos estos valores con los datos que obtuvimos, en caso de que existan.

También agregamos un input de tipo oculto, ahí guardaremos el ID para que el usuario, en teoría, no pueda cambiarlo.

Y finalmente observa el action, ahora no irá a nuevaPersona.php sino a guardarDatosEditados.php. Éste último archivo vamos a programarlo ahora mismo. Por cierto, editar se ve así:

(justo como el de agregar nueva persona, pero con los campos llenos por defecto)

Recibiendo datos para editar

Este será casi igual al de nuevaPersona.php salvo que ahora también necesitamos el id, y será un UPDATE en lugar de un INSERT. Veamos el código y luego lo explicamos:

Podemos ver que usamos el ID para hacer un Where dentro de la consulta. Y actualizamos todos los valores. De todos modos, no hay problema, pues si el usuario no toca el valor se quedará tal y como estaba.

Eliminando

Pequeña gran nota: repito que esto es un post más que nada educativo. Nunca pero nunca debemos hacer que se elimine usando un link, y mucho menos sin confirmación. ¿te imaginas que Facebook tuviera esa opción para, por ejemplo, eliminar mensajes con alguna persona? supongamos que el link fuera algo como eliminar_mensajes.php?idPersona=111

Ahora yo te digo que visites ese link, pero antes lo pongo en un acortador para que no haya sospechas. Una vez que hagas click en él, adiós a esa conversación. Obviamente no perdemos nada con eliminar una conversación (al menos que incrimine a alguien, tenga valor sentimental, etcétera) pero basta con esto para darnos una idea.

En este ejemplo eliminamos con el valor pasado por un link y no hay vuelta atrás, pero igual no perdemos nada. Para casos reales, es mejor hacerlo usando POST, pues ahí los datos no se ven en la URL. Además, podemos mandar una confirmación, comprobar si el usuario tiene permisos, etcétera.

Pero eso es otra historia, veamos ahora sí el último pilar para armar este crud. Por cierto, podríamos poner un confirm con javascript, o algo así, pero sería mezclar código y confundir al lector.

La operación que más me gusta es eliminar, pues sólo necesitamos el ID. Espero que el código se explique por sí mismo, porque si no, ni yo mismo podría hacerlo.

Probando y descargando

Sería un pecado explicar todo esto y no dejar los archivos para que los pruebes por ti mismo. Aquí dejo el proyecto completo, sólo pégalo y extráelo en la carpeta pública de tu servidor Apache (htdocs o public_html).

mysql_pdo_php_crud

También puedes probarlo en línea.

Conclusión

Podemos agregar unos links de navegación para ir, por ejemplo, de editar a listar todos, etcétera. Pero eso lo dejo para que el usuario lo haga. También sería bueno agregar un poco de estilos CSS. O incluso crear un servicio web con PHP y consumirlo desde cualquier lugar, o hacerlo con Javascript utilizando AJAX.

Pero todo eso es arena de otro costal que se llevaría decenas de posts, así que dejemos eso por el momento.

Finalmente, si quieres un ejemplo un poco más avanzado, te invito a leer Pequeño, muy pequeño sistema de ventas con PHP

27 pensamientos sobre “MySQL y PHP con PDO: CRUD (create, read, update, delete)”

  1. Me parece genial la ayuda y te agradesco porque es para un sistema que estoy implementando, por otro lado como recomendarias ocultar el ID que se solicita por get? en la pagina de eliminar registro.

  2. Pingback: Extraer texto e imágenes de PDF con PHP - Parzibyte's blog

  3. Pingback: Cómo obtener un hosting gratuito con dominio, PHP 7, MySQL y cuentas FTP - Parzibyte's blog

  4. Pingback: Búsqueda en MySQL con PHP y PDO: con like y coincidencia exacta - Parzibyte's blog

    1. Hola. ¿Te refieres a algo que por ejemplo busque en una tabla de personas a partir del nombre? si es así, todavía no, pero muy pronto lo escribiré. Puedes estar al pendiente de mis publicaciones siguiéndome en mis redes sociales o suscribiéndote al blog. Saludos

    2. Si, que busque el nombre de “Juan” por ejemplo, y que muestre el resultado y que se actualice la tabla mostrando todos los “Juan”. Te lo agradecería. Voy a suscribirme, de todos modos tienes mucho contenido muy bueno. Gracias 🙂

  5. Pingback: Presentando un sistema web para hacer cotizaciones y presupuestos, gratuito y open source - Parzibyte's blog

  6. Pingback: Exportar datos de MySQL a Excel con PHP, PHPSpreadSheet y PDO - Parzibyte's blog

  7. Pingback: PHP y PDO parte 2: iterar con cursor y comprobar si elemento existe - Parzibyte's blog

    1. Cuando diseñes tu base de datos selecciona una colación que soporte acentos y esas cosas. O puedes especificarlo al crear las tablas. Aquí te dejo un ejemplo de cómo lo hago yo:

      CREATE TABLE productos(
      id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
      codigo VARCHAR(255) NOT NULL,
      descripcion VARCHAR(255) NOT NULL,
      precioVenta DECIMAL(5, 2) NOT NULL,
      precioCompra DECIMAL(5, 2) NOT NULL,
      existencia DECIMAL(5, 2) NOT NULL,
      PRIMARY KEY(id)
      ) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8;

      Fíjate bien que ahí se especifica DEFAULT CHARACTER SET = utf8. De esta manera se podrán soportar caracteres especiales.

  8. Buenas, soy sumamente nuevo en php, y primero agradecerte por este tutorial basico y por otra parte queria decirte que me da un error de sintaxis en la lineas donde usas el “execute”, yo por mi parte borre los corchetes y dejo de saltar ese tipo de error pero al probar el Crud obviamente me pide parametros,asi que si podrias responder esto te estaria muy agradecido… d

    1. Hola Fernando. No lo hice con MVC porque sería un poco más difícil para los principiantes. Pronto haré un ejemplo con MVC, mientras tanto te invito a que te suscribas a mi blog en la barra superior derecha.
      Saludos.

  9. Pingback: Creando un manejador de sesiones propio en PHP con MySQL y PDO - Parzibyte's blog - El blog de Luis Cabrera

    1. Bueno, primero que todo muchas gracias por el tuto, me sirvió mucho, use mas que todo el Update, pero a la hora de hacer el Insert me saca este error:
      Algo salió mal. Por favor verifica que la tabla exista
      Pero se que si existe pues estoy haciendo el actualizar en otro lado y funciona.

      Estructura update:
      include_once “con.php”;
      switch ($_GET[‘tipo’]) {
      case 1:
      //Modificar el nombre
      if (isset($_GET[‘code’])) {
      $id=$_GET[‘code’];
      $nombre = $_POST[‘name’];
      $sentencia = $con->prepare(“UPDATE birthdays SET name = ? WHERE id = ?;”);
      $resultado = $sentencia->execute([$nombre, $id]);…. cada case es para la actualización de cada elemento.

      estructura insert:
      include_once “con.php”;
      $nombre = ‘Seadog’;
      $apellido = ‘Gato’;
      $job = ‘Dañar’;
      $fecha = explode(“/”, $_POST[‘birthday’]);
      $day = ’24’;
      $month = ’09’;
      $year = ‘1992’;
      $inicio = ’10/05/2000′;
      $sentencia = $con->prepare(“INSERT INTO `birthdays` (`id`, `name`, `surname`, `year`, `month`, `day`, `job`, `start`, `image`, `content`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);”);
      var_dump($sentencia);
      $resultado = $sentencia->execute([NULL, $nombre, $apellidos, $year, $month, $day, $job, $inicio, NULL, NULL]); # Pasar en el mismo orden de los ?

      var_dump($resultado);
      //header(‘Location: ../admin’);
      if($resultado === TRUE) echo “Insertado correctamente”;
      else echo “Algo salió mal. Por favor verifica que la tabla exista”;
      ?>

    2. Hola, me parece que es por los NULL. No pases a Null desde PHP, mejor ponlo directamente la consulta.
      Por otro lado, el id de autoincremento no se debe especificar. El código quedaría así:

      $sentencia = $con->prepare(“INSERT INTO `birthdays` (`name`, `surname`, `year`, `month`, `day`, `job`, `start`, `image`, `content`) VALUES ( ?, ?, ?, ?, ?, ?, ?, NULL, NULL);”);
      $resultado = $sentencia->execute([NULL, $nombre, $apellidos, $year, $month, $day, $job, $inicio]);

      Si sigue marcando errores, entonces prueba escribiendo esa consulta (con datos reales en lugar de signos de interrogación) en la CLI de MySQL o desde phpmyadmin y eso debería darte algunas pistas

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *