Use MongoDB como almacenamiento de archivos en PHP

Syed Hassan Sabeeh Kazmi 20 junio 2023
Use MongoDB como almacenamiento de archivos en PHP

Cuando se trata de crear almacenamiento escalable para archivos grandes, MongoDB y su GridFS (escrito en MongoDB Query Language - MQL) es una de las mejores soluciones de almacenamiento de archivos del mercado. En este tutorial, aprenderá a usar MongoDB como almacenamiento de archivos en PHP.

Facilita el proceso de consulta de cualquier parte de la colección de archivos y da como resultado el mismo proceso que cualquier otra consulta al cargar los datos que necesita en su conjunto de trabajo (el conjunto de trabajo representa un conjunto de datos o datos cargados en ese momento dado) requerido por MongoDB dentro de un marco de tiempo determinado para mejorar o mantener un rendimiento óptimo. Además, realiza la consulta (almacenamiento, transferencia, manipulación de datos/archivos) al paginarlo en la RAM.

Su rendimiento de lectura varía, ya que puede ser excelente para archivos pequeños directamente desde la RAM y, por otro lado, podría ser mejor para archivos grandes. Se espera que la mayoría de las computadoras no tengan más de 600 GB de RAM y pueden manejar fácilmente particiones de más de 600 GB de un solo archivo en una sola instancia de mongod.

Una cosa importante a considerar aquí es que el tamaño predeterminado o promedio de los fragmentos es de 256 KB, lo que genera una gran cantidad de documentos para una colección de archivos de 600 GB; sin embargo, puede manipular esta configuración en la mayoría de los controladores. GridFS usa los bloqueos predeterminados (nivel de base de datos 2.2+ o nivel global anterior a 2.2) como en cualquier otra colección.

El nivel de base de datos 2.2+ y el nivel global anterior a 2.2 interfieren entre sí, y con una comprensión profunda, puede garantizar una lectura coherente de un documento que se está escribiendo.

El controlador del servidor que se está implementando significa que no tiene idea de GridFS, y no hay una resolución especial de los datos de GridFS en el lado del servidor. Aprenderá cómo implementar GridFS usando MongoDB en su proyecto PHP, y existe la posibilidad de contención según las especificaciones de su escenario, el tráfico, la cantidad de escrituras/lecturas simultáneas y muchos otros, por lo que puede haber algún bloqueo para lectura/ operaciones de escritura en algunos casos.

Use GridFS de MongoDB como almacenamiento de archivos

Los archivos que aumentan de tamaño (por encima del límite predeterminado de 16 MB del archivo BSON) requieren un sistema de almacenamiento más robusto, y GridFS es capaz de manejar archivos grandes, ya que los divide en partes para almacenar/manejar cada parte como un archivo/documento separado. en lugar de almacenar el archivo como un solo documento. Su tamaño de fragmento predeterminado es de 255 KB y los almacena en una colección y los metadatos del archivo en otra.

El sistema de archivos a nivel del sistema no puede manejar archivos grandes y almacenarlos en una base de datos MongoDB es más eficiente. GridFS es una solución perfecta para acceder a información de porciones de archivos grandes sin cargar todo el documento en la memoria, y es una solución de rendimiento óptimo para aumentar el límite de datos/almacenamiento en un directorio.

Además, ayuda con la sincronización de documentos, archivos y metadatos y para implementar los datos en muchos sistemas para distribuir archivos y sus metadatos de manera eficiente y automática cuando se usan conjuntos de réplicas distribuidas geográficamente (distribución de datos a varias instancias mongod). GridFS facilita a los programadores almacenar y distribuir datos de dos maneras, incluido el uso de un controlador MongoDB o la herramienta de línea de comandos mongofiles.

Hay dos tipos de colecciones con las que trabaja GridFS, incluidas las colecciones de trozos y archivos. Además, representa la colección chunks de fs.chunks y la colección files de fs.files para un dólar llamado fs.

/*
prerequisites

i) MongoDB 3.0 or higher
ii) PHP Driver

[Remember| install both on the same server]

This example will store a >1GB video on a MongoDB server.

the source code `mkdir src` must be stored in a directory so create one
to create a successful connection and understanding between your files and storage, create a settings file
your new directory will contain a `Settings.php` file with the following PHP contents:
*/

<?php
    # Remember| PHP 7.0 allows you to have one `define` using an array
    define("USERNAME_MONGODB", "[your_username]");
    define("PASSWORD_MONGODB", "[your_password]");
    define("DATABASE_MONGODB", "[your_databaseName]");
    define("SERVERIP_MONGODB", "[your_serverIP or your_hostname]");

    // the following script will enable file storage so you can store a file
    require_once(__DIR__ . '/Settings.php');

    if (!isset($argv[1]))
    {
        die("Please mention/pass the filepath to the file you want to store in MongoDB Server.");
    }

    $storage_filepath = $argv[1];

    if (!file_exists($storage_filepath) || is_dir($storage_filepath))
    {
        die("Invalid! Please, re-check your filepath.");
    }


    function mongo_Connect($your_username, $your_password, $your_database, $your_host_serverIP)
    {
        $con_MongoDB = new Mongo("mongodb://{$your_username}:{$your_password}@{$your_host_serverIP}"); // Connect to Mongo Server
        $con_database = $con_MongoDB -> selectDB($your_database); // Connect to Database
        return $con_database;
    }

    $con_database = mongo_Connect(
        USERNAME_MONGODB,
        PASSWORD_MONGODB,
        DATABASE_MONGODB,
        SERVERIP_MONGODB
    );

    $grid_FS = $con_database -> getGridFS();

    # you can stick any metadata here, e.g., upload the owner's ID, date of execution, etc.
    $add_metadata = array("date" => new MongoDate());
    $storage_filepath = $storage_filepath;
    $grid_FS -> storeFile($storage_filepath, array("metadata" => $add_metadata));

    // You can execute the script using the php `StoreFile.php` "filename.com.avi"
    // list files with the file size
    require_once(__DIR__ . '/Settings.php');

    function _mongoConnect($your_username, $your_password, $your_database, $your_host_serverIP)
    {
        $con_MongoDB = new Mongo("mongodb://{$your_username}:{$your_password}@{$your_host_serverIP}"); // Connect to Mongo Server
        $con_database = $con_MongoDB -> selectDB($your_database); // Connect to Database
        return $con_database;
    }

    $con_database = _mongoConnect(
        USERNAME_MONGODB,
        PASSWORD_MONGODB,
        DATABASE_MONGODB,
        SERVERIP_MONGODB
    );

    $grid_FS = $con_database -> getGridFS();

    # Loop over the files and output their names and file sizes
    $storage_files = $grid_FS -> find();

    while (($your_file = $storage_files -> getNext()) != null)
    {
        print $your_file -> getFilename() . "\t" . $your_file -> getSize() . PHP_EOL;
    }

    // retrieve files
    require_once(__DIR__ . '/Settings.php');

    if (!isset($argv[1]))
    {
        die("Please mention/pass the filepath to the file you want to store in MongoDB Server.");
    }

    $storage_filepath = $argv[1];

    if (!file_exists($storage_filepath) || is_dir($storage_filepath))
    {
        die("Invalid! Please, re-check your filepath.");
    }

    function mongoConnect($your_username, $your_password, $your_database, $your_host_serverIP)
    {
        $con_MongoDB = new Mongo("mongodb://{$your_username}:{$your_password}@{$your_host_serverIP}"); // Connect to Mongo Server
        $con_database = $con_MongoDB -> selectDB($your_database); // Connect to Database
        return $con_database;
    }

    $con_database = mongoConnect(
        USERNAME_MONGODB,
        PASSWORD_MONGODB,
        DATABASE_MONGODB,
        SERVERIP_MONGODB
    );

    $grid_FS = $con_database -> getGridFS();

    # in the following code, you can search for the filepath passed in as the first argument
    $search_fileParams = array("filename" => $storage_filepath);

    if (false)
    {
        # If you used absolute paths when storing files, then you could use the following to download a folder's contents.
        $folder = '/path/to/folder';

        # Refer to https://secure.php.net/manual/en/class.mongoregex.php
        $file_get_filename = new MongoRegex("/^$folder");

        $search_fileParams = array(
            'filename' => $file_get_filename
        );
    }

    # Alternatively, use findOne($search_fileParams) if you expect only one file with the provided name.
    $storage_files = $grid_FS -> find($search_fileParams);

    while (($your_file = $storage_files -> getNext()) != null)
    {
        # Use a random string in case there is a file with the same name in the current directory.
        $random_string = substr(str_shuffle(MD5(microtime())), 0, 10);
        $outputFile_path = __DIR__ . '/' . $random_string . "_" . basename($your_file -> getFilename());
        $your_file -> write($outputFile_path);
        print "Retrieved: " . $outputFile_path . PHP_EOL;
    }

    // use the script like
    // php RetrieveFiles.php "my_filename.mp4"
?>

Producción :

Retrieved: my_filename.mp4

Utilice el método StoreUpload() si está desarrollando un sitio web PHP en lugar de una herramienta CLI (en lugar de utilizar el método StoreFile()). Use rutas relativas o completas para almacenar un archivo en el sistema, y el nombre de archivo almacenado en MongoDB será la cadena exacta que se pasó si pasa la ruta completa, como /ruta/a/archivo.mp4 y el nombre de archivo será lo mismo.

Recuerde, llamar al script varias veces en el mismo archivo no fallará; sin embargo, hacerlo puede desperdiciar valiosos recursos de almacenamiento almacenando el mismo archivo varias veces. El ejemplo de código PHP le muestra cómo usar MongoDB como el almacenamiento predeterminado para su sitio web o proyectos PHP.

Hadoop y su HDFS son una gran alternativa a MongoDB, pero es extremadamente complicado; sin embargo, admite trabajos Map/Reduce en comparación con MongoDB. Lo que es más importante, GridFS es una opción de primer nivel, ya que su implementación es del lado del cliente dentro del propio controlador (sin carga especial ni comprensión del contexto del archivo).

MongoDB y su GridFS se implementan con controladores, y la especificación puede variar, ya que los controladores le permitirán consultar una colección de documentos de la colección de archivos y permitirán a los programadores enviar más tarde el archivo mismo de la colección de fragmentos con una sola consulta. . Facilita la carga de la colección de archivos y la subsiguiente colección de fragmentos en su conjunto de trabajo.

Syed Hassan Sabeeh Kazmi avatar Syed Hassan Sabeeh Kazmi avatar

Hassan is a Software Engineer with a well-developed set of programming skills. He uses his knowledge and writing capabilities to produce interesting-to-read technical articles.

GitHub