Laravel被称为“全栈”式框架,因为它处理从网络服务到数据库管理,直到HTML生成的一切事情,一个垂直集成的web开发环境能给开发者提供更好的体验。
一个典型的程序员通过命令行工具与Laravel交互,生成和管理Laravel项目环境。Laravel带有一个名为Artisan的优秀的命令行工具,可以用它来生成框架代码和数据库架构,Artisan能够处理从数据库架构迁移到资源和配置管理的一切事情。
首先看看总体的目录
app:开发主目录,以后开发多数代码都在里面
bootstrap:用来存放系统启动时需要的文件,这些文件会被如index.php这样的文件调用。
config:配置文件
public:这个文件夹是唯一外界可以看到的,是必须指向你web服务器的目录。它含有laravel框架核心的引导文件index.php,这个目录也可用来存放任何可以公开的静态资源,如css,Javascript,images等。
database:数据库生成文件,就是使用artisan命令生成的包含一些 PHP 类,允许 Laravel更新当前数据库的架构并同时保持所有版本的数据库的同步。迁移文件是使用Artisan工具生成的。
resource:包含了view以及一些资源文件
storage:该目录存储Laravel各种服务的临时文件,如session, cache, compiled view templates。这个目录在web服务器上必须是可以写入的。该目录由Laravel维护,我们可以不关心。
tests:testdemo
vendor:用来存放所有的第三方代码,在一个典型的Laravel应用程序,这包括Laravel源代码及其相关,并含有额外的预包装功能的插件。
好!总体目录架构我们已经看清楚了,然后就细致的研究某些文件了,看了看手册,发现了这么一些文件很有特色!
按照正常的逻辑。
一般的框架都是喜欢用xml来控制配置,这会导致很多繁琐的问题!但是larvarel不同呢!
laravel的约束大于控制!
我们在这里找来几个比较典型的文件研究下:
config/database.php
laravel和一般的框架一样,也有自己的数据库配置设置文件,一般都是在config.php里面写上一个数组返回文件,但是5.3里面有一个写的很漂亮的地方,他把数据库的配置写到了根目录的.env文件夹下
然后在database.php用
env这个函数读取,但是我在IDE里面没有检索出来这个文件有点奇怪。
这点写的很好,避免了直接暴露出来数据库的各种信息!
然后跟踪,env函数,找到了这个路径:
打开!
if (! function_exists('env')) {
/**
* Gets the value of an environment variable. Supports boolean, empty and null.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
function env($key, $default = null)
{
$value = getenv($key);//获取系统的环境变量
if ($value === false) {
return value($default);
}
switch (strtolower($value)) {
case 'true':
case '(true)':
return true;
case 'false':
case '(false)':
return false;
case 'empty':
case '(empty)':
return '';
case 'null':
case '(null)':
return;
}
if (strlen($value) > 1 && Str::startsWith($value, '"') && Str::endsWith($value, '"')) {
return substr($value, 1, -1);
}
return $value;
}
}
代码鲁棒性很棒,加上了function_exists()做判断然后在写这个函数!!然后getenv获取这个变量是否在内存里面!
不在则返回null.
好好,貌似有点走题了,我们看代码还是从入口文件开始把。
上面我们的入口文件是在: public/index.php里面
根据一些资料可以得到:
- 入口文件 index.php
- Illuminate\Foundation\Application 类
- 注入所有基础 Service Provider
然后我们看代码:
第22行根据PSR-0约定是自动加载规范。
require __DIR__.'/../bootstrap/autoload.php';
引入autoload.php文件,好我们跟踪下:
这其实就是一个自动加载的文件,将Vendor加载进来了
require __DIR__.'/../vendor/autoload.php';
其次是cache
$compiledPath = __DIR__.'/cache/compiled.php';
在看看vendor里面也有一个autoload.php也是自动加载的,在进去以后,看到了这行代码,难道这就是传说中的composer依赖包?
return ComposerAutoloaderInit67db7509c61e60a4f92e012c704d3566::getLoader();
在composer文件夹下发现了
autoload_real.php文件,从里面找到了这个类
使用了spl_autoload_register
spl_autoload_register(array('ComposerAutoloaderInit67db7509c61e60a4f92e012c704d3566', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit67db7509c61e60a4f92e012c704d3566', 'loadClassLoader'));
看到了这三行代码。将自动加载类注册到_autoload队列,然后在new这个类,在解绑。干净利落的过程。
在看看ClassLoader()类里面有这么一行:
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
其实可以直接renturn array_merge($this->prefixesPsr0)的。。。但是优雅。。。
在继续往下看其实就没有什么了,目的是在于把Vendor的目录全部注册到map里面,用Vendor下的autoload.php集合分发。
待所有的class文件都集合起来之后,
然后看这行代码
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
就把所有Vendor下包含的类文件全部送入__autoload队列中。
同理还要自动加载cache文件,这里就不多说了。