Problem mit NULL
L(in)uchs
- php
Hallo,
irgendwie stehe ich auf dem Schlauch.
In einem Tabellenfeld habe ich den Wert NULL (mit phpMyAdmin geprüft). Ich lese den Datensatz mit SELECT ein und frage dieses Feld ab:
if (is_null($row_trm['geo_breite'])) echo "[".$row_trm['geo_breite']."] is null"; else echo "[".$row_trm['geo_breite']."] is NOT null";
Anzeige:
[] is NOT null
Wird beim Einlesen aus NULL der Wert "" (leerer String, ist wohl was anderes als NULL)? Oder was mache ich falsch?
Gruß, L(in)uchs
Soweit ich weiß ist alles was du aus der Datenbank holst ein String. Auch zahlen sind streng genommen Strings. Nur ist da PHP nicht ganz so streng und behandelt "String-Integer" als normale Integer.
Deshalb läuft deine Prüfung ins leere.
Gruß
halb voller
T-Rex
Soweit ich weiß ist alles was du aus der Datenbank holst ein String.
Gut, aber woher weiss dann phpMyAdmin, dass das Feld den Wert NULL hat? phpMyAdmin ist doch auch mit PHP programmiert.
Also muss man mit PHP doch NULL und leeren String unterscheiden können. Wie geht das?
Gruß
(noch leerer) L(in)uchs
Hi,
Wird beim Einlesen aus NULL der Wert "" (leerer String, ist wohl was anderes als NULL)? Oder was mache ich falsch?
Welche Funktion verwendest du denn zum fetchen der Datensätze?
MfG ChrisB
Welche Funktion verwendest du denn zum fetchen der Datensätze?
mysql_fetch_array()
Hallo,
Welche Funktion verwendest du denn zum fetchen der Datensätze?
mysql_fetch_array()
damit ist das Verhalten nicht nachvollziehbar, siehe Hinweis im Handbuch bei den Anmerkungen.
Und ja: eine leere Zeichenkette ist was völlig anderes als der spezielle Wert NULL.
Freundliche Grüße
Vinzenz
Hello,
irgendwie stehe ich auf dem Schlauch.
In einem Tabellenfeld habe ich den Wert NULL (mit phpMyAdmin geprüft). Ich lese den Datensatz mit SELECT ein und frage dieses Feld ab:
if (is_null($row_trm['geo_breite'])) echo "[".$row_trm['geo_breite']."] is null"; else echo "[".$row_trm['geo_breite']."] is NOT null";
Das klappt mMn so nicht.
Entweder einen Doppelpunkt hinter der Bedingungsklammer, oder aber Blockklammern setzen.
Ich bin daher immer für die explizite Schreibweise. Die dauert in der Ausführung auch nicht länger, aber man kann sie viel schneller lesen.
if (is\_null($row\_trm['geo\_breite']))
{
echo "[" . $row\_trm['geo\_breite'] . "] is null" ;
}
else
{
echo "[".$row\_trm['geo\_breite']."] is NOT null";
}
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
![](http://selfhtml.bitworks.de/Virencheck.gif)
--
☻\_
/▌
/ \ Nur selber lernen macht schlau
<http://bergpost.annerschbarrich.de>
Hi,
if (is_null($row_trm['geo_breite'])) echo "[".$row_trm['geo_breite']."] is null"; else echo "[".$row_trm['geo_breite']."] is NOT null";
Das klappt mMn so nicht.
Entweder einen Doppelpunkt hinter der Bedingungsklammer, oder aber Blockklammern setzen.
warum das? Okay, es ist im Interesse der Lesbarkeit und Wartbarkeit zu empfehlen. Aber solange der Anweisungsblock nur aus einer einzigen Anweisung besteht, darf man vom syntaktischen Standpunkt her die geschweiften Klammern auch weglassen.
So long,
Martin
Hello,
if (is_null($row_trm['geo_breite'])) echo "[".$row_trm['geo_breite']."] is null"; else echo "[".$row_trm['geo_breite']."] is NOT null";
Das klappt mMn so nicht.
Entweder einen Doppelpunkt hinter der Bedingungsklammer, oder aber Blockklammern setzen.warum das? Okay, es ist im Interesse der Lesbarkeit und Wartbarkeit zu empfehlen. Aber solange der Anweisungsblock nur aus einer einzigen Anweisung besteht, darf man vom syntaktischen Standpunkt her die geschweiften Klammern auch weglassen.
Das ist mir klar. Ich habe mich auch geirrt.
Ich hatte die Schreibweise anders im Gedächtnis, ohne ein Semikolon hinter dem If-Zweig, wenn man die Klammern weglässt. Aber das war wohl bei einer anderen Programmiersprache so :-O
Und wenn man diese Anweisung "trocken" ausprobiert, funktioniert sie auch.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallöchen,
Ich hatte die Schreibweise anders im Gedächtnis, ohne ein Semikolon hinter dem If-Zweig, wenn man die Klammern weglässt. Aber das war wohl bei einer anderen Programmiersprache so :-O
ja, vielleicht Pascal und davon abgeleitete Sprachen. Da ist es zumindest unüblich (wenn auch nicht verboten), vor einem "end" oder "else" noch ein Semikolon zu setzen.
Ciao,
Martin
hi,
[] is NOT null
NULL würde heißen: Der Wert ist gesetzt. Aber: Dein Wert ist eben nicht gesetzt, isset() ist Dein Freund ;)
Hotti
PS: In Perl würdest Du ein undef bekommen, wenn DB-Felder NULL sind.
Hallo,
NULL würde heißen: Der Wert ist gesetzt. Aber: Dein Wert ist eben nicht gesetzt, isset() ist Dein Freund ;)
nein, der Code von L(in)uchs ist völlig in Ordnung (außer nicht besonders lesbar) und das vom OP beschriebene Verhalten läßt sich nicht nachvollziehen.
Bedenke, dass der OP die Funktion is_null() verwendet, deren Einsatz hier völlig angemessen ist. Er weiß ja, dass es diese Spalte und damit diesen Arrayeintrag gibt.
Beispielcode für einen XAMPP (out-of-the-box, ungesichert):
# Ich gehe Kontextproblemen aus dem Weg
header("Content-type: text/plain");
# Verbindungsaufbau zu einem ungesicherten XAMPP :-)
$conn = mysql_connect('localhost', 'root', '');
# Die Fehlerbehandlung lasse ich der Einfachheit halber weg ...
# Mir reicht ein Datensatz mit einer Spalte, die einen NULL-Wert enthält
$query = 'SELECT NULL AS spalte1, 3 AS spalte2';
$result = mysql_query($query);
if ($row = mysql_fetch_array($result)) {
# Erste Debugausgabe
var_dump($row);
print "\n\n";
# Schauen wir, was aus L(in)uchs' Code resultiert
if ([link:http://de.php.net/manual/de/function.is-null.php@title=is_null]($row['spalte1'])) {
print "Spalte1 IS NULL\n";
}
else {
print "is_null konnte nicht feststellen, dass da ein NULL-Wert steht.\n";
}
}
#------------------------------------------------
Ausgabe
array(4) {
[0]=>
NULL
["spalte1"]=>
NULL
[1]=>
string(1) "3"
["spalte2"]=>
string(1) "3"
}
Spalte1 IS NULL
#------------------------------------------------
Und somit das gewünschte Ergebnis.
Ja, ich habe es auch mit der unübersichtlichen "Kurzschreibweise" mit gleichem Ergebnis getestet:
if (is_null($row['spalte1'])) echo "Spalte1 IS NULL\n"; else echo "is_null konnte nicht feststellen, dass da ein NULL-Wert steht.\n";
Freundliche Grüße
Vinzenz
hi,
nein, der Code von L(in)uchs ist völlig in Ordnung (außer nicht besonders lesbar) und das vom OP beschriebene Verhalten läßt sich nicht nachvollziehen.
Stimmt: Nicht nachvollziehbar. Hab jetzt nochmal mysqli/mysql verglichen, Spalte text ist in MySQL NULL:
mysql> select * from test where id=677;
+-----+------+---------------------+
| id | text | datum |
+-----+------+---------------------+
| 677 | NULL | 2012-07-23 19:07:32 |
+-----+------+---------------------+
1 row in set (0.00 sec)
mysql> select version();
+------------------+
| version() |
+------------------+
| 5.1.40-community |
+------------------+
1 row in set (0.02 sec)
include 'mysqli.php';
class xperlbase extends Manager_MyBase{
function browse(){
$res = $this->DBH->query("SELECT * FROM test WHERE id = 677");
$r = mysqli_fetch_object($res);
if(!isset($r->text)) print "Not Set\n";
if(is_null($r->text)) print "Is NULL\n";
}
}
$mb = new xperlbase;
$mb->browse();
$conn = mysql_connect('localhost') or die(123);
mysql_select_db('myweb') or die(234);;
$res = mysql_query("SELECT * FROM test WHERE id = 677", $conn);
$r = mysql_fetch_object($res);
if(!isset($r->text)) print "Not Set\n";
if(is_null($r->text)) print "Is NULL\n";
print_r($r);
Not Set
Is NULL
Not Set
Is NULL
stdClass Object
(
[id] => 677
[text] =>
[datum] => 2012-07-23 19:07:32
)
Version PHP
PHP 5.3.0 (cli) (built: Jun 29 2009 21:25:23)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies
Hotti
Tach!
if(!isset($r->text)) print "Not Set\n";
if(is_null($r->text)) print "Is NULL\n";
isset() funktioniert "nicht richtig", denn es liefert auch bei vorhandener Variable/Array-Element/Objekteigenschaft ein false, wenn deren Inhalt null ist. Insofern ist es nur zum Testen auf Nicht-Null-Werte geeignet. Dass es so arbeitet ist der Laxheit geschuldet, mit der einge PHP-Anwender ihren Code schreiben.
$foo = $_POST['foo'];
vardump(isset($foo));
Abgesehen vom Unsinn des Umkopierens und der Tatsache, dass $foo nun definiv existiert (var_dump($GLOBALS);), egal ob $_POST['foo'] existierte oder nicht, liefert das isset() ein false, wenn durch die Nichtexistenz von $_POST['foo'] ein null in $foo zu stehen kommt.
Dass isset() nun doch wie vorgesehen arbeitet, liegt daran, dass man die Beschreibung durch einen Zusatz an die Funktionsweise angepasst hat: Determine if a variable is set and is not NULL.
isset() ist also eine ungeeignete Testmethode für Variablen, die null enthalten können, wenn man auf ihre Existenz prüfen will.
print_r($r);
print_r() eignet sich nicht zum Nachvollziehen von Inhalten wie null, false und Leerstring oder auch true und 1. Für alle drei gibt es einen Leerstring und die anderen beiden eine 1 aus. Eindeutig ist hingegen die Ausgabe von var_dump().
dedlfix.
Hello,
isset() ist also eine ungeeignete Testmethode für Variablen, die null enthalten können, wenn man auf ihre Existenz prüfen will.
Wie würdest Du denn auf die Existenz einer Variablen testen, die Null enthalten kann?
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Tach!
Wie würdest Du denn auf die Existenz einer Variablen testen, die Null enthalten kann?
isset() liefert false, egal ob sie tatsächlich existiert oder nicht. is_null() antwortet genau entgegengesetzt und wirft zusätzlich eine Notice bei Nichtvorhandensein. Selbst mit einem @ davor ist is_null() allein unbrauchbar. isset() und is_null() zu kombinieren bringt nichts.
is_null() und Testen auf eine Fehlermeldung ist unpraktisch, weil die Aussage von error_get_last() nicht auf eine bestimmte Anweisung zurückgeführt werden kann. $php_errormsg kann man zwar löschen und anschließend auf Inhalt prüfen.
ini_set('track_errors', 1);
$php_errormsg = null; var_dump(@is_null($x) and !$php_errormsg);
Doch das kann man nicht in eine Funktion auslagern, weil beim Übergeben von nicht vorhandenen $x entweder eine Notice geworfen wird oder bei Übergabe als Referenz die Variable mit Inhalt null angelegt wird.
Bleibt am Ende wohl nur dieses Konstrukt:
var_dump(array_key_exists('x', get_defined_vars()) and is_null($x));
Das schaut in der aktuellen Variablenliste für den aktuellen Scope nach dem Vorhandensein des Namens der Variable und erst dann erfolgt der Test auf null. $GLOBALS statt get_defined_vars() schränkt auf den globalen Scope ein, ist also unbrauchbar. Zudem müssen andere Lösungen für Array-Elemente und Objekt-Eigenschaften gefunden werden, wenn man das braucht.
Apropos "braucht". Man braucht sowas eigentlich nicht. Nicht vorhandene Array-Elemente können nur in $_GET/$_POST/etc. vorkommen, und da ist null kein von PHP gesetzter Wert. Ansonsten hat man doch die Kontrolle über seine Variablen, oder man macht was falsch. (Zum Fehlersuchen bekommt man mit E_ALL und var_dump() eindeutige Aussagen.)
dedlfix.
Hello,
Apropos "braucht". Man braucht sowas eigentlich nicht. Nicht vorhandene Array-Elemente können nur in $_GET/$_POST/etc. vorkommen, und da ist null kein von PHP gesetzter Wert. Ansonsten hat man doch die Kontrolle über seine Variablen, oder man macht was falsch. (Zum Fehlersuchen bekommt man mit E_ALL und var_dump() eindeutige Aussagen.)
Das habe ich auch erst gedacht. Aber das Problem existiert z.B. in ähnlicher Form auch bei fgetcsv().
Im Prinzip soll NULL allerdings auch bedeuten "den Wert gibt es nicht".
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Tach!
Aber das Problem existiert z.B. in ähnlicher Form auch bei fgetcsv().
Im Prinzip soll NULL allerdings auch bedeuten "den Wert gibt es nicht".
Du meinst, var_dump(str_getcsv("")); liefert ein Array mit einem null-Eintrag? Nun, dann hat das Array ja ein Element, das dir mit count(...), oder array_key_exists('0', ...) oder auch beim foreach als ein Schleifendurchlauf signalisiert wird.
dedlfix.