The ternary conditional operator is a useful way of avoiding
http://phpsourcecode.blogspot.com
inconvenient if statements. They can even be used in the middle of a string concatenation, if you use parentheses.
Example:
if ( $wakka ) {
$string = 'foo' ;
} else {
$string = 'bar' ;
}
The above can be expressed like the following:
$string = $wakka ? 'foo' : 'bar' ;
If $wakka is true, $string is assigned 'foo', and if it's false, $string is assigned 'bar'.
To do the same in a concatenation, try:
$string = $otherString . ( $wakka ? 'foo' : 'bar' ) ;
Poglavje 9. Izrazi
Izrazi so najpomembnejši del PHP-ja. V PHP-ju je skoraj vse kar napišete izraz. Najenostavnejša, a tudi najbolj točna definicija izraza je: "vse kar ima neko vrednost".
Najbolj osnovne oblike izrazov so konstante in spremenljivke. Ko zapišete "$a = 5", dodeljujete vrednost '5' v spremenljivko $a. '5', očitno, ima vrednost 5, ali v drugih besedah, '5' je izraz z vrednostjo 5 (v tem primeru je '5' številska konstanta).
Po tej dodelitvi, bi pričakovali, da bo vrednost spremenljivke $a enaka 5. Pravtako, če bi zapisali $b = $a, bi pričakovali, da se bo obnašalo kot če bi zapisali $b = 5. Z drugimi besedami, tudi $a je izraz, ki ima vrednost 5. Če vse deluje pravilno, se bo ravno to zgodilo.
Malenkost bolj zahtevni primer za izraz so funkcije. Kot primer, upoštevajte naslednjo funkcijo:
Če predvidevamo, da ste seznanjeni s konceptom funkcij (če niste, si oglejte poglavje o funkcijah), bi predvidevali da ko zapišete $c = foo(), je to pravzaprav enako, kot če bi zapisali $c = 5 - kar je popolnoma pravilno. Funkcije so izrazi, ki imajo vrednost vrnjene vrednosti funkcije. Ker foo() vrne 5, je vrednost izraza 'foo()' enaka 5. Ponavadi funkcije ne vrnejo neke statične vrednosti, ampak vrnejo neko izračunano vrednost.
Seveda, za vrednosti v PHP-ju ne velja, da morajo biti številke in velikokrat to tudi niso. PHP podpira tri skalarne tipe vrednosti: številske vrednosti, plavajočo vejico in niz (skalarne vrednosti so vrednosti, ki ji ne moremo 'razbiti' na manjše dele, kar recimo ne velja za polja). PHP podpira tudi dva neskalarna tipa: polja in objekti. Vsak od teh tipov vrednosti je lahko dodeljen neki spremenljivki, ali vrnjen iz neke funkcije.
Do sedaj, uporabniki PHP/FI 2 nebi smeli čutiti nobene spremembe. Vseeno, PHP nadgrajuje izraze, tako kot ostali programski jeziki. PHP je izrazni jezik v tem pomenu besede, da je skoraj vse, kar zapišemo, izraz. Upoštevajte primer, ki smo ga že imeli, '$a = 5'. Zlahka opazimo, da sta tukaj dve vrednosti, vrednost številske konstante in vrednost spremenljivke $a kateri je bila dodeljena vrednost 5. V resnici pa je tu še ena vrednost - vrednost samega prireditvenega stavka. Prireditveni stavek sam, dobi vrednost same prireditve, v tem primeru 5. V praksi to pomeni, da je '$a = 5', karkoli še naredi, izraz z vrednostjo 5. Kar pomeni, da če zapisemo '$b = ($a = 5)', je enako zapisu '$a = 5; $b = 5;' (podpičje označuje konec stavka). Ker so pripreditveni stavki razčlenjeni od desne proti levi, lahko zapišemo to tudi kot '$b = $a = 5'.
Drugi dober primer izraza je pred- in po-povečanje in manjšanje. Uporabniki PHP/FI 2, kot tudi drugih jezikov, so verjetno seznanjeni z notacijo spremenljivka++ in spremenljivka--. To sta operatorja za povečanje in pomanjšanje. V PHP/FI 2 stavek '$a++' nima nobene vrednosti (ni izraz) in ga zato tudi ne moremo prirediti na noben način. PHP izboljša sposobnost povečevanja/manjšanja s tem, da tudi to postane izraz, tako kot v programskem jeziku C. V PHP-ju, kot v C-ju, obstajata dva tipa povečevanja. - pred-povečevanje in po-povečevanje. Oba povečata spremenljivko in efekt na spremenljivko je v obeh primerih enak. Razlika je v tem, da pred-povečanje, zapisano kot '++spremenljivka', vrne povečano vrednost (PHP poveča spremenljivko, preden prebere njeno vrednost, od tu ime pred-povečanje). Po-povečanje, katerega zapišemo kot 'spremenljivka++', vrne vrednost spremenljivke pred povečanjem (PHP poveča vrednost spremenljivke šele ko jo prebere).
Zelo pogosti tip izraza je primerjalni izraz. Te izrazi lahko vrnejo vrednost 0 ali 1, kar pomeni FALSE ali TRUE. PHP podpira > (večji kot), >= (večji kot ali enak), == (enak), != (neenak), < (manjšsi kot) in <= (manjši kot ali enak). Te izrazi so najbolj pogosto uporabljeni znotraj pogojnih stavkov, kot so if stavki.
Zandji primer izrazov, ki jih bomo obdelali v tem poglavju je kombiniran z opreratorjem in dodelitvenim izrazom. Kot že veste, če želite $a povečati za 1, lahko enostavno napišete '$a++' ali '++$a'. Kaj se pa zgodi, če bi želeli povečati spremenljivko za recimo 3? Lahko bi napisali '$a++' trikrat in dobili željeni rezultat, a to ni najbolj učinkovita ali zadovoljiva rešitev. V praksi se uporablja '$a = $a + 3'. '$a + 3' vrne vrednost spremenljivke $a plus 3 in jo vrne nazaj v $a, kar pomeni, da se $a poveča za 3. V PHP-ju, kot tudi v drugih programskih jezikih, lahko to zapišemo krajše, kar bi čez čas bilo bolj jasno in lažje za razumeti. Torej, če želimo vrednost spremenljivke $a povečati za 3, preprosto zapišemo '$a += 3'. To pomeni: "vzemi vrednost spremenljivke $a, jo povečaj za 3 in dodeli dobljeno vrednost nazaj v spremenljivko $a". Poleg tega, da je ta način krajši in lažji, je tudi hitrejši. Vrednost '$a += 3', kot vrednost navadnega dodelitvenega izraza, je dodeljena vrednost. Zapomnite si, da to NI 3, ampak skupna vrednost od $a + 3 (to ni vrednost, ki je dodeljena spremenljivki $a). Uporabljate lahko tudi druge operatorje, kot naprimer '$a -= 5' (odšteje 5 od vrednosti spremenljivke $a), '$b *= 7' (množi vrednost spremenljivke $b z 7), itd.
Obstaja še en izraz, ki se vam bo mogoče zdel čuden, če ga še niste srečali v drugih jezikih - trojni pogojni operator:
Če je vrednost prvega podizraza TRUE (ni nič), potem se izvede drugi podizraz, kar postane rezultat pogojnega izraza. V nasprotnem primeru se izvede tretju podizraz, kar postane rezultat pogojnega izraza.Spodnji primer bi vam moral pomagati malo bolje razumeti pred-, po-povečanje in izraze na splosno:
function double($i) |
V začetku tega poglavja smo zapisali, da bomo opisali različne tipe stavkov in kot obljubljeno, izraz je lahko stavek. A vseeno, ni vsak izraz stavek. V tem primeru ima stavek obliko 'izraz' ';', to je izraz ki mu sledi podpičje. V '$b=$a=5;', $a=5 je veljaven izraz, ampak ni stavek sam po sebi. '$b=$a=5;' pa je veljaven stavek.
Zadnja stvar, ki bi bila vredna omembe je resnična vrednost izraza. V veliko primerih, večinoma v pogojnem izvajanju ali zankah, vas ne zanima toliko sama vrednost izraza, ampak samo ali je ta izraz TRUE ali FALSE. Konstante TRUE in FALSE (majhne ali velike črke) sta dve najbolj verjetne boolean vrednosti. Ko je potrebno, se izraz avtomatsko konvertira v boolean vrednost. Poglejte si section about type-casting za več informacij o tem.
PHP zagotavlja popolno implementacijo izrazov in če bi želeli dokumentirati vse možnosti in načine uporabe, bi bilo to preveč za ta priročnik. Zgornji primeri naj bi vam dali idejo kaj izrazi so in kako sestaviti uporabne izraze. Skozi ta priročnik bomo, ko bomo želeli poudariti veljaven PHP izraz, zapisali to kot expr.
Izrazi
02-Jul-2008 06:37
16-Mar-2008 05:52
To jvm at jvmyers dot com:
Your first two if statements just check if there's anything in the string, if you wish to actually execute the code in your string you need eval().
24-Feb-2008 12:20
<?php
// Compound booleans expressed as string args in an 'if' statement don't work as expected:
//
// Context:
// 1. I generate an array of counters
// 2. I dynamically generate a compound boolean based on selected counters in the array
// Note: since the real array is sparse, I must use the 'empty' operator
// 3. When I submit the compound boolean as the expression of an 'if' statement,
// the 'if' appears to resolve ONLY the first element of the compound boolean.
// Conclusion: appears to be a short-circuiting issue
$aArray = array(1,0);
// Case 1: 'if' expression passed as string:
$sCondition = "!empty($aArray[0]) && !empty($aArray[1])";
if ($sCondition)
{
echo "1. Conditions met<br />";
}
else
{
echo "1. Conditions not met<br />";
}
// Case 1 output: "1. Conditions met"
// Case 2: same as Case 1, but using catenation operator
if ("".$sCondition."")
{
echo "2. Conditions met<br />";
}
else
{
echo "2. Conditions not met<br />";
}
// Case 2 output: "2. Conditions met"
// Case 3: same 'if' expression but passed in context:
if (!empty($aArray[0]) && !empty($aArray[1]))
{
echo "3. Conditions met<br />";
}
else
{
echo "3. Conditions not met<br />";
}
// Case 3 output: "3. Conditions not met"
// jvm@jvmyers.com
?>
PS: the bug folks say this "does not imply a bug in PHP itself." Sure bugs me!
20-Oct-2007 08:41
Regarding the ternary operator, I would rather say that the best option is to enclose all the expression in parantheses, to avoid errors and improve clarity:
<?php
print ( $a > 1 ? "many" : "just one" );
?>
PS: for php, C++, and any other language that has it.
23-Aug-2007 01:42
reply to egonfreeman at gmail dot com
04-Apr-2007 07:45
the second example u mentioned as follow:
=====================================
$n = 3;
$n * $n++
from 3 * 3 into 3 * 4. Post- operations operate on a variable after it has been 'checked', but it doesn't necessarily state that it should happen AFTER an evaluation is over (on the contrary, as a matter of fact).
===========================================
everything works correctly but one sentence should be modified:
"from 3 * 3 into 3 * 4" should be "from 3 * 3 into 4 * 3"
best regards~ :)
20-Jul-2007 11:01
Here's a quick example of Pre and Post-incrementation, in case anyone does feel confused (ref anonymous poster 31 May 2005)
<?PHP
echo "Using Pre-increment ++\$a:<br>";
$a = 1;
echo "\$a = $a<br>";
$b = ++$a;
echo "\$b = ++\$a, so \$b = $b and \$a = $a<br>";
echo "<br>";
echo "Using Post-increment \$a++:<br>";
$a = 1;
echo "\$a = $a<br>";
$b = $a++;
echo "\$b = \$a++, so \$b = $b and \$a = $a<br>";
?>
HTH
04-Apr-2007 07:45
It is worthy to mention that:
$n = 3;
$n * --$n
WILL RETURN 4 instead of 6.
It can be a hard to spot "error", because in our human thought process this really isn't an error at all! But you have to remember that PHP (as it is with many other high-level languages) evaluates its statements RIGHT-TO-LEFT, and therefore "--$n" comes BEFORE multiplying, so - in the end - it's really "2 * 2", not "3 * 2".
It is also worthy to mention that the same behavior will change:
$n = 3;
$n * $n++
from 3 * 3 into 3 * 4. Post- operations operate on a variable after it has been 'checked', but it doesn't necessarily state that it should happen AFTER an evaluation is over (on the contrary, as a matter of fact).
So, if you ever find yourself on a 'wild goose chase' for a bug in that "impossible-to-break, so-very-simple" piece of code that uses pre-/post-'s, remember this post. :)
(just thought I'd check it out - turns out I was right :P)
14-Feb-2007 04:56
An easy fix (although intuitively tough to do...) is to reverse the comparison.
if (5 == $a) {}
If you forget the second '=', you'll get a parse error for trying to assign a value to a non-variable.
29-Jan-2007 07:46
Attention! php will not warn you if you write (1) When you mean (2)
(1)
<?
if($a=0)
echo "condition is true";
else
echo "condition is false";
//output: condition is false
?>
(2)
<?
if($a==0)
echo "condition is true";
else
echo "condition is false";
//output: condition is true
?>
19-Jan-2006 12:00
Follow up on Martin K. There are no hard and fast rules regarding operator precedence. Newbies should definitely learn them, but if their use results in code that is not easy to read you should use parentheses. The two important things are that it works properly AND is maintainable by you and others.
20-Oct-2005 06:28
At 04-Feb-2005 05:13, tom at darlingpet dot com said:
> It's also a good idea to use parenthesis when using something SIMILAR to:
>
> <?php
> echo (trim($var)=="") ? "empty" : "not empty";
> ?>
No, it's a BAD idea.
All the short-circuiting operators, including the ternary conditional operator, have LOWER precedence than the comparison operators, so they almost NEVER need parentheses around their subexpressions.
Inserting the parentheses suggested above does not change the meaning of the code, but their use misleads inexperienced programmers to expect that things like this will work in a similar manner:
<?php
function my_print($a) { print($a); }
my_print (trim($var)=="") ? "empty" : "not empty";
?>
when of course it doesn't.
Rather than worrying that code doesn't work as expected, simply learn the precedence rules (http://www.php.net/manual/en/language.operators.php) so that one expects the right things.
19-Aug-2005 05:06
12345alex at gmx dot net 's case is actually handled by the === operator. That's what he needs.
There is also another widely used function. I call it myself is_nil which is true for NULL,FALSE,array() and '', but not for 0 and "0".
function is_nil ($value) {
return !$value && $value !== 0 && $value !== '0';
}
Another useful function is "get first argument if it is not empty or get second argument otherwise". The code is:
function def ($value, $defaultValue) {
return is_nil ($value) ? $defaultValue : $value;
}
14-Aug-2005 07:00
this code:
print array() == NULL ? "True" : "False";
print " (" . (array() == NULL) . ")\n";
$arr = array();
print array() == $arr ? "True" : "False";
print " (" . (array() == $arr) . ")\n";
print count(array()) . "\n";
print count(NULL) . "\n";
will output (on php4 and php5):
True (1)
True (1)
0
0
so to decide wether i have NULL or an empty array i will also have to use gettype(). this seems some kind of weird for me, although if is this is a bug, somebody should have noticed it before.
alex
26-Jun-2005 11:25
Pre- and Post-Incrementation, I believe, are important to note and in the correct place. The section deals with the value of an expression. ++$a and $a++ have different values, and both forms have valid uses.
And, because it can be confusing, it is that much more important to note. Although it could be worded better, it does belong.
I don't see why it is necessary here to explain pre- and post- incrementing.
This is something that will confuse new users of PHP, even longer time programmers will sometimes miss a the fine details of a construct like that.
If something has a side-effect it should be on a line of it's own, or at least be an expression of it's own and not part of an assignment, condition or whatever.
04-Feb-2005 02:13
Something I've noticed with ternary expressions is if you do something like :
<?= $var=="something" ? "is something" : "not something"; ?>
It will give wacky results sometimes...
So be sure to enclose the ternary expression in parenthesis when ever necessary (such as having multiple expressions or nested ternary expressions)
The above could look like:
<?= ($var=="something") ? "is something" : "not something"; ?>
It's also a good idea to use parenthesis when using something SIMILAR to:
<?php
echo (trim($var)=="") ? "empty" : "not empty";
?>
In some cases other than the <?= ?> example, not placing the entire expression in appropriate parenthesis might yield undesirable results as well.. but I'm not quite sure.
25-Feb-2003 02:37
The short-circuit feature is indeed intended, and there are two types of evaluators, those who DO short-circuit, and those who DON'T, || / && and | / & respectively.
The latter method is the bitwise operators, but works great with the usual boolean values ( 0/1 )
So if you don't want short-circuiting, try using the | and & instead.
Read more about the bitwise operators here:
http://www.php.net/manual/en/language.operators.bitwise.php
07-Aug-2002 06:06
The short-circuiting IS a feature. It is also available in C, so I suppose the developers won´t remove it in future PHP versions.
It is rather nice to write:
$file=fopen("foo","r") or die("Error!");
Greets,
Oliver
17-Jul-2002 11:08
It should probably be mentioned that the short-circuiting of expressions (mentioned in some of the comments above) is often called "lazy evaluation" (in case someone else searches for the term "lazy" on this page and comes up empty!).
25-May-2002 03:29
A note about the short-circuit behaviour of the boolean operators.
1. if (func1() || func2())
Now, if func1() returns true, func2() isn't run, since the expression
will be true anyway.
2. if (func1() && func2())
Now, if func1() returns false, func2() isn't run, since the expression
will be false anyway.
The reason for this behaviour comes probably from the programming
language C, on which PHP seems to be based on. There the
short-circuiting can be a very useful tool. For example:
int * myarray = a_func_to_set_myarray(); // init the array
if (myarray != NULL && myarray[0] != 4321) // check
myarray[0] = 1234;
Now, the pointer myarray is checked for being not null, then the
contents of the array is validated. This is important, because if
you try to access an array whose address is invalid, the program
will crash and die a horrible death. But thanks to the short
circuiting, if myarray == NULL then myarray[0] won't be accessed,
and the program will work fine.
11-Mar-2001 11:14
Manual defines "expression is anything that has value", Therefore, parser will give error for following code.
<?php
($val) ? echo('true') : echo('false');
Note: "? : " operator has this syntax "expr ? expr : expr;"
?>
since echo does not have(return) value and ?: expects expression(value).
However, if function/language constructs that have/return value, such as include(), parser compiles code.
Note: User defined functions always have/return value without explicit return statement (returns NULL if there is no return statement). Therefore, user defined functions are always valid expressions.
[It may be useful to have VOID as new type to prevent programmer to use function as RVALUE by mistake]
For example,
<?php
($val) ? include('true.inc') : include('false.inc');
?>
is valid, since "include" returns value.
The fact "echo" does not return value(="echo" is not a expression), is less obvious to me.
Print() and Echo() is NOT identical since print() has/returns value and can be a valid expression.
24-Nov-2000 11:01
The ternary conditional operator is a useful way of avoiding inconvenient if statements. They can even be used in the middle of a string concatenation, if you use parentheses.
Example:
if ( $wakka ) {
$string = 'foo' ;
} else {
$string = 'bar' ;
}
The above can be expressed like the following:
$string = $wakka ? 'foo' : 'bar' ;
If $wakka is true, $string is assigned 'foo', and if it's false, $string is assigned 'bar'.
To do the same in a concatenation, try:
$string = $otherString . ( $wakka ? 'foo' : 'bar' ) ;
