【问题标题】:PHP sqlsrv: passing a resource from a functionPHP sqlsrv:从函数传递资源
【发布时间】:2013-05-15 10:31:44
【问题描述】:

PHP 5.4.14 SQL Server 2012/SQL 客户端 2012 视窗 2008 R2

我有一个函数(以下是简化版),我调用它来运行 SQL 查询。它工作正常:连接到数据库;运行查询并获取有效资源。问题是返回的资源是null...

function squeal($query) {

    $serverName     = "XXXXXXXX\SQLEXPRESS";
    $uid            = "private";
    $pwd            = "private";
    $connectionInfo = array( "UID"=>$uid, "PWD"=>$pwd, "Database"=>"DBname");

    /* Connect using SQL Server Authentication. */
    $conn = sqlsrv_connect( $serverName, $connectionInfo);
    if( $conn === false ) {
         echo "Unable to connect.</br>";
         die( print_r(sqlsrv_errors(), true));
    }
    /* Run query */
    $result = sqlsrv_query( $conn, $query, array(), array("Scrollable"=>"buffered"));
    if( $result === false ) {
         echo "Error in executing query.</br>";
         die( print_r(sqlsrv_errors(), true));
    }
    /* check resource exists for debug (still fails without these lines) */
    echo("Resource=".intval($result)."</br>");
    echo("Has rows=".sqlsrv_has_rows($result)."</br>");

    return $result;
}

$tsql = "SELECT id FROM mytable";
$fred = squeal($tsql);

echo("Resource=".intval($fred)."</br>");
echo("Has rows=".sqlsrv_has_rows($fred)."</br>");

它给出以下输出...

Resource=8
Has rows=1
Resource=8

Warning: sqlsrv_has_rows(): 8 is not a valid ss_sqlsrv_stmt resource in <path> on line 85
Has rows=

SQL 工作正常并返回有效资源。从函数返回时,它知道它已经传递了资源#8(在这种情况下),但它是空的。我对 MySQL 使用了类似的方法,效果很好。我的整个 Intranet 应用程序依赖于能够调用函数来运行查询并取回资源。

将函数留在 sqlsvr/ODBC 中时资源是否会“死亡”?肯定不会。

我现在花了几天时间在谷歌上搜索答案,但只能让 SQL 服务器在函数之外工作。我将不胜感激任何建议

干杯

【问题讨论】:

  • 一个函数没有考虑输出值...只是返回值...只是一个提示;)

标签: php sql-server sqlsrv


【解决方案1】:

我发现这是一个有趣的问题,在寻找可能的原因时,我发现了this topic,这听起来似乎很合理。

简而言之:您在函数范围内打开连接资源$conn。因此,离开该范围时将其销毁是有道理的。源自该连接资源的所有资源都自动不再有效,因此这解释了为什么查询资源在退出范围时也会死亡。如果您以这种方式看待它,它也很有意义 - 派生资源如何在没有其逻辑父资源的情况下继续存在。我们只是被 PHP 宠坏了,它通常不关心这一点,但在 C#/Java 等中,这是合理的行为。

如果这个假设是正确的,最简单的解决方案是将global $conn; 放在squeal 函数的开头,这样它就不会超出范围。根据其余代码,您可以实现一个更优雅(且潜在冲突更少)的解决方案,无论如何,该实现并不是真正的犹太教,因为它连接在一个函数中,然后期望后续在外部继续存在。

【讨论】:

  • 谢谢你,是的,PHP 让我陷入了糟糕的实践。尽管在示例中 $result 没有被声明为全局变量,但不是 $conn,这就是为什么代码知道资源 # 是什么但忘记了它的内容的原因。无论如何,正如你所说,这是一个让我现在工作的讨厌的杂物,但意味着对未来的重新设计。我想唯一的犹太方法是调用函数,将所有数据提取到 PHP 数组中并将其返回给调用代码。再次感谢
  • 老实说,我也认为父资源没有被正确引用计数显然应该被认为是 sqlsrv 驱动程序中的一个错误,因此可能与它的“孩子”一起死亡。然而,这可能是由 PHP 的内部结构造成的 - mysql API 只是保持全局实例化所有内容,直到脚本终止,因此它们没有这些问题。
  • 没有保护,让我们去 OOP 并正确地完成它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多