语言参考

一、基本语法
(一)PHP 标记
(二)从 HTML 中分离
(三)指令分隔符
(四)注释
二、类型
(一)简介
(二)Boolean 布尔类型
(三)Integer 整型
(四)Float 浮点型
(五)String 字符串
(六)Array 数组
(七)Object 对象
(八)Resource 资源类型
(九)NULL
(十)Callback 回调类型
(十一)本文档中使用的伪类型与变量
(十二)类型转换的判别
三、变量
(一)基础
(二)预定义变量
(三)变量范围
(四)可变变量
(五)来自 PHP 之外的变量
四、常量
(一)语法
(二)魔术常量
五、表达式
六、运算符
(一)运算符优先级
(二)算术运算符
(三)赋值运算符
(四)位运算符
(五)比较运算符
(六)错误控制运算符
(七)执行运算符
(八)递增/递减运算符
(九)逻辑运算符
(十)字符串运算符
(十一)数组运算符
(十二)类型运算符
七、流程控制
(一)简介
(二)if
(三)else
(四)elseif/else if
(五)流程控制的替代语法
(六)while
(七)do-while
(八)for
(九)foreach
(十)break
(十一)continue
(十二)switch
(十三)declare
(十四)return
(十五)require
(十六)include
(十七)require_once
(十八)include_once
(十九)goto

八、函数

(一)用户自定义函数

一个函数可由以下的语法来定义:

Example #1 展示函数用途的伪代码
<?php
 function  foo ( $arg_1 ,  $arg_2 ,  /* ..., */  $arg_n )
{
    echo  "Example function.\n" ;
    return  $retval ;
}
?>

任何有效的 PHP 代码都有可能出现在函数内部,甚至包括其它函数和类定义。

函数名和 PHP 中的其它标识符命名规则相同。有效的函数名以字母或下划线打头,后面跟字母,数字或下划线。可以用正则表达式表示为:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

  • Tip:请参见用户空间命名指南。

函数无需在调用之前被定义,除非是下面两个例子中函数是有条件被定义时。

当一个函数是有条件被定义时,必须在调用函数之前定义。

Example #2 有条件的函数
<?php
$makefoo  =  true ;

 /* 不能在此处调用foo()函数,
   因为它还不存在,但可以调用bar()函数。*/
bar ();

if ( $makefoo ) {
  function  foo ()
  {
    echo  "I don't exist until program execution reaches me.\n" ;
  }
}

 /* 现在可以安全调用函数 foo()了,
   因为 $makefoo 值为真 */
 if ( $makefoo )  foo ();

function  bar ()
{
  echo  "I exist immediately upon program start.\n" ;
}

?>
Example #3 函数中的函数
<?php
 function  foo ()
{
  function  bar ()
  {
    echo  "I don't exist until foo() is called.\n" ;
  }
}

 /* 现在还不能调用bar()函数,因为它还不存在 */

 foo ();

 /* 现在可以调用bar()函数了,因为foo()函数
   的执行使得bar()函数变为已定义的函数 */

 bar ();

?>

PHP 中的所有函数和类都具有全局作用域,可以定义在一个函数之内而在之外调用,反之亦然。

PHP 不支持函数重载,也不可能取消定义或者重定义已声明的函数。

Note: 函数名是大小写无关的,不过在调用函数的时候,使用其在定义时相同的形式是个好习惯。

PHP 的函数支持可变数量的参数和默认参数。参见 func_num_args() , func_get_arg() 和 func_get_args() 。

在 PHP 中可以调用递归函数。

Example #4 递归函数
<?php
 function  recursion ( $a )
{
    if ( $a  <  20 ) {
        echo  " $a \n" ;
         recursion ( $a  +  1 );
    }
}
?>

Note: 但是要避免递归函数/方法调用超过 100-200 层,因为可能会使堆栈崩溃从而使当前脚本终止。 无限递归可视为编程错误。

(二)函数的参数

通过参数列表可以传递信息到函数,即以逗号作为分隔符的表达式列表。参数是从左向右求值的。

PHP 支持按值传递参数(默认),通过引用传递参数以及默认参数。也支持可变长度参数列表。

Example #1 向函数传递数组
<?php
 function  takes_array ( $input )
{
    echo  " $input [ 0 ]  +  $input [ 1 ]  = " ,  $input [ 0 ]+ $input [ 1 ];
}
?>

通过引用传递参数

默认情况下,函数参数通过值传递(因而即使在函数内部改变参数的值,它并不会改变函数外部的值)。如果希望允许函数修改它的参数值,必须通过引用传递参数。

如果想要函数的一个参数总是通过引用传递,可以在函数定义中该参数的前面加上符号 &:

Example #2 用引用传递函数参数 
<?php
 function  add_some_extra (& $string )
{
     $string  .=  'and something extra.' ;
}
 $str  =  'This is a string, ' ;
 add_some_extra ( $str );
echo  $str ;     // outputs 'This is a string, and something extra.'
?>

默认参数的值

函数可以定义 C++ 风格的标量参数默认值,如下所示:

Example #3 在函数中使用默认参数
<?php
 function  makecoffee ( $type  =  "cappuccino" )
{
    return  "Making a cup of  $type .\n" ;
}
echo  makecoffee ();
echo  makecoffee ( null );
echo  makecoffee ( "espresso" );
?>
以上例程会输出:
Making a cup of cappuccino.
Making a cup of .
Making a cup of espresso.

PHP 还允许使用数组 array 和特殊类型 NULL 作为默认参数,例如:

Example #4 使用非标量类型作为默认参数
<?php
 function  makecoffee ( $types  = array( "cappuccino" ),  $coffeeMaker  =  NULL )
{
     $device  =  is_null ( $coffeeMaker ) ?  "hands"  :  $coffeeMaker ;
    return  "Making a cup of " . join ( ", " ,  $types ). " with  $device .\n" ;
}
echo  makecoffee ();
echo  makecoffee (array( "cappuccino" ,  "lavazza" ),  "teapot" );
?>

默认值必须是常量表达式,不能是诸如变量,类成员,或者函数调用等。

注意当使用默认参数时,任何默认参数必须放在任何非默认参数的右侧;否则,函数将不会按照预期的情况工作。考虑下面的代码片断:

Example #5 函数默认参数的不正确用法
<?php
 function  makeyogurt ( $type  =  "acidophilus" ,  $flavour )
{
    return  "Making a bowl of  $type   $flavour .\n" ;
}

echo  makeyogurt ( "raspberry" );    // won't work as expected
?>
以上例程会输出:
Warning: Missing argument 2 in call to makeyogurt() in 
/usr/local/etc/httpd/htdocs/phptest/functest.html on line 41
Making a bowl of raspberry .

现在,比较上面的例子和这个例子:

Example #6 函数默认参数正确的用法
<?php
 function  makeyogurt ( $flavour ,  $type  =  "acidophilus" )
{
    return  "Making a bowl of  $type   $flavour .\n" ;
}

echo  makeyogurt ( "raspberry" );    // works as expected
?>
以上例程会输出:
Making a bowl of acidophilus raspberry.

Note: 自 PHP 5 起,传引用的参数也可以有默认值。

  • Type declarations

    Note: Type declarations were also known as type hints in PHP 5.

Type declarations allow functions to require that parameters are of a certain type at call time. If the given value is of the incorrect type, then an error is generated: in PHP 5, this will be a recoverable fatal error, while PHP 7 will throw a TypeError exception.

To specify a type declaration, the type name should be added before the parameter name. The declaration can be made to accept NULL values if the default value of the parameter is set to NULL .

  • Valid types
Type Description Minimum PHP version
Class/interface name The parameter must be an instanceof the given class or interface name. PHP 5.0.0
array The parameter must be an array . PHP 5.1.0
callable The parameter must be a valid callable . PHP 5.4.0
bool The parameter must be a boolean value. PHP 7.0.0
float The parameter must be a float ing point number. PHP 7.0.0
int The parameter must be an integer . PHP 7.0.0
string The parameter must be a string . PHP 7.0.0

范例

Example #7 Basic class type declaration
<?php
 class  C  {}
class  D  extends  C  {}

 // This doesn't extend C.
 class  E  {}

function  f ( C $c ) {
    echo  get_class ( $c ). "\n" ;
}

 f (new  C );
 f (new  D );
 f (new  E );
?>
以上例程会输出:

C
DFatal error: Uncaught TypeError: Argument 1 passed to f() must be an instance of C, instance of E given, called in - on line 14 and defined in -:8
Stack trace:
#0 -(14): f(Object(E))
#1 {main}
  thrown in - on line 8
Example #8 Basic interface type declaration
<?php
 interface  I  { public function  f (); }
class  C  implements  I  { public function  f () {} }

 // This doesn't implement I.
 class  E  {}

function  f ( I $i ) {
    echo  get_class ( $i ). "\n" ;
}

 f (new  C );
 f (new  E );
?>
以上例程会输出:
CFatal error: Uncaught TypeError: Argument 1 passed to f() must implement interface I, instance of E given, called in - on line 13 and defined in -:8
Stack trace:
#0 -(13): f(Object(E))
#1 {main}
  thrown in - on line 8
Example #9 Nullable type declaration
<?php
 class  C  {}

function  f ( C $c  =  null ) {
     var_dump ( $c );
}

 f (new  C );
 f ( null );
?>

以上例程会输出:
object(C)#1 (0) {
}
NULL
  • Strict typing

By default, PHP will coerce values of the wrong type into the expected scalar type if possible. For example, a function that is given an integer for a parameter that expects a string will get a variable of type string .

It is possible to enable strict mode on a per-file basis. In strict mode, only a variable of exact type of the type declaration will be accepted, or a TypeError will be thrown. The only exception to this rule is that an integer may be given to a function expecting a float .

To enable strict mode, the declare statement is used with the strict_types declaration:

Caution: Enabling strict mode will also affect return type declarations.

  • Note:

Strict typing applies to function calls made from within the file with strict typing enabled, not to the functions declared within that file. If a file without strict typing enabled makes a call to a function that was defined in a file with strict typing, the caller's preference (weak typing) will be respected, and the value will be coerced.

  • Note:

Strict typing is only defined for scalar type declarations, and as such, requires PHP 7.0.0 or later, as scalar type declarations were added in that version.

Example #10 Strict typing
<?php
 declare( strict_types = 1 );

function  sum ( int $a ,  int $b ) {
    return  $a  +  $b ;
}

 var_dump ( sum ( 1 ,  2 ));
 var_dump ( sum ( 1.5 ,  2.5 ));
?>
以上例程会输出:
int(3)Fatal error: Uncaught TypeError: Argument 1 passed to sum() must be of the type integer, float given, called in - on line 9 and defined in -:4
Stack trace:
#0 -(9): sum(1.5, 2.5)
#1 {main}
  thrown in - on line 4
Example #11 Weak typing
<?php
 function  sum ( int $a ,  int $b ) {
    return  $a  +  $b ;
}

 var_dump ( sum ( 1 ,  2 ));

 // These will be coerced to integers: note the output below!
 var_dump ( sum ( 1.5 ,  2.5 ));
?>
以上例程会输出:
int(3)
int(3)
Example #12 Catching TypeError
<?php
 declare( strict_types = 1 );

function  sum ( int $a ,  int $b ) {
    return  $a  +  $b ;
}

try {
     var_dump ( sum ( 1 ,  2 ));
     var_dump ( sum ( 1.5 ,  2.5 ));
} catch ( TypeError $e ) {
    echo  'Error: ' . $e -> getMessage ();
}
?>
以上例程会输出:
int(3)
Error: Argument 1 passed to sum() must be of the type integer, float given, called in - on line 10
  • 可变数量的参数列表

PHP 在用户自定义函数中支持可变数量的参数列表。在 PHP 5.6 及以上的版本中,由 ... 语法实现;在 PHP 5.5 及更早版本中,使用函数 func_num_args() , func_get_arg() ,和 func_get_args() 。

  • ... in PHP 5.6+

In PHP 5.6 and later, argument lists may include the ... token to denote that the function accepts a variable number of arguments. The arguments will be passed into the given variable as an array; for example:

Example #13 Using ... to access variable arguments
<?php
 function  sum (... $numbers ) {
     $acc  =  0 ;
    foreach ( $numbers  as  $n ) {
         $acc  +=  $n ;
    }
    return  $acc ;
}

echo  sum ( 1 ,  2 ,  3 ,  4 );
?>
以上例程会输出:
10

You can also use ... when calling functions to unpack an array or Traversable variable or literal into the argument list:

Example #14 Using ... to provide arguments
<?php
 function  add ( $a ,  $b ) {
    return  $a  +  $b ;
}

echo  add (...[ 1 ,  2 ]). "\n" ;

 $a  = [ 1 ,  2 ];
echo  add (... $a );
?>
以上例程会输出:
3
3

You may specify normal positional arguments before the ... token. In this case, only the trailing arguments that don't match a positional argument will be added to the array generated by ....

It is also possible to add a type hint before the ... token. If this is present, then all arguments captured by ... must be objects of the hinted class.

Example #15 Type hinted variable arguments
<?php
 function  total_intervals ( $unit ,  DateInterval  ... $intervals ) {
     $time  =  0 ;
    foreach ( $intervals  as  $interval ) {
         $time  +=  $interval -> $unit ;
    }
    return  $time ;
}

 $a  = new  DateInterval ( 'P1D' );
 $b  = new  DateInterval ( 'P2D' );
echo  total_intervals ( 'd' ,  $a ,  $b ). ' days' ;

 // This will fail, since null isn't a DateInterval object.
 echo  total_intervals ( 'd' ,  null );
?>
以上例程会输出:
3 days
Catchable fatal error: Argument 2 passed to total_intervals() must be an instance of DateInterval, null given, called in - on line 14 and defined in - on line 2

Finally, you may also pass variable arguments by reference by prefixing the ... with an ampersand (&).

  • Older versions of PHP

No special syntax is required to note that a function is variadic; however access to the function's arguments must use func_num_args() , func_get_arg() and func_get_args() .

The first example above would be implemented as follows in PHP 5.5 and earlier:

Example #16 Accessing variable arguments in PHP 5.5 and earlier
<?php
 function  sum () {
     $acc  =  0 ;
    foreach ( func_get_args () as  $n ) {
         $acc  +=  $n ;
    }
    return  $acc ;
}

echo  sum ( 1 ,  2 ,  3 ,  4 );
?>
以上例程会输出:
10

(三)返回值

值通过使用可选的返回语句返回。可以返回包括数组和对象的任意类型。返回语句会立即中止函数的运行,并且将控制权交回调用该函数的代码行。更多信息见 return 。

Note:如果省略了 return ,则返回值为 NULL 。

return 的使用

Example #1 return  的使用
<?php
 function  square ( $num )
{
    return  $num  *  $num ;
}
echo  square ( 4 );    // outputs '16'.
?>

函数不能返回多个值,但可以通过返回一个数组来得到类似的效果。

Example #2 返回一个数组以得到多个返回值
<?php
 function  small_numbers ()
{
    return array ( 0 ,  1 ,  2 );
}
list ( $zero ,  $one ,  $two ) =  small_numbers ();
?>

从函数返回一个引用,必须在函数声明和指派返回值给一个变量时都使用引用运算符 &:

Example #3 从函数返回一个引用
<?php
 function & returns_reference ()
{
    return  $someref ;
}

 $newref  =&  returns_reference ();
?>

有关引用的更多信息, 请查看引用的解释。

  • Return type declarations

PHP 7 adds support for return type declarations. Similarly to argument type declarations, return type declarations specify the type of the value that will be returned from a function. The same types are available for return type declarations as are available for argument type declarations.

Strict typing also has an effect on return type declarations. In the default weak mode, returned values will be coerced to the correct type if they are not already of that type. In strong mode, the returned value must be of the correct type, otherwise a TypeError will be thrown.

Note: When overriding a parent method, the child's method must match any return type declaration on the parent. If the parent doesn't define a return type, then the child method may do so.

范例

Example #4 Basic return type declaration
<?php
 function  sum ( $a ,  $b ):  float  {
    return  $a  +  $b ;
}

 // Note that a float will be returned.
 var_dump ( sum ( 1 ,  2 ));
?>
以上例程会输出:
float(3)
Example #5 Strict mode in action
<?php
 declare( strict_types = 1 );

function  sum ( $a ,  $b ):  int  {
    return  $a  +  $b ;
}

 var_dump ( sum ( 1 ,  2 ));
 var_dump ( sum ( 1 ,  2.5 ));
?>
以上例程会输出:
int(3)Fatal error: Uncaught TypeError: Return value of sum() must be of the type integer, float returned in - on line 5 in -:5
Stack trace:
#0 -(9): sum(1, 2.5)
#1 {main}
  thrown in - on line 5
Example #6 Returning an object
<?php
 class  C  {}

function  getC ():  C  {
    return new  C ;
}

 var_dump ( getC ());
?>
以上例程会输出:
object(C)#1 (0) {
}

(四)可变函数

PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。

可变函数不能用于例如 echo , print , unset() , isset() , empty() , include , require 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。

Example #1 可变函数示例
<?php
 function  foo () {
    echo  "In foo()<br />\n" ;
}

function  bar ( $arg  =  '' ) {
    echo  "In bar(); argument was ' $arg '.<br />\n" ;
}

 // 使用 echo 的包装函数
 function  echoit ( $string )
{
    echo  $string ;
}

 $func  =  'foo' ;
 $func ();         // This calls foo()

 $func  =  'bar' ;
 $func ( 'test' );   // This calls bar()

 $func  =  'echoit' ;
 $func ( 'test' );   // This calls echoit()
?>

也可以用可变函数的语法来调用一个对象的方法。

Example #2 可变方法范例
<?php
 class  Foo
 {
    function  Variable ()
    {
         $name  =  'Bar' ;
         $this -> $name ();  // This calls the Bar() method
     }

    function  Bar ()
    {
        echo  "This is Bar" ;
    }
}

 $foo  = new  Foo ();
 $funcname  =  "Variable" ;
 $foo -> $funcname ();    // This calls $foo->Variable()
?>

当调用静态方法时,函数调用要比静态属性优先:

Example #3 Variable 方法和静态属性示例
<?php
 class  Foo
 {
    static  $variable  =  'static property' ;
    static function  Variable ()
    {
        echo  'Method Variable called' ;
    }
}

echo  Foo :: $variable ;  // This prints 'static property'. It does need a $variable in this scope.
 $variable  =  "Variable" ;
 Foo :: $variable ();   // This calls $foo->Variable() reading $variable in this scope.
?>

参见 is_callable() , call_user_func() ,可变变量和 function_exists() 。

(五)内部(内置)函数

PHP 有很多标准的函数和结构。还有一些函数需要和特定地 PHP 扩展模块一起编译,否则在使用它们的时候就会得到一个致命的“未定义函数”错误。例如,要使用 image 函数中的 imagecreatetruecolor() ,需要在编译 PHP 的时候加上 GD 的支持。或者,要使用 mysql_connect() 函数,就需要在编译 PHP 的时候加上 MySQL 支持。有很多核心函数已包含在每个版本的 PHP 中如字符串和变量函数。调用 phpinfo() 或者 get_loaded_extensions() 可以得知 PHP 加载了那些扩展库。同时还应该注意,很多扩展库默认就是有效的。PHP 手册按照不同的扩展库组织了它们的文档。请参阅配置,安装以及各自的扩展库章节以获取有关如何设置 PHP 的信息。

手册中如何阅读函数原型讲解了如何阅读和理解一个函数的原型。确认一个函数将返回什么,或者函数是否直接作用于传递的参数是很重要的。例如, str_replace() 函数将返回修改过的字符串,而 usort() 却直接作用于传递的参数变量本身。手册中,每一个函数的页面中都有关于函数参数、行为改变、成功与否的返回值以及使用条件等信息。了解这些重要的(常常是细微的)差别是编写正确的 PHP 代码的关键。

Note: 如果传递给函数的参数类型与实际的类型不一致,例如将一个 array 传递给一个 string 类型的变量,那么函数的返回值是不确定的。在这种情况下,通常函数会返回 NULL 。但这仅仅是一个惯例,并不一定如此。

参见 function_exists() ,函数参考, get_extension_funcs() 和 dl() 。

(六)匿名函数

匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。

Example #1 匿名函数示例
<?php
 echo  preg_replace_callback ( '~-([a-z])~' , function ( $match ) {
    return  strtoupper ( $match [ 1 ]);
},  'hello-world' );
 // 输出 helloWorld
?>

闭包函数也可以作为变量的值来使用。PHP 会自动把此种表达式转换成内置类 Closure 的对象实例。把一个 closure 对象赋值给一个变量的方式与普通变量赋值的语法是一样的,最后也要加上分号:

Example #2 匿名函数变量赋值示例
<?php
$greet  = function( $name )
{
     printf ( "Hello %s\r\n" ,  $name );
};

 $greet ( 'World' );
 $greet ( 'PHP' );
?>

闭包可以从父作用域中继承变量。 任何此类变量都应该用 use 语言结构传递进去。

Example #3 从父作用域继承变量
<?php
$message  =  'hello' ;

 // 没有 "use"
 $example  = function () {
     var_dump ( $message );
};
echo  $example ();

 // 继承 $message
 $example  = function () use ( $message ) {
     var_dump ( $message );
};
echo  $example ();

 // Inherited variable's value is from when the function
// is defined, not when called
 $message  =  'world' ;
echo  $example ();

 // Reset message
 $message  =  'hello' ;

 // Inherit by-reference
 $example  = function () use (& $message ) {
     var_dump ( $message );
};
echo  $example ();

 // The changed value in the parent scope
// is reflected inside the function call
 $message  =  'world' ;
echo  $example ();

 // Closures can also accept regular arguments
 $example  = function ( $arg ) use ( $message ) {
     var_dump ( $arg  .  ' '  .  $message );
};
 $example ( "hello" );
?>
以上例程的输出类似于:
Notice: Undefined variable: message in /example.php on line 6
NULL
string(5) "hello"
string(5) "hello"
string(5) "hello"
string(5) "world"
string(11) "hello world"

这些变量都必须在函数或类的头部声明。 从父作用域中继承变量与使用全局变量是不同的。全局变量存在于一个全局的范围,无论当前在执行的是哪个函数。而 闭包的父作用域是定义该闭包的函数(不一定是调用它的函数)。示例如下:

Example #4 Closures 和作用域
<?php
 // 一个基本的购物车,包括一些已经添加的商品和每种商品的数量。
// 其中有一个方法用来计算购物车中所有商品的总价格,该方法使
// 用了一个 closure 作为回调函数。
 class  Cart
 {
    const  PRICE_BUTTER   =  1.00 ;
    const  PRICE_MILK     =  3.00 ;
    const  PRICE_EGGS     =  6.95 ;

    protected    $products  = array();
    public function  add ( $product ,  $quantity )
    {
         $this -> products [ $product ] =  $quantity ;
    }
    public function  getQuantity ( $product )
    {
        return isset( $this -> products [ $product ]) ?  $this -> products [ $product ] :
                FALSE ;
    }
    public function  getTotal ( $tax )
    {
         $total  =  0.00 ;
         $callback  =
            function ( $quantity ,  $product ) use ( $tax , & $total )
            {
                 $pricePerItem  =  constant ( __CLASS__  .  "::PRICE_"  .
                     strtoupper ( $product ));
                 $total  += ( $pricePerItem  *  $quantity ) * ( $tax  +  1.0 );
            };
         array_walk ( $this -> products ,  $callback );
        return  round ( $total ,  2 );;
    }
}

 $my_cart  = new  Cart ;

 // 往购物车里添加条目
 $my_cart -> add ( 'butter' ,  1 );
 $my_cart -> add ( 'milk' ,  3 );
 $my_cart -> add ( 'eggs' ,  6 );

 // 打出出总价格,其中有 5% 的销售税.
 print  $my_cart -> getTotal ( 0.05 ) .  "\n" ;
 // 最后结果是 54.29
 ?>

匿名函数目前是通过 Closure 类来实现的。

  • 更新日志
版本 说明
5.4.0 $this 可用于匿名函数。
5.3.0 可以使用匿名函数
  • 注释

Note: 可以在闭包中使用 func_num_args() , func_get_arg() 和 func_get_args() 。

九、类与对象

(一)简介

自 PHP 5 起完全重写了对象模型以得到更佳性能和更多特性。这是自 PHP 4 以来的最大变化。PHP 5 具有完整的对象模型。

PHP 5 中的新特性包括访问控制,抽象类和 final 类与方法,附加的魔术方法,接口,对象复制和类型约束。

PHP 对待对象的方式与引用和句柄相同,即每个变量都持有对象的引用,而不是整个对象的拷贝。参见对象和引用。

Tip:请参见用户空间命名指南。

(二)基本概念

  • class

每个类的定义都以关键字 class 开头,后面跟着类名,后面跟着一对花括号,里面包含有类的属性与方法的定义。

类名可以是任何非 PHP 保留字的合法标签。一个合法类名以字母或下划线开头,后面跟着若干字母,数字或下划线。以正则表达式表示为:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

一个类可以包含有属于自己的常量,变量(称为“属性”)以及函数(称为“方法”)。

Example #1 简单的类定义
<?php
 class  SimpleClass
 {
     // property declaration
     public  $var  =  'a default value' ;

     // method declaration
     public function  displayVar () {
        echo  $this -> var ;
    }
}
?>

当一个方法在类定义内部被调用时,有一个可用的伪变量 $this 。 $this 是一个到主叫对象的引用(通常是该方法所从属的对象,但如果是从第二个对象静态调用时也可能是另一个对象)。

Example #2 $this  伪变量的示例
<?php
 class  A
 {
    function  foo ()
    {
        if (isset( $this )) {
            echo  '$this is defined (' ;
            echo  get_class ( $this );
            echo  ")\n" ;
        } else {
            echo  "\$this is not defined.\n" ;
        }
    }
}

class  B
 {
    function  bar ()
    {
         // Note: the next line will issue a warning if E_STRICT is enabled.
         A :: foo ();
    }
}

 $a  = new  A ();
 $a -> foo ();

 // Note: the next line will issue a warning if E_STRICT is enabled.
 A :: foo ();
 $b  = new  B ();
 $b -> bar ();

 // Note: the next line will issue a warning if E_STRICT is enabled.
 B :: bar ();
?>
以上例程会输出:
$this is defined (A)
$this is not defined.
$this is defined (B)
$this is not defined.
  • new

要创建一个类的实例,必须使用 new 关键字。当创建新对象时该对象总是被赋值,除非该对象定义了构造函数并且在出错时抛出了一个异常。类应在被实例化之前定义(某些情况下则必须这样)。

如果在 new 之后跟着的是一个包含有类名的字符串,则该类的一个实例被创建。如果该类属于一个名字空间,则必须使用其完整名称。

Example #3 创建一个实例
<?php
$instance  = new  SimpleClass ();

 // 也可以这样做:
 $className  =  'Foo' ;
 $instance  = new  $className ();  // Foo()
?>

在类定义内部,可以用 new self 和 new parent 创建新对象。

当把一个对象已经创建的实例赋给一个新变量时,新变量会访问同一个实例,就和用该对象赋值一样。此行为和给函数传递入实例时一样。可以用克隆给一个已创建的对象建立一个新实例。

Example #4 对象赋值
<?php
$instance  = new  SimpleClass ();
 $assigned    =   $instance ;
 $reference   =&  $instance ;
 $instance -> var  =  '$assigned will have this value' ;
 $instance  =  null ;  // $instance and $reference become null
 var_dump ( $instance );
 var_dump ( $reference );
 var_dump ( $assigned );
?>
以上例程会输出:
NULL
NULL
object(SimpleClass)#1 (1) {
   ["var"]=>
     string(30) "$assigned will have this value"
}

PHP 5.3.0 引进了两个新方法来创建一个对象的实例:

Example #5 创建新对象
<?php
 class  Test
 {
    static public function  getNew ()
    {
        return new static;
    }
}

class  Child  extends  Test
 {}

 $obj1  = new  Test ();
 $obj2  = new  $obj1 ;
 var_dump ( $obj1  !==  $obj2 );

 $obj3  =  Test :: getNew ();
 var_dump ( $obj3  instanceof  Test );

 $obj4  =  Child :: getNew ();
 var_dump ( $obj4  instanceof  Child );
?>
以上例程会输出:
bool(true)
bool(true)
bool(true)
  • extends

一个类可以在声明中用 extends 关键字继承另一个类的方法和属性。PHP不支持多重继承,一个类只能继承一个基类。

被继承的方法和属性可以通过用同样的名字重新声明被覆盖。但是如果父类定义方法时使用了 final,则该方法不可被覆盖。可以通过 parent:: 来访问被覆盖的方法或属性。

当覆盖方法时,参数必须保持一致否则 PHP 将发出 E_STRICT 级别的错误信息。但构造函数例外,构造函数可在被覆盖时使用不同的参数。

Example #6 简单的类继承
<?php
 class  ExtendClass  extends  SimpleClass
 {
     // Redefine the parent method
     function  displayVar ()
    {
        echo  "Extending class\n" ;
         parent :: displayVar ();
    }
}

 $extended  = new  ExtendClass ();
 $extended -> displayVar ();
?>
以上例程会输出:
Extending class
a default value
  • ::class

自 PHP 5.5 起,关键词 class 也可用于类名的解析。使用 ClassName::class 你可以获取一个字符串,包含了类 ClassName 的完全限定名称。这对使用了 命名空间 的类尤其有用。

Example #7 类名的解析
<?php
 namespace  NS  {
    class  ClassName  {
    }
    echo  ClassName ::class;
}
?>
以上例程会输出:
NS\ClassName

(三)属性

类的变量成员叫做“属性”,或者叫“字段”、“特征”,在本文档统一称为“属性”。属性声明是由关键字 public,protected 或者 private 开头,然后跟一个普通的变量声明来组成。属性中的变量可以初始化,但是初始化的值必须是常数,这里的常数是指 PHP 脚本在编译阶段时就可以得到其值,而不依赖于运行时的信息才能求值。

有关 public,protected 和 private 的更多详细信息,请查看访问控制(可见性)。

  • Note:为了向后兼容 PHP 4,PHP 5 声明属性依然可以直接使用关键字 var 来替代(或者附加于)public,protected 或 private。但是已不再需要 var 了。在 PHP 5.0 到 5.1.3,var 会被认为是废弃的,而且抛出 E_STRICT 警告,但是 5.1.3 之后就不再认为是废弃,也不会抛出警告。

如果直接使用 var 声明属性,而没有用 public,protected 或 private 之一,PHP 5 会将其视为 public。

在类的成员方法里面,可以用 ->(对象运算符): $this->property (其中 property 是该属性名)这种方式来访问非静态属性。静态属性则是用 ::(双冒号): self::$property 来访问。更多静态属性与非静态属性的区别参见 Static 关键字。

当一个方法在类定义内部被调用时,有一个可用的伪变量 $this 。 $this 是一个到主叫对象的引用(通常是该方法所从属的对象,但如果是从第二个对象静态调用时也可能是另一个对象)。

Example #1 属性声明
<?php
 class  SimpleClass
 {
    // 错误的属性声明
    public  $var1  =  'hello '  .  'world' ;
   public  $var2  = <<<EOD
 hello world
 EOD;
   public  $var3  =  1 + 2 ;
   public  $var4  =  self :: myStaticMethod ();
   public  $var5  =  $myVar ;

    // 正确的属性声明
    public  $var6  =  myConstant ;
   public  $var7  = array( true ,  false );

    //在 PHP 5.3.0 及之后,下面的声明也正确
    public  $var8  = <<<'EOD'
 hello world
 EOD;
}
?>

Note:更多关于类/对象的处理函数,请查看类/对象函数。

跟 heredocs 不同,nowdocs 可在任何静态数据上下文中使用,包括属性声明。

Example #2 示例:使用 nowdoc 初始化属性
<?php
 class  foo  {
    // 自 5.3.0 起
    public  $bar  = <<<'EOT'
 bar
 EOT;
}
?>
  • Note: Nowdoc 支持是在 PHP 5.3.0 新增的。

(四)类常量

可以把在类中始终保持不变的值定义为常量。在定义和使用常量的时候不需要使用 $ 符号。

常量的值必须是一个定值,不能是变量,类属性,数学运算的结果或函数调用。

接口(interface)中也可以定义常量。更多示例见文档中的接口部分。

自 PHP 5.3.0 起,可以用一个变量来动态调用类。但该变量的值不能为关键字(如 self,parent 或 static)。

Example #1 定义和使用一个类常量
<?php
 class  MyClass
 {
    const  constant  =  'constant value' ;

    function  showConstant () {
        echo   self :: constant  .  "\n" ;
    }
}

echo  MyClass :: constant  .  "\n" ;

 $classname  =  "MyClass" ;
echo  $classname :: constant  .  "\n" ;  // 自 5.3.0 起

 $class  = new  MyClass ();
 $class -> showConstant ();

echo  $class :: constant . "\n" ;  // 自 PHP 5.3.0 起
?>
Example #2 静态数据示例
<?php
 class  foo  {
     // 自 PHP 5.3.0 起
     const  bar  = <<<'EOT'
 bar
 EOT;
}
?>

和 heredoc 不同,nowdoc 可以用在任何静态数据中。

  • Note: Nowdoc 支持是在 PHP 5.3.0 新增的。

(五)自动加载类

很多开发者写面向对象的应用程序时对每个类的定义建立一个 PHP 源文件。一个很大的烦恼是不得不在每个脚本开头写一个长长的包含文件列表(每个类一个文件)。

在 PHP 5 中,不再需要这样了。可以定义一个 __autoload() 函数,它会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。

  • Tip: spl_autoload_register() 提供了一种更加灵活的方式来实现类的自动加载。因此,不再建议使用 __autoload() 函数,在以后的版本中它可能被弃用。

  • Note: 在 5.3.0 版之前,autoload 函数抛出的异常不能被 catch 语句块捕获并会导致一个致命错误。从 5.3.0+ 之后,autoload 函数抛出的异常可以被 catch 语句块捕获,但需要遵循一个条件。如果抛出的是一个自定义异常,那么必须存在相应的自定义异常类。__autoload 函数可以递归的自动加载自定义异常类。

  • Note: 自动加载不可用于 PHP 的 CLI 交互模式。

  • Note: 如果类名比如被用于 call_user_func() ,则它可能包含一些危险的字符,比如 ../。 建议您在这样的函数中不要使用用户的输入,起码需要在 __autoload() 时验证下输入.

Example #1 自动加载示例

本例尝试分别从 MyClass1.php 和 MyClass2.php 文件中加载 MyClass1 和 MyClass2 类。
<?php
 function  __autoload ( $class_name ) {
    require_once  $class_name  .  '.php' ;
}

 $obj   = new  MyClass1 ();
 $obj2  = new  MyClass2 ();
?>
Example #2 另一个例子
本例尝试加载接口 ITest。
<?php

 function  __autoload ( $name ) {
     var_dump ( $name );
}

class  Foo  implements  ITest  {
}

 /*
string(5) "ITest"

Fatal error: Interface 'ITest' not found in ...
*/
?>
Example #3 自动加载在 PHP 5.3.0+ 中的异常处理
本例抛出一个异常并在 try/catch 语句块中演示。
<?php
 function  __autoload ( $name ) {
    echo  "Want to load  $name .\n" ;
    throw new  Exception ( "Unable to load  $name ." );
}

try {
     $obj  = new  NonLoadableClass ();
} catch ( Exception $e ) {
    echo  $e -> getMessage (),  "\n" ;
}
?>
以上例程会输出:
Want to load NonLoadableClass.
Unable to load NonLoadableClass.
Example #4 自动加载在 PHP 5.3.0+ 中的异常处理 - 没有自定义异常机制
本例将一个异常抛给不存在的自定义异常处理函数.
<?php
 function  __autoload ( $name ) {
    echo  "Want to load  $name .\n" ;
    throw new  MissingException ( "Unable to load  $name ." );
}

try {
     $obj  = new  NonLoadableClass ();
} catch ( Exception $e ) {
    echo  $e -> getMessage (),  "\n" ;
}
?>
以上例程会输出:
Want to load NonLoadableClass.
Want to load MissingException.Fatal error: Class 'MissingException' not found in testMissingException.php on line 4

参见

  1. unserialize()
  2. unserialize_callback_func
  3. spl_autoload()
  4. spl_autoload_register()

(六)构造函数和析构函数

构造函数
void  __construct  ([ mixed  $args  [, $...  ]] )

PHP 5 允行开发者在一个类中定义一个方法作为构造函数。具有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象之前做一些初始化工作。

  • Note: 如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct() 。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)。
Example #1 使用新标准的构造函数
<?php
 class  BaseClass  {
   function  __construct () {
       print  "In BaseClass constructor\n" ;
   }
}

class  SubClass  extends  BaseClass  {
   function  __construct () {
        parent :: __construct ();
       print  "In SubClass constructor\n" ;
   }
}

class  OtherSubClass  extends  BaseClass  {
     // inherits BaseClass's constructor
 }

 // In BaseClass constructor
 $obj  = new  BaseClass ();

 // In BaseClass constructor
// In SubClass constructor
 $obj  = new  SubClass ();

 // In BaseClass constructor
 $obj  = new  OtherSubClass ();
?>

为了实现向后兼容性,如果 PHP 5 在类中找不到 construct() 函数并且也没有从父类继承一个的话,它就会尝试寻找旧式的构造函数,也就是和类同名的函数。因此唯一会产生兼容性问题的情况是:类中已有一个名为 construct() 的方法却被用于其它用途时。

与其它方法不同,当 construct() 被与父类 construct() 具有不同参数的方法覆盖时,PHP 不会产生一个 E_STRICT 错误信息。

自 PHP 5.3.3 起,在命名空间中,与类名同名的方法不再作为构造函数。这一改变不影响不在命名空间中的类。

Example #2 Constructors in namespaced classes
<?php
 namespace  Foo ;
class  Bar  {
    public function  Bar () {
         // treated as constructor in PHP 5.3.0-5.3.2
        // treated as regular method as of PHP 5.3.3
     }
}
?>
析构函数
void  __destruct  ( void )

PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。

Example #3 析构函数示例
<?php
 class  MyDestructableClass  {
   function  __construct () {
       print  "In constructor\n" ;
        $this -> name  =  "MyDestructableClass" ;
   }

   function  __destruct () {
       print  "Destroying "  .  $this -> name  .  "\n" ;
   }
}

 $obj  = new  MyDestructableClass ();
?>

和构造函数一样,父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::__destruct() 。此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的。

析构函数即使在使用 exit() 终止脚本运行时也会被调用。在析构函数中调用 exit() 将会中止其余关闭操作的运行。

  • Note: 析构函数在脚本关闭时调用,此时所有的 HTTP 头信息已经发出。脚本关闭时的工作目录有可能和在 SAPI(如 apache)中时不同。

  • Note: 试图在析构函数(在脚本终止时被调用)中抛出一个异常会导致致命错误。

(七)访问控制(可见性)

对属性或方法的访问控制,是通过在前面添加关键字 public(公有),protected(受保护)或 private(私有)来实现的。被定义为公有的类成员可以在任何地方被访问。被定义为受保护的类成员则可以被其自身以及其子类和父类访问。被定义为私有的类成员则只能被其定义所在的类访问.

属性的访问控制

类属性必须定义为公有,受保护,私有之一。如果用 var 定义,则被视为公有。

Example #1 属性声明
<?php
 /**
 * Define MyClass
 */
 class  MyClass
 {
    public  $public  =  'Public' ;
    protected  $protected  =  'Protected' ;
    private  $private  =  'Private' ;

    function  printHello ()
    {
        echo  $this -> public ;
        echo  $this -> protected ;
        echo  $this -> private ;
    }
}

 $obj  = new  MyClass ();
echo  $obj -> public ;  // 这行能被正常执行
 echo  $obj -> protected ;  // 这行会产生一个致命错误
 echo  $obj -> private ;  // 这行也会产生一个致命错误
 $obj -> printHello ();  // 输出 Public、Protected 和 Private


/**
 * Define MyClass2
 */
 class  MyClass2  extends  MyClass
 {
     // 可以对 public 和 protected 进行重定义,但 private 而不能
     protected  $protected  =  'Protected2' ;

    function  printHello ()
    {
        echo  $this -> public ;
        echo  $this -> protected ;
        echo  $this -> private ;
    }
}

 $obj2  = new  MyClass2 ();
echo  $obj2 -> public ;  // 这行能被正常执行
 echo  $obj2 -> private ;  // 未定义 private
 echo  $obj2 -> protected ;  // 这行会产生一个致命错误
 $obj2 -> printHello ();  // 输出 Public、Protected2 和 Undefined
?>

Note: 为了兼容性考虑,在 PHP 4 中使用 var 关键字对变量进行定义的方法在 PHP 5 中仍然有效(只是作为 public 关键字的一个别名)。在 PHP 5.1.3 之前的版本,该语法会产生一个 E_STRICT 警告。

  • 方法的访问控制

类中的方法可以被定义为公有,私有或受保护。如果没有设置这些关键字,则该方法默认为公有。

Example #2 方法声明
<?php
 /**
 * Define MyClass
 */
 class  MyClass
 {
     // 声明一个公有的构造函数
     public function  __construct () { }

     // 声明一个公有的方法
     public function  MyPublic () { }

     // 声明一个受保护的方法
     protected function  MyProtected () { }

     // 声明一个私有的方法
     private function  MyPrivate () { }

     // 此方法为公有
     function  Foo ()
    {
         $this -> MyPublic ();
         $this -> MyProtected ();
         $this -> MyPrivate ();
    }
}

 $myclass  = new  MyClass ;
 $myclass -> MyPublic ();  // 这行能被正常执行
 $myclass -> MyProtected ();  // 这行会产生一个致命错误
 $myclass -> MyPrivate ();  // 这行会产生一个致命错误
 $myclass -> Foo ();  // 公有,受保护,私有都可以执行


/**
 * Define MyClass2
 */
 class  MyClass2  extends  MyClass
 {
     // 此方法为公有
     function  Foo2 ()
    {
         $this -> MyPublic ();
         $this -> MyProtected ();
         $this -> MyPrivate ();  // 这行会产生一个致命错误
     }
}

 $myclass2  = new  MyClass2 ;
 $myclass2 -> MyPublic ();  // 这行能被正常执行
 $myclass2 -> Foo2 ();  // 公有的和受保护的都可执行,但私有的不行

 class  Bar
 {
    public function  test () {
         $this -> testPrivate ();
         $this -> testPublic ();
    }

    public function  testPublic () {
        echo  "Bar::testPublic\n" ;
    }
    private function  testPrivate () {
        echo  "Bar::testPrivate\n" ;
    }
}

class  Foo  extends  Bar 
 {
    public function  testPublic () {
        echo  "Foo::testPublic\n" ;
    }
    private function  testPrivate () {
        echo  "Foo::testPrivate\n" ;
    }
}

 $myFoo  = new  foo ();
 $myFoo -> test ();  // Bar::testPrivate 
                // Foo::testPublic
?>
  • 其它对象的访问控制

同一个类的对象即使不是同一个实例也可以互相访问对方的私有与受保护成员。这是由于在这些对象的内部具体实现的细节都是已知的。

Example #3 访问同一个对象类型的私有成员
<?php
 class  Test
 {
    private  $foo ;

    public function  __construct ( $foo )
    {
         $this -> foo  =  $foo ;
    }

    private function  bar ()
    {
        echo  'Accessed the private method.' ;
    }

    public function  baz ( Test $other )
    {
         // We can change the private property:
         $other -> foo  =  'hello' ;
         var_dump ( $other -> foo );

         // We can also call the private method:
         $other -> bar ();
    }
}

 $test  = new  Test ( 'test' );

 $test -> baz (new  Test ( 'other' ));
?>
以上例程会输出:
string(5) "hello"
Accessed the private method.

(八)对象继承

继承已为大家所熟知的一个程序设计特性,PHP 的对象模型也使用了继承。继承将会影响到类与类,对象与对象之间的关系。

比如,当扩展一个类,子类就会继承父类所有公有的和受保护的方法。除非子类覆盖了父类的方法,被继承的方法都会保留其原有功能。

继承对于功能的设计和抽象是非常有用的,而且对于类似的对象增加新功能就无须重新再写这些公用的功能。

Note:除非使用了自动加载,否则一个类必须在使用之前被定义。如果一个类扩展了另一个,则父类必须在子类之前被声明。此规则适用于类继承其它类与接口。

Example #1 继承示例
<?php
 class  foo
 {
    public function  printItem ( $string ) 
    {
        echo  'Foo: '  .  $string  .  PHP_EOL ;
    }
    public function  printPHP ()
    {
        echo  'PHP is great.'  .  PHP_EOL ;
    }
}

class  bar  extends  foo
 {
    public function  printItem ( $string )
    {
        echo  'Bar: '  .  $string  .  PHP_EOL ;
    }
}

 $foo  = new  foo ();
 $bar  = new  bar ();
 $foo -> printItem ( 'baz' );  // Output: 'Foo: baz'
 $foo -> printPHP ();        // Output: 'PHP is great' 
 $bar -> printItem ( 'baz' );  // Output: 'Bar: baz'
 $bar -> printPHP ();        // Output: 'PHP is great'
?>

(九)范围解析操作符(::)

范围解析操作符(也可称作 Paamayim Nekudotayim)或者更简单地说是一对冒号,可以用于访问静态成员,类常量,还可以用于覆盖类中的属性和方法。

当在类定义之外引用到这些项目时,要使用类名。

自 PHP 5.3.0 起,可以通过变量来引用类,该变量的值不能是关键字(如 self,parent 和 static)。

把 Paamayim Nekudotayim 选作双冒号操作符的名字似乎有些奇怪。然而,这是 Zend 开发小组在写 Zend Engine 0.5(被用于 PHP 3 中)时所作出的决定。事实上这个词在希伯莱文就是双冒号的意思。

Example #1 在类的外部使用 :: 操作符
<?php
 class  MyClass  {
    const  CONST_VALUE  =  'A constant value' ;
}

 $classname  =  'MyClass' ;
echo  $classname :: CONST_VALUE ;  // 自 PHP 5.3.0 起

 echo  MyClass :: CONST_VALUE ;
?>

self , parent 和 static 这三个特殊的关键字是用于在类定义的内部对其属性或方法进行访问的。

Example #2 在类定义内部使用 ::
<?php
 class  OtherClass  extends  MyClass
 {
    public static  $my_static  =  'static var' ;

    public static function  doubleColon () {
        echo  parent :: CONST_VALUE  .  "\n" ;
        echo  self :: $my_static  .  "\n" ;
    }
}

 $classname  =  'OtherClass' ;
echo  $classname :: doubleColon ();  // 自 PHP 5.3.0 起

 OtherClass :: doubleColon ();
?>

当一个子类覆盖其父类中的方法时,PHP 不会调用父类中已被覆盖的方法。是否调用父类的方法取决于子类。这种机制也作用于构造函数和析构函数,重载以及魔术方法。

Example #3 调用父类的方法
<?php
 class  MyClass
 {
    protected function  myFunc () {
        echo  "MyClass::myFunc()\n" ;
    }
}

class  OtherClass  extends  MyClass
 {
     // 覆盖了父类的定义
     public function  myFunc ()
    {
         // 但还是可以调用父类中被覆盖的方法
         parent :: myFunc ();
        echo  "OtherClass::myFunc()\n" ;
    }
}

 $class  = new  OtherClass ();
 $class -> myFunc ();
?>

参见 伪变量的示例。

(十)Static(静态)关键字

(十一)抽象类

(十二)对象接口

(十三)Traits

(十四)Anonymous classes

(十五)重载

(十六)遍历对象

(十七)魔术方法

(十八)Final 关键字

(十九)对象复制

(二十)对象比较

(二十一)类型约束

(二十二)后期静态绑定

(二十三)对象和引用

(二十四)对象序列化

(二十五)OOP 变更日志

十、命名空间

(一)命名空间概述

(二)定义命名空间

(三)定义子命名空间

(四)在同一个文件中定义多个命名空间

(五)使用命名空间:基础

(六)命名空间和动态语言特征

(七)namespace关键字和__NAMESPACE__常量

(八)使用命名空间:别名/导入

(九)全局空间

(十)使用命名空间:后备全局函数/常量

(十一)名称解析规则

(十二)FAQ: things you need to know about namespaces

十一、Errors

(一)Basics

(二)Errors in PHP 7

十二、异常处理

(一)扩展(extend) PHP 内置的异常处理类

十三、生成器

(一)生成器总览

(二)生成器语法

(三)Comparing generators with Iterator objects

十四、引用的解释

(一)引用是什么

(二)引用做什么

(三)引用不是什么

(四)引用传递

(五)引用返回

(六)取消引用

(七)引用定位

十五、预定义变量

(一)超全局变量 — 超全局变量是在全部作用域中始终可用的内置变量

(二)$GLOBALS — 引用全局作用域中可用的全部变量

(三)$_SERVER — 服务器和执行环境信息

(四)$_GET — HTTP GET 变量

(五)$_POST — HTTP POST 变量

(六)$_FILES — HTTP 文件上传变量

(七)$_REQUEST — HTTP Request 变量

(八)$_SESSION — Session 变量

(九)$_ENV — 环境变量

(十)$_COOKIE — HTTP Cookies

(十一)$php_errormsg — 前一个错误信息

(十二)$HTTP_RAW_POST_DATA — 原生POST数据

(十三)$http_response_header — HTTP 响应头

(十四)$argc — 传递给脚本的参数数目

(十五)$argv — 传递给脚本的参数数组

十六、预定义异常

(一)Exception

(二)ErrorException

十七、预定义接口

(一)遍历 — Traversable(遍历)接口

(二)迭代器 — Iterator(迭代器)接口

(三)聚合式迭代器 — IteratorAggregate(聚合式迭代器)接口

(四)数组式访问 — ArrayAccess(数组式访问)接口

(五)序列化 — 序列化接口

(六)Closure — Closure 类

(七)生成器 — 生成器类

十八、上下文(Context)选项和参数

(一)套接字上下文选项 — 套接字上下文选项列表

(二)HTTP context 选项 — HTTP context 的选项列表

(三)FTP context options — FTP context option listing

(四)SSL 上下文选项 — SSL 上下文选项清单

(五)CURL context options — CURL 上下文选项列表

(六)Phar 上下文(context)选项 — Phar 上下文(context)选项列表

(七)MongoDB context options — MongoDB context option listing

(八)Context 参数 — Context 参数列表

十九、支持的协议和封装协议

(一)file:// — 访问本地文件系统

(二)http:// — 访问 HTTP(s) 网址

(三)ftp:// — 访问 FTP(s) URLs

(四)php:// — 访问各个输入/输出流(I/O streams)

(五)zlib:// — 压缩流

(六)data:// — 数据(RFC 2397)

(七)glob:// — 查找匹配的文件路径模式

(八)phar:// — PHP 归档

(九)ssh2:// — Secure Shell 2

(十)rar:// — RAR

(十一)ogg:// — 音频流

(十二)expect:// — 处理交互式的流

文章目录