• Книга по шаблонам проектирования?

    OnYourLips
    @OnYourLips
    Есть классика от "Банды четырех". Актуальна ли она сейчас и стоит ли с ней ознакомится?

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

    Советую книгу по паттернам от Head First.
    Ответ написан
    1 комментарий
  • Подход к реализации DI в проектах Yii2 - правильно или не очень?

    @MadridianFox
    Web-программист, многостаночник
    Какое-то однобокое решение:
    if (!isset($config['dependencyClass'])) {
        $this->dependencyClass = new Dependency();
    }

    Вроде как и внедрение зависимости, но всё-равно остаётся жесткая связь.

    А чем вас не устроил родной Yii сервис-локатор через конфиг?
    Можно было бы делать конфигурирование зависимости как компонента yii вот так:
    //config/web.php
    "components"=>[
        //...
        "model_deps"=>[
              "class"=>"app\components\ModelDependenciesService",
              "default_dependency"=>"app\model\model_2",
              "dependencies"=>[
                     "app\model\model_1"=>[
                            "dep_1"=>"app\model\model_3",
                            //....
                      ]
               ]
         ]
        //...
    ]
    // в базовом классе модели
    public function getDepClass($dep_name){
        retrn Yii::$app->model_deps->depClass(static,$dep_name); // не помню точно как текущий класс брать
    }
    // где-то в модели
    public function getDependencies()
    {
        return $this->hasMany($this->getDepClass($dep_name), ['modelId' => 'id']);
    }

    В классе ModelDependenciesService, естественно надо реализовать метод depClass, который будет возвращать класс зависимости или класс по умолчанию, если зависимость не определена.
    Ответ написан
    Комментировать
  • Подход к реализации DI в проектах Yii2 - правильно или не очень?

    Insolita
    @Insolita
    Отчаянная домохозяйка
    А чем классический вариант не устраивает?

    Объявите интерфейс который нужен зависимой модели и прямо в конструктор его, можно от ActiveRecordInterface унаследовать
    Пусть ваша модель будет Post с Зависимостью Comments

    interface PostCommentModelInterface // можно extends ActiveRecordInterface
         {
            /**
             * @return ActiveRecord[]|Comment[]
            **/
                public function findForPost();
    
        }
    
         class Model extends yii\base\Model
         {
               protected $commentModel;
               public function __construct(PostCommentModelInterface $commentModel, $config = [])
              {
                    $this->commentModel = $commentModel;
                    parent::__construct($config);
               }
        ]

    А зависимости региструются в начале приложения после запуска конфига, в файле bootstrap.php
    типа Yii::$container->set('\app\modules\posts\PostCommentModelInterface','\app\modules\comments\CommenModel')

    только создавать модель надо будет не new Post(), а Yii::createObject(['class'=>'\app\module\Post']) тогда автоматом зависимость подключит... ну или вручную new Post(new Comment())

    ну или альтернативный, но менее красивый вариант

    ...
         protected $commentModel;
    
          public function __construct(\yii\container\Container $container, $config = [])
          {
             $this->commentModel = $container->get('\app\modules\posts\PostCommentModelInterface'');
              parent::__construct($config);
           }
       ...


    правда смущает ваше $this->hasMany ... при extends yii\base\Model ...
    посмотрите тут про паттерны, особенно в комментах
    https://habrahabr.ru/post/183658/#comment_6392902
    Ответ написан
    4 комментария
  • Как правильно организовать код в php-фреймворке?

    zolt85
    @zolt85
    Программист
    Учиться, учиться и еще раз учиться, как завещал дедушка Ленин.
    Не видя сам код и структуру проекта, тут трудно что-либо советовать. Почитайте "Чистый код" Боба Мартина, особенно про принцип единой ответственности. Если метод вашего класса не помещается на мониторе компьютера - его необходимо переписать. Ну и все в таком духе. Главное не гнаться за чистотой кода ради самой чистоты. Все к чему призывает дядя Боб, это писать читаемый, поддерживаемый код, который после Вас смогут читать и поддерживать другие разработчики.

    И еще важный момент, закрепите правила разработки на уровне команды. Т.е. что бы все писали одинаково. Структура проекта должна быть четкой и понятной. Мы в своей команде такие правила обозначили (они конечно же пересматриваются, обсуждаются) и теперь команда из 6 разработчиков легко ориентируется в коде enterprise монстра с 6 летней историей, и с over 5000 классов на борту, и даже умудряется его улучшать.

    По поводу контроллеров: я лично не знаком с философией Laravel, сам разрабатываю на Java и мой framework - Spring. У меня философия на счет контроллеров такая - контроллер является посредником между front и back end-ами. Никакой логики контроллер в себе не содержит, от слова "совсем". Вся логика вынесена в фасад, который в свою очередь может включать в себя кучу сервисов. Сервисы (по-возможности) разрабатываются с учетом принципа единой ответственности. Сервисы содержат в себе всю бизнес-логику приложения.
    Ответ написан
    5 комментариев
  • "Сильные" книги по Symfony и архитектуре приложений?

    by25
    @by25
    Веб-разработчик
    1. Мэтт Зандстра "PHP: объекты, шаблоны и методики программирования" - Врубиться в ООП
    2. Эрик Фримэн и ко "Паттерны проектирования" (Head First) - Влюбиться в ООП
    3. Эрик Эванс "Предметно-ориентированное проектирование" - научиться проектировать сложные системы
    4. Крэг Ларман "Применение UML 2.0 и шаблонов проектирования" - про проектирование, глубокое понимание ООП
    Ответ написан
    Комментировать
  • Как удалить файл после использования?

    alsopub
    @alsopub
    Вы наверное это ищите - https://ru.wikipedia.org/wiki/Data:_URL
    <img
    src="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAw
    AAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFz
    ByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSp
    a/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJl
    ZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uis
    F81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PH
    hhx4dbgYKAAA7"
    alt="Larry" />
    Ответ написан
    1 комментарий
  • Вопрос по yii и общая теория?

    Akdmeh
    @Akdmeh
    PHP, Yii2, Music
    1) Намного быстрее. И вы делаете сайты вместо того, чтобы копаться в архитектуре и пытаться постоянно усовершенствовать свой код, который к сайтам имеет посредственное отношение
    2) самому прописать в конфигах, почитайте об этом в главе о настройке/установке Yii
    3) Можно, но это довольно условно. Начните с basic-шаблона, для начала его хватит, а когда поймете базовые концепции и овладеете фреймоврком - сможете разобраться с advanced. Впрочем, можно пойти третьим путем и самому себе создать базовый шаблон, который вам подходит во всем.
    4) обычно на чистом PHP пишут шаблоны (это позволяет удобно подключать штатные виджеты и методы), но есть библиотеки для интеграции Smarty и Twig при необходимости
    Ответ написан
    3 комментария
  • Как правильно организовать мультиязычность в Yii2?

    ThunderCat
    @ThunderCat
    {PHP, MySql, HTML, JS, CSS} developer
    В нашем велосипеде мы используем алиасы, чтобы во первых не писать что то типа:
    \Yii::t('app', 'Разлюбезная моя Елизавета Петровна! С этим письмом прилагаю свою любовь бла бла');
    // instead use alias
    \Yii::t('app', 'suhov_mail');

    и для каждого языка свой файл. Включая основной.
    Ответ написан
    2 комментария
  • Как организовать ядро приложения в Yii2?

    webinar
    @webinar Куратор тега Yii
    Учим yii: https://youtu.be/-WRMlGHLgRg
    Делаете модуль ЯДРО, в нем другие модули.
    Все зависит от того что Вам надо, если модули независимы, то удобно как отдельные модули иметь, если они неотъемлемая часть ядра, то соответственно.
    Тут скорее важно при написании этого ядра сделать его максимально абстрактным. Ему должно быть пофиг к чему оно подключено. А 1 это модуль или 10 - второй вопрос.
    Ответ написан
    2 комментария
  • Нужно ли ИП на УСН6% платить НДС при доходах со Steam, Google Play, AppStore?

    kovspace
    @kovspace
    Web developer
    ИП по УСН не должен платить НДС. Только 6% и отчисления в ПФР
    Ответ написан
    3 комментария
  • В чем разница между ActiveForm и Html Form yii2?

    ActiveForm тесно связана с моделью - сама получает из неё данные, сама заполняет.
    HtmlForm - просто реализация формы.
    Ответ написан
    3 комментария
  • Как тестировать методы, создающие объекты других классов?

    @matperez
    Разнесите создание инстанса и его использование.
    class BarFabric
    {
      public function create(array $config = [])
      {
        return new Bar($config);
      }
    }
    class Foo
    {
      protected $barFabric;
      public function __construct(BarFabric $barFabric)
      {
        $this->barFabric = $barFabric;
      }
      public function someMethod()
      {
        $bar = $this->barFabric->create();
        $bar->method1();
        $bar->method2();
        $blabla = $bar->getResult();
        //etc
      }
    }
    
    class FooTest
    {
      public function testSomeMethod()
      {
        $bar = \Mokery::mock(Bar::class);
        // ... описание поведения для мока
        $factory = \Mokery::mock(BarFactory::class);
        $factory->shouldReceive('create')->andReturn($bar);
        $foo = new Foo($factory);
        $this->assertSomething($foo);
      }
    }


    О том, как быть с ActiveQuery...

    Во первых, выносите логику запроса так же в отдельный класс. Если генерируете новую модель, Gii это может сделать и сам.
    class FooQuery extend ActiveQuery
    {
        /**
         * @inheritdoc
         * @return Foo[]|array
         */
        public function all($db = null)
        {
            return parent::all($db);
        }
    
        /**
         * @inheritdoc
         * @return Foo|array|null
         */
        public function one($db = null)
        {
            return parent::one($db);
        }
    }


    Этот объект передавайте в целевой класс так же как фабрику:
    class Bar
    {
      protected $query;
      public function __construct(FooQuery $query)
     {
        $this->query = $query;
     }
    
     public function someMethod()
     {
        $foo = $this->query->where(...)->one();
        $foo->doSomething();
     }
    }


    Ну а дальше мокайте как и в первом случае
    $queryMock = \Mockery::mock(FooQuery::class);
    $queryMock->shouldRecieve('where->one')->andReturn($fooMock);


    ActiveQuery можно мокать частично, после этого будут выполняться все родные методы, а вот сохранение в базу пропустится.
    $fooMock = \Mockery::mock(Foo::class.'[save, update]');
    $fooMock->shouldRecieve('save', 'update')->andReturn(true);


    Relations можно не подменять вообще. Они прекрасно подставляются через ActiveRecord::populateRelation().

    $foo = new Foo();
    $foo->populateRelation('bar', new Bar());
    Ответ написан
    9 комментариев
  • Как тестировать методы, создающие объекты других классов?

    qRoC
    @qRoC
    Использование Dependency Injection решает данную проблему.
    Ответ написан
    Комментировать
  • Не помешает ли мне изучение PHP потом перейти на RoR?

    scherbuk
    @scherbuk
    А есть какая то разница на жигулях или на волге ездить? главное ПДД знать
    Учить надо наверное все таки шаблоны программирования там разные как по мне
    Ответ написан
    2 комментария
  • Согласно MVC, как рекомендуется управлять сессиями?

    27cm
    @27cm
    TODO: Написать статус
    Забавно смотреть, как вы пытаетесь абсолютно всё отнести к одной из трёх букв MVC, как буд-то кроме моделей, видов и контроллеров других паттернов нет.

    За работу аутентификацией/авторизацией/сессией/куками может отвечать некий сервис, не имеющий отношения к MVC. А получение доступа из моделей и контроллеров к ним можно осуществлять через Service Locator.

    пожалуйста, не рекомендуйте использовать фреймворки вместо велосипедов

    Всё же посоветую пересилить свой страх, а то звучит как "пожалуйста, не заставляйте меня идти правильным путём".
    Ответ написан
    3 комментария
  • Куда вынести логику работы с данными принадлежащими разным моделям?

    SilenceOfWinter
    @SilenceOfWinter
    та еще зажигалка...
    Шаблон фасад (англ. Facade) — структурный шаблон проектирования, позволяющий скрыть сложность системы путем сведения всех возможных внешних вызовов к одному объекту, делегирующему их соответствующим объектам системы.
    Ответ написан
    6 комментариев
  • Yii - как в init() передать параметры через конструктор?

    @Arik
    Можно записать в свойство и в init работать с этим свойством
    Ответ написан
    2 комментария
  • Как вывести изображение во view Yii?

    bitver
    @bitver
    Url::to(['/img/bootles.jpg'])
    Откройте документацию, там на этот счёт целая страница.
    Ответ написан
    Комментировать
  • Yii2: Как выполнить добавление в одну таблицу с включенным режимом транзакции?

    Это
    $transaction->rollBack();
        foreach ($this->firstErrors as $key => $value) break;
        if (empty($value)) $value = 'Неизвестная ошибка';
        return array('message' => $value, 'status' => false);

    заменяем на что-то, типа этого
    throw new HttpException(500, 'Неизвестная ошибка');

    А уже в catch'а делаете свои проверки и генерируете сообщения от ошибке, если нужно.
    И все должно работать.
    Ответ написан
    2 комментария