Slim研读笔记三之Composer(上)
来源:互联网 发布:gbgb55域名永久获取 编辑:程序博客网 时间:2024/06/04 19:38
上章节,我们自制了一款属于我们自己的Slim框架样板项目。这章节,我们从网络请求开始的地方index.php来研读slim框架。
<?phpuse Psr\Http\Message\ServerRequestInterface as Request;use Psr\Http\Message\ResponseInterface as Response;require '../vendor/autoload.php';// 数据库配置$config = require '../config/databases.php';// 声明一个应用主体对象并加载配置文件$app = new \Slim\App($config);// 依赖注入容器$container = $app->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.1Host: example.comfoo=bar&baz=bat
请求的第一行是“请求行”,包含了HTTP请求方法,请求目标地址(通常为一个绝对URL或Web服务器路径),HTTP协议版本号。接下来是一个或多个HTTP头,一个空行和消息内容。
HTTP响应也具有相似的结构。
HTTP/1.1 200 OKContent-Type: text/plainThis 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,看到如下代码
<?php// autoload.php @generated by Composerrequire_once __DIR__ . '/composer/autoload_real.php';return ComposerAutoloaderInit2b0e34f11c87555a88f83f6bf964b679::getLoader();
这行代码是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是如何实现类的自动加载的。
阅读全文
1 0
- Slim研读笔记三之Composer(上)
- Slim研读笔记四之Composer(下)
- Slim研读笔记五之依赖注入容器(上)
- Slim研读笔记六之应用主体(上)
- Slim研读笔记七乱入篇之Monolog(上)
- Slim研读笔记七之应用程序中间件(上)
- Slim研读笔记八之路由(上)
- Slim研读笔记五之依赖注入容器(中)
- Slim研读笔记五之依赖注入容器(下)
- Slim研读笔记五之依赖注入容器(补)
- Slim研读笔记七乱入篇之Monolog(中)
- Slim研读笔记七乱入篇之Monolog(下)
- Slim研读笔记六之应用主体(中)
- Slim研读笔记六之应用主体(下)
- Slim研读笔记七之应用程序中间件(下)
- Slim研读笔记七乱入篇之Monolog(补)
- Slim研读笔记八之路由(中)
- Slim研读笔记二之造一款Slim应用
- 垃圾收集器
- 《悟空传》绘本---by乱舞
- TM1638八位数码管八按键驱动程序(stm32f103驱动,使用了stm32 3.5库)
- Android 动画1--View控件的显示和隐藏效果
- 总结——STM32F103C8T6通过MAX31865读取PT100电阻值
- Slim研读笔记三之Composer(上)
- C和指针之动态内存分配之编程练习4
- python打印平行四边形
- JUC-ArrayBlockingQueue学习
- 总结——调试STM32F103ZET6及外围传感器_电路图设计问题+SHT10温湿度传感器
- 【RealVnc Error】Raspberry pi 3B RealVnc bad escape code 0x50
- 初识Shader着色器
- Android studio导入第三方jar包出现java.util.zip.ZipException错误
- 生子