• Валидация пользователей WebAPP в Telegram, почему не работает?

    Хешер данных

    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);
        }
    }


    ValidateData для передачи данных в метод хеширования

    namespace WebApp\Domain\Data;
    
    readonly class ValidateData
    {
        public function __construct(
            public string $query_id,
            public string $user,
            public string $auth_date
        ) {
        }
    }


    JS

    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;
    Ответ написан
    Комментировать
  • Php код в браузере открывается как текст решение?

    Не знаю кто такой Сергей Николаевич ) но или он что то пропустил, или вы.

    Подозреваю что у вас связка apache и php, только в apache вы забыли включить модуль php (libapache2-mod-php7) вашей версии. Сейчас ваш веб сервер не понимает php файлов. Или файлы отдаются с другим заголовком, если не ошибаюсь нужно в конфиг вашего хоста добавить что то вроде AddType application/x-httpd-php .php

    А ещё, как вы открываете ваш файл в браузере? Запустите сервер и откройте адрес localhost или 127.0.0.1
    Ответ написан
    Комментировать
  • Json_encode на локально и хосте, почему разница?

    Проверьте не $encodedKeyboard, а ошибку сериализации json_last_error_msg(). Там уже можно дальше смотреть
    Ответ написан
    Комментировать
  • Как отслеживать новые записи в бд и выводить их на экран без перезагрузки страницы?

    Вам нужно сделать проверку новых сообщений по интервалу.
    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)


    При последнем обновлении, вы можете хранить ID последнего сообщения, а при следующем запросе, получать сообщения только с ID позже сохраненного.

    Запрос для БД:
    SELECT * FROM chat WHERE `message_id` > $_POST['last_id']


    еще лучше, сначала проверять есть ли вообще новые сообщения, и если есть то тогда уже получать эти сообщения:
    SELECT COUNT(*) FROM chat WHERE `message_id` > $_POST['last_id']


    Это очень простой вариант я описал, но в общем реализация чата через AJAX - это кривой вариант. Вам постоянно придется дергать БД на проверку новых сообщений, и так каждому пользователю.

    Лучший и правильный вариант использовать websoket. Используя websoket пользователи будут получать сообщения сразу после их написания, по сути и БД дергать не нужно. Так как БД будет служить только для подгрузки истории сообщений,
    Ответ написан
    1 комментарий
  • Почему ложится php-cgi в связке с nginx в windows?

    weblive
    @weblive Автор вопроса
    PHP
    Нашел, что проблема может быть в ограничении php-cgi до 500 запросов. Но это не точно, но как один из вариантов. После 500 запросов php-cgi сам выключается, соответственно nginx его уж точно сам запускать не будет. Для линуксов вроде как есть параметр на увеличение запросов (вроде как и отключить можно), но для винды я не нашел такого, и мне не удалось это сделать. Буду изучать докер - давно пора бы. Простое руководство по нему, написал в комментариях к вопросу.
    Ответ написан
  • Как реализовать таймер средствами php и js?

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

    Можете сохранять в куку время старта вашего таймера. Когда пользователь вернется на сайт, сравнивать сколько прошло времени с момента старта и что-то делать.

    Если вам нужно прислать уведомление пользователю, то используйте HTML 5 Notifications API (в интернете найдете). Больше догадываться что вы хотите реализовать у меня мыслей нет). Уведомление придет даже если страница закрыта.
    Ответ написан
    Комментировать
  • Осталось мало памяти на хостинге. Что делать?

    Интересно что вы там храните? Можно попробовать использовать облачные сервисы https://cloud.yandex.ru/services/storage хранить и использовать файлы от туда (сам еще не пробовал реализацию, но на сколько я понимаю, сервис как раз для этого).

    Думаю Вам нужно изменить структуру своего проекта, если вы предлагаете скачать что-то, проще выдавать ссылки на облако, опять же тот же Яндекс.Диск, Облако.Меил.РУ или гугл диск.

    С такими объемами данных вам вряд ли стоит использовать хостинг.
    Ответ написан
    Комментировать
  • Как правильно подключать файлы сайта?

    В начальном файле вы можете создать константу, на "корень сайта".
    То есть в файле index.php добавляете

    <?php
        /**
         * Указываем начальную точку от куда,
         * будем тянуть все файлы в последующем.
         * Также для проверки как запущен наш файл, 
         * напрямую из браузера или подключен из главного скрипта.
         */
        define('BASEPATH', __DIR__);
    
        // подключаете нужные файлы header, content, footer
        require_once "partials/header.php";
    
        // в подключенных файлах используйте такой способ.
        // например в файле partials/header.php
        // require_once BASEPATH . "partials/menu.php";


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

    <?php if (!defined('BASEPATH')) exit('Прямой доступ к файлу запрещен...');
    // ... ваш код файла partials/header.php, partials/menu.php и т.д. ...
    Ответ написан
    1 комментарий
  • Как добавить json всех файлов в каталоге c gulp-data?

    weblive
    @weblive Автор вопроса
    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')); }))


    То есть, 1 файл с json для глобальных данных (что используются на каждой странице). И подгружается в зависимости от страницы, дополнительный файл. Например, если файл страницы с именем News.twig нужно создать в каталоге где хранятся json файлы, файл с названием "News.twig.json".

    В общем-то такой подход вполне решает мою проблему. В какой-то степени такой подход даже и лучше.
    Ответ написан
    Комментировать
  • Как установить мат-фильтр для сайта на php?

    со старого известного скрипта.

    // выражения, которые где угодно считаются матом
       $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 'Не нужно ругаться!';
    }
    Ответ написан
    Комментировать
  • На чем лучше реализовать конструктор печати на чехлах?

    Я использовал маски в css. Создавал 2 изображения каждого макета, где 1 из них - маска, а второй накладывался поверх первого (position: absolute), на котором были тени и блики. Для загрузки изображения использовал jquery загрузчик. Загруженное изображение размещал под 1 слоем (где была маска (форма чехла)). В итоге получался готовый макет для пользователя. Это минимальный набор для вашей реализации.

    После отправки формы, тоже самое проделываем на PHP. Берем загруженное изображение, накладываем на него изображение-маску, после чего на это готовое изображение добавляли картинку с тенями и бликами - данное изображение служило для хранения в заказах и так как у меня можно было поворачивать, менять размер изображения и сдвигать его, то и для выполнения заказа таким как сделал его юзер.
    Ответ написан
    Комментировать
  • Как в PHP закрыть доступ к скрипту?

    Воу воу. В index.php создайте константу которую будете проверять, и после во всех подключаемых файлах проверяйте ее.

    // index.php - до подключения других файлов
    define('MY_CONSTANT', TRUE);


    // во всех подключаемых файлах делайте проверку
    <?php
    if (!defined('MY_CONSTANT')) exit('No direct script access allowed.');
    
    class MY_Class {
    ....
    }


    п.с. не посмотрел дату вопроса)) но может пригодится
    Ответ написан
    Комментировать
  • Как обеспечить безопасность при работе с Ajax?

    Создавайте и храните токен в сессии как только пользователь вошел на сайт. После чего добавляйте ее во все формы и сравнивайте каждый раз при получении данных на сервере.
    Ответ написан
  • Как привести номер телефона к единому виду с добавочными номерами?

    Основной номер и добавочный я бы раздел на 2 разных поля - это самый лучший вариант. И естественно хранил бы их отдельно в базе.

    Сначала отформатировал бы номер телефона, а после уже добавил свой добавочный если он есть

    Оставить в номере телефона только цифры, и отформатировать в красивый вид (функция сама простая, для примера)
    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;
        }
    Ответ написан
    Комментировать