• PHP 核心特性


      

    提出

    在命名空间提出之前,不同的组件很容易碰到命名的冲突,例如 Request 、Response 等常见的命名。PHP 在 5.3 后提出了命名空间用来解决组件之间的命名冲突问题,主要参考了文件系统的设计:

    • 同一个目录下不允许有相同的文件名 - 同一个命名空间下不允许有相同的类;
    • 不同的目录可以有同名文件 - 不同的命名空间可以有相同的类;
     

    定义

    使用 namespace 关键字来定义一个命名空间。其中,顶层命名空间通常为厂商名,不同开发者的厂商命名空间是唯一的。命名空间不需要与文件目录一一对应,但是最好遵守 PSR-4 规范。

     1 <?php
     2 
     3 namespace SymfonyComponentHttpFoundation;
     4 
     5 class Request {
     6 
     7 }
     8 命名空间必须在所有代码之前声明,唯一的例外就是 declare 关键字。
     9 
    10 <?php
    11 
    12 declare(strict_types=1);
    13 
    14 namespace App;

    命名空间内可包含任意 PHP 代码,但是仅对类 (包括抽象类和 Trait)、接口、函数和常量这四种类型生效。

    1 <?php
    2 namespace MyProject;
    3 
    4 const CONNECT_OK = 1;
    5 class FOO {}
    6 interface Foo{}
    7 function foo() {}
     

    使用

    使用 use 关键字来引入命名空间

     1 <?php
     2 
     3 namespace App;
     4 
     5 use SymfonyComponentHttpFoundationRequest;
     6 use FooBar;
     7 
     8 class Test {
     9     public function run() 
    10     {
    11         $bar = new Bar();
    12     }
    13 }

    定义和使用推荐遵循 PSR-2 的规范

    • namespace 之后必须存在一个空行;
    • 所有 use 声明必须位于 namespace 声明之后;
    • 每条 use 声明必须只有一个 use 关键字。
      use 语句块之后必须存在一个空行。

    当 use 引入的类出现同名时,可使用 as 来定义别名

    1 <?php
    2 
    3 namespace App;
    4 
    5 use FooBar as BaseBar;
    6 
    7 class Bar extends BaseBar {
    8 
    9 }
     

    限定符

    除了使用 use 外,还可以直接使用  限定符来进行解析,规则很简单:如果含有  前缀则代表从全局命名空间开始解析,否则则代表从当前命名空间开始解析。

     1 <?php
     2 
     3 namespace App;
     4 
     5 FooBarfoo();  // 解析成 FooBarfoo();
     6 FooBarfoo();  // 解析成 AppFooBarfoo();
     7 此规则也适用于函数、常量等
     8 
     9 $a = strlen('hi'); // 调用全局函数 strlen
    10 $b = INI_ALL; // 访问全局常量 INI_ALL
    11 $c = new Exception('error'); // 实例化全局类 Exception

    有两个需要特别注意的地方:

    对于函数和常量而言,如果当前命名空间不存在,则会自动去全局命名空间去寻找,因此可省略  前缀。对于类而言,如果当前命名空间解析不到,不会去全局空间寻找,因此,不可省略 

    1 $a = strlen('hi');
    2 $b = INI_ALL;
    3 $c = new Exception('error'); // 错误
    4 $c = new Exception('error'); // 正确

    当动态调用命名空间时,该命名空间始终会被当成是全局命名空间,因此可以省略前缀 

    1 $class1 = 'FooBar';
    2 $object1 = new $class1;  // 始终被解析成 FooBar
     

    在内部访问命名空间

    PHP 支持两种抽象的访问当前命名空间内部元素的方法,__NAMESPACE__ 魔术常量和 namespace 关键字。

    __NAMESPACE__ 常量的值是包含当前命名空间名称的字符串,如果是在全局命名空间,则返回空字符串。

    1 <?php
    2 namespace MyProject;
    3 
    4 function get($classname)
    5 {
    6     $a = __NAMESPACE__ . '\' . $classname;
    7     return new $a;
    8 }

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

     1 namespace App;
     2 
     3 use blahlah as mine; 
     4 
     5 blahmine(); // Applahmine()
     6 namespacelahmine(); // Applahmine()
     7 
     8 namespacefunc(); // Appfunc()
     9 namespacesubfunc(); // Appsubfunc()
    10 namespacecname::method(); // Appcname::method()
    11 $a = new namespacesubcname(); // Appsubcname
    12 $b = namespaceCONSTANT; // AppCONSTANT
     

    转义  符号

    此外,推荐对所有的  进行转义,避免出现不可预期的后果

    1 $class = "dangerous
    ame"; // 
     被解析成换行符
    2 $obj = new $class;
    3 
    4 $class = 'dangerous
    ame'; // 正确,但是不推荐
    5 $class = 'dangerous\name'; // 推荐
    6 $class = "dangerous\name"; // 推荐
  • 相关阅读:
    boost之实用工具
    boost之内存池
    boost之智能指针
    boost之日期date_time
    boost之时间timer
    boost之网络通信
    boost之定时器和io_service
    【Linux 线程】线程同步《一》
    【Linux 线程】常用线程函数复习《四》
    【Linux 线程】常用线程函数复习《三》
  • 原文地址:https://www.cnblogs.com/a609251438/p/11844855.html
Copyright © 2020-2023  润新知