频道栏目
首页 > 资讯 > 其他 > 正文

Slim研读笔记:Composer使用安全

17-12-01        来源:[db:作者]  
收藏   我要投稿
上章节,我们自制了一款属于我们自己的Slim框架样板项目。这章节,我们从网络请求开始的地方index.php来研读slim框架。
getContainer();

// 在容器中注册Monolog日志组件
$container['logger'] = function($c) {
    $logger = new \Monolog\Logger('my_logger');
    $file_handler = new \Monolog\Handler\StreamHandler('../logs/app.log');
    $logger->pushHandler($file_handler);
    return $logger;
};

// 在容器中注册Illuquent数据库Orm组件
$container['db'] = function ($c) {
    $capsule = new \Illuminate\Database\Capsule\Manager;
    $capsule->addConnection($c['settings']['db']);

    $capsule->setAsGlobal();
    $capsule->bootEloquent();

    return $capsule;
};

// 在容器中注册Twig模板引擎组件
$container['view'] = function ($c) {
    $view = new \Slim\Views\Twig('../templates', [
        'cache' => '../storage/cache'
    ]);

    // 实例化并添加Slim特定的扩展
    $basePath = rtrim(str_ireplace('index.php', '', $c['request']->getUri()->getBasePath()), '/');
    $view->addExtension(new \Slim\Views\TwigExtension($c['router'], $basePath));
    return $view;
};

// 在路由中渲染Twig模板
$app->get('/hello/{name}', function (Request $request, Response $response, $args) {
    //$name = $request->getAttribute('name');
    //$response->getBody()->write("hello, $name");
    //return $response;
    return $this->view->render($response, 'index.htm', [
        'name' => $args['name']
    ]);
})->setName('myname');

$app->get('/', function(){
    // 日志功能测试
    $this->logger->addInfo("发生了一件有趣的事,并把它记录了下来");

    // 数据库ORM对象测试
    $users = $this->db->table('users')->get();

    return "hello world";

});

$app->run();
这是index.php的全部内容。我们会顺序对其进行分析,首先是
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
Psr\Http\Message是和PSR-7 HTTP消息接口相关的组件我们要使用它,必须先了解PSR-7接口规范。

PSR-7 HTTP消息接口

在PSR系列规范之前,PHP大牛们各自为战,代码命名千奇百怪,自动加载方式随心所欲。各项目的规范状态令人堪忧。后来PHPFIG为了实现组件间的互操作性,并为实现最佳编程和测试实践而制定了PSR规范。PSR并非官方规范,但其包含了众多知名开源项目参与并制定使其成为PHP项目的最佳规范。PSR-7 HTTP消息接口是已实施的PSR规范之一。HTTP消息是web开发的基础,Web浏览器和HTTP客户端创建发送到Web服务器的HTTP请求消息,然后由服务端返回HTTP响应消息。
每个HTTP请求消息都有特定的格式。
POST /path HTTP/1.1
Host: example.com

foo=bar&baz=bat
请求的第一行是“请求行”,包含了HTTP请求方法,请求目标地址(通常为一个绝对URL或Web服务器路径),HTTP协议版本号。接下来是一个或多个HTTP头,一个空行和消息内容。
HTTP响应也具有相似的结构。
HTTP/1.1 200 OK
Content-Type: text/plain

This is the response body
第一行是“状态行”,一次包含HTTP协议版本号,HTTP状态码以及对状态码进行描述的“原因短语”。接下来是一个或多个HTTP头,一个空行和一行消息内容。
PSR-7规范就是对HTTP消息与构成他们元素的抽象,该规范制定了抽象HTTP消息的接口。这里先进行PSR规范及PSR7消息接口的简单介绍,后面在看到源码的具体使用时再对其进行深入探讨。

Composer

代码中我们引入了Composer,Compser是管理依赖关系的工具。它允许你申明项目所依赖的代码库,它会在你的项目中为你安装他们。
Composer准备了一个自动加载文件,它可以加载Composer下载的库中的所有的类文件,使用它,你仅需这一行代码就足够:
require '../vendor/autoload.php’;
进入../vendor/autoload.php,看到如下代码
这行代码是Composer自动生成的,具体的生成方式我们暂时不必知道。第一行是引入了composer/autoload_real.php,第二行是调用autoload_real.php中的ComposerAutoloaderInitXxxx类的getLoader()方法。进入该类继续深剖…
class ComposerAutoloaderInit2b0e34f11c87555a88f83f6bf964b679{   
    private static $loader;
    public static function loadClassLoader($class)    {        
        // 引入ClassLoader.php        
        if ('Composer\Autoload\ClassLoader' === $class) {            
            require __DIR__ . '/ClassLoader.php’;        
        }    
    }
    public static function getLoader()    {        
        // 典型的单例模式        
        if (null !== self::$loader) {            
            return self::$loader;        
        }
        // 注册一个自动加载函数到autoload队列中,由于第三个参数prepend为true,则队列会预先加载自动加载器loadClassLoader。
        // 这意味着spl队列会首先使用loadClassLoader对应的自动加载器        
        spl_autoload_register(array('ComposerAutoloaderInit2b0e34f11c87555a88f83f6bf964b679', 'loadClassLoader'), true, true);
        // 上面刚刚声明这里就已经用到啦,使用当前类的loadClassLoader方法,同时将返回值赋给静态变量$loader        
        self::$loader = $loader = new \Composer\Autoload\ClassLoader();                
        // 将刚刚注册到autoload队列的loaderClassLoader自动加载器舍弃掉(反正已获取到Composer的加载类对象到self::$loader,这个加载器也就用不到了) 
        spl_autoload_unregister(array('ComposerAutoloaderInit2b0e34f11c87555a88f83f6bf964b679', 'loadClassLoader'));
        。。。
问题变得愈发地清晰了,现在关键是要了解$loader的值——ClassLoader的类对象具体包含了哪些可用的方法?
通过注释我们了解到ClassLoader实现了PSR-0,PSR-4和类映射classmap的自动加载器。该自动加载器是如何实现的呢?如示例:
$loader = new \Composer\Autoload\ClassLoader();    
// register classes with namespaces     
$loader->add('Symfony\Component', __DIR__.'/component');     
$loader->add('Symfony', __DIR__.'/framework');     
// activate the autoloader     
$loader->register();     
// to enable searching the include path (eg. for PEAR packages)     
$loader->setUseIncludePath(true);
在这个例子中,如果你尝试使用使用一个类在Symfony\Component命名空间或它的子命名空间(如Symfony\Component\Console)。自动加载器将会在component/*目录寻找类,如果没有寻找到该类它会回退到framework/目录。既然提到PSR4规范,那么我们更为详细的介绍PSR4.

PSR-4自动加载规范

PSR-0和PSR-4均是自动加载规范,目前PSR-0已被废弃。

一个完整的类名需要具备\<命名空间名>(\<子命名空间名>)*\<类名>这种格式。

完全限定类名必须有一个顶级命名空间(Vendor Name);完全限定类名可以有多个子命名空间;完全限定类名应该有一个终止类名;下划线在完全限定类名中是没有特殊含义的;字母在完全限定类名中可以是任何大小写的组合;所有类名必须以大小写敏感的方式引用;

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

在完全限定类名中,连续的一个或几个子命名空间构成的命名空间前缀(不包括顶级命名空间的分隔符),至少对应着至少一个基础目录。在「命名空间前缀」后的连续子命名空间名称对应一个「基础目录」下的子目录,其中的命名空间分隔符表示目录分隔符。子目录名称必须和子命名空间名大小写匹配;终止类名对应一个以.php结尾的文件。文件名必须和终止类名大小写匹配;自动载入器的实现不可抛出任何异常,不可引发任何等级的错误;也不应返回值;

在Composer使用PSR-4风格

vendor/

vendor_name/

package_name/

src/

ClassName.php # Vendor_Name\Package_Name\ClassName

tests/

ClassNameTest.php # Vendor_Name\Package_Name\ClassNameTest

好了,今天关于Composer的学习就到此为止吧,我们今天介绍了Composer的引入,PSR7 HTTP消息接口、PSR-4自动加载规范,下节中我们会继续深入到Composer的ClassLoader类去学习Composer是如何实现类的自动加载的。

相关TAG标签
上一篇:远程Linux上部署Redis
下一篇:matlab_N皇后问题的处理方法
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站