Задать вопрос
Ответы пользователя по тегу PHP
  • Класс управления зависимостями, как вам реализация?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    // Должен быть приватным
    DependencyManager::$dependencies;
    
    // Что это за хардкод?))
    DependencyManager::__construct
    
    // 1. Вы не проверяете аргументы, что будет, если я передам в $class
    // например new \Exception()? А еще лучше строку "trololo"?
    // 2. Нейминг - гуано, вы не проверяете зависимость, а возвращаете.
    // 3. Если зависимость не найдена - будьте добры исключение.
    DependencyManager::checkDependencies($class)
    
    // Эта переменная не нужна, передавайте ее в метод
    Loader::$className
    
    // Эта переменная должна быть приватная, что будет, если туда вставить
    // например строку и попытаться обработать?
    Loader::$dependencyManager;
    
    // Херня. У вас метод делает какую-то магию.
    Loader::loadClass


    Из SOLID вы нарушили:
    * SRP - Loader выполняет И управление зависимостями и подгрузку. То что вы называете DependencyManager - это конфигурация, но ни как не менеджер зависимостей
    * OCP - у вас явно открыты свойства, которые отвечают за внутреннюю логику выполнения. А то вот конфиги из вашей конфигурации зависимостей стоит возвращать через геттер
    * ISP - вы в принципе не заморачиваетесь с интерфейсами, а полностью зависите от реализации.

    Странно то, что загрузку не делаете рекурсивной, что если у вас у зависимого класса тоже есть зависимость?
    Плохо то, что инициализируете сразу все классы, что если их будет много?

    Еще пришла идея в классы с зависимостями передавать в аргументах интерфейсы, а не объекты.

    Отличная идея)) как только в PHP появится инициализация интерфейсов - вернетесь к ней, а пока что забудьте.

    Когда наиграетесь - выбрасывайте и переходите на качественные решения, по совету shaqster
    Ответ написан
    Комментировать
  • Считается ли плохим тоном, наследование PDO в класс вспомогательной обертки?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Вообще говоря \PDO - это чужой вендроский код, вам на прямую неподвластный (разве что сырцы пыхи пилить будете), так что лучше все таки обертку, так как она будет гарантировать вам постоянство интерфейса работы с БД.
    С другой стороны, если выделаете что-то не большое - выбирайте по удобству, если удобнее и быстрее наследование - пусть будет так, если обертка - тогда обертка. Руководствуйтесь здравым смыслом.
    Посмотрите Doctrine на досуге
    Ответ написан
    Комментировать
  • Можно ли сохранять в git папку vendor после composer update?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Если одни разработчик обновил библиотеки, другие должны как то об этом узнать, чтобы обновится у себя

    Если другие разработчики делают git pull и не обращают внимания на изменения - это их проблемы. Хорошим тоном является уведомление от автора правок в composer.json, что остальным стоит его обновить.

    Список библиотек и версии обновляются не очень часто, а при каждом релизе, приходится выкачивать одни и те же либы

    Вообще говоря композер умеет в кэш и одни и те же версии либ тянутся с кэша.

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

    Если нужно именно поднять окружение с проектом - настройте vagrant и пропишите в README как им пользоваться конкретно для вашего проекта.
    Что касается людей:
    * верстальщики - vagrant
    * технические писатели - я конечно не в курсе вашего проекта, но я бы доступ даже к репозиторию не дал, максимум - завел отдельный репозиторий для них.
    * ревьюер кода (безопасности) - ревьюер, который не может в composer / консоль?? Шутка не удачная.
    * сюда же и вопрос оплаты специалиста - лолшто? Это вообще не связано с окружением вашего проекта, ну вот ни капли.

    Нет возможности просто и быстро передать кому-то код, просто расшарив ссылку на гит

    Если у вас проект НЕ opensource - то такого делать в принципе нельзя. Доступ к репозиторию должны иметь специалисты, которые работают с кодом этого проекта и ни кто другой, а composer тут вот ни капли ни при чем!

    Вопрос в том, можно ли сохранять папку vendor в git

    НЕТ! Вы придумали НЕ существующую проблему и пытаетесь героически ее решить, только от этого решения будет еще хуже.

    насколько это противоречит принятому стилю

    на полностью

    какие могут быть проблемы с этим (сейчас самый жирный минус от такого подхода вижу в распухании репозитория) ?

    1. Вы становитесь вендором кода, который взяли где-то, как следствие вы следите за его обновлением, у изначального вендора и вы проводите аналогичные правки в своем проекте. Если так не делать - баги, найденные в этой зависимости сами себя не пофиксят и этот код будет быстро устаревать.
    2. В код зависимости появляется соблаз провести собственные наработки - это то, что делать нельзя, иначе процесс обновления будет сложнее на порядки.
    3. Ваш репозиторий разбухнет.
    4. Композер вашу зависимость придется явно прописать иначе автолоад может ее не подтянуть.

    Использует ли кто-нибудь такую практику в своих проектах ?

    Пару лет назад работал на крупном проекте, который начинался до появления композера. Когда зависимостей тьма и ты не знаешь, какие из них содержат артефакты собственных наработок, какие обновляются синхронно с официальными вендорами, а какие тянутся из вне приходится тратить кучу времени на выяснение. Это просранное время.
    Ответ написан
    1 комментарий
  • Как безопаснее PDO?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Ни первое, ни второе.

    0. SQL запросу ну вот ни как не место в аргументах, это то, что должен делать ваш insert метод. Все что он должен получать - это аргументы которые будут вставляться в ваш запрос!
    1. Вы не проверяете аргументы. Что произойдет, если я вызову insert:
    $db->insert(new \Exception(), []);
    Или так
    $db->insert("DELETE FROM user", []);
    Или так (тут lastInsertId вернет не id вставки)
    $db->insert("SELECT CURRENT_TIMESTAMP", []);
    2. Никогда, слышите? НИКОГДА! Не используйте при работе с БД суперглобальные переменные. Их удел - в самом начале index.php собрать объект Request, далее про их существование можно забыть.
    3. datab обычно называются connection, либо по типу класса
    4. В следующем коде нет смысла, от слова "совсем"
    }catch(PDOException $e){
                    throw new Exception($e->getMessage());

    Вы просто обрубаете стектрейс, который далее стоит использовать для поиска ошибок.
    5. У вас ключи строковые, зачем вот это?
    unset($arr[$key + 1]);
    6. Если в params передать [[]], как себя поведет ":$key"?
    7. lastInsertId возвращает строку, кастовать в ваш тип не помешает.
    8. Ради всего святого: прочитайте и следуйте PSR

    Вот вам пример безопасного кода. Проверок в реальном коде должно быть на много больше:
    * логин стоит прогнать по регулярке на допустимые символы
    * почту стоит прогнать по регулярке, или через filter_var
    * что пароль таки хэш (смотря какой алгоритм используете)
    * если будут еще поля не строковых типов - их подключаем через bindValue с указанием типа
    Тут сделано допущение, что подключение PDO уже настроен на бросание ошибок. В задачи репозитория не входит конфигурирование коннекшна.
    По хорошему это дело еще и в транзакцию обернуть.
    <?php
    declare(strict_types = 1);
    
    class UserRepository
    {
        /** @var \PDO */
        private $pdo;
    
        /**
         * @param PDO $pdo
         */
        public function __construct(\PDO $pdo)
        {
            $this->pdo = $pdo;
        }
    
        /**
         * @param string $login
         * @param string $email
         * @param string $password
         * @return int
         * @throws \InvalidArgumentException
         * @throws \PDOException
         */
        public function insert(string $login, string $email, string $password): int
        {
            if (empty($login)) {
                throw new \InvalidArgumentException('Argument "$login" must be not empty');
            } elseif (empty($email)) {
                throw new \InvalidArgumentException('Argument "$email" must be not empty');
            } elseif (empty($password)) {
                throw new \InvalidArgumentException('Argument "$password" must be not empty');
            }
    
            $sql = '
            INSERT INTO `user`(
                `login`,
                `email`,
                `password`
            ) VALUES (
                :login,
                :email,
                :password
            )';
    
            $this->pdo->prepare($sql)->execute(
                [
                    ':login' => $login,
                    ':email' => $email,
                    ':password' => $password
                ]
            );
            
            return (int) $this->pdo->lastInsertId();
        }
    }
    Ответ написан
    Комментировать
  • Как добавлять комментарии в Instagram без api?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    phantomJS
    Ответ написан
    Комментировать
  • Как начать осмысленную разработку веб приложений на php?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Вот список штук которые делать не стоит. Если что не понятно, почему нельзя - спрашивай.

    PSR - СВЯТОЕ, ОБЯЗАТЕЛЬНО ЗНАТЬ

    Прошу подсказать, куда искать, что почитать, что бы в голове прояснилось как грамотно проектировать подобные проекты. Хотя бы какие ключевые слова присутствуют в описании данных процедур.

    Если нужно понимение, что и зачем - Symfony ну и разве что Zend.
    Никакие Laravel, Yll тебя хорошим практикам не научат, увы. Это я как в прошлом фан yii говорю.
    Что так? Погугли на тему: "Singleton antipattern", "ActiveRecord antipattern"
    Ответ написан
    Комментировать
  • Continuous delivery, Continuous integration, Docker при "многоверсионном" приложении. Как организовать?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Не нравится, что в итоге заводится куча тегов, веток, может есть альтернативное решение для такой задачи?

    На самом деле это оптимальное решение. У вас создается релизная ветка в которую в случае проблем именно на этой платформе будут вливаться фиксы, не мешающие другим. Далее когда релизный образ оттестирован и дан зеленый свет - они размазывается по проду. То что тегов много - да какая разница?)) У вас есть возможность получить состояние любой сборки.

    Схема кажется немного избыточна nginx->nginx->php, в итоге на сервере дофигища разных процессов, особенно nginx.

    Тут все зависит от того, можно ли отдавать клиенту доступ на прямую к nginx2. Если нельзя - ваша схема вполне норм. Если же можно - тогда стоит это делать, смотрите в сторону своего балансировщика, который будет отдавать клиенту сервер, который А - жив, Б - минимально нагружен и штук типа consul.

    ansible забирает из гита исходный код, грузит на сервер, в контейнеры исходники пробрасываются через volume.

    Зачем? Контейнер как бы иммутабельный и все такое. Если у вас там кучка статики подсасывается не под git - смотрите в сторону mogilefs и т.д. Безусловно, для разработки volume - самое оно, но для прода - ну такое..., должна быть веская причина.
    Ответ написан
    1 комментарий
  • Обычные константы, или константы в классе?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    В константе без класса - не стоит, view тут в принципе ни при чем. Как правило домен - это данные конфигурации вашего окружения/приложения. Можете сделать конфиг-класс с константой своего домена.

    По хорошему в генерацию ссылок по роутам должен уметь сервис (либо в составе роутера, либо отдельный) который уже знает про ваш домен. А дописывать его руками - это не то, что бы плохая практика, скорее странно.
    Ответ написан
    Комментировать
  • Нормальный ли принцип CMS я сформулировал?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Нормальный ли принцип CMS я сформулировал?

    Вы сформулировали вовсе не принцип CMS)).
    - Что произойдет при запросе HEAD/OPTIONS/PUT/DELETE?
    - Что произойдет, если отправить вам такое: ?act[]=logout?

    На счет реализации роутера - посмотрите Silex.

    Почитайте на досуге: Попросили проверить код, на что смотреть нужно?
    Обратите внимание на пункты, связанные со статикой.
    Ответ написан
  • Какие существуют способы защиты кода от копипаста?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    От кого вы пытаетесь защититься?))
    - от рядового пользователя. Он даже не подозревает о существовании php
    - от прогера, которому оно не особо надо. Он по тыкает палочкой 15мин и забъет.
    - от прогера, которому капец как надо. Он ваш код взломает.

    Защиту можно обеспечить как saas, но все зависит от того, что именно вы пытаетесь предоставить как сервис.

    некоторые cms без лицензии могут работать только на денвере но не на живом хостинге.

    хрень какая-то)) т.е. под линухой такую cms запустить нельзя что-ли?))
    Ответ написан
    2 комментария
  • Как оценить стоимость проверки кода сайта?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Элементарно, посмотрите вакансии на должность Team Lead у конкурентов. Чаще всего в задачи TL входит code review. Однако,
    то ли делает что нужно, правильно ли он это делает

    Вот это уже ближе к QA.
    Ответ написан
    Комментировать
  • Как не "изобретать велосипед", а использовать готовые решения?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    У js есть jquery, а у php что?

    HttpFoundation - это можно сказать стандарт для обработки запросов. Используется в Symfony, Laravel, Silex и еще куча где.
    Doctrine - по моему опыту это лучшая система для работы с БД. Если еще не смотрели - настоятельно рекомендую. А системы реализующие ActiveRecord (если у вас проект не на пару дней) - лучше не используйте, почему - см. тут.
    Monolog - это библиотека логгирования, практически не имеет аналогов по функциональности.
    Symfony Console Component - очень гибкий компонент для реализации консольных приложений.

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

    Разные кейсы предполагают разные решения. В случае высоких требований к производительности, тестируемости и защищенности часто оптимален вариант типа этого:

    /**
     * @Route("/profile/{id}", name="getProfile")
     * @Method({"GET"})
     * @param Request $request
     * @return JsonResponse
     */
    public function getProfileAction(Request $request): JsonResponse
    {
        try {
            $id = $request->attributes->get('id');
            
            if (is_null($id)) {
                return new JsonResponse("Param 'id' is required", JsonResponse::HTTP_BAD_REQUEST);
            } elseif (!is_string($id)) {
                return new JsonResponse("Param 'id' must be string", JsonResponse::HTTP_BAD_REQUEST);
            } elseif (!ctype_digit($id)) {
                return new JsonResponse("Param 'id' must be digit", JsonResponse::HTTP_BAD_REQUEST);
            }
            
            // Business logic here
            return new JsonResponse();
        } catch (\Throwable $exception) {
            return new JsonResponse($exception->getMessage(), JsonResponse::HTTP_BAD_REQUEST);
        }
    }


    Да, кода получается МНОГО, но такой подход очень гибок и производителен. Есть альтернативный вариант с использованием библиотеки ko-ko-ko/php-assert

    try {
        $id = $request->attributes->get('id');
        Assert::assert($id, 'id')->notNull()->string()->digit();
    } catch (\Throwable $exception) {
        return new JsonResponse($exception->getMessage(), JsonResponse::HTTP_BAD_REQUEST);
    }
    try {
        // Business logic here
        return new JsonResponse();
    } catch (\Throwable $exception) {
        return new JsonResponse($exception->getMessage(), JsonResponse::HTTP_BAD_REQUEST);
    }


    Есть ли подобные отработанные решения в фреймворках, они дают что-то кроме "каркаса"?

    Есть, практически у каждого фреймворка свои решения со своими плюсами и минусами.

    И почему нет библиотек популярных для php?

    см. Самое началом моего ответа, там список популярных библиотек.
    Ответ написан
    1 комментарий
  • Как использовать Websocket на сайте?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Ответ написан
    Комментировать
  • Есть ли бесплатные решения как Roistat, Перезвоним, Позвоним?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    piwik вероятно
    Ответ написан
    Комментировать
  • Как подсчитать кол-во одинаковых цифр и суммировать их?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    1. Не обманывайте людей)) 7774455566 у вас это совсем не строка)
    2. Вам тут json ну вот вообще нафиг не нужен.
    3. Создаете ассоциативный массив где ключами выступают цифры, а значениями - их количество. Дальше суммируете в другом цикле те значения, что больше 1.
    4. Если в строке могут быть посторонние символы - удалите их регуляркой
    preg_replace('/[^\d]/', '', $inputString);
    Ответ написан
  • Что должен сделать (integer) в данном примере?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Вы путаете приведение типов и округление. Округление типа round, ceil или floor приводят float к ближайшему целому, большему целому и меньшему целому соответственно. Приведение типов же - оставляет только ту часть данных, что подходит для результирующего типа.
    Ответ написан
    2 комментария
  • Как посчитать массив?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Конкретно в вашем случае можно и через eval
    Но это очень опасная конструкция и лучше про ее существование забыть
    Ответ написан
  • Высоконагруженный. Отправка 100 миллионов сообщений каждую секунд?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Как быстро все умрет?

    Закончатся открытые порты (65536) и все.

    Хостинг не поможет?

    Выдержит распределенная сеть серверов. Хостинг, или собственные сервера - не важно. Хотя скорее всего вас забанят по ip. Что кстати будет правильно. DDOS - это плохо.

    Как сделать чтобы не украли скрипт?

    За счет своих серверов. На месте хостинг провайдера я бы тоже вас забанил за такое))
    Ответ написан
    9 комментариев
  • Как динамически поменяеть имя класса?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Если существует ли возможность динамической смены имени класса?

    Нет, даже через runkit.

    Это решение для очень кривой архитектуры

    Это не решение, а усугубление проблемы.

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

    Если проект не особо развивается, а команда состоит из 1 разработчика - то смысла в переносе на неймспейсы может и нет.

    В остальном же - ничто не мешает начать перепил на найспейсы и человеческий автолоадинг помодульно. + Нормальные IDE типа PhpStorm с этим довольно быстро справляются.
    Ответ написан
    Комментировать