2010-10-13 4 views
0

хотел бы узнать, как я могу рассчитать время между двумя датами. Я работаю над функциональностью пользователя Разблокировать и следующее, что я:PHP - Рассчитать время между датами

даты
// get offender's username from session 
$username = $_SESSION['UserName']; 
require_once('./connections/mysql.php'); 

$checklockoutexpiration = mysqli_query($conn,"SELECT IsLockedOut, LastLockoutDate FROM users WHERE UserName = '$username' Limit 1") or die($dataaccess_error); 

if(mysqli_num_rows($checklockoutexpiration) == 1) 
{ 
    $row = mysqli_fetch_array($checklockoutexpiration); 
    $islockedout = $row['IsLockedOut']; 
    $lastlockoutdate = $row['LastLockoutDate']; 
} 

if(**$islockedout == 1 && $lastlockoutdate + LOCKOUT_DURATION_IN_MINUTES < getdate()**) 
{ 
    // unlock user 
} 

Локаута находится в базе данных в виде NOW() и выглядит как 2010-10-13 13:01:05 , Я предполагаю, что это время сервера, которое на данный момент является моей локальной машиной разработки.

ВОПРОС: Как я могу сделать жирный шрифт в коде.

В asp.net я хотел бы сделать что-то вроде:

// if lockout datetime + lockout duration is less than datetime now 
if (usrInfo != null && usrInfo.IsLockedOut && usrInfo.LastLockoutDate.ToUniversalTime().AddMinutes(passwordAttemptLockoutDuration) < DateTime.UtcNow) 
{ 
// then automatically Unlock user 
    usrInfo.UnlockUser(); 
} 

Может кто-то пожалуйста, покажите мне, как это делается? Спасибо!

+0

Мое редактирование отменило выделение жирным шрифтом - это четвертое последнее в 1-м абзаце –

+0

Также вы слышали о атаках SQL Injection? Используйте http://php.net/manual/en/function.mysql-real-escape-string.php – James

+0

Действительно, $ username нуждается в дезинфекции. Конечно, он, возможно, уже дезинфицировал $ username в другом месте (это из переменной $ _SESSION afterall, поэтому ее «возможно доверяют»). Я дам ему преимущество от сомнений ... но это достаточно важно, чтобы упомянуть об этом. – Dragontamer5788

ответ

0

Благодарим за все советы. Я решил решить эту проблему, добавив новый столбец (LastUnlockDate). Когда пользователь блокируется, я устанавливаю значение IsLockedOut равным 1, LastLockoutDate для NOW() и LastUnlockDate для NOW() + $ lockoutduration (в секундах).

Тогда часть моего кода выглядит примерно так:

//------------------------------------------------------------ 
// if lockout session exits 
//------------------------------------------------------------ 

if(!empty($_SESSION['count'])) 
{ 
    require_once('./connections/mysql.php'); 
    require_once('./web.config.php'); 
    require_once('./controls/login/error_messages.php'); 

    $count = $_SESSION['count']; 
    $offender = mysqli_real_escape_string($conn, $_SESSION['offender']); 
    $maxloginattempt = MAX_LOGIN_ATTEMPT; 

    if($count >= $maxloginattempt) 
    { 
     echo $maxloginattempt_error; 
     $showform = 0; 

     // check if user exists in database 
     $checkoffender = mysqli_query($conn, "SELECT UserName, IsLockedOut, LastLockoutDate, LastUnlockDate, NOW() AS ServerTime FROM users WHERE UserName = '$offender' LIMIT 1") 
     or die($dataaccess_error); 

     if(mysqli_num_rows($checkoffender) == 1) 
     { 
      $row = mysqli_fetch_array($checkoffender); 
      $islockedout = $row['IsLockedOut']; 
      $lastlockoutdate = $row['LastLockoutDate']; 
      $lastunlockdate = $row['LastUnlockDate']; 
      $servertime = $row['ServerTime']; 
     } 

     // unlock user if lockout has expired 
     if($islockedout == 1 && $lastunlockdate < $servertime) 
     { 
      $unlockoffender = mysqli_query($conn,"UPDATE users SET IsLockedOut = 0 WHERE UserName = '$offender'") 
      or die($updateactivity_error); 

      unset($_SESSION['count']); 
      unset($_SESSION['offender']); 

      $showform == 1; 
     } 

     // otherwise lockout the user 
     if($islockedout == 0) 
     { 
      $lockoutduration = (LOCKOUT_DURATION * 60); 
      $updateoffender = mysqli_query($conn,"UPDATE users SET IsLockedOut = 1, LastLockoutDate = NOW(), LastUnlockDate = (NOW() + $lockoutduration) WHERE UserName = '$offender'") 
      or die($updateactivity_error); 
     } 
    } 
} 

Поскольку этот код чисто зависит от наличия сессии, если браузер закрыт и сеанс потерян, пользователь в базе данных по-прежнему установлен как заблокированный. Поэтому, чтобы исправить это, я изменил мою фактическую страницу входа, которая теперь проверяет во время аутентификации и разблокирует пользователя, если блокировка уже истекла.

Спасибо всем за помощь и предложение. Итак, чтобы обернуть, мой вопрос был, как я могу добавить время до даты - и простой ответ был: СЕЙЧАС() + $ lockoutduration.

0

Короткий ответ: преобразуйте временную метку и продолжительность блокировки в секундах, затем сравните.

Длинный ответ:

$lockout = ($lockoutDurationMinutes * 60); 
$timestamp= strtotime($yourTimeStampFieldVariable); 

if (($timestamp + $lockout) > time()) 
{ 
// still locked out 
} 
3

Использование http://php.net/strtotime превратить дату формата «2010-10-13 13:01:00» в секундах с начала эпохи как целого.

Используйте http://php.net/time, чтобы получить текущие секунды, начиная с эпохи как целое число.

Тогда это легко.

+2

Также, используя NOW(), когда запись в MySQL будет хранить текущее время на вашем сервере базы данных. Если вы сравните это с текущим временем на своем веб-сервере позже, у вас могут возникнуть проблемы, если A) Ваш веб-сервер и сервер db - это разные машины, а B) они имеют разные времена. (Объяснить вопросы о вашей точке «Я предполагаю») – James

+0

Да, интересно. Я никогда не думал о случае с несколькими серверами. Думаю, это преимущество моего подхода тогда :-) – Dragontamer5788

0

Если вы хотите сделать это больше как ваш пример ASP, используйте класс DateTime. Вы должны иметь возможность построить один из своей строки, и вместе со своим аналоговым классом DateInterval вы можете указать add интервал времени или использовать diff, чтобы получить интервал от двух раз.

(Похоже, это доступно только на PHP 5.3, хотя. Это может быть дело выключатель.)

1

Есть уже приемлемые ответы ... так что я покажу другой подход. Я бы изменить строки запроса:

SELECT IsLockedOut, LastLockoutDate, 
    (addtime(LastLockoutDate, $passwordAttemptLockoutDuration) < NOW()) unlocked 
FROM users WHERE UserName = '$username' Limit 1 

Где $ passwordAttemptLockoutDuration строка вида «часы: минуты: секунды»

Значение «разблокировано» будет 0 (или ложь), если они» re все еще заблокирован, и будет 1, если они смогут снова войти в систему.

Смежные вопросы