精华内容
下载资源
问答
  • PSR-4 WordPress插件 WordPress标准插件,支持自动加载。 PSR-4:自动装带器 该PSR描述了从文件路径类的规范。 它是完全可互操作的,并且除包括任何其他自动加载规范外,还可以使用。 该PSR还描述了根据规范自动放置...
  • composer 的自动载入 autoload 可以很方便的帮我们快速的构建一套自己的框架结构。而自动载入本身其实是利用命名空间进行对应规则或标准的路径映射,从而找到我们所需的类文件,...四种模式psr-0 标准autoload_nam...

    composer 的自动载入 autoload 可以很方便的帮我们快速的构建一套自己的框架结构。

    而自动载入本身其实是利用命名空间进行对应规则或标准的路径映射,从而找到我们所需的类文件,读取载入都当前运行时。利用命名空间的自动载入都是懒加载形式的,并不会让程序变得臃肿,但懒加载在一定程度上也影响了程序的性能,要在程序规模和运行效率上做一个折中的选择。

    四种模式

    psr-0 标准 autoload_namespaces

    懒加载,将目标目录作为基目录再进行命名空间和路径的映射后继续向后加载

    // php 的 psr-0 规范的自动载入,是将目标目录作为命名空间的基目录再进行路径映射载入类文件

    "psr-0": {

    "Psr0\\Lib\\": "psr0/lib/src/"

    }

    这里还有一点是需要注意的,下划线 _ 对 psr-0 是有特殊意义的。psr-0 的加载器会将类名中的 _ 解析成目录分隔符。

    即 Foo_Bar_Test 类会去加载 Foo/Bar/Test.php 文件。

    // PSR-0 lookup

    if (false !== $pos = strrpos($class, '\\')) {

    // namespaced class name

    $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)

    . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);

    } else {

    // PEAR-like class name

    $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;

    }

    也可以看下composer 的源码,可以看到是将 _ 替换成了 DIRECTORY_SEPARATOR(目录分隔符)。

    在 php 5.2 之前,是没有 namespace 关键字去友好的管理类包的,是 php 5.3 以后才有新特性:命名空间,匿名函数,静态延迟绑定。

    然而有很多普遍使用的第三方类库还是使用的下划线的方式去命名类,比如 PHPExcel,这里我们可以看下其官方的 composer.json 文件里自动载入的配置:

    "autoload": {

    "psr-0": {

    "PHPExcel": "Classes/"

    }

    }

    则 PHPExcel 顶级类下的检索都会以 Classes 文件夹为起始目录,比如我想使用 PHPExcel_Cell_DataType 这个类。我就可以判断出这个类是在 Classes/PHPExcel/Cell/DataType.php 文件中。

    // 则会加载 Classes/PHPExcel/Cell/DataType.php

    use PHPExcel_Cell_DataType;

    psr-4 标准 autoload_psr4

    懒加载,将目标目录直接映射为命名空间对应的目录继续向后加载

    // php 的 psr-4 规范的自动载入,是将目标目录直接影射为命名空间的

    "psr-4": {

    "Psr4\\Lib\\": "psr4/lib/src/",

    "App\\Controllers\\": "app/controllers/",

    "App\\Models\\": "app/models/"

    }

    classmap 模式 autoload_classmap

    懒加载,扫描目录下的所有类文件,支持递归扫描, 生成对应的类名=>路径的映射,当载入需要的类时直接取出路径,速度最快

    // classmap 扫描目录下的所有类文件 生成对应的类名=>路径的映射

    "classmap": [

    "classmap/lib/src/"

    ]

    files 模式

    自动载入的文件,主要用来载入一些没办法懒加载的公共函数

    // 扫描目录下的所有文件生成 hash => 路径的映射 运行时实时加载

    // 主要用来载入工具函数

    "files": [

    "ext/common/functions.php",

    "ext/system/functions.php"

    ]

    框架结构

    这里我要尽可能把四种自动载入模式的特征举例出来,所以框架结构并不很合理,不要在意

    ./

    ├── app

    │   ├── controllers

    │   └── models

    ├── classmap

    │   └── lib

    │   └── src

    ├── composer.json

    ├── ext

    │   ├── common

    │   │   └── functions

    │   └── system

    │   └── functions

    ├── psr0

    │   └── lib

    │   └── src

    └── psr4

    └── lib

    └── src

    autoload 规则

    编辑 composer.json 文件

    {

    "autoload": {

    "psr-0": {

    "Psr0\\Lib\\": "psr0/lib/src/"

    },

    "psr-4": {

    "Psr4\\Lib\\": "psr4/lib/src/",

    "App\\Controllers\\": "app/controllers/",

    "App\\Models\\": "app/models/"

    },

    "classmap": [

    "classmap/lib/src/"

    ],

    "files": [

    "ext/common/functions.php",

    "ext/system/functions.php"

    ]

    }

    }

    刷新 autoload 规则

    composer dump-autoload

    当你添加了新的  psr-0/psr-4 的规则,或者在 classmap/files 规则相应的目录下新增了文件时,都需要执行 dump-autoload 来刷新系统的自动载入。

    我们可以看一下生成的 psr-0 和 psr-4 标准的自动载入

    psr-0:vendor/composer/autoload_namespaces.php

    // autoload_namespaces.php @generated by Composer

    $vendorDir = dirname(dirname(__FILE__));

    $baseDir = dirname($vendorDir);

    return array(

    'Psr0\\Lib\\' => array($baseDir . '/psr0/lib/src'),

    );

    psr-4:vendor/composer/autoload_psr4.php

    // autoload_psr4.php @generated by Composer

    $vendorDir = dirname(dirname(__FILE__));

    $baseDir = dirname($vendorDir);

    return array(

    'Psr4\\Lib\\' => array($baseDir . '/psr4/lib/src'),

    'App\\Models\\' => array($baseDir . '/app/models'),

    'App\\Controllers\\' => array($baseDir . '/app/controllers'),

    );

    其实 psr-0/psr-4 的自动载入都将命名空间映射为相应的目录。只不过 psr-0 是映射到目标地址作为基目录再解析命名空间,而 psr-4 是直接映射。

    实现一个 psr-0 规范的类文件

    psr0/lib/src/Psr0/Lib/Psr0LibClass.php

    // psr-0: "Psr0\\Lib\\": "psr0/lib/src/"

    namespace Psr0\Lib;

    class Psr0LibClass

    {

    public static function index()

    {

    echo __CLASS__ . "@" . __FILE__ . PHP_EOL;

    }

    }

    实现一个 psr-4 规范的类文件

    psr4/lib/src/Psr4LibClass.php

    // psr-4: "Psr4\\Lib\\": "psr4/lib/src/"

    namespace Psr4\Lib;

    class Psr4LibClass

    {

    public static function index()

    {

    echo __CLASS__ . "@" . __FILE__ . PHP_EOL;

    }

    }

    classmap 就没什么规范可言了,绝对的一对一映射而已

    因为它本身就没遵循命名空间和路径映射的半点规范...随便写一个好了,他的模式其实就是扫描指定目录下的所有文件,把类采集出来,做一个映射表,这个类在这个文件里,完了。

    classmap/lib/src/ClassMapAutoload.php

    // classmap 放在 classmap/lib/src 下就好,autoload 会自动扫描记录它

    namespace ClassMap\Lib;

    class ClassMapLibClass

    {

    public static function index()

    {

    echo __CLASS__ . "@" . __FILE__ . PHP_EOL;

    }

    }

    files 是在运行时就直接载入的一些函数文件(非类文件)

    ext/common/functions.php

    ext/system/functions.php

    //ext/common/functions.php

    function hello_common()

    {

    echo __FUNCTION__ . "@" . __FILE__ . PHP_EOL;

    }

    //ext/system/functions.php

    function hello_system()

    {

    echo __FUNCTION__ . "@" . __FILE__ . PHP_EOL;

    }

    运行一下 compser dump-autoload 来刷新自动载入

    实例

    //为了方便 不标准 标准的引入文件和执行应该分开

    require_once(__DIR__ . "/vendor/autoload.php");

    use Psr0\Lib\Psr0LibClass;

    use Psr4\Lib\Psr4LibClass;

    use ClassMap\Lib\ClassMapLibClass;

    use App\Controllers\IndexController;

    use App\Models\User;

    //psr-0

    Psr0LibClass::index();

    //psr-4

    Psr4LibClass::index();

    //classmap

    ClassMapLibClass::index();

    // psr-4 规范的自动载入

    // 你应该知道去哪写代码

    IndexController::index();

    User::index();

    //files 自动加载

    hello_common();

    hello_system();

    运行结果

    #我把全路径隐藏了 就当作在当前工作目录下好了

    Psr0\Lib\Psr0LibClass@psr0/lib/src/Psr0/Lib/Psr0LibClass.php

    Psr4\Lib\Psr4LibClass@psr4/lib/src/Psr4LibClass.php

    ClassMap\Lib\ClassMapLibClass@classmap/lib/src/ClassMapAutoload.php

    App\Controllers\IndexController@app/controllers/IndexController.php

    App\Models\User@app/models/User.php

    hello_common@ext/common/functions.php

    hello_system@ext/system/functions.php

    标注:

    psr-0 规范同时兼容了 PHP5.2 版本前的为命名空间风格

    比如有一个类名为 Foo_Bar_HelloWorld 的类文件存放在

    app/Foo/Bar/HelloWorld.php 文件中

    "psr-0": {

    "Foo\\": "app/"

    }

    便可以将 Foo_Bar_HelloWorld 加载进来,原理其实就是把 _ 替换成路径分隔符 Foo/Bar/HelloWorld 然后进行加载

    Foo 命名空间会被基址到 app 目录下,继续按解析好的路径进行加载

    new Foo_Bar_HelloWorld();

    展开全文
  • 一、PSR0简介下文描述了若要使用一个通用的自动加载器(autoloader),你所需要遵守的规范:一个完全标准的命名空间(namespace)和类(class)的结构是这样的:()*每个命名空间(namespace)都必须有一个顶级的空间名...

    一、PSR0简介

    下文描述了若要使用一个通用的自动加载器(autoloader),你所需要遵守的规范:

    一个完全标准的命名空间(namespace)和类(class)的结构是这样的:()*

    每个命名空间(namespace)都必须有一个顶级的空间名(namespace)("组织名(Vendor Name)")。

    每个命名空间(namespace)中可以根据需要使用任意数量的子命名空间(sub-namespace)。

    从文件系统中加载源文件时,空间名(namespace)中的分隔符将被转换为 DIRECTORY_SEPARATOR。

    类名(class name)中的每个下划线_都将被转换为一个DIRECTORY_SEPARATOR。下划线_在空间名(namespace)中没有什么特殊的意义。

    完全标准的命名空间(namespace)和类(class)从文件系统加载源文件时将会加上.php后缀。

    组织名(vendor name),空间名(namespace),类名(class name)都由大小写字母组合而成。

    以下,列出PSR0构建的规范类的几种形式:

    e39733851ad0133f281d6459adbea831.png

    二、实现PSR0自动加载

    function autoload($className)

    {

    $className = ltrim($className, ‘\‘);

    $fileName  = ‘‘;

    $namespace = ‘‘;

    if ($lastNsPos = strrpos($className, ‘\‘)) {

    $namespace = substr($className, 0, $lastNsPos);

    $className = substr($className, $lastNsPos + 1);

    $fileName  = str_replace(‘\‘, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;

    }

    $fileName .= str_replace(‘_‘, DIRECTORY_SEPARATOR, $className) . ‘.php‘;

    require $fileName;

    }

    spl_autoload_register(‘autoload‘);

    三、PSR4简介

    这个 PSR 描述的是通过文件路径自动载入类的指南;它作为对 PSR-0 的补充;根据这个 指导如何规范存放文件来自动载入;

    术语「类」是一个泛称;它包含类,接口,traits 以及其他类似的结构;

    完全限定类名应该类似如下范例:

    ()*

    完全限定类名必须有一个顶级命名空间(Vendor Name);

    完全限定类名可以有多个子命名空间;

    完全限定类名应该有一个终止类名;

    下划线在完全限定类名中是没有特殊含义的;

    字母在完全限定类名中可以是任何大小写的组合;

    所有类名必须以大小写敏感的方式引用;

    当从完全限定类名载入文件时:

    在完全限定类名中,连续的一个或几个子命名空间构成的命名空间前缀(不包括顶级命名空间的分隔符),至少对应着至少一个基础目录。

    在「命名空间前缀」后的连续子命名空间名称对应一个「基础目录」下的子目录,其中的命名 空间分隔符表示目录分隔符。子目录名称必须和子命名空间名大小写匹配;

    终止类名对应一个以 .php 结尾的文件。文件名必须和终止类名大小写匹配;

    自动载入器的实现不可抛出任何异常,不可引发任何等级的错误;也不应返回值;

    在其中有以下的类实例,但是相对与PSR0,却是不太容易明白

    27b892116ee3e13b5b55cd230f0cdb87.png

    首先,SymfonyCoreRequest和endAcl很好理解,其满足PSR0规范,但是AcmeLogWriterFile_Writer就不太好理解了。

    四、Composer对PSR4的处理

    看了Composer对PSR4的处理,才能比较容易理解PSR4。自动生成的PSR4配置文件名称为autoload_psr4.php(PSR0的是autoload_namespace.php),配置文件返回一个关联数组,键是名称空间的前缀,值是名称空间前缀对应的路径。

    以AcmeLogWriterFile_Writer作为例子,其名称空间前缀是AcmeLogWriter,则其在autoload_psr4.php表示为

    ‘\Acme\Log\Writer‘ => (array) ‘./acme-log-writer/lib/‘

    使用自动加载时,先通过名称空间的前缀,找到对应的映射路径,在根据PSR0规范找到对应的类定义文件。但是这里有些例外,类名中的下划线在PSR4中是不需要转换成目录的。

    使用PSR4,我觉得有2个好处:

    1. 减少代码目录的深度

    2. 可以通过前缀快速找到映射目录,提高自动加载的效率

    展开全文
  • 如何在composer.json切换到PSR4? 安装 composer require symplify/psr4-switcher --dev 用法 短文件名是否与类名匹配? vendor/bin/psr4-switcher check-file-class-name src 哪些文件具有2个或更多类? vendor...
  • 使用PSR4自动加载的项目模型。 在此模型中,在登录系统和简单的CRUD中也有MVC概念的示例。 使用SwiftMailer通过smtp发送电子邮件的示例。 Docker环境安装(PHP7.1-MySQL 5.7) 在项目的根文件夹中,运行命令“ ...
  • psr0和psr4区别

    千次阅读 2017-07-11 15:23:21
    psr0和4区别一直对psr0和4了解不是很透彻,...在composer中定义的NS,psr4必须以\结尾否则会抛出异常,psr0则不要求 psr0里面最后一个\之后的类名中,如果有下划线,则会转换成路径分隔符,如Name_Space_Test会转换成N

    psr0和4区别

    一直对psr0和4了解不是很透彻,虽然官方已经废弃了psr0,但是发现composer还是对psr0向下兼容,所以也花时间从composer的加载代码中了解了一下他们的区别,具体如下:

    1. 在composer中定义的NS,psr4必须以\结尾否则会抛出异常,psr0则不要求

    2. psr0里面最后一个\之后的类名中,如果有下划线,则会转换成路径分隔符,如Name_Space_Test会转换成Name\Space\Test.php。在psr4中下划线不存在实际意义

    3. psr0有更深的目录结构,比如定义了NS为 Foo\Bar=>vendor\foo\bar\src,
      use Foo\Bar\Tool\Request调用NS。
      如果以psr0方式加载,实际的目录为vendor\foo\bar\src\Foo\Bar\Tool\Request.php
      如果以psr4方式加载,实际目录为vendor\foo\bar\src\Tool\Request.php

    介绍PSR-0之前,先来说说命名空间(NameSpace)和Autoloading吧。

    NameSpace(命名空间)

    namespace是PHP5.3版本加入的新特性,用来解决在编写类库或应用程序时创建可重用的代码如类或函数时碰到的两类问题:

    1. 用户编写的代码与PHP内部的类/函数/常量或第三方类/函数/常量之间的名字冲突。
    2. 为很长的标识符名称(通常是为了缓解第一类问题而定义的)创建一个别名(或简短)的名称,提高源代码的可读性。

    php 命名空间中的元素使用了类似文件系统的原理。例如,类名可以通过三种方式引用:

    1. 非限定名称,或不包含前缀的类名称,例如 $a=new foo(); 或 foo::staticmethod();如果当前命名空间是 currentnamespace,foo 将被解析为 currentnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,则 foo 会被解析为foo。 警告:如果命名空间中的函数或常量未定义,则该非限定的函数名称或常量名称会被解析为全局函数名称或常量名称。详情参见 使用命名空间:后备全局函数名称/常量名称。
    2. 限定名称,或包含前缀的名称,例如 $a = new subnamespace\foo(); 或 subnamespace\foo::staticmethod();。如果当前的命名空间是 currentnamespace,则 foo 会被解析为 currentnamespace\subnamespace\foo。如果使用 foo 的代码是全局的,不包含在任何命名空间中的代码,foo 会被解析为subnamespace\foo。
    3. 完全限定名称,或包含了全局前缀操作符的名称,例如, $a = new \currentnamespace\foo(); 或 \currentnamespace\foo::staticmethod();。在这种情况下,foo 总是被解析为代码中的文字名(literal name)currentnamespace\foo。

    另外注意访问任意全局类、函数或常量,都可以使用完全限定名称,例如 \strlen() 或 \Exception 或 \INI_ALL。

    use My\Full\Classname as Another, My\Full\NSname;  
    
    $obj = new Another; // 实例化一个 My\Full\Classname 对象  
    $obj = new \Another; // 实例化一个Another对象  
    $obj = new Another\thing; // 实例化一个My\Full\Classname\thing对象  
    $obj = new \Another\thing; // 实例化一个Another\thing对象  
    
    $a = \strlen('hi'); // 调用全局函数strlen  
    $b = \INI_ALL; // 访问全局常量 INI_ALL  
    $c = new \Exception('error'); // 实例化全局类 Exception  

    以上是namespace的简要介绍,对此不了解的同学还是把细读文档吧。在众多新的PHP项目中,namespace已经被普遍使用了。尤其是伴随Composer的流行,它已经是很有必要去了解的特性了。

    Autoload(自动加载)

    很多开发者写面向对象的应用程序时对每个类的定义建立一个 PHP 源文件。一个很大的烦恼是不得不在每个脚本开头写一个长长的包含(require, include)文件列表(每个类一个文件)。

    而Autoload,就是解决这个问题的,通过定义的一个或一系列autoload函数,它会在试图使用尚未被定义的类时自动调用。通过调用autoload函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类。这个autoload函数可以是默认的__autoload(),如下:

    function __autoload($class_name) {  
        require_once $class_name . '.php';  
    }  
    $obj  = new MyClass();

    也可以采用更灵活的方式,通过spl_autoload_register()来定义我们自己的__autoload()函数:

    function my_autoload($class_name) {  
        require_once $class_name . '.php';  
    }  
    spl_autoload_register("my_autoload");  
    $obj  = new MyClass(); 

    以上代码将my_autoload()函数注册到__autoload栈中,从而取到__autoload()函数(注意__autoload()函数将不再起作用,但可以显式的将其注册到__autoload栈)。注意到刚才提到了__autoload栈,意味着我们可以注册多个autoload函数,根据注册的顺序依次加载(通过spl_autoload_register的第三个参数可以改变这一顺序)。

    在这里我们展示了autoload函数最简单的例子,当然通过一些规则的设置,也可以胜任实际环境中许多复杂的情况。

    但是如果我们的项目依赖某些其他的项目,本来大家在各自独立的加载规则下能顺利运行,但融合在一起可能就不妙了。那么能否有一种通用的加载规则来解决这个问题?

    PSR-0

    PSR是由PHP Framework Interoperability Group(PHP通用性框架小组)发布的一系列标准/规范,目前包括了PSR-0~PSR-4共4个,而PSR-0就是其中的自动加载标准(其后的PSR-4称为改进的自动加载的标准,是PSR-0的补充。PSR-0使用更广泛)。https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md

    下面描述了具体互操作性的自动加载所必须的条件:

    强制要求

    一个完全合格的namespace和class必须符合这样的结构 \*
    每个namespace必须有一个顶层的namespace(”Vendor Name”提供者名字)
    每个namespace可以有多个子namespace
    当从文件系统中加载时,每个namespace的分隔符要转换成 DIRECTORY_SEPARATOR(操作系统路径分隔符)
    在CLASS NAME(类名)中,每个下划线()符号要转换成DIRECTORY_SEPARATOR。在namespace中,下划线()符号是没有(特殊)意义的。
    当从文件系统中载入时,合格的namespace和class一定是以 .php 结尾的
    verdor name,namespaces,class名可以由大小写字母组合而成(大小写敏感的)

    除此之外可能还会遵循这个规则:如果文件不存在则返回false。

    例子

    • \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
    NameSpace和Class Name中的下划线
    • \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

    将下划线转换成DIRECTORY_SEPARATOR实际上是出于兼容PHP5.3之前的版本的考虑

    实现的范例

    下面是一个按照如上标准进行自动加载的简单范例:

    function autoload($className)  
    {  
        //这里的$className一般是用namespace的方式来引用的,文章开头已有介绍  
        //去除$className左边的'\' 这是PHP5.3的一个bug,详见https://bugs.php.net/50731  
        $className = ltrim($className, '\\');  
        $fileName  = '';  
        $namespace = '';  
        //找到最后一个namespace分隔符的位置  
        if ($lastNsPos = strrpos($className, '\\')) {  
            $namespace = substr($className, 0, $lastNsPos);  
            $className = substr($className, $lastNsPos + 1);  
            $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;  
        }  
        $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';  
    
        require $fileName;  
    }

    SplClassLoader 的实现

    下面有一个SplClassLoader 的实现范例,如果你遵循了如上的标准,可以用它来进行自动加载。这也是目前PHP5.3推荐的类加载标准。http://gist.github.com/221634

    <?php        
    /* 
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
     * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
     * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
     * 
     * This software consists of voluntary contributions made by many individuals 
     * and is licensed under the MIT license. For more information, see 
     * <http://www.doctrine-project.org>. 
     */  
    
     /** 
      * SplClassLoader implementation that implements the technical interoperability 
      * standards for PHP 5.3 namespaces and class names. 
      * 
      * http://groups.google.com/group/php-standards/web/psr-0-final-proposal?pli=1 
      * 
      *     // Example which loads classes for the Doctrine Common package in the 
      *     // Doctrine\Common namespace. 
      *     $classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine'); 
      *     $classLoader->register(); 
      * 
      * @license http://www.opensource.org/licenses/mit-license.html  MIT License 
      * @author Jonathan H. Wage <jonwage@gmail.com> 
      * @author Roman S. Borschel <roman@code-factory.org> 
      * @author Matthew Weier O'Phinney <matthew@zend.com> 
      * @author Kris Wallsmith <kris.wallsmith@gmail.com> 
      * @author Fabien Potencier <fabien.potencier@symfony-project.org> 
      */  
     class SplClassLoader  
     {  
         private $_fileExtension = '.php';  
         private $_namespace;  
         private $_includePath;  
         private $_namespaceSeparator = '\\';  
    
         /** 
          * Creates a new <tt>SplClassLoader</tt> that loads classes of the 
          * specified namespace. 
          *  
          * @param string $ns The namespace to use. 
          */  
         public function __construct($ns = null, $includePath = null)  
         {  
             $this->_namespace = $ns;  
             $this->_includePath = $includePath;  
         }  
    
         /** 
          * Sets the namespace separator used by classes in the namespace of this class loader. 
          *  
          * @param string $sep The separator to use. 
          */  
         public function setNamespaceSeparator($sep)  
         {  
             $this->_namespaceSeparator = $sep;  
         }  
    
         /** 
          * Gets the namespace seperator used by classes in the namespace of this class loader. 
          * 
          * @return void 
          */  
         public function getNamespaceSeparator()  
         {  
             return $this->_namespaceSeparator;  
         }  
    
         /** 
          * Sets the base include path for all class files in the namespace of this class loader. 
          *  
          * @param string $includePath 
          */  
         public function setIncludePath($includePath)  
         {  
             $this->_includePath = $includePath;  
         }  
    
         /** 
          * Gets the base include path for all class files in the namespace of this class loader. 
          * 
          * @return string $includePath 
          */  
         public function getIncludePath()  
         {  
             return $this->_includePath;  
         }  
    
         /** 
          * Sets the file extension of class files in the namespace of this class loader. 
          *  
          * @param string $fileExtension 
          */  
         public function setFileExtension($fileExtension)  
         {  
            $this->_fileExtension = $fileExtension;  
         }  
    
         /** 
          * Gets the file extension of class files in the namespace of this class loader. 
          * 
          * @return string $fileExtension 
          */  
         public function getFileExtension()  
         {  
             return $this->_fileExtension;  
         }  
    
         /** 
          * Installs this class loader on the SPL autoload stack. 
          */  
         public function register()  
         {  
             spl_autoload_register(array($this, 'loadClass'));  
         }  
    
         /** 
          * Uninstalls this class loader from the SPL autoloader stack. 
          */  
         public function unregister()  
         {  
             spl_autoload_unregister(array($this, 'loadClass'));  
         }  
    
         /** 
          * Loads the given class or interface. 
          * 
          * @param string $className The name of the class to load. 
          * @return void 
          */  
         public function loadClass($className)  
         {  
             if (null === $this->_namespace || $this->_namespace.$this->_namespaceSeparator === substr($className, 0, strlen($this->_namespace.$this->_namespaceSeparator))) {  
                 $fileName = '';  
                 $namespace = '';  
                 if (false !== ($lastNsPos = strripos($className, $this->_namespaceSeparator))) {  
                     $namespace = substr($className, 0, $lastNsPos);  
                     $className = substr($className, $lastNsPos + 1);  
                     $fileName = str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;  
                 }  
                 $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . $this->_fileExtension;  
                 require ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName;  
            }  
        }  
    }  

    看到这里你可能还有疑问,比如psr-0中给出的例子

    \Symfony\Core\Request =>/path/to/project/lib/vendor/Symfony/Core/Request.php

    在=>号之前是我们要去加载的类,而后面的部分是这个文件在文件系统中的路径(我们实际加载的是这个)。在加载Symfony\Core\Request时,并没有同时给出实际路径来,那么是如何得到这个映射的呢?在PSR-0标准中并没有对/path/to/project/lib路径的强制要求,而是可以有自己的实现。一般有两种方式,一种就是使用php配置中的include_path(上面给出的例子有使用这个方式来做),第二种就是自己去注册这种映射,可以选用其中一种,或者两种都兼容。下面就来看看在Symfony中是怎么做的?

    <?php  
    require_once '/path/to/src/Symfony/Component/ClassLoader/ClassLoader.php';  
    
    use Symfony\Component\ClassLoader\ClassLoader;  
    
    $loader = new ClassLoader();  
    
    // to enable searching the include path (eg. for PEAR packages)  
    $loader->setUseIncludePath(true);  
    
    // ... register namespaces and prefixes here - see below  
    
    $loader->register();  
    
    // register a single namespaces  
    $loader->addPrefix('Symfony', __DIR__.'/vendor/symfony/symfony/src');  

    此时就将 Symfony 这个namespace 注册到了一个真实的路径上,Symfony的子命名空间也可以使用这个路径了。

    PSR-4

    PSR-4,称为改进的autoloading规范。

    在PSR-0中,\Symfony\Core\Request会被转换成文件系统的/path/to/project/lib/vendor/Symfony/Core/Request.php这个路径。PSR-4与PSR-0在内容上相差也不大。

    在此就不详谈两者的定义了。来看看两者在实际中的一些区别吧。由于Composer的流行,这里对Composer中这两种风格进行比较。

    在Composer中,遵循PSR-0标准的典型目录结构是这样的:

    vendor/  
        vendor_name/  
            package_name/  
                src/  
                    Vendor_Name/  
                        Package_Name/  
                            ClassName.php       # Vendor_Name\Package_Name\ClassName  
                tests/  
                    Vendor_Name/  
                        Package_Name/  
                            ClassNameTest.php   # Vendor_Name\Package_Name\ClassNameTest 

    可以看到目录结构有明显的重复而且层次很深。src/和test/目录又重新包含了Vendor和Package目录。

    再来看看PSR-4的:

    vendor/  
        vendor_name/  
            package_name/  
                src/  
                    ClassName.php       # Vendor_Name\Package_Name\ClassName  
                tests/  
                    ClassNameTest.php   # Vendor_Name\Package_Name\ClassNameTest

    可以看到目录结构更加简洁了。

    在PSR-0中目录结构要与命名空间层层对应,无法插入一个单独的目录。Vendor\Package\Class在psr-0会里被直接转换成同样的路径,而PSR-4则没有这样的强制要求。

    对比PSR-0,除了PSR-4可以更简洁外,需要注意PSR-0中对下划线(_)是有特殊的处理的,下划线会转换成DIRECTORY_SEPARATOR,这是出于对PHP5.3以前版本兼容的考虑,而PSR-4中是没有这个处理的,这也是两者比较大的一个区别。

    此外,PSR-4要求在autoloader中不允许抛出exceptions以及引发任何级别的errors,也不应该有返回值。这是因为可能注册了多个autoloaders,如果一个autoloader没有找到对应的class,应该交给下一个来处理,而不是去阻断这个通道。

    PSR-4更简洁更灵活了,但这使得它相对更复杂了。例如通过完全符合PSR-0标准的class name,通常可以明确的知道这个class的路径,而PSR-4可能就不是这样了。

        Given a foo-bar package of classes in the file system at the following paths ...  
    
            /path/to/packages/foo-bar/  
                src/  
                    Baz.php             # Foo\Bar\Baz  
                    Qux/  
                        Quux.php        # Foo\Bar\Qux\Quux  
                tests/  
                    BazTest.php         # Foo\Bar\BazTest  
                    Qux/  
                        QuuxTest.php    # Foo\Bar\Qux\QuuxTest  
    
        ... add the path to the class files for the \Foo\Bar\ namespace prefix as follows:  
            <?php  
             // instantiate the loader  
             $loader = new \Example\Psr4AutoloaderClass;  
    
             // register the autoloader  
             $loader->register();  
    
             // register the base directories for the namespace prefix  
             $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src');  
             $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests');  
    
             //此时一个namespace prefix对应到了多个"base directory"  
    
             //autoloader会去加载/path/to/packages/foo-bar/src/Qux/Quux.php  
             new \Foo\Bar\Qux\Quux;  
    
             //autoloader会去加载/path/to/packages/foo-bar/tests/Qux/QuuxTest.php  
             new \Foo\Bar\Qux\QuuxTest;  

    下面是如上PSR-4 autoloader的实现:

        <?php  
        namespace Example;  
    
        class Psr4AutoloaderClass  
        {  
            /** 
             * An associative array where the key is a namespace prefix and the value 
             * is an array of base directories for classes in that namespace. 
             * 
             * @var array 
             */  
            protected $prefixes = array();  
    
            /** 
             * Register loader with SPL autoloader stack. 
             *  
             * @return void 
             */  
            public function register()  
            {  
                spl_autoload_register(array($this, 'loadClass'));  
            }  
    
            /** 
             * Adds a base directory for a namespace prefix. 
             * 
             * @param string $prefix The namespace prefix. 
             * @param string $base_dir A base directory for class files in the 
             * namespace. 
             * @param bool $prepend If true, prepend the base directory to the stack 
             * instead of appending it; this causes it to be searched first rather 
             * than last. 
             * @return void 
             */  
            public function addNamespace($prefix, $base_dir, $prepend = false)  
            {  
                // normalize namespace prefix  
                $prefix = trim($prefix, '\\') . '\\';  
    
                // normalize the base directory with a trailing separator  
                $base_dir = rtrim($base_dir, '/') . DIRECTORY_SEPARATOR;  
                $base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/';  
    
                // initialize the namespace prefix array  
                if (isset($this->prefixes[$prefix]) === false) {  
                    $this->prefixes[$prefix] = array();  
                }  
    
                // retain the base directory for the namespace prefix  
                if ($prepend) {  
                    array_unshift($this->prefixes[$prefix], $base_dir);  
                } else {  
                    array_push($this->prefixes[$prefix], $base_dir);  
                }  
            }  
    
            /** 
             * Loads the class file for a given class name. 
             * 
             * @param string $class The fully-qualified class name. 
             * @return mixed The mapped file name on success, or boolean false on 
             * failure. 
             */  
            public function loadClass($class)  
            {  
                // the current namespace prefix  
                $prefix = $class;  
    
                // work backwards through the namespace names of the fully-qualified  
                // class name to find a mapped file name  
                while (false !== $pos = strrpos($prefix, '\\')) {  
    
                    // retain the trailing namespace separator in the prefix  
                    $prefix = substr($class, 0, $pos + 1);  
    
                    // the rest is the relative class name  
                    $relative_class = substr($class, $pos + 1);  
    
                    // try to load a mapped file for the prefix and relative class  
                    $mapped_file = $this->loadMappedFile($prefix, $relative_class);  
                    if ($mapped_file) {  
                        return $mapped_file;  
                    }  
    
                    // remove the trailing namespace separator for the next iteration  
                    // of strrpos()  
                    $prefix = rtrim($prefix, '\\');     
                }  
    
                // never found a mapped file  
                return false;  
            }  
    
            /** 
             * Load the mapped file for a namespace prefix and relative class. 
             *  
             * @param string $prefix The namespace prefix. 
             * @param string $relative_class The relative class name. 
             * @return mixed Boolean false if no mapped file can be loaded, or the 
             * name of the mapped file that was loaded. 
             */  
            protected function loadMappedFile($prefix, $relative_class)  
            {  
                // are there any base directories for this namespace prefix?  
                if (isset($this->prefixes[$prefix]) === false) {  
                    return false;  
                }  
    
                // look through base directories for this namespace prefix  
                foreach ($this->prefixes[$prefix] as $base_dir) {  
    
                    // replace the namespace prefix with the base directory,  
                    // replace namespace separators with directory separators  
                    // in the relative class name, append with .php  
                    $file = $base_dir  
                          . str_replace('\\', DIRECTORY_SEPARATOR, $relative_class)  
                          . '.php';  
                    $file = $base_dir  
                          . str_replace('\\', '/', $relative_class)  
                          . '.php';  
    
                    // if the mapped file exists, require it  
                    if ($this->requireFile($file)) {  
                        // yes, we're done  
                        return $file;  
                    }  
                }  
    
                // never found it  
                return false;  
            }  
    
            /** 
             * If a file exists, require it from the file system. 
             *  
             * @param string $file The file to require. 
             * @return bool True if the file exists, false if not. 
             */  
            protected function requireFile($file)  
            {  
                if (file_exists($file)) {  
                    require $file;  
                    return true;  
                }  
                return false;  
            }  
        }  

    单元测试代码:

        <?php  
        namespace Example\Tests;  
    
        class MockPsr4AutoloaderClass extends Psr4AutoloaderClass  
        {  
            protected $files = array();  
    
            public function setFiles(array $files)  
            {  
                $this->files = $files;  
            }  
    
            protected function requireFile($file)  
            {  
                return in_array($file, $this->files);  
            }  
        }  
    
        class Psr4AutoloaderClassTest extends \PHPUnit_Framework_TestCase  
        {  
            protected $loader;  
    
            protected function setUp()  
            {  
                $this->loader = new MockPsr4AutoloaderClass;  
    
                $this->loader->setFiles(array(  
                    '/vendor/foo.bar/src/ClassName.php',  
                    '/vendor/foo.bar/src/DoomClassName.php',  
                    '/vendor/foo.bar/tests/ClassNameTest.php',  
                    '/vendor/foo.bardoom/src/ClassName.php',  
                    '/vendor/foo.bar.baz.dib/src/ClassName.php',  
                    '/vendor/foo.bar.baz.dib.zim.gir/src/ClassName.php',  
                ));  
    
                $this->loader->addNamespace(  
                    'Foo\Bar',  
                    '/vendor/foo.bar/src'  
                );  
    
                $this->loader->addNamespace(  
                    'Foo\Bar',  
                    '/vendor/foo.bar/tests'  
                );  
    
                $this->loader->addNamespace(  
                    'Foo\BarDoom',  
                    '/vendor/foo.bardoom/src'  
                );  
    
                $this->loader->addNamespace(  
                    'Foo\Bar\Baz\Dib',  
                    '/vendor/foo.bar.baz.dib/src'  
                );  
    
                $this->loader->addNamespace(  
                    'Foo\Bar\Baz\Dib\Zim\Gir',  
                    '/vendor/foo.bar.baz.dib.zim.gir/src'  
                );  
            }  
    
            public function testExistingFile()  
            {  
                $actual = $this->loader->loadClass('Foo\Bar\ClassName');  
                $expect = '/vendor/foo.bar/src/ClassName.php';  
                $this->assertSame($expect, $actual);  
    
                $actual = $this->loader->loadClass('Foo\Bar\ClassNameTest');  
                $expect = '/vendor/foo.bar/tests/ClassNameTest.php';  
                $this->assertSame($expect, $actual);  
            }  
    
            public function testMissingFile()  
            {  
                $actual = $this->loader->loadClass('No_Vendor\No_Package\NoClass');  
                $this->assertFalse($actual);  
            }  
    
            public function testDeepFile()  
            {  
                $actual = $this->loader->loadClass('Foo\Bar\Baz\Dib\Zim\Gir\ClassName');  
                $expect = '/vendor/foo.bar.baz.dib.zim.gir/src/ClassName.php';  
                $this->assertSame($expect, $actual);  
            }  
    
            public function testConfusion()  
            {  
                $actual = $this->loader->loadClass('Foo\Bar\DoomClassName');  
                $expect = '/vendor/foo.bar/src/DoomClassName.php';  
                $this->assertSame($expect, $actual);  
    
                $actual = $this->loader->loadClass('Foo\BarDoom\ClassName');  
                $expect = '/vendor/foo.bardoom/src/ClassName.php';  
                $this->assertSame($expect, $actual);  
            }  
        }  
    展开全文
  • PSR-1:基本编码标准 标准的这一部分包括应被认为是确保共享PHP代码之间实现高水平技术互操作性所需的标准编码元素。 本文档中的关键字“必须”,“不得”,“必须”,“应”,“应禁止”,“应”,“不应...

    PHP编码规范-PSR1

    详细见php规范官网:

    https://www.php-fig.org/psr/psr-1/

    https://www.php-fig.org/psr/psr-2/

    https://www.php-fig.org/psr/psr-3/

    https://www.php-fig.org/psr/psr-4/

    PSR-1:基本编码标准

    标准的这一部分包括应被认为是确保共享PHP代码之间实现高水平技术互操作性所需的标准编码元素。

    本文档中的关键字“必须”,“不得”,“必须”,“应”,“应禁止”,“应”,“不应”,“推荐”,“可以”和“可选”是按照RFC 2119中的描述进行解释。

    1.概述

    • 文件只能使用<?php<?=标记。

    • 文件必须仅使用UTF-8,而不能将BOM用于PHP代码。

    • 文件应该任一声明的符号(类,函数,常量等) 引起副作用(例如生成输出,变化的.ini设置,等等),但是不应该这样做既。

    • 命名空间和类必须遵循“自动加载” PSR:[ PSR-0PSR-4 ]。

    • 类名必须在中声明StudlyCaps

    • 类常量必须在所有大写字母中使用下划线分隔符声明。

    • 方法名称必须在中声明camelCase

    • PSR-2:

    2.PSR-2概述(最新版见psr12)

    • 代码必须遵循“编码样式指南” PSR [ PSR-1 ]。

    • 代码必须使用4个空格来缩进,不能使用制表符。

    • 线长绝不能有硬性限制;软限制必须为120个字符;每行不得超过80个字符。

    • namespace声明后必须有一个空白行,use声明块后必须有一个空白行。

    • 类的开括号必须在下一行,闭括号必须在正文之后的下一行。

    • 方法的右括号必须在下一行,而右括号必须在正文之后的下一行。

    • 必须在所有属性和方法上声明可见性;abstract并且 final必须在可见性之前声明;static必须在可见性之后声明。

    • 控制结构关键字必须在其后有一个空格;方法和函数调用绝不能。

    • 控制结构的开括号必须在同一行上,闭括号必须在主体之后的下一行上。

    • 控制结构的开括号必须在其后没有空格,控制结构的闭括号必须在其前没有空格。

    2.PSR1详细说明

    2.1。PHP标签

    PHP代码必须使用long 标记或short-echo 标记;它绝对不能使用其他标签变体。<?php ?><?= ?>

    2.2。字符编码

    PHP代码必须仅使用没有BOM的UTF-8。

    2.3。副作用

    文件应该声明新的符号(类,函数,常量等),并且不会引起其他副作用,或者文件应该执行具有副作用的逻辑,但不能两者都做。

    短语“副作用”表示仅通过包括文件就不与声明类,函数,常量等直接相关的逻辑的执行。

    “副作用”包括但不限于:生成输出,显式使用requireinclude,连接到外部服务,修改ini设置,发出错误或异常,修改全局或静态变量,读取或写入文件等等。

    以下是同时具有声明和副作用的文件示例;即,应避免的示例:

    <?php
    // side effect: change ini settings
    ini_set('error_reporting', E_ALL);
    
    // side effect: loads a file
    include "file.php";
    
    // side effect: generates output
    echo "<html>\n";
    
    // declaration
    function foo()
    {
        // function body
    }
     

    以下示例是一个包含无副作用声明的文件。即,要模拟的示例:

    <?php
    // declaration
    function foo()
    {
        // function body
    }
    
    // conditional declaration is *not* a side effect
    if (! function_exists('bar')) {
        function bar()
        {
            // function body
        }
    }
     

    3.命名空间和类名

    命名空间和类必须遵循“自动加载” PSR:[ PSR-0PSR-4 ]。

    这意味着每个类本身都在文件中,并且在至少一个级别的名称空间中:顶级供应商名称。

    类名必须在中声明StudlyCaps

    为PHP 5.3和之后编写的代码必须使用正式的名称空间。

    例如:

    <?php
    // PHP 5.3 and later:
    namespace Vendor\Model;
    
    class Foo
    {
    }
     

    为5.2.x和之前版本编写的代码应Vendor_在类名上使用前缀的伪命名间隔约定。

    <?php
    // PHP 5.2.x and earlier:
    class Vendor_Model_Foo
    {
    }
     

    4.类常量,属性和方法

    术语“类”是指所有类,接口和特征。

    4.1。常数

    类常量必须在所有大写字母中使用下划线分隔符声明。例如:

    <?php
    namespace Vendor\Model;
    
    class Foo
    {
        const VERSION = '1.0';
        const DATE_APPROVED = '2012-06-01';
    }
     

    4.2。物产

    本指南有意避免关于使用任何建议 $StudlyCaps$camelCase$under_score属性名称。

    无论使用哪种命名约定,都应在合理范围内一致地应用。该范围可以是供应商级,程序包级,类级或方法级。

    4.3。方法

    方法名称必须在中声明camelCase()

     

    PHP编码规范-PSR2

    1.概述

    • 代码必须遵循“编码样式指南” PSR [ PSR-1 ]。

    • 代码必须使用4个空格来缩进,不能使用制表符。

    • 线长绝不能有硬性限制;软限制必须为120个字符;每行不得超过80个字符。

    • namespace声明后必须有一个空白行,use声明块后必须有一个空白行。

    • 类的开括号必须在下一行,闭括号必须在正文之后的下一行。

    • 方法的右括号必须在下一行,而右括号必须在正文之后的下一行。

    • 必须在所有属性和方法上声明可见性;abstract并且 final必须在可见性之前声明;static必须在可见性之后声明。

    • 控制结构关键字必须在其后有一个空格;方法和函数调用绝不能。

    • 控制结构的开括号必须在同一行上,闭括号必须在主体之后的下一行上。

    • 控制结构的开括号必须在其后没有空格,控制结构的闭括号必须在其前没有空格。

     

    展开全文
  • PSR4自动加载自定义类

    2019-11-22 17:25:47
    PSR4自动加载自定义类笔者需求具体实现方法利用composer的autoload实现ThinkPHP框架配置文件实现 笔者需求 基于ThinkPHP实现PSR4自动加载自定义类; 具体实现方法 方法1:.利用composer的autoload; 方法2:利用...
  • 根据官方PHP SDK DEMO改写,去除了SDK中的lotusphp框架,改成支持PSR4命名空间导入方式使用,并且重新封装接口,更便于调用。
  • 1.psr0 这是个啥东西呢,这是一个标准。一个实现自动加载类的标准。在这之前你需要先了解__autoload 和spl_autoload_register这两个方法。为什么要实现这个标准呢?如果整个项目是自己写的不需要任何其他人的代码,...
  • 在composer中的实践,我理解大概是这样的psr4中在composer.json里面配置的映射关系 composer install的时候写入vendor/composer/autoload_psr4.php 供加载使用。 { "autoload": { "psr-4": { "Monolog\\": ...
  • PSR4是一种自动加载规范,老版本是PSR0,尽管thinkPHP支持PSR4和PSR0的自动加载方式,但是默认也是优先进行PSR4加载,如果失败,再进行PSR0的加载。本篇文章只会讨论PSR4的加载。代码示例:spl_autoload_register...
  • 关于php规范psr4与psr0命名空间的理解

    千次阅读 2017-07-19 11:38:18
    use 命名空间只是防止命名空间的冲突,使用时...与psr0不同,psr4不再转换 '_' 为文件分隔符,且 psr4有前缀gainia 以tp5的自动加载为例 Loader.php -> autoload() -> findFile() /** * 查找文件 * @param $class
  • http://www.cnblogs.com/xp796/p/6441700.html 转载于:https://www.cnblogs.com/songyanan/p/10836938.html
  • 第二部分是如何通过类名找到该文件并引入 入口方法:ClassLoader.php中的loadClass(),寻找顺序是 先classMap里找 再PSR4 PSR0 找 // class map lookup if (isset($this->classMap[$class])) { return $this->class...
  • PSR4 目录映射

    2018-06-03 16:33:21
    PSR4 VS PSR01.在类名中使用下划线没有任何特殊含义。2. 命名空间与文件目录的映射方法有所调整。假如我们有一个命名空间:Foo/classFoo 是顶级命名空间,其存在着用户定义的与目录的映射关系:"Foo/" =&...
  • PHP规范PSR4(自动加载)介绍

    千次阅读 2018-10-28 09:19:24
    本文档中的关键词“必须”,...它完全可互操作,除了包括PSR-0在内的任何其他自动加载规范外,还可以使用它。此PSR还描述了根据规范放置将自动加载的文件的位置。 2 细则 (1)术语“类”指的是类,接口,特征和其...
  • composer自动加载psr4规则

    千次阅读 2018-05-28 09:56:09
    #生成环境下使用 composer dump-atoload -o #这里的意思是composer dump-autoload --optimize,不是用的话会损失性能。...psr-4":{ "DB\\":"db/", "Util\\":"util/"
  • PSR规范0-4整理

    2021-03-30 08:04:28
    PSR规范psr规范引言: PSR 是 PHP Standard Recommendations 的简写,由 PHP FIG 组织制定的 PHP 规范,是 PHP 开发的实践标准。这些规范的目的是:通过框架作者或者框架的代表之间讨论,以最低程度的限制,制定一个...
  • PHP规范psr0-psr4

    2018-08-06 09:39:16
    1. PSR是什么?  PSR(PHP StandardsRecommendation)PHP 推荐规范的简称。是一种代码格式规范。   2. PSR1:基本代码风格  PSR1的代码要满足以下要求:  1) 必须把代码放在 \&lt;\?PHP\?\&gt;” ...
  • 就是这个联盟组织发明和创造了PSR规范,其中自动加载涉及其中两个规范,一个是PSR0,一个是PSR4, PSR0规范已经过时了,官方有提示,现在主要是用PSR4规范定义自动加载标准。2.PRS4简介这个 PSR 描述的是通过文件...
  • psr0和psr4规范

    2019-05-16 22:56:40
    一.Psr0 一个完全标准的命名空间(namespace)和类(class)的结构是这样的:\<Vendor Name>\(<Namespace>\)*<Class Name> 每个命名空间(namespace)都必须有一个顶级的空间名(namespace)("组织名...
  • 目录结构如下:├─app │ └─controller │ └─StudentController.php ├─view │ ├─resource │ │ └─StudentView.php │ └─Test.php ├─AutoLoad.php └─index.php StudentController.... clas
  • netbeans-psr-formatting, PSR 1 & 2的NetBeans配置设置 用于NetBeans的 PSR自动格式库提供了 PHP PSR1 和 PSR2标准的源代码自动格式设置。尽管并不提供对所有和 PSR2'规则'的自动格式支持( 例如。 重构类和方法名...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,529
精华内容 8,211
关键字:

PSR4