дата: 2017-12-10 22:24:18 название: интерпретация исходного кода laravel
Исходный код yii/laravel высокого качества, phper должен внимательно его прочитать
Интерпретация исходного кода:Карта мозга Baidu.com/file/9's 4 не 5...
Несколько блогов, которые я недавно написал, очень длинные, без подробностей, и студенты с небольшими базовыми знаниями, похоже, знают, как это делать.КомфортныйНекоторые, но студенты с лучшей базой, почувствуют, что они недостаточно глубоки.галантерейные товарыНедостаточно И писать длинную статью действительно утомительно, поэтому в этой статье мы попытаемся сосредоточиться на структуре фреймворка, общей структуре и идеях, а также на деталях, и я поделюсь ею с вами позже.
жизненный цикл
Если вы знакомы с моими одноклассниками, то знаете, что я уделяю особое внимание этой концепции.Жизненный цикл является хорошим мостом, соединяющим конкретный бизнес и лежащую в его основе реализацию.Знание жизненного цикла может не только развивать способности разработки программного обеспечения, но также развивать способность понимать бизнес.
Важная вещь зацикливается бесконечно: жизненный цикл.
жизненный цикл ларавеля:
инициализация
- использовать
$basePath
инициализация(new
)Illuminate\Foundation\Application
, класс приложения на самом деле является контейнером для разрешения зависимостей классов, следуйтеPSRстандартный - Привязка приложения (
bind
) 3 синглтона:App\Http\Kernel
,App\Console\Kernel
,App\Exceptions\Handler
, запрос выполняется конкретным ядром. Зависимости, используемые контейнером для разрешения класса,По требованиюДа, здесь указаносинглтонОбратите внимание на laravel Основные моменты: Привязка выполняется в соответствии сIlluminate\Contracts\Xxx -> App\xxx
Ограничения для достижения, глобальное единство.Контракт мы продолжим говорить об этом позже.
специфическое лечение
- Приложение в зависимости от сцены (веб/консоль), создание экземпляра (
make
) в соответствующее ядро - В процессе инстанцирования ядра сначала войдите в этап начальной загрузки: регистрация (
register
) ServiceProvider, выполняемый Приложением, примечаниерегистрЭто необходимозаявление об отношениях, на самом деле выполняется контейнеромПо требованиюнагрузка. - Используйте информацию в глобальной переменной php для инициализации объекта запроса, например
$_SERVER
- Ядро обрабатывает объект Request и возвращает объект Response.
- Наконец, ядро выполняет метод terminate() для завершения
Ядро обрабатывает процесс запроса
- Сначала запустите определенное ПО промежуточного слоя
- Передайте его объекту Router для обработки: сопоставление маршрута, сопоставление с замыканием/контроллером для логической обработки и возврата данных.
- Соберите данные, возвращенные выше, и соберите их в объект Response в соответствии с некоторыми другими конфигурациями, такими как формат
Вы обнаружите, что знакомый MVC не упоминается, потому что MVC также имеет приложение для управления объектами один за другим, а также все другие службы.
Имея основу Container и понимание жизненного цикла, вы можете заполнять код по мере необходимости в соответствии с бизнесом.
Контракт Контракт
Жизненный цикл и контейнер в основном одинаковы для современных фреймворков.Давайте поговорим о разнице между laravel и Contract.
Сначала представим две идеи программирования:
интерфейсно-ориентированное программирование
соглашение о конфигурации
Эти две идеи на самом деле пересекаются, подчеркивая, что в спецификации проекта системыопределениеа такжевыполнитьдолжны быть разделены.
laravel всегда практиковал эту идею, навсегдаопределениеВо-первых, все функции, предоставляемые фреймворком, можно найти здесь.источник, Некоторые люди также любят говорить «да».тень.
Проще говоря: мне все равно, как этого добиться, я все равно должен следовать тому, что говорю.
Да, реальность на самом деле такова, она нужна всемтанцевать в цепях.
В laravel для определения функции/сервиса вам необходимо выполнить следующие шаги:
- Определить интерфейс в контракте
- Foundation определяет базовую реализацию, большое количество Traits и основных функций, связанных с этим сервисом.
- Реализация конкретной функции/службы должна быть реализована в соответствии с определением в контракте, и необходимо добавить ServiceProvider для регистрации службы в контейнере.
- Поддержка предоставляет некоторые общие, неспецифические независимые от бизнеса/сервиса вспомогательные методы для использования при реализации конкретных функций/сервисов.
После того, как этот набор завершен, мы можем следоватьXxxServiceProvider
определенный в методе register(), используйте$app['xxx']
Эта форма для доступа к нужным нам услугам.
Например:
// AuthServiceProvider
protected function registerAuthenticator()
{
$this->app->singleton('auth', function ($app) {
// Once the authentication service has actually been requested by the developer
// we will set a variable in the application indicating such. This helps us
// know that we need to set any queued cookies in the after event later.
$app['auth.loaded'] = true;
return new AuthManager($app);
});
$this->app->singleton('auth.driver', function ($app) {
return $app['auth']->guard();
});
}
// 需要使用 Auth 服务
$auth = $app['auth']
Вот подсказка, обычно устанавливает свойство класса$app
, назначаемый приложению при инициализации фреймворка, чтобы можно было использовать все зависимости$app
Переменные обрабатываются единообразно, лаконично и просто.
Почему на laravel так удобно писать
Этот заголовок на самом деле объясняет слоган laravel:
Love beautiful code? We do too. The PHP Framework For Web Artisans
С частями, представленными выше, все основные функции, которые нам нужны, были использованы, а остальное зависит от того, как мы планируем его использовать.Фактически, был введен метод:$app['auth']
, вызовите зарегистрированную службу аутентификации.
DI
DI, внедрение зависимости, внедрение зависимости.Этот метод более распространен:
// 框架提供的注册功能
/**
* Handle a registration request for the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function register(Request $request)
{
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
$this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
Передаем нужный нам класс прямо в параметре функции\Illuminate\Http\Request $request
, то контейнер автоматически предоставит нам этот класс для использования
helper function
Поговорим о вспомогательной функции в широком смысле, которая реализуется автоматической загрузкой composer:
// laravel/framework/src/composer.json
"autoload": {
"files": [
"src/Illuminate/Foundation/helpers.php",
"src/Illuminate/Support/helpers.php"
],
"psr-4": {
"Illuminate\\": "src/Illuminate/"
}
},
Как вы можете видеть здесь, laravel зарегистрировал 2 типа вспомогательных функций:
-
Foundation/helpers.php
: Вспомогательные функции, связанные с функциями фреймворка. -
Support/helpers.php
: общие вспомогательные функции, независимые от функций фреймворка, такие как обработка массивов, обработка строк.
Вот вспомогательные функции, связанные с функциями фреймворка:
// 核心函数
function app($abstract = null, array $parameters = [])
{
if (is_null($abstract)) {
return Container::getInstance(); // 相当于上面的 $app
}
return Container::getInstance()->make($abstract, $parameters); // 相当于上面的 $app['auth']
}
// 使用效果
app() -> $app
app('auth') -> $app['auth']
Посмотрите, как это удобно, на примере службы кэширования:
// 实现
function cache()
{
$arguments = func_get_args();
if (empty($arguments)) {
return app('cache');
}
if (is_string($arguments[0])) {
return app('cache')->get($arguments[0], $arguments[1] ?? null);
}
if (! is_array($arguments[0])) {
throw new Exception(
'When setting a value in the cache, you must pass an array of key / value pairs.'
);
}
if (! isset($arguments[1])) {
throw new Exception(
'You must specify an expiration time when setting a value in the cache.'
);
}
return app('cache')->put(key($arguments[0]), reset($arguments[0]), $arguments[1]);
}
// 使用效果
cache($key); // 获取缓存
cache($key, $value); // 设置缓存
Разве это не удобно?
Facade
Шаблон проектирования фасадов: упростите приложение, обернув фасады, скрыв определенные детали объектов.
Давайте сначала посмотрим на эффект, также используя приведенный выше Cache в качестве примера:
\Cache::get($key);
\Cache::set($key, $value);
Кажется, это немного сложнее, чем вспомогательная функция. Давайте сделаем это в конце. Посмотрим, как реализован Facade.
Сначала настройте новый Facede в соответствии с официальной документацией:
- первый пришел
config/app.php
Регистрация в, регистрация ServiceProvider также здесь - Создайте новый класс Facede, унаследованный от
Illuminate\Support\Facades\Facade
Например, фасад кэша здесь:
namespace Illuminate\Support\Facades;
class Cache extends Facade
{
protected static function getFacadeAccessor() // 只需要实现这个函数就好
{
return 'cache';
}
}
В чем принцип?Illuminate\Support\Facades\Facade
код:
// 魔法函数
public static function __callStatic($method, $args)
{
$instance = static::getFacadeRoot(); // 上面实现的 getFacadeAccessor() 就在这里使用到, 最后其实返回的 $app['cache']
if (! $instance) {
throw new RuntimeException('A facade root has not been set.');
}
return $instance->$method(...$args);
}
Итак, выполнить\Cache::get($key);
наконец казнен$app['cache']->get($key);
Проанализировав это, каждый обнаружит, что на самом деле все крутится вокруг$app
вращаться,заверните, реализует множество различных методов записи.
3 способа сравнить
Прежде всего, давайте посмотрим на DI и Facade, интересно, у всех ли будет такой же вопрос, как у меня:
// 书写控制器代码时, 有 2 种方式:
public function index(Request $request)
{
$input = $request->all();
}
public function index()
{
$input = Request::all();
}
Когда напишем Запрос, редактор предложит выйти 2\Illuminate\Http\Request
а также\Request
.Когда я впервые соприкоснулась с этим местом, то долго недоумевала, его теперь все могут отличить, один ДИ, другой Фасад, хотя названиеТакой же.
В этом примере также можно увидеть разницу между DI и Facade.
Давайте посмотрим на Facade и вспомогательную функцию.На самом деле, некоторые из вышеперечисленных перечислены.По крайней мере, приведенный выше пример кажется немного более кратким для вспомогательной функции, но это ограничено:
Cache::get($key, $timeout); // 缓存可以设置过期时间, Cache Facade 直接加一下参数就行了
cache()->get($key, $timeout); // Cache helper function 没有封装, 所有要先用 cache() 来返回 $app['cache'], 然后再调用
Так много способов достичь, вы чувствуетеНемного кружится голова, как сказал чиновникИзобразительное искусство ?
С большей свободой написания (аббревиатуры) совершенно очевидно, что повышается производительность.
Конечно, стенография приносит проблему подсказок кода, что повлияет на производительность, это можно увидеть в моем предыдущем посте.блог - Давайте поговорим о советах по коду php.
Последний взгляд
Например, сервис Cache можно использовать по-разному, но когда мы его используем, мы все одинаковы, как это реализовано?
- Первый, или Контракт,Мне все равно, как этого добиться, это просто то, что я говорю, это последовательно во всем
- Затем, когда есть несколько способов реализовать это, laravel идиоматически
manager-driver
Сюда
Или возьмем в качестве примера службу Cache:
// CacheServiceProvider 中这样注册的服务
public function register()
{
$this->app->singleton('cache', function ($app) { // 这就是我们常用的 $app['cache'], 实际使用的 CacheManager
return new CacheManager($app);
});
$this->app->singleton('cache.store', function ($app) { // 继续看
return $app['cache']->driver();
});
...
}
// CacheManager
// 魔法函数, 比如执行 $app['cahe']->get($key), 其实最终执行的 $this->store()->get($key)
public function __call($method, $parameters)
{
return $this->store()->$method(...$parameters);
}
public function store($name = null)
{
$name = $name ?: $this->getDefaultDriver();
return $this->stores[$name] = $this->get($name);
}
Продолжайте читать код, вы обнаружите, что окончательный проход$name
найти классcreate{$ame}()
метод создания экземпляра$this->store()
этоmanager-driver
способ, широко используемый в laravel, например файловая система, уведомление, очередь
напиши в конце
Писал-писал и обнаружил, что это еще одна длинная статья, простоУстала, Очевидно, что это очень простая вещь, просто посмотрите на код и прочитайте его по крупицам, но для того, чтобы написать текст, требуется так много времени.
Очевидно, очень простые вещи, разберитесь с жизненным циклом и лежащей в его основе реализацией, а для остального прочитайте код по крупицам.