Рубрика «PHP»

Кто сейчас на сайте?

Протокол HTTP не позволяет устанавливать сессии и, как следствие, не позволяет отслеживать длительность работы посетителя с Web-ресурсом. Единственное, что можно зафиксировать, - это время обращения клиента к ресурсам сервера. После этого посетитель может часами читать загруженную страницу - Web-сервер не может узнать момент прекращения работы посетителя с загруженными страницами. Поэтому будем считать, что посетитель покинул Web-ресурс, если с момента последней загрузки им страницы прошло 20 минут.

Для фиксирования времени обращения посетителей к страницам ресурса создадим таблицу MySQL session, в которой будем хранить имена пользователей и время их последнего обращения к странице.

CREATE TABLE session (
  id_session TINYTEXT NOT NULL,
  putdate DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  user TINYTEXT NOT NULL
) ENGINE=MyISAM;

Таблица содержит три поля:

  • id_session - идентификатор сессии;
  • putdate - время последнего обращения посетителя к страницам сайта;
  • user - имя пользователя.

Тогда для регистрации посетителей, которые находятся в данный момент на сайте, можно использовать следующий скрипт:

<?php
  // Начинаем сессию
  session_start();
  // Получаем уникальный id сессии
  $id_session = session_id();
  // Устанавливаем соединение с базой данных
  include 'connect.php';
  if ( isset( $_SESSION['user'] ) )
    $user = $_SESSION['user'];
  else
    $user = '';
  // Проверяем, присутствует ли такой id в базе данных
  $query = "SELECT * FROM session
            WHERE id_session = '"
.$id_session."'";
  $res = mysql_query($query);
  if ( $res ) {
    // Если сессия с таким номером уже существует,
    // значит пользователь online - обновляем время его
    // последнего посещения
    if( mysql_num_rows($res) > 0 ) {
      $query = "UPDATE session SET putdate = NOW(), user = '".$user."'
                WHERE id_session = '"
.$id_session."'";
      mysql_query($query);
    } else {
      // Иначе, если такого номера нет - посетитель только что
      // вошёл - помещаем в таблицу нового посетителя
      $query = "INSERT INTO session
              VALUES('"
.$id_session."', NOW(), '".$user."')";
      mysql_query($query);
    }
  } 
  // Будем считать, что пользователи, которые отсутствовали
  // в течении 20 минут - покинули ресурс - удаляем их
  // id_session из базы данных
  $query = "DELETE FROM session
            WHERE putdate < NOW() -  INTERVAL '20' MINUTE"
;
  mysql_query($query);
?>

В начале скрипта при помощи функции session_id() получается текущий идентификатор сессии. Если такой идентификатор отсутствует в таблице session, то происходит добавление новой записи, что эквивалентно приходу на ресурс нового посетителя. Если же идентификатор присутствует в таблице session, следовательно, данный посетитель уже зашел на ресурс и требуется обновить время его посещения и имя на тот случай, если он осуществил авторизацию только сейчас. В конце скрипта происходит удаление всех записей таблицы, время посещения для которых было обновлено более чем 20 минут назад - таким образом фиксируется уход посетителя с ресурса.

Этот скрипт следует подключить при помощи инструкции include ко всем страницам сайта, чтобы отслеживать присутствие посетителя на сайте.

Теперь не составит труда вывести список текущих посетителей:

<?php
  // Устанавливаем соединение с базой данных
  include 'connect.php';
  // Выводим имена всех посетителей, записи о которых имеются
  // в таблице session
  $query = 'SELECT * FROM session';
  $res = mysql_query($query);
  if ( $res ) {
    // Если хоть кто-то есть - выводим список
    if ( mysql_num_rows($res) > 0 )
    {  
      $guests = 0;
      while( $row = mysql_fetch_array($res) )
      {
        if ( empty( $row['user'] ) )
          $guests = $guests + 1;
        else
          $users[] = $row['user'];
      }
      if ( $guests > 0 or isset( $users ) ) {
        echo 'Сейчас на сайте: ';
        if ( isset( $users ) ) echo implode(',', $users);
        if ( $guests > 0 and isset( $users ) ) echo ' и ';
        if ( $guests > 0 ) echo $guests.' гостей';
      }
    }
  } 
?>

Извлечение названия HTML-страницы

Для решения этой задачи понадобится функция preg_match(), которая осуществляет поиск в строке по регулярному выражению и имеет следующий синтаксис:

int preg_match(string pattern, string subject, [, array matches [, int flags [, int offset]]])

Эта функция ищет в строке subject соответствие регулярному выражению pattern. Если задан необязательный параметр matches, то результаты поиска помещаются в массив. Элемент $matches[0] будет содержать часть строки, соответствующую вхождению всего шаблона, $matches[1] — часть строки, соответствующую первым круглым скобкам, $matches[2] — вторым и т.п.

Необязательный флаг $flag может принимать единственное значение PREG_OFFSET_CAPTURE, при указании которого изменяется формат возвращаемого масива $matches — каждое вхождение возвращается в виде массива, в нулевом элементе которого содержится найденная подстрока, а в первом — смещение. Поиск осуществляется слева направо, с начала строки.

Дополнительный параметр offset может быть использован для указания альтернативной начальной позиции для поиска. Функция preg_match() возвращает количество найденных соответствий. Это может быть 0 (совпадения не найдены) и 1, поскольку preg_match() прекращает свою работу после первого найденного совпадения.

$content = file_get_contents( "index.html" );
$pattern = "|<title>(.*?)</title>|si";
if ( preg_match( $pattern, $content, $out ) ) echo $out[1];

Загрузка файлов средствами AJAX

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

Итак, мы создаем скрытый фрейм iframe, и в атрибуте target тега form указываем имя этого фрейма. Отправка файла будет выполнена обычным способом. Но с точки зрения посетителя загрузка будет выглядеть асинхронной - страница, которую он видит, перезагружена не будет.

<form action="/upload.php" name="uploadForm" method="post" target="hiddenframe" enctype="multipart/form-data"
onsubmit="document.getElementById('res').innerHTML=''; document.getElementById('loading').style.display='block';
return true;"
>

<input type="file" name="userfile" />
<input type="submit" value="Загрузить"  />
</form>
<div id="res" style="margin: 1em 0"></div>
<div id="loading" style="display:none; position: absolute; z-index: 99; left: 45%; top: 45%;">
<img src="/loading.gif" border="0" /> Идет загрузка...
</div>
<iframe id="hiddenframe" name="hiddenframe" style="width:0; height:0; border:0"></iframe>

Работает это так - при нажатии на кнопку submit на экране появляется изображение “loading” (загрузка), потом идет отправка формы. Когда файл загрузился, мы убираем изображение загрузки и выводим на основную страницу сообщение с результатами.

<?php
// ...............................................
sleep(5);
echo '<script type="text/javascript">';
echo 'window.parent.document.getElementById("loading").style.display="none";';
// Если загрузка прошла успешно
if (empty($error)) {
   echo 'window.parent.document.getElementById("res").innerHTML="Файл успешно загружен";';
} else {
  echo 'window.parent.document.getElementById("res").innerHTML="Ошибка при загрузке файла";';
}
echo '</script>';
?>

Серверный скрипт upload.php создает текстовую строку, содержащую обычный JavaScript код. Когда ответ сервера будет загружен во фрейм, код будет автоматически выполнен.