php表达式10%2.5值为,php-langspec-cn

#表达式

##概述

表达式包含一个或多个项和零个或多个运算符。

完整表达式是一个不是另一个表达式的一部分的表达式。

副作用是改变执行环境的状态的一个操作。 (比如一个修改变量的

操作,写入设备或文件,或调用执行这样的操作的函数)。

当计算表达式时,它会生成结果。 它也可能产生副作用。 只有少数操作符产生

副作用。 (例如,给定表达式语句 $v = 10;表达式10对结果10求值,没有副作用,

然后执行赋值运算符,这导致 $v 的副作用被修改。 类似地,给定表达式

语句 ++$v;表达式被求值为结果增加的 $v 值,副作用是$v实际上是递增的。同样,结果从不使用)。

数值计算和副作用的发生是由序列点界定的。在程序执行中,所有序列点之前所承诺的所有计算和副作用发生,

序列点之后的计算或副作用尚未发生。 每个完整表达式的末尾都有一个序列点。

逻辑与,逻辑或,

条件,合并和函数调用操作符

都包含一个序列点。 (例如,在以下一系列表达式语句 $a = 10; ++$a; $b = $a;中,在每个

完整表达式的结尾处都有序列点,因此在 $a 之前的赋值完成 $a 增量,增量在赋给 $b)之前完成。

当表达式包含多个运算符时,这些运算符的优先级控制应用这些运算符的顺序。

(例如,表达式 $a - $b / $c 被计算为 $a - ($b / $c),因为 / 运算符的

优先级高于二进制运算符 -。 运算符的优先级由其相关语法生成的定义确定。

如果操作对象出现在具有相同优先级的两个操作符中间,则执行操作的顺序由那些

操作符的关联性确定。 使用左关联运算符,从左到右执行操作。 (例如,

$a + $b - $c 被计算为($a + $b) - $c)。 使用右关联运算符,从右到左执行操作。

(例如,$a = $b =$c 被计算为 $a =($b = $c))。

优先级和关联性可以使用分组括号来控制。 (例如,在表达式 ($a - $b) / $c 中,

减法在除法之前完成,没有分组括号,除法将首先进行)。

优先级的同时,关联性和分组括号也控制应用运算符的顺序,但它们不控制计算项本身的计算顺序。

除非在本手册中明确说明,否则表达式中的操作数相对于彼此求值的顺序是未指定的。

请参阅上面有关包含序列点的运算符的讨论。 (例如,在完整表达式 $list1[$i] = $list2[$i++] 中,

左侧的 $i 的值是旧的还是新的 $i 是未指定的,类似地,表达式 $j = $i + $i++,$i 的值是

旧的还是新的 $i 未指定最后,在完整表达式 f()+ g() * h() 三个函数被调用,计算顺序是未指定的)。

注意事项

不包含副作用且不使用其结果值的表达式,不需要计算。 例如,表达式语句 6;,$i + 6;

和 $i / $j; 形成良好,但它们不含有副作用,并且不使用它们的结果。

如果可以确定没有出现其他程序代码依赖,则不需要执行副作用。 (例如,在 return $a++; 和 return ++$a

的情况下,显然在每种情况下都必须返回什么值,但如果 $a 是封闭函数的局部变量,$a 实际上不需要自增。

##基本表达式

###概述

语法

语义

带括号的类型和值的表达式,跟不括号的表达式相同。

###简单变量

语法

约束

最后两个变量中的简单变量或表达式必须指明一个标量值或可转换为字符串的对象。

语义

The variable $this is predefined inside any non-static instance method (including

constructor) when that method is called from within an object

context. The value of $this is the calling object or the object being constructed.

简单变量表达式指明具有由变量名或简单变量或表达式的结果的字符串表示形式确定的名称的变量,

这取决于哪种情况适用。 在后两种情况下,变量名可以包含在词法变量名中不允许的字符。

简单变量在不同上下文和不同类型变量中的行为在变量部分中指明。

当在对象上下文中调用该方法时,变量 $this 在任何非静态实例方法(包括构造函数)中都是预定义的。

$this 的值是调用对象或正在构造的对象。

示例

$color = "red";

$$color = 123; // equivalent to $red = 123

// -----------------------------------------

$x = 'ab'; $ab = 'fg'; $fg = 'xy';

$$ $ $x = 'Hello'; // equivalent to $xy = Hello

// -----------------------------------------

$v1 = 3;

$$v1 = 22; // equivalent to ${3} = 22, variable name is "3"

$v2 = 9.543;

$$v2 = TRUE; // equivalent to ${9.543} = TRUE

$v3 = NULL;

$$v3 = "abc"; // equivalent to ${NULL} = "abc", here we create a variable with empty name

// -----------------------------------------

function f1 () { return 2.5; }

${1 + f1()} = 1000; // equivalent to ${3.5} = 1000

###Dereferencable expression

Syntax

Constraints

The string-literal must not use variable interpolation and must not be a heredoc

or nowdoc string literal.

Semantics

A dereferencable-expression can be used as the left hand side of dereferencing operators, such

as [], -> and ::. A callable-expression can be used as the left hand side of the function

call operator.

###Variables

Syntax

Semantics

A variable is an expression that can in principle be used as an lvalue. However, the

individual possible expressions may further restrict whether they can behave as lvalues.

An expression that is not a variable can never act as an lvalue.

###Constant Access Expression

constant-access-expression:

Semantics

A constant-access-expression evaluates to the value of the constant

with name qualified-name.

###Literals

Syntax

Semantics

A literal evaluates to its value, as specified in the lexical specification for

literals.

###Intrinsics

####General

Syntax

Semantics

The names in this series of sections have special meaning and are

called intrinsics, but they are not keywords; nor are they functions, they

are language constructs that are interpreted by the Engine.

intrinsic-operator can be used as part of an expression, in any place

other values or expressions could be used.

intrinsic-construct can be used only as stand-alone statement.

####echo

Syntax

Constraints

expression value must be convertable to a string.

In particular, it should not be an array and if it is an object, it must implement

a __toString method.

Semantics

After converting each of its expressions' values to strings, if

necessary, echo concatenates them in order given, and writes the

resulting string to STDOUT. Unlike print, it does

not produce a result.

Examples

$v1 = TRUE;

$v2 = 123;

echo '>>' . $v1 . '|' . $v2 . "<>1|123<

echo '>>' , $v1 , '|' , $v2 , "<>1|123<

echo ('>>' . $v1 . '|' . $v2 . "<>1|123<

$v3 = "qqq{$v2}zzz";

echo "$v3\n";

####empty

Syntax

empty-intrinsic:

empty (

Semantics

This intrinsic returns TRUE if the variable or value designated by

expression is empty, where empty means that the variable designated by it does not

exist, or it exists and its value compares equal to FALSE. Otherwise,

the intrinsic returns FALSE.

The following values are considered empty: FALSE, 0, 0.0, "" (empty string), "0", NULL,

an empty array, and any uninitialized variable.

If this intrinsic is used with an expression that designates a dynamic

property, then if the class of that property has

an __isset, that method is called.

If that method returns TRUE, the value of the property is retrieved

(which may call __get if defined) and compared

to FALSE as described above. Otherwise, the result is FALSE.

Examples

empty("0"); // results in TRUE

empty("00"); // results in FALSE

$v = [10, 20];

empty($v); // results in FALSE

####eval

Syntax

eval-intrinsic:

eval (

Constraints

expression must designate a string, or be convertable to a string.

The contents of the string must be valid PHP source code. If the source code is ill formed, an exception of type ParseError is thrown.

The PHP source code in the string must not be delimited by opening and

closing PHP tags. However, the source code

itself may contain the tags.

Semantics

This intrinsic evaluates the contents of the string designated by

expression, as PHP script code.

Execution of a return statement from within the source code

terminates the execution, and the value returned becomes the value

returned by eval. If the source code is ill formed, eval returns FALSE;

otherwise, eval returns NULL.

The source code is executed in the scope of that from which eval is

called.

Examples

$str = "Hello";

eval("echo \$str . \"\\n\";"); // → echo $str . "\n"; → prints Hello

####exit/die

Syntax

exit-intrinsic:

exit

exit ( opt )

die

die ( opt )

Constraints

When expression designates an integer, its value must be in the range

0–254.

Semantics

exit and die are equivalent.

This intrinsic terminates the current script. If expression designates

a string, that string is written to STDOUT. If expression

designates an integer, that represents the script's exit status code.

Code 255 is reserved by PHP. Code 0 represents "success". The exit

status code is made available to the execution environment. If

expression is omitted or is a string, the exit status code is zero.

exit does not have a resulting value.

exit performs the following operations, in order:

Writes the optional string to STDOUT.

Calls any functions registered via the library function

register_shutdown_function in their order of registration.

Invokes destructors for all remaining instances.

Examples

exit ("Closing down");

exit (1);

exit;

####isset

Syntax

Semantics

This intrinsic returns TRUE if all the variables designated by

variabless are set and their values are not NULL. Otherwise, it

returns FALSE.

If this intrinsic is used with an expression that designate a dynamic

property, then if the class of that property has

an __isset, that method is called.

If that method returns TRUE, the value of the property is retrieved

(which may call __get if defined) and

if it is not NULL, the result is TRUE. Otherwise, the result is FALSE.

Examples

$v = TRUE;

isset($v); // results in TRUE

$v = NULL;

isset($v); // results in FALSE

$v1 = TRUE; $v2 = 12.3; $v3 = NULL;

isset($v1, $v2, $v3); // results in FALSE

####list

Syntax

Constraints

list-intrinsic must be used as the left-hand operand in a

simple-assignment-expression of which the right-hand

operand must be an expression that designates an array or object implementing

the ArrayAccess interface (called the source array).

Each expression in list-or-variable must designate a variable (called

the target variable).

At least one of the elements of the list-expression-list must be non-empty.

Semantics

This intrinsic assigns one or more elements of the source array to the

target variables. On success, it returns a copy of the source array. If the

source array is not an array or object implementing ArrayAccess no

assignments are performed and the return value is NULL.

For unkeyed-list-expression-list, all elements in the source array having

keys of type string are ignored.

The element having an int key of 0 is assigned to the first target

variable, the element having an int key of 1 is assigned to the second

target variable, and so on, until all target variables have been

assigned. Any other array elements are ignored. If there are

fewer source array elements having int keys than there are target

variables, the unassigned target variables are set to NULL and

a non-fatal error is produced.

For keyed-list-expression-list, each key-variable pair is handled in turn,

with the key and variable being separated by the => symbol.

The element having the first key, with the key having been converted using the

same rules as the subscript operator,

is assigned to the frst target variable. This process is repeated for the

second => pair, if any, and so on. Any other array elements are ignored.

If there is no array element with a given key, the unassigned target variable

is set to NULL and a non-fatal error is produced.

The assignments must occur in this order.

Any target variable may be a list, in which case, the corresponding

element is expected to be an array.

If the source array elements and the target variables overlap in any

way, the behavior is unspecified.

Examples

list($min, $max, $avg) = array(0, 100, 67);

// $min is 0, $max is 100, $avg is 67

list($min, $max, $avg) = array(2 => 67, 1 => 100, 0 => 0);

// same as example above

list($min, , $avg) = array(0, 100, 67);

// $min is 0, $avg is 67

list($min, $max, $avg) = array(0, 2 => 100, 4 => 67);

// $min is 0, $max is NULL, $avg is 100

list($min, list($max, $avg)) = [0, [1 => 67, 99, 0 => 100], 33];

// $min is 0, $max is 100, $avg is 67

list($arr[1], $arr[0]) = [0, 1];

// $arr is [1 => 0, 0 => 1], in this order

list($arr2[], $arr2[]) = [0, 1];

// $arr2 is [0, 1]

list("one" => $one, "two" => $two) = ["one" => 1, "two" => 2];

// $one is 1, $two is 2

list(

"one" => $one,

"two" => $two,

) = [

"one" => 1,

"two" => 2,

];

// $one is 1, $two is 2

list(list("x" => $x1, "y" => $y1), list("x" => $x2, "y" => $y2)) = [

["x" => 1, "y" => 2],

["x" => 3, "y" => 4]

];

// $x1 is 1, $y1 is 2, $x2 is 3, $y2 is 4

list(0 => list($x1, $x2), 1 => list($x2, $y2)) = [[1, 2], [3, 4]];

// $x1 is 1, $y1 is 2, $x2 is 3, $y2 is 4

####print

Syntax

print-intrinsic:

print

Constraints

expression value must be convertable to a string.

In particular, it should not be an array and if it is an object, it must implement

a __toString method.

Semantics

After converting its expression's value to a string, if necessary,

print writes the resulting string to STDOUT.

Unlike echo, print can be used in any context allowing an expression. It

always returns the value 1.

Examples

$v1 = TRUE;

$v2 = 123;

print '>>' . $v1 . '|' . $v2 . "<>1|123<

print ('>>' . $v1 . '|' . $v2 . "<>1|123<

$v3 = "qqq{$v2}zzz";

print "$v3\n"; // outputs "qqq123zzz"

$a > $b ? print "..." : print "...";

####unset

Syntax

unset-intrinsic:

unset (

Semantics

This intrinsic unsets the variables designated by each

variable in variable-list. No value is returned. An

attempt to unset a non-existent variable (such as a non-existent element

in an array) is ignored.

When called from inside a function, this intrinsic behaves, as follows:

For a variable declared global in that function, unset removes the

alias to that variable from the scope of the current call to that

function. The global variable remains set.

(To unset the global variable, use unset on the corresponding

$GLOBALS array entry.

For a variable passed byRef to that function, unset removes the

alias to that variable from the scope of the current call to that

function. Once the function returns, the passed-in argument variable

is still set.

For a variable declared static in that function, unset removes the

alias to that variable from the scope of the current call to that

function. In subsequent calls to that function, the static variable

is still set and retains its value from call to call.

Any visible instance property may be unset, in which case, the property

is removed from that instance.

If this intrinsic is used with an expression that designates a dynamic

property, then if the class of that property has an __unset

method, that method is called.

Examples

unset($v);

unset($v1, $v2, $v3);

unset($x->m); // if m is a dynamic property, $x->__unset("m") is called

###Anonymous Function Creation

Syntax

Semantics

This operator returns an object of type Closure, or a derived

type thereof, that encapsulates the anonymous function defined

within. An anonymous function is defined like, and behaves like, a named

function except that the former has no name and has an optional

anonymous-function-use-clause.

An expression that designates an anonymous function is compatible with

the pseudo-type callable.

The use-variable-name-list is a list of variables from the enclosing

scope, which are to be made available by name to the body of the

anonymous function. Each of these may be passed by value or byRef, as

needed. The values used for these variables are those at the time the

Closure object is created, not when it is used to call the function it

encapsulates.

An anonymous function defined inside an instance or static method has its

scope set to the class it was defined in. Otherwise,

an anonymous function is unscoped.

An anonymous function defined inside an instance method is bound

to the object on which that method is called, while an

an anonymous function defined inside a static method, or prefixed with the

optional static modifier is static, and otherwise

an anonymous function is unbound.

Examples

function doit($value, callable $process)

{

return $process($value);

}

$result = doit(5, function ($p) { return $p * 2; }); // doubles a value

$result = doit(5, function ($p) { return $p * $p; }); // squares a value

// -----------------------------------------

class C

{

public function compute(array $values)

{

$count = 0;

$callback1 = function () use (&$count) // has C as its scope

{

++$count;

//...

};

//...

$callback2 = function() // also has C as its scope

{

//...

};

//...

}

//...

}

##Postfix Operators

###General

Syntax

Semantics

These operators associate left-to-right.

###The clone Operator

Syntax

clone-expression:

clone

Constraints

expression must designate an object.

Semantics

The clone operator creates a new object that is a shallow copy of the object designated by expression.

Then, if the class type of expression has a method called __clone, it is called to perform a deep copy.

The result is the new object.

Examples

Consider a class Employee, from which is derived a class Manager. Let us

assume that both classes contain properties that are objects. clone is

used to make a copy of a Manager object, and behind the scenes, the

Manager object uses clone to copy the properties for the base class,

Employee.

class Employee

{

//...

public function __clone()

{

// make a deep copy of Employee object

}

}

class Manager extends Employee

{

//...

public function __clone()

{

$v = parent::__clone();

// make a deep copy of Manager object

}

}

$obj1 = new Manager("Smith", 23);

$obj2 = clone $obj1; // creates a new Manager that is a deep copy

###The new Operator

Syntax

Constraints

qualified-name must name a class.

expression must be a value of type string (but not be a string

literal) that contains the name of a class, or an object.

class-type-designator must not designate an abstract class.

The number of arguments in argument-expression-list must be at least

as many as the number of non-optional parameters defined for the class's constructor.

Semantics

The new class-type-designator forms create an object of the class type specified by class-type-designator. The new class forms create an object of an anonymous class type, a type that has an unspecified name. In all other respects, however, an anonymous class has the same capabilities as a named class type.

If the class-type-designator is an expression resulting in a string value,

that string is used as the class name. If the expression results in an object,

the class of the object is used as the class for the new object.

The qualified-name is resolved according to the rules described in

scope resolution operator, including

support for self, parent and static.

After the object has been created, each instance property is initialized

with the values specified in property definition,

or the value NULL if no initializer value is provided.

The object is then initialized by calling the class's constructor

passing it the optional argument-expression-list. If the class has no

constructor, the constructor that class inherits (if any) is used. The class

can also specify no constructor definition, in this case the constructor call is omitted.

The result of a named-type object-creation-expression is an object of the type specified by class-type-designator. The result of an anonymous class object-creation-expression is an object of unspecified type. However, this type will subtype all types

provided by class-base-clause and class-interface-clause and the class-members definition should follow the same inheritance and implementation rules as the regular class declaration does.

Each distinct source code expression of the form new class results in the class type that is different from that of all other anonymous class types. However, multiple evaluations of the same source code expression of the form new class result in instances of the same class type.

Because a constructor call is a function call, the relevant parts of

function call operator section also apply.

Examples

class Point

{

public function __construct($x = 0, $y = 0)

{

...

}

...

}

$p1 = new Point; // create Point(0, 0)

$p1 = new Point(12); // create Point(12, 0)

$cName = 'Point';

$p1 = new $cName(-1, 1); // create Point(-1, 1)

// -----------------------------------------

$v2 = new class (100) extends C1 implements I1, I2 {

public function __construct($p) {

echo "Inside class " . __CLASS__ . " constructor with parameter $p\n";

}

};

###Array Creation Operator

Syntax

Constraints

If array-element-initializer contains &, expression in element-value

must designate a variable.

Semantics

If array-initializer is omitted, the array has zero elements. For

convenience, an array-initializer may have a trailing comma; however,

this comma is ignored. An array-initializer-list consists of a

comma-separated list of one or more array-element-initializer items, each

of which is used to provide an element-value and an optional

element-key.

If the type of element-key is neither int nor string, keys with float

or bool values, or strings whose contents match exactly the pattern of

decimal-literal, are converted to integer,

and keys of all other types are converted to string.

If element-key is omitted from an array-element-initializer, an

element key of type int is associated with the corresponding

element-value. The key associated is one more than the largest previously

assigned non-negative int key for this array, regardless of whether that key was

provided explicitly or by default. If the array has no non-negative int keys,

the key 0 is used.

If the largest previously assigned int key is the largest integer value that can be represented,

the new element is not added.

Once the element keys have been converted to int or string, and omitted

element keys have each been associated by default, if two or more

array-element-initializer elements in an array-initializer contain the same

key, the lexically right-most one is the one whose element-value is used

to initialize that element.

The result of this operator is the newly created array value.

If array-element-initializer contains &, element-value's value is

stored using byRef assignment.

Examples

$v = []; // array has 0 elements, i.e. empty array

$v = array(TRUE); // array has 1 element, the Boolean TRUE

$v = [123, -56]; // array of two ints, with implicit int keys 0 and 1

$v = [0 => 123, 1 => -56]; // array of two ints, with explicit int keys 0 and 1

$i = 10;

$v = [$i - 10 => 123, $i - 9 => -56]; // key can be a runtime expression

$v = [NULL, 1 => FALSE, 123, 3 => 34e12, "Hello"]; // implicit & explicit keys

$i = 6; $j = 12;

$v = [7 => 123, 3 => $i, 6 => ++$j]; // keys are in arbitrary order

$v[4] = 99; // extends array with a new element

$v = [2 => 23, 1 => 10, 2 => 46, 1.9 => 6];

// array has 2, with keys 2 and 1, values 46 and 6, respectively

$v = ["red" => 10, "4" => 3, 9.2 => 5, "12.8" => 111, NULL => 1];

// array has 5 elements, with keys “red”, 4, 9, “12.8”, and “”.

$c = array("red", "white", "blue");

$v = array(10, $c, NULL, array(FALSE, NULL, $c));

$v = array(2 => TRUE, 0 => 123, 1 => 34.5, -1 => "red");

foreach($v as $e) { /* ... */ } // iterates over keys 2, 0, 1, -1

for ($i = -1; $i <= 2; ++$i) { echo $v[$i]; } // retrieves via keys -1, 0, 1, 2

###Subscript Operator

Syntax

Constraints

If dereferencable-expression designates a string, expression must not

designate a string.

expression can be omitted only if subscript-expression is used in a

modifiable-lvalue context and dereferencable-expression does not designate a string.

Exception from this is when dereferencable-expression is an empty string - then it is

converted to an empty array.

If subscript-expression is used in a non-lvalue context, the element

being designated must exist.

Semantics

A subscript-expression designates a (possibly non-existent) element of

an array or string. When subscript-expression designates an object of

a type that implements ArrayAccess, the minimal semantics are

defined below; however, they can be augmented by that object's methods

offsetGet and offsetSet.

The element key is designated by expression. If the type of element-key is neither int nor string, keys with float

or bool values, or strings whose contents match exactly the pattern of

decimal-literal, are converted to integer,

and key values of all other types are converted to string.

If both dereferencable-expression and expression designate strings,

expression is treated as if it specified the int key zero instead

and a non-fatal error is produces.

A subscript-expression designates a modifiable lvalue if and only if

dereferencable-expression designates a modifiable lvalue.

dereferencable-expression designates an array

If expression is present, if the designated element exists, the type

and value of the result is the type and value of that element;

otherwise, the result is NULL.

If expression is omitted, a new element is inserted. Its key has type

int and is one more than the highest, previously assigned, non-negative

int key for this array. If this is the first element with a non-negative

int key, key 0 is used.

If the largest previously assigned int key is the largest integer value that can be represented,

the new element is not added.

The result is the added new element, or NULL if the element was not added.

If the usage context is as the left-hand side of a

simple-assignment-expression, the value of the new

element is the value of the right-hand side of that

simple-assignment-expression.

If the usage context is as the left-hand side of a

compound-assignment-expression: the expression

e1 op= e2 is evaluated as e1 = NULL op (e2).

If the usage context is as the operand of a

postfix- or prefix-increment or decrement operator, the value

of the new element is considered to be NULL.

dereferencable-expression designates a string

The expression is converted to int and the result is the character of the

string at the position corresponding to that integer. If the integer is negative,

the position is counted backwards from the end of the string. If the position refers

to a non-existing offset, the result is an empty string.

If the operator is used as the left-hand side of a simple-assignment-expression,

If the assigned string is empty, or in case of non-existing negative offset (absolute value larger than string length), a warning is raised and no assignment is performed.

If the offset is larger than the current string length, the string is extended to a length equal to the offset value, using space (0x20) padding characters.

The value being assigned is converted to string and the character in the specified offset is replaced by the first character of the string.

The subscript operator can not be used on a string value in a byRef context or as the operand of the

postfix- or prefix-increment or decrement operators or on the left

side of compound-assignment-expression,

doing so will result in a fatal error.

dereferencable-expression designates an object of a type that implements ArrayAccess

If expression is present,

If subscript-expression is used in a non-lvalue context, the

object's method offsetGet is called with an argument of

expression. The return value of the offsetGet is the result.

If the usage context is as the left-hand side of a

simple-assignment-expression, the object's method offsetSet is

called with a first argument of expression and a second argument

that is the value of the right-hand side of that

simple-assignment-expression. The value of the right-hand side

is the result.

If the usage context is as the left-hand side of a

compound-assignment-expression, the expression e1[e] op= e2 is

evaluated as e1[e] = e1->offsetGet(e) op (e2), which is then

processed according to the rules for simple assignment immediately

above.

If the usage context is as the operand of

the postfix- or prefix-increment or decrement operators,

the object's method offsetGet is called with an argument of

expression. However, this method has no way of knowing if an

increment or decrement operator was used, or whether it was a prefix

or postfix operator. In order for the value to be modified by the increment/decrement,

offsetGet must return byRef.

The result of the subscript operator value returned by offsetGet.

If expression is omitted,

If the usage context is as the left-hand side of a

simple-assignment-expression, the object's method

offsetSet is called with a first argument of NULL and a second

argument that is the value of the right-hand side of that

simple-assignment-expression. The type and value of the result is

the type and value of the right-hand side of that

simple-assignment-expression.

If the usage context is as the left-hand side of a

compound-assignment-expression: The expression e1[] op= e2 is

evaluated as e1[] = e1->offsetGet(NULL) op (e2), which is then processed

according to the rules for simple assignment immediately above.

If the usage context is as the operand of

the postfix- or prefix-increment or decrement operators,

the object's method offsetGet is called with an argument of NULL.

However, this method has no way of knowing if an increment or

decrement operator was used, or whether it was a prefix or postfix

operator. In order for the value to be modified by the increment/decrement,

offsetGet must return byRef.

The result of the subscript operator value returned by offsetGet.

Note: The brace ({...}) form of this operator has been deprecated.

Examples

$v = array(10, 20, 30);

$v[1] = 1.234; // change the value (and type) of element [1]

$v[-10] = 19; // insert a new element with int key -10

$v["red"] = TRUE; // insert a new element with string key "red"

[[2,4,6,8], [5,10], [100,200,300]][0][2] // designates element with value 6

["black", "white", "yellow"][1][2] // designates substring "i" in "white"

function f() { return [1000, 2000, 3000]; }

f()[2]; // designates element with value 3000

"red"[1.9]; // designates "e"

"red"[-2]; // designates "e"

"red"[0][0][0]; // designates "r"

// -----------------------------------------

class MyVector implements ArrayAccess { /* ... */ }

$vect1 = new MyVector(array(10, 'A' => 2.3, "up"));

$vect1[10] = 987; // calls Vector::offsetSet(10, 987)

$vect1[] = "xxx"; // calls Vector::offsetSet(NULL, "xxx")

$x = $vect1[1]; // calls Vector::offsetGet(1)

###Function Call Operator

Syntax

Constraints

callable-expression must designate a function, by being a value of type string

that contains the function's name, or by being an object of a type that implements

__invoke method (including

Closure objects).

The number of arguments present in a function call must be at least as

many as the number of non-optional parameters defined for that function.

No calls can be made to a conditionally defined function until

that function exists.

Any argument that matches a parameter passed byRef should (but need not)

designate an lvalue.

If variadic-unpacking is used, the result of the expression must be an array or Traversable.

If incompatible value is supplied, the argument is ignored and a non-fatal error is issued.

Semantics

An expression of the form function-call-expression is a function

call. The expression designates the called function, and

argument-expression-list specifies the arguments to be passed to that

function. An argument can be any value. In a function call,

callable-expression is evaluated first, followed by each

assignment-expression in the order left-to-right. There is

a sequence point after each argument is evaluated and right before the function is called.

For details of the result of a function call see return statement.

The value of a function call is a modifiable lvalue only if the function returns a modifiable value byRef.

When a function is called, the value of each argument passed to it is

assigned to the corresponding parameter in that function's definition,

if such a parameter exists. The assignment of argument values to

parameters is defined in terms of simple or

byRef assignment, depending on how the parameter was declared.

There may be more arguments than parameters, in which case, the library functions

func_num_args,

func_get_arg

and func_get_args

can be used to get access to the complete argument list that was

passed. If the number of arguments present in a function call is fewer

than the number of parameters defined for that function, any parameter

not having a corresponding argument is considered undefined if it has no

default argument value; otherwise, it is considered defined with

that default argument value.

If an undefined variable is passed using byRef, that variable becomes

defined, with an initial value of NULL.

Direct and indirect recursive function calls are permitted.

If callable-expression is a string, this is

a variable function call.

If variadic-unpacking operation is used, the operand is considered to be a parameter list.

The values contained in the operand are fetched one by one (in the same manner as foreach would do)

and used for next arguments of for the call. The keys for in the iteration are ignored.

Multiple unpacking operations can be used in the same function call, and unpacking and regular

parameters can be mixed in any order.

Examples

function square($v) { return $v * $v; }

square(5); // call square directly; it returns 25

$funct = square; // assigns the string "square" to $funct

$funct(-2.3) // call square indirectly; it returns 5.29

strlen($lastName); // returns the # of bytes in the string

// -----------------------------------------

function f1() { ... } function f2() { ... } function f3() { ... }

for ($i = 1; $i <= 2; ++$i) { $f = 'f' . $i; $f(); }

// -----------------------------------------

function f($p1, $p2, $p3, $p4, $p5) { ... }

function g($p1, $p2, $p3, $p4, $p5) { ... }

function h($p1, $p2, $p3, $p4, $p5) { ... }

$funcTable = array(f, g, h); // list of 3 function designators

$i = 1;

$funcTable[$i++]($i, ++$i, $i, $i = 12, --$i); // calls g(2,3,3,12,11)

// -----------------------------------------

function f4($p1, $p2 = 1.23, $p3 = "abc") { ... }

f4(); // inside f4, $p1 is undefined, $p2 is 1.23, $p3 is "abc"

// -----------------------------------------

function f(&$p) { ... }

$a = array(10, 20, 30);

f($a[5]); // non-existent element going in, but element exists afterwards

// -----------------------------------------

function factorial($int) // contains a recursive call

{

return ($int > 1) ? $int * factorial($int - 1) : $int;

}

// -----------------------------------------

$anon = function () { ... }; // store a Closure in $anon

$anon(); // call the anonymous function encapsulated by that object

###Member Access Operator

Syntax

Constraints

The dereferencable-expression must designate an object or be NULL, FALSE,

or an empty string.

expression must be a value of type string (but not a string literal)

that contains the name of an instance property (without the

leading $) or an instance or static method of that instance's class

type.

Semantics

A member-access-expression designates an instance property of the object

designated by dereferencable-expression with the name given by the string

representation of member-name. The value is that of the property, and is a

modifiable lvalue if dereferencable-expression is a modifiable lvalue.

When the -> operator is used in a modifiable lvalue context and member-name

designate a property that is not visible, the property is treated as a

dynamic property. If dereferencable-expression's class

type defines a __set method, it is called to store the

property's value. When the -> operator is used in a non-lvalue context

and member-name designate a property that is not visible, the property

is treated as a dynamic property. If dereferencable-expression's

class type defines a __get method,

it is called to retrieve the property's value.

If dereferencable-expression is NULL, FALSE, or an empty string, an expression

of the form $p->x = 10 causes an instance of stdClass

to be created with a dynamic property x having a value of 10. $p is then made

to refer to this instance.

Examples

class Point

{

private $x;

private $y;

public function move($x, $y)

{

$this->x = $x; // sets private property $x

$this->y = $y; // sets private property $x

}

public function __toString()

{

return '(' . $this->x . ',' . $this->y . ')';

} // get private properties $x and $y

public function __set($name, $value) { ... }

public function __get($name) { ... }

}

$p1 = new Point;

$p1->move(3, 9); // calls public instance method move by name

$n = "move";

$p1->$n(-2, 4); // calls public instance method move by variable

$p1->color = "red"; // turned into $p1->__set("color", "red");

$c = $p1->color; // turned into $c = $p1->__get("color");

###Member Call Operator

Syntax

Constraints

The dereferencable-expression must designate an object.

Additionally the general function call constraints

apply.

Semantics

A member-call-expression calls an instance or static method of the

object designated by dereferencable-expression, with the method

name given by the string representation of member-name and the

arguments given by argument-expression-list. The value of

dereferencable-expression is used as the value of $this in the

invoked method.

If the called method does not exist or is not visible from the current

scope an exception is thrown, unless a __call method

exists, in which case it will be called instead.

Examples

###Postfix Increment and Decrement Operators

Syntax

postfix-increment-expression:

postfix-decrement-expression:

Constraints

The operand of the postfix ++ and -- operators must be a modifiable

lvalue that has scalar-compatible type.

Semantics

These operators behave like their prefix counterparts except

that the value of a postfix ++ or -- expression is the value before any

increment or decrement takes place.

Examples

$i = 10; $j = $i-- + 100; // old value of $i (10) is added to 100

$a = array(100, 200); $v = $a[1]++; // old value of $ia[1] (200) is assigned

###Scope-Resolution Operator

Syntax

Constraints

qualified-name must be the name of a class or interface type.

expression must be a value of type string that contains the name

of a class or interface type.

Semantics

From inside or outside a class or interface, operator :: allows the

selection of a constant. From inside or outside a class, this operator

allows the selection of a static property, static method, or instance

method. From within a class, it also allows the selection of an

overridden property or method.

If the scoped-property-access-expression form is used, this operator

is accessing a static property given by simple-variable and can be

used as an lvalue.

If the class-constant-access-expression form is used, this operator is

is accessing a class constant given by name. This form can not be used

as an lvalue.

If the scoped-call-expression form is used, the operator is calling the

method given by member-anem, which, outside of the object context,

is treated as static method call.

Inside of the object context when $this is defined and the called method is not static and

the called class is the same as a parent of the class of $this, then the method call is

non-static with the same $this. Otherwise it is a static method call.

relative-scope designates the class with relation to the current class scope.

From within a class, self refers to the same class, parent refers to the

class the current class extends from. From within a method, static refers

to the class corresponds to the class inheritance context in which the method is called.

This allows late static binding, when class resolution depends on the dynamic

call context.

class Base

{

public function b()

{

static::f(); // calls the most appropriate f()

}

public function f() { ... }

}

class Derived extends Base

{

public function f() { ... }

}

$b1 = new Base;

$b1->b(); // as $b1 is an instance of Base, Base::b() calls Base::f()

$d1 = new Derived;

$d1->b(); // as $d1 is an instance of Derived, Base::b() calls Derived::f()

The value of the form of scope-resolution-expression ending in ::class

is a string containing the fully qualified name of the current class,

which for a static qualifier, means the current class context.

Examples

final class MathLibrary

{

public static function sin() { ... }

...

}

$v = MathLibrary::sin(2.34); // call directly by class name

$clName = 'MathLibrary';

$v = $clName::sin(2.34); // call indirectly via string

// -----------------------------------------

class MyRangeException extends Exception

{

public function __construct($message, ...)

{

parent::__construct($message);

...

}

...

}

// -----------------------------------------

class Point

{

private static $pointCount = 0;

public static function getPointCount()

{

return self::$pointCount;

}

...

}

###Exponentiation Operator

Syntax

exponentiation-expression:

Semantics

The ** operator produces the result of raising the value of the

left-hand operand to the power of the right-hand one.

If either of the operands have an object type supporting ** operation,

then the object semantics defines the result. The left operand is checked first.

If either or both operands have non-numeric types, their values are converted

to type int or float, as appropriate. If both operands have non-negative

integer values and the result can be represented as an int, the result has

type int; otherwise, the result has type float. If either or both operands

were leading-numeric or non-numeric strings, a non-fatal error must be produced

for each. Examples

2**3; // int with value 8

2**3.0; // float with value 8.0

"2.0"**"3"; // float with value 8.0

##Unary Operators

###General

Syntax

Semantics

These operators associate right-to-left.

###Prefix Increment and Decrement Operators

Syntax

prefix-increment-expression:

++ prefix-decrement-expression:

--

Constraints

The operand of the prefix ++ or -- operator must be a modifiable lvalue

that has scalar-compatible type.

Semantics

Arithmetic Operands

For a prefix ++ operator used with an arithmetic operand, the side

effect of the operator is to increment the value of the operand by 1.

The result is the value of the operand after it

has been incremented. If an int operand's value is the largest

representable for that type, the operand is incremented as if it were float.

For a prefix -- operator used with an arithmetic operand, the side

effect of the operator is to decrement the value of the operand by 1.

The result is the value of the operand after it has been

decremented. If an int operand's value is the smallest representable for

that type, the operand is decremented as if it were float.

For a prefix ++ or -- operator used with an operand having the value

INF, -INF, or NAN, there is no side effect, and the result is the

operand's value.

Boolean Operands

For a prefix ++ or -- operator used with a Boolean-valued operand, there

is no side effect, and the result is the operand's value.

NULL-valued Operands

For a prefix -- operator used with a NULL-valued operand, there is no

side effect, and the result is the operand's value. For a prefix ++

operator used with a NULL-valued operand, the side effect is that the

operand's type is changed to int, the operand's value is set to zero,

and that value is incremented by 1. The result is the value of the

operand after it has been incremented.

String Operands

For a prefix -- operator used with an operand whose value is an empty

string, the side effect is that the operand's type is changed to int,

the operand's value is set to zero, and that value is decremented by 1.

The result is the value of the operand after it has been incremented.

For a prefix ++ operator used with an operand whose value is an empty

string, the side effect is that the operand's value is changed to the

string "1". The type of the operand is unchanged. The result is the new

value of the operand.

For a prefix -- or ++ operator used with a numeric string, the numeric

string is treated as the corresponding int or float value.

For a prefix -- operator used with a non-numeric string-valued operand,

there is no side effect, and the result is the operand's value.

For a non-numeric string-valued operand that contains only alphanumeric

characters, for a prefix ++ operator, the operand is considered to be a

representation of a base-36 number (i.e., with digits 0–9 followed by A–Z or a–z) in

which letter case is ignored for value purposes. The right-most digit is

incremented by 1. For the digits 0–8, that means going to 1–9. For the

letters "A"–"Y" (or "a"–"y"), that means going to "B"–"Z" (or "b"–"z").

For the digit 9, the digit becomes 0, and the carry is added to the next

left-most digit, and so on. For the digit "Z" (or "z"), the resulting

string has an extra digit "A" (or "a") appended. For example, when

incrementing, "a" -> "b", "Z" -> "AA", "AA" -> "AB", "F29" -> "F30", "FZ9" -> "GA0", and "ZZ9" -> "AAA0". A digit position containing a number wraps

modulo-10, while a digit position containing a letter wraps modulo-26.

For a non-numeric string-valued operand that contains any

non-alphanumeric characters, for a prefix ++ operator, all characters up

to and including the right-most non-alphanumeric character is passed

through to the resulting string, unchanged. Characters to the right of

that right-most non-alphanumeric character are treated like a

non-numeric string-valued operand that contains only alphanumeric

characters, except that the resulting string will not be extended.

Instead, a digit position containing a number wraps modulo-10, while a

digit position containing a letter wraps modulo-26.

Object Operands

If the operand has an object type supporting the operation,

then the object semantics defines the result. Otherwise, the operation has

no effect and the result is the operand.

Examples

$i = 10; $j = --$i + 100; // new value of $i (9) is added to 100

$a = array(100, 200); $v = ++$a[1]; // new value of $a[1] (201) is assigned

$a = "^^Z"; ++$a; // $a is now "^^A"

$a = "^^Z^^"; ++$a; // $a is now "^^Z^^"

###Unary Arithmetic Operators

Syntax

unary-op-expression:

unary-operator: one of

+ - ! ~

Constraints

The operand of the unary + and unary - must have scalar-compatible type.

The operand of the unary ~ operator must have arithmetic or string type, or be

an object supporting ~.

Semantics

For a unary ! operator the type of the result is bool.

The value of the operand is converted to type bool

and if it is TRUE then the of the operator result is FALSE, and the result is TRUE otherwise.

Arithmetic Operands

For a unary + operator used with an arithmetic operand, the type and

value of the result is the type and value of the operand.

For a unary - operator used with an arithmetic operand, the value of the

result is the negated value of the operand. However, if an int operand's

original value is the smallest representable for that type, the operand is

treated as if it were float and the result will be float.

For a unary ~ operator used with an int operand, the type of the result

is int. The value of the result is the bitwise complement of the value

of the operand (that is, each bit in the result is set if and only if

the corresponding bit in the operand is clear). For a unary ~ operator

used with a float operand, the value of the operand is first converted

to int before the bitwise complement is computed.

Boolean Operands

For a unary + operator used with a TRUE-valued operand, the value of the

result is 1 and the type is int. When used with a FALSE-valued operand,

the value of the result is zero and the type is int.

For a unary - operator used with a TRUE-valued operand, the value of the

result is -1 and the type is int. When used with a FALSE-valued operand,

the value of the result is zero and the type is int.

NULL-valued Operands

For a unary + or unary - operator used with a NULL-valued operand, the

value of the result is zero and the type is int.

String Operands

For a unary + or - operator used with a numeric string or a

leading-numeric string, the string is first converted to an int or

float, as appropriate, after which it is handled as an arithmetic

operand. The trailing non-numeric characters in leading-numeric strings

are ignored. With a non-numeric string, the result has type int and

value 0. If the string was leading-numeric or non-numeric, a non-fatal error

MUST be produced.

For a unary ~ operator used with a string, the result is the string with each byte

being bitwise complement of the corresponding byte of the source string.

Object Operands

If the operand has an object type supporting the operation,

then the object semantics defines the result. Otherwise, for ~ the fatal error is issued

and for + and - the object is converted to int.

Examples

$v = +10;

if ($v1 > -5) // ...

$t = TRUE;

if (!$t) // ...

$v = ~0b1010101;

$s = "\x86\x97"; $s = ~$s; // $s is "yh"

###Error Control Operator

Syntax

error-control-expression:

@

Semantics

Operator @ suppresses the reporting of any error messages generated by the evaluation of

expression.

If a custom error-handler has been established using the library

function set_error_handler, that handler is

still called.

Examples

$infile = @fopen("NoSuchFile.txt", 'r');

On open failure, the value returned by fopen is FALSE, which is

sufficient to know to handle the error. The error message that may have been generated

by the fopen call is suppressed (not displayed and not logged).

Implementation Notes

Given the following example:

function f() {

$ret = $y;

return $ret;

}

$x = @f(); // without @, get "Undefined variable: y"

The following code shows how this statement is handled:

$origER = error_reporting();

error_reporting(0);

$tmp = f();

$curER = error_reporting();

if ($curER === 0) error_reporting($origER);

$x = $tmp;

###Shell Command Operator

Syntax

shell-command-expression:

` opt `

where ` is the GRAVE ACCENT character U+0060, commonly referred to as a

backtick.

Semantics

This operator passes dq-char-sequence to the command shell for

execution, as though it was being passed to the library function

shell_exec. If the output from execution of that command is

written to STDOUT, that output is the result of this operator

as a string. If the output is redirected away from STDOUT, or

dq-char-sequence is empty or contains only white space, the result of

the operator is NULL.

If shell_exec is disabled, this operator is disabled.

Examples

$result = `ls`; // result is the output of command ls

$result = `ls >dirlist.txt`; // result is NULL

$d = "dir"; $f = "*.*";

$result = `$d {$f}`; // result is the output of command dir *.*

###Cast Operator

Syntax

cast-expression:

cast-type: one of

array binary bool boolean double int integer float object

real string unset

Semantics

With the exception of the cast-type unset and binary (see below), the

value of the operand cast-expression is converted to the type

specified by cast-type, and that is the type and value of the result.

This construct is referred to as a cast and is used as the verb, "to

cast". If no conversion is involved, the type and value of the result

are the same as those of cast-expression.

A cast can result in a loss of information.

A cast-type of array results in a conversion to type array.

A cast-type of binary is reserved for future use in dealing with

so-called binary strings. For now, it is fully equivalent to string cast.

A cast-type of bool or boolean results in a conversion to type bool.

A cast-type of int or integer results in a conversion to type int.

A cast-type of float, double, or real results in a conversion to type float.

A cast-type of object results in a conversion to type object.

A cast-type of string results in a conversion to type string.

A cast-type of unset always results in a value of NULL. (This use of

unset should not be confused with the unset intrinsic.

Examples

(int)(10/3) // results in the int 3 rather than the float 3.333...

(array)(16.5) // results in an array of 1 float; [0] = 16.5

(int)(float)"123.87E3" // results in the int 123870

##instanceof Operator

Syntax

Constraints

The expression in instanceof-type-designator and instanceof-subject must not be any form of

literal.

Semantics

Operator instanceof returns TRUE if the value designated by

expression in instanceof-subject is an object having the type specified

by instanceof-type-designator, is an object whose type is derived from that type,

or is an object whose type implements the interface specified by instanceof-type-designator.

Otherwise, it returns FALSE.

The type can be specified by instanceof-type-designator in one of the three forms:

qualified-name specifies the type name directly.

When the expression form is used, expression may have a string value that contains a class or interface name.

Alternatively, expression can designate an object, in which case the type of the object is used as the specified type.

Note that an interface can not be specified with this form.

Note that instanceof will not invoke autoloader if the name of the type given does not

correspond to the existing class or interface, instead it will return FALSE.

Examples

class C1 { }

$c1 = new C1;

class C2 { }

$c2 = new C2;

class D extends C1 { };

$d = new D;

var_dump($d instanceof C1); // TRUE

var_dump($d instanceof C2); // FALSE

var_dump($d instanceof D); // TRUE

// -----------------------------------------

interface I1 { }

interface I2 { }

class E1 implements I1, I2 { }

$e1 = new E1;

var_dump($e1 instanceof I1); // TRUE

$iName = "I2";

var_dump($e1 instanceof $iName); // TRUE

$e2 = new E1;

var_dump($e2 instanceof $e1); // TRUE

##Multiplicative Operators

Syntax

Constraints

The right-hand operand of operator / and operator % must not be zero.

Semantics

If either of the operands is an object supporting the operation, the result is

defined by that object's semantics, with the left operand checked first.

The binary * operator produces the product of its operands. If either or both

operands have non-numeric types, their values are converted to type int or

float, as appropriate. If either or both operands were leading-numeric or

non-numeric strings, a non-fatal error MUST be produced for each. Then if

either operand has type float, the other is converted to that type, and the

result has type float. Otherwise, both operands have type int, in which

case, if the resulting value can be represented in type int that is the

result type. Otherwise, the result would have type float.

Division by zero results in a non-fatal error. If the value of the numerator is positive, the result value is INF. If the value of the numerator is negative, the result value is -INF. If the value of the numerator is zero, the result value is NAN.

The binary / operator produces the quotient from dividing the left-hand

operand by the right-hand one. If either or both operands have non-numeric

types, their values are converted to type int or float, as appropriate. If

either or both operands were leading-numeric or non-numeric strings, a

non-fatal error must be produced for each. Then if either operand has type

float, the other is converted to that type, and the result has type float.

Otherwise, both operands have type int, in which case, if the mathematical

value of the computation can be preserved using type int, that is the result

type; otherwise, the type of the result is float.

The binary % operator produces the remainder from dividing the left-hand

operand by the right-hand one. If the type of both operands is not int, their

values are converted to that type. If either or both operands were

leading-numeric or non-numeric strings, a non-fatal error MUST be produced for

each. The result has type int. If the right-hand operand has value zero, an

exception of type DivisionByZeroError is thrown.

These operators associate left-to-right.

Examples

-10 * 100; // int with value -1000

100 * -3.4e10; // float with value -3400000000000

"123" * "2e+5; // float with value 24600000

100 / 100; // int with value 1

100 / "123"; // float with value 0.8130081300813

"123" % 100; // int with value 23

100 / 0; // results in a diagnostic followed by bool with value false

100 / 0.0; // results in a diagnostic followed by bool with value false

1.3 / 0; // results in a diagnostic followed by bool with value false

1.3 / 0.0; // results in a diagnostic followed by bool with value false

100 / "a"; // results in a diagnostic followed by bool with value false (a is converted to 0)

##Additive Operators

Syntax

Constraints

If either operand of + has array type, the other operand must also have array

type.

Binary - operator can not be applied to arrays.

Semantics

If either of the operands is an object supporting the operation, the result is

defined by that object's semantics, with the left operand checked first.

For non-array operands, the binary + operator produces the sum of those

operands, while the binary - operator produces the difference of its operands

when subtracting the right-hand operand from the left-hand one. If either or

both operands have non-array, non-numeric types, their values are converted to

type int or float, as appropriate. If either or both operands were

leading-numeric or non-numeric strings, a non-fatal error MUST be produced for

each. Then if either operand has type float, the other is converted to that

type, and the result has type float. Otherwise, both operands have type

int, in which case, if the resulting value can be represented in type int

that is the result type. Otherwise, the result would have type float.

If both operands have array type, the binary + operator produces a new

array that is the union of the two operands. The result is a copy of the

left-hand array with elements inserted at its end, in order, for each

element in the right-hand array whose key does not already exist in the

left-hand array. Any element in the right-hand array whose key exists in

the left-hand array is ignored.

The binary . operator creates a string that is the concatenation of the

left-hand operand and the right-hand operand, in that order. If either

or both operands have types other than string, their values are

converted to type string. The result has type string.

These operators associate left-to-right.

Examples

-10 + 100; // int with value 90

100 + -3.4e10; // float with value -33999999900

"123" + "2e+5"; // float with value 200123

100 - "123"; // int with value 23

-3.4e10 - "abc"; // float with value -34000000000

// -----------------------------------------

[1, 5 => FALSE, "red"] + [4 => -5, 1.23]; // [1, 5 => FALSE, "red", 4 => -5]

// dupe key 5 (value 1.23) is ignored

[NULL] + [1, 5 => FALSE, "red"]; // [NULL, 5 => FALSE, "red"]

// dupe key 0 (value 1) is ignored

[4 => -5, 1.23] + [NULL]; // [4 => -5, 1.23, 0 => NULL]

// -----------------------------------------

-10 . NAN; // string with value "-10NAN"

INF . "2e+5"; // string with value "INF2e+5"

TRUE . NULL; // string with value "1"

10 + 5 . 12 . 100 - 50; // int with value 1512050; ((((10 + 5).12).100)-50)

##Bitwise Shift Operators

Syntax

Constraints

Each of the operands must have scalar-compatible type.

Semantics

If either of the operands is an object supporting the operation, the result is

defined by that object's semantics, with the left operand checked first.

Given the expression e1 << e2, the bits in the value of e1 are shifted

left by e2 positions. Bits shifted off the left end are discarded, and

zero bits are shifted on from the right end. Given the expression

e1 >> e2, the bits in the value of e1 are shifted right by

e2 positions. Bits shifted off the right end are discarded, and the sign

bit is propagated from the left end.

If either operand does not have type int, its value is first converted to

that type. If either or both operands were leading-numeric or non-numeric

strings, a non-fatal error MUST be produced for each.

The type of the result is int, and the value of the result is that after

the shifting is complete. The values of e1 and e2 are unchanged.

Left shifts where the shift count is greater than the bit width of the integer

type (e.g. 32 or 64) must always result in 0, even if there is no native

processor support for this.

Right shifts where the shift count is greater than the bit width of the integer

type (e.g. 32 or 64) must always result in 0 when e1 is positive and -1 when

e1 is negative, even if there is no native processor support for this.

If the shift count is negative, an exception of type ArithmeticError is thrown.

These operators associate left-to-right.

Examples

1000 >> 2 // 0x3E8 is shifted right 2 places

-1000 << 2 // 0xFFFFFC18 is shifted left 5 places

123 >> 128 // Shift count larger than bit width => result 0

123 << 33 // For 32-bit integers the result is zero, otherwise

// it is 0x7B shifted left 33 places

##Relational Operators

Syntax

Semantics

Operator <=> represents comparison operator between two expressions, with the

result being an integer less than 0 if the expression on the left is less than the expression on the right

(i.e. if $a < $b would return TRUE), as defined below by the semantics of the operator

integer 0 if those expressions are equal (as defined by the semantics of the == operator)

and integer greater than 0 otherwise.

Operator < represents less-than, operator > represents

greater-than, operator <= represents less-than-or-equal-to, and

operator >= represents greater-than-or-equal-to.

The type of the result is bool.

Note that greater-than semantics is implemented as the reverse of less-than, i.e.

$a > $b is the same as $b < $a. This may lead to confusing results if the operands

are not well-ordered - such as comparing two objects not having comparison semantics, or

comparing arrays.

The following table shows the result for comparison of different types, with the left

operand displayed vertically and the right displayed horizontally.

The conversions are performed according to type conversion rules.

NULL

bool

int

float

string

array

object

resource

NULL

=

->

->

->

->

->

<

<

bool

1

int

->

2

2

<

3

float

->

2

2

<

3

string

->

->

->

2, 4

<

3

2

array

->

>

>

>

5

3

>

object

>

->

3

3

3

3

6

3

resource

>

->

->

->

2

<

3

2

= means the result is always "equals", i.e. strict comparisons are always FALSE and equality comparisons are always TRUE.

< means that the left operand is always less than the right operand.

> means that the left operand is always greater than the right operand.

-> means that the left operand is converted to the type of the right operand.

A number means one of the cases below:

If either operand has type bool, the other operand is converted to

that type. The result is the logical comparison of the two operands

after conversion, where FALSE is defined to be less than TRUE.

If one of the operands has arithmetic type, is a resource, or a numeric string,

which can be represented as int or float without loss of precision,

the operands are converted to the corresponding arithmetic type, with float taking precedence over int,

and resources converting to int.

The result is the numerical comparison of the two operands after conversion.

If only one operand has object type, if the object has comparison handler,

that handler defines the result.

Otherwise, if the object can be converted to the other operand's type,

it is converted and the result is used for the comparison. Otherwise, the object

compares greater-than any other operand type.

If both operands are non-numeric strings, the result is the lexical

comparison of the two operands. Specifically, the strings are

compared byte-by-byte starting with their first byte. If the two

bytes compare equal and there are no more bytes in either string,

the strings are equal and the comparison ends; otherwise, if this is

the final byte in one string, the shorter string compares less-than

the longer string and the comparison ends. If the two bytes compare

unequal, the string having the lower-valued byte compares less-than

the other string, and the comparison ends. If there are more bytes

in the strings, the process is repeated for the next pair of bytes.

If both operands have array type, if the arrays have different

numbers of elements, the one with the fewer is considered less-than

the other one, regardless of the keys and values in each, and the

comparison ends. For arrays having the same numbers of elements, the

keys from the left operand are considered one by one, if

the next key in the left-hand operand exists in the right-hand

operand, the corresponding values are compared. If they are unequal,

the array containing the lesser value is considered less-than the

other one, and the comparison ends; otherwise, the process is

repeated with the next element. If the next key in the left-hand

operand does not exist in the right-hand operand, the arrays cannot

be compared and FALSE is returned. If all the values are equal,

then the arrays are considered equal.

When comparing two objects, if any of the object types has its own compare

semantics, that would define the result, with the left operand taking precedence.

Otherwise, if the objects are of different types, the comparison result is FALSE.

If the objects are of the same type, the properties of the objects are

compares using the array comparison described above.

These operators associate left-to-right.

Examples

"" < "ab" // result has value TRUE

"a" > "A" // result has value TRUE

"a0" < "ab" // result has value TRUE

"aA <= "abc" // result has value TRUE

// -----------------------------------------

NULL < [10,2.3] // result has value TRUE

TRUE > -3.4 // result has value FALSE

TRUE < -3.4 // result has value FALSE

TRUE >= -3.4 // result has value TRUE

FALSE < "abc" // result has value TRUE

// -----------------------------------------

10 <= 0 // result has value FALSE

10 >= "-3.4" // result has value TRUE

"-5.1" > 0 // result has value FALSE

// -----------------------------------------

[100] < [10,20,30] // result has value TRUE (LHS array is shorter)

[10,20] >= ["red"=>0,"green"=>0] // result has value FALSE, (key 10 does not exists in RHS)

["red"=>0,"green"=>0] >= ["green"=>0,"red"=>0] // result has value TRUE (order is irrelevant)

// ------------------------------------

function order_func($a, $b) {

return ($a->$x <=> $b->x) ?: ($a->y <=> $b->y) ?: ($a->z <=> $b->z);

}

##Equality Operators

Syntax

Semantics

Operator == represents value equality, operators != and <> are

equivalent and represent value inequality.

For operators ==, !=, and <>, the operands of different types are converted and

compared according to the same rules as in relational operators.

Two objects of different types are always not equal.

Operator === represents same type and value equality, or identity, comparison, and operator !== represents

the opposite of ===. The values are considered identical if they have the same type and compare as equal, with the

additional conditions below:

When comparing two objects, identity operators check to

see if the two operands are the exact same object, not two different objects of the same type and value.

Arrays must have the same elements in the same order to be considered identical.

Strings are identical if they contain the same characters, unlike value comparison operators no conversions are performed for numeric strings.

The type of the result is bool.

These operators associate left-to-right.

Examples

"a" <> "aa" // result has value TRUE

// -----------------------------------------

NULL == 0 // result has value TRUE

NULL === 0 // result has value FALSE

TRUE != 100 // result has value FALSE

TRUE !== 100 // result has value TRUE

// -----------------------------------------

"10" != 10 // result has value FALSE

"10" !== 10 // result has value TRUE

// -----------------------------------------

[10,20] == [10,20.0] // result has value TRUE

[10,20] === [10,20.0] // result has value FALSE

["red"=>0,"green"=>0] === ["red"=>0,"green"=>0] // result has value TRUE

["red"=>0,"green"=>0] === ["green"=>0,"red"=>0] // result has value FALSE

Bitwise AND Operator

Syntax

Constraints

Each of the operands must have scalar-compatible type.

Semantics

If either of the operands is an object supporting the operation, the result is

defined by that object's semantics, with the left operand checked first.

If either operand does not have type int, its value is first converted to

that type. If either or both operands were leading-numeric or non-numeric

strings, a non-fatal error MUST be produced for each.

The result of this operator is the bitwise-AND of the two operands, and

the type of that result is int.

However, if both operands are strings, the result is the string composed of the sequence of bytes

that are the result of bitwise AND operation performed on the bytes of the operand strings

in the matching positions (result[0] = s1[0] & s2[0], etc.).

If one of the strings is longer than the other, it is cut to the length of the shorter one.

This operator associates left-to-right.

Examples

0b101111 & 0b101 // 0b101

$lLetter = 0x73; // letter 's'

$uLetter = $lLetter & ~0x20; // clear the 6th bit to make letter 'S'

##Bitwise Exclusive OR Operator

Syntax

Constraints

Each of the operands must have scalar-compatible type.

Semantics

If either of the operands is an object supporting the operation, the result is

defined by that object's semantics, with the left operand checked first.

If either operand does not have type int, its value is first converted to

that type. If either or both operands were leading-numeric or non-numeric

strings, a non-fatal error MUST be produced for each.

The result of this operator is the bitwise exclusive-OR of the two

operands, and the type of that result is int.

However, if both operands are strings, the result is the string composed of the sequence of bytes

that are the result of bitwise XOR operation performed on the bytes of the operand strings

in the matching positions (result[0] = s1[0] ^ s2[0], etc.).

If one of the strings is longer than the other, it is cut to the length of the shorter one.

This operator associates left-to-right.

Examples

0b101111 ^ 0b101 // 0b101010

$v1 = 1234; $v2 = -987; // swap two integers having different values

$v1 = $v1 ^ $v2;

$v2 = $v1 ^ $v2;

$v1 = $v1 ^ $v2; // $v1 is now -987, and $v2 is now 1234

##Bitwise Inclusive OR Operator

Syntax

Constraints

Each of the operands must have scalar-compatible type.

Semantics

If either of the operands is an object supporting the operation, the result is

defined by that object's semantics, with the left operand checked first.

If either operand does not have type int, its value is first converted to

that type. If either or both operands were leading-numeric or non-numeric

strings, a non-fatal error MUST be produced for each.

The result of this operator is the bitwise inclusive-OR of the two

operands, and the type of that result is int.

However, if both operands are strings, the result is the string composed of the sequence of bytes

that are the result of bitwise OR operation performed on the bytes of the operand strings

in the matching positions (result[0] = s1[0] | s2[0], etc.).

If one of the strings is shorter than the other, it is extended with zero bytes.

This operator associates left-to-right.

Examples

0b101111 | 0b101 // 0b101111

$uLetter = 0x41; // letter 'A'

$lLetter = $upCaseLetter | 0x20; // set the 6th bit to make letter 'a'

##Logical AND Operator (form 1)

Syntax

Semantics

Given the expression e1 && e2, e1 is evaluated first. If e1 converts to bool as FALSE, e2 is not evaluated, and the result has type bool, value FALSE. Otherwise, e2 is evaluated. If e2 converts to bool as FALSE, the result has type bool, value FALSE; otherwise, it has type bool, value TRUE. There is a sequence point after the evaluation of e1.

This operator associates left-to-right.

Except for the difference in precedence, operator && has exactly the

same semantics as operator and.

Examples

if ($month > 1 && $month <= 12) ...

##Logical Inclusive OR Operator (form 1)

Syntax

Semantics

Given the expression e1 || e2, e1 is evaluated first. If e1 converts to bool as TRUE, e2 is not evaluated, and the result has type bool, value TRUE. Otherwise, e2 is evaluated. If e2 converts to bool as TRUE, the result has type bool, value TRUE; otherwise, it has type bool, value FALSE. There is a sequence point after the evaluation of e1.

This operator associates left-to-right.

Examples

if ($month < 1 || $month > 12) ...

##Conditional Operator

Syntax

Semantics

Given the expression e1 ? e2 : e3, e1 is evaluated first and converted to bool if it has another type.

If the result is TRUE, then and only then is e2 evaluated, and the result and its type become the result and type of

the whole expression. Otherwise, then and only then is e3 evaluated, and

the result and its type become the result and type of the whole

expression. There is a sequence point after the evaluation of e1. If e2

is omitted, the result and type of the whole expression is the value and

type of e1 (before the conversion to bool).

This operator associates left-to-right.

Examples

for ($i = -5; $i <= 5; ++$i)

echo "$i is ".(($i & 1 == TRUE) ? "odd\n" : "even\n");

// -----------------------------------------

$a = 10 ? : "Hello"; // result is int with value 10

$a = 0 ? : "Hello"; // result is string with value "Hello"

$i = PHP_INT_MAX;

$a = $i++ ? : "red"; // result is int with value 2147483647 (on a 32-bit

// system) even though $i is now the float 2147483648.0

// -----------------------------------------

$i++ ? f($i) : f(++$i); // the sequence point makes this well-defined

// -----------------------------------------

function factorial($int)

{

return ($int > 1) ? $int * factorial($int - 1) : $int;

}

##Coalesce Operator

Syntax

Semantics

Given the expression e1 ?? e2, if e1 is set and not NULL (i.e. TRUE for

isset), then the result is e1. Otherwise, then and only then is e2

evaluated, and the result becomes the result of the whole

expression. There is a sequence point after the evaluation of e1.

Note that the semantics of ?? is similar to isset so that uninitialized variables will not produce

warnings when used in e1.

This operator associates right-to-left.

Examples

$arr = ["foo" => "bar", "qux" => NULL];

$obj = (object)$arr;

$a = $arr["foo"] ?? "bang"; // "bar" as $arr["foo"] is set and not NULL

$a = $arr["qux"] ?? "bang"; // "bang" as $arr["qux"] is NULL

$a = $arr["bing"] ?? "bang"; // "bang" as $arr["bing"] is not set

$a = $obj->foo ?? "bang"; // "bar" as $obj->foo is set and not NULL

$a = $obj->qux ?? "bang"; // "bang" as $obj->qux is NULL

$a = $obj->bing ?? "bang"; // "bang" as $obj->bing is not set

$a = NULL ?? $arr["bing"] ?? 2; // 2 as NULL is NULL, and $arr["bing"] is not set

function foo() {

echo "executed!", PHP_EOL;

}

var_dump(true ?? foo()); // outputs bool(true), "executed!" does not appear as it short-circuits

##Assignment Operators

###General

Syntax

Constraints

The left-hand operand of an assignment operator must be a modifiable

lvalue.

Semantics

These operators associate right-to-left.

###Simple Assignment

Syntax

Constraints

If the location designated by the left-hand operand is a string element,

the key must not be a negative-valued int, and the right-hand operand

must have type string.

Semantics

If assignment-expression designates an expression having value type,

see assignment for scalar types

If assignment-expression designates an expression having handle type, see assignment for object and resource types.

If assignment-expression designates an expression having array type, see

assignment of array types.

The type and value of the result is the type and value of the left-hand

operand after the store (if any [see below]) has taken place. The result

is not an lvalue.

If the location designated by the left-hand operand is a non-existent

array element, a new element is inserted with the designated key and

with a value being that of the right-hand operand.

If the location designated by the left-hand operand is a string element,

then if the key is a negative-valued int, there is no side effect.

Otherwise, if the key is a non-negative-valued int, the left-most single

character from the right-hand operand is stored at the designated

location; all other characters in the right-hand operand string are

ignored. If the designated location is beyond the end of the

destination string, that string is extended to the new length with

spaces (U+0020) added as padding beyond the old end and before the newly

added character. If the right-hand operand is an empty string, the null

character \0 (U+0000) is stored.

Examples

$a = $b = 10 // equivalent to $a = ($b = 10)

$v = array(10, 20, 30);

$v[1] = 1.234; // change the value (and type) of an existing element

$v[-10] = 19; // insert a new element with int key -10

$v["red"] = TRUE; // insert a new element with string key "red"

$s = "red";

$s[1] = "X"; // OK; "e" -> "X"

$s[-5] = "Y"; // warning; string unchanged

$s[5] = "Z"; // extends string with "Z", padding with spaces in [3]-[5]

$s = "red";

$s[0] = "DEF"; // "r" -> "D"; only 1 char changed; "EF" ignored

$s[0] = ""; // "D" -> "\0"

$s["zz"] = "Q"; // warning; defaults to [0], and "Q" is stored there

// -----------------------------------------

class C { ... }

$a = new C; // make $a point to the allocated object

###byRef Assignment

Syntax

byref-assignment-expression:

Constraints

assignment-expression must be an lvalue or a call to a function that

returns a value byRef.

Semantics

unary-expression becomes an alias for assignment-expression.

If assignment-expression designates an expression having value type,

see byRef assignment for scalar types

If assignment-expression designates an expression having handle type, see byRef assignment for non-scalar types.

If assignment-expression designates an expression having array type, see

deferred array copying.

Examples

$a = 10;

$b =& $a; // make $b an alias of $a

++$a; // increment $a/$b to 11

$b = -12; // sets $a/$b to -12

$a = "abc"; // sets $a/$b to "abc"

unset($b); // removes $b's alias to $a

// -----------------------------------------

function &g2() { $t = "xxx"; return $t; } // return byRef

$b =& g2(); // make $b an alias to "xxx"

##Compound Assignment

Syntax

compound-assignment-expression:

compound-assignment-operator: one of

**= *= /= %= += -= .= <<= >>= &= ^= |=

Constraints

Any constraints that apply to the corresponding binary operator apply to the compound-assignment form as well.

Semantics

The expression e1 op= e2 is equivalent to e1 = e1 op (e2), except

that e1 is evaluated only once.

Examples

$v = 10;

$v += 20; // $v = 30

$v -= 5; // $v = 25

$v .= 123.45 // $v = "25123.45"

$a = [100, 200, 300];

$i = 1;

$a[$i++] += 50; // $a[1] = 250, $i → 2

##Logical AND Operator (form 2)

Syntax

Semantics

Except for the difference in precedence, operator and has exactly the

same semantics as operator &&.

##Logical Exclusive OR Operator

Syntax

Semantics

If either operand does not have type bool, its value is first converted

to that type.

Given the expression e1 xor e2, e1 is evaluated first, then e2. If

either e1 or e2 converted to bool as TRUE, but not both, the result has type bool, value

TRUE. Otherwise, the result has type bool, value FALSE. There is a

sequence point after the evaluation of e1.

This operator associates left-to-right.

Examples

f($i++) xor g($i) // the sequence point makes this well-defined

##Logical Inclusive OR Operator (form 2)

Syntax

Semantics

Except for the difference in precedence, operator and has exactly the

same semantics as operator ||.

yield Operator

Syntax

Semantics

Any function containing a yield-expression is a generator function.

A generator function generates a collection of zero or more key/value

pairs where each pair represents the next in some series. For example, a

generator might yield random numbers or the series of Fibonacci

numbers. When a generator function is called explicitly, it returns an

object of type Generator, which implements the interface

Iterator. As such, this allows that object to be iterated over

using the foreach statement. During each iteration, the Engine

calls the generator function implicitly to get the next key/value pair.

Then the Engine saves the state of the generator for subsequent key/value pair requests.

The yield operator produces the result NULL unless the method

Generator->send was called to provide a result value. This

operator has the side effect of generating the next value in the collection.

Before being used, an element-key must have, or be converted to, type

int or string. Keys with float or bool values, or numeric strings, are

converted to int. Values of all other key types are converted to

string.

If element-key is omitted from an array-element-initializer, an

element key of type int is associated with the corresponding

element-value. The key associated is one more than the previously

assigned int key for this collection. However, if this is the first

element in this collection with an int key, key zero is used. If

element-key is provided, it is associated with the corresponding

element-value. The resulting key/value pair is made available by

yield.

If array-element-initializer is omitted, default int-key assignment is

used and each value is NULL.

If the generator function definition declares that it returns byRef,

each value in a key/value pair is yielded byRef.

The following applies only to the yield from form:

A generator function (referred to as a delegating generator) can delegate to another generator function (referred to as a subgenerator), a Traversable object, or an array, each of which is designated by expression.

Each value yielded by expression is passed directly to the delegating generator's caller.

Each value sent to the delegating generator's send method is passed to the subgenerator's send method. If expression is not a generator function, any sent values are ignored.

Exceptions thrown by expression are propagated up to the delegating generator.

Upon traversable completion, NULL is returned to the delegating generator if the traversable is not a generator. If the traversable is a generator, its return value is sent to the delegating generator as the value of the yield from expression.

An exception of type Error is thrown if expression evaluates to a generator that previously terminated with an uncaught exception, or it evaluates to something that is neither Traversable nor an array.

Examples

function getTextFileLines($filename)

{

$infile = fopen($filename, 'r');

if ($infile == FALSE) { /* deal with the file-open failure */ }

try

{

while ($textLine = fgets($infile)) // while not EOF

{

$textLine = rtrim($textLine, "\r\n"); // strip off terminator

yield $textLine;

}

}

finally

{

fclose($infile);

}

}

foreach (getTextFileLines("Testfile.txt") as $line) { /* process each line */ }

// -----------------------------------------

function series($start, $end, $keyPrefix = "")

{

for ($i = $start; $i <= $end; ++$i)

{

yield $keyPrefix . $i => $i; // generate a key/value pair

}

}

foreach (series(1, 5, "X") as $key => $val) { /* process each key/val pair */ }

// -----------------------------------------

function gen()

{

yield 1;

yield from gen2();

yield 4;

}

function gen2()

{

yield 2;

yield 3;

}

foreach (gen() as $val)

{

echo $val . "\n"; // Produces the values 1, 2, 3, and 4

}

// -----------------------------------------

function g() {

yield 1;

yield from [2, 3];

yield 4;

}

$g = g();

foreach ($g as $yielded) {

echo $yielded . "\n"; // Produces the values 1, 2, 3, and 4

}

##Script Inclusion Operators

###General

Syntax

Semantics

When creating large applications or building component libraries, it is

useful to be able to break up the source code into small, manageable

pieces each of which performs some specific task, and which can be

shared somehow, and tested, maintained, and deployed individually. For

example, a programmer might define a series of useful constants and use

them in numerous and possibly unrelated applications. Likewise, a set of

class definitions can be shared among numerous applications needing to

create objects of those types.

An include file is a script that is suitable for inclusion by

another script. The script doing the including is the including file,

while the one being included is the included file. A script can be an

including file and an included file, either, or neither.

Using the series-of-constants example, an include file called

Positions.php might define the constants TOP, BOTTOM, LEFT, and RIGHT,

in their own namespace, Positions. Using the set-of-classes

example, to support two-dimensional geometry applications, an include

file called Point.php might define the class Point. An include file

called Line.php might define the class Line (where a Line is represented

as a pair of Points).An include file, called Circle.php might define the

class Circle (where a Circle is represented as a Point for the origin,

and a radius).

If a number of the scripts making up an application each use one or more

of the Position constants, they can each include the corresponding

include file via the include operator. However, most include

files behave the same way each time they are included, so it is

generally a waste of time including the same include file more than once

into the same scope. In the case of the geometry example, any attempt to

include the same include file more than once will result in a fatal

"attempted class type redefinition" error. However, this can be avoided

by using the include_once operator instead.

The require operator is a variant of the include operator,

and the require_once operator is a variant of the

include_once operator.

It is important to understand that unlike the C/C++ (or similar)

preprocessor, script inclusion in PHP is not a text substitution

process. That is, the contents of an included file are not treated as if

they directly replaced the inclusion operation source in the including

file. See examples below for more information.

An inclusion expression can be written to look like a function call;

however, that is not the case, even though an included file can return a

value to its including file.

The name used to specify an include file may contain an absolute or

relative path. In the latter case, an implementation may use the

configuration directive

include_path

to resolve the include file's location.

Examples:

As mentioned above, script inclusion in PHP is not a text substitution process (unlike C/C++'s preprocessor and alike). This allows that one can specify namespaces in the included file even though nested namespaces in a single file only are not permitted:

include.php

namespace foo;

$x = 'hello';

foo();

index.php

namespace bar {

include 'include.php'; // this is fine does not result in a nested namespace

echo $x; // hello

\foo\foo(); // function foo is still member of the foo namespace

//namespace baz{} // would fail, nesting namespaces are not allowed

}

Moreover, nested classes in a single file are not permitted whereas classes defined in an included file does not result in a nested class (in a conditionally defined class though) - the same applies for nested interfaces or traits:

include.php

namespace foo;

class Foo{}

index.php

class Bar{

function bar(){

include 'include.php'; // this is fine, does not result in a nested class

}

//class Foo1{} // would fail, nested classes are not allowed

//interface Foo2{} // would fail as well

//trait Foo3{} // and would fail as well

}

new Foo(); // fails, \Foo could not be found

new \foo\Foo(); // fails, definition for class Foo was not loaded yet

$bar = new Bar();

$bar->bar();

new Foo(); // still fails, include != use statement

new \foo\Foo(); // succeeds, definition for class Foo was loaded

c-constants can not be defined within a function or method (in contrast to d-constants. As in the other examples above, this is perfectly legal when it happens through a file inclusion in which the constant does not lose its scope. Consider the following example:

include.php

namespace foo;

const X = 2;

index.php

class Bar{

function bar(){

include 'include.php';

}

}

echo X; // emits a notice: Use of undefined constant X ...

echo \foo\X; // same as above since the inclusion did not happen yet

$bar = new Bar();

$bar->bar();

echo X; // still fails, include != use statement

echo \foo\X; // succeeds, X was defined through the inclusion

In contrast to constants, functions, classes, interfaces and traits, variables defined at the top level of a file might change their meaning (being a global variable) when the corresponding file is included by another file. This is the case when the inclusion happens in a local scope. In this case the variables become local variables of the corresponding scope. Following an example as illustration:

include.php

namespace foo;

$x = 'hello';

index.php

function bar(){

include 'include.php'; // introduces the local variable $x

$x = 'hi'; // modification is only local

return $x;

}

echo bar(); // hi

echo $x; // emits a notice: Undefined variable: x ...

include 'include.php'; // introduces the global variable $x

echo $x; // hello

###The include Operator

Syntax

include-expression:

include

Constraints

expresssion must be convertable to a string, which designates

a filename.

Semantics

Operator include results in parsing and executing the designated include

file. If the filename is invalid or does not specify a readable

file, a non-fatal error is produced.

When an included file is opened, parsing begins in HTML mode at the beginning of the file.

After the included file has been parsed, it is immediately executed.

Variables defined in an included file take on scope of the source line

on which the inclusion occurs in the including file. However, functions

and classes defined in the included file are always in global scope.

If inclusion occurs inside a function definition within the including

file, the complete contents of the included file are treated as though

it were defined inside that function.

The result produced by this operator is one of the following:

If the included file returned any value, that value is the result.

If the included file has not returned any value, the result is the integer 1.

If the inclusion failed for any reason, the result is FALSE.

The library function get_included_files provides the names of

all files included by any of the four including operators.

Examples:

$fileName = 'limits' . '.php'; include $fileName;

$inc = include('limits.php');

If ((include 'Positions.php') == 1) ...

###The include_once Operator

Syntax

include-once-expression:

include_once

Semantics

This operator is identical to operator include except that in

the case of include_once, the same include file is included once per

program execution.

Once an include file has been included, a subsequent use of

include_once on that include file results in a return value of TRUE but nothing else

happens.

The files are identified by the full pathname, so different forms of the filename (such as full

and relative path) still are considered the same file.

Examples:

Point.php:

\\ Point.php:

class Point { ... }

\\ Circle.php:

include_once 'Point.php';

class Circle { /* uses Point somehow */ }

\\ MyApp.php

include_once 'Point.php'; // Point.php included directly

include_once 'Circle.php'; // Point.php now not included indirectly

$p1 = new Point(10, 20);

$c1 = new Circle(9, 7, 2.4);

###The require Operator

Syntax

require-expression:

require

Semantics

This operator is identical to operator include except that in

the case of require, failure to find/open the designated include file

produces a fatal error.

###The require_once Operator

Syntax

require-once-expression:

require_once

Semantics

This operator is identical to operator require except that in

the case of require_once, the include file is included once per

program execution.

Once an include file has been included, a subsequent use of

require_once on that include file results in a return value of TRUE but nothing else

happens.

The files are identified by the full pathname, so different forms of the filename (such as full

and relative path) still are considered the same file.

##Constant Expressions

Syntax

constant-expression:

Constraints

The expression may only use the following syntactic elements:

Literals. String literals must not use interpolation.

Unary operators +, -, ~, !.

Binary operators +, -, *, /, %, ., **, ^, |, &,

, <=, >=, <=>, ==, !=, ===, !==, &&, ||, ??.

Semantics

A constant-expression evaluates to the value of the constituent expression.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值