2016-04-15 2 views
0

Ich bin ein Projekt PHP 5.6-PHP 7.0 und mit PHP 7.0 Aktualisierung gestartet Datenbankfehler immer von postgresql (Version 9.5, wenn das einen Unterschied macht) dass die eingefügten Daten eine Constraint-Prüfung verletzen. Führen Sie den gleichen Code erneut mit PHP 5.6 und es gab keine Verletzung. Alle Überprüfungen entfernt, um zu sehen, was die Parameter tatsächlich waren und es schien, dass dort leere Zeichenfolgen waren, in denen NULL Werte erwartet wurden. Ich fand ein paar alte und feste PHP Bugs, wo pg_query() und pg_query_params() konvertiert NULL Werte zu leeren Strings, aber das ist anders. NULL wird nur in eine leere Zeichenfolge konvertiert, wenn das Array params mit einer Referenz durchlaufen wurde.PHP 7.0 pg_query_params(): null zu leeren String umgewandelt wird, aber erst, nachdem mit einer Referenz Looping

Code demonstriert das Problem:

$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>"; 

Ausgang:

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 log:

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' 

Ich würde sehr m Ich schätze, wenn jemand erklären könnte, was hier passiert ...

+0

Dies kann ein Fehler sein. [Handhabung von foreach] (http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.foreach) ist sicherlich geändert, aber ich kann nicht sehen, wie das dazu führen könnte. Du kannst [einen Bug an PHP Entwickler senden] (https://bugs.php.net), aber bis dahin könntest du 'unset ($ p);' von der foreach entfernen (wie es nichts tut, außer es ist nur ein übermäßig vereinfachte Version des Codes). – pozs

+0

danke @ pozs. Dies ist in der Tat eine übermäßig vereinfachte Version. Ohne 'unset ($ p);' 'var_dump' sieht das Array so aus:' array (2) {[0] => NULL [1] => & string (37) "nach dem Schleifen mit einer Referenz einfügen"} ' . Aber natürlich ist es genug, erst nach der foreach-Schleife zu löschen (wird bearbeitet). – iivarih

Antwort

Verwandte Themen