0
我更新項目從PHP 5.6
到PHP 7.0
與PHP 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'
我會非常米如果有人能夠解釋這裏發生的事情,請欣賞...
這可能是一個錯誤。 [處理的foreach](http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.foreach)肯定會改變,但我不明白這是如何造成這種情況。您可以向[PHP開發人員]提交一個錯誤(https://bugs.php.net),但在此之前,您可以從foreach中刪除'unset($ p);'(因爲它什麼都不做,除非這只是一個代碼的過度簡化版本)。 – pozs
謝謝@pozs。這確實是一個過於簡化的版本。如果沒有'unset($ p);''var_dump''數組看起來像這樣:'array(2){[0] => NULL [1] =>&string(37) 。但是,當然,僅在foreach循環(將被編輯)之後纔可以解除設置。 – iivarih