5 php functional-programming laravel laravel-5 laravel-5.3
我对PHP和Laravel 还很陌生。我正在按照本教程向我的 Laravel 应用程序中的页面添加reCAPTCHA支持:
http://tutsnare.com/how-to-use-captcha-in-laravel-5/
无论如何,我的怀疑与验证码无关,而是与上一教程的内容有关:
如您所见,添加此服务提供者:
'providers' => [
Anhskohbo\NoCaptcha\NoCaptchaServiceProvider::class,
],
Run Code Online (Sandbox Code Playgroud)
据我了解阅读官方文档:https : //laravel.com/docs/5.4/providers
一个的ServiceProvider是登记在其启动时使用我的应用程序“组件”的东西。
但这究竟是什么意思?
我试图了解它研究以前的NoCaptchaServiceProvider类并将其与文档进行比较。
所以这是它的代码:
<?php
namespace Anhskohbo\NoCaptcha;
use Illuminate\Support\ServiceProvider;
class NoCaptchaServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Bootstrap the application events.
*/
public function boot()
{
$app = $this->app;
$this->bootConfig();
$app['validator']->extend('captcha', function ($attribute, $value) use ($app) {
return $app['captcha']->verifyResponse($value, $app['request']->getClientIp());
});
if ($app->bound('form')) {
$app['form']->macro('captcha', function ($attributes = []) use ($app) {
return $app['captcha']->display($attributes, $app->getLocale());
});
}
}
/**
* Booting configure.
*/
protected function bootConfig()
{
$path = __DIR__.'/config/captcha.php';
$this->mergeConfigFrom($path, 'captcha');
if (function_exists('config_path')) {
$this->publishes([$path => config_path('captcha.php')]);
}
}
/**
* Register the service provider.
*/
public function register()
{
$this->app->singleton('captcha', function ($app) {
return new NoCaptcha(
$app['config']['captcha.secret'],
$app['config']['captcha.sitekey']
);
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return ['captcha'];
}
}
Run Code Online (Sandbox Code Playgroud)
它包含了:
1) register()方法:
public function register()
{
$this->app->singleton('captcha', function ($app) {
return new NoCaptcha(
$app['config']['captcha.secret'],
$app['config']['captcha.sitekey']
);
});
}
Run Code Online (Sandbox Code Playgroud)
它只将东西绑定到服务容器中。在这种情况下,它需要存储到.env文件中的2 个值。这些值包含 re-CAPTCHA 字符串。
我的疑问是:在应用程序启动时 Laravel 调用register()方法,但到底发生了什么?。
register()方法的这一部分是什么意思?
$this->app->singleton('captcha', function ($app) {
return new NoCaptcha(
$app['config']['captcha.secret'],
$app['config']['captcha.sitekey']
);
});
Run Code Online (Sandbox Code Playgroud)
谁是$this?我认为它是NoCaptchaServiceProvider实例(但我不太确定),是它还是我遗漏了什么?
$this->app是什么意思?app 是方法还是属性?
什么意思$this->app->singleton('captcha'.....}); 我认为它就像一个工厂实现了某个东西的单个实例......但是到底在构建什么?它是 **NoCaptcha实例吗?
我认为之前单例构建的逻辑是由内部函数实现的:
function ($app) {
return new NoCaptcha(
$app['config']['captcha.secret'],
$app['config']['captcha.sitekey']
);
Run Code Online (Sandbox Code Playgroud)在这里我有两个疑问:
第一个是:谁将$app传递给这个函数?它是否类似于稍后将填充的空变量\对象?还是以某种方式注入?
这个函数好像是创建单例的逻辑。因为它放在里面:
singleton('captcha', function ($app) {
return new NoCaptcha(
$app['config']['captcha.secret'],
$app['config']['captcha.sitekey']
);
});
Run Code Online (Sandbox Code Playgroud)
那是什么意思呢?这意味着当调用singleton()方法时,会执行返回新NoCaptcha对象的这个函数,它代表了我的单例创建逻辑?
所以这意味着 PHP 以某种方式实现了函数式编程范式?
$this指的是 NoCaptchaServiceProvider。
NoCaptchaServiceProvider 扩展了服务提供者。它具有属性$app ,它是\Illuminate\Contracts\Foundation\Application又名 Laravel 应用程序的实例。
创建新的服务提供者时,Laravel 会将应用程序实例注入到服务提供者的构造函数中:
public function __construct($app)
{
$this->app = $app;
}
Run Code Online (Sandbox Code Playgroud)
因此,$this->app您正在检索laravel 应用程序实例。
应用程序实例扩展了Container类,该类具有singleton()方法。它只是在容器中注册一个共享绑定。
public function singleton($abstract, $concrete = null)
{
$this->bind($abstract, $concrete, true);
}
Run Code Online (Sandbox Code Playgroud)
编辑:请注意,这些名称空间指的是合同,而不是实际的类。
服务容器的作用是将接口绑定到给定的实现。契约(或接口)只是告诉类应该实现哪些方法。
例如:我们有 UserRepository,它有 UserRepositoryContract,它告诉某个实现需要具有 all() 和 find() 函数。我们将该 Contract 绑定到 EloquentUserRepository,它只是一个实现这些方法并使用 Eloquent 返回 all() 和 find() 的类。
现在我们唯一需要做的就是设置绑定并使用 UserRepositoryContract 作为实例而不是 EloquentUserRepository。
如果我们以后想使用 Redis,我们只需要创建一个实现相同方法的 RedisUserRepository 类,更改容器中的绑定即可。现在所有 UserRepositoryContract 实例都将使用 Redis 而不是 Eloquent。