时区中间件不起作用
Timezone middleware does not work
我创建了一个中间件,以便根据数据库中设置的 auth 用户时区来设置时区:
<?php
namespace App\Http\Middleware;
use Closure;
class TimezoneMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->user()->guest()) {
$timezone = config('app.timezone');
}
else {
$timezone = $request->user()->timezone;
}
date_default_timezone_set($timezone);
return $next($request);
}
}
我将此 class 添加到 Kernel.php
中全局 HTTP 中间件声明的底部。
问题是它不起作用。当显示 created_at
字段时,无论我在数据库中设置什么用户时区,时间都完全相同。
你的问题似乎你想要普通的 filter/system 中间件而不是 route 中间件所以如果你把你的中间件放在 kernel.php 文件的底部那将不会工作。
kernel.php中有不同的中间件,您应该在$middleware section and if your middleware is for routes to protect the routes then add into
routeMiddleware`中添加过滤器类型的中间件。
过滤类型中间件,如您所愿
protected $middleware = [
//.............
];
如果路由保护和过滤中间件进入这个
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
//..................
//.................
];
和时区
Config::set('app.timezone','custom time zone');
你可以这样使用:
{{ $model->created_at->setTimezone( $timezone )->toDateTimeString() }}
不过,我相信一定有更好的选择。
我强烈建议将您的日期保留在 UTC 的数据库中 - 它会让您以后不再头疼。
我建议使用 Eloquent Mutators,可以是
应用于您的模型。
这将使您仍然可以使用数据表,因为突变发生在从数据库中提取数据之后。
您或许可以在您的应用程序中创建一个可重复使用的 class,它具有用于解析日期的静态方法,例如:
<?php
namespace App;
use Carbon\Carbon;
class DateTimeZoneMutator
{
public static function mutate($value)
{
if (auth()->user()->guest()) {
$timezone = config('app.timezone');
}
else {
$timezone = auth()->user()->timezone;
}
return new Carbon(
$value, $timezone
);
}
}
然后在您的模型中,为了论证我们假设您的日期字段被称为 "registered_at",您将添加以下方法:
<?php
namespace App;
use App\DateTimeZoneMutator;
use Illuminate\Database\Eloquent\Model;
class Something extends Model
{
// ...
public function getRegisteredAtAttribute($value)
{
return DateTimeZoneMutator::mutate($value);
}
// ...
}
我创建了一个中间件,以便根据数据库中设置的 auth 用户时区来设置时区:
<?php
namespace App\Http\Middleware;
use Closure;
class TimezoneMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->user()->guest()) {
$timezone = config('app.timezone');
}
else {
$timezone = $request->user()->timezone;
}
date_default_timezone_set($timezone);
return $next($request);
}
}
我将此 class 添加到 Kernel.php
中全局 HTTP 中间件声明的底部。
问题是它不起作用。当显示 created_at
字段时,无论我在数据库中设置什么用户时区,时间都完全相同。
你的问题似乎你想要普通的 filter/system 中间件而不是 route 中间件所以如果你把你的中间件放在 kernel.php 文件的底部那将不会工作。
kernel.php中有不同的中间件,您应该在$middleware section and if your middleware is for routes to protect the routes then add into
routeMiddleware`中添加过滤器类型的中间件。
过滤类型中间件,如您所愿
protected $middleware = [
//.............
];
如果路由保护和过滤中间件进入这个
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
//..................
//.................
];
和时区
Config::set('app.timezone','custom time zone');
你可以这样使用:
{{ $model->created_at->setTimezone( $timezone )->toDateTimeString() }}
不过,我相信一定有更好的选择。
我强烈建议将您的日期保留在 UTC 的数据库中 - 它会让您以后不再头疼。
我建议使用 Eloquent Mutators,可以是 应用于您的模型。
这将使您仍然可以使用数据表,因为突变发生在从数据库中提取数据之后。
您或许可以在您的应用程序中创建一个可重复使用的 class,它具有用于解析日期的静态方法,例如:
<?php
namespace App;
use Carbon\Carbon;
class DateTimeZoneMutator
{
public static function mutate($value)
{
if (auth()->user()->guest()) {
$timezone = config('app.timezone');
}
else {
$timezone = auth()->user()->timezone;
}
return new Carbon(
$value, $timezone
);
}
}
然后在您的模型中,为了论证我们假设您的日期字段被称为 "registered_at",您将添加以下方法:
<?php
namespace App;
use App\DateTimeZoneMutator;
use Illuminate\Database\Eloquent\Model;
class Something extends Model
{
// ...
public function getRegisteredAtAttribute($value)
{
return DateTimeZoneMutator::mutate($value);
}
// ...
}