大型 .PDF 文件无法通过 PHP 作为中型 BLOB 上传到 MySQL 数据库,2MB 以下的文件工作正常
我正在开发一个 PHP 脚本,用于通过 PHP 将 .PDF 文档作为中等 BLOB 上传到 MySQL 数据库中。该脚本还允许用户搜索文件并打开/下载它们,但我认为该脚本的一部分与我的问题无关。该脚本适用于小于 2 MB 的文件,但一旦我尝试上传大于 2 MB 的文件,我的内容(中 BLOB)列中就不会出现任何内容,并且 mime 类型没有值。我已经尝试将 MySQL 服务器的 max_packet_size 从默认值 1 MB 增加到 4 MB。我认为我还将 php.ini 更新为正确的值。我将 upload_max_size 设置为 4MB,post_max_size 设置为 4 MB,memory_limit 设置为 16 MB。不过,我还没有真正尝试过 max_input_time,因为它默认为 60 秒,考虑到该脚本用于 Intranet 上的内部应用程序,这似乎已经足够了。
我还尝试使用 errorInfo() 和 errorCode() 捕获脚本中 PDO 对象的错误,并且两者都通过 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 MB,文件test.pdf 为2.5 MB。
http://www.imagechicken.com/viewpic.php?p=1255628359017775300& ;x=png
我本来会使用 img 标签,但可惜我是新用户,不允许。
接下来我要寻找的是 Apache 中限制文件大小的设置。我是 LAMP 新手,所以任何建议都会很棒。 谢谢
I am developing a PHP script for uploading .PDF documents as medium BLOBs into a MySQL database via PHP. The script also allows users to search for files and open/download them but I do not think that part of the script is relevant to my issue. The script works fine with files less than 2 MB but as soon as I try and upload a file that is more than 2 MB nothing is going into my content(Medium BLOB) column and there is no value for the mime type. I have already tried increasing the max_packet_size for the MySQL server to 4 MB from its default value of 1 MB. I have also updated php.ini to the correct values, I think. I set upload_max_size to 4MB, post_max_size to 4 MB, and memory_limit to 16 MB. I haven't really experimented with the max_input_time though because it is defaulted to 60 seconds which seems like plenty considering this script is for an internal application on an intranet.
I have also tried to catch errors from the PDO object in my script with errorInfo() and errorCode() and both through 0s (no error).
Here is the upload section of my script:
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;
}
}
And Here is the front end of the application showing that a smaller file works and a larger file does not. The file sample.pdf is less than 1 MB and the file test.pdf is 2.5 MB.
http://www.imagechicken.com/viewpic.php?p=1255628359017775300&x=png
I would have used img tags but alas I am a new user and not allowed.
The next thing I am going to look for is a setting in Apache that limits file sizes. I am new to LAMP so any tips would be great.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可能会遇到 HTTP 请求的限制(我认为是 4MB),或者您的 HTTP 请求可能会超时。我以前遇到过这个问题。您可能需要查看您的 php.ini 文件以了解最大上传大小。
免责声明:我不是 PHP 开发人员 :D
YOu might be running up against the limitations of the HTTP request (which I think is 4MB), or your HTTP request might be timming out. I have run into this issue before. You might want to look @ your php.ini file for maximum upload size.
Disclaimer: I am not a PHP developer :D
您可能遇到了 mySQL 限制。
在 mySQL 中运行以下命令:
这将显示您当前的设置。
默认值为 1047552 字节。
这可以通过您的 my.cnf 文件进行更改。
只需添加
或需要任何大小,然后重新启动 mySQL。
编辑:
吗?
这可能是问题的一部分
You might be running into a mySQL limit.
Run the following in mySQL:
That will show you your current setting.
The default is 1047552 bytes.
This can be changed with your my.cnf file.
Simply add
or what ever size is required and restart mySQL.
EDIT:
What about
Might that be part of the problem?
我实际上解决了这个问题。我更改了 php.ini 和 my.cnf 中推荐的所有值,但我还需要更改 PDO 的设置。
我改变了:
PDO::MYSQL_ATTR_MAX_BUFFER_SIZE(整数)
最大缓冲区大小。默认为 1 MiB。
必须在创建 PDO 对象时设置此项才能工作。现在一切都很好。
I actually fixed the issue. I changed all of the values that were recommended here in php.ini and my.cnf but I also needed to change a setting for PDO.
I changed:
PDO::MYSQL_ATTR_MAX_BUFFER_SIZE (integer)
Maximum buffer size. Defaults to 1 MiB.
This has to be set when the PDO object is created to work though. All is good now.
因此,回顾一下我认为我必须设置的所有内容,以便允许我正在处理的事情上传> 1MB:
php.ini
post_max_size
(我想要 15MB 文件上传,所以我设置以防万一,将其更改为20M
)upload_max_filesize
更改为15M
max_execution_time
更改为60
max_input_time
为60
default_socket_timeout
为60
my.ini
max_allowed_packet
更改为 < code>15MPHP 代码
将我的 PDO 调用更改为:
new PDO("mysql:host=$host;dbname=$db_name", $db_username, $db_password, array (PDO::MYSQL_ATTR_MAX_BUFFER_SIZE=>15*1024*1024))
< /p>So to recap all the things I believe I had to set in order to allow file uploads >1MB on something I was working on:
php.ini
post_max_size
(I wanted 15MB file uploads, so I set it to20M
just in case)upload_max_filesize
to15M
max_execution_time
at60
max_input_time
at60
default_socket_timeout
at60
my.ini
max_allowed_packet
to15M
PHP Code
changed my PDO call to:
new PDO("mysql:host=$host;dbname=$db_name", $db_username, $db_password, array (PDO::MYSQL_ATTR_MAX_BUFFER_SIZE=>15*1024*1024))
如果您尝试在共享主机上执行此操作(您无法更改 MySQL conf 文件等),请谷歌“mysqli 准备好的语句”。
这允许您以预定义的字节块上传大型查询,从而规避任何缓冲区限制。
If you're trying to do this on shared hosting (where you can't make changes to MySQL conf files, etc), Google 'mysqli prepared statements'.
This allows you to upload large queries in predefined byte chunks, circumventing any buffer restrictions.