• Как перенести проект с Codeigniter 2.2 на Laravel 5.2?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    как его относительно безболезненно перенести на Laravel/Symfony.


    1) подключаем отдельные симфони компоненты и планомерно переводим на них проект. Ну и не только симфони компоненты, в целом компоненты которые не привязаны к конкретному фреймворку.
    2) выносим логику из контроллеров в сервисы (если они у вас есть), подключаем какой контейнер зависимостей. Делаем контроллеры тонкими. Сервисы потом чистим от зависимостей от CI сначала постепенно вынося их все в какие-то маленькие сервисы и потом просто избавляясь от них.
    3) лепим сверзу HTTP kernel который будет прокидывать запросы на новые или на старые контроллеры.
    4) ???
    5) profit.

    https://www.symfony.fi/entry/rewrite-your-legacy-p... - рекомендую ознакомиться.
    Ответ написан
    Комментировать
  • Как правильно вывести дату php?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    А теперь прочитайте ваш код вслух. НУ вот серьезно, он же не читабелен вообще. К примеру вот:

    $from = new \DateTime('14:30');
    $to = new \DateTIme('17:00');
    
    $now = new \DateTime();
    if ($from < $now && $now < $to) {
      // ваш код
    }


    Тут просто и понятно что откуда и куда, не нужно много думать что бы это прочитать и понять что вы хотите сделать. А в вашем варианте.... словом код ревью не пройдет.
    Ответ написан
    1 комментарий
  • Как правильно составить условие?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    'total_cost' => $row['new_cost'] ?? $row['total_cost'];
    Ответ написан
  • Как отследить нужную комбинацию в массиве?

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

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    printf

    printf('<a href="blog/all/%s">%s</a>', $row['OriginalAlias'], $row['Title']);
    Ответ написан
    2 комментария
  • Как правильно реализовать паттерн MVC?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Ваша задача - не зацикливаться на аббривиатуре MVC и подумать над тем, как отделить HTTP от приложения. Для упрощения представьте что:

    - view - это HTTP запрос и ответ. Это представление данных которое требует от сервера клиент.
    - model - это ваше приложение которое ничего не знает о HTTP
    - controller - это не один класс, а возможно целая цепочка классов, чья задача - абстрагирование модели от HTTP. Можно воспринимать ее как цепочку адаптеров. Запрос приходит в один адаптер - там разруливаем маршрутизацию, нашли контроллер - передаем дальше. Со временем адаптеры могут добавляться, например для добавления CORS или аутентификации могут быть дополнительные "адаптеры" (гуглить про middelwares, PSR-7 и т.д.)

    Так же не забываем про принцип инверсии контроля (Inversion of control). Фреймворк должен вызывать ваш код а не ваш код дергать фреймворк. То есть именно контроллеры дергают модель а не наоборот. Модель ничего не должна знать ни о view ни о контроллерах.

    Удачи.

    p.s. я описал mediating controller MVC, оригинальный же паттерн MVC 79-ого года на бэкэнде не применим.

    p.p.s. Перед имплементацией MVC рекомендую познакомиться с такими инструментами как composer. И например роутер сходу не писать свой. И ради бога не используйте PHP как шаблонизатор (гуглить про то что такое XSS), возьмите twig.

    p.p.p.s https://github.com/pmjones/adr - рекомендую ознакомиться.
    Ответ написан
  • Как создать и выйти из бесконечного цикла в PHP?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    php.net/manual/ru/language.control-structures.php - читаем

    И вообще где используются бесконечные циклы?


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

    Другой пример - игры. Каждый кадр - это одна итерация бесконечного цикла. Цикл продолжается с момента запуска игры до того момента как мы выключили игру.
    Ответ написан
    Комментировать
  • Как сделать верный Docker и использовать его для NodeJS приложения?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Как это верно все сделать?


    нанять девопса с опытом работы с докером?

    И чтобы если нагрузка на один повысится не падали другие


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

    у вас будет:

    - 1 nginx контейнер
    - 2 node.js контейнера (по одному на каждое приложение)
    - 1 php контейнер (если есть cron и т.д. имеет смысл завести еще один контейнер для оного)
    - 1 контейнер для базы данных (или 3 если каждому нужно по базе)
    Ответ написан
    2 комментария
  • Как зная год месяц день недели, определить дату?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    echo (new DateTime($year . '-' . $month))
          ->modify('first ' . $day ' . of this month') // first monday of this month
          ->format(\DateTime::ATOM);
    Ответ написан
    Комментировать
  • Можно ли задать ожидание порядка выполнения методов мока в phpunit?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    и нужно ли это делать в юнит-тестах?


    не нужно, поскольку вы таким образом жестко привязываете себя к текущей реализации. Чем меньше ваши тесты знают о тестируемом коде - тем лучше. В целом примите за правило что мокать нужно либо интерфейсы (причем ваши желательно, инверсия зависимости и все такое), либо то что общается с внешним миром. Все остальное желательно не мокать что бы не завязывать тесты на имплементацию.
    Ответ написан
    1 комментарий
  • Как правильно создавать классы внутри объектов в javascript?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    реализовать подобие ООП в JavaScript


    Скажите где в аббривиатуре "ООП" вы видите слово "класс"?)

    Хочу например создать объект вот так:


    А зачем? "нэймспейсы"? Это не нужно если есть модули.

    Как мне создать конструктор внутри объекта Earth


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

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Комментировать
  • Как использовать контроллеры и модели в фреймворках?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    модель - это очень абстрактное слово. Заглянем в словарь:

    Модель - представление предмета, системы...


    Итого - "моделью" в контексте MV* является... модель вашего приложения, то есть что собственно приложение делает. Главное не заблуждаться что это "способ доступа к данным", там по сути все что относится к обработке данных. То есть контроллеры максимум могут просить модель что-то сделать или дать представление каких-то данных, что бы контроллер сформировал из этого view (HTTP ответ в контексте PHP фреймворка).

    Есть еще такая штука - Action-Domain-Responder называется, там чуть меньше "абстрактных слов" но суть примерно та же что и у MVC.

    Но вернемся к вопросу

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


    Это вам решать. Slim - это очень простой HTTP фреймворк. Его задача - дать вам контроллеры, а модель - ваша задача ее реализовать. Вы можете вооружиться контейнером зависимостей или сервис локатором даже, и дергать нужные сервисы, которые уже будут делать дела.

    Суть всего этого - абстрагировать "модель" то есть ваше приложения от HTTP. Что бы потом можно было реюзать код вашего приложения с другими интерфейсами (как правило консольными командами или очередями).

    Ссылку на "зачем нужна инъекция зависимостей" вам уже привели, я лишь добавлю более-менее полезное чтиво на тему разделения ответственноси и слоеных архитектур в slim: codereview.stackexchange.com/questions/93914/slim-...
    Ответ написан
    3 комментария
  • 10к websoket соединений,нужны ли кластеры?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    нагрузку в 10к соединений сервер?


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

    Горизонтальное масштабирование стоит закладывать (хотя бы минимально что бы можно было потом быстро подправить).
    Ответ написан
    Комментировать
  • Почему не так часто используют JS фреймворки?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    очему так мало сайтов в рунете используют данные фреймворки?


    потому что это сайты. Потому что поисковики должны индексировать контент. Потому что это рунет. Потому что 90% разработчиков не достаточно квалифицированы что бы эффективно делать Single page Application-ы. Потому что 80% рунета сделано на wordpress/joomla/dle/etc. Ну как-то так.

    По поводу поисковиков и конверсии отдельно скажу. Если ваш сайт загружается несколько секунд - вы будете терять конверсию. Так же поисковики банально не умеют (с оговорками) индексировать динамические сайты.

    Для всего этого есть решение - серверсайд пререндеринг. Делают его обычно либо при помощи сторонних решений в клауде (что обходится обычному блогеру/интернет магазинчику не дешево или тупо много рисков), которые так же не всегда безболезненно юзаются, так и на сервере средствами node.js. Причем популярность этот подход начал набирать в 2013-ом году с появлением react и концепцией виртуального дома (использовали и раньше, тот же твиттер). Причем в том же react это все еще не самая тривиальная задача сделать все так что бы небыло боли. Пока лидером в плане безболезненной реализации является Angular2, которому помогает dependency injection и километры абстракций. Но только он еще не вышел даже в релиз (хотя все уже фигачат на бете). Ну и опять же на "шаред хостинге" это не взлетит (с оговорками опять же, я встречал те где это можно провернуть без боли).

    С каждым же годом количество SPA увеличивается. Со временем большая часть людей перейдут на похожие подходы. Опять же есть еще здравый смысл. Например пилить лэндинг на всяких там реактах или ангулярах или vue - это оверхэд. Тут и ванильного джаваскрипта хватит.
    Ответ написан
    2 комментария
  • Как перебрать цифры с нулями впереди?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Number('000042'); // 42

    и еще метод sort принимает пользовательскую функцию в качестве аргумента.... ну или я не правильно понял вашу задачу.

    если на оборот надо из циферок строки - гуглить "javascript pad string leading zero"
    Ответ написан
  • Как не нарушать SOLID?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    вы путаете инверсию контроля и инверсию зависимости. Давайте по порядку кратенько.

    Зачем нам нужны контроллеры или различные представления данных

    Зачем нам в принципе контроллер? Что он делает? Для упрощения не будет воспринимать контроллер как "один объект" и вместо этого представим себе его как целый слой. Так же заменим слово "модель" словом "приложение".

    Задача контроллера - принять и обработать запрос и выдать ответ. По сути в контексте WEB наш HTTP запрос и ответ это представление, которое хочет получить клиент (браузер, мобильное приложение, SPA, что угодно). HTTP - это интерфейс пользователя (UI) для нашего web-приложения.

    Например что бы независеть от реализации клиента и что бы было удобно мы передаем даты в формате iso 8601 (пример: 2016-07-14T19:40:12Z). Это удобно что бы быть независимым от реализации клиента или сервера. Но это не удобно для нашего приложения. В приложении скорее всего нам удобнее всего работать с объектом типа DateTime. То есть приложение использует абсолютно другое представление.

    Мы могли бы прямо в приложении конвертить DateTime в iso 8601 но тогда мы делаем наше приложение привязанным к одному конкретному представлению, которое хочет получить клиент. К примеру по каким-нибудь причинам известным только темным богам, вам вдруг понадобится быстро прикрутить интеграцию с другим сервисом и те же данные гонять уже в RFC2822. И стало быть уже приложению нужно париться о еще одном представлении.

    Мы могли бы сделать какие-то адаптеры у приложения, и дергать их в зависимости от потребностей, но тогда опять же наше приложение все еще знает о представлении, которое ему собственно не нужно. То есть у нас есть зависимость приложения от его UI что... похоже на "не лучшую идею". И тут на помощь приходит Inversion of Control.

    Что такое Inversion of Control

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

    То есть если еще упростить - фреймворк должен дергать ваш код, а не код дергать код фреймворка. Тем самым мы снижаем связанность одного от другого.

    Роутер и контроллеры как реализация UI

    Что бы отвязать приложение от логики формирования представления, вынесем это все в отдельный "слой" и назовем этот слой - контроллеры. Точнее это будет как цепочка адаптеров. Один адаптер (фронт-контроллер по сути) получает Request и делает какие-нибудь вещи с ним. Например проверяет можем ли мы вообще делать подобный запрос. Другой адаптер вызывает роутер и выясняет какой дальше адаптер вызвать. Если следующий адаптер не вызван - надо вернуть 404-ую ошибку. Если же все пошло хорошо - мы вызываем еще один адаптер, который уже будет конвертировать HTTP запрос в какое-то действие приложения (вызов метода приложения по сути).

    Так а инверсия зависимости это что?

    Инверсия зависимости - очень похожа на инверсию контроля но действует чуть по другому. Проще всего будет вглянуть на картинку:

    Dependency_inversion.png

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

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

    Нужно ли соблюдать принцип инверсии зависимости в случае контроллеров?

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

    будет ли правильным передавать зависимости в роутинге

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

    С другой стороны у вас теперь роутинг совмещает обязанность маршрутизации и разруливания зависимостей. Сами понимаете что это как-то нарушает прицип единой ответственности. Этим может заниматься Controller Resolver какой-нибудь.
    Ответ написан
    2 комментария
  • Оффлайн справочник по php и mysql?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    php.net/download-docs.php

    p.s. даже 3g-ка нет?
    Ответ написан
    Комментировать
  • Как наследуются функций в PHP?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    функции не наследуются.

    > Возвращает baseClass, я голову сломал.

    константа эта (__CLASS__) возвращает имя класса в котором вызываемый код вы пишите. Если вам нужен тип инстанса - используйте get_class($this). Он будет возвращать именно тип инстанса с которым вы работаете.

    p.s. завязывать код на имена типов - плохая идея.
    Ответ написан