2016-04-15 15 views
0

我更新項目從PHP 5.6PHP 7.0PHP 7.0循環後,纔開始從9.5 postgresql(版本獲取數據庫錯誤,如果有什麼差別)告訴插入的數據違反了約束檢查。與PHP 5.6再次運行相同的代碼,並沒有違反。刪除所有檢查,看看實際參數是什麼,看起來有空字符串,其中NULL值預計。我發現一些舊的和固定的PHP錯誤,其中pg_query()pg_query_params()NULL值轉換爲空字符串,但這是不同的。如果參數數組已被循環引用,則NULL只會被轉換爲空字符串。PHP 7.0 pg_query_params():空被轉換爲空字符串,但與基準

代碼演示問題:

$sql = "INSERT INTO params_test (value, details) VALUES ($1, $2)"; 

$params = array(null, "insert before looping with a reference"); 
var_dump($params); echo "<br>"; 
var_dump(is_null($params[0])); echo "<br>"; 
$result = pg_query_params($this->connection, $sql, $params); 

$params2 = array(null, "insert after looping with a reference"); 
foreach ($params2 as &$p) { 
    // doing nothing 
} 
unset($p); 
var_dump($params2); echo "<br>"; 
var_dump(is_null($params2[0])); echo "<br>"; 
$result = pg_query_params($this->connection, $sql, $params2); 

echo "NULL equals NULL: "; var_dump($params[0] === $params2[0]); echo "<br>"; 

輸出:

array(2) { [0]=> NULL [1]=> string(36) "insert before looping with reference" } 
bool(true) 
array(2) { [0]=> NULL [1]=> string(67) "insert after looping with a reference" } 
bool(true) 
NULL equals NULL: bool(true) 

PostgreSQL的日誌:

2016-04-15 09:28:04 EEST LOG: execute <unnamed>: INSERT INTO params_test (value, details) VALUES ($1, $2) 
2016-04-15 09:28:04 EEST DETAIL: parameters: $1 = NULL, $2 = 'insert before looping with a reference' 
2016-04-15 09:28:04 EEST LOG: execute <unnamed>: INSERT INTO params_test (value, details) VALUES ($1, $2) 
2016-04-15 09:28:04 EEST DETAIL: parameters: $1 = '', $2 = 'insert after looping with a reference' 

我會非常米如果有人能夠解釋這裏發生的事情,請欣賞...

+0

這可能是一個錯誤。 [處理的foreach](http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.foreach)肯定會改變,但我不明白這是如何造成這種情況。您可以向[PHP開發人員]提交一個錯誤(https://bugs.php.net),但在此之前,您可以從foreach中刪除'unset($ p);'(因爲它什麼都不做,除非這只是一個代碼的過度簡化版本)。 – pozs

+0

謝謝@pozs。這確實是一個過於簡化的版本。如果沒有'unset($ p);''var_dump''數組看起來像這樣:'array(2){[0] => NULL [1] =>&string(37) 。但是,當然,僅在foreach循環(將被編輯)之後纔可以解除設置。 – iivarih

回答