Задать вопрос
Ответы пользователя по тегу PHP
  • Переписать грамотнее и с помощью Laravel реально ли и каким лучше образом?

    Шаблонизатор - прекрасная и очень нужная штука для PHP.

    Вы, я вижу, не хотите переписывать код. Однако, подумайте, вы ведь всё равно уже намешали код с разметкой, и для внедрения шаблонизатора всё равно придется очень много всего переписывать.

    Поэтому, совет перейти на Laravel очень разумен. Это неплохой выбор, фреймворк крайне популярен, в него встроено вообще всё, что вам понадобится для написания практически любого проекта.

    Могу дать вам ещё один вариант вместо Laravel. Это Symfony. Да, освоение этого фреймворка будет немного сложнее, чем Laravel, но преимуществом Symfony является то, что он заставляет писать код чище, чем обычно пишут на PHP. Он более строгий, а строгость в программировании всегда к лучшему. Symfony состоит из большого числа компонентов, и собирать проект можно как конструктор. Минимальная его сборка весьма легковесна. Кстати, огромное количество компонентов Symfony используется и в других фреймворках, многие из них можно использовать и без фреймворка.

    Как раз таким компонентом, который можно использовать без фреймворка, т.е. так, как вы хотите, является шаблонизатор Twig. Это превосходный шаблонизатор, его легко внедрять.
    https://twig.symfony.com/

    Но всё же рассмотрите возможность перейти на фреймворк, потому что сейчас в мире PHP почти везде используют именно фреймворки.
    Ответ написан
    9 комментариев
  • Какой аналог itemOperations в api-platform 3 версии?

    Сам ещё не ставил третью версию, но одним глазом посмотрел документацию, и вроде как они тупо по названию классов в аргументе options ориентируются. В принципе, это логично, если подумать. Но не очевидно.
    #[ApiResource(
        operations: [
            new Get(), // item
            new Put(), // item
            new Patch(), // item
            new Delete(), // item
            new GetCollection(), // collection
            new Post() // collection
        ],
    )]
    Ответ написан
  • Как можно решить проблему с доступам к методам PHP классов унаследованным от одного класса?

    Красиво сделать не получится. Но можно сделать так, чтобы хотя бы на тестах оно упало и показало, что нельзя так делать.

    <?php
    
    class Node
    {
        protected function func1() {
            print "NODE PARENT; ";
        }
    }
    class NodeA extends Node
    {
        public function FUNC2() {
            print "NODE A; ";
        }
    
        // Используем метод родителя внутри этого класса
        public function func1Overrided() {
            print "From parent: " . parent::func1();
        }
    
        // Переопределяем метод так, чтобы его нельзя было использовать
        protected function func1() {
            throw new \Exception("Нельзя вызывать этот метод из NodeB");
        }
    }
    
    class NodeB extends Node
    {
        // Функция инициализации
        public function onInit(NodeA $a): void
        {
            // Сделал так, чтобы не мокать api )
            (function (?NodeA $a) {
                $a->FUNC2(); // Метод успешно вызывется так как он public
                $a->func1();  // Метод теперь кидает исключение, использовать не получится
            })($a);
        }
    }
    
    $nodeA = new NodeA;
    $nodeA->func1Overrided(); // Работает вызов метода funс1 из родителя
    
    $nodeB = new NodeB;
    $nodeB->onInit($nodeA); // Выдаёт ошибку, нельзя использовать метод func1 из класса NodeB


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

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

    <?php
    // Делаем общий трейт для всех классов
    trait Func1 {
        private function func1() {
            print "FUNC1; ";
        }
    }
    
    class Node
    {
        // Включаем трейт
        use Func1;
    }
    
    class NodeA extends Node
    {
        // Включаем трейт
        use Func1;
    
        public function FUNC2() {
            print "FUNC 2 NODEA; ";
        }
    }
    
    class NodeB extends Node
    {
        // Включаем трейт
        use Func1;
    
        // Функция инициализации
        public function onInit(NodeA $a): void
        {
            // Добавить зависимость
            (function (?NodeA $a) {
                $a->FUNC2(); // Метод успешно вызывется так как он public
                $a->func1();  // Метод использовать не получится, т.к. он private
            })($a);
        }
    }
    
    $nodeA = new NodeA;
    
    $nodeB = new NodeB;
    $nodeB->onInit($nodeA); // Выдаёт ошибку, нельзя использовать метод func1 из класса NodeB
    Ответ написан
  • Можно ли уникализировать отправку форм с сайта без cms?

    Ответ выше про скрытое поле абсолютно верен.
    Если же вы по какой-то причине не хотите использовать скрытые поля, то можете просто назначить имя (или value) самой кнопке отправки формы.

    <input type="submit" value="save" name="loginForm">


    if (isset($_POST['loginForm'])){
        // Код
    }
    Ответ написан
    Комментировать
  • Как создавать, принимать и обрабатывать socket?

    1. Вебсокеты - это сложновато.
    2. Вебсокеты на PHP - вдвойне сложно. Проблема в том, что PHP задуман как скриптовый язык, т.е. скрипт выполняется заканчивает свою работу. А вебсокет - это постоянное соединение, т.е нам надо, чтобы программа постоянно крутилась в фоне. Вебсокеты можно реализовать на PHP, но, как персонально мне кажется, проще будет выучить Go )) , или же, как в ответе уважаемого Артём , сделать сервер на ноде.
    3. Если ваш чат не такой супер-функциональный, как чат в мессенджерах, то вместо вебсокетов можно обойтись SSE (Server Sent Events). SSE так же требует постоянного соединения, но всё работает через HTTP, и это ну прямо намного проще. Единственный недостаток - это то, что SSE работает только в одну сторону: от сервера в браузер. Т.е. запросы из браузера можно получать обычным POST запросом, а отдавать обратно информацию уже через SSE.

    С SSE есть два пути:
    1. Написать сервер самому, используя какую-то простую библиотеку вроде этой https://github.com/hhxsv5/php-sse
    2. Но я бы сделал ещё проще. Есть такой великолепный проект под названием Mercure https://mercure.rocks
    Это отдельный сервис на Go, задача которого как раз поддерживать SSE соединение и отправлять сообщения в браузеры. Сервис сидит в фоне, а браузеры подписываются на события через EventSource буквально в три строчки, как описано тут https://mercure.rocks/docs/getting-started
    Прелесть этого в том, что для того, чтобы отправить сообщение всем браузерам из кода на PHP, вам надо просто сделать обычный POST запрос на специальный адрес этого сервиса Mercure с телом самого сообщения и его id. Т.е. вам не надо делать никаких долгоживущих процессов на PHP, всё будет работать как раньше.

    Т.е. подытожим:
    - Браузеры пользователей подписываются на события в Mercure
    - Пользователь 1 отправляет текстовое сообщение обычным POST запросом на обычный PHP сайт.
    - PHP сайт получает этот POST запрос, определяет, что его надо отправить Пользователю 2, и отправляет соответствующее сообщение обычным POST запросом в сервис Mercure
    - Mercure отправляет сообщение Пользователю 2 через SSE, на которые он подписан.
    - Сообщение появляется у него на страничке
    Ответ написан
    5 комментариев
  • Как получить переменную из callback php?

    Можно использовать замыкание. Тут фишка в том, что надо использовать в замыкании не обычную строковую переменную, а объект, потому что строковая переменная будет передана в виде копии, и не получится её изменить.
    В коде я заменил класс Client на его мок.

    class Client {
        public function miniTicker(array $callbacks) {
            foreach ($callbacks as $key => $callback) {
                $conn = 'aaaaa';
                $msg = 'msg-'.$key;
                $callback($conn, $msg);
            }
        }
    }
    
    class Message {
        public array $messages = [];
    
        public function addMessage(string $msg) {
            $this->messages[] = $msg;
        }
    }
    
    $message = new Message();
    
    $callbacks = [
        'message' => function ($conn, $msg) use ($message) {
            $message->addMessage($msg);
            
        },
        'ping' => function ($conn, $msg) use ($message) {
            $message->addMessage($msg);
        }
    ];
    
    $client = new Client();
    $client->miniTicker($callbacks);
    var_dump($message->messages);


    В результате в конце у нас выводятся все сообщения
    https://onlinephp.io/?s=tVK7boQwEOyR-IctkDDSkR8gR4...
    Ответ написан
    5 комментариев