Kortere if mogelijk?
Maar goed, mijn punt is dan ook niet dat het in het alledaagse gebruik veel voor zal komen, sterker nog het zal in de meeste gevallen gewoon goed gaan. Alleen in dat ene geval waar de code wel iets anders doet dan je verwacht, is het een stuk lastiger debuggen. Je verwacht dat AND hetzelfde doet als &&, maar dat is dus niet in alle gevallen zo.
PHP en de MySQL() functies zijn helaas wat slordig van aard. In de andere SQL talen waarmee ik werk is het ondenkbaar dat je OF een dataset OF een false terugkrijgt. Een dataset en een boolean zijn gebruikelijk twee verschillende objecten.
Gewijzigd op 01/01/1970 01:00:00 door John D
Blanche schreef op 10.01.2010 14:17:
Je hebt geen gelijk. Ik heb de volgende code uitgevoerd:Natuurlijk is ook dit een kwestie van smaak en gebruik van methoden waaraan je gewend bent. Alleen bij het gebruik van AND en OR zul je er dan dus wel voor moeten zorgen dat je bedacht bent op de 'functionaliteit' die ik in mijn vorige post al aangaf. Het werkt niet altijd zoals je zou verwachten!
Ik houd het voorlopig gewoon bij || en && :-)
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
if($res = mysql_query($sql) && $continue) {
// Wordt uitgevoerd als query gelukt is en $continue TRUE is
}
if($res = mysql_query($sql) AND $continue) {
// Wordt uitgevoerd als query gelukt is, ongeacht de waarde van $continue!
}
?>
if($res = mysql_query($sql) && $continue) {
// Wordt uitgevoerd als query gelukt is en $continue TRUE is
}
if($res = mysql_query($sql) AND $continue) {
// Wordt uitgevoerd als query gelukt is, ongeacht de waarde van $continue!
}
?>
Ik houd het voorlopig gewoon bij || en && :-)
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php
/*
* Connectie openen en de resource opslaan als $rConnectie
*/
$connectie = mysql_connect ( 'host' , 'buser' , 'pass' );
/*
* Als de connectie gelukt is of als er geen database geselecteerd kan worden
* de meegegeven error geven.
*/
if ( !$connectie OR !mysql_select_db ( 'db' , $connectie ) )
die ( 'Fout.' );
/*
* Voor testdoeleinden zetten we $continue op false.
*/
$continue = false;
/*
* We maken een simpele SQL die niet fout gaat.
*/
$sql = "
SELECT id
FROM gebruikers
";
/*
* We voeren de SQL uit en vragen de variabele $continue erbij met &&
*/
if ( $res = mysql_query ( $sql ) && $continue )
{
/*
* Volgens Blanche:
* Wordt uitgevoerd als query gelukt is en $continue TRUE is.
* Als we hier uitkomen gebeurt er iets geks.
*/
echo 'Blanche heeft geen gelijk met &&.';
}
else
{
/*
* Het zal dus hier uitkomen omdat $continue false is.
*/
echo 'Blanche heeft gelijk met &&.';
}
/*
* Voor de zekerheid de waarde van $res erbij.
*/
echo '<pre>';
var_dump ( $res );
echo '</pre>';
echo '<br />';
/*
* We voeren de SQL nogmaals uit en vragen de variabele $continue erbij met AND
*/
if ( $res = mysql_query ( $sql ) AND $continue )
{
/*
* Volgens Blanche:
* Wordt uitgevoerd als query gelukt is, ongeacht de waarde van $continue!
*/
echo 'Blanche heeft gelijk. We komen door de if ondanks dat $continue een
voorwaarde is die met AND aan de mysq_query() voorwaarde is gekoppeld..';
}
else
{
echo 'Blanche heeft geen gelijk. Mysql_query() geeft true en $continue is
false. Toch komen we hier.';
}
/*
* Voor de zekerheid de waarde van $res erbij.
*/
echo '<pre>';
var_dump ( $res );
echo '</pre>';
?>
/*
* Connectie openen en de resource opslaan als $rConnectie
*/
$connectie = mysql_connect ( 'host' , 'buser' , 'pass' );
/*
* Als de connectie gelukt is of als er geen database geselecteerd kan worden
* de meegegeven error geven.
*/
if ( !$connectie OR !mysql_select_db ( 'db' , $connectie ) )
die ( 'Fout.' );
/*
* Voor testdoeleinden zetten we $continue op false.
*/
$continue = false;
/*
* We maken een simpele SQL die niet fout gaat.
*/
$sql = "
SELECT id
FROM gebruikers
";
/*
* We voeren de SQL uit en vragen de variabele $continue erbij met &&
*/
if ( $res = mysql_query ( $sql ) && $continue )
{
/*
* Volgens Blanche:
* Wordt uitgevoerd als query gelukt is en $continue TRUE is.
* Als we hier uitkomen gebeurt er iets geks.
*/
echo 'Blanche heeft geen gelijk met &&.';
}
else
{
/*
* Het zal dus hier uitkomen omdat $continue false is.
*/
echo 'Blanche heeft gelijk met &&.';
}
/*
* Voor de zekerheid de waarde van $res erbij.
*/
echo '<pre>';
var_dump ( $res );
echo '</pre>';
echo '<br />';
/*
* We voeren de SQL nogmaals uit en vragen de variabele $continue erbij met AND
*/
if ( $res = mysql_query ( $sql ) AND $continue )
{
/*
* Volgens Blanche:
* Wordt uitgevoerd als query gelukt is, ongeacht de waarde van $continue!
*/
echo 'Blanche heeft gelijk. We komen door de if ondanks dat $continue een
voorwaarde is die met AND aan de mysq_query() voorwaarde is gekoppeld..';
}
else
{
echo 'Blanche heeft geen gelijk. Mysql_query() geeft true en $continue is
false. Toch komen we hier.';
}
/*
* Voor de zekerheid de waarde van $res erbij.
*/
echo '<pre>';
var_dump ( $res );
echo '</pre>';
?>
Quote:
Blanche heeft gelijk met &&.
bool(false)
Blanche heeft geen gelijk. Mysql_query() geeft true en $continue is false. Toch komen we hier.
resource(4) of type (mysql result)
bool(false)
Blanche heeft geen gelijk. Mysql_query() geeft true en $continue is false. Toch komen we hier.
resource(4) of type (mysql result)
Gewijzigd op 01/01/1970 01:00:00 door K i p
Als je een resultaatset in $res terugkrijgt mag je die niet aftesten als boolean. Ga dus terug naar de tekentafel en try-trail-on-error again ;-)
John schreef op 10.01.2010 14:01:
Ik heb niet gezegd dat je het "door elkaar" moet gebruiken en ik raad dat zelfs altijd af!! Dat werkt juist optimaal verwarrend. Je probeert je gelijk te halen op verkeerde argumenten. Ik heb gesteld dat de leesbaarheid beter is wanneer je afstapt van het cryptische gedoe van || && en AND en OR gebruikt. Niet meer en niet minder.
Nee, je hebt gezegd dat de precedence gelijk is:
John schreef op 10.01.2010 13:53:
Ooievaar: je stelling is onjuist. De precedence is gelijk:
http://www.php.net/manual/en/language.operators.precedence.php
http://www.php.net/manual/en/language.operators.precedence.php
Later heb je dit erbij ge-edit:
John schreef op 10.01.2010 13:53:
Left associativity means that the expression is evaluated from left to right, right associativity means the opposite.
Daar staat duidelijk associativity en geen precedence. Dan heb je het tegen mij dat ik mijn gelijk probeer te halen op verkeerde argumeten, terwijl jij dingen door elkaar gaat halen. Ik heb steeds voet bij stuk gehouden. De precedence is belangrijk (kom ik later nog op terug).
Ik heb het niet tegen jou gehad over de leesbaarheid (kom ik later nog op terug), alleen maar dat jij geen gelijk had over dat de precedence gelijk is. Dit is dus gewoon een drogreden van jou, je probeert onder je fout uit te komen door de boel te verdraaien.
Blanche schreef op 10.01.2010 14:03:
@Ooievaar: dat is alleen van belang in de IMO onlogische situatie dat je && en AND door elkaar gebruikt. Waarom zou je dat willen doen?
Je hebt echter wel gelijk en dat geeft mij bovendien nog een extra reden om AND en OR af te raden. Die operators doen niet wat je zou verwachten, zie dit voorbeeld van php.net:
Waar je dus zou verwachten dat $h het resultaat van de expressie 'true and false' (dus false) bevat, krijgt $h de waarde true. Als je daar niet op bedacht bent, wordt het leuk debuggen!
Je hebt echter wel gelijk en dat geeft mij bovendien nog een extra reden om AND en OR af te raden. Die operators doen niet wat je zou verwachten, zie dit voorbeeld van php.net:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
// The result of the expression (true && false) is assigned to $g
// Acts like: ($g = (true && false))
$g = true && false;
// The constant true is assigned to $h and then false is ignored
// Acts like: (($h = true) and false)
$h = true and false;
?>
// The result of the expression (true && false) is assigned to $g
// Acts like: ($g = (true && false))
$g = true && false;
// The constant true is assigned to $h and then false is ignored
// Acts like: (($h = true) and false)
$h = true and false;
?>
Waar je dus zou verwachten dat $h het resultaat van de expressie 'true and false' (dus false) bevat, krijgt $h de waarde true. Als je daar niet op bedacht bent, wordt het leuk debuggen!
Waarom schrijf je bij wiskunde sin2x en niet sin(x)^2 ja, omdat je dat haakjes scheelt. Omdat het gewoon duidelijk is wat je bedoelt. Het zelfde geldt voor 5*2+4/2, hierbij doe je ook geen haakjes. Iedereen die de volgorde kent weet hoe het zit.
Met php is dit hetzelfde. Iedereen heeft wel meneer van dale wacht op antwoord geleerdt (is overigs niet juist, lees dat hier).
Verder doen die operators gewoon wat je van ze verwacht, als je naar de precedence lijst kijkt zie je dus dat = een hogere precedence heeft dan AND. Dat betekend dus dat wat er in jou voorbeeld gebeurd gewoon correct is. Zoals verwacht wordt er bij AND true aan $h toegeschreven.
Blanche schreef op 10.01.2010 14:17:
Natuurlijk is ook dit een kwestie van smaak en gebruik van methoden waaraan je gewend bent. Alleen bij het gebruik van AND en OR zul je er dan dus wel voor moeten zorgen dat je bedacht bent op de 'functionaliteit' die ik in mijn vorige post al aangaf. Het werkt niet altijd zoals je zou verwachten!
Ik houd het voorlopig gewoon bij || en && :-)
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
if($res = mysql_query($sql) && $continue) {
// Wordt uitgevoerd als query gelukt is en $continue TRUE is
}
if($res = mysql_query($sql) AND $continue) {
// Wordt uitgevoerd als query gelukt is, ongeacht de waarde van $continue!
}
?>
if($res = mysql_query($sql) && $continue) {
// Wordt uitgevoerd als query gelukt is en $continue TRUE is
}
if($res = mysql_query($sql) AND $continue) {
// Wordt uitgevoerd als query gelukt is, ongeacht de waarde van $continue!
}
?>
Ik houd het voorlopig gewoon bij || en && :-)
Probeer het volgende voorbeeld (met dank aan Maarten) eens:
Code (php)
Er worden nu geen haakjes gebruikt, maar wel de 'veilige' && en ||. Als je dit nu uitvoert dan krijg je:
Code (php)
1
Notice: Undefined index: a in C:\xampp\htdocs\test\eval.php(5) : eval()'d code on line 8
De foutmelding komt dus voor de tweede if.
Bij de eerste if krijg je geen notice, je kunt die uitschrijven naar (zie dus ook operators.precedence):
Als a false is zal php nooit beginnen aan het tweede gedeelte, want dat maakt niet uit of die nou true of false is. De uitkomst blijft dan gewoon false. Zie ook deze waarheidstabel.
De tweede if kan je omschrijven naar dit:
Nu hebben ze allemaal dezelfde voorrang (net als bij keer en delen), dus wordt deze vergelijking van links naar rechts opgelost.
De evaluatie van de verschillende statements is hier wel duidelijk te zien:
Code (php)
Zet je de laatste in een if-statement, dat evalueert hij wel weer naar FALSE. En als je daar even langer over nadenkt, is het logisch: de haakjes zorgen dat het statement wel goed uitgevoerd wordt.
Gewijzigd op 01/01/1970 01:00:00 door Joren de Wit
http://www.php.net/manual/en/language.operators.precedence.php op zich al verwarrend omdat er teveel type operators in staan. Dit druist eigenlijk in tegen de regels van het programmeren. Er zou per type een lijstje moeten staan toch ?
Ik vrees toch dat er onderweg in de code en de conclusies sprake is van appelen met peren vergelijken. Mag je een comparison operator qua orde in een lijstje interpreteren en een hogere orde (precedence) geven dan een boolean operator of niet of omgekeerd ? Naar mijn mening is het lijstje Vrij normaal tabelletje is dit, zo ziet het er in andere talen ook ongeveer uit:
http://www.difranco.net/cop2220/op-prec.htm
http://www.cppreference.com/wiki/operator_precedence
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/operators.html
http://msdn.microsoft.com/en-us/library/ms190276.aspx
http://msdn.microsoft.com/en-us/library/aa691323(VS.71).aspx
http://www.codehouse.com/javascript/precedence/
@Blanche: Erg jammer en slecht dat jij dit niet eens weet, het staat zelfs in de meeste beginnersboeken (zoals Easy computing gids PHP 5, wat niet echt een geweldig goed boek is).