1. PHP / Говнокод #6373

    +155

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    /* 
      где-то в 
      /includes.php
    */
    
    function __autoload($class_name) {
        if ($class_name[0] == 'm'){
            $m = DOCROOT . APPBASE . 'Models/' . substr($class_name,1) . '.php';
            if(defined('DEBUG')) echo 'autoload model class'.$m.'<br/>';
            require_once $m;
        } elseif ($class_name[0] == 'c'){
            $c=DOCROOT . APPBASE . 'Controllers/' . substr($class_name,1) . '.php';
            if(defined('DEBUG')) echo 'autoload controller class'.$c.'<br/>';
            require_once $c;
        }
    }
    
    /* 
      где-то в 
      /Controllers/Data.php
    */
    class cData extends controller {
    /* ... */
    }
    
    
    /* 
      где-то в 
      /Models/Data.php
    */
    class mData extends model {
    /* ... */
    }

    каждый программист обязан написать свой MVC и свой ActiveRecord

    Запостил: RomaShka, 15 Апреля 2011

    Комментарии (57) RSS

    • Когда делаю что-нибудь узкоспециальное, чтобы не перепиливать какой-нибудь ORM и не воротить еще больше абстракций над фреймворком под свои узкоспециальные нужды, тоже так пишу.
      ГК или не ГК - зависит от контекста.
      Ответить
      • Когда более-менее адекватному коду приходится навязывать узкоспециальности ->
        значит в скором времени это накладут на govnokod.ru
        Ответить
    • ооо, __autoload
      говным говно
      Ответить
      • а в нем что не так?
        Ответить
        • http://ru.php.net/__autoload
          там прямо в тексте написано
          Ответить
          • Но ведь жизнеспособно?
            Ответить
            • сам PHP почему-то оказался жизнеспособным
              поэтому не показательная характеристика
              Ответить
              • может, именно поэтому пхп не так уж плох? если его так любят.
                Ответить
                • любовь зла...
                  Ответить
                • php любят такое количество пролетариата - что начинает казаться, будто php - это "язык лёгкого поведения"...
                  Ответить
        • Фо зе грейт джастис можно заюзать spl_autoload_register(), если кого-то сильно не прёт юзать глобальную магическую функцию.
          Ответить
      • когда возникает необходимость включить файл с классом и создать экземпляр, так или иначе придется это сделать или прописать эти два действия последовательно или оставить инклюд на совести класса, пусть сам свой исходник подключает автолоадом. Исходя из того, что других классов (кроме каркаса, реализующего MVC) использовать не планируется, то и решил не грузить лишним диспетчер (dispatchCAId ниже по коментам). Хотя справедливости ради следовало бы проверять, не описан ли запрашиваемый класс в загруженных ранее файлах, дабы не производить поиск файла класса в папках Controllers и Models и предусмотреть имена классов не подходящих под соглашение "mModelname"/"cControllername"
        Ответить
    • Контроллеры можно, и даже нужно, подключать из написанного маршрутизатора, который должен знать название контроллера в зависимости от ссылки.
      Ответить
      • Автор еще покажет свой диспетчер?
        Ответить
        • пжалста ))
          function dispatchCAId($controller = 'Main', $action = 'index', $id = '') {
              $controllerClassName = 'c'.$controller;
              if (class_exists($controllerClassName)) {
                  if (class_exists('cMain') && method_exists('cMain', 'appInit'))
                      obj('cMain')->appInit($controller, $action, $id);
                  obj($controllerClassName);
                  if (method_exists($controllerClassName, $action)) {
                      push('yield',pop($controllerClassName)->$action($id));
                  }
              }
          }
          Ответить
          • вот тут то и нада бы подключать файл класса нужного контроллера, а не автолоадером. А Автолоадер переделать для загрузки по неймспейсам, чтобы можно было не только модели ним грузить но и другие классы
            Ответить
            • и казалось бы, к чему тут
              obj($controllerClassName);

              а оно, оказывается, проверяет, если был создан уже объект, то возвращает его, нет - создает и возвращает )) почти синглтон )))
              function obj($classname) {
                  if (!pushed($classname)) push($classname,new $classname);
                  return pop($classname);
              }
              Ответить
              • Ну и синглтон тут не при чем,
                простая архитектура, есть ссылка например show/post/10
                есть маршрутизатор, который по show/post/:id определяет что нужно вызвать такой-то экшн такого-то контроллера, далее инклудится файл с контроллером (не автолоадером) и создается его инстанс, вызывается экшн. Внутри контроллера я могу вызывать кучу разных классов, которые должны грузиться автолоадером, при чем не только модели но и разные хелперы и т п
                Ответить
                • выше коментами http://govnokod.ru/6373#comment82038 об этом же. согласен, что в данной редакции автолоадер ограничивает создание экземпляров классов, кроме оговоренных. Когда встанет задача описывать более сложные механизмы в приложении, надо будет доработать либо диспетчер либо автолоадер
                  Ответить
    • какое очаровательное соглашение именования ))
      Ответить
      • правда? можно было бы просто все файлики-классы покидать в одну папку и не париться ))
        Ответить
        • лучше уж сделать как в Зенде или Кохане.
          Ответить
          • Да ладно, Some_Namespace_Some_Type_Class тоже далеко не лучший вариант :)
            Ответить
            • по мне, так лучше разделять не по типу, а по имени. например, юзеры, страничка профайла. Тогда файлы такие:
              /Users/Profile/Controller.php - класс Users_Profile_Controller extends Controller
              /Users/Profile/Model.php - класс Users_Profile_Model extends Model
              /Users/Profile/View.php - класс Users_Profile_View extends View
              /Users/Profile/views/main.php - основной шаблон вьюва
              /Users/Profile/views/edit.php - шаблон вьюва страницы редактирования
              /Users/Profile/js/*.js - подрубаемые жабаскрипты профайла
              /Users/Profile/css/*.css - подрубаемые стили профайла
              /Users/Profile/img/*.* - картинки, относящиеся только к профайлу.

              Так плохо?
              Ответить
              • Статику лучше не мешать, а держать отдельно. И вьюшки лучше не php, а какой-то phtml
                Ответить
                • ну хорошо, статика пойдет в /Users/Profile/res/*/*.*

                  но у меня идея в том, что бы все, относящееся к компоненту, держать вместе в папках с подпапками, вместо разброса по корневым директориям по всему проекту
                  Ответить
            • Use Some\Namespace\Some\Type;
              ...

              Type\Class

              уже можно:)
              Ответить
      • не не не, все пучком ))) зато все точно раздельно )) столько проектиков на этом велосипеде написал... сначала развивал фреймворк в сторону хелперов/хтмл-выдачи вьюхами. Потом добавил у контроллера кроме $this->renderAction($action) еще и $this->renderJSON и ушел в глубокий Мутулз и толстенные джаваскрипты. хелперы сразу стали настолько не нужны...
        Ответить
        • отдельно ))) ггг, все в двух папках )))
          а рутеры то тут есть?
          Ответить
          • мои задачи вполне решались до сих пор адресами вида /controllername/action/id и диспетчер передавал action и id нужному контроллеру
            понятно, что все, что выходит за рамки "просто id" передается через POST
            Ответить
            • нормально )
              Ответить
            • SEO рыдает
              Ответить
              • ну почему же он плачет? ведь id может быть не только числовым!
                APPBASE/Users/add/UserName
                приведет к созданию экземпляра класса cUsers и вызову его метода
                $this->add('UserName');
                Этот метод создаст пользователя и выполнит $this->renderAction('ViewName') или $this->renderJSON($data), что приведет к html- или JSON-выдаче
                Ответить
              • запрос может быть вполне ЧПУ:
                APPBASE/news/read/navodnenie-v-seo-otdele
                Ответить
                • А если я вдруг захочу поменять ссылку на что-то другое, нужно менять названия контроллеров, экшенов. Лучше написать простенький маршрутизатор, и проганять всё через него.
                  Ответить
                  • Хотя, как вариант, на .htaccess реврайтами разруливать, так раньше все делали:)
                    Ответить
                    • а не сильно нагрузит дополнительно? ведь ради гибкости надо будет еще все настройки маршрутизатора в базе хранить... лишние запросы, расходы...
                      Ответить
                      • а зачем настройки маршрутизатора в базе?
                        Ответить
                        • Можно и в базе, если планируется гибкая система, типа CMS, энивэй можно закешировать
                          Ответить
                          • если CMS, то может быть. Но кешировать, скорей всего, придется
                            Ответить
                            • Ну я не спорю, можно и в конфигах если система не CMS, как в зенде по-умолчанию. Тоже, между прочим, можно закешировать:)
                              Ответить
                              • в кохане - кешируется.
                                Ответить
                                • Да и в чистом пхп можно закешировать с помощью api мемкешей или редисов.
                                  Ответить
                                  • ну, конечно, можно.
                                    просто там об этом подумано "за нас".
                                    Ответить
                                • Ну, для меня, как для заядлого велосипедиста, не интересно то, что где-то реализовано, я предпочитаю стоя и в гамаке - реализовывать вручную. Но чувствую, что кеширование придется скоро писать...
                                  Ответить
                                  • Тоже иногда полезно:)

                                    А кеширование писать легко:
                                    $mc = new Memcaсhe;// если демон на локалхосте и 11211 порту, иначе указать куда конектитсья
                                    $mс->set('ключ', 'значение');

                                    echo $mc->get('ключ');

                                    // Только свой мемкеш не нужно писать:)
                                    Ответить
                                    • свой мемкеш - это как свой крон. Тут один товарищ пытался и такое сделать ))
                                      Ответить
                                      • не не не ))) я не пишу заново вспомогательные приблуды. Но некоторые вещи на PHP предпочитаю написать сам. Не из любви к языку (некоторые вещи на Java удобнее, да и вообще серверные языки не важны, важно взаимодействие клиентов и сервисов), а из желания лучше понять алгоритм.
                                        Ответить
                                      • Свой линукс еще осталось:)
                                        Ответить
                                        • не, у меня покруче - сын. компилился почти год. уже 5 лет аптайму )))) вроде не ГК. Хотя лет через 10 - 15 посмотрим )))
                                          Ответить
    • Это что получается, что cData он будет грузить из Controllers/Data.php, а controller - из Controllers/ontroller.php? Да, очень здорово ) Тогда бы уж обозвал его cController что-ли... ну или там cBaseController
      Ответить
      • класс baseClass, его потомки dbConnection, controller и model прописаны в /classes.php
        model реализует подобие ActiveRecord - на уровне выбрать/вставить/листать абстрагирует от БД
        controller имеет методы renderAction, renderText и renderJSON
        renderAction собирает вид /Views/controllerName/actionName.php
        методы возвращают собранный вид, не выводя его. Соответственно можно собрать выдачу нескольких контроллеров на одном общем виде...
        Ответить
      • напрямую с этих классов создавать экземпляры смысла нет. baseClass - абстрактный; controller, model, dbConnection - интерфейсы
        Ответить

    Добавить комментарий