class HasherDataAction
{
const WEB_APP_DATA_CONST = 'WebAppData';
public function handle(string $bot_token, ValidateData $data): string {
$data_check = (array) $data;
ksort($data_check, SORT_NATURAL);
$data_check_string = urldecode(http_build_query($data_check, arg_separator: "\n"));
$secret_key = $this->sha256($bot_token, self::WEB_APP_DATA_CONST);
$hash_data = $this->sha256($data_check_string, $secret_key);
return bin2hex($hash_data);
}
private function sha256(string $data, string $key) {
return hash_hmac('sha256', $data, $key, true);
}
}
namespace WebApp\Domain\Data;
readonly class ValidateData
{
public function __construct(
public string $query_id,
public string $user,
public string $auth_date
) {
}
}
import axios from "axios";
const { initData } = window.Telegram.WebApp
document.addEventListener('DOMContentLoaded', () => {
validateData(initData)
})
function validateData(data) {
// как по мне лучше сразу передать данными и не парcить это в PHP, так проще и можно валидировать.
// axios.post('/{your_controller_validate_date}', data).then(response => {})
// оставлю вариант с передачей строки в initData
axios.post('/{your_controller_validate_date}', {initData: data})
.then(response => { console.log(response.data) })
}
// данные из JS, $_POST['initData']
$initData = 'user=%7B%22id%22%3A491735603%2C%22first_name%22%3A%22%F0%9F%85%BD%F0%9F%85%B0%EF%B8%8F%F0%9F%86%83%F0%9F%86%82%22%2C%22last_name%22%3A%22%22%2C%22username%22%3A%22mtNATS%22%2C%22language_code%22%3A%22ru%22%2C%22allows_write_to_pm%22%3Atrue%7D&chat_instance=-3312718360795391383&chat_type=sender&auth_date=1703053222&hash=05dd0f9552a0f12ea994e3616fccf18b0f4c151269664314d9dfd38202e431c5';
parse_str($initData, $data_array); // если отправляете данными, это не нужно, у вас сразу будет массив с данными в $_POST;
// $data_array = $_POST
$hash = $data_array['hash'];
$data = new ValidateData($data_array['query_id'], $data_array['user'], $data_array['auth_date']);
$data_hash = (new HasherDataAction)->handle('YOUR_BOT_TOKEN', $data);
// true/false
$isValid = $data_hash == $hash;
let lastMessageId = null
let checkNewMessageInterval = setInterval(() => {
$.ajax({
url: 'ajax/checkNewMessage.php',
type: 'POST',
cache: false,
data: {last_id: lastMessageId},
dataType: 'html',
success: function(response) {
let lastMessage = response.data[response.data.length - 1]
lastMessageId = lastMessage.message_id // сохраняем последнее сообщение которое получили
// .....
}
})
// ...
}, 5000)
SELECT * FROM chat WHERE `message_id` > $_POST['last_id']
SELECT COUNT(*) FROM chat WHERE `message_id` > $_POST['last_id']
<?php
/**
* Указываем начальную точку от куда,
* будем тянуть все файлы в последующем.
* Также для проверки как запущен наш файл,
* напрямую из браузера или подключен из главного скрипта.
*/
define('BASEPATH', __DIR__);
// подключаете нужные файлы header, content, footer
require_once "partials/header.php";
// в подключенных файлах используйте такой способ.
// например в файле partials/header.php
// require_once BASEPATH . "partials/menu.php";
<?php if (!defined('BASEPATH')) exit('Прямой доступ к файлу запрещен...');
// ... ваш код файла partials/header.php, partials/menu.php и т.д. ...
.pipe(data(function(file) { return JSON.parse(fs.readFileSync('./app-source/app-data/Globals.json')); }))
.pipe(data(function(file) { return JSON.parse(fs.readFileSync('./app-source/app-data/' + path.basename(file.path) + '.json')); }))
// выражения, которые где угодно считаются матом
$f_pregmat='~'.
'[^и][hхx][уyu][йyяij]|'. // защита от: прихуй
'[hхx][уyu][eеЁ][tlvлвт]|'.
'[hхx][уyu][йyijoeоеёЁ]+[vwbв][oiоы]|'.
'[pп][ieие][dдg][eaoеао][rpр]|'.
'[scс][yuу][kк][aiuаи]|'.
'[scс][yuу][4ч][кk]|'.
'[3zsз][aа][eiе][bpб][iи]|'.
'[^н][eе][bpб][aа][lл]|'. // защита от: не бал*
'fuck|xyu|'.
'[pп][iи][zsз3][dд]|'.
'[z3ж]h?[оo][pп][aаyуыiеe]'.
'~si';
// сложные слова, типа "оскорблять", писать с пробелом перед словом
$f_pregmat2='~'.
' фак |'.
' лох |'.
' [бb6][лl]([яy]|ay)|'.
' [eiе][bpб][iи]|'.
' [eiе][bpб][aeаеёЁ][tlтл]'.
'~si';
if (preg_match($f_pregmat," $tmp ") || preg_match($f_pregmat2," $tmp ")) {
echo 'Не нужно ругаться!';
}
// index.php - до подключения других файлов
define('MY_CONSTANT', TRUE);
// во всех подключаемых файлах делайте проверку
<?php
if (!defined('MY_CONSTANT')) exit('No direct script access allowed.');
class MY_Class {
....
}
echo format_phone('7wer9e85w11-1"!1н1*11'); // вернет: +7 (985) 111-11-11
function format_phone($phone = '')
{
$phone = preg_replace('/[^0-9]/', '', $phone); // вернет 79851111111
if (strlen($phone) != 11 and ($phone[0] != '7' or $phone[0] != '8')) {
return FALSE;
}
$phone_number['dialcode'] = substr($phone, 0, 1);
$phone_number['code'] = substr($phone, 1, 3);
$phone_number['phone'] = substr($phone, -7);
$phone_number['phone_arr'][] = substr($phone_number['phone'], 0, 3);
$phone_number['phone_arr'][] = substr($phone_number['phone'], 3, 2);
$phone_number['phone_arr'][] = substr($phone_number['phone'], 5, 2);
$format_phone = '+' . $phone_number['dialcode'] . ' ('. $phone_number['code'] .') ' . implode('-', $phone_number['phone_arr']);
return $format_phone;
}