[连载] PHP 5.3.0 alpha3 中的名字空间(namespace)改进 (一)


 近日,PHP官方已将拥有众多新特性的PHP5.3放到A3版本. 在更新日志中强调了这一版本的名字空间部份变化较大.

正好前段时间我开发的工业快捷框架SmartYU用到了5.3 A2中的不少特性,其中就包括了名字空间.所以将两者做了一些比较.

发现不得不对之前的名字空间部份全部推翻重写 :( (看来在发行版本未稳定之前,最好还是不要轻易尝试用其做项目).

 首先说定义.
 创建一个名字空间,都是通过在文件头部 使用namespace保留关键字定义.
 A2版的定义方式是  namespaces SYU::Kernel::Module 的形式
 A3版的定义方式是  namespaces SYU/Kernel/Module 的形式
 
 相较而言,A2版的子空间分隔符是 ::  比A3的 / 多一个字符,另外在使用类静态方法时会跟静态方法的操作符:: 相同,容易引起一些不必要的麻烦.
 比如  SYU::DB::Connect( ) 的形式,时常会让人分不清到底该是调用SYU::DB类的Connect( )方法,还是该调用SYU::DB::Connect类的构造函数.
 
 A3使用 / 符 类似于win下的路径分隔符,好处就是__autoload自动载入的时候 :-) .但不好的地方在于如果名字空间出现在字符串中,须注意转义. 一会儿两根斜线,一会儿用一根斜线.感觉还是有些混乱.
 
 一但定义了名字空间.自定义以下的部份,函数,类,都属于此名字空间

  1.  <?php
  2.  namespace test;
  3.  function strlen(){return "i'm here!"; }; //跟php自带的strlen同名.但不会报错,因为实际访问名字空间是  /test/strlen
  4.  class pdo{};            //跟php扩展里的pdo类同名.但不会报复重定义类错误,因为实际访问名字空间是 /test/pdo
  5.  echo strlen(); //调用名字空间内的函数.
  6.  echo /strlen(strlen()); //调用全局空间,直接加 / 符
  7.  ?>

 

定义名字空间时,需要注意的地方是 namespace定义必须在脚本文件的顶部声明(同一脚本文件可以申明多个名字空间,但第一个申明必须在脚本文件的头部,)
 例如
 
唯一能在namespace前的例外是控制结构中的declare和不起任何作用的原子语句

  1. <?php
  2. declare(encoding='GB2312');
  3. namespace test;
  4. ?>
  5. <?php
  6. 1;
  7. namespace test;
  8. ?>

其次,A3增加了名字空间内的const ,这在A2版中是没有的.

  1.  <?php
  2.  namespace test/sayhello ;
  3. const t='hello';
  4.  ........
  5.  ?>

 那么在其它的程序里可以使用 echo /test/sayhello/t 这样的方式来显示 t的值.结果将打印出 hello
 这跟类中的const定义是差不多的..
 
 再者,A2版中,同一脚本文件只能定义一次名字空间,而从A3开始,允许在同一个PHP脚本文件内,定义多个名字空间,
 定义的方法有好种:
 1是简单定义

  1. <?php
  2. namespace n1;
  3. const n1_const = 1;
  4. function test() {echo "n1";}
  5. namespace n2;
  6. const n2_const = 1;
  7. function test () {echo "n2";}
  8. /n1/test();
  9. /n2/test();
  10. ?>  

2是花括号界定

  1. <?php
  2. //定义n1名字空间,注意,使用花括号后,定义语句不再带 ; 号
  3. namespace n1
  4. {
  5.  const n1_const = 1;
  6.  function test() {echo "n1";}
  7. }
  8. namespace n2
  9. {
  10.  const n2_const = 1;
  11.  function test () {echo "n2";}
  12.   Function strlen() { }  //在n2空间里,这样定义不会报错,跟全局空间的strlen不冲突
  13. }
  14. //如果namespace没有指定名字,则视为全局global空间
  15. namespace
  16. {
  17.   /n1/test();
  18.   /n2/test();
  19.   //Function strlen(){}  在全局空间里,这样定义就会报错.跟全局空间的strlen函数重复定义.
  20. }
  21. ?>

着重注意的一点时.一但一个脚本文件被定义了名定空间,那么不允许有任何代码是在名字空间之外.
除了在第一部份讲的declare结构,连空格都不允许.
如果用的第一种简单定义法.没有花括号界定.那么最后一个namespace定义将一直延伸到整个脚本文件结束.
但如果用花括号界定名字空间.则千万要注意在PHP结束(而不是整个脚本文件结束)的后面.不能再有其它东西.
比如下例就是错误的演示

  1. <?php
  2. namespace test
  3. {
  4.  //do sth...
  5. }
  6. ?><spaces>

未完待续........

 

本文章由syu于csdn首发

QQ:19179816

MSN:peteryu@live.cn

 


 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值