Problem mit logischen Operator

Problem mit logischen Operator

am 28.08.2006 14:15:28 von Michael Jostmeyer

Hi,

ich glaube, ich muss mein komplettes Wissen nochmal wegschmeissen und
neu lernen...

Habe folgende kleine Testseite "test.php"

if($_GET['k'] && $_GET['k'] != ''){
echo "Versuch 1: k={$_GET['k']}!
";
}
if($_GET['k'] & $_GET['k'] != ''){
echo "Versuch 2: k={$_GET['k']}!
";
}
?>


Aufgerufen wird Sie mit:
A) https://.../test.php?k=105313021544f2b2x654c8ff
und
B) https://.../test.php?k=1405449844f2c141068ea

Mit A wird "Versuch 1:.." sowie "Versuch 2:..." ausgegeben,
mit B leider nur "Versuch 1:..."...

Ich dachte, der einfache & Operator vergleich bitweise, also 1 & 1 = 1,
was ja eigentlich immer zutrifft, wenn k != '', ich habe hier ja
eigentlich auch keine weitere Abfrage des Wertes.

Was ich also nicht verstehe, was ist an k in B anders als in A?
Warum ist k in B leer?

Oder mach ich hier was prinzipielles falsch?

Gruss Josi

Re: Problem mit logischen Operator

am 28.08.2006 14:29:52 von Carsten Wiedmann

Michael Jostmeyer schrieb:

> > if($_GET['k'] && $_GET['k'] != ''){
> echo "Versuch 1: k={$_GET['k']}!
";
> }
> if($_GET['k'] & $_GET['k'] != ''){
> echo "Versuch 2: k={$_GET['k']}!
";
> }
> ?>
>
> Aufgerufen wird Sie mit:
> A) https://.../test.php?k=105313021544f2b2x654c8ff
> und
> B) https://.../test.php?k=1405449844f2c141068ea
>
> Was ich also nicht verstehe, was ist an k in B anders als in A?
> Warum ist k in B leer?

Auf was willst du denn hinaus? Ich würde das einfach so schreiben:
| | if(!empty($_GET['k'])){
| echo "Versuch 1: k={$_GET['k']}!
";
| }
| ?>

Gruß
Carsten

Re: Problem mit logischen Operator

am 28.08.2006 14:31:35 von Wolfgang Fellger

Michael Jostmeyer schrieb:

> if($_GET['k'] & $_GET['k'] != '')

!= hat Vorrang vor &, der Vergleich ergibt false, dieses wird zu 0 gewandelt,
x & 0 ergibt 0, also wieder false.

Was du damit bezwecken willst ist mir allerdings nicht klar.

--
Wolfgang Fellger

Re: Problem mit logischen Operator

am 28.08.2006 14:31:44 von Michael Jostmeyer

Carsten Wiedmann schrieb:
> Michael Jostmeyer schrieb:
>
>> >> if($_GET['k'] && $_GET['k'] != ''){
>> echo "Versuch 1: k={$_GET['k']}!
";
>> }
>> if($_GET['k'] & $_GET['k'] != ''){
>> echo "Versuch 2: k={$_GET['k']}!
";
>> }
>> ?>
>>
>> Aufgerufen wird Sie mit:
>> A) https://.../test.php?k=105313021544f2b2x654c8ff
>> und
>> B) https://.../test.php?k=1405449844f2c141068ea
>>
>> Was ich also nicht verstehe, was ist an k in B anders als in A?
>> Warum ist k in B leer?
>
> Auf was willst du denn hinaus? Ich würde das einfach so schreiben:
> | > | if(!empty($_GET['k'])){
> | echo "Versuch 1: k={$_GET['k']}!
";
> | }
> | ?>
>
> Gruß
> Carsten
>
Sicher, so kann ich das "Problem" umgehen, aber eine genaue Erklärung
über das Warum und Weshalb habe ich dann immer noch nicht.
Gruss Josi

Re: Problem mit logischen Operator

am 28.08.2006 14:35:21 von Michael Jostmeyer

Wolfgang Fellger schrieb:
> Michael Jostmeyer schrieb:
>
>> if($_GET['k'] & $_GET['k'] != '')
>
> != hat Vorrang vor &, der Vergleich ergibt false, dieses wird zu 0 gewandelt,
> x & 0 ergibt 0, also wieder false.
>
> Was du damit bezwecken willst ist mir allerdings nicht klar.
>
Wieso ergibt 105313021544f2b2x654c8ff != '' false?
Für mich ist die Variable k gefüllt, also k != '' => true...

Re: Problem mit logischen Operator

am 28.08.2006 14:49:43 von Wolfgang Fellger

Michael Jostmeyer schrieb:

>Wieso ergibt 105313021544f2b2x654c8ff != '' false?
>Für mich ist die Variable k gefüllt, also k != '' => true...

Ups, das hatte ich übersehen.

In dem Fall ist k true, was zu 1 umgewandelt wird.
Jetzt ist die Frage was PHP bei einem & zwischen Integer und String macht...
Ich vermute mal: Nach links wird mit 0 aufgefüllt, dann würde es den Ascii-Code
von 'f'==102 & 1 ermitteln. Das ergibt 0, weil 102 eine gerade Zahl ist.

Warum formulierst du dein Problem (was immer es auch sein mag) nicht so, dass
es nicht von irgendwelchen impliziten Wandlungen abhängt?

--
Wolfgang Fellger

Re: Problem mit logischen Operator

am 28.08.2006 15:00:07 von Michael Jostmeyer

Wolfgang Fellger schrieb:
> Michael Jostmeyer schrieb:
>
>> Wieso ergibt 105313021544f2b2x654c8ff != '' false?
>> Für mich ist die Variable k gefüllt, also k != '' => true...
>
> Ups, das hatte ich übersehen.
>
> In dem Fall ist k true, was zu 1 umgewandelt wird.
> Jetzt ist die Frage was PHP bei einem & zwischen Integer und String macht...
> Ich vermute mal: Nach links wird mit 0 aufgefüllt, dann würde es den Ascii-Code
> von 'f'==102 & 1 ermitteln. Das ergibt 0, weil 102 eine gerade Zahl ist.
Aber das ist doch immer noch keine Erklärung, warum
105313021544f2b2x654c8ff != ''
und
1405449844f2c141068ea != ''
unterschiedliche Ergebnisse liefern...
>
> Warum formulierst du dein Problem (was immer es auch sein mag) nicht so, dass
> es nicht von irgendwelchen impliziten Wandlungen abhängt?
>

Es geht mir hier nicht um eine Lösung des Problems, sondern nur um eine
Erklärung, insbesondere das Verhalten bei unterschiedlichen Werten,
welche ja beide != '' sind und auch beide Strings sind. Ausserdem ist ja
das Ergebnis des Vergleiches kein String sondern ein boolscher Wert.

Das Problem habe ich bereits umgangen, wie gesagt, ich suche nur eine
Erklärung, warum das Problem bestand.

Also eher theoretischer Natur...

Gruss Josi

Re: Problem mit logischen Operator

am 28.08.2006 15:10:20 von Wolfgang Fellger

Michael Jostmeyer schrieb:

>Aber das ist doch immer noch keine Erklärung, warum
>105313021544f2b2x654c8ff != ''
>und
>1405449844f2c141068ea != ''
>unterschiedliche Ergebnisse liefern...

Das Problem ist ja nicht das != . Das liefert in beiden Fällen true. Das
nachfolgenden & macht die Schwierigkeiten, da dann eben ein bitweise
Und-Verknüpfung zwischen dem String und dem Ergebnis des Vergleichs (==1)
durchgeführt wird.

x & 1 ergibt (nur dann) 1, wenn das letzte Bit von x gesetzt ist.
x && 1 hingegen ergibt true (==1), wenn x!=0 ist.

--
Wolfgang Fellger

Re: Problem mit logischen Operator

am 28.08.2006 15:15:28 von Michael Jostmeyer

Wolfgang Fellger schrieb:
> Michael Jostmeyer schrieb:
>
>> Aber das ist doch immer noch keine Erklärung, warum
>> 105313021544f2b2x654c8ff != ''
>> und
>> 1405449844f2c141068ea != ''
>> unterschiedliche Ergebnisse liefern...
>
> Das Problem ist ja nicht das != . Das liefert in beiden Fällen true. Das
> nachfolgenden & macht die Schwierigkeiten, da dann eben ein bitweise
> Und-Verknüpfung zwischen dem String und dem Ergebnis des Vergleichs (==1)
> durchgeführt wird.
>
> x & 1 ergibt (nur dann) 1, wenn das letzte Bit von x gesetzt ist.
> x && 1 hingegen ergibt true (==1), wenn x!=0 ist.
>
ok, soweit so gut. aber x ist ja hier in beiden Fällen $_GET['k']...
aaaah, ok, es wird hier ja nicht true oder false, sondern der wert
selber zurückgegeben... korrekterweise müsste hier also noch ein
isset($_GET['k'] davor....

ok, hätte ich auch selber draufkommen müssen, war halt mal wieder
"betriebsblind"...

Sorry...

Gruss Josi

Re: Problem mit logischen Operator

am 28.08.2006 15:22:33 von Niels Braczek

Michael Jostmeyer schrieb:

> Was ich also nicht verstehe, was ist an k in B anders als in A?
> Warum ist k in B leer?

Das letzte Bit. Nur dieses ist relevant, weil du eine bitweise
Verknüpfung mit true =3D> 1 =3D> 0000 0001 (bin) machst.

> Oder mach ich hier was prinzipielles falsch?

Ja. && erzwingt die Typwandlung in boolean, & nicht.
Hingegen können zwei Werte, die für sich zu true evaluieren würden,=
bei
der Verknüpfung mit & einen Wert ergeben, der zu false evaluiert:

1 & 2 =3D> 0000 0001 & 0000 0010 =3D> 0000 0000 =3D> 0 =3D> false
1 && 2 =3D> true && true =3D> true

MfG
Niels

--=20
| http://www.kolleg.de =B7 Das Portal der Kollegs in Deutschland |
| http://www.bsds.de =B7 BSDS Braczek Software- und DatenSysteme |
| Webdesign =B7 Webhosting =B7 e-Commerce =B7 Joomla! Content Management =
|
------------------------------------------------------------ ------

Re: Problem mit logischen Operator

am 28.08.2006 15:24:35 von Niels Braczek

Michael Jostmeyer schrieb:

> aaaah, ok, es wird hier ja nicht true oder false, sondern der wert
> selber zurückgegeben... korrekterweise müsste hier also noch ein
> isset($_GET['k'] davor....
>=20
> ok, hätte ich auch selber draufkommen müssen, war halt mal wieder
> "betriebsblind"...

Das ist der Grund, warum das prüft, was man prüfen will, und nicht
etwas, von dem man glaubt, dass es so ähnlich evaluiert.
Der korrekte Test in deinem Falle wäre

if ( !empty( $_GET[$k] ) ) {

MfG
Niels

--=20
| http://www.kolleg.de =B7 Das Portal der Kollegs in Deutschland |
| http://www.bsds.de =B7 BSDS Braczek Software- und DatenSysteme |
| Webdesign =B7 Webhosting =B7 e-Commerce =B7 Joomla! Content Management =
|
------------------------------------------------------------ ------

Re: Problem mit logischen Operator

am 28.08.2006 15:27:04 von Sven Drieling

Michael Jostmeyer wrote:

Hallo,

> > if($_GET['k'] && $_GET['k'] !=3D ''){
> echo "Versuch 1: k=3D{$_GET['k']}!
";
> }
> if($_GET['k'] & $_GET['k'] !=3D ''){
> echo "Versuch 2: k=3D{$_GET['k']}!
";
> }

> Ich dachte, der einfache & Operator vergleich bitweise,

&& und & vergleichen nicht, sondern verknüpfen. Bei && werden zwei
Boolean Werte miteinander per Und verknüpft. Deshalb ist es der
Operator, den man in if-Abfragen wie der obigen verwenden soll.

Bei & werden die einzelnen Bits zweier Integer-Zahlen miteinander
per Und verknüpft. Dazu werden die Werte zunächst einmal in
Integer-Zahlen umgewandelt. Aus $_GET['k'] !=3D '' wird 1
als Integer wo nur das 1. Bit gesetzt ist. Wenn nun aus dem anderen
$_GET['k'] eine Zahl wird in der nicht das 1. Bit gesetzt ist
ergibt das bitweise & immer 0 als Integer und damit fürs if ein
Boolean false.

Mal mit k=3D0, k=3D1, k=3D2 usw. aufrufen und sich das als Integer-Zahl=
en
mit den jeweils gesetzten Bits umdenken.

echo $_GET['k'] & $_GET['k'] !=3D '';


tschuess
[|8:)

Re: Problem mit logischen Operator

am 28.08.2006 16:02:15 von Michael Jostmeyer

Niels Braczek schrieb:
> Michael Jostmeyer schrieb:
>
>> aaaah, ok, es wird hier ja nicht true oder false, sondern der wert
>> selber zurückgegeben... korrekterweise müsste hier also noch ein
>> isset($_GET['k'] davor....
>>
>> ok, hätte ich auch selber draufkommen müssen, war halt mal wieder
>> "betriebsblind"...
>
> Das ist der Grund, warum das prüft, was man prüfen will, und nicht
> etwas, von dem man glaubt, dass es so ähnlich evaluiert.
> Der korrekte Test in deinem Falle wäre
>
> if ( !empty( $_GET[$k] ) ) {
>
> MfG
> Niels
>
Was ich auch schon lange gemacht hatte.
Wie gesagt, mir ging es nur um die Logik in dem Fall.
Ich hatte halt in diesem Fall $_GET['k'] verwendet, um festzustellen, ob
die Variable gesetzt ist, aber nicht beachtet, das dort ja der Wert
selber und nicht true oder false zurückgegeben wird.
Asche auf mein haupt...

Gruss Josi

Re: Problem mit logischen Operator

am 28.08.2006 16:06:24 von Michael Jostmeyer

Sven Drieling schrieb:
> Michael Jostmeyer wrote:
>
> Hallo,
>
>> >> if($_GET['k'] && $_GET['k'] != ''){
>> echo "Versuch 1: k={$_GET['k']}!
";
>> }
>> if($_GET['k'] & $_GET['k'] != ''){
>> echo "Versuch 2: k={$_GET['k']}!
";
>> }
>
>> Ich dachte, der einfache & Operator vergleich bitweise,
>
> && und & vergleichen nicht, sondern verknüpfen. Bei && werden zwei
> Boolean Werte miteinander per Und verknüpft. Deshalb ist es der
> Operator, den man in if-Abfragen wie der obigen verwenden soll.
>
> Bei & werden die einzelnen Bits zweier Integer-Zahlen miteinander
> per Und verknüpft. Dazu werden die Werte zunächst einmal in
> Integer-Zahlen umgewandelt. Aus $_GET['k'] != '' wird 1
> als Integer wo nur das 1. Bit gesetzt ist. Wenn nun aus dem anderen
> $_GET['k'] eine Zahl wird in der nicht das 1. Bit gesetzt ist
> ergibt das bitweise & immer 0 als Integer und damit fürs if ein
> Boolean false.
>
> Mal mit k=0, k=1, k=2 usw. aufrufen und sich das als Integer-Zahlen
> mit den jeweils gesetzten Bits umdenken.
>
> echo $_GET['k'] & $_GET['k'] != '';
>
>
> tschuess
> [|8:)
danke für die ausführliche antwort. die funktionsweise beider
verknüpfungen waren mir bekannt, nur leider habe ich die wirkung von
$_GET nicht berücksichtigt. (Gibt Wert statt Boolean zurück)
Hatte also die ganze Zeit etwas wie
if(isset($_GET['k']) & $_GET['k'] != '')
im Hinterkopf, was ja falsch war.

Gruss Josi