file_get_contents替代ajax上传中的大文件

时间:2018-11-28 18:59:49

标签: javascript php ajax file-get-contents

显然,大文件不适用于php的file_get_contents。如果显然是“堆栈溢出”问题,该怎么办?

HTML文件

<form id='test'>
 <input type='file' name='Receipt' />
</form>
<button onClick='save_Receipt();'>Save</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
function save_Receipt(){
 var ticketData = new FormData($('form#test')[0]);
 $.ajax({
  cache: false,
  processData: false,
  contentType: false,
  url:"cgi-bin/php/post/testimage.php",
  method:"POST",
  data:ticketData,
  success:function(code){}
 });
}
</script>

PHP文件

ini_set('memory_limit','512M');
$img = file_get_contents($_FILES['Receipt']['tmp_name']);

echo base64_encode($img);
echo $img;
sqlsrv_query($Portal,
" INSERT INTO Portal.dbo.[File]([Name], [Type], [Data], [User], Ticket)
  VALUES(?, ?, ?, ?, ?);", array($_FILES['Receipt']['name'], $_FILES['Receipt']['type'],  array(base64_encode($img), SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY), SQLSRV_SQLTYPE_VARBINARY('max')), $_SESSION['User'], 2094378));

为了更好地说明,回声不会导致任何事情

1 个答案:

答案 0 :(得分:1)

几乎每个数据库驱动程序都有一种方法来处理过大的BLOB数据,而不必不必要地增加内存需求。 Sqlsrv似乎是您可以将PHP流指定为输入类型。

我没有SQL Server可以对此进行测试,但是您的代码如下所示:

$fh = fopen($theFile, 'rb');
$stmt = sqlsrv_prepare(
  $conn,
  'INSERT INTO blobTable VALUES (?)',
  [
    [$fh, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY), SQLSRV_SQLTYPE_BLOB]
  ]
);
$stmt->execute();
fclose($fh);

参考:

此外,我不知道您是否需要将其输出为base64,但是您也可以流式传输该输出。 Base64可以将3个字节的输入编码为4个字节的输出而无需填充,因此,只要您使用大小为3的倍数的输入块,就可以安全地将它们连接在一起。

例如:

$fh = fopen($theFile, 'rb');
while( $buf = fread($fh, 3072) ) {
  echo base64_encode($buf);
}
fclose($fh);