Профиль пользователя заблокирован сроком с 10 апреля 2022 г. и навсегда по причине: систематические нарушения правил сервиса
  • Как сделать универсальный шаблон навигации?

    ThunderCat
    @ThunderCat Куратор тега PHP
    {PHP, MySql, HTML, JS, CSS} developer
    Читаем про относительные и абсолютные пути, в частности по отношению к структуре домена.
    Хинт - /some/route - путь от корня сайта.
    Ответ написан
    3 комментария
  • Почему в Symfony зарплаты выше, чем в Laravel?

    ThunderCat
    @ThunderCat
    {PHP, MySql, HTML, JS, CSS} developer
    По личным ощущениям, лара как раз разрабатывалась для джун+ уровня. То есть она сложно организована внутри и просто пишется поверх уже готовых компонент, собственно все сводится к подбору компонент или небольшому допиливанию чего-то готового искаропки. Этакий вордпресс в мире движков.

    В то же время Симфони (и тут я больше высказываю свое предвзятое мнение, еще и не подкрепленное никаким реальным опытом, кроме как рассматриванием чужих проектов) достаточно просто устроен внутри, и сложность больше архитектурного толка, то есть попытка сделать так чтобы неправильно на нем было некомфортно писать. При этом больше упор на классический ооп, обязательно интерфейсы, абстракции и разделение на модель-репозиторий, никаких активрекорд, только репозитории/доктрина, только хардкор... По опыту зенда, где все примерно в том же духе, смысл в этом есть, особенно на крупных проектах, где легко могут быть задействованы несколько хранилищ или даже их цепочки, и логика хранения (как пример) на симфони выходит очень гибкая. Это больше частное вИдение и больше следствие из архитектуры в целом. Отсюда и требования к кандидатам и к разработчикам в целом выше, скорее всего после лары в симфони вам придется долго втыкать как вообще со всем этим работать...
    Ответ написан
    1 комментарий
  • В чем моя ошибка в запросе?

    rozhnev
    @rozhnev Куратор тега PHP
    Fullstack programmer, DBA, медленно, дорого
    Пожалуйста ознакомьтесь с документацией модуля mysqli Prepared statements
    $stmt = $mysqli->prepare('INSERT INTO viber_messages (`datetimemsg`, `id_viber`, `message`) VALUES (?, ?, ?);');
    $stmt->bind_param('sss', $datetimemsg, $sender_id, $message);
    
    $stmt->execute();


    Share PHP code
    Ответ написан
  • Как правильно определить потребляемую память?

    REZ1DENT3
    @REZ1DENT3
    web-developer
    Массивы хранятся в 2^x. Когда размер массива переваливает за выделенное количество памяти, то php автоматически выделяет под размер массива в 2 раза больше памяти. Что у вас и происходит.

    Если стоит задача поиграть с range, то лучше написать свой аналог на генераторах.
    function xrange(int $min, int $max): iterable {
        for ($i = $min; $i < $max; $i++) {
            yield $i;
        }
    }
    
    $startMemory = memory_get_usage();
    
    $array = xrange(1, 34000000);
    foreach ($array as $item) {}
    
    print_r($endMemory = memory_get_usage() - $startMemory); // 568
    print_r(round($endMemory / 1024 / 1024) . ' MB'); // 0 MB
    Ответ написан
    1 комментарий
  • Как правильно определить потребляемую память?

    Rsa97
    @Rsa97
    Для правильного вопроса надо знать половину ответа
    Давайте определим точную границу, где проходит увеличение объёма потребляемой памяти. Это 33554432 элементов.
    3355443210 = 200000016
    Поищем предыдущий скачок. Он происходит на 16777216 элементах.
    1677721610 = 100000016
    Проверим дальше. Получим следующие значения:
    838860810 = 80000016
    419430410 = 40000016
    209715210 = 20000016
    104857610 = 10000016
    ...
    810 = 816
    Вывод - PHP резервирует память округляя количество элементов вверх до ближайшей степени двойки.
    Ответ написан
    1 комментарий
  • Как удалить дубликаты из бд размером больше 200 млн записей?

    ThunderCat
    @ThunderCat Куратор тега MySQL
    {PHP, MySql, HTML, JS, CSS} developer
    Не проще отслеживать уникальность когда вставляете??? Либо по уник ключу и инсерт игноре, либо выборка + вставка по пустому результату.

    PS: parent | parent_id - чем отличается???
    Ответ написан
    2 комментария
  • Можно ли давать такое название класса?

    @sl0
    Кто ж запретит? Но лучше, конечно, чтобы по названию класса было понятно что он делает.
    Если он делает выгрузку в excel, то можно назвать его ExcelWriter или ExcelExporter.
    Так же можно изменить структуру папок и неймспейсы, чтобы было яснее. Например:
    services/Exporter/Excel, Cvs и т.д.
    Ответ написан
    1 комментарий
  • Как имитировать отправки форму через post php?

    customtema
    @customtema
    arint.ru
    Для начала - убрать из подписи слово "специалист" и декомпозировать вопрос. Ответ на поверхности: phpfaq.ru/newbie/na_tanke

    Если я вас все же совсем неправильно понял (что не отменяет предыдущих рекомендаций), тогда ответ - CURLом.
    Ответ написан
    Комментировать
  • Получение доступа к объекту вложенному в массив?

    E1ON
    @E1ON
    Programming, Gamedev, VR
    $result['ADD_3']->{'2'}
    Ответ написан
    Комментировать
  • Как раскодировать строку из hex? Кто сталкивался с таким?

    @galaxy
    Это не хеш, а обычный текст в UTF-8, закодированный в hex.

    print hex2bin("d091d183d0bad0bcd0b5d0bad0b5d180d181d0bad0b8d0b520d0bad0bed0bdd182d0bed180d18b20d0b820d181d182d0b0d0b2d0bad0b820d0bdd0b020d181d0bfd0bed180d182");
    
    # Букмекерские конторы и ставки на спорт
    Ответ написан
    3 комментария
  • Чем автоматизировать массовое подключение по ssh?

    nikonor
    @nikonor
    Программист go, perl
    а в чем проблема с ansible? Вроде же он ровно для этого и создан?
    Ответ написан
    2 комментария
  • Есть ли встроенные механизмы для развертывания массива?

    Fernus
    @Fernus
    Техник - Механик :)
    <?php
    
    $samples = [
        123,
        [1, 2, 3],
        321
    ];
    
    $samples_modified = [];
    array_walk_recursive($samples, function ($item, $key) use (&$samples_modified) {
        $samples_modified[] = $item;    
    });
    
    print_r($samples_modified);


    UPD:

    Вариант с foreach:
    <?php
    
    $samples = [
        123,
        [1, 2, 3],
        321
    ];
    
    $samples_modified = [];
    
    function recursive_func($array){
        
        global $samples_modified; 
        
        if(is_array($array)){
            foreach($array as $below){
                $res = recursive_func($below); 
    
            }
        }else{
            $samples_modified[] = $array; 
        }
        return $samples_modified; 
    }
    
    recursive_func($samples);
    
    print_r($samples_modified);


    P.S.: За global помидорами не кидайте...чисто для примера...
    Ответ написан
  • Как получить русские символы из запроса PDO?

    E1ON
    @E1ON
    Programming, Gamedev, VR
    Нужно установить кодировку
    new PDO('mysql:host=host;dbname=dbname;charset=utf8mb4', 'dbuser', 'password');
    Ответ написан
    3 комментария
  • Трюк с тернарным оператором PHP?

    @Flying
    В целом то, что вам нужно скорее ближе к новой функциональности в PHP 8: throw expression. В этом случае ваш код мог бы выглядеть, к примеру, вот так:
    Auth::check() ?? throw new AuthenticationRequiredException("Вам необходимо сначала авторизоваться");

    Однако, если вы реально хотите именно такой конструкции как ваша - то здесь, конечно, тоже есть варианты, ведь начиная с PHP 7 нам доступен uniform function call syntax и, следовательно, возможны конструкции вида:
    Auth::check() ?? (function(){echo "Вам необходимо сначала авторизоваться";})();

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

    Существенно лучшим вариантом в этом случае на самом деле будет просто создание отдельной функции, которая будет брать на себя реакцию на такие ситуации:
    function failure(string $error): void 
    {
      // Просто для того чтобы быть ближе к вашему примеру, 
      // в реальности здесь должна быть нормальная логика обработки, 
      // к примеру тот же throw new RuntimeExcepton($error);
      echo $error;  
    }

    в этом случае ваш пример сводится к:
    Auth::check() ?? failure("Вам необходимо сначала авторизоваться");

    Помимо этого обратите внимание на то, что использование null coalescing operator ?? подразумевает, что тип возвращаемого значения функции Auth::check() - это mixed|null что выглядит странно, поскольку от результата проверки ожидается тип boolean.

    В реальности здесь лучше подходит сокращённая версия тернарного оператора, т.н. elvis operator. В этом случае ваш код может выглядеть вот так:
    class Auth {
        public static function check(): bool 
        {
            return false;
        }
    }
    
    function failure(string $error): void 
    {
        // В реальности, как указано выше, лучше использовать 
        // throw new RuntimeException($error);   
        // echo используется для примера
        echo $error;
    }
    
    Auth::check() ?: failure('Вам необходимо сначала авторизоваться');

    Проверить можно здесь.
    Ответ написан
  • Что нужно добавить в SMTP, чтобы пройти антиспам?

    @galaxy
    Что за прикол писать smtp руками? PHPMailer или mail() на худой конец чем не угодил?
    Правильно сформировать письмо - нетривиальная задача, полно мелких нюансов.
    Вам же, впрочем, основные вещи перечислили:
    • нет Content-type и charset
    • заголовки не кодируются как положено
    • нет Mime-version

    Также не указан transfer-encoding.
    Нет DKIM (хотя это уже мелочь). Неизвестно, что с SPF у домена.
    Ответ написан
  • Может ли кто-то проревьюить ООП код на PHP (тестовая задача, Symfony)?

    glaphire
    @glaphire
    PHP developer
    Мне кажется что тестовое сделано хорошо, но есть вещи которые немного некомфортны для потенциального проверяющего:
    1) Хорошо бы было все команды по поднятию проекта завернуть в Makefile или bash сценарий
    2) EmployeeScheduleController Аннотация Route на уровне класса это похоже на оверхед здесь, потому что только два эндпоинта и пустой роут над getWorkSchedule сразу пугает)) И private методы лучше сместить все вниз или вынести в базовый контроллер.
    3) Employee создание класса Time тоже больше похоже на оверхед, с одной стороны хорошо, что все ограничения инкапсулированы в одном классе, с другой стороны операции с DateTime как-то более интуитивны.
    4) EmployeeRepository Метод loadEmployeesFromFile() это точно не зона ответственности доктриновского репозитория, это отдельный класс, обычно сервис. Репозиторий это слой чтения из хранилища, а тут процесс записи.
    5) DayFactory, TimeFactory, TimeRangeFactory и их интерфейсы кажутся очень большим оверхедом, потому что на небольшую логику созданы три класса и три интерфейса, про которые надо помнить и проверять их содержимое для поддержания общей линии приложения.
    6) Обычно в симфони стараются придерживаться прямолинейной структуры папок, внутри Service есть Builder, ExternalApi, Factory и Validation - это разные группы задач и точно не сервисы, стоило бы оставить их в неймспейсе App (папке src) или выделить папку Module/Scheduler и создавать эти папки там.
    7) Calendar - у этого класса зона ответственности это быть апи клиентом, можно его переименовать в CalendarApiClient, чтобы однозначно понимать что он дергает внешнее апи, а не просто сущность, как-то связанная с другим апи.
    8) Validation - это необязательно, но обычно стараются по-максимуму использовать компонент Validator и логику дополнительных проверок строить вокруг него
    9) ScheduleDirector может я раньше не встречалась с такой группой классов, но Director звучит контринтуитивно, Service или Manager немного привычнее и предсказуемее.
    Тут есть противоречние - свойство scheduleBuilder не сеттится сразу, хотя оно необходимо для фунционирования, при этом его надо сеттить обязательно через сторонний метод. В симфони можно сконфигурировать класс заранее в services.yaml, задать ему алиас и уже готовый инжектить в нужный класс. Немного странно видеть исключения BadRequestHttpException, NotFoundHttpException в классе, зоной ответственности которого не является работа с http напрямую)
    10) EmployeeNonWorkScheduleControllerTest - зачем использовать в качестве названий переменных подчеркивания? Может это ошибка? Просто выглядит очень странно)
    11) В комментариях упоминали добавить коллекцию постмана, это было бы желательно
    Ответ написан
    9 комментариев
  • Фильтрация данных?

    delphinpro
    @delphinpro Куратор тега PHP
    frontend developer
    пароль htmlspecialchars для перестраховки

    зачем?
    htmlspecialchars кодирует служебные символы html. Зачем ее применять для пароля?
    И вообще, пароль у вас никогда нигде не хранится в открытом виде, только его хеш и то внутри системы.

    минимальную фильтрацию где это необходимо

    верное направление мысли.

    Необходимо в двух местах:
    1. запись базу
    2. вывод на страницу

    Чтобы защититься от sql-injection при записи, используйте подготовленные запросы.
    Чтобы не сломать верстку при выводе данных — используйте htmlspecialchars при рендере страницы. А лучше возьмите шаблонизатор. Они все по умолчанию эскейпят вывод.

    разрешить в логин и имя только a-zа-яё0-9


    Это уже не фильтрация, а валидация данных, к безопасности особого отношения не имеет и выполняется в других местах приложения.
    Простой пример. Пользователь отправил форму.
    Вы первым делом сделаете проверку всех полей на допустимые значения, на заполненность и т.д., и если что вернете посетителя обратно на форму с указанием ошибки. Данные здесь не изменяются.
    Если все в порядке, вы будете писать эти данные в базу. Как я уже написал, используя подготовленный запрос. Опять же, ничего менять в них не требуется.
    Потом, вы будете эту информацию где-то выводить на странице. Вот здесь уже, перед выводом, вы прогоните все через htmlspecialchars, возможно какие-то еще корректировки сделаете.

    Но, опять же вы пишете про универсальную фильтрацию на все случаи. Так не бывает.
    Если вы ожидаете во входных данных исключительно текст, то можно, например, смело резать все теги перед записью в базу. А если вы получаете их из визуального редактора, с разметкой, то резать теги уже не нужно.
    Ответ написан
    2 комментария
  • Как хранить подключение к БД для удобного обращения из других классов без глобальной переменной?

    @0x131315
    Пора освоить внедрение зависимостей.
    https://m.habr.com/ru/post/350708/comments/#commen...
    Это такие штуки, которые сами подставляют в конструктор класса требуемые ему зависимости.
    Например можно взять php-di пакет в composer.
    Ответ написан
    7 комментариев
  • Как продублировать содержимое строки?

    dyuriev
    @dyuriev
    A posteriori
    в попу циклы, echo и cat.
    одной командой sed -r 's/(.*)/\1\1/' < ./file1.txt > ./output.txt все заменить можно

    $ cat file1.txt
    1
    2
    3
    4
    5
    $ sed -r 's/(.*)/\1\1/' < ./file1.txt 
    11
    22
    33
    44
    55
    Ответ написан
    Комментировать