БлогNot. Привязываем к клиенту Javascript серверную часть на PHP

Помощь дата->рейтинг Поиск Почта RSS канал Статистика nickolay.info Домой

Привязываем к клиенту Javascript серверную часть на PHP

Мне понадобилось в учебных целях (и пока без JQuery) продемонстрировать, как можно для клиентского скрипта, например, некой игры, написанной на HTML+Javascript, поддерживать с помощью серверного скрипта на PHP некий общий для всех файл (например, таблицу лучших игроков).

При этом хотелось бы сделать следующее:

Саму "игру" возьмём простейшей, кто больше раз нажмёт кнопку, тот и прав. А раз можно только тупо кликать, пусть "Кликушей" продукт и называется.

Вот код клиентского скрипта и комментарии к нему:

<script type="text/javascript" charset="UTF-8">
 function trim(string) {
  return string.replace (/\s+/g, " ").replace(/(^\s*)|(\s*)$/g, '');
 }
 function getname () {
  var name = window.prompt ("Пожалуйста, введите Ваше имя:", "Гость");
  if (name==null || trim(name)=='') name = "Гость";
  return trim(name);
 }
 function getparam () {
  var params_object = {}; 
  var params_array = window.location.search.substring(1).split("&"); 
  for (var i=0; i<params_array.length; i++) { 
   var getVar = params_array[i].split("="); 
   params_object[getVar[0]] = (typeof(getVar[1])=="undefined" ? "" : getVar[1]); 
  } 
  return params_object; 
 }
 function click1 () { document.f1.cnt0.value=++cnt; }
 function click2 () { document.f1.cnt.value=document.f1.cnt0.value; }


 document.writeln ('<p id="status">Стань лучшей кликушей :)</p>');

 var params = getparam ();
 var status=params['status'];
 var status_msg= new Array (
  'Вы успешно записаны в список лучших',
  'К сожалению, Ваш результат не попал в список лучших',
  'Неверный вызов скрипта');
 if (status!='' && status!='undefined') {
  var status_number = parseInt(status);
  if (!isNaN(status_number) && status_number>-1 && status_number<status_msg.length)
   document.getElementById('status').innerHTML = status_msg[status];
 }
 var name=decodeURI(params['name']);
 if (name=='' || name=='undefined') name = getname();
 var cnt=0;

 document.writeln ('<form name="f1" method="post" action="server.php">'+
  '<p>Ваше имя: '+name+". \n"+
  'Щёлкай: <input type="button" name="cnt0" value="0" onClick="click1()"> '+"\n"+
  '<input type="hidden" name="name" value="'+name+'">'+"\n"+
  '<input type="submit" name="cnt" value="Отправь&nbsp;результат" onClick="click2()"></form></p>'+"\n"+
  '<p><a href="server.php?a=show" target="_blank">Список&nbsp;лучших</a></p>');
</script>
<noscript><p>Извините, для работы приложения нужен включённый Javascript</p></noscript>

Рекомендуется в заголовке HTML-документа со скриптом поставить вот такие мета-теги:

<head>
 <META HTTP-EQUIV="Pragma" CONTENT="no-cache">
 <meta content="text/html; charset=UTF-8" http-equiv="content-type">
 <title>Clickusha (client side)</title>
</head>

Метод trim убирает из строки-параметра как лишние пробелы между словами, так и лишние лидирующие или завершающие пробелы.

Метод getname() позволяет ввести имя пользователя или оставить его без изменений. Рекомендуется всегда использовать имя по умолчанию. Как-то я видел "бесконечный" ввод имени, то есть, примерно вот такую getname():

function getname () {
 var input=false;
 var name='';
 while (input==false) {
  name = prompt("Пожалуйста, введите Ваше имя:", "Гость");
  if (name!=null && trim(name)!='') input=true;
 } 
 return trim(name);
}

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

Метод getparam() - пример того, как на Javascript обработать параметры, переданные странице методом GET (через URL-адрес). Возвращает объект, а не просто массив, то есть, при вызове

var params = getparam ();
параметр с именем status надо получать в виде
var status=params['status'];

Методы click1() и click2() понадобились потому, что стандартная кнопка отправки данных в HTML <input type="submit"> игнорирует другие кнопочные элементы, так что мы не смогли бы передать число от кнопки с цифрой.

Можно было попробовать отправлять результат и так:

document.writeln ('<a href="#" onClick="post1()">Отправь&nbsp;результат</a>');
//...
function post1 () { 
 if (name!="" && cnt>0) { 
  location.replace ('server.php?name='+name+'&cnt='+cnt);
 } 
}

принимая его в серверном скрипте методом GET, но это может быть запрещено, например, модулем Анти-баннер антивируса Касперского.

Основные действия серверного скрипта подробно закомментированы:

<?php
 //Глобальные настройки скрипта:
 $GLOBALS['key'] = "\t"; //Разделитель в записи "Счёт-Имя-Дата/Время"
 $GLOBALS['limit'] = 10; //Максимальное число записей
 $GLOBALS['filename'] = './data.txt'; //Путь к файлу с  записями

 //Шапка страницы на HTML:
 function start1 () {
  echo '<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
   <html>
    <head>
     <meta content="text/html; charset=UTF-8" http-equiv="content-type">
     <title>Clickusha (server side)</title>
    </head>
   <body>';
 }

 //Подвал страницы на HTML:
 function end1 () {
  echo '</body></html>';
  exit (2);
 }

 //Функция для сравнения 2 записей файла
 function compare ($a,$b) {
  //счёт-имя-дата/время
  @list ($ca,$na,$da) = explode ($GLOBALS['key'], $a);
  @list ($cb,$nb,$db) = explode ($GLOBALS['key'], $b);
  if (intval($ca)>intval($cb)) return 1;
  else if (intval($ca)<intval($cb)) return -1;
  else {
   if (intval($da)>intval($db)) return 1;
   else if (intval($da)<intval($db)) return -1;   
   else return strcmp($na,$nb);
  }
 }

 $status = 1; //Статус, который вернём клиенту; 1=ошибка

 //Читаем и вносим в массив $a список из файла:
 $table = @file_get_contents ($GLOBALS['filename']);
 $a = explode("\n", $table, $GLOBALS['limit']);
 if (isset($_GET['a'])) { //Если это был запрос "Показать список"
  start1();
  if (count($a)<2 and empty($a[0])) {
   echo '<p>Список лучших пока пуст, станьте первым</p>';
  }
  else {
   echo '<table border="1" cellpadding="4" cellspacing="0">'."\n".
    '<tr><th>Имя</th><th>Результат</th><th>Дата</th></tr>';
   for ($i=0; $i<min(count($a),$GLOBALS['limit']); $i++) if (!empty($a[$i])) {
    list ($result, $name, $date) = explode ($GLOBALS['key'], $a[$i]);
    echo '<tr><td>'.$name.'</td><td>'.$result.'</td><td>'.date("d.m.Y, H:i",$date).'</td></tr>';
   }
   echo '</table>'."\n";
  }
  end1();
 }
 else if (isset($_POST['name']) and isset($_POST['cnt'])) { //Если это был запрос на внесение данных
  $name = htmlspecialchars(trim($_POST['name'])); //Получить имя
  $cnt = intval(htmlspecialchars(trim($_POST['cnt']))); //...и счёт игрока
  if ($cnt>0) { //Если счёт не пуст,
   $time = time(); //получить метку времени,
   $key = $GLOBALS['key']; //разделитель записей,
   $item = "$cnt$key$name$key$time"; //сформировать строку с новой записью,
   array_push ($a, $item); //сунуть её в массив,
   $a = array_unique($a); //на всякий случай, убить одинаковые элементы в массиве,
   if (count($a)>1) uasort ($a,'compare'); //отсортировать записи собственной функцией,
   $a = array_slice(array_reverse ($a),0,$GLOBALS['limit']); 
    //перевернуть массив (по убыванию счёта) и избавиться от лишних записей
   $data = implode ("\n",$a); //положить данные в строку $data
   $status = (in_array($item,$a)==true?0:1); //новый элемент в массиве? Если да, статус=0 (успех)
   if ($status==0) {
    $res = @file_put_contents ($GLOBALS['filename'],$data,LOCK_EX); //монопольно записать в файл
    if ($res === false) $status = 2; //НЕ удалось записать - увы, вернём ошибку :)
   }
  }
 }

 header('Location: index.html?status='.$status.'&name='.$name); //Вернём клиенту его имя и статус
?>

Следует помнить, что для более безопасной работы с данными существуют базы, а сделать всё с меньшими усилиями в наше время можно с помощью библиотеки JQuery.

 Посмотреть всё в работе


теги: javascript php безопасность jquery

комментарии (0)

26.09.2014, 13:23; рейтинг: 8752

  в началопоиск по блогунаписать авторустатистика

Наверх Яндекс.Метрика
© PerS
вход