PHP语言参考-命名空间/异常处理/引用/预定义变量/预定义异常/预定义接口

一、命名空间

* 命名空间的作用

1、用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。

2、为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

namespace my\name; // 参考 "定义命名空间" 小节

class MyClass {}
function myfunction() {}
const MYCONST = 1;

$a = new MyClass;
$c = new \my\name\MyClass; // 参考 "全局空间" 小节

$a = strlen('hi'); // 参考 "使用命名空间:后备全局函数/常量" 小节

$d = namespace\MYCONST; // 参考 "namespace操作符和__NAMESPACE__常量” 小节

$d = __NAMESPACE__ . '\MYCONST';
echo constant($d); // 参考 "命名空间和动态语言特征" 小节

 

* 定义命名空间

PHP代码都可以包含在命名空间中,但只有三种类型的代码受命名空间的影响,它们是:类,函数和常量。命名空间通过关键字namespace来声明。如果一个文件中包含命名空间,它必须在其它所有代码之前声明命名空间。(定义源文件编码方式的 declare语句除外)

declare(encoding='UTF-8');
namespace
MyProject; const CONNECT_OK = 1; class Connection { /* ... */ } function connect() { /* ... */ }

* 子命名空间

与目录和文件的关系很象,PHP 命名空间也允许指定层次化的命名空间的名称。因此,命名空间的名字可以使用分层次的方式定义。如 namespace MyProject\Sub\Level;

* 同文件多命名空间

namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace AnotherProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

将全局的非命名空间中的代码与命名空间中的代码组合在一起,只能使用大括号形式的语法。全局代码必须用一个不带名称的 namespace 语句加上大括号括起来,开始的declare语句外,命名空间的括号外不得有任何PHP代码。

 

* 使用命名空间

在一个命名空间中,当 PHP 遇到一个非限定的类、函数或常量名称时,它使用不同的优先策略来解析该名称。类名称总是解析到当前命名空间中的名称。因此在访问系统内部或不包含在命名空间中的类名称时,必须使用完全限定名称

非限定名称,或不包含前缀的类名称;$a=new foo();

限定名称,或包含前缀的名称;$a = new subnamespace\foo();

完全限定名称,或包含了全局前缀操作符的名称;$a = new \currentnamespace\foo();

 

访问系统内部或不包含在命名空间中的类名称时,必须使用完全限定名称

对于函数和常量来说,如果当前命名空间中不存在该函数或常量,PHP 会退而使用全局空间中的函数或常量

 

* 命名空间和动态语言特征

在动态的类名称、函数名称或常量名称中,限定名称和完全限定名称没有区别,因此其前导的反斜杠是不必要的。 

 

* namespace关键字和__NAMESPACE__常量

PHP支持两种抽象的访问当前命名空间内部元素的方法,__NAMESPACE__魔术常量和namespace关键字。常量__ NAMESPACE__的值是包含当前命名空间名称的字符串。在全局的,不包括在任何命名空间中的代码,它包含一个空的字符串。

关键字 namespace 可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的 self 操作符 。

 

* 命名空间别名及导入

别名是通过操作符 use ..as..来实现的.一行可包含多个use语句

namespace foo;
use My\Full\Classname as Another;

// 下面的例子与 use My\Full\NSname as NSname 相同
use My\Full\NSname;

// 导入一个全局类
use \ArrayObject;

$obj = new namespace\Another; // 实例化 foo\Another 对象
$obj = new Another; // 实例化 My\Full\Classname 对象
NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func
$a = new ArrayObject(array(1)); // 实例化 ArrayObject 对象
// 如果不使用 "use \ArrayObject" ,则实例化一个 foo\ArrayObject 对象

 

* 全局空间

如果没有定义任何命名空间,所有的类与函数的定义都是在全局空间,在名称前加上前缀 \ 表示该名称是全局空间中的名称。

 

* 名称解析规则

命名空间名称定义
非限定名称Unqualified name:名称中不包含命名空间分隔符的标识符,例如 Foo

限定名称Qualified name :名称中含有命名空间分隔符的标识符,例如 Foo\Bar

完全限定名称Fully qualified name :名称中包含命名空间分隔符,并以命名空间分隔符开始的标识符,例如 \Foo\Bar。 namespace\Foo 也是一个完全限定名称。


名称解析遵循下列规则:

# 对完全限定名称的函数,类和常量的调用在编译时解析。例如 new \A\B 解析为类 A\B。
# 所有的非限定名称和限定名称(非完全限定名称)根据当前的导入规则在编译时进行转换。例如,如果命名空间 A\B\C 被导入为 C,那么对 C\D\e() 的调用就会被转换为 A\B\C\D\e()。
# 在命名空间内部,所有的没有根据导入规则转换的限定名称均会在其前面加上当前的命名空间名称。例如,在命名空间 A\B 内部调用 C\D\e(),则 C\D\e() 会被转换为 A\B\C\D\e() 。
# 非限定类名根据当前的导入规则在编译时转换(用全名代替短的导入名称)。例如,如果命名空间 A\B\C 导入为C,则 new C() 被转换为 new A\B\C() 。
# 在命名空间内部(例如A\B),对非限定名称的函数调用是在运行时解析的。例如对函数 foo() 的调用是这样解析的:
## 在当前命名空间中查找名为 A\B\foo() 的函数
## 尝试查找并调用 全局(global) 空间中的函数 foo()。
在命名空间(例如A\B)内部对非限定名称或限定名称类(非完全限定名称)的调用是在运行时解析的。下面是调用 new C() 及 new D\E() 的解析过程: new C()的解析:
## 在当前命名空间中查找A\B\C类。
## 尝试自动装载类A\B\C。
new D\E()的解析:
在类名称前面加上当前命名空间名称变成:A\B\D\E,然后查找该类。
## 尝试自动装载类 A\B\D\E。
## 为了引用全局命名空间中的全局类,必须使用完全限定名称 new \C()。

 

二、异常处理

用户可以用自定义的异常处理类来扩展 PHP 内置的异常处理。

* 内置的异常处理类

class Exception
{
    protected $message = 'Unknown exception';   // 异常信息
    protected $code = 0;                        // 用户自定义异常代码
    protected $file;                            // 发生异常的文件名
    protected $line;                            // 发生异常的代码行号

    function __construct($message = null, $code = 0);

    final function getMessage();                // 返回异常信息
    final function getCode();                   // 返回异常代码
    final function getFile();                   // 返回发生异常的文件名
    final function getLine();                   // 返回发生异常的代码行号
    final function getTrace();                  // backtrace() 数组
    final function getTraceAsString();          // 已格成化成字符串的 getTrace() 信息

    /* 可重载的方法 */
    function __toString();                       

* 扩展的异常处理类

/**
 * 自定义一个异常处理类
 */
class MyException extends Exception
{
    // 重定义构造器使 message 变为必须被指定的属性
    public function __construct($message, $code = 0) {
        // 自定义的代码

        // 确保所有变量都被正确赋值
        parent::__construct($message, $code);
    }

    // 自定义字符串输出的样式
    public function __toString() {
        return __CLASS__ . ": [{$this->code}]: {$this->message}\n";
    }

    public function customFunction() {
        echo "A Custom function for this type of exception\n";
    }
}


/**
 * 创建一个用于测试异常处理机制的类
 */
class TestException
{
    public $var;

    const THROW_NONE    = 0;
    const THROW_CUSTOM  = 1;
    const THROW_DEFAULT = 2;

    function __construct($avalue = self::THROW_NONE) {

        switch ($avalue) {
            case self::THROW_CUSTOM:
                // 抛出自定义异常
                throw new MyException('1 is an invalid parameter', 5);
                break;

            case self::THROW_DEFAULT:
                // 抛出默认的异常
                throw new Exception('2 isnt allowed as a parameter', 6);
                break;

            default:
                // 没有异常的情况下,创建一个对象
                $this->var = $avalue;
                break;
        }
    }
}


// 例子 1
try {
    $o = new TestException(TestException::THROW_CUSTOM);
} catch (MyException $e) {      // 捕获异常
    echo "Caught my exception\n", $e;
    $e->customFunction();
} catch (Exception $e) {        // 被忽略
    echo "Caught Default Exception\n", $e;
}

// 执行后续代码
var_dump($o);
echo "\n\n";


// 例子 2
try {
    $o = new TestException(TestException::THROW_DEFAULT);
} catch (MyException $e) {      // 不能匹配异常的种类,被忽略
    echo "Caught my exception\n", $e;
    $e->customFunction();
} catch (Exception $e) {        // 捕获异常
    echo "Caught Default Exception\n", $e;
}

// 执行后续代码
var_dump($o);
echo "\n\n";


// 例子 3
try {
    $o = new TestException(TestException::THROW_CUSTOM);
} catch (Exception $e) {        // 捕获异常
    echo "Default Exception caught\n", $e;
}

// 执行后续代码
var_dump($o);
echo "\n\n";


// 例子 4
try {
    $o = new TestException();
} catch (Exception $e) {        // 没有异常,被忽略
    echo "Default Exception caught\n", $e;
}

// 执行后续代码
var_dump($o);
echo "\n\n";

 

三、引用

引用允许用两个变量来指向同一个内容,引用不是指针

$a =& $b;

引用返回用在当想用函数找到引用应该被绑定在哪一个变量上面时。不要用返回引用来增加性能,引擎足够聪明来自己进行优化。仅在有合理的技术原因时才返回引用 

不用 & 运算符导致对象生成了一个拷贝。如果在类中用 $this,它将作用于该类当前的实例。没有用 &的赋值将拷贝这个实例(例如对象)并且 $this将作用于这个拷贝上,这并不总是想要的结果。由于性能和内存消耗的问题,通常只想工作在一个实例上面。

尽管可以用 @ 运算符来抑制构造函数中的任何错误信息,例如用 @new,但用 &new 语句时这不起效果

* 引用传递

 

 * 引用返回

 

class foo {
    public $value = 42;

    public function &getValue() {
        return $this->value;
    }
}

$obj = new foo;
$myValue = &$obj->getValue(); // $myValue is a reference to $obj->value, which is 42.
$obj->value = 2;
echo $myValue;                // prints the new value of $obj->value, i.e. 2.

参数传递不同,这里必须在两个地方都用 &符号——指出返回的是一个引用,而不是通常的一个拷贝

 

* 取消引用

当 unset 一个引用,只是断开了变量名和变量内容之间的绑定。这并不意味着变量内容被销毁。

 

* 引用定位

global引用

$this引用

 

四、预定义变量

 * 超全局变量

在全部作用域中始终可用的内置变量

■$GLOBALS — 引用全局作用域中可用的全部变量
■$_SERVER — 服务器和执行环境信息

$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建

#PHP_SELF: 当前执行脚本的文件名,与 document root 有关
#__FILE__: 常量包含当前文件的完整路径和文件名
#argv: 传递给该脚本的参数的数组。
#argc: 包含命令行模式下传递给该脚本的参数的数目
#GATEWAY_INTERFACE: 服务器使用的 CGI 规范的版本
#SERVER_ADDR: 当前运行脚本所在的服务器的 IP 地址
#SERVER_NAME: 当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定。
#SERVER_SOFTWARE: 服务器标识字符串,在响应请求时的头信息中给出。
#SERVER_PROTOCOL: 请求页面时通信协议的名称和版本。例如,“HTTP/1.0”。
#REQUEST_METHOD: 访问页面使用的请求方法;如GET,HEAD,POST,PUT。如果请求方法为 HEAD,将在发送 Header 头信息之后终止,产生任何输出后,不再有输出缓冲
#REQUEST_TIME: 请求开始时的时间戳。
#QUERY_STRING: query string(查询字符串),如果有的话,通过它进行页面访问。
#DOCUMENT_ROOT: 当前运行脚本所在的文档根目录。在服务器配置文件中定义。
#HTTP_ACCEPT: 当前请求头中 Accept: 项的内容,如果存在的话。
#HTTP_ACCEPT_CHARSET: 当前请求头中 Accept-Charset: 项的内容,如果存在的话。例如:“iso-8859-1,*,utf-8”。
#HTTP_ACCEPT_ENCODING: 当前请求头中 Accept-Encoding: 项的内容,如果存在的话。例如:“gzip”。
#HTTP_ACCEPT_LANGUAGE: 当前请求头中 Accept-Language: 项的内容,如果存在的话。例如:“en”。
#HTTP_CONNECTION: 当前请求头中 Connection 项的内容,如果存在的话。例如:“Keep-Alive”。
#HTTP_HOST: 当前请求头中 Host: 项的内容,如果存在的话。
#HTTP_REFERER: 引导用户代理到当前页的前一页地址(如果存在)。由 user agent 设置决定。并非所有用户代理都会设置该项,有的还提供了修改 HTTP_REFERER 的功能。该值并不可信。


#HTTP_USER_AGENT: 该字符串表明了访问该页面的用户代理的信息
#HTTPS: 如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值
#REMOTE_ADDR: 浏览当前页面的用户的 IP 地址。
#REMOTE_HOST: 浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的 REMOTE_ADDR。
#REMOTE_PORT: 用户机器上连接到 Web 服务器所使用的端口号。
#SCRIPT_FILENAME: 当前执行脚本的绝对路径。
#SERVER_ADMIN: 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值。
#SERVER_PORT: Web 服务器使用的端口。默认值为 “80”。如果使用 SSL 安全连接,则这个值为用户设置的 HTTP 端口。
#SERVER_SIGNATURE: 包含了服务器版本和虚拟主机名的字符串。
#PATH_TRANSLATED: 当前脚本所在文件系统(非文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果
#SCRIPT_NAME: 包含当前脚本的路径。这在页面需要指向自己时非常有用。__FILE__ 常量包含当前脚本(例如包含文件)的完整路径和文件名。
#REQUEST_URI: URI 用来指定要访问的页面。例如 “/index.html”。
#PHP_AUTH_DIGEST: 当作为 Apache 模块运行时,进行 HTTP Digest 认证的过程中,此变量被设置成客户端发送的“Authorization” HTTP 头内容

#PHP_AUTH_USER: 当 PHP 运行在 Apache 或 IIS(PHP 5 是 ISAPI)模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的用户名。
#PHP_AUTH_PW: 当 PHP 运行在 Apache 或 IIS(PHP 5 是 ISAPI)模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的密码。
#AUTH_TYPE: 当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型。
#PATH_INFO: 包含由客户端提供的、跟在真实脚本名称之后并且在查询语句(query string)之前的路径信息
#ORIG_PATH_INFO: 在被 PHP 处理之前,“PATH_INFO” 的原始版本。

 

■$_GET — HTTP GET 变量

通过 URL 参数传递给当前脚本的变量的数组

■$_POST — HTTP POST 变量

通过 HTTP POST 方法传递给当前脚本的变量的数组
■$_FILES — HTTP 文件上传变量

通过 HTTP POST 方式上传到当前脚本的项目的


■$_REQUEST — HTTP Request 变量

默认情况下包含了 $_GET$_POST$_COOKIE数组
■$_SESSION — Session 变量

 当前脚本可用 SESSION 变量的数 

■$_ENV — 环境变量

通过环境方式传递给当前脚本的变量的数组。这些变量被从 PHP 解析器的运行环境导入到 PHP 的全局命名空间。很多是由支持 PHP 运行的 Shell 提供的,并且不同的系统很可能运行着不同种类的 Shell


■$_COOKIE — HTTP Cookies

通过 HTTP Cookies 方式传递给当前脚本的变量的数组

■$php_errormsg — 前一个错误信息

由 PHP 生成的最新错误信息。这个变量只在错误发生的作用域内可用,并且要求 track_errors 配置项是开启的(默认关闭)。
■$HTTP_RAW_POST_DATA — 原生POST数据

■$http_response_header — HTTP 响应头

■$argc — 传递给脚本的参数数目

■$argv — 传递给脚本的参数数组

 

五、预定义异常

* Exception:所有异常的基类

Exception {

/* 属性 */

protectedstring$message ; //异常消息内容

protectedint$code ; //异常代码

protectedstring$file ; //抛出异常的文件名

protectedint$line ; //抛出异常在该文件中的行号

/* 方法 */

public__construct ([ string $message = "" [, int $code = 0 [, Exception $previous = NULL ]]] )

final public string getMessage ( void ) //获取异常消息内容
 
final public Exception getPrevious ( void ) //返回异常链中的前一个异常
 
final public int getCode ( void ) //获取异常代码
 
final public string getFile ( void ) //获取发生异常的程序文件名称
 
final public int getLine ( void ) //获取发生异常的代码在文件中的行号
 
final public array getTrace ( void ) //获取异常追踪信息
 
final public string getTraceAsString ( void ) //获取字符串类型的异常追踪信息
 
public string__toString ( void ) //将异常对象转换为字符串
 
final private void __clone ( void ) //异常克隆
 }

 

* ErrorException : 错误异常

六、预定义接口

* 遍历接口Traversable

检测一个类是否可使用 foreach 进行遍历的接口。无法被单独实现的基本抽象接口。它必须由 IteratorAggregate 或 Iterator 接口实现

* 迭代器接口Iterator

Iterator extends Traversable {

abstract public mixed current ( void )
 
abstract public scalar key ( void )
 
abstract public void next ( void )
 
abstract public void rewind ( void )//返回到迭代器的第一个元素
 
abstract public boolean valid ( void )//检查当前位置是否有效
}

* 聚合迭代器接口IteratorAggregate

IteratorAggregate extends Traversable {
abstract public Traversable getIterator ( void )
}

* 数组式访问接口ArrayAccess

提供像访问数组一样访问对象的能力的接口

ArrayAccess {
abstract public boolean offsetExists ( mixed $offset ) //检查一个偏移位置是否存在
 
abstract public mixed offsetGet ( mixed $offset ) //获取一个偏移位置的值
 
abstract public void offsetSet ( mixed $offset , mixed $value ) //设置一个偏移位置的值
 
abstract public void offsetUnset ( mixed $offset ) //复位一个偏移位置的值
}

 

* 序列化接口Serializable

Serializable {

abstract public string serialize ( void ) //对象的字符串表示
 
abstract public mixed unserialize ( string $serialized ) //构造对象
}

 

* Closure Class

 

七、Context Options and Parameters

* Socket context options

* HTTP content options

* FTP  content options

* SSL  content options

* CURL  content options

* Phar  content options

* Context Parameters

 

八、Supported Protocols and Wrappers

■file:// — Accessing local filesystem
■http:// — Accessing HTTP(s) URLs
■ftp:// — Accessing FTP(s) URLs
■php:// — Accessing various I/O streams
■zlib:// — Compression Streams
■data:// — Data (RFC 2397)
■glob:// — Find pathnames matching pattern
■phar:// — PHP Archive
■ssh2:// — Secure Shell 2
■rar:// — RAR
■ogg:// — Audio streams
■expect:// — Process Interaction Streams

 

 

 

 

 

posted @ 2012-08-28 22:48  全栈深入  阅读(1631)  评论(0编辑  收藏  举报