laravel sql注入Request 依赖注入报错是怎么回事?

看了laravel的php框架怎么感觉很不靠谱_百度知道
看了laravel的php框架怎么感觉很不靠谱
这也要求你非常熟练php。因此laravel是一个适合学习的框架,依赖注入。另外其实很多事情并不复杂。很多东西一旦想通也就那么回事儿,laravel 的确不是一流和优秀的框架、这里难哪里难,怕的是复杂的理论内容,等等,我只能说,以及各种各样的设计模式,他和其他的框架思想有着极大的不同。如果你觉得laravel很困难 那么原因只有一个 你php基础不够好。laravel最大的特点和优秀之处就是集合了php比较新的特性,Ioc容器,基础扎实,你会发现,善于利用命名空间和面向对象的诸多特性,去追寻一些东西,原来这一切这么容易。很多人觉得 laravel 这不好那不好
其他类似问题
为您推荐:
php框架的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁Laravel 5.0 之方法注入 - 推酷
Laravel 5.0 之方法注入
Laravel 5.0 中, 容器可以对其解析的方法进行自动分析, 然后根据类型限制把方法所需要的依赖项自动注入. 本文将介绍这一机制的原理, 何时解析, 如何注入等.
依赖注入的背景知识
在现代编程实践中, PHP 开发者要学会的首要知识之一就是使用依赖注入. 这就是 SOLID(
依赖反转(Dependency Inversion)
Laravel 的
被称为 IOC(Inversion of Control) 容器, 之所以如此命名, 是因为它允许开发者掌控应用底层所发生的事件: 在顶层代码(controllers, 扩展类等)中请求一个实例, 比如 &mailer&, 容器就会返回一个 &mailer& 的实例. 这样, 顶层代码不关注底层到底是由哪个服务来发送邮件--不管是 Mandrill, Mailgun 还是 SendMail, 都不重要, 因为所有 mailer 类都实现相同的接口.
Laravel 4 中的构造函数注入
下面是一个以前的依赖注入的示例:
class Listener
protected $
public function __construct(Mailer $mailer)
$this-&mailer = $
public function userWasAdded(User $user)
// Do some stuff...
$this-&mailer-&send('emails.welcome', ['user' =& $user], function($message)
$message-&to($user-&email, $user-&name)-&subject('Welcome!');
从例子中可以看到, 可以通过构造函数把 Mailer 类注入到对象. Laravel 的容器让实例化这样的一个类变得很容易, 因为它会自动把依赖项注入构造函数. 比如, 我们可以创建该类的一个新实例, 但不需要传入 Mailer. 因为 Laravel 自动分析构造函数, 知道并且自动替我们注入了这个对象.
$listener = App::make('Listener');
这很方便, 因为
在应用中可以只定义一次 Mailer 的具体实现, 而不是每次都要指定.
由于采用了依赖注入, 更便于进行测试.
假如只是对象中的某一个方法需要用到注入的类呢? 构造函数会因为很多只用到一次的注入变得非常凌乱.
另一种情况, 假如需要通过注入类执行某些操作, 但只针对特定的方法执行呢? 比如 FormRequests 和 ValidatesUponResolved.
上述问题的解决方案就是方法注入: 类似构造函数注入, 但允许容器要调用某个方法的时候直接给该方法注入依赖项.
我觉得方法注入最普遍的应用场景就是控制器(controllers). 比如前文提到的 FormRequests 就是一个最好的例子. 但有关 FormRequests 之前已经有详细的介绍, 所以这次我们举点别的例子:
class DashboardController extends Controller
public function showMoneyDashboard(MoneyRepository $money)
$usefulMoneyStuff = $money-&getUsefulStuff();
return View::make('dashboards.money')
-&with('stuff', $usefulMoneyStuff);
public function showTasksDashboard(TasksRepository $tasks)
$usefulTasksStuff = $tasks-&getUsefulStuff();
return View::make('dashboards.tasks')
-&with('stuff', $usefulTasksStuff);
public function showSupervisionDashboard(SupervisionRepository $supervision)
$usefulSupervisionStuff = $supervision-&getUsefulStuff();
return View::make('dashboards.supervision')
-&with('stuff', $usefulSupervisionStuff);
我们把控制器的 public methods 映射到路由, 用户访问对应的路由时, 容器会调用这些方法, 并自动注入指定的依赖项. 非常棒, 非常简洁.
容器在什么时候会解析方法
前文介绍的控制器方法会被容器解析. ServiceProvider 的
方法也会. 实际上你可以根据你的需要指定容器对任何方法进行解析. 比如:
class ThingDoer
public function doThing($thing_key, ThingRepository $repository)
$thing = $repository-&getThing($thing_key);
$thing-&do();
然后可以在控制器中通过
App::call()
App::call()
的第二个参数是可选的, 它接受以数组方式提供的被调用方法所需的参数:
namespace App\Http\C
use Illuminate\Contracts\Container\C
use Illuminate\Routing\C
class ThingController extends Controller
public function doThing(Container $container)
$thingDoer = $container-&make('ThingDoer');
// 调用 $thingDoer 对象的 doThing 方法, 并传入 $thing_key 参数,
// 参数的值是 'awesome-parameter-here'
$container-&call(
[$thingDoer, 'doThing'],
['thing_key' =& 'awesome-parameter-here']
在 Laravel 核心代码中, 用方法注入实现了一些有用的系统功能, 比如 FormRequest. 但别让这些案例局限了你的思维. 它只是让代码保持精简的一个手段, 而我们都需要简洁的代码.
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致Laravel实现构造函数自动依赖注入的方法【站长博客网】
Laravel实现构造函数自动依赖注入的方法
作者:小谈博客 来源:网络整理 时间: 23:24
这篇文章主要介绍了Laravel实现构造函数自动依赖注入的方法,涉及Laravel构造函数自动初始化的相关技巧,需要的朋友可以参考下
相关推荐:
本文实例讲述了Laravel实现构造函数自动依赖注入的方法。分享给大家供大家参考,具体如下:
在Laravel的构造函数中可以实现自动依赖注入,而不需要实例化之前先实例化需要的类,如代码所示:
namespace Lio\Http\Controllers\F
use Lio\Forum\Replies\ReplyR
use Lio\Forum\Threads\ThreadC
use Lio\Forum\Threads\ThreadCreatorL
use Lio\Forum\Threads\ThreadDeleterL
use Lio\Forum\Threads\ThreadF
use Lio\Forum\Threads\ThreadR
use Lio\Forum\Threads\ThreadUpdaterL
use Lio\Http\Controllers\C
use Lio\Tags\TagR
class ForumThreadsController extends Controller implements ThreadCreatorListener, ThreadUpdaterListener, ThreadDeleterListener
protected $
protected $
protected $currentS
protected $threadC
public function __construct(
ThreadRepository $threads,
ReplyRepository $replies,
TagRepository $tags,
ThreadCreator $threadCreator
$this-&threads = $
$this-&tags = $
$this-&threadCreator = $threadC
$this-&replies = $
注意构造函数中的几个类型约束,其实并没有地方实例化这个Controller并把这几个类型的参数传进去,Laravel会自动检测类的构造函数中的类型约束参数,并自动识别是否初始化并传入。
源码vendor/illuminate/container/Container.php中的build方法:
$constructor = $reflector-&getConstructor();
dump($constructor);
这里会解析类的构造函数,在这里打印看:
它会找出构造函数的参数,再看完整的build方法进行的操作:
public function build($concrete, array $parameters = [])
// If the concrete type is actually a Closure, we will just execute it and
// hand back the results of the functions, which allows functions to be
// used as resolvers for more fine-tuned resolution of these objects.
if ($concrete instanceof Closure) {
return $concrete($this, $parameters);
$reflector = new ReflectionClass($concrete);
// If the type is not instantiable, the developer is attempting to resolve
// an abstract type such as an Interface of Abstract Class and there is
// no binding registered for the abstractions so we need to bail out.
if (! $reflector-&isInstantiable()) {
$message = "Target [$concrete] is not instantiable.";
throw new BindingResolutionContractException($message);
$this-&buildStack[] = $
$constructor = $reflector-&getConstructor();
// If there are no constructors, that means there are no dependencies then
// we can just resolve the instances of the objects right away, without
// resolving any other types or dependencies out of these containers.
if (is_null($constructor)) {
array_pop($this-&buildStack);
return new $
$dependencies = $constructor-&getParameters();
// Once we have all the constructor's parameters we can create each of the
// dependency instances and then use the reflection instances to make a
// new instance of this class, injecting the created dependencies in.
$parameters = $this-&keyParametersByArgument(
$dependencies, $parameters
$instances = $this-&getDependencies(
$dependencies, $parameters
array_pop($this-&buildStack);
return $reflector-&newInstanceArgs($instances);
具体从容器中获取实例的方法:
protected function resolveClass(ReflectionParameter $parameter)
return $this-&make($parameter-&getClass()-&name);
// If we can not resolve the class instance, we will check to see if the value
// is optional, and if it is we will return the optional parameter value as
// the value of the dependency, similarly to how we do this with scalars.
catch (BindingResolutionContractException $e) {
if ($parameter-&isOptional()) {
return $parameter-&getDefaultValue();
框架底层通过Reflection反射为开发节省了很多细节,实现了自动依赖注入。这里不做继续深入研究了。
写了一个模拟这个过程的类测试:
class kulou
class junjun
class tanteng
public function __construct(kulou $kulou,junjun $junjun)
$this-&kulou = $
$this-&junjun = $
//$tanteng = new tanteng(new kulou(),new junjun());
$reflector = new ReflectionClass('tanteng');
$constructor = $reflector-&getConstructor();
$dependencies = $constructor-&getParameters();
print_r($dependencies);
原理是通过ReflectionClass类解析类的构造函数,并且取出构造函数的参数,从而判断依赖关系,从容器中取,并自动注入。
转自:小谈博客 /2016/01/laravel-construct-ioc/
更多关于Laravel相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》、《》、《》、《》及《》
希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。
大家感兴趣的内容
最近更新的内容关于扩展 Laravel 默认 Session 中间件导致的 Session 写入失效问题分析
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了关于扩展 Laravel 默认 Session 中间件导致的 Session 写入失效问题分析的相关资料,需要的朋友可以参考下
最近由于项目开发需要,手机客户端和网页端统一使用一套接口,为保证 会话(Session) 能够正常且在各类情况下兼容,我希望能够改变 SessionID 的获取方式。默认情况下,所有网站都是通过 HTTP 请求的 Header 头部中的 Cookie 实现的,通过 Cookie 中指定的 SessionID 来关联到服务端对应数据,从而实现会话功能。
但对于手机客户端,可能并不会支持原始的 Cookie,亦或者根据平台需要而屏蔽,因此开发中要求通过增加一个请求头 X-Session-Token 来标识 SessionID。在 Laravel 框架中,实现 Session 初始化、读取和启动,都是通过 Illuminate\Session\Middleware\StartSession 这个中间件实现的,该中间件有一个关键方法 getSession ,这个方法就是获取 SessionId 从而告知 Session 组件以什么凭据恢复 Session 数据。
该中间件注册于 app/Http/Kernel.php 文件下。
我新建了一个类继承该中间件,同时替换了在 app/Http/Kernel.php 下的注册的地方,原来的 getSession 方法源码如下:
public function getSession(Request $request)
$session = $this-&manager-&driver();
$session-&setId($request-&cookies-&get($session-&getName()));
在新的中间件中,我修改为:
public function getSession(Request $request)
$session = $this-&manager-&driver();
// 判断是否是接口访问并根据实际情况选择 SessionID 的获取方式
if ($request-&headers-&has('x-session-token')) {
$sessionId = $request-&headers-&has('x-session-token');
$sessionId = $request-&cookies-&get($session-&getName());
$session-&setId($sessionId);
但是麻烦也随之而来。。。
修改完后,推送至分支,在合并至主开发分支之前往往需要跑一下单元测试,不幸的是,之前通过的 Case 这回竟然报错,问题是 CSRF 组件 报出 Token 错误,而我们在这一处提供的 Token 跟平时并无二致,问题肯定出在 Session 上。
值得注意的是,我修改中间件的代码,对框架的影响可以说根本没有,事实上也确实没有,因为我将我自己创建的中间件代码修改成继承的中间件代码一致也无济于事,但奇怪的是,在我将中间件换回原来的中间件就没有这个问题。
于是我将正常情况下和非正常情况下的代码都跑了一遍,在关键处断点调试,发现问题出在中间件的一个重要属性 $sessionHandled , 若该值为 false 则会引起我们之前的状况。关键在于,中间件启动之时,都会走 handle 方法,而对于 Session 这个中间件, handle 方法的第一行代码就是:
$this-&sessionHandled =
Interesting。。。
我们知道。Laravel 框架的特色是其 IoC 容器,框架中初始化各种类都是由其负责以实现各种依赖注入,以保证组件间的松耦合。中间件定然不例外。要知道,单例和普通实例最大的区别在于无论创建多少次,单例永远都是一个,实例中的属性不会被初始化,因此无问题的中间件必然是一个单例,而我自己创建的中间件只是个普通的类的实例。但本着知其然更要知其所以然,我需要确认我这一想法(其实解决办法已经想到了,后面说)。
那么问题大致就在于初始化中间件这块了,于是不得不打起精神,仔细理一下 Laravel 的启动代码。而这里面的重点,在于一个叫 Illuminate\Pipeline\Pipeline 的类。
这个类有三个重要方法 send 、 through 、 then 。其中 then 是开始一切的钥匙。这个类主要是连续执行几个框架启动步骤的玩意儿,首先是初始化处理过程需要的组件(Request 和 中间件),其次是将请求通过这些处理组件构成的堆栈(一堆中间件和路由派发组件),最后是返回处理结果(Response)。
可以说这玩意儿是 Laravel Http 部分的核心(额,,本来就是 Kernel)。那么之前的问题就在于 Pipeline 的 then 方法和其调用的 getSlice 方法,直接观察 getSlice 方法,可以发现它负责的是生成处理堆栈,并实例化 Middleware (中间件)类,整个方法代码如下:
protected function getSlice()
return function ($stack, $pipe) {
return function ($passable) use ($stack, $pipe) {
if ($pipe instanceof Closure) {
return call_user_func($pipe, $passable, $stack);
list($name, $parameters) = $this-&parsePipeString($pipe);
return call_user_func_array([$this-&container-&make($name), $this-&method],
array_merge([$passable, $stack], $parameters));
可以注意到 $this-&container-&make($name) ,这意味着其初始化一个中间件类,单纯的就是 make,若其不是单例则反复 new ,导致之前的属性被初始化。
那么解决办法也显而易见面,使其成为一个单例。
我在 app/Providers/AppServiceProvider.php 的 register 方法中添加如下一行代码,就解决了之前的问题:
$this-&app-&singleton(SessionStart::class); // SessionStart 是我那个中间件类名
以上给大家介绍了扩展 Laravel 默认 Session 中间件导致的 Session 写入失效问题分析的全部内容,希望大家喜欢。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具Laravel实现构造函数自动依赖注入的方法,laravel构造函数-android100学习网
Laravel实现构造函数自动依赖注入的方法,laravel构造函数
Laravel实现构造函数自动依赖注入的方法,laravel构造函数本文实例讲述了Laravel实现构造函数自动依赖注入的方法。分享给大家供大家参考,具体如下:在Laravel的构造函数中可
Laravel实现构造函数自动依赖注入的方法,laravel构造函数
本文实例讲述了Laravel实现构造函数自动依赖注入的方法。分享给大家供大家参考,具体如下:
在Laravel的构造函数中可以实现自动依赖注入,而不需要实例化之前先实例化需要的类,如代码所示:
namespace Lio\Http\Controllers\F
use Lio\Forum\Replies\ReplyR
use Lio\Forum\Threads\ThreadC
use Lio\Forum\Threads\ThreadCreatorL
use Lio\Forum\Threads\ThreadDeleterL
use Lio\Forum\Threads\ThreadF
use Lio\Forum\Threads\ThreadR
use Lio\Forum\Threads\ThreadUpdaterL
use Lio\Http\Controllers\C
use Lio\Tags\TagR
class ForumThreadsController extends Controller implements ThreadCreatorListener, ThreadUpdaterListener, ThreadDeleterListener
protected $
protected $
protected $currentS
protected $threadC
public function __construct(
ThreadRepository $threads,
ReplyRepository $replies,
TagRepository $tags,
ThreadCreator $threadCreator
$this-&threads = $
$this-&tags = $
$this-&threadCreator = $threadC
$this-&replies = $
注意构造函数中的几个类型约束,其实并没有地方实例化这个Controller并把这几个类型的参数传进去,Laravel会自动检测类的构造函数中的类型约束参数,并自动识别是否初始化并传入。
源码vendor/illuminate/container/Container.php中的build方法:
$constructor = $reflector-&getConstructor();
dump($constructor);
这里会解析类的构造函数,在这里打印看:
它会找出构造函数的参数,再看完整的build方法进行的操作:
public function build($concrete, array $parameters = [])
// If the concrete type is actually a Closure, we will just execute it and
// hand back the results of the functions, which allows functions to be
// used as resolvers for more fine-tuned resolution of these objects.
if ($concrete instanceof Closure) {
return $concrete($this, $parameters);
$reflector = new ReflectionClass($concrete);
// If the type is not instantiable, the developer is attempting to resolve
// an abstract type such as an Interface of Abstract Class and there is
// no binding registered for the abstractions so we need to bail out.
if (! $reflector-&isInstantiable()) {
$message = "Target [$concrete] is not instantiable.";
throw new BindingResolutionContractException($message);
$this-&buildStack[] = $
$constructor = $reflector-&getConstructor();
// If there are no constructors, that means there are no dependencies then
// we can just resolve the instances of the objects right away, without
// resolving any other types or dependencies out of these containers.
if (is_null($constructor)) {
array_pop($this-&buildStack);
return new $
$dependencies = $constructor-&getParameters();
// Once we have all the constructor's parameters we can create each of the
// dependency instances and then use the reflection instances to make a
// new instance of this class, injecting the created dependencies in.
$parameters = $this-&keyParametersByArgument(
$dependencies, $parameters
$instances = $this-&getDependencies(
$dependencies, $parameters
array_pop($this-&buildStack);
return $reflector-&newInstanceArgs($instances);
具体从容器中获取实例的方法:
protected function resolveClass(ReflectionParameter $parameter)
return $this-&make($parameter-&getClass()-&name);
// If we can not resolve the class instance, we will check to see if the value
// is optional, and if it is we will return the optional parameter value as
// the value of the dependency, similarly to how we do this with scalars.
catch (BindingResolutionContractException $e) {
if ($parameter-&isOptional()) {
return $parameter-&getDefaultValue();
框架底层通过Reflection反射为开发节省了很多细节,实现了自动依赖注入。这里不做继续深入研究了。
写了一个模拟这个过程的类测试:
class kulou
class junjun
class tanteng
public function __construct(kulou $kulou,junjun $junjun)
$this-&kulou = $
$this-&junjun = $
//$tanteng = new tanteng(new kulou(),new junjun());
$reflector = new ReflectionClass('tanteng');
$constructor = $reflector-&getConstructor();
$dependencies = $constructor-&getParameters();
print_r($dependencies);
原理是通过ReflectionClass类解析类的构造函数,并且取出构造函数的参数,从而判断依赖关系,从容器中取,并自动注入。
转自:小谈博客 /2016/01/laravel-construct-ioc/
更多关于Laravel相关内容感兴趣的读者可查看本站专题:《Laravel框架入门与进阶教程》、《php优秀开发框架总结》、《smarty模板入门基础教程》、《php日期与时间用法总结》、《php面向对象程序设计入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家基于Laravel框架的PHP程序设计有所帮助。
您可能感兴趣的文章:
PHP的Laravel框架结合MySQL与Redis数据库的使用部署
PHP的Laravel框架中使用消息队列queue及异步队列的方法
Laravel执行migrate命令提示:No such file or directory的解决方法
Laravel中Trait的用法实例详解
Laravel中注册Facades的步骤详解
Laravel使用Caching缓存数据减轻数据库查询压力的方法
基于laravel制作APP接口(API)
详解PHP的Laravel框架中Eloquent对象关系映射使用
Laravel框架数据库CURD操作、连贯操作总结
深入解析PHP的Laravel框架中的event事件操作}

我要回帖

更多关于 laravel 依赖注入 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信