针对php依赖注入和Laravel参考这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展$request->only()在laravel7.9中返回空数组来自Laravel5.4的文档Refe
针对php 依赖注入和Laravel 参考这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展$request->only() 在 laravel 7.9 中返回空数组 来自 Laravel 5.4 的文档 Reference来自 Laravel 7.9 的文档 Reference、Laravel 5.2 使用 JWT 完成多用户认证 | Laravel China 社区 - 高品质的 Laravel 开发者社区 - Powered by PHPHub、Laravel Dependency Injection (依赖注入) 概念详解、laravel php artisan 错误 laravel 视频教程 thinkphp php laravel等相关知识,希望可以帮助到你。
本文目录一览:- php 依赖注入(Laravel 参考)(php依赖注入有什么用)
- $request->only() 在 laravel 7.9 中返回空数组 来自 Laravel 5.4 的文档 Reference来自 Laravel 7.9 的文档 Reference
- Laravel 5.2 使用 JWT 完成多用户认证 | Laravel China 社区 - 高品质的 Laravel 开发者社区 - Powered by PHPHub
- Laravel Dependency Injection (依赖注入) 概念详解
- laravel php artisan 错误 laravel 视频教程 thinkphp php laravel
php 依赖注入(Laravel 参考)(php依赖注入有什么用)
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
这几行代码说明了该控制器的依赖注入,简单来说,依赖注入就是将该控制器用到的依赖添加进来。
比如,所有的 Controller 都依赖 基础 Controller.php ,所以需要:
use App\Http\Controllers\Controller;
比如,当我们处理请求的时候,我们引入 Request 类,才可以使用很多 Laravel 提供的方法:
use Illuminate\Http\Request;
$request->only() 在 laravel 7.9 中返回空数组 来自 Laravel 5.4 的文档 Reference来自 Laravel 7.9 的文档 Reference
如何解决$request->only() 在 laravel 7.9 中返回空数组 来自 Laravel 5.4 的文档 Reference来自 Laravel 7.9 的文档 Reference
我在 laravel 5.4 到 7.9 的时候一团糟,我已经阅读了以下文档:https://laravel.com/docs/7.x/requests,但我不清楚:
在 laravel 5.4 中,它返回一个数组:
这是 laravel 7.9 中的空数组:
谢谢!
解决方法
您所描述的问题是预期行为,并且在不同版本之间发生了变化。
来自 Laravel 5.4 的文档 Reference
only
方法返回您请求的所有键/值对,即使传入请求中不存在该键。当请求中不存在密钥时,该值将为 null
。
来自 Laravel 7.9 的文档 Reference
only
方法返回您请求的所有键/值对;但是,它不会返回请求中不存在的键/值对。
Laravel 5.2 使用 JWT 完成多用户认证 | Laravel China 社区 - 高品质的 Laravel 开发者社区 - Powered by PHPHub
Json Web Token#
JWT代表Json Web Token.JWT能有效地进行身份验证并连接前后端。
-
降地耦合性,取代session,进一步实现前后端分离
-
减少服务器的压力
-
可以很简单的实现单点登录
我在实现这个功能的时候查到了这个扩展“tymon/jwt-auth”,最新稳定版是0.5.9。OK照着wiki撸起来,第一步我们先实现API
安装扩展#
composer require tymon/jwt-auth
之后打开config/app.php文件添加service provider 和 aliase
config/app.php#
''providers'' => [
....
Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class, // 注意这里的名字,下文会提到],''aliases'' => [
....
''JWTAuth'' => Tymon\JWTAuth\Facades\JWTAuth::class],
OK,现在来发布JWT的配置文件,比如令牌到期时间配置等
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
最后一步需要生成JWT Key
php artisan jwt:generate
创建API路由#
我在创建Api路由的时候会用到一个“cors”中间件,虽然它不是强制性的,但是后面你会发现报类似这样的错
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://xxx.com/api/register. (Reason: CORS header ''Access-Control-Allow-Origin'' missing)
大致翻译下,“跨源请求阻塞:同源策略不允许读取http://kylesean.com/api/register远程资源。(原因:CORS 头“Access-Control-Allow-Origin” 没有)。” 这就是跨域请求导致的错误消息,当然你可以自定义Header,Origin, Method来解决跨域问题,不过我这边推荐一个package:barryvdh/laravel-cors(最新稳定版是0.8.2),这里安装过程省略。
创建中间件#
php artisan make:middleware CORS
进入app/Http/Middleware,编辑CORS.php
app/Http/Middleware/CORS.php#
namespace App\Http\Middleware;use Closure;class CORS{
public function handle($request, Closure $next)
{
header(''Access-Control-Allow-Origin: *'');
$headers = [
''Access-Control-Allow-Methods''=> ''POST, GET, OPTIONS, PUT, DELETE'',
''Access-Control-Allow-Headers''=> ''Content-Type, X-Auth-Token, Origin''
];
if($request->getMethod() == "OPTIONS") {
return Response::make(''OK'', 200, $headers);
}
$response = $next($request);
foreach($headers as $key => $value)
$response->header($key, $value);
return $response;
}}
Ok,在app/Http/Kernel.php注册中间件
app/Http/Kernel.php#
namespace App\Http;use Illuminate\Foundation\Http\Kernel as HttpKernel;class Kernel extends HttpKernel{
...
...
protected $routeMiddleware = [
...
''cors'' => \App\Http\Middleware\CORS::class,
];}
有了这个中间件我们就解决了跨域问题。接下来回到路由
app/Http/routes.php#
Route::group([''middleware'' => [''api'',''cors''],''prefix'' => ''api''], function () {
Route::post(''register'', ''ApiController@register''); // 注册
Route::post(''login'', ''ApiController@login''); // 登陆
Route::group([''middleware'' => ''jwt.auth''], function () {
Route::post(''get_user_details'', ''APIController@get_user_details''); // 获取用户详情
});});
建议:过滤掉路由api/*下的csrf_token,方便测试开发#
上面的jwt-auth中间件现在还是无效的,接着创建这个middleware
php artisan make:middleware authJWT
同样的我们需要编辑下这个authJWT.php
app/Http/Middleware/authJWT.php#
namespace App\Http\Middleware;use Closure;use Tymon\JWTAuth\Facades\JWTAuth;use Exception;class authJWT{
public function handle($request, Closure $next)
{
try {
// 如果用户登陆后的所有请求没有jwt的token抛出异常
$user = JWTAuth::toUser($request->input(''token''));
} catch (Exception $e) {
if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException){
return response()->json([''error''=>''Token 无效'']);
}else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException){
return response()->json([''error''=>''Token 已过期'']);
}else{
return response()->json([''error''=>''出错了'']);
}
}
return $next($request);
}}
OK,接着注册该中间件
app/Http/Kernel.php#
namespace App\Http;use Illuminate\Foundation\Http\Kernel as HttpKernel;class Kernel extends HttpKernel{
...
...
protected $routeMiddleware = [
...
''jwt.auth'' => \App\Http\Middleware\authJWT::class,
];}
然后,我们创建控制器管理所有的请求
app/Http/Controllers/ApiController.php#
<?phpnamespace App\Http\Controllers;use Illuminate\Http\Request;use App\User;use Illuminate\Support\Facades\Hash;use Tymon\JWTAuth\Facades\JWTAuth;class ApiController extends Controller{
/*注册*/
public function register(Request $request)
{
$input = $request->all();
$input[''password''] = Hash::make($input[''password'']);
User::create($input);
return response()->json([''result''=>true]);
}
/*登陆*/
public function login(Request $request)
{
$input = $request->all();
if (!$token = JWTAuth::attempt($input)) {
return response()->json([''result'' => ''邮箱或密码错误.'']);
}
return response()->json([''result'' => $token]);
}
/*获取用户信息*/
public function get_user_details(Request $request)
{
$input = $request->all();
$user = JWTAuth::toUser($input[''token'']);
return response()->json([''result'' => $user]);
}}
最后一步我们就来模拟一个请求来测试这个api,为了模拟本地跨域请求,我们简单的新建一个静态页面test.html
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8">
<title>Document</title>
<script src="http://apps.bdimg.com/libs/jquery/2.1.1/jquery.min.js"></script></head><body></body><script>
$.ajax({
url: "http://localhost/api/login",
dataType: "json",
type: "POST",
data: {"email":kylesean@qq.com","password":"123456"},
success: function (data) {
alert(data.result)
}
// 这里我们用ajax请求测试,当然你也可以用Angular.js Vue.js});</script></html>
这里我们要注意一下,以上测试我们仍是基于User table的,我们来模拟一下login过程,如果账号密码匹配成功,不出意外将会出现类似:
{
"result": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEsImlzcyI6Imh0dHA6XC9cL2xvY2FsaG9zdFwvYXBpXC9sb2dpbiIsImlhdCI6MTQ3MzQ1MjUyNSwiZXhwIjoxNDczNDU2MTI1LCJuYmYiOjE0NzM0NTI1MjUsImp0aSI6IjA1M2IzNjliYzYyZjJiZjJmMGMxNjFiNzIxNzY4Y2MzIn0.4WeezpSgEKjNmDFxv1nMU9HxqJgBE7bPyaJDRK4iLeA"}
至此,我们已经实现了jwt的认证功能,那么我们接着完成下一半工作,实现jwt的多用户认证,即Jwt for Multi Auth.
如果你的业务场景是的确需要多用户认证,比如为管理员admin单独生成一张表,恰好字段也是laravel auth user里面默认的name email password remember_token等,那么实现起来就方便的多,官方文档和网上的demo示例已经很多了,但是若结合这个laravel/jwt-auth扩展进行多用户认证,其实坑还是蛮多的,由于该扩展0.5.9似乎不支持多用户认证(反正不会帮我们自定义好guard,当然我们可以自己在AuthServiceProvider里用boot方法实现) 我在其github issue里面看到好多人踩过此坑,结合我遇到的
总结一下,里面一个哥们说,得用^0.1@dev版本(什么鬼,what''s the fuck!),so 继续撸之:
composer.json里修改为#
"require": {
...
"tymon/jwt-auth": "^1.0@dev", // 修改之前的,Or making a fresh start
...}
同样app.php里进行配置#
''providers'' => [
....
Tymon\JWTAuth\Providers\LaravelServiceProvider::class, // 上文已经提到过,这里的provider已经不是JWTauthServiceProvider],''aliases'' => [
....
''JWTAuth'' => Tymon\JWTAuth\Facades\JWTAuth::class],
发布配置文件#
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
生成密钥#
php artisan jwt:secret // 发现没生成key的方法也变了,不是 php artisan jwt:generate了
在.env文件中配置JWT_SECRET = 生成的的secret
接下来就是重点了,要设置好config/auth.php里面的配置项了,这里不能乱设置:
config/auth.php#
/**
* 默认使用web这个guard
*/''defaults'' => [
''guard'' => ''web'',
''passwords'' => ''users'',
],''guards'' => [
''web'' => [
''driver'' => ''session'',
''provider'' => ''users'',
],
''api'' => [
''driver'' => ''token'',
''provider'' => ''users'',
],
/**
* 这里是我自定义的guard,这里我叫staffs,你也可以根据自己的业务需求设置admins等,并且我
* 需要实现json web token认证
*/
''staffs'' => [
''driver'' => ''jwt'', // 结合扩展这里定义即生效
''provider'' => ''staffs''
]
],''providers'' => [
''users'' => [
''driver'' => ''eloquent'',
''model'' => App\User::class, // 这里注意修改命名空间 通常是''model'' => App\Models\User::class,
],
/** * 同样的这里定义自己的provider */ ''staffs'' => [ ''driver'' => ''eloquent'', ''model'' => App\Models\Staff::class, ] // ''users'' => [ // ''driver'' => ''database'', // ''table'' => ''users'', // ],],''passwords'' => [ ''users'' => [ ''provider'' => ''users'', ''email'' => ''auth.emails.password'', ''table'' => ''password_resets'', ''expire'' => 60, ], /** * 这里我并没有设置如下,因为我的staff表并没有email字段,默认的重置密码功能暂时没考虑 */ <!-- ''staffs'' => [ ''provider'' => ''staffs'', ''email'' => ''auth.emails.password'', ''table'' => ''password_resets'', ''expire'' => 60, ],-->]
下一步,创建我们的staff model
Models\staff.php#
<?phpnamespace App\Models;use Illuminate\Auth\Authenticatable;use Illuminate\Database\Eloquent\Model;use Illuminate\Auth\Passwords\CanResetPassword;use Illuminate\Foundation\Auth\Access\Authorizable;use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;use Tymon\JWTAuth\Contracts\JWTSubject as AuthenticatableUserContract; class Staff extends Model implements AuthenticatableContract, AuthorizableContract, AuthenticatableUserContract{
use Authenticatable, Authorizable, CanResetPassword;
protected $table = ''staffs'';
protected $fillable = [''name'', ''phone'', ''password''];
protected $hidden = [''password'', ''remember_token''];
public function getJWTIdentifier()
{
return $this->getKey(); // Eloquent model method
}
/**
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}}
好吧,接下来我们又要添加相关路由了
Route::post(''/api/login'', ''StaffAuthController@login'');Route::post(''/api/register'', ''StaffAuthController@register'');
控制器书写我们的业务逻辑
namespace App\Http\Controllers\Staff;use App\Models\Staff;use Illuminate\Http\Request;use App\Http\Controllers\Controller;use App\Http\Requests;use Illuminate\Foundation\Auth\ThrottlesLogins;use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;use Illuminate\Support\Facades\Validator;use Tymon\JWTAuth\Facades\JWTAuth;use Illuminate\Support\Facades\Auth;class StaffAuthController extends Controller{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected $guard = ''staffs'';
/*注册*/
public function register(Request $request)
{
$this->validate($request, [
''phone'' => ''required|max:16'',
''password'' => ''required|min:6'',
]);
$credentials = [
''phone'' => $request->input(''phone''),
''password'' => bcrypt($request->input(''password'')),
];
$id = Staff::create($credentials);
if ($id) {
$token = Auth::guard($this->getGuard())->attempt($credentials); // 也可以直接guard(''staffs'')
return response()->json([''result'' => $token]);
}
}
/*登录*/
public function login(Request $request)
{
$credentials = $request->only(''phone'',''password'');
if ( $token = Auth::guard($this->getGuard())->attempt($credentials) ) {
return response()->json([''result'' => $token]);
} else {
return response()->json([''result''=>false]);
}
}{
到现在,一个基于JWT的多用于认证系统雏形就建立就来了,这里面需要完善的东西很多,比如刷新token,退出登录,增加额外的中间件等,可以参考该扩展issue(Feature: Laravel 5.2 Custom Authentication Guard and Driver。markdown用的不多,排版不好请见谅,如有错误请指正,一起学习,谢谢。
Laravel Dependency Injection (依赖注入) 概念详解
本文翻译自
Symfony
作者 Fabien Potencier 的 《Dependency Injection in general and the implementation of a Dependency Injection Container in PHP》 系列文章。
- Part 1: What is Dependency Injection?
- Part 2: Do you need a Dependency Injection Container?
- Part 3: Introduction to the Symfony Service Container
- Part 4: Symfony Service Container: Using a Builder to create Services
- Part 5: Symfony Service Container: Using XML or YAML to describe Services
- Part 6: The Need for Speed
依赖注入
设计模式非常简单,但又很难解释清楚。造成这个现象的主要原因是,别的介绍 依赖注入
的文章里太多废话,让人混淆。下面我将通过一些更适合 PHP 的例子来讲解它。
HTTP 协议是无状态的,我们的 Web 应用程序如果需要在请求之间存储用户信息,可以通过 COOKIE
或 SESSION
:
$_SESSION[''language''] = ''fr'';
上述代码中,我们将 language
存储在全局变量 $_SESSION
中,因此可以这样获取它:
$user_language = $_SESSION[''language''];
只有在 OOP
开发时中才会遇到 依赖注入
,因此假设我们有一个封装 SESSION
的 SessionStorage
类:
class SessionStorage
{
function __construct($cookieName=''PHPSESSID'')
{
session_name($cookieName);
session_start();
}
function set($key, $value)
{
$_SESSION[$key] = $value;
}
function get($key)
{
return $_SESSION[$key];
}
// ...
}
以及一个更高层的 User
类:
class User
{
protected $storage;
function __construct()
{
$this->storage = new SessionStorage();
}
function setLanguage($language)
{
$this->storage->set(''language'', $language);
}
function getLanguage()
{
return $this->storage->get(''language'');
}
// ...
}
这两个类很简单,并且用起来也很方便:
$user = new User();
$user->setLanguage(''fr'');
$user_language = $user->getLanguage();
这种方式看起来很完美,但是并不够灵活。比如:现在想修改会话的 COOKIE
名称(默认为 PHPSESSID
) ,怎么办?这时有一大堆办法:
- 把会话的
COOKIE
名称写死在User
类中SessionStorage
的构造函数中 (Hardcode):
class User
{
function __construct()
{
$this->storage = new SessionStorage(''SESSION_ID'');
}
// ...
}
- 或者在
User
类外面定义一个常量:
class User
{
function __construct()
{
$this->storage = new SessionStorage(SESSION_COOKIE_NAME);
}
// ...
}
define(''SESSION_COOKIE_NAME'', ''SESSION_ID'');
- 或者把会话的
COOKIE
名称作为User
类构造函数的一个参数传进去:
class User
{
function __construct($cookieName)
{
$this->storage = new SessionStorage($cookieName);
}
// ...
}
$user = new User(''SESSION_ID'');
- 或者给
SessionStorage
类加个选项数组:
class User
{
function __construct($storageOptions)
{
$this->storage = new SessionStorage($storageOptions[''cookie_name'']);
}
// ...
}
$user = new User([''cookie_name'' => ''SESSION_ID'']);
上述方法都很糟糕:
- 把会话的
COOKIE
名称写死的话,每次想再改名,都要修改User
类 - 使用常量的话,
User
类的变化将取决于设置的常量 - 使用参数或者选项数组看起来很灵活,但它把与
User
本身无关的东西掺杂在了构造函数中
通过构造函数,把一个外部的 SessionStorage
实例"注入"进 User
实例内部,而不是在 User
实例内部创建 SessionStorage
实例,就是 依赖注入
。
class User
{
function __construct($storage)
{
$this->storage = $storage;
}
// ...
}
很清爽吧!只需先创建 SessionStorage
实例,再创建 User
实例:
$storage = new SessionStorage(''SESSION_ID'');
$user = new User($storage);
用这个方法,配置 SessionStorage
很简单,给 User
替换 $storage
类型也很简单,都不需要去修改 User
类。这就实现了解耦。
依赖注入
并不限于构造函数:
- Constructor Injection:
class User
{
function __construct($storage)
{
$this->storage = $storage;
}
// ...
}
- Setter Injection:
class User
{
function setSessionStorage($storage)
{
$this->storage = $storage;
}
// ...
}
- Property Injection:
class User
{
public $sessionStorage;
}
$user->sessionStorage = $storage;
作为经验, Constructor 注入
最适合必须的依赖关系,比如示例中的情况; Setter 注入
最适合可选依赖关系,比如缓存一个对象实例。
现在,大多数现代 PHP 框架都大量使用依赖注入来提供一组 去耦
但 粘合
的组件:
// symfony: A constructor injection example
$dispatcher = new sfEventDispatcher();
$storage = new sfMySQLSessionStorage([
''database'' => ''session'',
''db_table'' => ''session'',
]);
$user = new sfUser($dispatcher, $storage, [''default_culture'' => ''en'']);
// Zend Framework: A setter injection example
$transport = new Zend_Mail_Transport_Smtp(''smtp.gmail.com'', [
''auth'' => ''login'',
''username'' => ''foo'',
''password'' => ''bar'',
''ssl'' => ''ssl'',
''port'' => 465,
]);
$mailer = new Zend_Mail();
$mailer->setDefaultTransport($transport);
如果你有兴趣了解更多有关 依赖注入
的信息,我强烈建议你阅读 Martin Fowler 的介绍 或 Jeff Moore 的 PPT。你还可以看看我去年关于 依赖注入
的 PPT,其中我详细了介绍本文中所讨论的示例。
希望本文能让你更好的理解 依赖注入
,在本系列的下一部分中,我将讨论 依赖注入容器
(Dependency Injection Containers)。
原创。 所有 Laravel 文章均已收录至 laravel-tips 项目。
laravel php artisan 错误 laravel 视频教程 thinkphp php laravel
当运行 php artisan 的任意命令时出现如下错误时:
<span>[</span>RuntimeException<span>]</span> Error Output: PHP Catchable fatal error: Argument 2 passed to Illuminate<span>\R</span> outing<span>\UrlGenerator</span>::__construct() must be an instance of Illuminate<span>\Http</span><span>\R</span> equest, null given, called in <span>\laravel</span>5<span>\vendor</span><span>\laravel</span><span>\fram</span> ework<span>\src</span><span>\Illuminate</span><span>\Routing</span><span>\RoutingServiceProvider</span>.php on line 62 and defi ned in laravel5<span>\vendor</span><span>\laravel</span><span>\framework</span><span>\src</span><span>\Illuminate</span><span>\Ro</span> uting<span>\UrlGenerator</span>.php on line 102
可能是因为你在config目录下的配置文件中调用了 url(”) 方法,只要去掉url(”) 方法即可。
'').addClass(''pre-numbering'').hide(); $(this).addClass(''has-numbering'').parent().append($numbering); for (i = 1; i '').text(i)); }; $numbering.fadeIn(1700); }); });以上就介绍了laravel php artisan 错误,包括了laravel方面的内容,希望对PHP教程有兴趣的朋友有所帮助。
今天关于php 依赖注入和Laravel 参考的介绍到此结束,谢谢您的阅读,有关$request->only() 在 laravel 7.9 中返回空数组 来自 Laravel 5.4 的文档 Reference来自 Laravel 7.9 的文档 Reference、Laravel 5.2 使用 JWT 完成多用户认证 | Laravel China 社区 - 高品质的 Laravel 开发者社区 - Powered by PHPHub、Laravel Dependency Injection (依赖注入) 概念详解、laravel php artisan 错误 laravel 视频教程 thinkphp php laravel等更多相关知识的信息可以在本站进行查询。
本文标签: