Note that even though PHP borrows large portions of its syntax from C, the ',' is treated quite differently. It's not possible to create combined expressions in PHP using the comma-operator that C has, except in for() loops.
Example (parse error):
<?php
$a = 2, $b = 4;
echo $a."\n";
echo $b."\n";
?>
Example (works):
<?php
for ($a = 2, $b = 4; $a < 3; $a++)
{
echo $a."\n";
echo $b."\n";
}
?>
This is because PHP doesn't actually have a proper comma-operator, it's only supported as syntactic sugar in for() loop headers. In C, it would have been perfectly legitimate to have this:
int f()
{
int a, b;
a = 2, b = 4;
return a;
}
or even this:
int g()
{
int a, b;
a = (2, b = 4);
return a;
}
In f(), a would have been set to 2, and b would have been set to 4.
In g(), (2, b = 4) would be a single expression which evaluates to 4, so both a and b would have been set to 4.Изрази
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
Изрази
Референца за `language.expressions.php` со подобрена типографија и навигација.
Изрази
Изразите се најважните градивни блокови на PHP. Во PHP, речиси сè што пишувате е израз. Наједноставниот, а воедно и најточниот начин да се дефинира израз е „сè што има вредност“.
Најелементарните форми на изрази се константи и променливи. Кога пишувате $a = 5, 5 into
$a. 5очигледно, има вредност 5, или со други зборови 5 е израз со вредност 5 (во овој случај, 5 е константа од тип integer).
По ова доделување, би очекувале $aвредноста да биде исто така 5, па ако напишете $b = $a, $b = 5би очекувале да се однесува исто како да сте напишале $a . Со други зборови,
исто така е израз со вредност 5. Ако сè работи како што треба, ова е токму она што ќе се случи.
<?php
function foo ()
{
return 5;
}
?>
Мало посложени примери за изрази се функциите. На пример, разгледајте ја следната функција: functionsПод претпоставка дека сте запознаени со концептот на функции (ако не сте, погледнете го поглавјето за $c = foo() ), би претпоставиле дека пишувањето $c = 5е суштински исто како пишување foo()
,foo()и сте во право. Функциите се изрази со вредност на нивната вратена вредност. Бидејќи
враќа 5, вредноста на изразот ' int ' е 5. Обично функциите не враќаат само статична вредност, туку пресметуваат нешто.float), string вредности и bool вредности (скаларни вредности се вредности што не можете да ги „разделите“ на помали парчиња, за разлика од низите, на пример). PHP исто така поддржува два составни (нескаларни) типа: низи и објекти. Секој од овие типови на вредности може да се додели на променливи или да се врати од функции.
PHP ги носи изразите многу подалеку, на ист начин како што прават многу други јазици. PHP е јазик ориентиран кон изрази, во смисла дека речиси сè е израз. Разгледајте го примерот со кој веќе се занимававме, $a = 5. Лесно е да се види дека овде се вклучени две вредности, вредноста на цел број константа 5, и вредноста на $a што исто така се ажурира на 5. Но, вистината е дека овде е вклучена една дополнителна вредност, а тоа е вредноста на самата доделување. Самото доделување се проценува на доделената вредност, во овој случај 5. Во пракса, тоа значи дека $a = 5, без оглед на тоа што прави, е израз со вредност 5. Така, пишувањето на нешто како
$b = ($a = 5) е како пишување
$a = 5; $b = 5; (точка-запирка го означува крајот на изјавата). Бидејќи доделувањата се парсираат од десно кон лево, можете исто така да напишете $b = $a = 5.
Друг добар пример за ориентација кон изрази е претходното и пост-инкрементот и декрементот. Корисниците на PHP и многу други јазици можеби се запознаени со нотацијата на variable++ and
variable--. Овие се
оператори за инкремент и декремент. Во PHP, како и во C, постојат два вида инкремент - пре-инкремент и пост-инкремент. И пре-инкрементот и пост-инкрементот суштински го зголемуваат променливата, а ефектот врз променливата е идентичен. Разликата е во вредноста на изразот за инкремент. Пре-инкрементот, кој е напишан ++$variable, се проценува на зголемената вредност (PHP ја зголемува променливата пред да ја прочита нејзината вредност, оттука и името 'пре-инкремент'). Пост-инкрементот, кој е напишан $variable++ , се проценува на оригиналната вредност на
$variable, пред да биде зголемена (PHP ја зголемува променливата откако ќе ја прочита нејзината вредност, оттука и името 'пост-инкремент').
Многу чест тип на изрази се comparison
изрази. Овие изрази се проценуваат на или false or true. PHP поддржува > (поголемо од), >= (поголемо од или еднакво на), == (еднакво), != (не еднакво), < (помало од) и <= (помало од или еднакво на). Јазикот исто така поддржува сет на оператори за строго еквивалентност: === (еднакво на и ист тип) и !== (не еднакво на или не ист тип). Овие изрази најчесто се користат во условна извршување, како што се if statements.
Последниот пример на изрази со кои ќе се занимаваме овде се комбинирани изрази за доделување оператор. Веќе знаете дека ако сакате да го зголемите $a со 1, можете едноставно да напишете
$a++ or ++$aсо 1, можете едноставно да напишете $a++ . Но, што ако сакате да додадете повеќе од еден на него, на пример 3? Можете да напишете $a =
$a + 3. $a + 3 повеќе пати, но ова очигледно не е многу ефикасен или удобен начин. Многу почеста практика е да се напише $a се проценува на вредноста на $aплус 3, и повторно му се доделува на $a
, што резултира со зголемување $a
со 3. Во PHP, како и во неколку други јазици како C, можете да го напишете ова на пократок начин, што со текот на времето ќе стане појасно и побрзо за разбирање. Додавање 3 на моменталната вредност на $a += 3може да се напише $a. Ова значи точно „земи ја вредноста на $a, додади му 3 и додели ја повторно на
$a += 3“. Покрај тоа што е пократко и појасно, ова исто така резултира со побрзо извршување. Вредноста на $a , како вредноста на обична доделување, е доделената вредност. Забележете дека тоа НЕ е 3, туку комбинираната вредност на $aплус 3 (ова е вредноста што се доделува на $a -= 5
). Секој оператор со две места може да се користи во овој режим на оператор-доделување, на пример $a), $b *= 7
(одземи 5 од вредноста на $b (помножи ја вредноста на
со 7), итн.
<?php
$first ? $second : $third
?>
Постои уште еден израз што може да изгледа чудно ако не сте го виделе во други јазици, тернарниот условен оператор: true Ако вредноста на првиот под-израз е
Следниот пример треба да ви помогне подобро да ги разберете претходното и пост-зголемувањето и изразите воопшто:
<?php
function double($i)
{
return $i*2;
}
$b = $a = 5; /* assign the value five into the variable $a and $b */
$c = $a++; /* post-increment, assign original value of $a
(5) to $c */
$e = $d = ++$b; /* pre-increment, assign the incremented value of
$b (6) to $d and $e */
/* at this point, both $d and $e are equal to 6 */
$f = double($d++); /* assign twice the value of $d before
the increment, 2*6 = 12 to $f */
$g = double(++$e); /* assign twice the value of $e after
the increment, 2*7 = 14 to $g */
$h = $g += 10; /* first, $g is incremented by 10 and ends with the
value of 24. the value of the assignment (24) is
then assigned into $h, and $h ends with the value
of 24 as well. */
?>
Следниот пример треба да ви помогне подобро да ги разберете претходното и пост-инкрементирањето и изразите воопшто:expr ;Некои изрази може да се сметаат за искази. Во овој случај, исказот има форма на ' $b = $a = 5;,
$a = 5 ' односно израз проследен со точка и запирка. Во $b = $a = 5;е валиден израз, но сам по себе не е исказ.
, меѓутоа, е валиден исказ. true or falseЕдна последна работа вредна за споменување е вистинитоста на изразите. Во многу настани, главно во условно извршување и циклуси, не ве интересира специфичната вредност на изразот, туку само дали тоа значи true and false . Константите
(независно од големината на буквите) се двете можни булови вредности. Кога е потребно, изразот автоматски се претвора во булов. Погледнете го делот за типот на кастинг
за детали за тоа како. expr PHP обезбедува целосна и моќна имплементација на изрази, а целосното документирање оди надвор од опсегот на овој прирачник. Горенаведените примери треба да ви дадат добра идеја за тоа што се изрази и како можете да конструирате корисни изрази. Во текот на остатокот од овој прирачник ќе напишеме
Белешки од корисници за да означиме кој било валиден PHP израз.
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.Note that there is a difference between a function and a function call, and both
are expressions. PHP has two kinds of function, "named functions" and "anonymous
functions". Here's an example with both:
<?php
// A named function. Its name is "double".
function double($x) {
return 2 * $x;
}
// An anonymous function. It has no name, in the same way that the string
// "hello" has no name. Since it is an expression, we can give it a temporary
// name by assigning it to the variable $triple.
$triple = function($x) {
return 3 * $x;
};
?>
We can "call" (or "run") both kinds of function. A "function call" is an
expression with the value of whatever the function returns. For example:
<?php
// The easiest way to run a function is to put () after its name, containing its
// arguments (if any)
$my_numbers = array(double(5), $triple(5));
?>
$my_numbers is now an array containing 10 and 15, which are the return values of
double and $triple when applied to the number 5.
Importantly, if we *don't* call a function, ie. we don't put () after its name,
then we still get expressions. For example:
<?php
$my_functions = array('double', $triple);
?>
$my_functions is now an array containing these two functions. Notice that named
functions are more awkward than anonymous functions. PHP treats them differently
because it didn't use to have anonymous functions, and the way named functions
were implemented didn't work for anonymous functions when they were eventually
added.
This means that instead of using a named function literally, like we can with
anonymous functions, we have to use a string containing its name instead. PHP
makes sure that these strings will be treated as functions when it's
appropriate. For example:
<?php
$temp = 'double';
$my_number = $temp(5);
?>
$my_number will be 10, since PHP has spotted that we're treating a string as if
it were a function, so it has looked up that named function for us.
Unfortunately PHP's parser is very quirky; rather than looking for generic
patterns like "x(y)" and seeing if "x" is a function, it has lots of
special-cases like "$x(y)". This makes code like "'double'(5)" invalid, so we
have to do tricks like using temporary variables. There is another way around
this restriction though, and that is to pass our functions to the
"call_user_func" or "call_user_func_array" functions when we want to call them.
For example:
<?php
$my_numbers = array(call_user_func('double', 5), call_user_func($triple, 5));
?>
$my_numbers contains 10 and 15 because "call_user_func" called our functions for
us. This is possible because the string 'double' and the anonymous function
$triple are expressions. Note that we can even use this technique to call an
anonymous function without ever giving it a name:
<?php
$my_number = call_user_func(function($x) { return 4 * $x; }, 5);
?>
$my_number is now 20, since "call_user_func" called the anonymous function,
which quadruples its argument, with the value 5.
Passing functions around as expressions like this is very useful whenever we
need to use a 'callback'. Great examples of this are array_map and array_reduce.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)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~ :)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.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().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.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,
OliverRegarding 12345alex at gmx dot net's example:
I think you miss the identical equal documentation line from: http://php.net/manual/en/language.operators.comparison.php
$a == $b Equal TRUE if $a is equal to $b after type juggling.
$a === $b Identical TRUE if $a is equal to $b, and they are of the same type.
Try:
print array() === NULL ? "True" : "False";
Check this:
var_dump(is_null(array()));evaluation order of subexpressions is not strictly defined for all operators
<?php
function a() {echo 'a';}
function b() {echo 'b';}
a() == b(); // outputs "ab", ie evaluates left-to-right
$a = 3;
var_dump( $a == $a = 4 ); // outputs bool(true), ie evaluates right-to-left
?>
this is not a bug: "we [php developers] make no guarantee about the order of evaluation".
See https://bugs.php.net/bug.php?id=61188