• Как считать ответ POST частями?

    kot2566
    @kot2566 Автор вопроса
    а какая разница, когда она закончится, если я точно знаю, что объём данных от сервера в каждом новом запросе будет всегда расти x2. И надо заранее предусмотреть этот случай
  • Как отправить пакетированный запрос multipart/mixed?

    kot2566
    @kot2566 Автор вопроса
    Надим Закиров,
    Вот так пытаюсь формировать, в итоге в переменной $response просто значение false

    $CAL_BATCH_URL = 'https://www.googleapis.com/batch';
    
        $ch = curl_init($CAL_BATCH_URL);
    
    
        $access_token = 'myToken';
        $boundary = 'batch_' . uniqid();
        $data = '';
    
        $data .= "--" . $boundary . "\r\n";
        $data .= 'Content-Type: application/http' . "\r\n";
        $data .= 'Content-ID: ' . "\r\n";
        $data .= 'Content-Transfer-Encoding: binary' . "\r\n\r\n";
    
        // Add batches
        foreach ($content as $one_request_item) {
            $data .= "--" . $boundary . "\r\n"
                . 'POST ' . '/v3/urlNotifications:publish' . "\r\n"
                . 'Content-Type: application/json' . "\r\n"
                . 'Content-Length: ' . strlen(json_encode($one_request_item)) . "\r\n\r\n";
            $data .= json_encode($one_request_item) . "\r\n\r\n";
        }
    
    
        // Headers
        $headers = array(
            "Authorization: Bearer " . $access_token,
            "Host: www.googleapis.com",
            "Content-Type: multipart/mixed; boundary={$boundary}",
            'Content-Length: ' . strlen(json_encode($content))
        );
    
        // Curl Setup
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);
        curl_setopt($ch, CURLOPT_VERBOSE, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    
        $response = curl_exec($ch);
  • Как объединить запись в базу?

    kot2566
    @kot2566
    Можно убрать отдельную кнопку Загрузить и оставить только одну кнопку со свойством submit.
    А проверять наличие картинки по полю $_FILES['img_upload']

    <form action="admin" method="post" enctype="multipart/form-data">
    
        <input type="text" name="name">
        <input type="text" name="description">
        <input type="submit" name="myform" value="OK">
    
        <p>Загрузить картинку</p>
        <input type="file" name="img_upload">
    
    </form>


    Можно убрать отдельную кнопку Загрузить и оставить только одну кнопку со свойством submit.
    А проверять наличие картинки по полю <i>$_FILES['img_upload']</i>
    
    <code lang="html">
    <form action="admin" method="post" enctype="multipart/form-data">
    
        <input type="text" name="name">
        <input type="text" name="description">
        <input type="submit" name="myform" value="OK">
    
        <p>Загрузить картинку</p>
        <input type="file" name="img_upload">
    
    </form>
    </code>
    
    
    <code lang="php">
    if (isset($_POST["name"]) && isset($_FILES['img_upload'])) {
    
        try {
            $img_type = substr($_FILES['img_upload']['type'], 0, 5);
            $img_size = 2 * 1024 * 1024;
            if (!empty($_FILES['img_upload']['tmp_name']) and $img_type === 'image' and $_FILES['img_upload']['size'] <= $img_size) {
                $img = addslashes(file_get_contents($_FILES['img_upload']['tmp_name']));
            }
        }
        catch (Throwable $exception)
        {
            exit('<p>Не удалось сохранить файл</p>');
        }
    
    
        $sql = mysqli_query($connection, "INSERT INTO `catalog` (`name`, `description`, `img`) VALUES ('{$_POST['name']}', '{$_POST['description']}', '{$img}')");
        if ($sql) {
            echo '<p>Данные успешно добавлены в таблицу.</p>';
        } else {
            echo '<p>Произошла ошибка: ' . mysqli_error($link) . '</p>';
        }
    
    }
    </code>
  • Как асинхронно прочитать файл?

    kot2566
    @kot2566
    Если нужно просто создать задачу, то достаточно вести учёт этих задач в базе в виде очереди.
    Новые задачи добавлять в таблицу tasks со статусом wait.
    А уже выполнять задачи уже через CRON - модуль, который периодически вызывает ваш скрипт, который и выполняет тяжелую операцию и всё остальное (callback, удаление задачи из базы).
  • Как провести соответствие между строкой и классом с точки зрения SOLID?

    kot2566
    @kot2566 Автор вопроса
    FanatPHP, всё, теперь более-менее понял, спасибо
  • Как провести соответствие между строкой и классом с точки зрения SOLID?

    kot2566
    @kot2566 Автор вопроса
    FanatPHP,
    в Animal не должен быть,
    в ZooStore не должен быть,
    ... неизвестное количество других функций, классов, где используется ZooStore - в них не должен быть
    SomeClass1<===SomeClass1<===..<.===...<==ZooStore<===Animal

    Доходим до самой внешней точки, например, считывание из $_GET.
    Всё, тут уже можно делать switch.

    Понимаю, что утрирую, извините.

    $zoo_store = new ZooStore();
    $visitor = new Human(new HumanVoiceEngine());
    
    $animal_type = $_GET['animal_type'];
    
    switch ($animal_type) {
        case 'cat':
            $animal = new Cat(new CatVoiceEngine());
            break;
        case 'dog':
            $animal = new Cat(new CatVoiceEngine());
            break;
         default:
           errorHandler();
            break;
    }
    $zoo_store->OpenСageWithLabel($visitor, $animal);
    
    
    class ZooStore
    {
        /**
         * Открыть для посетителя Клетку с КОНКРЕТНЫМ животным
         * @param Human $visitor
         * @param Animal $animal
         */
        public function OpenСageWithLabel(Human $visitor, Animal $animal)
        {
            $visitor->touchAnimal($animal);
        }
    }
  • Как провести соответствие между строкой и классом с точки зрения SOLID?

    kot2566
    @kot2566 Автор вопроса
    Спасибо за развёрнутый ответ.
    В третьем варианте имелось ввиду "говорящее животное" (VoiceAnimal <=> AnimalWithVoice), мой неправильный нейминг ;(

    Но и в третьем варианте и в вашем случае эта "проклятая" логика со switch переносится наверх.
    Можно ли как-то от этой логики с разветвлениями избавиться или так и должно быть?
    Например, в классе ЗооМагазин, который может Открыть клетку с животным для посетителей, на которой жёстко прописан вид животного:
    class ZooStore
    {
        /**
         * Открыть для посетителя Клетку с табличкой, на которой Написан Вид животного (например, 'cat')
         * @param Human $visitor
         * @param string $label
         */
        public function OpenСageWithLabel(Human $visitor, string $label)
        {
            switch ($label) {
                case 'cat':
                    $animal = new Cat(new HumanVoiceEngine()); //не относится к вопросу: кошка может заговорить из-за слабой связности?
                    break;
                case 'dog':
                    $animal = new Dog(new DogVoiceEngine());
                    break;
            }
            $visitor->touchAnimal($animal);
        }
    }
  • Как провести соответствие между строкой и классом с точки зрения SOLID?

    kot2566
    @kot2566 Автор вопроса
    kot2566, не знаю, только если сделать через функцию, у которой указать возвращаемый тип:
    class Human
    {
        public  $animals = [
            'dog' => Dog::class,
            'cat' => Cat::class,
        ];
    
        public function touchAnimal($animal_type)
        {
            $animal = $this->getAnimal($animal_type);
            $animal->say();
        }
    
        public function getAnimal($name): VoiceAnimal
        {
            return $this->animals[$name]();
        }
    }
  • Как провести соответствие между строкой и классом с точки зрения SOLID?

    kot2566
    @kot2566 Автор вопроса
    Михаил,
    да, может лежать, но толку от этого :( :
    $home_animals = [
                'dog' => Dog::class,
                'cat' => Cat::class,
            ];


    Ide перестаёт видеть тип при динамическом присваивании и из-за этого большая вероятность ошибиться/опечататься:
    animal  = new Dog();
    $animal->say(); // IDE подсказывает, что у объекта $animal можно вызвать say
    
       $animal = new $this->home_animals[$animal_type](); 
            $animal->say();  // IDE перестаёт знать объектом какого класса является переменная и не подсказывает
  • Как провести соответствие между строкой и классом с точки зрения SOLID?

    kot2566
    @kot2566 Автор вопроса
    Это же на Java код, если не ошибаюсь?
    Проблема всего топика сводится к этой строчке:
    Supplier<Voice> supplier = suppliers.get(type);
    А в динамическом PHP вроде так не получится (нельзя принудительно указать тип переменной или сделать приведение к нужному классу):
    Voice $supplier = $suppliers.get(type);
    // или 
    $supplier = (Voice) $suppliers.get(type);

    Поправьте, если неправ.
  • Как сделать lazy-load нормально(async load)?

    kot2566
    @kot2566 Автор вопроса
    Идёт не так то, что браузер ждёт загрузку гифок, даже если я привязываюсь к событию ondomcontentloaded.
    НО если я оборачиваю это в SetTimeout, то браузер думает, что загрузил страницу полностью (хотя гифки ещё не загрузились). То есть как надо.

    И pagespeed тоже видит эти гифки, снижая индекс производительности.
    Мне нужно, чтобы сперва страница прогрузилась и отдельно Независимо грузились гифки, не влияя на скорость всего остального, но без settimeout.
    ПРИМЕРЫ:
    1) Как вы говорите (просто на событие ondomcontentloaded)
    kot256x3.beget.tech/index1.html
    PageSpeed 1
    PageSpeed "палит" мои гифки
    6203cecc02c96069288273.png

    2) Вместе с SetTimeout 4 секунды:
    kot256x3.beget.tech/index2.html
    PageSpeed 2

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

    Возможно, я неправильно что-то сделал при тесте, заранее извиняюсь.
  • Как сделать lazy-load нормально(async load)?

    kot2566
    @kot2566 Автор вопроса
    Я надеялся, что есть готовое надёжное решение.
    Я не понимаю, зачем мы вынуждены использовать SetTimeout, если мы делаем операции по замене внутри, например, $(document).ready( ?
    Почему SetTimeout с задержкой 10мс не срабатывает как ожидается (как будто многопоток)?
    $(document).ready(function () {
         // способ 1
        $("img[async-src]").each(function (index) {
            // $(this).attr("src", $(this).attr("async-src"));
            
            setTimeout(function () {
                $(this).attr("src", $(this).attr("async-src"));
            }, 5000);
        });
    
        // способ 2
        $("img[async-src]").each(function (index) {
            let self = $(this).parent();
            let src = $(this).attr("async-src");
    
            setTimeout(function () {
               
                var img = new Image();
    
                img.onload = function () {
                    self.append(img)
                };
                img.src = src;
            }, 5000);
    
        });
      });


    Как высчитать оптимальное значение задержки для SetTimeout?
  • Как сделать lazy-load нормально(async load)?

    kot2566
    @kot2566 Автор вопроса
    Alex Karo, Изначально было с этим атрибутом, но не подходит, так как gif-ка должна отображаться сразу на первом экране, в видимой области экрана.

    Атрибут loading элемента (или loading (en-US) атрибут для (en-US)) могут быть использованы, чтобы указать браузеру на необходимость отложить загрузку изображений / iframe до тех пор, пока пользователь не доскроллит до них.
  • Как сделать lazy-load нормально(async load)?

    kot2566
    @kot2566 Автор вопроса
    620172a879e3e988300335.png
    Нет, не помогло.

    На боевом сервере подключение скрипта с атрибутом defer и запуск внутри $('document.ready'). То есть происходит позже DOMContentLoaded и всё равно нет.
    Не могу настройку в библиотеке, чтобы она работала как хочу, но не только по скроллингу.
  • Могу ли я создать чатбота для Instragram также, как для Telegram?

    kot2566
    @kot2566 Автор вопроса
    shurshur, Осталось понять как реализовать deep-linking https://qna.habr.com/q/1100506
    если он там вообще есть
  • Могу ли я создать чатбота для Instragram также, как для Telegram?

    kot2566
    @kot2566 Автор вопроса
    shurshur, сперва отсюда взял https://developers.facebook.com/docs/messenger-pla...
    там как раз "template_type":"button", не сработало.
    Да, потом через generic заработало:
    "message": {
            "attachment": {
                "type": "template",
                "payload": {
                    "template_type": "generic",
                    "elements": [
                        {
                            "title": "Welcome!",  // обязательно указывать
                            "buttons": [
                                {
                                    "type": "postback",
                                    "title": "Start Chatting",
                                    "payload": "DEVELOPER_DEFINED_PAYLOAD"
                                }
                            ]
                        }
                    ]
                }
            }
        }
  • Как сделать описанный редирект?

    kot2566
    @kot2566
    RewriteRule ^video\/nazvanie-video-(\d+)-(\d+)-(.+)$ nazvanie-video-$1