PHP Curl: Segmentation fault

Столкнулся со странной ошибкой на Astra Linux, а именно если вызывать:

curl --insecure 'https://esia.gosuslugi.ru/login/'

То получаем ошибку:

Хотя в любом другом дистрибутиве получаю стандартное:

ошибка сегментирования

Начал рыть….долго и упорно… искал разницу между установленными версиями curl. И единственное что по большому счёту отличало версию Astra Linux — поддержка сертификатов шифрования ГОСТ. А сайт Госуслуг именно их и использует. Причем шифрование на этом сайте версии 1.3. А что если попробовать принудительно попросить curl именно это шифрование? И в правду заработало:

curl --insecure  --tlsv1.3  'https://esia.gosuslugi.ru/login/'

На PHP аналог выставления данного флага:

curl_setopt ($ch, CURLOPT_SSLVERSION , CURL_SSLVERSION_TLSv1_3);

Хотя конечно остаются вопрос, почему просто падает не показывая почему..

PHP и его странная математика

Столкнулся с очень чудесной ошибкой на PHP:

<?php
$a=1.15;
$b=$a*100;
var_dump($b);
echo $b;
echo "\n";
?>

Что вы ожидаете увидеть в выводе? 115? А вот и нет. Если echo выведет 115, то var_dump выведет 114.99999

Что не так с float?

Тип float в языке PHP, как и его “родственник” тип double, вовсе не предназначен для точного представления десятичных дробей. Всё что мы записали в float, хранится в приближенном значении, с некоторой погрешностью.

Решение: в виду того что в PHP это считается фичей, а не багом, то для точной работы с математикой нужно использовать модуль bcmath. Ну или использовать округления до нужной точности

P.S. Не первый раз уже вспотыкаюсь об это

Таблица в массив на php

Задача: Есть некая очень захламленная сторонними элементами страница в разметке html. Необходимо преобразовать находящуюся на ней таблица в массив данных.

Решение: сначала вычленим «грязное» содержимое таблицы между тегами <tbody></tbody>, затем преобразуем его в DOM документ, а далее уже распарсим его обходами и разложим элементы в массив.

Получилось что-то вроде:

 //вычленяю таблицу
        $t1=explode("<tbody>",$res);
        $t2=explode("</tbody>",$t1[1]);
        $tbody="<html><head><meta charset='UTF-8'></head><body><table><tbody>".$t2[0]."</tbody></table></body></html>";
        
        $mass=[];
        $dom = new domDocument('1.0', 'utf-8'); 
        @$dom->loadHTML($tbody);         
        $tables= $dom->getElementsByTagName('table');
        foreach ($tables as $table) {
            $trs= $table->getElementsByTagName('tr');
            foreach ($trs as $tr) {
                $tds=$tr->getElementsByTagName('td');
                $info=[];
                foreach ($tds as $td) {                    
                    $info[]=$td->textContent;
                };
                $mass[]=$info;
            }
        }        

Bitrix: Request is not XHR

В одном из проектов, скрипт парсит сайт на bitrix. С какого то момента, при установке параметров таблицы отдаваемой по ajax, стала выводиться ошибка «Request is not XHR». Быстрый гуглинг решения не дал. Стал кропотливо сравнивать заголовки которые отдаются запросом в браузере и заголовки который отдавал в скрипте. Отличие нашлось относительно быстро, страница на сайте добавляла дополнительный заголовок «Bx-ajax:true». В результате модифицировал скрипт следующим образом:

        $custom_header=[];
        $custom_header[]="Access-Control-Allow-Origin: *";
        $custom_header[]="Accept: */*";
        $custom_header[]="Bx-ajax:true";
        $res=$this->request("/bitrix/components/bitrix/main.ui.grid/settings.ajax.php?GRID_ID=".$grid_id."&bxajaxid=".$bxajaxid."&action=setSort",$param,"POST",true,$custom_header);        
        var_dump($res);

Сама функция запроса уже устоялась, и при таскании из скрипта в скрипт у меня выглядит так::

 public function request($query,$param,$type="POST",$headers=false,$custom_header=[],$follow_location=true) {
        $url=$this->url.$query;
        if ($this->debug==true){echo "URL:$url\n";};
        $ch = curl_init($url);        
        curl_setopt($ch, CURLOPT_VERBOSE, $this->debug);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $follow_location); 
        if ($headers==true){
            curl_setopt($ch, CURLOPT_HEADER, 1);
        };
        if ($type=="POST"){
            curl_setopt($ch, CURLOPT_POST, 1);        
            curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
            if ($this->debug==true){
                echo "---------------- POST -------------\n";
                var_dump($param);
                echo "-----------------------------------\n";
            };
        };        
        if (count($custom_header)>0){          
          curl_setopt($ch, CURLOPT_HTTPHEADER, $custom_header);  
          if ($this->debug==true){
            echo "---------------- HEADER -------------\n";            
            var_dump($custom_header);
            echo "-----------------------------------\n";
          };
        };
        if (count($this->cookies)>0){
            $str_cook="";
            foreach ($this->cookies as $key=>$value) {
             $str_cook=$str_cook.$key."=".$value.";";   
            };
            if ($this->debug==true){
                echo "COOKIE:$str_cook\n";  
            };

            curl_setopt($ch, CURLOPT_COOKIE,$str_cook);               
        };
        
        $res=curl_exec($ch);        
          if (curl_errno($ch)) {
            $error_msg = curl_error($ch);
            if ($this->debug==true){
              var_dump($res);
              var_dump($error_msg);
              die();  
            };
          };  
        if ($this->debug==true){
                echo "---------------- РЕЗУЛЬТАТ -------------\n";
                var_dump($res);
                echo "-------------------------- -------------\n";
        };          
        return $res;
    }    
Request is not XHR

Работа с архивами zip на PHP

Для начала прочитаем содержимое архива (чтение архива zip на php). Во встречающихся на просторах интернета примерах, зачастую игнорируется тот факт, что имена файлов могут быть в кириллице.В результате пользователи видят «крякозябры». А zip хранит имена файлов, указывая их не в кодировке UTF-8, а в кодировке cp866 (видимо из соображения совместимости). По крайне мере на Windows. Поэтому имена файлов перед употреблением, нужно переформатировать в UTF-8.

$za = new ZipArchive();
$za->open(WUO_ROOT."/tmp.zip");
$result_stats = array();
for ($i = 0; $i < $za->numFiles; $i++){
    $name = $za->getNameIndex($i, \ZipArchive::FL_ENC_RAW);
    $encoded_filename = iconv("cp866","UTF-8//IGNORE",$name);
    var_dump($encoded_filename);
}

Далее попробуем распаковать понравившийся файл:

file_put_contents(WUO_ROOT."/peni.xls", $za->getFromIndex($index_file_peni));

Как видно, всё достаточно просто.

чтение архива zip на php
1 2 3 4 5 24