• Как прописать ответственность ИТ-исполнителя за ошибки?

    DMGarikk
    @DMGarikk
    Lead Software Developer
    Для начала надо понять что вешая на исполнителя денежную ответственность за потерю прибыли по вине косяков внедрения - это путь в тупик, вы распугаете всех подрядчиков и с вами никто не будет работать

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

    Это ВЫ не проверили работоспособность системы, а не подрядчик накосячил, поймите что ЭТО главное
    Ответ написан
    5 комментариев
  • Какие есть сервисы или CMS для создания документации по API?

    DevMan
    @DevMan
    swagger - один из самых популярных.
    а вообще, особого рояля нет. особенно, если все писать ручками.
    Ответ написан
    Комментировать
  • Как правильно работать с исключениями?

    Stalker_RED
    @Stalker_RED
    На самом верхнем уровне вашего приложения должен быть какой-то Глобальный И Великий Обработчик Исключений Общего Назначения. Задачи у него очень простые - записать в лог что и где сломалось, показать пользователю табличку "ой, все пропало", и опционально пнуть мониторинг, отправить смс админу или письмо деду морозу.

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

    Рассмотрим пару примеров:
    1. Представим, что модуль "генератор превьюшек для фоточек", который верой и правдой трудился многие месяцы, однажды наталкивается на непреодолимую для него преграду и бросает исключение - "капец, место на диске кончилось, я так больше не работаю!"

    Если ваш код не может ничего с этим поделать - вы пропускаете это исключение выше, пускай Глобальный И Великий Обработчик показывает юзеру красивую табличку "извините, у нас перерыв обед", и шлет письма админу в три часа ночи. А если у вас облачный хостинг, например, и вы можете на лету подключить больше дискового пространства, или может снести какой-то ненужный кэш освободив место, то можно перехватить это исключение, показать юзеру "извините, за задержку, ваши фоточки будут обработаны через пару минут", а админу прислать не красный алерт, а желтый.

    2. Виджет, который показывает самых рейтинговых котиков с ютуба не смог подгрузить очередную порцию котиков, т.к. ютуб забанен роскомнадзором. Если ваш код ничего не может с этим поделать - Глобальный И Великий Обработчик Исключений покажет пользователю "ой все". Или вы перехватите это событие на более низком уровне и покажете табличку "свежих котиков нет, но вот есть рейтинг за прошлую пятницу". Или, если котики должны быть обязательно свежие, то можете предусмотреть экстренное подключение через vpn или tor, или может возьмете котиков с vimeo вместо ютуба, например.

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

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

    try...catch не нужно использовать как управляющую конструкцию или для проверки состояния вместо if...else. Она для обработки транзакций. Если потенциально транзакция может не завершится, бросается эксепшн. Например запись в базу.
    try {  
      пишем в базу 100 записей
    } catch (Exception $e) {
      если на 99й записи сбой — откат
      echo $e->getMessage();
    }
    Ответ написан
    Комментировать
  • Как реализовать программу?

    Therapyx
    @Therapyx
    Data Science
    Ключевые слова:
    - Обьектно-ориентированный анализ и дизайн
    - UML
    - Use case's
    - Class Diagramm
    Гайд на скорую руку тык

    На эту тему есть конечно же много книг. В зависимости от состояния проета используются разные методы. Иначе же на этот вопрос нельзя конкретно ответить.
    Ответ написан
    Комментировать
  • Как прекратить создавать объекты классов?

    qonand
    @qonand
    Software Engineer
    Проблема Вашего кода это сильная связанность со всеми вытекающими. В такой ситуации как минимум стоит применить SOLID-принципы, как максимум - переработать архитектуру приложения (но тут конечно все зависит от масштаба проекта).

    Рекомендую почитать:
    Robert Martin - Agile Software Development, Principles, Patterns and Practices
    Martin Fowler - Patterns of Enterprise Application Architecture
    Ответ написан
  • Брать коробочный продукт и допиливать или делать с нуля?

    begemot_sun
    @begemot_sun
    Программист в душе.
    Я бы на старте взял готовое решение с минимальными допилами в виде костылей.
    Далее если бы взлетело --- пилил бы своё.
    Если вы уверены что взлетит, пилите сразу.
    Экспертизу делайте сторонним разработчиком, кому доверяете.
    Ответ написан
    1 комментарий
  • Куда писать sql запросы при реализации репозиториев (DDD)?

    Использование репозиториев является альтернативой ORM, то есть в этом случае модель Category не должна иметь методов получения или сохранения себя в БД.
    Ваш пример будет выглядеть следующим образом:
    class CategoryRepository
    {
        /*
         * @return Category[]
        */
        public function getAllCategories()
        {
            // Извлекаем категории из БД и создаем массив моделей Category
            return $categories;
        }
    }

    Соответственно для сохранения категории ваш сервис должен иметь метод CategoryService::save(), в котором будут выполняться необходимые проверки и подготовка данных, а затем вызываться метод репозитория CategoryRepository::save(Category $category).
    Ответ написан
    Комментировать
  • Какой php фреймворк учить?

    @Vasiliy_M
    1) В чем смысл фрейморков?
    За тебя уже все написано. Каркас, CRUD/ORM и масса плюшек.

    2) Какой учить первый?
    никто не даст ответа. Индустрия сходит с ума, территория PHP проклята - одному работодателю нужен один фреймворк, другому - другой. Угнаться за всем этим - нереально. В идеале - искать работодателей, готовых вас "вырастить", т.е. взять лишь с минимальным набором знаний, например, теоретических. Все фреймворки знать невозможно. А если и возможно, то это лишь временно - нереально всю жизнь знать все возможности десятка пхпшных фреймворков.

    3) Почему способ с самописным роутером, плохой?
    Фреймворк - это не только роутер. Можно перефразировать вопрос и спросить:
    Почему способ с самописным фреймворком плохой?
    Самописный фреймворк - это не плохо. Как получение опыта - очень даже хорошо. Для себя можешь писать. Но что бы в команду устроиться работать, тебе твой фрейм самописный не поможет. Команде нужна унификация, для этого и существуют фреймворки.

    Думаю если немного его усложнить, то и с более сложными проектами справится.
    бесспорно. реально справится. только он будет заточен только под тебя. и будет ограничен функционал - тебе не хватит жизни, что бы написать то, что делают команды фанатиков.
    Ответ написан
    Комментировать
  • "Global" или "&"?

    PretorDH
    @PretorDH
    HTML5, CSS3, PHP, JS - люблю в чистом виде.
    Объявляя глобальную переменную в области видимости функции - вы прописываете даете доступ к ней из функции и для переменной доступ к функции (именно так в двух направлениях). При этом локальная изменения переменной влияет на значение глобальной, но и изменения глобально тоже влияют на значение переменной внутри функции.

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

    Последствия применения глобальных переменных самые плачевные:
    • сложно обнаруживаемые ошибки;
    • безопасность - "хромая на две ноги";
    • сложности в рефакторинге и понимании кода;
    • сложность в масштабировании стремящаяся к инифинимуму;
    • не прогнозируемое значение переменной;
    • возможная инициализация/реинициализация переменной в разных местах кода.

    Что относится к косвенному вызову/привязке переменной или как это ещё называют "внедрение зависимостей" (Dependency injections) - значоком "&"...
    Такая переменная может хранится в любой области видимости, а не только в глобальной. Но проблемы - те же, что и при использовании глобальной переменной, может даже и более усугубленные. Так как ещё более сложно выявление ошибок и возможна перелинковка таких параметров между разными функциями использующими друг-друга!

    Принципы такие:
    • Если вы используете глобальные переменные, то масштабируемость и отказоустойчивость кода будет скорее всего никакая. Код сразу в топку;
    • Если косвенная привязка появляется в параметрах функции - это явный показатель того, что функция слишком сложна и скорее всего нужно разделить функцию на меньшие, или создать класс на основе этой функции, или разделить класс на составные.
    Ответ написан
    Комментировать
  • Расположение кода при работе с Doctrine?

    Обычно, бизенс-логику выносят в отдельный слой. Напишите классы-сервисы, куда и поместите свою бизнес-логику. Где они будут лежать и как называться - это, по сути, ваше дело уже. А сами сервисы потом уже инжектите в контроллеры и вызывайте нужные вам методы.
    Ответ написан
    6 комментариев
  • API php, Как правильно отдать данные?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега PHP
    Нужная сторона: Fractal.
    Ответ написан
    Комментировать
  • Правильно ли будет, если поставить GitLab на сервере разработки?

    @MadridianFox
    Web-программист, многостаночник
    Центральный репозиторий (тот в котороый пушат несколько разработчиков) должен быть bare - т.е. без файлов.
    Например GitLab как раз хранит bare репозитории.

    Если /var/www/project это хост только чтобы показывать сайт (не разрабатывать прямо тут), то туда надо клонировать репозиторий из центрального. Когда разрабы пушат в центральный - руками или автоматически делаете pull в /var/www/project.

    Где ставить гитлаб - вопрос наличия и мощности ваших машин. У меня в последнем проекте машин было мало и на dev-машине работали и гитлаб и хосты разработчиков, но в docker-контейнерах, т.е. они никак не были связаны.

    Если же /var/www/project это хост с которым работают все разрабы сразу (прямо редактируют код), то срочно заваривайте чай - придётся переделывать. Лучше каждому разрабу выделить свой хост где он будет редактировать файлы своей копии сайта.
    Ответ написан
    7 комментариев
  • Что использовать в качестве логгера на php?

    @D3lphi
    Ответ написан
    Комментировать
  • Нужна помощь с архитектурой в MVC?

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

    qonand
    @qonand
    Software Engineer
    1. Как-то у Вас сущности живут отдельной жизнью друг от друга. По сути сейчас Вы перенесли структуру своей базы данных на объекты, а это не правильно. Сущность заказа должна агрегировать в себя сущности позиций заказа и покупателя, а не просто содержать их идентификаторы. Например:
    class OrderEntity
    {
        /**
         * @var integer Идентификатор заказа
         */
        protected $id;
        
        /**
         * @var MemberEntity Объект покупателя
         */
        protected $member;
        
        /**
         * @var ItemEntity Массив позиций заказа
        protected $items = [];
    }

    2. Получение данных из базы данных в объект должно быть реализовано в каком-нибудь репозитории или в каком-нибудь датамаппере. Почитайте про эти паттерны. Но вообще лучше взять какую-нибудь вменяемую ORM что бы избежать кучи гемора.
    3. По названиям классам - не добавляйте в них суфикс Entity, код становиться из-за этого более нагроможденным, лучше используйте пространства имен
    Ответ написан
    3 комментария
  • Как создать приватный пакет composer?

    если вашего пакета нет на пакаджист, значит, нужно описать репозиторий, откуда пакет будет грузиться.
    https://getcomposer.org/doc/05-repositories.md#vcs
    прописать в composer.json приложения.
    Ответ написан
    1 комментарий
  • Как правильно называется класс который содержит реализацию?

    1) это похоже на стратегию, здесь в качестве стратегии ваш функционал для библиотеки, собственно для разных CMS можно иметь разный функционал, или тот же самый, подставляя ту или иную реализацию, в общем похоже на ваш случай, но информации мало
    2) нужно поставлять все что необходимо чтобы библиотека работала, если это будет отдельным репозиторием, значит надо добавить зависимость в композер, однако слишком не надо усложнять, заранее нельзя все продумать, вы можете и в будущем вынести в отдельный репозиторий
    Ответ написан
    Комментировать