2013-10-20 21 views
6

Mam aplikację Laravel, w której sprawdzam, czy użytkownik logował się regularnie z pulsem na każde 3 sekundy (cel demo, w rzeczywistości 5 minut). Dla każdego rytmu sprawdzam, czy ostatnia aktywność użytkownika z bieżącym czasem to także 5 minut. Jeśli tak, wyloguj się.Laravel wybierz rekordy starsze niż 5 minut?

Oto mój kod:

$result = DB::table('db_user')->where('id_user','=',Session::get('id_user'))->where('last_activity','>=',"now() - interval 5 minute")->get(); 

    if(!empty($result)) 
     return Redirect::to('/logout'); 
    else 
     return Response::json('still-alive'); 

Mój problem jest, to nie działa. Jeśli zmienię operand na <=, wyloguje mnie on bezpośrednio przed 5 minutami, jeśli operandem jest >=, nawet po 5 minutach nie wyloguje mnie, czy ktoś może wyjaśnić dlaczego?

-EDIT-

Dzięki za wszystkie odpowiedzi, I rozwiązać swoje problemy poprzez modyfikację mojego kodu:

$result = DB::table('db_user')->where('id_user','=',Session::get('id_user'))->first(); 

    if(!empty($result)) 
     if(strtotime($result->last_activity) < strtotime("-5 minutes")) 
      return Redirect::to('/logout'); 
     else 
      return Response::json('still-alive'); 
    else 
     return Response::json('no-record'); 

Odpowiedz

24

Zakładając, że logika biznesowa jest prawidłowy, spróbuj za pomocą PHP zamiast ciąg SQL w where klauzula:

$date = new DateTime; 
$date->modify('-5 minutes'); 
$formatted_date = $date->format('Y-m-d H:i:s'); 

$result = DB::table('db_user')->where('id_user','=',Session::get('id_user'))->where('last_activity','>=',$formatted_date)->get(); 

Ponadto, jest to dobra praktyka, aby zawsze wyjście wykonanych zapytań SQL tylko upewnić laravel zachowuje się zgodnie z oczekiwaniami:

$queries = DB::getQueryLog(); 
+0

dzięki, próbowałem je też, i to działa. Zaakceptowałem i wznowiłem ze względu na twój czas na odpowiedź, w każdym razie już rozwiązałem problem za pomocą mojego własnego kodu (patrz edycja), dziękuję bardzo za poświęcony czas: D – user2002495

+6

możesz również użyć węgla (domyślnie zawartego w Laravel), aby utworzyć sformatowany date: '$ formatted_date = Carbon :: now() -> subMinutes (5) -> toDateTimeString();' – murze

27

Zaakceptowanych odpowiedź jest poprawna, ale można zrobić to jeszcze czystsze stosując zakres kwerendy na modelu użytkownika (zakładając, że masz model użytkownika) ...

$result = User::currentUser()->activityOlderThan(self::HEARTBEAT_INTERVAL)->get(); 

Twój użytkownika Model będzie wtedy mieć te funkcje:

public function scopeCurrentUser($query) 
{ 
    return $query->where('id_user', '=', Session::get('id_user')); 
} 

I

public function scopeActivityOlderThan($query, $interval) 
{ 
    return $query->where('last_activity', '>=', Carbon::now()->subMinutes($interval)->toDateTimeString()); 
} 

Teraz kod jest czysty i czytelny :-)

1

Można użyć whereRaw():

$result = DB::table('db_user')->where('id_user','=',Session::get('id_user'))->whereRaw('last_activity >= now() - interval 5 minute')->get(); 

lub

$result = DB::table('db_user')->where('id_user','=',Session::get('id_user'))->whereRaw('last_activity >= now() - interval ? minute', [5])->get();