Tengo el código en busca de algo como esto:

$data = file_get_contents($tempFile); //perhaps 30MB of file data, now in PHP's memory
$hash = md5($data);
$query = "INSERT INTO some_table
          SET BlobData = '" . mysql_real_escape_string($data) . "',
          BlobHash = '$hash'
          ";
mysql_query($query);

Sé que esto no es muy eficiente ya que cada uno de los ‘.’ de los operadores de reasignar un mayor bloque de memoria y el de 30MB cadena será copiada varias veces.

Hay nada más eficiente que la siguiente solución?

$data = file_get_contents($tempFile); //perhaps 30MB of file data, now in PHP's memory
$hash = md5($data);
$query = "INSERT INTO some_table SET BlobData = '%s', BlobHash = '$hash'";
mysql_query(sprintf($query, mysql_real_escape_string($data)));

OriginalEl autor too much php | 2008-10-17

5 Comentarios

  1. 7

    Tiene dos problemas aquí:

    #1, hay varias maneras diferentes que usted puede calcular el hash MD5:

    • Hacer lo que haces y de carga en PHP como una cadena y el uso de PHP, md5()
    • Uso de PHP, md5_file()
    • Como de PHP 5.1+ se puede utilizar PHP flujos de la API con cualquiera de md5 o md5_file para evitar cargar completamente en memoria
    • Uso exec() llamar al sistema de md5sum comando
    • Uso de MySQL MD5() la función para calcular el hash

    Ya que todos estos son triviales para implementar sería fácil para usted para poner en práctica y de referencia a todos ellos por el uso de la memoria y la velocidad. Aquí están algunos puntos de referencia mostrando el sistema de md5 a través de exec a ser mucho más rápido que PHP md5_file como el tamaño del archivo aumenta. Haciendo su camino es sin duda la peor manera, tan lejos como el uso de memoria se refiere.

    #2, mysql_real_escape_string realiza una consulta de base de datos, entonces la transmisión de sus datos blob en la base de datos, obteniendo como una cadena, y que se transmite de nuevo(!) con la consulta de INSERCIÓN. Así que viajan hacia y desde el servidor de DB 3x lugar de 1x y 2x usando la memoria en PHP.

    Va a ser más eficaz el uso de PHP5 declaraciones preparadas y sólo enviar estos datos a la base de datos de una vez. Leer el artículo enlazado sección, verás que se menciona que cuando los parámetros de enlace, usted puede utilizar el tipo blob para transmitir datos blob en la base de datos en trozos. El PHP docs para mysqli_stmt::send_long_data tienen un gran ejemplo sencillo de esto que se Inserta un archivo en una columna blob igual que usted.

    Por ello, y mediante el uso de cualquiera de los arroyos de la API, md5_file o exec con el sistema md5 de comandos, usted puede hacer su totalidad INSERTAR sin cargar todo el archivo en la memoria, lo que significa que el uso de la memoria para su serie de operaciones puede ser tan bajo como usted desea!

    OriginalEl autor joelhardi

  2. 3

    Si usted está usando PDO, y preparado instrucciones puede utilizar el PDO::PARAM_LOB tipo. Vea el ejemplo #2 en la página LOB que muestra cómo insertar una imagen en una base de datos utilizando el puntero de archivo.

    http://us2.php.net/manual/en/pdo.lobs.php

    Problema con DOP es sólo emula preparado instrucciones si no tienes el mysqli biblioteca. Así que todo lo que esto hace es mover la concatenar en el PDO de la biblioteca.

    OriginalEl autor Zoredache

  3. 0

    Ha comparativo de los buffers de salida truco?

    ob_start();
    echo 'INSERT INTO some_table SET BlobData = \'', mysql_real_escape_string( $data ), '\', BlobHash = \'', $hash, '\'';
    mysql_query( ob_get_clean() );

    Otra cosa que usted podría hacer es convertir a mysqli o MDB2, que apoyan a los parámetros vinculados. Que te permiten saltar la mysql_real_escape_string llamada y las concatenaciones de cadenas.

    OriginalEl autor Don Neufeld

  4. 0

    Haría ninguna diferencia si usted no poner la consulta en una variable, sino que pasó directamente en el comando MySQL. Nunca he probado esto, pero puede hacer una diferencia como la totalidad de la cadena no se almacena en otra variable.

    OriginalEl autor Darryl Hein

  5. -1

    Bien si el uso de la memoria es su problema, usted puede leer el archivo de gran tamaño en fragmentos e insertar estos trozos con CONCAT en el campo de base de datos.

    Código de ejemplo (no probado):

        $id = 1337;
    $h = fopen("path/to/file.ext", "r");
    while (!feof($h)) 
        {
        $buffer = fread($h, 4096);
        $sql = "UPDATE table SET my_field = CONCAT(my_field, '" . mysql_real_escape_string($buffer) . "') WHERE Id = " . $id;
        mysql_query($sql);
        }

    Este método será más lento, pero usted necesita sólo 4Kb de su memoria.

    OriginalEl autor Joe Scylla

Dejar respuesta

Please enter your comment!
Please enter your name here