Ответы пользователя по тегу PHP
  • Как пройти авторизацию на сайте с помощью ЭЦП?

    @remzalp
    Программер чего попало на чем попало
    Если касается российского ЭЦП, то скорей всего это квалифицированная ЭЦП, чаще всего работает через криптопро
    cpdn.cryptopro.ru/content/cades/phpcades.html
    Может быть за компанию openssl. Сам ни разу такого не делал.

    Думаю, что потребуется внимательно смотреть в JS на сайте и аналогичным методом поступать.
    Как Вы будете получать доступ к ЭЦП тоже интересный вопрос
    Ответ написан
    6 комментариев
  • Почему пробелы заменяются на + в CURL POST JSON?

    @remzalp
    Программер чего попало на чем попало
    https://www.php.net/manual/ru/function.curl-setopt.php
    CURLOPT_POSTFIELDS
    Если value является массивом, заголовок Content-Type будет установлен в значение multipart/form-data.
    В этом случае заменяться не будут.

    Хвост растет из функции
    https://www.php.net/manual/ru/function.urlencode.php
    "а пробелы закодированы как знак сложения (+)"
    Ответ написан
  • Как правильно обработать большой JSON файл, расположенный на удаленном сервере?

    @remzalp
    Программер чего попало на чем попало
    JSON такого объема в принципе идея плохая. Встроенная функция json_decode умрёт, придётся писать какой-то парсер.
    Потому что эти 15 гигабайт должны будут целиком загрузиться в оперативную память, потом перестраиваться в объект. Итоговое потребление оперативной памяти пророчествую, не меньше 30 гигабайт и то считаю себя наивным.
    Ключевая проблема - файл нельзя читать порциями по заранее известному разделителю, получая валидные фрагменты JSON.
    Возможно добрые люди уже сделали из этого файла пачку JSON - просто дописывая построчно отдельные объекты, но тут лучше показать фрагмент файла, чтобы предлагать методы оптимизации.

    Посмотрите такой вариант для командной строки, запускайте на сервере который не жалко, возможно придётся потом его ронять в перезагрузку - https://stedolan.github.io/jq/

    Более цивильный вариант - CSV, читать построчно, копить пакет запросов в БД, пачкой в несколько десятков запросов лить в базу.

    UPD: гениальный вариант - а если залить это счастье напрямую в MongoDB, а потом по отдельным записям кромсать - получится?
    Ответ написан
  • Как реализовать такую структуру?

    @remzalp
    Программер чего попало на чем попало
    init.php:
    include "functions.php";
    include "index.php";
    Ответ написан
    Комментировать
  • Как сделать функцию, корректно обрабатывающую и кириллицу и латиницу?

    @remzalp
    Программер чего попало на чем попало
    php.net/manual/ru/function.mb-split.php
    корректно работает и с уникодовыми многобайтовыми символами.
    Ответ написан
  • Есть ли недочеты в коде?

    @remzalp
    Программер чего попало на чем попало
    Есть всего 3 значимых исхода:
    разница в днях = 0 - сегодня
    разница в днях = 1 - вчера
    разница в днях > 1 - писать дату.
    Зачем какие-то монстроидальные строки писать?

    Дальше - работаем с Unixtimestamp?
    Разница в датах: (int) ($date2 - $date1) / 86400
    без всяких лишних преобразований
    Ответ написан
    2 комментария
  • Как на сайт через PHP вставить значения из другой БД MySQL на другом сервере?

    @remzalp
    Программер чего попало на чем попало
    Вариант 1: просто коннектишься к удаленной БД, вместо localhost в настройках подключения пишешь IP сервера.
    Но с той стороны сервер БД должен быть настроен слушать не только localhost, а 0.0.0.0 или актуальный ип сервера. Плюс в настройках фаерволла разрешить доступ к серверу БД с ип первого сервера.

    Вариант 2: реализуешь на втором сервере на php какой-то примитивный api (google rest api). Пишешь скрипт, который на определенный запрос через веб генерирует запрос в БД, отдаёт результат в формате JSON.
    Из своего скрипта через curl или просто
    $obj = json_decode(file_get_contents("https://server2/api.php?id=$id"));

    и уже с этим объектом делаешь что нужно.
    Ответ написан
    Комментировать
  • Ошибка Row size too large?

    @remzalp
    Программер чего попало на чем попало
    Длина всей строки получается:
    id=4+last_access_time=4+34x255=8 678 байт.
    упёрлись в технические ограничения.

    Можно вылечить как советуют
    ALTER TABLE `user_settings` ROW_FORMAT=DYNAMIC;

    Ключевой вопрос - А ВАМ НАДО СТОЛЬКО ХРАНИТЬ ОДНОЙ ТАБЛИЦЕЙ?
    Исходя из чего выбиралась такая длина данных?
    varchar может быть использовать?
    Ответ написан
    4 комментария
  • Кодировка при curl?

    @remzalp
    Программер чего попало на чем попало
    У Вас проблема в том, что отдаёте кодировку UTF-8, а размещаете текст в кодировке 1251.
    Варианты:
    1. ответ kruslan - меняете кодировку до UTF-8 полученного текста
    2. header('Content-Type: text/html; charset=windows-1251')
    где-то в самом начале кода еще до вывода любого текста.
    Ответ написан
    Комментировать
  • Скрипт уведомлений о переходе на сайт из ПС?

    @remzalp
    Программер чего попало на чем попало
    $_SERVER['HTTP_REFERER'] содержит источник, откуда пришли, если он указан.
    Если там url поисковой системы (собирать список надо), то анализируем (urldecode) ссылку, откуда пришли, вытаскиваем нужное и с помощью функции mail отсылаем необходимую инфу.
    Но это дурацкое решение.

    Чуть лучше складывать в БД, а потом отсылать пачкой, запуская скрипт отправки по крону.

    Довольно хорошее - ставим яндекс-метрику, а потом смотрим её отчеты. Да, не увидим людей, с включенным adblock.
    Ответ написан
    3 комментария
  • Как составить регулярку на PHP?

    @remzalp
    Программер чего попало на чем попало
    1. не используйте регулярки для HTML. Есть огромное количество решений на базе DOM, css selector, xpath
    2. Скорей всего регулярка ломается на этом:
    <h4 class="textable">
      <h1 style="text-align: center;">
        ...
      </h1>
    </h4>

    И как, по Вашему мнению, это надо обрабатывать? Причем такая вложенность способна поломать логику и некоторым рекурсивным парсерам.

    <(h[1-7])[^>]*>(.*?)<\/\1>
    Вариант регулярки, которая ссылается на найденное название тэга, чтобы искать именно такой же закрывающий тэг.

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

    @remzalp
    Программер чего попало на чем попало
    У меня идиотский вопрос - что мешает один раз нормализовать данные в БД, чтобы не городить костылей?
    Почему название валюты внезапно стало значением?
    Почему в поле для хранения числовых значений вообще сумел храниться текст???

    На данный момент ситуация видится мне такой:
    #define TRUE FALSE //счастливой отладки

    На предмет костыля для решения проблемы:
    if (!is_numeric($cryptocurrency_value)) continue;
    if (!is_numeric($cryptocurrency_time)) continue;

    и всё, если у нас нет даты или числа в значении валюты - мы просто пропускаем эту запись.
    Добавить в цикле как раз по точке обрыва кода.
    Ответ написан
    3 комментария
  • Nginx + php-fpm дает 500 запросов/секунду?

    @remzalp
    Программер чего попало на чем попало
    Могут быть виноваты:
    1. Методика тестирования - тестировался совсем пустой index.php или что-то более сложное?
    2. Результаты TOP/IOTOP было бы интересно увидеть, вполне возможно, что тестировалась скорость жесткого диска или перегруженность процессора в случае оверселлинга

    с виду характеристик сервера хватает, а на деле может быть проблема была в коннекте к mysql
    Ответ написан
    5 комментариев
  • Распечатать массив в файле fwrite?

    @remzalp
    Программер чего попало на чем попало
    Это ж как надо не любить гугл с яндексом...
    mixed print_r ( mixed $expression [, bool $return = false ] )

    fwrite($fp, print_r($val_params, true))
    Ответ написан
  • Есть ли туториал как настроить интеграцию 1c и сайта используя commerceml?

    @remzalp
    Программер чего попало на чем попало
    v8.1c.ru/edi/edi_stnd/131
    собственно - всё, что нужно - официальный мануал. Плюс бонусом посмотреть единичную выгрузку из 1с для товаров. Этого за глаза, чтобы построить импорт товаров из 1С.

    Использовать со стороны 1С плагин - Сервис / настройки обмена с сайтом.

    Плюс есть готовый парсер:
    https://github.com/zenwalker/php-commerceml

    так что только заставить всё работать вместе
    Ответ написан
    1 комментарий
  • Как исправить кодировку сайта в ответ на cURL запрос?

    @remzalp
    Программер чего попало на чем попало
    Собственно Вам удаленный сайт уже и так всё говорит, почему бы не учесть то, что он говорит?

    1. Заглядываем в заголовки HTTP ответа, видим:
    Content-Type:text/html; charset=UTF-8
    2. Заглядываем в контент страницы, видим:
    <meta charset="UTF-8" />
    3. Есть еще один метод подсказать кодировку:
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    Решение - смотрим, чего нам говорят, подставляем в качестве параметра для iconv, но не забываем дефолтное значение на всякий случай.
    Вариант решения - если сайтов в ограниченное количество, храните где-то предпочитаемую кодировку.
    Фрагмент на python, реализующий автоматическое декодирование на основании заголовка ответа:
    encoding='utf-8' # кодировка по умолчанию
    tmp = r.headers.get('Content-Type').split('=') #режем по =, что справа - кодировка
    if len(tmp)>1: #если кодировка в заголовке есть - будет 2 элемента
        encoding=tmp[-1] # тогда берём последний
    page = r.content.decode(encoding)


    Итоговый ответ:
    <?php
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $engine_url );
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    ....
    //дополнить этим:
    curl_setopt($ch, CURLOPT_HEADER, 1);
    
    $tmpResult = curl_exec($ch);
    
    $header_size = curl_getinfo($ch,CURLINFO_HEADER_SIZE);
    curl_close($ch);
    
    $tmpHeaders = substr($tmpResult, 0, $header_size);
    $postResult = substr($tmpResult, $header_size);
    
    $headers = array();
    foreach(explode("\n",$tmpHeaders) as $header)
    {
    	$tmp = explode(":",trim($header),2);
    	if (count($tmp)>1)
    	{
    		$headers[strtolower($tmp[0])] = trim(strtolower($tmp[1]));
    	}
    }
    
    $encoding="utf-8"; //default
    if (isset($headers['content-type']))
    {
    	$tmp = explode("=", $headers['content-type']);
    	if (count($tmp)>1) $encoding = $tmp[1];
    }
    if ($encoding != "utf-8") $postResult = iconv($encoding, "UTF-8", $postResult);


    Всё. Получаем расширенный ответ, который содержит заголовки. Вырезаем из него заголовки и режем их в массив, плюс достаём тело ответа.
    Парсим заголовки http, вытаскиваем content-type и из него вытаскиваем кодировку
    Ответ написан
  • Как посчитать сумму детей необходимого узла за каждый день месяца (Nested Set)?

    @remzalp
    Программер чего попало на чем попало
    Изучите GROUP BY, который в случае с MySQL всё аккуратно отсортирует, сгруппирует, а за компанию и посчитает сумму.

    Не понимаю, откуда взялся и как работает getTreeSum(), мне кажется какой-то лишний оверкилл может происходить внутри.

    Дальше - допишите EXPLAIN перед своим запросом и покажите результат - это скажет, в каких местах всё плохо.

    Подозреваю, запрос должен делиться на 2 части - вывод идшников дочерних узлов вложенным подзапросом и SUMмма по полученному:
    WHERE id IN (select .... left_key >= левый_ключ_необходимого_узла AND right_key <= правый_ключ_необходимого_узла)
    Ответ написан
    Комментировать
  • Как залить товары в OpenCart «пачками»?

    @remzalp
    Программер чего попало на чем попало
    1. получаем товары:
    https://vk.com/dev/market.get
    Если есть проблемы с доступом к апи (не хватает прав) - создаёте приложение в ВК, получаете его ид и следуете по https://vk.com/dev/implicit_flow_user
    2. смотрим по импорту товаров в опенкарт
    начиная с https://www.opencart.com/index.php?route=marketpla...
    или любой на выбор
    3. пережевываем товары из вк в формат товаров опенкарта
    4. выгружаем.

    В особо сложном случае (как делал сам) пишется скрипт для импорта. Пример говнокода для версии 1.5, этого хватает, если остальные действия с товаром делать уже в админке - свойства, категории, проч.:
    ВНИМАНИЕ: БД в проекте, который показан в этом примере была сильно перекроена, в итоге поля description, image были вынесены из связанных таблиц и вставлены в эту (в связанных моделях пришлось аналогично поступать). Потеряна возможность хранить много фоток, многоязычность. Получен импорт 100к товаров секунд за 10.
    Спасибо alex-1917 за внимательность.

    <?php
    set_time_limit(0);
    error_reporting(E_ALL);
    
    include_once('config.php'); //конфиг админки
    $my = new mysqli(DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
    $my->set_charset("utf8");
    
    function addProduct($data,$my){
        foreach($data as $key=>$val)
        {
            $keys[] = '`'.$key.'`';
            $values[] = '"'.$my->real_escape_string($val).'"';
        }
        $keys[] = '`date_added`';   $values[] = 'NOW()';
        $keys[] = '`date_modified`';$values[] = 'NOW()';
    
        $keys2 = join(',',$keys);
        $vals2 = join(',',$values);
    
        $q = "INSERT INTO product ($keys2) VALUES ($vals2);";
        $my->query($q);
    }
    
    
    /*
    $items - массив с товарами из вк, в каталоге data лежат файлы с картинками
    */
    
    foreach($items as $item)
    {
        $data = array();
        $data['category_id'] = 1; //всё в один раздел
        $data['name'] = $item['name'];
        $data['description'] = $item['description'];
        $data['articul'] = $item['articul'];
        $data['quantity'] = 1;
        $data['stock_status_id'] = 1;
        $data['manufacturer_id'] = 0;
        $data['shipping'] = 1;
        $data['price'] = 0;
        $data['tax_class_id'] = 0;
        $data['subtract'] = 1;
        $data['minimum'] = 1;
        $data['image'] = 'data/'.$item['image'];
        $cnt++;
        addProduct($data,$my);
    }
    Ответ написан
    5 комментариев
  • Почему код грузит mysql?

    @remzalp
    Программер чего попало на чем попало
    1. $querystring - мне страшно даже думать про итоговый запрос. Изучите конструкцию "WHERE field_name IN (val1,val2,....)"
    2. WHERE `login`, ORDER BY `insearch` - индекс по этим полям создан?
    запрос вида
    EXPLAIN SELECT `account_id` FROM `accounts` WHERE `login` = 'any'
    даст немного инфы к размышлению
    3. $accounts[$i] что содержит? Может там многовато информации
    4. Весь цикл на самом деле можно свести к одному запросу
    SELECT `account_id` FROM `accounts` WHERE `login`IN(....)
    Ответ написан
    1 комментарий
  • Почему при скачке больших файлов через curl иногда они не докачиваются?

    @remzalp
    Программер чего попало на чем попало
    логируете всё на стороне php (лог ошибок посмотреть)
    берётё tcpdump, сохраняете дамп, анализируете в Wireshark

    одна из очевидных ошибок - пытаетесь всё забрать в оперативную память (отдаёте в переменную), а надо отдавать указатель на файл. CURLOPT_RETURNTRANSFER в случае больших файлов - вреден.

    Пример:
    $out = fopen($local_path.$newfilename,"wb");
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_FILE, $out);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_URL, $file);

    curl_exec($ch);
    curl_close($ch);
    Ответ написан
    Комментировать