架构
首先,应该了解larravel框架的架构模式(设计核心,larravel架构是使用服务组件化开发模式开发的,larravelframework由不同的服务组件组成)
larravel中的多个服务提供商构成了larravel组件。分层设计:将具有相同功能的类库放在同一文件夹中。
larravel框架具有组成服务和组件的多个类。类->服务->组件
Larravel使用基于组件的开发模式,具有多个类->服务->组件,多个类构成服务,多个服务构成组件。
多个组件提供不同的服务,然后多个服务构成我们的项目。
视图方法
如所见,传递给视图方法的第一个参数是resources/views目录中相应视图文件的名称,第二个参数是包含视图中所有有效数据的数组。在本例中,我们传递一个名称变量,该变量通过使用Blade语法显示在视图中。
当然,视图也可以存储在resources/views的子目录中。嵌套视图可以用“.”符号引用。例如,如果视图存储路径是resources/views/admin/profile.blade。php,我们可以如下引用它:
<?php
namespace App\Providers;
use View;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
View::share('key', 'value');
}
public function register()
{
//
}
}
视图生成器是呈现视图时的回调函数或类方法。如果每次渲染视图时都要绑定一些数据,则可以使用view Composer将逻辑组织到一个单独的位置。
在本例中,首先在服务提供商中注册视图Composer。我们将使用View facade访问Illuminate Contracts View Factory的底层实现。请记住,Larave不包含默认视图Composer目录。我们可以根据自己的喜好来组织它的路径。例如,我们可以创建app/Http/View/Compoers目录:
<?php
namespace App\Http\ViewComposers;
use Illuminate\View\View;
use Illuminate\Repositories\UserRepository;
class ProfileComposer
{
protected $users;
public function __construct(UserRepository $users)
{
$this->users = $users;
public function compose(View $view)
{
$view->with('count', $this->users->count());
}
}
在渲染视图之前,将调用Composer类的Compose方法,并将Illuminate view视图实例注入到该方法中,以便可以使用其with方法将数据绑定到视图。
注意:所有视图Composer都通过服务容器进行解析,因此可以在Composer类的构造函数中声明所需的任何依赖项。
View::composer(
['profile', 'dashboard'],
'App\Http\ViewComposers\MyViewComposer'
);
视图创建者与视图编写器非常相似。不同之处在于前者在视图实例化后立即失败,而不是等待视图呈现。使用视图外观的创建者方法注册视图创建者:
View::creator('profile', 'App\Http\ViewCreators\ProfileCreator');
内置会话
Larvel没有使用PHP的内置会话功能,而是实现了一种更灵活、更强大的会话机制。核心逻辑请参考Illuminate Session中间件StartSession的中间件。因此,在Larvel应用程序中,不应尝试使用$_通过session方法获取应用程序的会话值是徒劳的。此外,还有一个大家都很困惑的问题。无法在Larravel的控制器构造函数中获取应用程序会话数据。这是因为Larravel的会话是通过StartSession中间件启动的。由于它是中间件,它将在服务容器注册所有服务后执行,而控制器的构造函数在容器注册服务时执行,因此此时会话尚未启动。如何获取数据?解决方案是发布获取会话数据的逻辑,或者在构造函数中引入StartSession之后执行的中间件。
Schema::create('sessions', function ($table) {
$table->string('id')->unique();
$table->unsignedInteger('user_id')->nullable();
$table->string('ip_address', 45)->nullable();
$table->text('user_agent')->nullable();
$table->text('payload');
$table->integer('last_activity');
});
会话配置文件位于config/session php中默认情况下,Larave使用的会话驱动程序是文件驱动程序,这对许多应用程序来说都没有问题。在生产环境中,可以考虑使用Memcached或Redis驱动程序来获得更好的会话性能,特别是当同一个在线应用程序部署到多台机器时。这是最佳实践。
会话驱动程序用于定义所请求的会话数据的存储位置。Larave可以处理多种类型的驱动程序:
文件–会话数据存储在存储/框架/会话目录中;
Cookie–会话数据存储在已安全加密的Cookie中;
数据库–会话数据存储在数据库中
Memcached/Redis–会话数据存储在Memcached/Redis缓存中,访问速度最快;
Array–会话数据存储在一个简单的PHP数组中,在多个请求之间是非持久的。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UserController extends Controller{
public function show(Request $request, $id)
{
$value = $request->session()->get('key');
//
}
}
由于这些方法不容易理解,让我们快速了解每种方法:
开放方法用于基于文件的会话存储系统。由于Larave已经有一个文件会话驱动程序,因此不需要在该方法中放置任何代码。可以将其设置为空方法。
与open方法一样,close方法也可以忽略,这是大多数驱动程序所不使用的。
read方法应返回与给定$sessionId匹配的会话数据的字符串版本。从驱动程序获取或存储会话数据不需要序列化或其他编码,因为Larravel已经为我们序列化了它。
write方法应该将给定的$data写入持久存储系统(如MongoDB、Dynamo等)的相应$sessionId。同样,不要执行任何序列化操作。拉拉威尔已经为我们处理过了。
<?php
namespace App\Extensions;
class MongoSessionHandler implements SessionHandlerInterface
{
public function open($savePath, $sessionName) {}
public function close() {}
public function read($sessionId) {}
public function write($sessionId, $data) {}
public function destroy($sessionId) {}
public function gc($lifetime) {}
}
destroy方法从持久存储中删除与$sessionId对应的数据。
gc方法销毁所有大于给定$lifetime的会话数据。对于具有过期机制的系统,如Memcached和Redis,此方法可以留空。
注册驱动程序
会话驱动程序实现后,需要向框架注册它。要向Larravel会话的后端添加其他驱动程序,可以在会话外观上使用extend方法。我们在服务提供商(如AppServiceProvider)的引导方法中调用此方法(或者我们可以自己重新创建一个新的服务提供商):
<?php
namespace App\Providers;
use App\Extensions\MongoSessionHandler;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\ServiceProvider;
class SessionServiceProvider extends ServiceProvider
{
public function boot()
{
Session::extend('mongo', function($app) {
return new MongoSessionHandler;
});
}
public function register()
{
//
}
}
有时,可能希望存储仅在会话中的下一个请求中有效的数据。这可以通过闪光法实现。此方法中存储的会话数据仅在后续HTTP请求中有效,将被删除.
如果需要在更多请求中保留一次性数据,可以使用刷新方法将所有一次性数据保留到下一个请求中。如果只想保存特定的一次性数据,可以使用keep方法:
$request->session()->reflash();
$request->session()->keep(['username', 'email']);