gpt4 book ai didi

PHP使用sqlsrv一次检索包含流内容的多行

转载 作者:行者123 更新时间:2023-12-04 07:23:08 25 4
gpt4 key购买 nike

这是对 this question 的一种跟进.
此代码重试数据库中的一行,其中一列是资源,并使用它创建文件系统文件。

$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 它有一个参数“$fetchType”,但这是定义行组合在一起的格式(编号或关联数组)。
如何为该行数组下的每一列定义 fetchType?就像我可以用 sqlsrv_get_field($stmt, 2, SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY))当只获取一行时。
注意:我收到反馈说我的问题往往不清楚,如果您看到可以改进的地方以使这个问题更好更容易回答,请告诉我。
编辑
谢谢@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),
);
}
我收到以下异常:

Error: stream_get_contents(): supplied resource is not a valid stream resource File


我用 xdebug 将它调试到这个。下面是两种场景的截图。这是带有有效流的运行,没有异常(exception)(您可以看到“type=stream”):
enter image description here
在这里,我唯一做的就是在异常发生之前删除该行上的注释和断点(您可以看到“type = Unknown”):
enter image description here
为什么获取其他东西会破坏流? (无论是否使用 while 循环,此行为都相同)
编辑 2
更改 sqlsrv_get_field 的顺序时,行为确实会发生变化叫做。如果我把二进制数据放在文件名后面, $document变量是 false .甚至不是“未知”流。
enter image description here
编辑:原因是,正如@Zhorov 指出的那样:

From documentation - sqlsrv_get_field retrieves data from the specified field of the current row. Field data must be accessed in order. For example, data from the first field cannot be accessed after data from the second field has been accessed

最佳答案

@Zhorov 使我走上了解决方案的正确轨道。
似乎必须最后访问流内容。如果我在文档之前获取文件名,则流为“未知”并引发异常。但是如果我最后得到了流,它就起作用了!
你自己看。以下是流无效的版本:
enter image description here
并在检索列 DOCUMENT 中的二进制数据时最后,它的工作原理:
enter image description here

关于PHP使用sqlsrv一次检索包含流内容的多行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68378902/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com