Задать вопрос
  • Как реализовать отзывы для нескольких сущностей?

    padlyuck
    @padlyuck
    https://www.doctrine-project.org/projects/doctrine... или https://www.doctrine-project.org/projects/doctrine... для организации всех комментариев в одной таблице. Судя по документации вам придется сделать класс родительского комментария и 3 класса конкретных сущностей комментариев относительно того к чему они привязаны. Да и разный функционал будет проще потом разносить, а не мешать в кучу коней с людЯми
    Ответ написан
    1 комментарий
  • Какой php-фреймворк сейчас стоит изучать в качестве первого?

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Смотря какие у вас цели)). Пилить небольшие говносайтики - laravel. Что-то среднее - yii. Что-то серьезное - symfony. Что-то серьезное, но для крепких нервов - zend. "не хочу ничего учить" - code igniter. "тупой и жадный" (с) - bitrix.

    Рекомендую взглянуть: Попросили проверить код, на что смотреть нужно?
    Ответ написан
  • Many-to-many как избежать Race conditions?

    @yayashitoya
    Как можно избежать этого ?


    Все уже придумано до нас. Лет эдак за 50.
    Делать в одной транзакции. И проверку и добавление подписки.
    Ответ написан
    Комментировать
  • Что нужно учить, чтобы стать php разработчиком и работать на upwork?

    @Stalinko
    PHP'шник и фрилансер до мозга костей
    php5, php7, Laravel/Yii/Slim/Symfony/Zend, jQuery, MySQL, Highload, Computer Science, Redis, ElasticSearch, NodeJS, nginx, apache, AWS, memcache, unix, RESTful APIs, Payment intergration....
    Также не помешает AngularJS, VueJS, ReactJS, MSSQL, PostgreSQL, Oracle SQL, ES6...

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

    В общем, смотри, что умеют те, кто зарабатывает больше тебя, и делай так же.
    Ответ написан
    4 комментария
  • Как сделать правильный выбор между C# и Java?

    Sputterspark
    @Sputterspark
    В далеком прошлом, я занимался пустой тратой времени. А именно - выбором языков программирования.

    И продолжаешь этим заниматься.
    Ответ написан
    Комментировать
  • Как реализовать API запросы в PHP?

    @l4m3r
    Мне же не надо создавать для каждого поста отдельную папку?(а если поста нет?)

    А может ну его, это программирование?
    Ответ написан
    7 комментариев
  • На кого поступать, чтобы в будущем разрабатывать искусственный интеллект?

    1. На самом деле в наших ВУЗах нет программ близких к ИИ, так что просто поступайте на любую IT специальность вроде Прикладной информатики или Программной инженерии, а дальше изучайте это направление самостоятельно. Необходимую базу знаний для поступления на младшего разработчика получите. Выше уже скинули то что нужно изучать, но никто не мешает погуглить и дополнить или поправить этот список.
    2. Выбирайте те которые на слуху, там обычно часто приглашают разных специалистов, спикеров.
    3. Опыта нет, сам студент.
    Ответ написан
    Комментировать
  • Как побороть NIH-синдром?

    petermzg
    @petermzg
    Самый лучший программист
    Когда вы были маленьким ребенком, то для вас буквы представлялись неведомыми закорючками, а уж написать каждую букву требовало огромного труда, но они все равно были мало похожими.
    А сейчас вы умеете читать и писать. Вы научились этому. Так и с программированием.
    Ответ написан
    Комментировать
  • Чем опытнее разработчик, тем меньше соблюдается принцип KISS?

    @asd111
    То что ты назвал - repository, service layer, provider это не так сложно как кажется.

    Repository - это прослойка над моделью, обычно один класс для каждой модели в котором собраны все функции для работы с моделью, т.е. все нужные запросы к БД через модель, чтобы не писать их в самой модели.

    Service layer - прослойка между контроллером и репозиторием, обычно один класс для каждой модели(репозитория). Здесь обычно пишут обработку данных полученных из репозитория чтобы потом можно было сразу вставить во view. Как правило в service layer есть методы create read update delete - как в контроллере и в них пишут ту логику, которую обычно писали в контроллере только без привязки ко view.

    Sevice Provider - некий код который кочует из проекта в проект и делает например авторизацию пользователя или кеширование. В Laravel есть свой механизм service provider.

    Как правило service layer и repository добавляют чтобы всю логику класть туда и сохранить модели и контроллеры очень простыми. Например в методах контроллера может быть банальный вызов методов service layer с привязкой ко view и больше никакой логики.

    Посмотри вот этот пример https://blog.eduonix.com/web-programming-tutorials... и сразу станет понятно.
    В этом подходе нет ничего сложного иначе никто бы не пользовался.
    Можешь сам попробовать написать тот же блог но только с service layer и repository - это проще чем кажется.
    Ответ написан
    Комментировать
  • Чем опытнее разработчик, тем меньше соблюдается принцип KISS?

    Adamos
    @Adamos
    Чем опытнее разработчик, тем чаще, выполняя конкретную задачу, он понимает, что примерно такую уже решал. Поэтому опытный разработчик видит уровни абстракции, общие для многих решений. И описывает их так, чтобы потом, при решении очередной конкретной задачи, использовать написанное ранее с минимумом дополнительных усилий.
    Вы, не имея такого опыта, просто не понимаете, что все эти лееры, провайдеры и трейты - прекрасная возможность написать две строчки и быть уверенным в их работе там, где вы угробите два дня на написание "простого" решения, а потом еще неделю будете отлавливать его глюки.
    Ответ написан
    6 комментариев
  • Чем опытнее разработчик, тем меньше соблюдается принцип KISS?

    FanatPHP
    @FanatPHP
    Чебуратор тега РНР
    Принцип KISS не означает что надо использовать самые примитивные инструменты.
    Он означает, что не надо переусложнять систему без нужды.
    Если так рассуждать, так и высшее образование не нужно: "Дед отличные бани строил, хотя вовсе был неграмотный. Я и без сопромата небоскреб построю!"
    Если вы пока ещё не понимаете назначение всех этих "лееров, провайдеров и репозиториев", это не значит, что они вообще никому не нужны.

    Для того, чтобы упростить управление системой, её надо усложнить.
    Этот принцип относится к любой области человеческой деятельности, от постройки ракет до управления государствами.
    Чем сложнее система, тем больше накладные расходы на ее управление. Хоумпейдж с котиками можно и нужно делать примитивными средствами. В большом проекте надо сразу закладываться на будущую расширяемость. То есть, заранее делить ответственность между "леерами".

    И кстати. Код, в котором "всё друг на друге завязано" - это очень плохой код. Собственно, предназначение всех этих "лееров, провайдеров и репозиториев" как раз в том, чтобы компоненты были как можно более независимы друг от друга.
    Ответ написан
    1 комментарий
  • Как построить инфраструктуру большого проекта?

    opium
    @opium
    Просто люблю качественно работать
    Если все достаточно оптимально и нет каких то глупостей можно воткнуть на один сервер и все будет ок
    Ответ написан
    Комментировать
  • Почему phpStorm перечёркивает синтаксис "className" в yii2?

    @sidni
    Php Developer
    Потому как разработчики посчитали ее деприкейтед и приняли решение правильным будет использовать появившееся в 5.5.0 версии пхп нативное выражение
    Widget::class
    Ответ написан
    Комментировать
  • Как работает подход Unit of Work?

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

    class Tweet
    {
        private $id;
        private $content;
    
        public function __construct(int $id, string $content)
        {
            $this->id = $id;
            $this->content = $content;
        }
    
        public function getId(): int
        {
            return $this->id;
        }
    
        public function getContent(): string
        {
            return $this->content;
        }
    
        public function setContent(string $content): void
        {
            $this->content = $content;
        }
    }


    Схема данных:

    CREATE TABLE tweets (
        id INTEGER PRIMARY KEY,
        content VARCHAR(255) NOT NULL
    )


    Следующая реализация UnitOfWork будет иметь несколько ограничений:
    1. Она умеет работать только с Tweet;
    2. Она умеет только загружать сущности и сохранять произведённые в них изменения.
    class UnitOfWork
    {
        private $connection;
        private $identityMap;
        private $data;
    
        public function __construct(\PDO $connection)
        {
            $this->connection = $connection;
            $this->identityMap = [];
            $this->data = [];
        }
    
        public function find(int $id): Tweet
        {
            if (isset($this->identityMap[$id])) {
                return $this->identityMap[$id];
            }
    
            $query = $this->connection->prepare('SELECT * FROM tweets WHERE id = ?');
            $query->execute([ $id ]);
    
            if (false === $data = $query->fetch()) {
                throw new \Exception(\sprintf('Tweet with id "%d" not found.', $id));
            }
    
            $id = (int) $data['id'];
    
            // Исходные данные сохраняются для того, чтобы в дальнейшем вычислить изменения.
            $this->data[$id] = $data;
    
            $tweet = new Tweet($id, $data['content']);
    
            $this->identityMap[$id] = $tweet;
    
            return $tweet;
        }
    
        public function commit(): void
        {
            // Вообще говоря, лучше вычислить все изиенения, создать один "большой" запрос
            // и выполнить его внутри транзакции, но для простоты мы сделаем для каждого
            // изменения отдельный запрос
            $query = $this->connection->prepare('UPDATE tweets SET content = ? WHERE id = ?');
            foreach ($this->identityMap as $tweet) {
                if ($tweet->getContent() !== $this->data[$tweet->getId()]['content']) {
                    $query->execute([ $tweet->getContent(), $tweet->getId() ]);
                }
            }
        }
    }


    Полный пример можете скачить и посмотреть тут: https://gist.github.com/voronkovich/d35cdcdf6eb09e...
    Ответ написан
    1 комментарий
  • Как работает подход Unit of Work?

    @Flying
    Unit of Work - это паттерн определяющий логическую транзакцию т.е. атомарную синхронизацию изменений в объектах, помещённых в объект UoW с хранилищем (базой данных).

    Если обратиться к исходному описанию этого паттерна у Мартина Фаулера - то видно что объект, реализующий этот паттерн отвечает за накопление информации о том какие объекты входят в транзакцию и каковы их изменния относительно исходных значений в хранилище. Основная работа производится в методе commit() который отвечает за вычисление изменений в сохранённых в UoW объектах и синхронизацию этих изменений с хранилищем (базой данных).

    Паттерн Unit of Work как правило не является полностью самостоятельным, он обычно тесно связан с паттерном Identity Map, задача которого - сохранение карты созданных объектов, взятых из хранилища с тем чтобы гарантировать что одна единица информации из хранилища представлена ровно одним экземпляром объекта данных в приложении. Это позволяет избежать конфликтов изменений т.к. не допускает ситуации когда два объекта, представляющих один и тот же элемент данных в хранилище, изменены по-разному. Информация из Identity Map используется в методе commit() паттерна Unit of Work для вычисления разницы между исходными данными и накопленными изменениями.

    Поскольку для вычисления разницы (и, соответственно, определения того что и каким образом должно быть изменено в хранилище) необходимо знать какие данные и как именно хранятся в объектах - как правило необходима также реализация паттерна Metadata Mapping, описывающего связь между содержимым хранилища (к примеру таблицами и столбцами базы данных) и классами / свойствами объектов.

    Также, если данные в хранилище не являются независимыми (к примеру связи между таблицами в базе данных) - может потребоваться реализации ряда паттернов, отвечающих за сохранение информации о связях между данными (это паттерны раздела Object-Relational Structural Patterns в каталоге паттернов).

    Подводя итог: сам по себе Unit of Work довольно прост в своём внешнем интерфейсе, но реализация его корректной работы требует предоставления множества дополнительных данных, поэтому миниатюрных примеров привести не могу.

    Если говорить о PHP - то лучшей реализацией этих паттернов на PHP безусловно является Doctrine ORM. В частности в разделе Working with Objects документации Doctrine можно найти хорошее описание и множество примеров использования паттернов, описанных выше.
    Ответ написан
    6 комментариев
  • Правильно ли использование статичных методов в таком контексте?

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

    index0h
    @index0h
    PHP, Golang. https://github.com/index0h
    Смотря зачем)). Я когда делаю Code Review критерии следующие:

    * Безопасность:
    - Каждый аргумент метода простого типа должен проверяться на тип в случае его проксирования и на граничные значения в случае обработки. Чуть что не так - бросается исключение. Если метод с кучкой аргументов на 80% состоит из поверки из аргументов - это вполне норм))
    - Никаких trigger_error, только исключения.
    - Исключения ДОЛЖНЫ быть человеко-понятны, всякие "Something went wrong" можно отдавать пользователю, но в лог должно попасть исключение со стектрейсом и человеко-понятным описанием, что же там пошло не так.
    - Каждый аргумент (объект) метода должен быть с тайпхинтингом на этот его класс, или интерфейс.
    - За eval как правило шлю на **й.
    - @ допускается только в безвыходных ситуациях, например проверка json_last_error.
    - Перед работой с БД - обязательная проверка данных.
    - Никаких == и !=. Со swtich - единственное исключение, по ситуации.
    - Если метод возвращает не только bool, а еще что-то - жесткая проверка с ===, или !== обязательна.
    - Никаких условий с присваиваниями внутри. while($row = ...) - тоже идет лесом.
    - Магические геттеры/сеттеры разрешаются только в безвыходных ситуациях, в остальном - запрещены.
    - Конкатенации в sql - только в безвыходных ситуациях.
    - Параметры в sql - ТОЛЬКО через плейсхолдеры.
    - Никаких глобальных переменных.
    - Даты в виде строки разрешаются только в шаблонах и в БД, в пхп коде сразу преобразуется в \DateTimeImmutable (в безвыходных ситуациях разрешено \DateTime)
    - Конечно зависит от проекта, но как приавло должно быть всего две точки входа: index.php для web и console(или как-то по другому назваться) - для консоли.

    * Кодстайл PSR-2 + PSR-5 как минимум, + еще куча более жестких требований (для начала все то что в PSR помечено как SHOULD - становится MUST)
    - В PhpStorm ни одна строчка не должна подсвечиваться (исключением является typo ошибки, например словарик не знает какой-то из аббревиатур, принятых в вашем проекте). При этом разрешается использовать /** @noinspection *** */ для безвыходных ситуаций.
    - Если кто-то говорит, что пишет в другом редакторе и у него не подсвечивается, на эти отговорки кладется ВОТ ТАКЕЕЕНЫЙ мужской половой **й и отправляется на доработку)).

    * Организация кода:
    - Никаких глобальных функций.
    - Классы без неймспейса разрешаются только в исключительно безвыходных ситуациях.

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

    * Принципы MVC:
    - Никаких обработок пользовательского ввода в моделях, от слова совсем.
    - Никаких ***ть запросов в БД из шаблонов.
    - Никаких верстки/js/css/sql-ин в контроллерах.
    - В моделях НИКАКОЙ МАГИИ, только приватные свойства + геттеры с сеттерами.
    - В моделях разрешено использовать метод save(при наличии такого разумеется) только в исключительных ситуациях. Во всех остальных - либо insert, либо update.

    * Принципы SOLD:
    - Никаких божественных объектов умеющих во все.
    - Если метод для внутреннего пользования - private, никаких public.
    - Статические методы разрешаются только в случае безвыходности.

    * Принцип DRY разрешено нарушать в случаях:
    - Явного разделения обязанностей
    - В тестах (каждый тест должен быть независимым, на сколько это возможно)

    * Работа с БД:
    - Запрос в цикле должен быть РЕАЛЬНО обоснован.
    - За ORDER BY RAND() - шлю на***й.
    - Поиск не по ключам (конечно если таблица НЕ на 5 строк) запрещен.
    - Поиск без LIMIT (опять же если таблица НЕ на 5 строк) запрещен.
    - SELECT * - запрещен.
    - Денормализация БД должна быть обоснована.
    - MyISAM не используется (так уж)) )
    - Множественные операции обязательно в транзакции, с откатом если чо пошло не так.
    - БД не должна содержать бизнес логики, только данные в целостном виде.
    - Не должно быть нецелесообразного дерганья БД там, где без этого можно обойтись.

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

    * О людях:
    - "Я привык писать так и буду дальше" - не вопрос, ревью пройдешь только когда поменяешь свое мнение.
    - "Я пишу в vim-е и мне так удобно" - здорово, код консолью я тоже в нем пишу)) но есть требования к коду, если в них не сможешь - не пройдешь ревью.
    - "Я скопировал этот страшный метод и поменял 2 строчки" - это конечно замечательно, но по блейму автор всего этого метода ты, так что давай без говняшек, хорошо?
    - "Оно же работает!" - вот эта фраза переводится примерно так: "да, я понимаю, что пишу полную хрень, но не могу писать нормально потому, что руки из жо", я правильно тебя понял?))
    - "У меня все работает!" - рад за тебя, а как на счет продакшна?
    - "Там все просто" - не используй слово "просто", от слова "совсем". Вот тебе кусок кода (первого попавшегося с сложной бизнес логикой), где там ошибка (не важно есть она, или нет)? Ты смотришь его уже 2 минуты, в чем проблема, там же все "просто"))

    * Всякое:
    ActiveRecord (это я вам как в прошлом фанат Yii говорю) - полное говно, примите за исходную. По факту у вас бесконтрольно по проекту гуляют модельки с подключением к БД. Не раз натыкался на то, что в тех же шаблонах вызывают save, или update (за такое надо сжигать).
    То, что используется Laravel - это печально((. Что бы выполнить требования приведенные выше, приходится "воевать" с фреймворком.

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

    UPD

    Формализировал данные критерии по ссылочке: https://github.com/index0h/php-conventions
    Ответ написан
    55 комментариев
  • Нужно ли разделение системы на сервисы, за которые отвечает в полной мере минимум один человек?

    inoise
    @inoise
    Solution Architect, AWS Certified, Serverless
    Во-первых FullStack для сервисной архитектуры это полная задница, уж простите. Необходимо иметь раздельно людей на фронт и бэк. Проблема о которой вы еще не знаете в том что люди имеют свойство меняться и в таком ключе вы можете потерять очень значимую единицу. Бэк должен иметь четкую спецификацию и соответствовать логике работы микросервиса/ сервиса (по секрету - они только размером отличаются ).

    Микросервис и их интеграция появляется в системе с разной скоростью и строятся они абсолютно по-разному. Более того в таком подходе вам обязательно нужен тот кто проектирует все это вместе и по отдельности. Обычно это архитектор
    Ответ написан
    4 комментария
  • Символы в тексте мешают валидации XML. Как решить?

    serginhold
    @serginhold
    https://ru.m.wikipedia.org/wiki/CDATA
    Возможно об этом вопрос
    Ответ написан
    Комментировать
  • Хочу стать Full stack develper'ом. Что надо знать?

    Stalker_RED
    @Stalker_RED
    Если ты уже знаешь Laravel и Angular JS, Bootstrap, то ты уже full stack, поздравляю.
    Конечно, всегда есть возможность для роста, но сейчас вы можете выбирать те темы для изучения, которые вам нужны в работе. Базовый фундамент уже заложен.

    (Это конечно если "знаю что-то" в том смысле, что "могу применять на практике" а не "это название я уже где-то встречал")
    Ответ написан
    Комментировать