2013-05-15 19 views
2

PHP 5.4.14 的SQL Server 2012/SQL客戶端2012 的Windows 2008 R2PHP SQLSRV:從一個函數傳遞一個資源

我有一個函數(簡化版本如下),我打電話來運行SQL查詢。它工作正常:連接到DB;運行查詢並獲取有效的資源。問題是,被返回的資源是空...

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服務器在一個函數外工作。我將不勝感激任何建議

乾杯

+0

一個函數沒有考慮輸出值...只是爲了返回值...只是一個提示;) –

回答

2

我這個發現一個迷人的問題,而尋找一個可能的原因,我發現this topic這實際上聽起來很有道理的。

總之:您在功能範圍內打開連接資源$conn。因此,在離開該範圍時它被破壞是有道理的。源自該連接資源的所有資源自動不再有效,因此解釋了爲什麼查詢資源在退出範圍時也會死亡。如果以這種方式來看待它,它也是有道理的 - 如果沒有其邏輯父資源,派生資源如何繼續存在。我們只是被PHP寵壞了,它通常不會在意這一點,但在C#/ Java等中它是合理的行爲。

如果這個假設是正確的,最簡單的解決方法是將global $conn;放在squeal函數的開頭,這樣它就不能超出範圍。根據代碼的其餘部分,您可以實現更優雅(且可能更少衝突)的解決方案,但實現並不是真正的猶太教,它連接在一個函數內,然後期望後續工作能夠在外部生存。

+0

謝謝你,是的PHP導致我成爲不好的做法。儘管不在示例中,$ result已經被聲明爲全局的,但不是$ conn,這就是爲什麼代碼知道什麼是資源#但忘記了它的內容。 無論如何,正如你所說,它的一個令人討厭的雜物讓我現在工作,但意味着對未來的重新設計。我想唯一的方法就是調用該函數,將所有數據提取到一個PHP數組中,並將其返回給調用代碼。 再次感謝 –

+0

說實話,我也認爲它應該被認爲是sqlsrv驅動程序中的一個錯誤,即父資源顯然沒有被正確引用計數,因此可能會與它的「子」一起死亡。然而,這可能是由PHP的內部消息引起的 - 「mysql」API只是在全局實例化之前保留所有內容,直到腳本終止,因此它們不存在這些問題。 –

+0

沒有保證,讓我們去做OOP,並做好它 –

相關問題