file_get_contents ajax 上传大文件的替代方法

file_get_contents alternative for large files on ajax upload

显然大文件不适用于 php 的 file_get_contents。如果它显然是 "stack overflow" 问题,还有什么替代方案?

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));

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

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

我没有 SQL 服务器来测试它,但是你的代码看起来像这样:

$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);