网站找人做备案的价格,seo公司资源,网络营销案例分析论文,哈尔滨电子政务网站建设PHP 命名空间(namespace) PHP 命名空间(namespace)是在PHP 5.3中加入的#xff0c;如果你学过C#和Java#xff0c;那命名空间就不算什么新事物。 不过在PHP当中还是有着相当重要的意义。 PHP 命名空间可以解决以下两类问题#xff1a; 用户编写的代码与PHP内部的类/函数/常量… PHP 命名空间(namespace) PHP 命名空间(namespace)是在PHP 5.3中加入的如果你学过C#和Java那命名空间就不算什么新事物。 不过在PHP当中还是有着相当重要的意义。 PHP 命名空间可以解决以下两类问题 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名或简短的名称提高源代码的可读性。定义命名空间 默认情况下所有常量、类和函数名都放在全局空间下就和PHP支持命名空间之前一样。 命名空间通过关键字namespace 来声明。如果一个文件中包含命名空间它必须在其它所有代码之前声明命名空间。语法格式如下 ?php
// 定义代码在 MyProject 命名空间中
namespace MyProject; // ... 代码 ... 你也可以在同一个文件中定义不同的命名空间代码如 ?php
namespace MyProject1;
// MyProject1 命名空间中的PHP代码 namespace MyProject2;
// MyProject2 命名空间中的PHP代码 // 另一种语法
namespace MyProject3 { // MyProject3 命名空间中的PHP代码
}
? 在声明命名空间之前唯一合法的代码是用于定义源文件编码方式的 declare 语句。所有非 PHP 代码包括空白符都不能出现在命名空间的声明之前。 ?php
declare(encodingUTF-8); //定义多个命名空间和不包含在命名空间中的代码
namespace MyProject {const CONNECT_OK 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
}namespace { // 全局代码
session_start();
$a MyProject\connect();
echo MyProject\Connection::start();
}
? 以下代码会出现语法错误 html
?phpnamespace MyProject; // 命名空间前出现了“html” 会致命错误 - 命名空间必须是程序脚本的第一条语句
? 子命名空间 与目录和文件的关系很象PHP 命名空间也允许指定层次化的命名空间的名称。因此命名空间的名字可以使用分层次的方式定义 ?php
namespace MyProject\Sub\Level; //声明分层次的单个命名空间const CONNECT_OK 1;
class Connection { /* ... */ }
function Connect() { /* ... */ }? 上面的例子创建了常量 MyProject\Sub\Level\CONNECT_OK类 MyProject\Sub\Level\Connection 和函数 MyProject\Sub\Level\Connect。 命名空间使用 PHP 命名空间中的类名可以通过三种方式引用 非限定名称或不包含前缀的类名称例如 $anew foo(); 或 foo::staticmethod();。如果当前命名空间是 currentnamespacefoo 将被解析为 currentnamespace\foo。如果使用 foo 的代码是全局的不包含在任何命名空间中的代码则 foo 会被解析为foo。 警告如果命名空间中的函数或常量未定义则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。限定名称,或包含前缀的名称例如 $a new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果当前的命名空间是 currentnamespace则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的不包含在任何命名空间中的代码foo 会被解析为subnamespace\foo。完全限定名称或包含了全局前缀操作符的名称例如 $a new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo。下面是一个使用这三种方式的实例 file1.php 文件代码 ?php
namespace Foo\Bar\subnamespace; const FOO 1;
function foo() {}
class foo
{static function staticmethod() {}
}
? file2.php 文件代码 ?php
namespace Foo\Bar;
include file1.php;const FOO 2;
function foo() {}
class foo
{static function staticmethod() {}
}/* 非限定名称 */
foo(); // 解析为 Foo\Bar\foo resolves to function Foo\Bar\foo
foo::staticmethod(); // 解析为类 Foo\Bar\foo的静态方法staticmethod。resolves to class Foo\Bar\foo, method staticmethod
echo FOO; // resolves to constant Foo\Bar\FOO/* 限定名称 */
subnamespace\foo(); // 解析为函数 Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // 解析为类 Foo\Bar\subnamespace\foo,// 以及类的方法 staticmethod
echo subnamespace\FOO; // 解析为常量 Foo\Bar\subnamespace\FOO/* 完全限定名称 */
\Foo\Bar\foo(); // 解析为函数 Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // 解析为类 Foo\Bar\foo, 以及类的方法 staticmethod
echo \Foo\Bar\FOO; // 解析为常量 Foo\Bar\FOO
? 注意访问任意全局类、函数或常量都可以使用完全限定名称例如 \strlen() 或 \Exception 或 \INI_ALL。 在命名空间内部访问全局类、函数和常量 ?php
namespace Foo;function strlen() {}
const INI_ALL 3;
class Exception {}$a \strlen(hi); // 调用全局函数strlen
$b \INI_ALL; // 访问全局常量 INI_ALL
$c new \Exception(error); // 实例化全局类 Exception
? 命名空间和动态语言特征 PHP 命名空间的实现受到其语言自身的动态特征的影响。因此如果要将下面的代码转换到命名空间中动态访问元素。 example1.php 文件代码 ?php
class classname
{function __construct(){echo __METHOD__,\n;}
}
function funcname()
{echo __FUNCTION__,\n;
}
const constname global;$a classname;
$obj new $a; // prints classname::__construct
$b funcname;
$b(); // prints funcname
echo constant(constname), \n; // prints global
? 必须使用完全限定名称包括命名空间前缀的类名称。注意因为在动态的类名称、函数名称或常量名称中限定名称和完全限定名称没有区别因此其前导的反斜杠是不必要的。 动态访问命名空间的元素 ?php
namespace namespacename;
class classname
{function __construct(){echo __METHOD__,\n;}
}
function funcname()
{echo __FUNCTION__,\n;
}
const constname namespaced;include example1.php;$a classname;
$obj new $a; // prints classname::__construct
$b funcname;
$b(); // prints funcname
echo constant(constname), \n; // prints global/* note that if using double quotes, \\namespacename\\classname must be used */
$a \namespacename\classname;
$obj new $a; // prints namespacename\classname::__construct
$a namespacename\classname;
$obj new $a; // also prints namespacename\classname::__construct
$b namespacename\funcname;
$b(); // prints namespacename\funcname
$b \namespacename\funcname;
$b(); // also prints namespacename\funcname
echo constant(\namespacename\constname), \n; // prints namespaced
echo constant(namespacename\constname), \n; // also prints namespaced
? namespace关键字和__NAMESPACE__常量 PHP支持两种抽象的访问当前命名空间内部元素的方法__NAMESPACE__ 魔术常量和namespace关键字。 常量__NAMESPACE__的值是包含当前命名空间名称的字符串。在全局的不包括在任何命名空间中的代码它包含一个空的字符串。 __NAMESPACE__ 示例, 在命名空间中的代码 ?php
namespace MyProject;echo , __NAMESPACE__, ; // 输出 MyProject
? __NAMESPACE__ 示例全局代码 ?phpecho , __NAMESPACE__, ; // 输出
? 常量 __NAMESPACE__ 在动态创建名称时很有用例如 使用__NAMESPACE__动态创建名称 ?php
namespace MyProject;function get($classname)
{$a __NAMESPACE__ . \\ . $classname;return new $a;
}
? 关键字 namespace 可用来显式访问当前命名空间或子命名空间中的元素。它等价于类中的 self 操作符。 namespace操作符命名空间中的代码 ?php
namespace MyProject;use blah\blah as mine; // see Using namespaces: importing/aliasingblah\mine(); // calls function blah\blah\mine()
namespace\blah\mine(); // calls function MyProject\blah\mine()namespace\func(); // calls function MyProject\func()
namespace\sub\func(); // calls function MyProject\sub\func()
namespace\cname::method(); // calls static method method of class MyProject\cname
$a new namespace\sub\cname(); // instantiates object of class MyProject\sub\cname
$b namespace\CONSTANT; // assigns value of constant MyProject\CONSTANT to $b
? namespace操作符, 全局代码 ?phpnamespace\func(); // calls function func()
namespace\sub\func(); // calls function sub\func()
namespace\cname::method(); // calls static method method of class cname
$a new namespace\sub\cname(); // instantiates object of class sub\cname
$b namespace\CONSTANT; // assigns value of constant CONSTANT to $b
? 使用命名空间别名/导入 PHP 命名空间支持 有两种使用别名或导入方式为类名称使用别名或为命名空间名称使用别名。注意PHP不支持导入函数或常量。 在PHP中别名是通过操作符 use 来实现的. 下面是一个使用所有可能的三种导入方式的例子 1、使用use操作符导入/使用别名 ?php
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 对象
? 2、 一行中包含多个use语句 ?php
use My\Full\Classname as Another, My\Full\NSname;$obj new Another; // 实例化 My\Full\Classname 对象
NSname\subns\func(); // 调用函数 My\Full\NSname\subns\func
? 导入操作是在编译执行的但动态的类名称、函数名称或常量名称则不是。 3、导入和动态名称 ?php
use My\Full\Classname as Another, My\Full\NSname;$obj new Another; // 实例化一个 My\Full\Classname 对象
$a Another;
$obj new $a; // 实际化一个 Another 对象
? 另外导入操作只影响非限定名称和限定名称。完全限定名称由于是确定的故不受导入的影响。 4、导入和完全限定名称 ?php
use My\Full\Classname as Another, My\Full\NSname;$obj new Another; // instantiates object of class My\Full\Classname
$obj new \Another; // instantiates object of class Another
$obj new Another\thing; // instantiates object of class My\Full\Classname\thing
$obj new \Another\thing; // instantiates object of class Another\thing
? 使用命名空间后备全局函数/常量 在一个命名空间中当 PHP 遇到一个非限定的类、函数或常量名称时它使用不同的优先策略来解析该名称。类名称总是解析到当前命名空间中的名称。因此在访问系统内部或不包含在命名空间中的类名称时必须使用完全限定名称例如 1、在命名空间中访问全局类 ?php
namespace A\B\C;
class Exception extends \Exception {}$a new Exception(hi); // $a 是类 A\B\C\Exception 的一个对象
$b new \Exception(hi); // $b 是类 Exception 的一个对象$c new ArrayObject; // 致命错误, 找不到 A\B\C\ArrayObject 类
? 对于函数和常量来说如果当前命名空间中不存在该函数或常量PHP 会退而使用全局空间中的函数或常量。 2、 命名空间中后备的全局函数/常量 ?php
namespace A\B\C;const E_ERROR 45;
function strlen($str)
{return \strlen($str) - 1;
}echo E_ERROR, \n; // 输出 45
echo INI_ALL, \n; // 输出 7 - 使用全局常量 INI_ALLecho strlen(hi), \n; // 输出 1
if (is_array(hi)) { // 输出 is not arrayecho is array\n;
} else {echo is not array\n;
}
? 全局空间 如果没有定义任何命名空间所有的类与函数的定义都是在全局空间与 PHP 引入命名空间概念前一样。在名称前加上前缀 \ 表示该名称是全局空间中的名称即使该名称位于其它的命名空间中时也是如此。 使用全局空间说明 ?php
namespace A\B\C;/* 这个函数是 A\B\C\fopen */
function fopen() { /* ... */$f \fopen(...); // 调用全局的fopen函数return $f;
}
? 命名空间的顺序 自从有了命名空间之后最容易出错的该是使用类的时候这个类的寻找路径是什么样的了。 1 ?php2 namespace A;3 use B\D, C\E as F;4 5 // 函数调用6 7 foo(); // 首先尝试调用定义在命名空间A中的函数foo()8 // 再尝试调用全局函数 foo9
10 \foo(); // 调用全局空间函数 foo
11
12 my\foo(); // 调用定义在命名空间A\my中函数 foo
13
14 F(); // 首先尝试调用定义在命名空间A中的函数 F
15 // 再尝试调用全局函数 F
16
17 // 类引用
18
19 new B(); // 创建命名空间 A 中定义的类 B 的一个对象
20 // 如果未找到则尝试自动装载类 A\B
21
22 new D(); // 使用导入规则创建命名空间 B 中定义的类 D 的一个对象
23 // 如果未找到则尝试自动装载类 B\D
24
25 new F(); // 使用导入规则创建命名空间 C 中定义的类 E 的一个对象
26 // 如果未找到则尝试自动装载类 C\E
27
28 new \B(); // 创建定义在全局空间中的类 B 的一个对象
29 // 如果未发现则尝试自动装载类 B
30
31 new \D(); // 创建定义在全局空间中的类 D 的一个对象
32 // 如果未发现则尝试自动装载类 D
33
34 new \F(); // 创建定义在全局空间中的类 F 的一个对象
35 // 如果未发现则尝试自动装载类 F
36
37 // 调用另一个命名空间中的静态方法或命名空间函数
38
39 B\foo(); // 调用命名空间 A\B 中函数 foo
40
41 B::foo(); // 调用命名空间 A 中定义的类 B 的 foo 方法
42 // 如果未找到类 A\B 则尝试自动装载类 A\B
43
44 D::foo(); // 使用导入规则调用命名空间 B 中定义的类 D 的 foo 方法
45 // 如果类 B\D 未找到则尝试自动装载类 B\D
46
47 \B\foo(); // 调用命名空间 B 中的函数 foo
48
49 \B::foo(); // 调用全局空间中的类 B 的 foo 方法
50 // 如果类 B 未找到则尝试自动装载类 B
51
52 // 当前命名空间中的静态方法或函数
53
54 A\B::foo(); // 调用命名空间 A\A 中定义的类 B 的 foo 方法
55 // 如果类 A\A\B 未找到则尝试自动装载类 A\A\B
56
57 \A\B::foo(); // 调用命名空间 A\B 中定义的类 B 的 foo 方法
58 // 如果类 A\B 未找到则尝试自动装载类 A\B
59 ? 名称解析遵循下列规则 对完全限定名称的函数类和常量的调用在编译时解析。例如 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()。转载于:https://www.cnblogs.com/aiweixiao/p/5864657.html