Задать вопрос
Ответы пользователя по тегу PHP
  • Как отправить данные через websoket из php?

    @aspirantes
    Примерно так. Одно время копал в сторону веб-сокетов. Есть готовые наработки для дэймона и для чата. На просторах интернета готовый код не нашёл, только библиотеки, поэтому подгонял по RFC сам.

    Общий принцип - правильно кодировать и декодировать. Ну и само собой у серверов, куда подключаешься, тоже свои заморочки имеются.

    $context = stream_context_create(
      [
          'ssl' => [
            'disable_compression' => true
          ],
      ]
    );
    $fp = stream_socket_client("ssl://example.com:9443", $errstr, $errno, 30, STREAM_CLIENT_CONNECT, $context);
        if (!$fp) {
            echo "$errstr ($errno)<br />\n";
        } else {
            echo "true\n";
            fwrite($fp, "POST /ws/stream HTTP/1.1\r\n" .
                "Host: example.com\r\n" .
                "Accept: */*\r\n" .
                "Cache-Control: no-cache\r\n" .
                "Sec-WebSocket-Key: qwerty123\r\n" .
                "X-Mbx-Apikey: $akey\r\n" .
                "Connection: Upgrade\r\n" .
                "Upgrade: websocket\r\n\r\n");
                $old  = time() + 180000000;
            fwrite($fp, $data);
            while (!feof($fp)) {
                $stat = fstat($fp);
                $fp2 = fread($fp, 8192);
                $new = time();
                $fp2 = decode($fp2);
                if ($fp2['opcode'] == 9) {
                    fwrite($fp, encode($new, 'ping'));
                    echo "\nPING\n\n";
                };
                if (isset(json_decode($fp2['message'])->data->p)) $fp3 = json_decode($fp2['message'])->data->p;
                if (isset($fp3)) echo $fp3."\n";
                print_r($fp2)."\n";
            }
    }
    fclose($fp);
    echo('close');
    
    function decode($str, $message_only = false)
        {
            /* Разбираем заголовок */
            if (empty($str)) return "\n\n Пустое значение \n\n";
            $header = unpack("n", $str)[1];         /* Рапаковываем первые 16 бит, порядок байт «big endian», т.к. сетевой протокол */
            $data = [];
            $data['fin']            = (bool) (($header >> (16 - 1))  & 0b1);        /* Финальный фрейм. Если сообщение нефрагмантированное, то всегда 1, если фрагмантированно, то у последнего 1 у остальных 0 */
            $data['rsv1']           = (bool) (($header >> (16 - 2))  & 0b1);        /* Флаги RSV1, RSV2, RSV3 служат для расширений протокола, почти всегда в false */
            $data['rsv2']           = (bool) (($header >> (16 - 3))  & 0b1);
            $data['rsv3']           = (bool) (($header >> (16 - 4))  & 0b1);
            $data['opcode']         = (int)  (($header >> (16 - 8))  & 0b1111);     /* Тип фрейма */
            $data['is_mask']        = (bool) (($header >> (16 - 9))  & 0b1);        /* Замаскированы ли фреймы */
            $data['length_prev']    = (int)  (($header >> (16 - 16)) & 0b1111111);  /* Предварительная длина фрейма */
    
            /* Определяем тип фрейма */
            switch ($data['opcode']) {
                case '1':
                    $data['type'] = '1'; //text
                    break;
                case '2':
                    $data['type'] = '2'; //binary
                    break;
                case '8':
                    $data['type'] = '8'; //close
                    break;
                case '9':
                    $data['type'] = '9'; //ping
                    break;
                case '10':
                    $data['type'] = '10'; //pong
                    break;
                default:
                    break;
            }
    
            /* Определяем длину фрейма */
            if ($data['length_prev'] < 126)
            {
                $data['length'] = $data['length_prev'];
            }
            elseif ($data['length_prev'] === 126)
            {
                $data['length'] = unpack("x2/n", $str)[1];
            }
            elseif ($data['length_prev'] > 126)
            {
    //          $data['length'] = unpack("x2/J", $str)[1];
                $data['length'] = unpack("x2/x4/N", $str)[1];
            }
    
            /* Маска */
            if ($data['is_mask'])
            {
                if ($data['length_prev'] < 126)
                {
                    $mask = substr($str, 2, 4);
                }
                elseif ($data['length_prev'] === 126)
                {
                    $mask = substr($str, 2 + 2, 4);
                }
                elseif ($data['length_prev'] > 126)
                {
                    $mask = substr($str, 2 + 8, 4);
                }
            }
    
            /* Тело запроса */
            $message_start = 2;
            if ($data['length_prev'] < 126)
            {
    
            }
            elseif ($data['length_prev'] === 126)
            {
                $message_start += 2;
            }
            elseif ($data['length_prev'] > 126)
            {
                $message_start += 8;
            }
    
            if ($data['is_mask'])
            {
                $message_start += 4;
            }
            $data['message_start'] = $message_start;
    
            $message = substr($str, $message_start, $data['length']);
    
            /* Размаскируем сообщение */
            if ($data['is_mask'])
            {
                $length = strlen($message);
    
                for ($i = 0; $i < $length; $i++) 
                {
                    $message[$i] = $message[$i] ^ $mask[$i % 4];
                }
            }
    
            $data['message'] = $message;
    
            /* Возвращаем сообщение */
            if ($message_only === false)
            {
                return $data;
            }
            else
            {
                return $data['message'];
            }
        }
    
        /**
         * Закодировать строку
         * 
         * @param string $str
         * @param boolean $is_mask
         * @return string
         */
        function encode($str, $ping = false, $is_mask = false)
        {
            $bin = "";
    
            /* Основные флаги */
            $data = 
            [
                "fin" => 0b1,
                "rsv1" => 0b0,
                "rsv2" => 0b0,
                "rsv3" => 0b0,
                "opcode" => 0x1,
                "is_mask" => $is_mask === true ? 0b1 : 0b0,
                "length" => strlen($str)
            ];
    
            if ($ping = 'ping') $data['opcode'] = 0xA;
    
            /* Предварительная длина */
            if ($data['length'] < 126)
            {
                $data['length_prev'] = $data['length'];
            }
            elseif ($data['length'] < 65536)
            {
                $data['length_prev'] = 126;
            }
            else
            {
                $data['length_prev'] = 127;
            }
    
            /* Заголовок */
            $header = $data['fin'];
            $header = $header << 1 | $data['rsv1'];
            $header = $header << 1 | $data['rsv2'];
            $header = $header << 1 | $data['rsv3'];
            $header = $header << 4 | $data['opcode'];
            $header = $header << 1 | $data['is_mask'];
            $header = $header << 7 | $data['length_prev'];
            $bin .= pack("n", $header);
    
            /* Расширенная длина тела */
            if ($data['length_prev'] === 126)
            {
                $bin .= pack("n", $data['length']);
            }
            elseif ($data['length_prev'] > 126)
            {
                $bin .= pack("x4N", $data['length']);
            }
    
            /* Маскировать сообщение */
            if ($is_mask)
            {
                $mask = substr(md5(microtime()), 0, 4);
                $bin .= $mask;
    
                $length = strlen($str);
                for ($i = 0; $i < $length; $i++) 
                {
                    $str[$i] = $str[$i] ^ $mask[$i % 4];
                }
            }
    
            $bin .= $str;
            print_r($bin)."\n";
            return $bin;
        }
    Ответ написан
    Комментировать
  • Как мне настроить .htaccess?

    @aspirantes
    Разные способы есть, один из топорных.

    RewriteRule ^картинка /img/image.jpg [L]
    RewriteRule ^скрипты /assets/js/app.min.js [L]
    RewriteRule ^стиль /assets/css/style.min.css [L]
    RewriteRule ^command/([абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯA-Za-z0-9-_]+)$ /php/ajax.php?get1=$1 [L]
    RewriteRule ^([абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯA-Za-z0-9-_]+)/([абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯA-Za-z0-9-_]+)/([абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯA-Za-z0-9-_]+)$ /index.php?get1=$1&get2=$2&get3=$3 [L]
    RewriteRule ^([абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯA-Za-z0-9-_]+)/([абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯA-Za-z0-9-_]+)$ /index.php?get1=$1&get2=$2 [L]
    RewriteRule ^([абвгдеёжзийклмнопрстуфхцчшщьыъэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯA-Za-z0-9-_]+)$ /index.php?get1=$1 [L]
    Ответ написан
  • Как не ожидать выполнения функции?

    @aspirantes
    Для меня лучший вариант "proc_open"

    https://www.php.net/manual/ru/function.proc-open.php

    Работает в php из коробки.
    Ответ написан
  • Почему функция загрузки картинки через форму post не работает?

    @aspirantes
    https://www.php.net/manual/ru/features.file-upload...

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

    @aspirantes
    Я пришёл к выводу, что достаточно хранить в сессии. Так как с другого устройства верификацию не должны проходить, за исключением случаев верификации по ссылке.
    Ответ написан
    Комментировать
  • Почему иногда проскальзывает значение повторно?

    @aspirantes Автор вопроса
    array_search() игнорирует первый элемент в матрице. Не знаю с чем связано, помогла замена на in_array()
    Ответ написан
    Комментировать