这是一种后续行动这个问题 https://stackoverflow.com/questions/67998821/create-file-system-file-from-file-stored-in-microsoft-sql-database.
此代码重试数据库中的一行,其中一列是资源,并用它创建一个文件系统文件。
$query = "select top(1) DESCRIPTION, FILETYPE, DOCUMENT from dbo.Documents;";
$stmt = sqlsrv_query($this->sqlsrv_conn, $query);
if (sqlsrv_fetch($stmt)) {
$document = sqlsrv_get_field($stmt, 2, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY));
// $fileName = sqlsrv_get_field($stmt, 0, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR));
// $ext = sqlsrv_get_field($stmt, 1, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR));
file_put_contents(
// $fileName . '.' . $ext,
'filename'.'.doc',
stream_get_contents($document),
);
}
现在我必须对数据库中的所有记录执行此操作,而不仅仅是一条记录。实现这一目标的最佳方法是什么?
我在看sqlsrv_fetch_array https://www.php.net/manual/en/function.sqlsrv-fetch-array.php它有一个参数“$fetchType”,但这是定义行分组在一起的格式(编号或关联数组)。
如何为该行数组下的每一列定义 fetchType?就像我可以与sqlsrv_get_field($stmt, 2, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY))
当仅获取一行时。
注意:我收到的反馈表明我的问题往往不清楚,如果您发现可以改进的地方以使这个问题更好更容易回答,请告诉我。
Edit
谢谢@Zhorov while 循环确实有效!但我面临一个新的愚蠢问题。
我撒谎了,我发布的代码并不完全适合我。显然我也没有正确测试它并获取文件名和扩展名。只有当我以流的形式获取二进制数据时才有效没有别的.
我根本不明白。以下代码按预期工作:
$query = "select top(1) DESCRIPTION, FILETYPE, DOCUMENT from dbo.Documents;";
$stmt = sqlsrv_query($this->sqlsrv_conn, $query);
if (sqlsrv_fetch($stmt)) {
$document = sqlsrv_get_field($stmt, 2, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY));
// $fileName = sqlsrv_get_field($stmt, 0, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR));
file_put_contents(
// $fileName . '.doc',
'filename.doc',
stream_get_contents($document),
);
}
但如果我还想获取文件名或其他任何内容
$query = "select top(1) DESCRIPTION, FILETYPE, DOCUMENT from dbo.Documents;";
$stmt = sqlsrv_query($this->sqlsrv_conn, $query);
if (sqlsrv_fetch($stmt)) {
$document = sqlsrv_get_field($stmt, 2, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY));
$fileName = sqlsrv_get_field($stmt, 0);
file_put_contents(
'filename.doc',
stream_get_contents($document),
);
}
我得到以下异常:
错误:stream_get_contents():提供的资源不是有效的流资源文件
I debugged it down to this with xdebug. Here are screenshots of the two scenarios. This is the run with a valid stream and no exception (you can see the "type=stream"):
![enter image description here](https://i.stack.imgur.com/JLvAI.png)
And here, the only thing I did is remove the comment on the line and a breakpoint right before the exception happens (you can see the "type=Unknown"):
Why does fetching something else break the stream? (This behaviour is the same when I using while loop or not)
Edit 2
更改顺序时,行为确实会改变sqlsrv_get_field
叫做。如果我将二进制数据放在文件名后面,$document
变量是false
。甚至不是“未知”流。
编辑:正如@Zhorov 指出的那样,原因是:
From 文档 https://learn.microsoft.com/en-us/sql/connect/php/sqlsrv-get-field?view=sql-server-ver15 - sqlsrv_get_field 从当前行的指定字段检索数据。必须按顺序访问字段数据。例如,访问第二个字段的数据后,将无法访问第一个字段的数据