Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 12.03.2015 10:04:22

Xeilor

Class Override

Здравствуйте!

С Laravel знаком пару дней. Нужна помощь в переопределении классов.
Хочу получить результат подобный тому как это сделано в Magento.

Пример.

В  *composer.json* я добавил следующее:

    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/",
            "App\\local\\": "app/local/",
            "App\\core\\": "app/core/"
        }
    },

Структура папок:

app\
   local\
   core\

В папках `local` и `core` есть  "class Region extends Model".
Необходимо сделать проверку в папке `local` и если  file/class Region в ней отсутствует, то поlключить его из папки `core`.
Подскажите, пожалуйства правильный способ.

#2 12.03.2015 11:09:44

Re: Class Override

правильный способ — создать контракт и разрешать его IoC-контейнером. настраивать какую именно реализацию контракта использовать — в service provider’е.

только зачем это для моделей-то делать? если детали функционирования модели отличаются в разных окружениях, надо или выносить их в .env (если это простые настройки) или в сервис (если это какой-то функционал), а сама модель пусть остаётся неизменной.

или использовать репозиторий, абстракцию над моделями — и его разрешать контейнером.

а вот это

js        "psr-4": {
            "App\\": "app/",
            "App\\local\\": "app/local/",
            "App\\core\\": "app/core/"
        }

вообще лишено смысла. PSR4 уже включает подпапки в качестве неймспейсов в App.

Изменено constb (12.03.2015 11:13:54)

Не в сети

#3 12.03.2015 12:18:56

Xeilor

Re: Class Override

Цель сделать это не только для моделей, а для всего приложения.
Таким образом, в папке `core` мы разместим приложение и, например, зальем его на сервер.

Спустя какое-то время, возможно, сайт сопровождать будет другой программист.
И что бы не изменять ядро приложения, которое может быть просто перезалито  владельцем/предыдущим_разработчиком/еще_кем-то,
другой программист будет использовать папку `local` для тех классов, которые он изменял.

Вот как это описано в Magento:
Core files in the local folder override the same files in the core folder.
For example, if you copy app/code/core/Mage/Catalog/Model/Layer/Filter/Price.php to app/code/local/Mage/Catalog/Model/Layer/Filter/Price.php then Magento will use app/code/local/Mage/Catalog/Model/Layer/Filter/Price.php

Я понимаю как это реализовать на php и как это работает в Magento.
В Laravel я пришел к тому, что мне нужно переопределить class ClassLoader в namespace Composer\Autoload
Но что-то мне подсказывает, что это не верный путь.

Вероятно, контракт и IoC это то что мне нужно,
но пока что не могу найти пример как это использовать, нахожу только описание теории.
Если есть возможность посмотреть рабочий пример, то буду признателен.

#4 12.03.2015 14:06:35

Re: Class Override

пример есть в стоковом приложении — класс PHPApp\Services\Registrar реализует контракт PHPIlluminate\Contracts\Auth\Registrar. реализация контракта задаётся в сервис-провайдере, в данном случае регистрар назначает PHPApp\Providers\AppServiceProvider. теперь если мы попросим контейнера сделать нам регистрара — напрямую через PHPapp()->make('Illuminate\Contracts\Auth\Registrar') или через dependency injection — то получим экземпляр PHPApp\Services\Registrar. реализации контракта можно назначать условно, в том числе и через конфиги и через .env и явно — например так [https://mattstauffer.co].

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

Не в сети

#5 12.03.2015 14:11:37

Re: Class Override

вообще по здравому рассуждению, если просто стоит задача пасти другого программиста и ревьюить его правки, то контракты и IoC — не самое подходящее решение. надо всего лишь использовать git. им можно и правки откатывать и изменения в диффах читать.

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

а если программист будет упираться рогом и не хотеть использовать git — просто настроить гитом деплой на сервер и никуда он не денется. =)

Не в сети

#6 12.03.2015 14:54:28

Xeilor

Re: Class Override

Пример понял, буду копать в том направлении.

Вкратце, задача стоит не пасти другого программиста, а дать ему возможность влиять на приложене не изменяя его ядро.
Это необходимо, например, если мы хотим сохранить изменения владельца/другого_программиста и обновиться ядро приложения.

Хотелось бы уже на начальном этапе сделать это разделения на папки `core` и `local`.
Так же хотелось бы избежать действий когда новый программист должен создавать реализацию контракта в своей папочке.

Хочется использовать для этого простое решение, когда другой программист просто копирует всего один файлик в папку `local` соблюдая иерархию папок и не заботится о том как вообще работает Laravel.
Он просто знает, что ему нужно переопределить класс (например, контроллер) и для этого достаточно скопировать *только один файлик* из `core` в `local`, а система подлючик класс из `local` если он там есть, иначе и `core`.

На простом примере:

        if (file_exists('app/local/MyClass.php')) {
            include 'app/local/MyClass.php';
        }
        else {
            include 'app/core/MyClass.php';
        }
       
        $obj = new MyClass();

#7 12.03.2015 15:08:17

Re: Class Override

это всё понятно. но не надо делать из ларавеля битрикс. =)

в ларавеле если нас не устраивает стандартная реализация ларавелевского контракта, мы просто говорим контейнеру использовать нашу. если приложение должно расширяться — мы создаём контракты для классов приложения и их реализации, устанавливаем приложение как модуль композером и даём пользователю использовать свои реализации контрактов приложения вместо стандартных.

Не в сети

#8 12.03.2015 15:45:09

Xeilor

Re: Class Override

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

Признаться, я ожидал это в самом начале.  smile

Ваш пример в теории понял. Буду пробовать на практике.
Скорее всего мне нужно сделать что-то подобное: https://gist.github.com/greabock/48787baab768b519f21c
С некоторыми изменениями, конечно.

#9 13.03.2015 08:31:34

Re: Class Override

Xeilor пишет:

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

Признаться, я ожидал это в самом начале.  smile

Ваш пример в теории понял. Буду пробовать на практике.
Скорее всего мне нужно сделать что-то подобное: https://gist.github.com/greabock/48787baab768b519f21c
С некоторыми изменениями, конечно.

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

Не в сети

Подвал раздела