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();
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ResponseInterface as Response;
POST /path HTTP/1.1 Host: example.com foo=bar&baz=bat
HTTP/1.1 200 OK Content-Type: text/plain This is the response body
require '../vendor/autoload.php’;
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 = 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);
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是如何实现类的自动加载的。