en Programacion

Subir un archivo a un campo BLOB de Oracle desde un formulario de PHP

En el desarrollo que estoy realizando para mi empresa me ha surgido la necesidad de crear un formulario web que recoja unos campos de texto y, además, permita adjuntar múltiples archivos. Los campos de texto serán parte de los parámetros a un paquete de base de datos y los ficheros se almacenarán en una tabla bajo un campo BLOB.

A continuación os dejo los pasos que he seguido para subir correctamente un fichero en el servidor web a la base de datos.

Subir un archivo a Oracle desde PHP

1.- Lo primero que haremos será crear en la base de datos una tabla temporal (o podéis usar la definitiva) donde se almacenarán los ficheros. En mi caso por cuestiones de seguridad, primero los subo a esta tabla y luego un proceso interno los graba a la definitiva.

Para ello lanzamos los siguientes comandos, que crean la tabla y la secuencia para el contador ID:

CREATE SEQUENCE seq_web_temp_blob
  NOMINVALUE
  NOMAXVALUE
  NOCYCLE
  CACHE 20
  NOORDER
  INCREMENT BY 1;

CREATE TABLE web_temp_blob (
  ID NUMBER PRIMARY KEY,
  nombre VARCHAR2(500),
  archivo BLOB
);

 

2.- Ya en PHP, imaginemos que el formulario nos deja los ficheros a subir en la variable $_FILES. Lo primero que haremos (para mayor comodidad) es preparar un array con los datos que necesitaremos de los ficheros:

$files = array();

foreach ($_FILES["files"]["error"] as $key => $error) {

  $file = array();
  $file["name"] = $_FILES["files"]["name"][$key];
  $file["tmp_name"] = $_FILES["files"]["tmp_name"][$key];
  $file["error"] = $_FILES["files"]["error"][$key];

  array_push($files, $file);

}

 

3.- Finalmente procesamos la subida de cada fichero:

foreach ($files as $key => $name) {

  if ($files[$key]['error'] == UPLOAD_ERR_OK) {

    // el nombre que tendrá el fichero
    $nombre = $files[$key]["name"];
    // la ruta del servidor donde se almacena temporalmente
    $ruta = $files[$key]["tmp_name"];

    // conectamos a Oracle
    $cnx = oci_connect(_dbname, _dbpass, _host);

    // definimos la variable que procesará el fichero
    $lob = oci_new_descriptor($cnx, OCI_D_LOB);

    // preparamos la SQL
    $sql = "INSERT INTO web_temp_blob(ID, nombre, archivo) VALUES(seq_web_temp_blob.NEXTVAL,
            :nombre, EMPTY_BLOB()) RETURNING ID, archivo INTO :id, :archivo";

    // procesamos la petición
    $exec = oci_parse($cnx, $sql);
    oci_bind_by_name($exec, ":id", $id, 100);
    oci_bind_by_name($exec, ":nombre", $nombre, 500);
    oci_bind_by_name($exec, ':archivo', $lob, -1, OCI_B_BLOB);
    if(!oci_execute($exec, OCI_DEFAULT)) $id = 0;

    // cargamos el fichero en la tabla
    if ($lob->savefile($ruta)) {
      oci_commit($cnx);
    } else {
      $id = 0;
    }
    $lob->free();

  }

}

 

Listo. Con esto ya tendríamos nuestro fichero subido a Oracle en el campo BLOB de una tabla.

NOTA: En el caso de que lo que queramos subir sea una cadena de texto con el contenido del fichero, por ejemplo, en base64, reemplazaremos la llamada savefile por save:

$lob->save($string)