Skip to content

Instantly share code, notes, and snippets.

@Fedcomp
Created December 31, 2014 06:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Fedcomp/3179d61d6c6503aa541f to your computer and use it in GitHub Desktop.
Save Fedcomp/3179d61d6c6503aa541f to your computer and use it in GitHub Desktop.
Sockets example: PHP handler example
<?php
/*
========== HTTP SOCKET EXAMPLE ==============
Автор: Fedcomp
https://github.com/Fedcomp/socket_example/
Связка из скрипта и плагина показывающая
как связаться из amxx плагина с php скриптом
и как этому скрипту обработать запрос
!!Этот файл ТОЛЬКО отображает данные из базы (без разбиения на страницы)!!
*/
//phpinfo();exit; // Чисто для отладки
// Настройки для mysql. Настроено под мою локалку, изменяйте под себя.
$mysql_host = '127.0.0.1';
$mysql_user = 'socket_example';
$mysql_pass = 'socket_example';
$mysql_db = 'socket_example';
// == // Конец списка =========
// Подключаемся к базе
if(!$db_link = mysqli_connect($mysql_host, $mysql_user, $mysql_pass, $mysql_db))
die('Не могу подключиться к mysql: '. mysqli_error());
// Проверяем существует ли разметка базы данных
if (mysqli_num_rows(mysqli_query($db_link, "SHOW TABLES LIKE 'example_stats'")) > 0){
// Читаем все данные из базы, учтите что их может быть много.
// сразу сортируем по количеству убийств
$result = mysqli_query($db_link, "SELECT * FROM `example_stats` ORDER BY `kills` DESC");
$players = array();
if(mysqli_num_rows($result) > 0){
while($players[] = mysqli_fetch_assoc($result));
array_pop($players);
}
}
?><!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="author" content="Fedcomp">
<title>Статистика игроков</title>
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
<style>
footer {
margin-top: 30px;
padding: 4px;
display: inline-block;
background: whitesmoke;
border-radius: 4px;
float: right;
}
</style>
</head>
<body>
<div class="container">
<div>
<h1>Статистика игроков</h1>
<table class="table table-striped">
<tr>
<th>Игрок</th>
<th>Фрагов</th>
<th>Смертей</th>
</tr>
<?php if(!count($players)): ?>
<tr>
<td colspan="3">Статистики пока еще нет.</td>
</tr>
<?php else: ?>
<?php foreach($players as $player): ?>
<tr>
<td><?=$player['name']?></td>
<td><?=$player['kills']?></td>
<td><?=$player['deaths']?></td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</table>
</div>
<footer>
<a href="https://github.com/Fedcomp/socket_example/">Пример работы с сокетами</a>
&copy; <a href="https://github.com/Fedcomp">Fedcomp</a> 2014</footer>
</div>
</body>
</html>
<?php
/*
========== HTTP SOCKET EXAMPLE ==============
Автор: Fedcomp
https://github.com/Fedcomp/socket_example/
Связка из скрипта и плагина показывающая
как связаться из amxx плагина с php скриптом
и как этому скрипту обработать запрос
!!Этот файл ТОЛЬКО принимает статистику, т.е общается с плагином!!
Пример запроса: stats.php?name=Halyavshik&kills=2&deaths=1
*/
//phpinfo();exit; // Чисто для отладки
// Ошибки сами обрабатываем.
// Они могут быть опасны, т.к вы ожидаете json формат,
// а получаете текстовое сообщение об ошибке.
//error_reporting(0);
// == Список настроек скрипта =========
define('PLUGIN_USER_ID', 'Link 0.59/GET EXAMPLE'); // Аналогично значению PLUGIN_USER_ID в плагине
// Настройки для mysql. Настроено под мою локалку, изменяйте под себя.
$mysql_host = '127.0.0.1';
$mysql_user = 'socket_example';
$mysql_pass = 'socket_example';
$mysql_db = 'socket_example';
// == // Конец списка =========
// Функция будет выводить сообщение ошибку в формате json
function error($msg){
echo json_encode(array(
'status' => 'fail',
'error' => $msg
));
exit;
}
// Обработчик любых ошибок выкинутых PHP
function customErrorHandler($errno, $errstr, $errfile, $errline)
{
// На пустяки ложим большой х*й
if($errno == E_NOTICE)
return true;
error(
"PHP Error(${errno}): ${errstr}"
);
}
// Сразу же начинаем ловить ошибки
set_error_handler ('customErrorHandler');
// Зачем нам вообще этот обработчик?
// Сообразить множество возможных ошибок сразу практически невозможно.
// К тому же могут выскочить очень редкие, все не обработаешь.
// Но для нас критично вернуть ошибку именно в JSON формате,
// чтобы amxx нормально прочитал ответ
// === Сначала проверим все ли параметры пришли и правильны ли они
// Убедимся что это запрос пришедший не из браузера, а от нашего плагина
//if($_SERVER['HTTP_USER_AGENT'] != PLUGIN_USER_ID) error('Neverniy PLUGIN_USER_ID');
// == Проверим все параметры на корректность
if(!(
isset($_GET['name'])
and strlen($_GET['name']) < 33 // длина имени не больше 32 символов. Возможно не будет хорошо работать с UTF-8 в современных билдах
// Можно еще кучу проверок добавить, регулярные выражения, но зачем? это всего лишь пример ...
))
// Если что то из перечисленного неверно, показываем ошибку.
error('Invalidnoe uM9l');
// Просто проверим наличие оставшихся параметров и убедимся что это цифры
if(!(
isset($_GET['kills'])
and isset($_GET['deaths'])
//and isset($_GET['time']) // UNIX TIMESTAMP, в amxx получаем это время через get_systime();
and is_numeric($_GET['kills']) and (int) $_GET['kills'] < 300 // больше 300 киллов выглядит нереалистично
and is_numeric($_GET['deaths']) and (int) $_GET['deaths'] < 500 // в 500 смертей я больше поверю
//and is_numeric($_GET['time'])
)) // Если что то из этого неверно, выводим ошибку.
error('Nevernaya stata');
// переводим в локальные переменные для удобства
// заодно переводим в положительные числа без запятой (не float)
$name = $_GET['name'];
$kills = abs((int) $_GET['kills']);
$deaths = abs((int) $_GET['deaths']);
//$time = $_GET['time'];
// mysql_ функции считаются устаревшими и на некоторых
// хостингах будет плеваться на то что mysql устарел.
// Да, мы отключили вывод, но зачем пользоваться старьем?
// Подключаемся к базе
if(!$db_link = mysqli_connect($mysql_host, $mysql_user, $mysql_pass, $mysql_db))
error('(Mysql) Ne mogu podklu4ica k mysql: '. mysqli_error());
// Проверяем существует ли разметка базы данных
if (mysqli_num_rows(mysqli_query($db_link, "SHOW TABLES LIKE 'example_stats'")) == 0)
// Если не существует, создаем разметку
mysqli_query($db_link,
"
CREATE TABLE `example_stats` (
`name` varchar(35) NOT NULL,
`kills` int(2) NOT NULL,
`deaths` int(2) NOT NULL,
UNIQUE KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
"
);
// Добавляем/обновляем запись в базе
// Используем хитрый запрос в базу.
// Суть в том что столбец `name` (имя) в базе назначен уникальным.
// Значит что в этом столбце только каждое уникальное значение встречается только один раз.
// Если мы пытаемся воткнуть значение с тем же именем (в точности до байта)
// хитрый запрос ON DUPLICATE KEY (при дубликате ключей выполнить UPDATE) выполнит лишь обновление записей
// В нашем случае сплюсует уже имеющиеся килы и смерти с теми что только что прибыли
mysqli_query($db_link,
"INSERT INTO `example_stats` (`name`, `kills`, `deaths`)
VALUES ('${name}', ${kills}, ${deaths})
ON DUPLICATE KEY UPDATE kills=kills+${kills}, deaths=deaths+${deaths};
"
);
// проверяем изменил ли запрос что либо в базе
if(mysqli_affected_rows($db_link) < 1)
error('Zapros v bazu ni4ego ne izmenil. Jisn tlen.');
else{
echo json_encode(array(
'status' => 'success'
));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment