2017-04-24 64 views
0

我爲了設置基於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); 
    } 
} 

我加入這個類的全球HTTP中間件聲明的底部Kernel.php

問題是它不起作用。當顯示created_at字段時,無論我在數據庫中設置用戶時區,時間都保持完全相同。

+0

數據庫中的所有日期和時間均以UTC格式存儲。除非你做某種轉換,這是你將從數據庫查詢中得到的。 – RiggsFolly

+0

我只想從數據庫中提取任何'timestamp'來使用用戶指定的時區。我試過中間件,服務提供商,沒有任何工作。我迷路了。我使用數據表,所以我希望這是自動完成的。 – kjdion84

+0

你可能需要閱讀這個http://stackoverflow.com/questions/15017799/how-to-convert-utc-date-to-local-time-zone-in-mysql-select-query – RiggsFolly

回答

0

我強烈建議在UTC的數據庫中留下您的日期 - 它會爲您節省後續的麻煩。

我建議使用Eloquent Mutators,它可以是 適用於您的模型。

這將使您仍然可以使用數據表,因爲剛剛從數據庫中提取數據後發生突變。

也許你可以創建你的應用程序中可重複使用的類,它具有對分析的日期,例如靜態方法:

<?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); 
    } 

    // ... 

} 
0

你的問題似乎你想要正常的過濾器/系統中間件不是路由中間件所以如果你把你的中間件的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'); 
+0

我在問題中提到我已經完全做到了。 – kjdion84

+0

我已經把類放在全局HTTP'$ middleware'聲明中,就像我在OP中所說的那樣。 – kjdion84

+1

是否嘗試使用'Config :: set('app.timezone','custom time zone');'來代替'date_default_timezone_set($ timezone);' – webDev

0

您可能使用像:

{{ $model->created_at->setTimezone($timezone)->toDateTimeString() }} 

但是,我相信肯定有更好的選擇。