【问题标题】:Saving files to varbinary(max) field? [duplicate]将文件保存到 varbinary(max) 字段? [复制]
【发布时间】:2011-02-16 20:04:27
【问题描述】:

我整天都在做这件事,但我似乎无法弄清楚。我们的客户希望我们将他们上传的文件保存到我们数据库 (mssql) 中的一个表中。他们可以上传什么样的文件没有限制,所以根据我所拥有的有限知识,我做了一些谷歌搜索并尝试了以下操作:

我创建了这张表:

CREATE TABLE files
  (
    id int NOT NULL PRIMARY KEY IDENTITY,
    name varchar(256),
    content varbinary(max) NOT NULL,
    type varchar(30) NOT NULL,
    size int NOT NULL
    table_id INT NOT NULL FOREIGN KEY REFERENCES myTable(id)
   );

然后我尝试添加这样的内容:

$newfileName = $_FILES['uploadfile']['name'];
$newtmpName  = $_FILES['uploadfile']['tmp_name'];
$newfileSize = $_FILES['uploadfile']['size'];
$newfileType = $_FILES['uploadfile']['type'];

//need to get the content of the file
$fp = fopen($newtmpName, 'r');
$file_content = fread($fp, filesize($newtmpName));
$file_content = $file_content;
fclose($fp);

$sql = 'INSERT INTO files ([name], [content], [type], [size], [table_id]) VALUES ("'.$newfileName.'",CAST("'.$file_content.'" AS varbinary(max)),"'.$newfileType.'","'.$newfileSize.'","'.$table_id.'")';

但它只是不起作用...我可以上传 txt 文件没问题,但其他任何东西都会破坏。我收到如下错误(每个文件都不同):

[42000][105] [微软][SQL Server 本机客户端 10.0][SQL [服务器]后引号不加引号 字符串“����”。 [42000][102][微软][SQL Server 本机客户端 10.0][SQL 服务器]'����'附近的语法不正确。

现在我认为这是文件内容破坏 SQL 的问题,但我有 NO CLUE 如何处理它们(或如何将它们转换为不会破坏的字符串sql)。任何帮助将不胜感激,因为我对此完全迷失了。

(是的,我知道我没有保护自己免受这里的攻击,但现在我只是想让基础知识发挥作用)

【问题讨论】:

  • 你用的是PHP的Mssql驱动还是微软的sqlsrv?
  • 你为什么在二进制数据上调用addslashes()
  • @Hamish:我正在使用 sqlsrv 驱动程序。 @jnpcl:那是我忘记删除的东西(现在不在我的代码中)。我基本上只是在试验,因为我的很多错误都与引号有关,所以我想看看它是否能解决问题。
  • 你会再花一周时间尝试在网页上展示它
  • @Col。弹片:我已经创建了脚本来下载文件,一旦它们被保存到数据库,并且在对二进制数据进行编码后,就像下面提到的 Hamish 一样,我可以毫无问题地下载它们。我认为可能会出现一些错误,但到目前为止一切都很好:)

标签: php sql-server file-upload


【解决方案1】:

【讨论】:

  • 谢谢!这就是我一直在寻找的。你不知道我在这方面研究了多久,处理文件不是我的强项:P 只要网站允许,我就会把它变成正确的答案。
【解决方案2】:

在我使用 Microsoft 的 sqlsrv-Driver 的情况下,到目前为止,最简单的方法是使用参数!这样可以避免在二进制数据中使用引号,并且它会像它一样进入数据库......

代码片段:

$sql = "INSERT INTO tablename (binaryImageField) VALUES (CAST (? AS varbinary(max)))";
$params = array($binaryImageData);
sqlsrv_query($con,$sql,$params);

【讨论】:

    【解决方案3】:

    尝试使用 fopen 的二进制标志 (b):

    $fp = fopen($newtmpName, 'rb');
    $file_content = fread($fp, filesize($newtmpName));
    

    另外,我不确定您是否应该 addslashes 您的数据。我从来没有在 PHP 中使用过 MSSQL,所以我不知道。

    【讨论】:

    • 是的,addlashes 是我忘记从示例中删除的旧代码,现在不存在。我将编辑我的问题以删除以防它可以帮助某人。只是出于好奇,我添加了二进制标志,但它没有起到作用。也许还有其他事情要做,但既然我的问题现在已经解决了,我将让它休息并继续做更大的鱼:)
    猜你喜欢
    • 2014-11-05
    • 2021-10-23
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    相关资源
    最近更新 更多