Большие файлы .PDF не загружаются в базу данных MySQL как средний большой двоичный объект через PHP, файлы размером менее 2 МБ работают нормально

Я разрабатываю PHP-скрипт для загрузки документов .PDF в виде больших двоичных объектов среднего размера в базу данных MySQL через PHP. Скрипт также позволяет пользователям искать файлы и открывать / скачивать их, но я не думаю, что эта часть скрипта имеет отношение к моей проблеме. Сценарий отлично работает с файлами размером менее 2 МБ, но как только я пытаюсь загрузить файл размером более 2 МБ, в столбец содержимого (средний BLOB) ничего не попадает, и нет значения для типа mime. Я уже пробовал увеличить max_packet_size для сервера MySQL до 4 МБ со значения по умолчанию, равного 1 МБ. Думаю, я также обновил php.ini до правильных значений. Я установил upload_max_size на 4 МБ, post_max_size на 4 МБ и memory_limit на 16 МБ. Я действительно не экспериментировал с max_input_time, потому что по умолчанию он равен 60 секундам, что кажется достаточно большим, учитывая, что этот сценарий предназначен для внутреннего приложения в интрасети.

Я также попытался отловить ошибки объекта PDO в моем скрипте с помощью errorInfo () и errorCode (), и оба через 0 (без ошибок).

Вот раздел загрузки моего скрипта:

if ($key == 'upload')
{
    set_time_limit(0);
    $_SESSION['upload'] = $value;

    if ($_FILES['userfile']['name'])
    {
        $fileName = $_FILES['userfile']['name'];
        $tmpName  = $_FILES['userfile']['tmp_name'];
        $fileSize = $_FILES['userfile']['size'];
        $fileType = $_FILES['userfile']['type'];
        $docType = $_POST['docType'];
        $netKey = $_POST['netKey'];
        $fp       = fopen($tmpName, 'r');
        $content  = fread($fp, filesize($tmpName));
        $content  = addslashes($content);
        fclose($fp);

        $_SESSION['filetype'] = $fileType;

        if(!get_magic_quotes_gpc())
        {
            $fileName = addslashes($fileName);
        }
        $sqlCheck = "SELECT id, name, documentType, networkKey FROM upload WHERE active='1'";
        foreach ($dbh->query($sqlCheck) as $row)
        {
            if (($row['name'] == $fileName) && ($row[networkKey] == $netKey) && ($row['documentType'] == $docType)) 
            {
                $_SESSION['updateRow'] = $row['id'];
            }

        }

        if ($_SESSION['updateRow'])
            {
                $deactivateDuplicate = "UPDATE upload SET active = 0, modifiedBy = '".strtoupper($_SERVER['REMOTE_USER'])."', modifiedDate = Now() WHERE id = '".$_SESSION['updateRow']."' AND active ='1'";
                $dbh->query($deactivateDuplicate);
                $_SESSION['sql'] = "SELECT id, name, documentType, type, size, networkKey, modifiedBy, modifiedDate, active FROM upload WHERE active = '1'";
                $_SESSION['uploadSearch'] = 1;
                $_SESSION['updateRow'] = 0;
            }
            $values = "'".$fileName."','".$docType."','".$fileType."','".$content."','".$fileSize."','".$netKey."','".strtoupper($_SERVER['REMOTE_USER'])."', Now(), 1";
            $sqlUpload = "INSERT INTO upload (name, documentType, type, content, size, networkKey, modifiedBy, modifiedDate, active) VALUES (".$values.")";
            $dbh->query($sqlUpload);

            $_SESSION['sql'] = "SELECT id, name, documentType, type, size, networkKey, modifiedBy, modifiedDate, active FROM upload WHERE active = '1'";
            $_SESSION['uploadSearch'] = 1;


    }
}

А вот внешний интерфейс приложения, показывающий, что файл меньшего размера работает, а файл большего размера - нет. Размер файла sample.pdf меньше 1 МБ, а файла test.pdf - 2,5 МБ.

http://www.imagechicken.com/viewpic.php?p=1255628359017775300&x=png

Я бы использовал теги img, но, увы, я новый пользователь и мне это не разрешено.

Следующее, что я собираюсь найти, - это параметр в Apache, ограничивающий размер файлов. Я новичок в LAMP, поэтому любые советы будут отличными. Спасибо


person dbaugh    schedule 15.10.2009    source источник
comment
У меня все еще проблема с этим. Оказалось, что он работает после того, как я сделал то, что было рекомендовано в этой теме. Я установил параметр max_allowed_packet в MySQL на 4M, а значения публикации и загрузки в php.ini - более чем адекватные значения. Проблема, с которой я столкнулся сейчас, заключается в том, что файлы кажутся загружаемыми, но они по-прежнему ограничены размером 1M, что очевидно, когда я пытаюсь их загрузить. В массиве $ _FILES файл имеет правильный размер, но после того, как файл вставлен в базу данных MySQL, содержимое обрезается до 1 МБ, хотя столбец размера по-прежнему дает правильный размер. Пожалуйста помоги.   -  person dbaugh    schedule 20.10.2009


Ответы (5)


Возможно, вы столкнулись с ограничениями HTTP-запроса (который, я думаю, составляет 4 МБ), или ваш HTTP-запрос может истекать. Я уже сталкивался с этой проблемой раньше. Возможно, вы захотите посмотреть @ свой файл php.ini, чтобы узнать максимальный размер загружаемого файла.

Отказ от ответственности: я не разработчик PHP: D

person andrewWinn    schedule 15.10.2009
comment
+1 - скорее всего, это проблема конфигурации PHP, а не MySQL - person Eric Petroelje; 15.10.2009
comment
Я думаю, вам придется передавать файлы в потоковом режиме, но я никогда раньше этого не делал, особенно с PHP и / или MySQL. - person Julius F; 21.10.2009

Возможно, у вас установлен лимит mySQL.

Выполните в mySQL следующее:

show variables like 'max_allowed_packet'  

Это покажет вам ваши текущие настройки. По умолчанию 1047552 байта.

Это можно изменить с помощью файла my.cnf. Просто добавьте

set-variable = max_allowed_packet=2M

или любого необходимого размера и перезапустите mySQL.

РЕДАКТИРОВАТЬ:
Как насчет

<input type="hidden" name="MAX_FILE_SIZE" value="xxx" />

Может ли это быть частью проблемы?

person Jason    schedule 15.10.2009
comment
У меня уже был администратор базы данных, обновивший max_allowed_packet до 4M. - person dbaugh; 16.10.2009
comment
Я проверю свой вклад на работе. Что именно могло быть причиной проблемы. - person dbaugh; 16.10.2009
comment
Хороший звонок, Джейсон. Я установил значение «20000000», что, очевидно, было бы проблемой. Однако после того, как я изменил значение на «160000000», что более чем достаточно, файл не попадает в базу данных. Это похоже на то, что запрос вообще не выполняется. - person dbaugh; 16.10.2009
comment
Просто пришлось перезапустить apache. Хороший звонок, я совсем забыл об этом. - person dbaugh; 16.10.2009

Я действительно исправил проблему. Я изменил все рекомендованные здесь значения в php.ini и my.cnf, но мне также нужно было изменить настройку для PDO.

Я изменил: PDO :: MYSQL_ATTR_MAX_BUFFER_SIZE (целое число) Максимальный размер буфера. По умолчанию 1 МБ.

Это должно быть установлено при создании объекта PDO для работы. Теперь все хорошо.

person dbaugh    schedule 21.10.2009

Итак, чтобы резюмировать все вещи, которые, как мне кажется, мне пришлось установить, чтобы разрешить загрузку файлов> 1 МБ для того, над чем я работал:

php.ini

  • Изменен post_max_size (я хотел закачать файлы размером 15 МБ, поэтому на всякий случай установил 20M)
  • Изменен upload_max_filesize на 15M
  • Оставил max_execution_time на 60
  • Оставил max_input_time в 60
  • Оставил default_socket_timeout на 60

my.ini

  • Изменен max_allowed_packet на 15M

Код PHP

  • изменил мой вызов PDO на:

    new PDO("mysql:host=$host;dbname=$db_name", $db_username, $db_password, array (PDO::MYSQL_ATTR_MAX_BUFFER_SIZE=>15*1024*1024))

person Andrew Coleson    schedule 16.11.2009

Если вы пытаетесь сделать это на виртуальном хостинге (где вы не можете вносить изменения в файлы MySQL conf и т. Д.), Используйте Google «подготовленные операторы mysqli».

Это позволяет загружать большие запросы заранее определенными байтовыми блоками, обходя любые ограничения буфера.

person Lee Benson    schedule 09.03.2010