PSR 类自动加载规范的翻译与看法

先列举一些资源:

有几点事先说明:

  • 翻译部分,我只挑选PSR-0和PSR-4中的主要规范内容进行翻译。
  • 我的翻译,侧重以理解的角度,而不是严格的文法翻译。

关键修饰词的说明:

**MUST**        __务必__
**MUST_NOT**    __绝不__
**REQUIRED**    __务必__
**SHALL**       __务必__
**SHALL_NOT**   __绝不__
**SHOULD**      __应该__
**SHOULD_NOT**  __不应该__
**RECOMMENDED** __建议__
**MAY**         __可以__
**OPTIONAL**    __可选__

为啥这样子,看看rfc2119的定义吧!

PSR-0 类自动加载规范(Autoloading Standard)

已弃用,从2014年10月21日起,PSR-0规范已弃用,并推荐以PSR-4规范作为替代。

规范正文

  1. 命名空间(Namespace)和类(Class)务必拥有如右侧所示的标准结构\<Vendor Name>\(<Namespace>\)*<Class Name>
  2. (所有)命名空间(Namespace)务必拥有一个顶级的命名空间,如:Vendor Name
  3. (所有)命名空间(Namespace)可选根据实际需要,定义多个子命名空间(注意不是必选项)。
  4. 在加载时,(所有)命名空间(Namespace)的分隔符 \ 会转换为目录分隔符 DIRECTORY_SEPARATOR
  5. 类名(Class Name)中的 _ 会转换为目录分隔符 DIRECTORY_SEPARATOR,但在命名空间(Namespace) _ 不具备任何含义(纯粹修饰性)。
  6. 在加载时,命名空间(Namespace)和类(Class)时,源文件应该以.php为后缀(这条规则其实定义的很笼统)。
  7. 命名时,命名空间(Vendor Name,Namespace)、类名(Class Name)应该由半角英文字母、大小写组合而成。

演示

return [
    ‘\Doctrine\Common\IsolatedClassLoader‘ => ‘/path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php‘,
    ‘\Symfony\Core\Request‘ => ‘/path/to/project/lib/vendor/Symfony/Core/Request.php‘,
    ‘\Zend\Acl‘ => ‘/path/to/project/lib/vendor/Zend/Acl.php‘,
    ‘\Zend\Mail\Message‘ => ‘/path/to/project/lib/vendor/Zend/Mail/Message.php‘,
];

下划线在命名空间和类名的使用

return [
    ‘\namespace\package\Class_Name‘ => ‘/path/to/project/lib/vendor/namespace/package/Class/Name.php‘,
    ‘\namespace\package_name\Class_Name‘ => ‘/path/to/project/lib/vendor/namespace/package_name/Class/Name.php‘
];

PSR-4 类加载器(Autoloader)

  1. 本文中的类(Class),可指代包括: (Class,这里可以理解为代码上对类定义的结构体)、 接口 (Interface)、 特征 (Trait),等与之相似的结构体。
  2. 类全称(the fully qualified class name),如右侧所示 \<顶级命名空间>(\<子级命名空间>)*\<类名>
    1. 类全称务必拥有一个顶级命名空间,常见的如 “Vendor namespace”。
    2. 类全称可以有一个或者多个子命名空间名。
    3. 类全称务必以一个类名(ClassName)终结。
    4. 下划线 _ 不再具有任何指义(区别于 PSR-0#5)。
    5. 类全称中的英文字母,可以由大小写任意组合而成。
    6. 所有类名在引用时,务必遵守其命名的大小写风格。
  3. 加载(类源文件)时的一致性规则:
    1. 前缀映射规则:将类全称中的命名空间前缀,去掉最左边的分隔符 \,映射到一个基础目录上去(注意这里所说的命名空间前缀,可以指单个命名空间前缀,也可以是多个命名空间前缀,比如Acme\Log指向一个目录,再把Acme\Log\Writer指向另外一个目录)。
    2. 前缀映射剩余的子命名空间,务必与他所映射的基础目录下的目录结构一一对应(这里只说目录结构,不说文件命名)。
    3. 类源文件需以 .php 为结尾,且务必与类命名大小写吻合。
  4. 类加载器(Autoloader),绝不抛出任何异常、任意级别的错误、返回任意的结果。

看法

PSR-0其实是一个完全没有约束力的规范,因为从第三点开始,已经完全给不出有力的修饰词。

PSR-4就务实多了,从Standard转为er。不过这个前缀映射法,从AgiMVC 3我就开始在玩了,但说实在的,这个东西就是个鸡肋。为啥这么说呢?

PSR-4中的前缀映射,是无限映射,假定我有个类全称是 \My\Sub1\Sub2\Sub3\ClassA,我将 My\Sub1\Sub2 指向了目录1,将 My\Sub1 指向了目录2,那么在引用这个类的时,loadClass应该如何设计呢?最直接的做法就是,从 My\Sub1\Sub2\Sub3 开始匹配,那么到 My\Sub1\Sub2 时候,我就命中了目录1。天哪,假如我的定义的命名空间很多的话,这个匹配,需要走多少次循环呢?所以就算是Composer也不得不提供一个优化的参数,把一个类库的所有定义的类都做一个枚举。

项目刚开始的时候,我们可能真的需要无限量的空间,但是进入到具体的开发环节,所有的一切都是具体得不能再具体的了。

或者说,这就是PHP语言本身的失败的地方所在,他坚定不移的走在微软无限抄的道路上,但却不给出任何具体的语言规范,乃至更先进一点的加载机制,而把所有的一切都让给了他身后的诸多山寨框架联盟——PSR联盟。

Composer和PSR把所有傻帽坑爹耗性能的事情都一股脑的扣在了PHP这个性能最差的开发语言上……

前些日子用node.js做了一些东西,真心觉得node.js的包机制明确而具体。PHP就不能学学node.js吗,哎,被后来的小弟超越了,PHP啊,你也该甩甩你的老包袱了吧?

时间: 2024-08-12 16:23:44

PSR 类自动加载规范的翻译与看法的相关文章

springboot属性类自动加载配置文件中的值

springboot属性类自动加载配置文件中的值,如Person类加载在yml中配置的name,age等属性值,可以通过如下步骤获取: 类上添加@ConfigurationProperties注解,prefix为yml中配置的属性名称,要想属性类生效得加上@Component注解 如果想要在yml中有对应类的提示,还需要添加如下依赖: yml书写如下: 如果是properties文件,则书写如下: 在yml中如果值中有特殊字符,需要转义可以用单引号包裹,默认是双引号 如果仅仅为类中的某个属性值赋

PSR-4 自动加载规范

关键词 "必须"("MUST")."一定不可/一定不能"("MUST NOT")."需要"("REQUIRED"). "将会"("SHALL")."不会"("SHALL NOT")."应该"("SHOULD")."不该"("SHOULD N

php自动加载PSR-0原文翻译,PSR-0中文版

已弃用 - 截止到2014年10月21日,PSR-0已被弃用. 推荐替代使用PSR-4. 下文描述了若要使用一个通用的自动加载器(autoloader),你所需要遵守的规范: 规范 一个完全标准的命名空间(namespace)和类(class)的结构是这样的:\<Vendor Name>\(<Namespace>\)*<Class Name> 每个命名空间(namespace)都必须有一个顶级的空间名(namespace)("组织名(Vendor Name)&

类自动加载封装类

1 <?php 2 3 class Common { 4 /** 5 * 可以实现类文件的加载 6 */ 7 public static function autoload($class_name) { 8 include './' . $class_name . '.class.php'; 9 } 10 /** 11 * 注册自动加载方法 12 */ 13 public function register() { 14 // spl_autoload_register(array($this,

YII框架的类自动加载机制

YII之所以能实现快速的自动加载类文件,是因为它通过两种途径来实现. 先看文件 vendor\yiisoft\yii2\BaseYii.php 里面的 autoload 方法 public static function autoload($className) { if (isset(static::$classMap[$className])) { //先去类地图里面找 $classFile = static::$classMap[$className]; if ($classFile[0]

类自动加载方法详解

在了解这个函数之前先来看另一个函数:__autoload. 一.__autoload 这是一个自动加载函数,在PHP5中,当我们实例化一个未定义的类时,就会触发此函数.看下面例子: printit.class.php <?php class PRINTIT { function doPrint() { echo 'hello world'; } } ?> index.php <? function __autoload( $class ) { $file = $class . '.cla

类自动加载器

1 /** 2 * Created by [中弘集团] qq 812035863 . 3 * User: Taoist 4 * Date: 2015/7/9 5 * Time: 20:57 6 * description: 自动类加载 7 * 入口文件首先载入加载器 8 * 9 * 加载文件要放在类库内才有作用 10 * 11 * 如果 root 是根目录 12 * 13 * /root/library 是库目录 14 * 15 * autoload文件放在library 下面 16 * 17

PHP的类自动加载机制

<?php/* 如果使用关键字self运行结果: A A 如果使用关键字static运行结果:A B 使用 self:: 或者 __CLASS__ 对当前类的静态引用,取决于定义当前方法所在的类:使用 static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的.也可以称之为"静态绑定",因为它可以用于(但不限于)静态方法的调用.静态绑定是PHP 5.3.0,增加的一个功能 用于在继承范围内引用静态调用的类简单通俗的来说,self就是写在哪个类里面, 实际调用的就是

如何实现一个php框架系列文章【3】支持psr4的自动加载类

psr4自动加载规范https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-4-autoloader-cn.md 我们把第三方使用psr规范的类库放在vendor目录下 修改一下autoload函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22     //psr     if (!empty($GLOBALS['_UCT']['autoload_psr'])) {