Ответы пользователя по тегу PHP
  • Как лечить экранирующий слеш в json php?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Это именно та причина, по которой двойные кавычки использовать не стоит, нарваться можно и не на такие грабли, а потом 1000 лет отлаживать. Надеюсь, что этот опыт послужит вам хорошим уроком и в будущем позволит избежать подобных проблем. А заодно научит использовать IDE, где есть статический анализ и нормальная подсветка ;)

    spoiler
    5mn963wbx_tjjjlxoiinyncfve8.png


    P.S. Ну и конечно стоит читать документацию: php.net/manual/ru/language.types.string.php
    \[0-7]{1,3} последовательность символов, соответствующая регулярному выражению символа в восьмеричной системе счисления, который молча переполняется, чтобы поместиться в байт (т.е. "\400" === "\000")
    Ответ написан
    Комментировать
  • Как правильно указать директорию?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Вопроса нихрена не понял, но в коде есть ошибки, обуславливающиеся малым опытом:
    1) По теме: "define('DIR_TMPL', __DIR__ . '/tmpl');" избавит от указаний полного пути.

    Прочее:
    2) Глобальные штуки - это всегда плохо. Константы достаточно заменить на файлы конфигураций, а ещё лучше класс, который умеет читать эти файлы:
    <?php
    // config/example.php
    return [
        'templates' => __DIR__ . '/tmpl'
    ];

    $config = new Config(__DIR__ . '/config');
    $config->get('example.templates'); // ".../tmpl"


    В дальнейшем это позволит расширять и модифицировать конфиги за счёт переменных окружения, т.к. реальный способ чтения конфигов скрыт за соответствующим классом.
    Ответ написан
    2 комментария
  • Запись в файл данных.?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Помимо ответов выше, стоит почитать документацию: php.net/manual/ru/function.file-exists.php

    file_exists - это проверка директории или файла. А записать в папку данные невозможно. Если в "$log_file" будет путь к папке - будет ошибка.
    Ответ написан
    Комментировать
  • Библиотеки для работы со строками и массивами?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Массивы, строки, коллекции: https://github.com/illuminate/support
    Каррирование и частичное применение: https://github.com/SerafimArts/Curry
    Ответ написан
    Комментировать
  • Как правильно обрабатывать ошибки и исключения?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Стоит разделять публичные и приватные исключения. Пользователям не стоит видеть внутреннюю кухню. Так что:
    class HttpExcepton extends RuntimeException {}
    class ExampleHttpException extends HttpExcepton {}
    
    //
    
    throw new ExampleHttpException('Сообщение не может быть пустым', 422);


    Так что всё это дело можно свести к одному единственному try/catch, который будет выводить текст из всех HttpExcepton (и статус код, например, в данном примере 422), и выводить сообщения "Internal Server Error" от любых других.
    Ответ написан
    4 комментария
  • Как открыть проект на локалочке windows?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Скачать php с офф сайта и в консоли проекта набрать php app/console server
    Ответ написан
    Комментировать
  • Обычный метод копируется для каждого объекта или PHP оптимизирует и не делает копию методов для объектов?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    У каждой функции в PHP есть два контекста: Статический и объекта. Метод - это обычная именованная функция, у которой заранее объявлены оба этих контекста. Таким образом мы получаем, что метод один и выделение памяти под него тоже одно, но для разных объектов меняется контекст (т.е. ссылка на this), а значит создание нового объекта - это всего лишь выделение this контекста для метода, т.е. тупо один адрес.

    Помимо этого, создавая новый объект память не выделяется вообще. Если объект идентичен предыдущему, то адрес нового объекта соответствует предыдущему с пометкой разделения ZVAL-структуры при мутациях (до некоторого времени даже баг был, когда функция spl_object_hash возвращала одну и ту же строчку для двух разных объектов, которые содержали одни и теже данные). Во время изменений объектов - ссылка на изменённое поле разделяется и новое значение пытается занять память тех переменных (напоминаю, что структура ZVAL едина для всех типов переменных), которые были помечены для уничтожения через GC (т.е. refcount=0), это позволяет избавиться от лишних аллокаций памяти. Такая модель поведения, например, позволяет делать клонирование (оператор clone) и инстанциирование (оператор new) объектов без выделений памяти вообще.

    P.S. Так было в какой-то из 5.х веток, когда я исследовал поведение пыха. Сейчас же, когда на носу 7.3 - я уже хз, много поменяли, хотя в основном работа была проведена по уменьшению потребления памяти zval объектами, DCE оптимизациям и AVX/SSE инструкциям, так что не думаю что сильно.
    Ответ написан
    Комментировать
  • Как построить архитектуру веб-сервиса на PHP?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Возможно, это всё не нужно и лучше использовать готовые решения, а не велосипед?

    Не возможно, а точно.

    P.S. Это даже не мини, а просто набор файлов времён php 4)))
    Ответ написан
    Комментировать
  • Почему запрос к бд возвращает ошибку?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Ураааа, новая классическая дырища в сайте!

    Вы ведь понимаете, что благодаря этому коду, после того как он заработает - вас сможет взломать любой школьник?
    Ответ написан
    Комментировать
  • Консольный скрипт php?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Правильно ли я понимаю, что т.к. PHP не асинхронный язык,

    Нет, не правильно.

    то если пользователь 1 отправил запрос (например он будет выполняться 10 секунд), а через 2 секунды пользователь 2 отправит тоже запрос, то он обработается только тогда, когда запрос от 1 юзера будет готов?


    Зависит от реализации и наличии блокирующих операций.

    Стоит заметить, что не важно синхронные операции или нет - сумма общего выполнения запросов будет идентичной (хотя в случае асинхронной работы даже дольше, т.к. издержки на переключение контекстов).

    Есть некая реализация вебсокетов на php (реализовано на основе этого).

    Феерический трешак. Ни тестов, ничего. Да и в коде глобалсы. Жесть
    Ответ написан
    Комментировать
  • Как отформатировать php + html код?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    намешал php и htm

    намешаны пробел и tab

    переносы строк и скобки.


    Лучший вариант: Ctrl+A -> Delete

    Вариант чуть похуже, но тоже ничего: PhpStorm -> Ctrl+Shift+Alt+L -> Enter
    Ответ написан
    2 комментария
  • Обучение PHP: как праквильно практиковаться в нем?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Хотите практики - запилите бложик себе. Самое популярное занятие в '18ом году после туду листов
    Ответ написан
    1 комментарий
  • Как усовершенствовать функцию?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    return \collect((array)$requestTags)->map(function($tag): int {
        return \is_numeric($tag) ? (int)$tag : Tag::upsert(['name' => $tag])->id;
    });
    Ответ написан
    1 комментарий
  • Как правильно протестировать метод?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    mockery?
    Ответ написан
    Комментировать
  • В чем отличие контроллера от экшена?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Немного о наболевшем:

    В MVC нет экшенов. MVC работает следующим образом:
    - Во вьюхе располагается модель (например "текстовое поле")
    - Любые изменения в модели сразу же изменяют вью (изменяем текст в текстовом поле и этот текст визуализируется/рендерится)
    - Контроллер подписывается на события вьюхи (например "изменение текста в текстовом поле") и выполняет какое-либо действие, в том числе изменяет модели (ну хз, например проверяет что длина не более 10 символов. Или другой пример. Контроллер подписывается на событие нажатия кнопки "delete" и удаляет текст из модели текстового поля, а модель сразу же перерисовывается, т.к. напрямую связана с представлением).

    MVC-Process.png

    Всё это прекрасно видно на картинке, которая взята с вики: https://ru.wikipedia.org/wiki/Model-View-Controller

    В вебе реализация MVC без сокетов не возможна физически (который, к слову, в районе 80х-90х годов назывался MVCE: Model-View-Controller-Editor, не суть). Большинство существующих решений - это вариации MVP (Laravel/Symfony/etc) с небольшими нюансами. Контроллер там называются контроллерами, а не презентером по принципу GRASP и никак не связан с MVC.

    НО. Есть такая штука как коллективное мнение. Например, по правилам русского языка можно писать "парашут", а не "парашют" начиная с какого-то там 2010го года. Это теперь норма. Хз. Короче безграмотных неучей дохрена. И т.к. таких реально дохрена, кто не может отличить одно от другого и не быть неучем, то решили что назовём-ка мы это дело "MVC с пассивными моделями", потому что называть этот подход MVP слишком сложно, это же читать надо ещё, учиться, лучше будем терминами кидаться, подумают что умный.

    Так вот, к чему я веду. Классический MVP в вебе неудобен (что можно увидеть на примерах первого Zend, Phalcon и прочих догматов), по-этому добавили прослойку в виде роутера, который говорит: "По адресу /users при GET запросе отправляйся мне вот в этот класс и выполни вот этот метод", например: "$router->get('/users', 'UserClass', 'action')". Сам метод, возвращает нужную вьюшку с данными и называется "экшен", а класс, который содержит набор этих самых "экшенов" называется "контроллер" или "презентер". Во вьюшке, с помощью читов (шаблонизатора) можно указать, например, какой хедер\футер (лайаут) использовать, какой тайтл и прочее. Таким образом мы получаем разные страницы по разным адресам с разными данными, с возможностью сохранить основное оформление и пересипользовать какие-то другие куски вьюшек.
    Ответ написан
    1 комментарий
  • Как правильно и проще сделать генерацию ключа?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    \base64_encode(\random_bytes(...));
    Не проще ли?
    Ответ написан
    Комментировать
  • Где могут пригодиться итераторы PHP?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Ну раз нужны примеры, то что-нибудь придумаю...

    Задача следующая. Надо делать запросы к АПИ по всем доступным страницам, ну я не знаю, например полчаем статьи с хабра. Алгоритм следующий:
    - Работаем до тех пор, пока страница не является последней
    - Получаем список статей и начинаем их возвращать.
    - Как только они кончатся, проверяем, является ли текущая страница последней.
    - И так до тех пор, пока страница не кончится.

    class HabraArticles implements \IteratorAggregate 
    {
        // ...
        // Какие-то методы настроек апишки
        // ...
    
        public function getIterator(): iterable
        {
            $page = 0;
    
            do {
                $response = // запрос_к_апи?page=$page++
                yield from $response['articles'];
            } while ($response['last_page'] !== $page);
        }
    }


    И использование. Мы создаём новый объект нашего апи и настраиваем его. Как только начинаем по нему пробегаться через foreach - автоматом вызывается нужный метод интерфейса (в нашем случае getIterator, т.к. заюзали интерфейс IteratorAggregate).
    $articles = (new HabraArticles)
        ->какой_то_метод_настроек(23)
        ->ещё_какой_то_метод_настроек(42);
    
    foreach($articles as $article) {
        \var_dump($article); // Пробегаемся по всем существующим статьям и не думаем о том, как оно работает.
    }


    Схожим образом реализован, например, симфонёвый файндер: symfony.com/doc/current/components/finder.html
    Ответ написан
    1 комментарий
  • Почему не устанавливается phalcon?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    ini для сервера и для консоли разные. Просто добавьте экстеншн в серверное окружение и всё будет работать.

    1) В консоли просто посмотрите пути к экстеншенам, они примерно следующего вида: /etc/php/7.2/...
    2) Там несколько папочек, одна из них cli - это консольные конфиги
    3) Перемещаете (копируете) ссылку на фалкон в другую с веб окружением (я точно не помню как называется, но там по имени будет понятно).

    `sudo service php-fpm restart` и всё.
    Ответ написан
    1 комментарий
  • PHP. Как распарсить PHP файл?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Два варианта выше вполне годятся. Ну или написать свою EBNF грамматику, воспользовавшись:
    1) Hoa LL(1)/LL(k): https://github.com/hoaproject/Compiler (Пример выше nikic от Mikhail Osher использует LALR парсер на основе Yacc)
    2) Или моим форком: https://github.com/railt/compiler (возможности грамматики почти те же, но исправлено несколько ошибок, переписаны исходники и ускорен лексический анализ в 140 раз).
    Ответ написан
    Комментировать
  • Поле с каким типом данных нужно создать в MySQL для хранения массивов?

    SerafimArts
    @SerafimArts
    Senior Notepad Reader
    Эм, а может всё же не парить мозг и использовать JSON тип? Там и индексация, как бы есть, да и тип нативный...
    Ответ написан
    Комментировать