PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

Оператори> <Вълшебни константи
Last updated: Fri, 27 Jun 2008

view this page in

Изрази

Изразите са най-важните градивни елементи на PHP. Почти всичко, което пишете в PHP, е израз. Най-простият и точен начин да се дефинират изразите е "всичко, което има стойност".

Най-простите форми на изрази са константите и променливите. Когато напишете "$a = 5", вие присвоявате '5' на $a. '5', очевидно има стойност 5, или с други думи, '5' е израз със стойността 5 (в този случай '5' е целочислена константа).

След това присвояване, бихте очаквали стойността на $a да бъде също 5, така че би трябвало $b = $a да работи по същия начин като $b = 5. С други думи, $a също става израз със стойност 5. Ако всичко работи правилно, ще се случи точно това.

Малко по-сложен пример за изрази са функциите. Например, да вземем следната функция:

<?php
function foo ()
{
    return 
5;
}
?>

Ако приемем, че сте наясно с концепцията за функциите (ако не сте, вижте главата за функции), би трябвало да предположите, че $c = foo() е по същество същото като $c = 5, и ще сте прави. Функциите са изрази със стойност - стойността която връщат. Тъй като foo() връща 5, стойността на израза 'foo()' е 5. Обикновено, функциите не просто връщат статична стойност, а изчисляват нещо.

Разбира се, не е задължително стойностите в PHP да са целочислени и в много случаи те не са. PHP поддържа четири скаларни типа стойности: целочислени стойности, стойности с плаваща запетая (плаващи), низови стойности и булеви стойности (скаларни стойности са такива стойности, които не могат да бъдат 'счупени' на по-малки парчета, както масивите, например). PHP също поддържа два съставни (не-скаларни) типа: масиви и обекти. Всеки един от тези типове стойности може да бъде присвояван на променливи или връщан от функции.

PHP навлиза много по-дълбоко в изразите, както правят и много други езици. PHP е изразно-ориентиран език, в смисъл, че почти всичко е израз. Да вземем примера, който вече разгледахме - '$a = 5'. Лесно е да се види, че в случая има две замесени стойности - стойността на целочислената константа '5' и стойността на $a, която се променя на 5. Но истината е, че тук има замесена още една допълнителна стойност и това е стойността на самото присвояване. Самото присвояване се изчислява на присвоената стойност, която в случая е 5. На практика, това означава, че '$a = 5', независимо от това, което прави, е израз със стойност 5. Така че, писането на нещо като '$b = ($a = 5)' е същото като да напишеш '$a = 5; $b = 5;' (точката и запетаята обозначават край на инструкция). Понеже присвояванията се предават от дясно на ляво, можете също да напишете '$b = $a = 5'.

Друг добър пример за изразна ориентираност са предварителното и последващото инкрементиране и декрементиране. Потребителите на PHP и на много други езици вероятно са запознати с нотацията променлива++ и променлива--. Това са операторите за инкрементиране и декрементиране. В PHP/FI 2, инструкцията '$a++' няма стойност (не е израз), и затова не можете да я присвоите или използвате по никакъв начин. PHP увеличава възможностите на инкрементирането и декрементирането като ги прави също изрази, като в C. В PHP, както в C, има два типа инкрементиране - предварително и последващо. И двете всъщност увеличават стойността на променливата с единица и ефектът върху променливата е един и същ. Разликата е в стойността на инкременталния израз. Предварителното инкрементиране, което се пише '++$променлива', се изчислява на увеличената стойност (PHP инкрементира променливата преди да е прочел стойността й, от там и името 'предварително инкрементиране'). Последващото инкрементиране, което се пише '$променлива++' се изчислява на първоначалната стойност на $променлива, преди да бъде инкрементирана (PHP инкрементира променливата след като е прочел стойността й, от там и името 'последващо инкрементиране').

Широко разпространен тип изрази са изразите за сравнение. Тези изрази се изчисляват или на FALSE или на TRUE. PHP поддържа > (по-голямо), >= (по-голямо или равно), == (равно), != (различно), < (по-малко) и <= (по-малко или равно). Езикът също поддържа набор от стриктни оператори за еквивалентност: === (равно и от същия тип) и !== (различно или не от същия тип). Тези изрази най-често се използват при условно изпълнение, като инструкцията if.

Последният пример за изрази, с който ще се занимаваме, е изразът за операторно присвояване. Вече знаете, че за да увеличите $a с 1, можете просто да напишете '$a++' или '++$a'. Но какво ако искате да добавите повече от единица, например 3? Бихте могли да напишете '$a++' няколко пъти, но това очевидно не е много ефикасен и удобен начин. Много по-разпространена практика е да се напише '$a = $a + 3'. '$a + 3' се изчислява на стойността на $a плюс 3, и се присвоява обратно на $a, което увеличава $a с 3. В PHP, както и в много други езици като C, можете да напишете това по-съкратено, което с времето би трябвало да стане също и по-изчистено и по-разбираемо. Добавянето на 3 към текущата стойност на $a може да се напише така: '$a += 3'. Това буквално означава "вземи стойността на $a, добави 3 към нея и я присвои обратно на $a". Освен че е по-късо и по-изчистено, това също е и по-бързо за изпълнение. Стойността на '$a += 3', също като стойността на обикновено присвояване, е присвояваната стойност. Отбележете, че тя НЕ е 3, а комбинираната стойност от $a плюс 3 (това е стойността, която се присвоява на $a). Всички двуместни оператори могат да бъдат използвани в този операторно-присвоителен режим, например '$a -= 5' (изваждане на 5 от стойността на $a), '$b *= 7' (умножаване стойността на $b със 7) и т.н.

Има още един израз, който може би изглежда странно, ако не сте го виждали досега в други езици - третичния оператор:

<?php
$first 
$second $third
?>

Ако стойността на първия под-израз е TRUE (не-нула), тогава се изчислява вторият под-израз и това е резултатът на условния израз. В противен случай се изчислява третият под-израз и това е стойността.

Следващият пример би трябвало да ви помогне да разберете по-добре предварителното и последващото инкрементиране и изразите като цяло:

<?php
function double($i)
{
    return 
$i*2;
}
$b $a 5;        /* присвояване на стойността пет на променливите $a и $b */
$c $a++;          /* последващо инкрементиране, присвояване на първоначалната стойност на $a 
                       (5) на $c */
$e $d = ++$b;     /* предваричелно инкрементиране, присвояване на инкрементираната стойност на 
                       $b (6) на $d и $e */

/* в този момент, и $d и $e са равни на 6 */

$f double($d++);  /* присвояване на удвоената стойност на $d преди инкрементирането
                       2*6 = 12 на $f */
$g double(++$e);  /* присвояване на удвоената стойност на $e след инкрементирането
                       2*7 = 14 на $g */
$h $g += 10;      /* първо, $g се увеличава с 10 като се получава стойността 24.
                       след това, стойността на присвояването (24) се
                       присвоява на $h, и така $h получава също стойност 24. */
?>

Някои изрази могат да бъдат използвани като инструкции. В този случаи, инструкцията е във формат 'израз' ';', т.е. израз последван от точка и запетая. В '$b=$a=5;', $a=5 е валиден израз, но сам по себе си не е инструкция. '$b=$a=5;', обаче, е валидна инструкция.

Едно последно нещо за споменаване е истинната стойност на изразите. При много събития, главно при условно изпълнение и при цикли, не се интересувате от специфичната стойност на израза, а само дали означава TRUE или FALSE. Константите TRUE (истина) и FALSE (неистина) (нечувствителни към регистъра) са двете възможни булеви стойности. Когато е необходимо, изразът автоматично се преобразува в булев тип. Вж. разделът за преобразуване на типове за подробности как става това.

PHP предлага пълна и мощна реализация на изразите и пълното им документиране излиза извън обхвата на това ръководство. Горните примери би трябвало да са ви дали добра представа за това какво са изразите и как да създавате полезни изрази. В останалата част на това ръководство ще пишем expr, за да обозначим валиден израз в PHP.



Оператори> <Вълшебни константи
Last updated: Fri, 27 Jun 2008
 
add a note add a note User Contributed Notes
Изрази
phpsourcecode at blogspot dot com
02-Jul-2008 01:37
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' ) ;
denzoo at gmail dot com
16-Mar-2008 12: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().
jvm at jvmyers dot com
24-Feb-2008 08: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!
petruzanauticoyahoo?com!ar
20-Oct-2007 03: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.
winks716
23-Aug-2007 08: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~ :)
george dot langley at shaw dot ca
20-Jul-2007 06: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
egonfreeman at gmail dot com
04-Apr-2007 02: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)
shawnster
15-Feb-2007 12: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.
nabil_kadimi at hotmail dot com
30-Jan-2007 03: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
?>
richard at phase4 dot ie
19-Jan-2006 08: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.
Martin K
21-Oct-2005 01: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.
stochnagara at hotmail dot com
19-Aug-2005 12: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;
}
12345alex at gmx dot net
14-Aug-2005 02: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
sabinx at gmail dot com
26-Jun-2005 06: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.
31-May-2005 07:07
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.
tom at darlingpet dot com
04-Feb-2005 10: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.
stian at datanerd dot net
25-Feb-2003 10: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
oliver at hankeln-online dot de
07-Aug-2002 01:06
The short-circuiting IS a feature. It is also available in C, so I suppose the developers wont remove it in future PHP versions.

It is rather nice to write:

$file=fopen("foo","r") or die("Error!");

Greets,
Oliver
php at cotest dot com
17-Jul-2002 06: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!).
Mattias at mail dot ee
25-May-2002 10: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.
yasuo_ohgaki at hotmail dot com
12-Mar-2001 07: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.
anthony at n dot o dot s dot p dot a dot m dot trams dot com
24-Nov-2000 07: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' ) ;

Оператори> <Вълшебни константи
Last updated: Fri, 27 Jun 2008
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites