• Как реализовать простой календарь на php7 с использованием AJAX'a?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    В PHP из коробки есть мощнейший парсер дат:

    php.net/manual/ru/datetime.formats.php

    То есть вы можете писать такое:

    new \DateTime('first monday of this month');        // 2016-11-07
    new \DateTime('first sunday of November 2016'); // 2016-11-06


    так же с датами можно производить манипуляции, сравнения и т.д.

    И как можно реализовать подгружение месяцев при щелчке, например, на кнопку 'далее'?


    Будьте последовательны. Сначала выведите календарь на этот месяц. Затем сделайте так, что бы можно было смотреть календарь за любой месяц любого года. Затем погуглите как делать http запросы средствами javascript.

    p.s. такие вещи проще и удобнее делать целиком на клиенте. Не говоря о том что лучше взять существующий календарь.
    Ответ написан
    Комментировать
  • Рефакторнуть код в ООП?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Стоит задача превратить это всё в ООП


    давайте не так, не в ООП а просто в читабельный и поддерживаемый код.

    - избавьтесь от дублирования кода. Вынесите для начала все действия в отдельные функции. Например:

    $("#addComment").css("display", "block");

    и подобные можно заменить как

    // функции хэлперы для устранения дублирования
    function hide(selector) {
       return function () {
            $(selector).css("display", "none");
       };
    }
    function show(selector) {
       return function () {
            $(selector).css("display", "block");
       };
    }
    
    // специализированные хэлперы с говорящими названиями
    var showCommentsForm = show("#form");
    var hideCommentsForm = hide("#form");
    var showAddCommentButton = show("#addComent");
    var hideAddCommentButton = hide("addComment");


    идем дальше...

    var counter = parseInt($("#counter span").html())+1;
              $("#counter span").html(counter);


    Тут явно стоит использовать data-*. Или любой другой способ подсчета. Знать бы еще что считается, судя по всему вам надо посчитать количество сообщений. В этом случае вообще так себе идея так делать.

    $(document).on("click", "input[name='send']", function (){


    лучше случать сабмит формы. Обязательно устраните "глобальный поиск" по селекторам.

    Ну и это не говоря о том что инлайн стили, селекторы на айдишках, шаблоны с дублированием - это путь к боли.
    Ответ написан
    8 комментариев
  • Почему товары отсортированы некорректно (ASC)?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    это строки. сравнение происходит посимвольно. То есть символ "2" больше чем символ "1" а длина строки не влияет на порядок.
    Ответ написан
    Комментировать
  • Нормальный ли это код? и как его можно оптимизировать (Фильтр данных из базы)?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    У вас там баги и копипаста, как такой код может быть хорошим? Что вы будете делать если вам нужно будет в один прекрасный день выводить не 40 элементов а 50? find/replace? А если поменяется название поля? А если добавится еще одно поле? Добавлять степень двойки веток?

    if ($visa_type && $status & $company) {

    вот тут например я полагаю что мы имеем дело с опечаткой.

    Дополню Кандрашкин Алексей и избавлюсь еще от одного уровня вложенности.

    public static function filter($visa_type, $status, $company)
        {
            $query = self::query();
    
            if (!Auth::user()->hasRole('administrator|Manager')) {
                $query->where('user_id', Auth::user()->id);
            }
            if ($visa_type) {
                $query->where('visa_type', $visa_type);
            }
            if ($status) {
                $query->where('status', $visa_type);
            }
            if ($company) {
                $query->where('company', $company);
            }
    
            return $query
                ->orderBy('id', 'desc')
                ->paginate(40)
                ->toArray()['data'];
    Ответ написан
    Комментировать
  • Почему "прямой" цикл for быстрее обратного for или while?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    возможно в том, что там список а не массив?
    Ответ написан
    1 комментарий
  • Знания Junior php разработчика?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    что должен знать идеальный джуниор (мое личное мнение):

    - Сетевой стэк. Нужно иметь хотя бы базовое представление о том как с сервером общаются. Ну то есть не нужно лезть в дебри, но понимать что такое HTTP или чем TCP от UDP отличается - нужно. В целом это пара часов чтения википедии.
    - GIT или любая другая распределенная VCS. Базовые навыки, что бы хотя бы понимал что есть git revert или git rebase, что такое фичабрэнчи и примерное представление как это работает и зачем надо.
    - Базовые основы unix. Ну то есть что бы не пугаться таких вещей как ssh хотя бы.
    - PHP. Без этого никуда. Он должен понимать что такое слабая динамическая типизация (не заучивать табличку кастов типов, а понимать плюсы и минусы, такая же история с приоритетами операторов - не заучивать а знать как избегать проблем с чтением кода)
    - Понимать что код чаще читают чем пишут, а потому не экономить 5 минут на написании кода, а писать так, чтобы сэкономить 30 минут человеку, разбирающемуся в куске кода.
    - Знать базовые вещи в плане безопасности. XSS и как защищаться, SQL инъекции и как защищаться, CSRF, MITM. Понимать что такое NDA, что данные пользователей - секретная информация. Как хэшировать пароли (не md5 а password_hash) и почему это важно.
    - Знать SQL. Глубоких знаний не требуется, нужно лишь понимание того, что такое нормальная форма, желательно разобраться с вопросом денормализации данных. Идеально иметь хотя бы базовые представления о том как работать с NoSQL решениями.
    - Процедурное программирование: почему глобальные переменные порождают сложность, что такое состояние, как можно использовать классы для изоляции состояния и т.д. Инкапсуляция. Инварианты, пост/пред условия, сохранение целостности...
    - Разделение ответственности. Это один из важнейших принципов, и упрощать все это до "mvc фреймворк" слегка неправильно. Вы должны понимать что от чего отделяете и главное зачем.
    - Автоматические тесты. Джуниор должен знать что это такое и иметь хотя бы минимальный опыт их написания. Должен понимать разницу между юнит и интеграционными тестами. Быть знакомым с пирамидой тестирования.
    - Уметь решать стандартные задачи не задавая слишком много вопросов. Например регистрацию пользователя по email-у вы должны написать, или авторизацию через соц сети, или комментарии, или новостную ленту.
    - Уметь дебажить. xdebug, blackfire и тд.

    В целом где-то за годик весь этот список можно влегкую покрыть с нуля.

    p.s. Я в списке специально не указывал ООП, поскольку всеравно первые пару лет у разработчиков выходит процедурщина на классах. Это не плохо, но того что в моем списке более чем должно хватать для решения стандартных задач. Но термины вроде "инкапсуляция/полиморфизм/наследование" требуются в обязательном порядке подавляющем количеством интервьюверов, а стало быть знать это надо. Единственное что - рекомендую в свободное время глубже погрузиться в этот вопрос а не тупо заучивать формулировки.

    Так же вещи вроде docker джуниорам знать не обязательно просто потому, что их врядли допустят сходу к управлению инфраструктурой. А так пару неделек на изучение и вперед.
    Ответ написан
    12 комментариев
  • Как организовать управление демонами на PHP?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Также нужно, чтобы был один мастер процесс


    Очень крутая тема с этим в том, что вам не обязательно нужен мастер процесс написанный на php. Вы можете взять старый добрый pm2 для nodejs, или supervisord для unix. Я к примеру вообще тупо запускаю "демоны" в отдельных докер контейнерах, и у меня полный контроль за ситуацией (docker-demon в моем случае выступает в роли гипервизора).

    Есть идея собрать какой-то свой велосипед


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

    мне нужно, чтобы сервис был максимально неубиваемым.


    именно с такими требованиями справляется erlang. В целом же стоит знать контекст задачи. В общем изучайте supervisord, судя по всему он покрывает все ваши нужды.
    Ответ написан
    1 комментарий
  • Как использовать factory как хранилище данных между контролерами?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    1. "factory" это способ порождения сервиса. То есть хранить данные вы будете в сервисе. Ну и такой момент - вы там не храните данные а храните логику получения этих данных.
    2. почитайте про анонимные функции, не надо указывать имена для колбэков
    3. почитайте про промисы, это решит вашу проблему. Так же почитайте про event loop в javascript, про то как работать с асинхронными операциями и т.д.
    4. Очень удобно такие вещи выносить в резолверы, оставляя контроллеры максимально тупыми
    5. компоненты. Подход с регистрацией "независимых контроллеров" считается устаревшим.

    Последние два пункта обязательны к изучению но не прямо сейчас. Это если вы захотите научиться делать "удобно".
    Ответ написан
    1 комментарий
  • REST или Json-RPC для большого проекта?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    json rpc - это когда все запросы post.

    rest же, это стиль архитектуры. Он не про урлы и не про http. Просто на http он ложится очень неплохо.

    Ну то есть вы можете сделать все придерживаясь принципов REST. Главное не путать http и rest и не ограничивать себя мыслью что ресурсы это отображение табличек в базе.

    При этом нужно учитывать что методов или урлов будет несколько сотен.


    А какая разница? У вас так и так будет какой-то роутер.
    Ответ написан
    Комментировать
  • Чем отличается JDBC от ORM?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Для начала упростим JDBC до общего случая Data Access Object (DAO).

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

    Словом, основная задача DAO - предоставить механизм работы с базой данных скрывая детали внутри себя.

    ORM (Object-relational mapping) - это, если опять же упростить, общая идея конвертации "объектов" между системами с несовместимыми типами. Ну то есть как объекты из базы мэпятся на объекты.

    Если под ORM брать мощные реализации вроде Hibernate, то тут становятся очевиднее минусы конкретно этой реализации. А именно - работать это будет эффективно когда вам нужно построить объектную модель логики приложения, нежели модель данных. Такие подходы хорошо работают в приложениях с реально сложной логикой, где вам бы хотелось в коде передать суть того, как все работает в реальности. Например как именно происходит автоматизация бизнес процесса. С реальными объектами и т.д.

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

    Ну и в целом, ORM и DAO это весьма разные концепции, они о разных вещах. То есть у вас может быть использовано и ORM и DAO. Или ORM внутри использующее DAO... это не столь важно.
    Ответ написан
    9 комментариев
  • Как научиться создавать свои функции в PHP?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Реально ли вообще с нуля самому не смотря не документацию или чужой код создать Движок?


    Нет. Хватит лениться.
    Ответ написан
    Комментировать
  • Реализация snmp через php. Как и с чего начать?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Реализация snmp через php. Как и с чего начать?


    начните с этой ссылки: https://packagist.org/search/?q=snmp
    Ответ написан
    Комментировать
  • Правильно ли я понимаю паттерн прототип?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    А вы точно читали что это за паттерн и чем он от фабрики отличается?

    В целом ответить на вопрос можно если вы приведете пример использования данного паттерна. Ну и еще учитывайте такой момент - в вашем примере использование прототипа не рационально - клонирование таких объектов как request не сильно то и дорогое.

    p.s. метод `getClone` должен быть приватным. В остальном вроде бы все ок.
    Ответ написан
    2 комментария
  • Как лучше сделать автомодератора на комментарии?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    1. Кнопка пожаловаться, которая отправляет комментарий на модерацию. Сортировать список можно по количеству жалоб. Делается очень легко и быстро. Работает надежно.
    2. При наличии матных слов (тупая проверка по словарю) можно блочить отправку комментария. В этом случае стоит сделать словарь либеральнее оставляя только очевидные варианты. Далее будет работать кнопка "пожаловаться". Проверять на ссылки бесполезно - часто дают полезные.
    3. Greg Young - Stop over engineering - рекомендую к просмотру и осмыслению.
    4. Воспользоваться существующей системой комментариев.
    5. Можно защититься от тупых краулеров сделав отправку комментариев через JS и добавив опциональное скрытое поле. Тупые боты их заполнят. Такие запросы можно отбрасывать. Защищает от доброй половины спама.
    Ответ написан
    1 комментарий
  • Как перенять объектно-ориентированное мышление?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Т.е. сложно понимаю, что "засунуть" в один объект, что в другой, что должно быть статическим методом, что приватным и тд.


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

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

    Теперь задумаемся о декомпозиции всего этого хаоса. Мы находим какую-то задачу, которую выполняет наш код (например какую функцию вызвать для обработки каждого конкретного запроса) и выносим это в отдельный объект. Отправка email-ов - отдельный объект. Весь SQL зашиваем в отдельный объект. Соединение с базой - объект. Пользователи - объекты. Все - объекты.

    И главное, у каждого объекта есть своя область ответственности. UNIX way. Каждый объект делает что-то одно и делает это хорошо. Бывает так что ну... нужно сделать так что бы один объект делал две вещи. НЕ вопрос, мы можем его попросить сделать что-то сложное, а он будет как хороший менеджер тупо делегировать работу другим объектом. То есть он и сложную штуку сделает, и сам не будет знать как она делается.

    А все безхозные функции, которые не пренадлежат никаким объектам (например функции порождающие объекты) можно вынести в статические методы. Главное что бы статичесих переменных у нас небыло (ибо это те же глобальные переменные). И поменьше публичного ибо черт его знает что эти разработчики будут использовать. Причем "те разработчики" это вы завтра.

    Вообщем писав всё время на процедурке, сложно перейти на ооп.


    Просто не думайте что это что-то "принципиально другое". Это та же самая процедурка, просто благодаря классам и объектам, вы можете порезать систему на маленькие модули. Данные будут лежать рядом с процедурами и у вас будет больше контроля за происходящим.

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

    Подскажите, какой проект начать писать (гостевая, блог), или может начать изучать фреймворк.


    Фреймворки универсальны, а значит чистого ООП там быть не может. Во всяком случае нет ни одного фреймворка на котором стоит учиться ООП.

    Есть хорошие упражнения на развитие понимания объектно-ориентированного проектирования. Например вот: https://habrahabr.ru/post/206802/

    Сразу хочу отметить что это крайности. Упражнения же. Они должны ограничивать вас что бы заставлять думать и задавать правильные вопросы.

    Или может подскажите книгу/сайт где пошагово в ооп написан какой-то проект, чтобы быстрее пришло понимание.


    Так вы научитесь делать один конкретный проект а на втором вы уже проиграете. Так дела не делаются. Надо разобраться с причинами появления идеи ООП. Ну то есть что было до. Можно еще с функциональным программированием попробовать разобраться. В PHP оно слабо применимо, но основные идеи очень тесно переплетаются с ООП и познав немного функциональщины ваше ООП будет лучше. Да и если про ООП вы можете найти много булшита, про функциональщину врут мало.
    Ответ написан
    3 комментария
  • Как разобраться с инверсией зависимостей?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Что такое адаптер?


    Смотрите. Есть у вас например micro USB кабель. И есть дырка в новом макбуке - Usb type c. Друг в друга они, как вы понимаете, не втыкаются. И можно взять адаптер microUSB -> USB type-c.

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

    Таким образом если вдруг через месяц обнаружатся проблемы, вы сможете заменить "готовую штуку" на другую готовую, сделать другой адаптер, и все. Изменения с точки зрения кода, который использует нужный нам интерфейс, будут только в используемом адаптере.

    За счет этого достигается независимость.

    Что значит "принимает зависимость"?


    Предположим у нас есть метод для смены пароля юзера. Что бы это безопасно провернуть, нам надо пароль захэшировать и хранить в захэшированном виде. То есть нам нужна какая-то штука, которая будет эти пароли хэшировать. Мы о ней знать ничего не хотим, хотим что б нам ее давали:

    public function changePassword(string $password, PasswordEncoder $encoder)
    {
        $this->password = $encoder->encode($password);      
    }


    Это зависимость нашего метода. Он зависит от него. Диалог между объектами можно представить себе такой:

    - Слыш, поменяй пароль на этот
    - Оке, только хэшер паролей мне дай, мне очень надо
    - А какой тебе?
    - Да любой с этим типом
    - Ну ок. На вот пароль и хэшер. Делай дела.

    Что такое вообще эта зависимость?


    Зависимости - это все что мы используем чтобы сделать дела. Это не только библиотечки, но и просто классы, функци и т.д. Весь "сторонний" код с точки зрения нашего кода. И самое важное в том, что "нашим" кодом является тот, над которым мы работаем в данный момент времени, а не все что мы написали. Даже функции, которые есть в языке программирования из коробки являются зависимостями. Вот только от них вам не деться никуда особо, а потому с ними замарачиваться не стоит. Или если есть долговременная поддержка у библиотеки и она устаялась - тоже можно просто использовать. А вот если это поделка на гитхабе с 10-ю звездочками и там до сих пор нет ни одного релиза - но она вам вот очень нужна, возможные поломки в ней (а они рано или поздно будут) стоит "закрыть" адаптером что бы потом поменять на что-то получше или обновить без боли.
    Ответ написан
    Комментировать
  • В чем преимущество Dependency Injection перед использованием оператора new?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    но так и не понял, в чем его прелесть.


    Не делать все руками. Описать граф зависимостей а он уже как-то сам соберется. То есть собирать граф зависимостей руками оно может даже правильнее, но с точки зрения читабельности кода, поддерживаемости кода (особенно учитывая миллионы зависимостей во фреймворках), да и просто увеличения скорости разработки, лучше использовать какой-нибудь контейнер в main и там запросить вершину графа зависимостей. А он уж разберется.

    По сути главное что бы ваш код о контейнере ничего не знал. ЧТо бы вы в один долгий зимний вечер могли влегкую заменить все на "ручную" сборку и сам код трогать не пришлось... Ну аннотации/атрибуты это уже компромис для удобства.
    Ответ написан
    Комментировать
  • Какие вы создаете шаблоны php проектов?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Единственный способ учесть изменения - это дождаться изменений и посмотреть.

    Как пишутся шаблоны? Для начала берется какой-то готовый и на его основе начинаются делаться проекты. Именно проекты а не просто "подготовка к проектам". Это по сути является преждевременной оптимизации. Особенно если опыта у вас не так много.

    Далее уже с каждым проектом вы будете привносить что-то новое. Можно делать ретроспективы и делать улучшения для других проектов... как-то так. Все остальное - либо у вас уже есть опыт (или у членов команды), либо это будет пустой тратой времени. И это время лучше потратить на изучение вопросов "почему у других так".
    Ответ написан
  • Нужно ли учить ООП (PHP)?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    но статья меня пугает, так нужно ли учить ООП или функциональное программирование: Welcome?


    ООП учить не нужно. Большинство вроде как и учат но выходит плохо. ООП надо понимать. Причем это скорее именно проектирование нежели программирование.

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

    А так... скажем так, использовать классы вам придется. В PHP другого способа изолировать состояние нет. Просто не надо думать что ООП про наследование (о чем большая часть статьи), оно про изоляцию состояния, взаимодействие объектов/модулей посредствам "общения" (tell don't ask, закон деметры), про позднее связывание (возможность подменить реализацию)... А не как не про классы. Классы лишь способ. Инкапсуляция, полиморфизм, наследование - все это было до ооп. Разве что наследование в Simula67 сделали в более удобном виде. Но все же считать этот язык объектно ориентированным не стоит. На его основе потом Страуступ плюсы сделал, и так же не думал делать объектно-ориентированный язык. Он хотел структурировать процедурный Си, задать так сказать культуру разработки. Менять парадигму он не собирался.

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

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    1. opcache обязательно, он кеширует байткод PHP, глупо его выключать.
    2. fastcgi_cache - кеширует результат. Идеально для статики и если лень поднимать varnish какой-нибудь. Однако следует понимать что вам придется здорово помучаться с инвалидацией кэша. Популярные CMS имеют уже неплохие плагины (тот же wp total cache) которые все берут на себя. И в целом они способны даже дампить себя на файловую систему что бы nginx тупо отдавал статику и даже не трогал fastcgi. Потому следует еще раз подумать надо ли вам это. И если надо - искать готовые плагины которые захэндлят инвалидацию кэша нормально.
    Ответ написан
    Комментировать