2012-09-29 51 views
2

我正在使用PHP5和MySQL開發一個網站。我使用mysqlnd驅動程序,我有一個使用預處理語句執行任何查詢的類。使用預準備語句在PHP5中獲取MySQL存儲過程的結果

我有一個表,我儲存關於照片的信息,就像是拍攝地點等的其ID,名稱,經緯度

我創建了以下存儲過程,並根據實施Haversin公式是什麼我在這裏找到:http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL

的程序是:

DELIMITER $$ 
CREATE PROCEDURE imagesNearMe(IN user_lat DOUBLE, IN user_lng DOUBLE, IN distance INT) 
READS SQL DATA 
BEGIN 

DECLARE lat1 DOUBLE; 
DECLARE lng1 DOUBLE; 
DECLARE lat2 DOUBLE; 
DECLARE lng2 DOUBLE; 

SET lng1 = user_lng - (distance/ABS(COS(RADIANS(user_lat)) * 69)); 
SET lng2 = user_lng + (distance/ABS(COS(RADIANS(user_lat)) * 69)); 
SET lat1 = user_lat - (distance/69); 
SET lat2 = user_lat + (distance/69); 

SELECT id, title, description, location, lat, lng, user_id, 
     3956 * 2 * ASIN(SQRT( 
     POWER(SIN((user_lat - ABS(lat)) * pi()/180/2), 2) + 
     COS(user_lat * pi()/180) * COS(ABS(lat) * pi() * 180) * POWER(SIN((user_lng - lng) * pi()/180/2), 2))) as distance 
     FROM images 
     WHERE (lat IS NOT NULL) AND (lng IS NOT NULL) 
      AND (lat BETWEEN lat1 AND lat2) 
      AND (lng BETWEEN lng1 AND lng2) 
     ORDER BY distance ASC; 

END$$ 
DELIMITER ; 

程序工作正常,當我從MySQL控制檯調用它,並返回預期的數據。問題是當我嘗試從我的PHP代碼中調用該過程時。出於某種原因,我無法獲取該過程返回的數據。

我有以下測試方法:

public function CallProcedure($procedure, $arguments) 
    { 
     print_r($procedure); 
     echo "<br>*************************<br>"; 

     if(! $this->_sqlStatement = $this->_dbSession->prepare($procedure)) 
     { 
      return FALSE; 
     } 

     else 
     { 
      //Prepare succeeded 
      if($arguments) 
      { 
       //if we have arguments we have to prepare and bind the to the query 
       //get the bind string 
       $bindString = array_shift($arguments); 

       //get references to the parameters passed to the query 
       $bindParamRefs = array(); 
       foreach($arguments as $key => $value) 
       { 
        $bindParamRefs[$key] = &$arguments[$key]; 
       } 
       //put a reference to the bindString inside the bindParamsRefs array 
       array_unshift($bindParamRefs, $bindString); 

       print_r($bindParamRefs); 
       echo "<br>*************************<br>"; 
       //Bind the params to the query 
       if(!call_user_func_array(array($this->_sqlStatement, "bind_param"), $bindParamRefs)) 
       { 
        return FALSE; 
       } 

       else 
       { 
        print_r($this->_sqlStatement); 
        echo "<br>*************************<br>"; 
        if(! $this->_sqlStatement->execute()) 
        { 
         return FALSE; 
        } 

        else 
        { 
         do 
        { 
         $this->_sqlStatement->store_result(); 
         print_r($this->_sqlStatement); 
         echo "<br>*************************<br>"; 


         $resultSet = array(); 
         $resultMetadata = $this->_sqlStatement->result_metadata(); 
         $resultVariables = array(); 
         $resultData = array(); 

         while($resultField = $resultMetadata->fetch_field()) 
         { 
          $resultVariables[] = &$resultData[$resultField->name]; 
         } 

         call_user_func_array(array($this->_sqlStatement, "bind_result"), $resultVariables); 

         $i = 0; 
         while($this->_sqlStatement->fetch()) 
         { 
          $resultSet[$i] = array(); 
          foreach($resultData as $fieldName => $fieldData) 
          { 
           $resultSet[$i][$fieldName] = $fieldData; 
          } 
          $i++; 
         } 

         print_r($resultSet); 
         echo "<br>*************************<br>"; 
         print_r($resultMetadata); 
         echo "<br>*************************<br>"; 
         print_r($resultVariables); 
         echo "<br>*************************<br>"; 
         print_r($resultData); 
         echo "<br>*************************<br>"; 

         $this->_sqlStatement->free_result(); 

        } 
        while($this->_sqlStatement->more_results() && $this->_sqlStatement->next_result()); 

        $this->_sqlStatement->close(); 
        } 
       } 
      } 
     } 

    } 

($這 - > _ dbSession是mysqli的的一個實例)

並且通過上面的代碼所產生的輸出是:

CALL imagesNearMe(?, ?, ?) 
************************* 
Array ([0] => ddi [1] => 38.246214 [2] => 38.246214 [3] => 150) 
************************* 
mysqli_stmt Object ([affected_rows] => -1 [insert_id] => 0 [num_rows] => 0 [param_count] => 3 [field_count] => 0 [errno] => 0 [error] => [sqlstate] => 00000 [id] => 1) 
************************* 
mysqli_stmt Object ([affected_rows] => 0 [insert_id] => 0 [num_rows] => 0 [param_count] => 3 [field_count] => 8 [errno] => 0 [error] => [sqlstate] => 00000 [id] => 1) 
************************* 
Array () 
************************* 
mysqli_result Object ([current_field] => 8 [field_count] => 8 [lengths] => [num_rows] => 0 [type] => 1) 
************************* 
Array ([0] => [1] => [2] => [3] => [4] => [5] => [6] => [7] =>) 
************************* 
Array ([id] => [title] => [description] => [location] => [lat] => [lng] => [user_id] => [distance] =>) 
************************* 

正如你可以看到的那樣,即使語句正確執行,也不會返回任何數據,即使通過調用完全相同的過程並從mysql控制檯返回4個相同的參數sults。

我錯過了什麼嗎?我完全迷失在這裏。

在此先感謝您的幫助。


UPDATE


下面的代碼:

$dbSession = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT); 

if($dbSession->connect_errno) 
{ 
    die($dbSession->connect_error); 
} 

else 
{ 
    $query = "CALL imagesNearMe(38.2462140, 21.735098, 50)"; 

    if(!$dbSession->multi_query($query)) 
    { 
     die($dbSession->error); 
    } 

    else 
    { 
     do 
     { 
      if($result = $dbSession->store_result()) 
      { 
       var_dump($result->fetch_all()); 
       echo "<br>******************************************************<br>"; 
       $result->free(); 
      } 
      else 
      { 
       die($dbSession->error); 
      } 
     } 
     while($dbSession->more_results() && $dbSession->next_result()); 

     $dbSession->close(); 
    } 
} 

返回所有的結果我希望,但爲什麼不是準備好的語句的工作?

回答

1

找到你的問題

的,因爲call_user_func_array運作的,你需要使用引用(以下簡稱「&」)的方式,您是通過fetch()方法在同一個參考循環 - 有第2個結果一套回來說CALL語句是成功的,其覆蓋的結果集,你正在尋找一個空白的結果集

嘗試改變「OK」

 
$i = 0; 
while($this->_sqlStatement->fetch()) 
{ 
    $resultSet[$i] = array(); 
    foreach($resultData as $fieldName => $fieldData) 
    { 
      $resultSet[$i][$fieldName] = $fieldData; 
    } 
    $i++; 
} 

 
if(!$this->_sqlStatement->fetch()) 
{ 
    //break do-while() loop 
    break; 
} 
$resultSet[$i] = array(); 
foreach($resultData as $fieldName => $fieldData) 
{ 
    $resultSet[$i][$fieldName] = $fieldData; 
} 
$i++; 

你還需要做,而()之前設置的初始$i值開始

+0

感謝。我會嘗試一下,儘快報告。 – feugatos

相關問題