Хранение кода в бд или собираем код по кирпичикам

    Данная статья написана Napolsky. По известным причина он не смог ее опубликовать. Если статья вам понравилась — поощрите автора известным способом.

    В этом топике я расскажу об одном разрабатываемым мною подходе в веб программировании, сердцем которого является хранение кода в базе данных. Несколько замечаний по дальнейшему тексту:
    • Под словосочетанием «код страницы» имеется ввиду исполняемый (php) код
    • Во всех вопросах, касательно производительности, имеется ввиду чистое время генерации страницы, без использования акселлераторов, систем кеширования и т д

    Как все начиналось


    Для того чтобы понять, а «зачем оно собственно надо» быстренько пройдем тот путь, который и привел меня к хранению кода в бд. Так сложилось, что свой путь в веб программировании я начинал не с написания каких-либо скриптов или модулей для существующих систем, а сразу с написания собственного движка сайта с абсолютного нуля. К этому моменту я имел двухлетний опыт программирования на C++ и, конечно же, по накатанной пытался строить свой веб движок на ООП (правда в то время в PHP от ООП было одно название :) ). В пределах разумного, я очень люблю свои «велосипеды». Особенно большие. И прежде чем воспользоваться готовым решением, всегда задаюсь вопросом «а нельзя ли написать получше?».


    Вообще написание своих велосипедов очень полезно, особенно для начинающих разработчиков (когда на первом месте стоит поднятие профессионализма, а не написание кода в отведенный срок и бюджет). Только написание собственных решений дает понимание того, как что-то устроено изнутри на самом низком уровне. А это в свою очередь дает понимание сложности, ресурсоемкости, скорости тех или иных подходов, что, в конечном счете, выливается в выбор правильного инструментария для решения задачи. Например, в университете нас заставляли писать свои pushback'и для массивов, чтобы мы не забывали, что за казалось бы простыми и тривиальными вещами может скрываться что-то гораздо большее.

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

    Не задумывались ли вы над количеством «мертвого» кода на странице? На самом деле его количество как правило в 7-15 раз превышает количество кода, который действительно будет выполнен при обращении к странице. Возьмите к примеру класс комментариев. В нем будут методы render(), delete(), edit(), add(), compress(), answer() и т д. При этом за 1 выполнение скрипта как правило будет вызван всего 1 из этих методов (delete — при удалении, edit — при редактировании и т д), а остальные заведомо не будут вызываться. Вот и считайте, сколько такого лишнего кода набежит на странице.

    По началу я пытался проводить оптимизацию, «разрезая» и «склеивая» большие библиотеки или классы под нужды различных страниц, уменьшая таким образом количество инклудов и «мертвого» кода. Но это, конечно же, тупиковый путь. Шло время. Проекты, написанные на этом движке (царство им небесное :) ) становились все больше. Вместе с этим росло количество и размеры подключаемого кода, а вместе с ними и время генерации страниц. Я начал все чаще думать о том, как избавиться от «мертвого» кода. И тут меня посетила смелая, показавшайся даже бредовой мысль. А что если…

    Рождение идеи


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

    Путь воина


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

    1 Хранение кирпичиков

    Тут все просто и понятно: каждая отдельная функция, класс (а лучше даже метод класса), контроллер модуля, представление модуля и т д — это отдельная строка в бд. Например в простейшем случае таблица может иметь вид id|code|name|componentType (где componentType — тип кирпичика(функция, класс, модуль..))

    2 Хранение зависимостей

    Так как код одного кирпичика может вызывать другой кирпичик (например зависимости типа функция-функция, модуль-функция или даже страница-модуль), то нужно хранить репликации. Сделать это можно с помощью таблицы репликаций, которая, в простейшем случае, имеет вид id|parentId|childId. Таким образом мы решаем проблему правильного сбора «кирпичиков» для вложенных конструкций:

    function A()
    {
    B();
    }



    В этом случае в таблице репликаций будет запись, что А «нуждается» в B. Следовательно при подключении А автоматом будет подключена B.
    3 генерация кода страниц

    Хорошо, у нас есть все кирпичики, но как из них собрать код страницы? Для этого, конечно же, нужен отдельный скрипт, который будет собирать из наших бесполезных самих по себе «кирпичиков» работоспособный код страницы. Назовем этот скрипт Codegen. Каким он будет зависит от того, что и как вы хотите собрать из своих «кирпичиков». В этом заключается одна из сильных сторон подхода: из одних и тех же кирпичиков вы можете собирать принципиально разные коды страниц. Можете даже собрать «классическую» архитектуру. Во избежание недопониманий: генерация кода страницы годегеном происходит 1 раз, а не при каждом обращении к странице.

    На выходе получаем монолитный сгенерированный код для каждой страницы. При этом, в зависимости от Codegen, возможно как сразу получать весь необходимый код для страницы, так и подгружать некоторые части во время выполнения страницы (посредством eval из базы).

    Пожинаем плоды


    Таким образом мы можем достичь следущих главных результатов:
    — полное отсутствие инклудов на странице
    — сведение «мертвого» кода к нулю


    Вот что это дало в моем конкретном случае:
    • количество кода сократилось с 12000-14000 до 1500-2000 строк на странице
    • количество инклудов на странице сократилось с 16-22 до 0
    • Время генерации страницы сократилось с 0.25-0.3 до 0.04-0.05 секунды (~600%. Напоминаю, что это без кеша в классике. с кешом цифра будет поменьше)


    За и против


    Рассмотрим подробно плюсы и минусы идеологии хранения кода в бд.

    Минусы
    -Невозможность полноценно использовать IDE.Как следствие.Так как код хранится в бд, то для его редактирование/написание должен быть свой интерфейс(я например использую веб интерфейс). Как это примерно выглядит, можно посмотреть здесь. Вообще для меня особых неудобств это никогда не представляло. Все необходимые мне инструменты (подсветка кода, горячие клавиши..) могу быть легко реализованы на веб интерфейсе. Для тех, кому нужно большее, полноценной замены IDE все же нет.

    -Сложность отладки. Вытекает из первого пункта. Осложняется тем, что если вы захотите какой-то код динамически загружать из бд и выполнять его функцией eval, то найти ошибку может быть действительно непросто.

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

    В этом топике так же были указаны еще минусы с которыми я попробую поспорить:

    исходники это файлы, в итоге с ними можно делать любые файловые операции

    Честно сказать, я не представляю что можно такого сделать с файлом, чего нельзя будет сделать со строкой в бд. Наоборот, строка в бд — куда более гибкая вещь чем файл.
    Распостранение/backup/update

    … делается с дампом sql(один файл) намного проще и быстрее, чем с большим количеством файлов при классике.
    Безопасность, прямой код инжекшн в случае проблем

    Проблема Тоже кажется надуманной. Сделайте разных пользователи для баз движка и баз сайта.
    Бекап, представляете, бывает так, что их не делают, и тогда любые ваши «кастомизации» on site коту под хвост если сломаеться база

    Для работы движка (после того как сработает кодеген) бд уже не нужна. То есть сайт может работать и при выключенной бд.

    Плюсы
    Скорость. Для меня это стало решающим фактором. Впервые, когда я сравнил скорость на старом «классическом» движке и на новом, я был потрясен результатом.
    Гибкость на макроуровне. Чем из наиболее мелких и простых частей состоит конструктор, тем более сложные вещи можно из него собрать.
    Атрибуты у частей кода. Так как наши кирпичики хранятся в таблице, то каждому из них мы можем задавать какие либо атрибуты, посредством добавления соответствующего поля. Это действительно очень важная особенность, открывающая новые просторы в разработке.
    Возможность проводить любую обработку исполняемого кода перед его выполнением. Как вы помните, весь код у нас проходит через codegen, а следовательно в нем мы можем его модифицировать произвольным образом. Например, применять языковые пакеты на стадии генерации кода страниц. Или еще таким образом: если в коде часто встречается какая-нибудь строка, например
    if(!$user->isAdmin()) {ErrorLog('нехватает прав'); return;}


    Вы можете вместо нее писать везде коротко
    _CHECKADMIN


    А на стадии генерации просто заменять его на нужный вам код. Так что предварительная обработка кода тоже дает простор для фантазии программиста.

    Заключение


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

    P.S. Если возникнет интерес, я могу продолжить эту тему описанием своей реализации предложенного подхода.
    Поделиться публикацией

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 270

      +5
      Зачем хранить в бд то, что лучше хранить в файлах? Уже давно использую магический метод __call для решения данной задачи, все методы хранятся в отдельных файлах, при условии что код можно перед использованием копироваться в рамдрайв, что существенно повысит скорость обращения к файлам, да и редактировать код при хранении в файлах в разы проще. А хранение кода в БД чревато тем, что невозможно использовать различные компиляторы и кэшеры исполняемого кода, а include в свою очередь быстрее отработает чем eval и закэшируется исполняемый код.
        +2
        >>Зачем хранить в бд то, что лучше хранить в файлах?
        для этого в статье отведен пункт «плюсы» )

        >> невозможно использовать различные компиляторы и кэшеры исполняемого кода
        Вы немного не поняли. В бд хранятся только кирпичики. Сам код страницы собирается кодегеном. поэтому ничто не мешает вам использовать кешеры либо что то еще

        >>include в свою очередь быстрее отработает чем eval
        Совсем необязательно использовать eval. Codegen вполне может собрать такой код, который не будет нуждаться в загрузке кода «на лету» из бд.
          +2
          Плюсы конечно тут хороши. Слов нет.

          Но есть ряд минусов, которые опущены в статье:
          1. огрмный размер кеша (если конечно это не домашная страничка какого-нить мальчика из неизвестной деревни.)
          2. как уникально генерить ключ для кеша? хорошо если проект маленьки, а если большой и активноразвивающийся.
          3. вообще если из вашей идеи убрать БД — уже будет лучше.
          4. дебаг усложняется при использовании __call, а при использовании еще и БД, вообще бэктрейсы будут веселые.

          вот пример одного крупного проекта:
          Кол-во файлов движка — ~4089
          Кол-во строк в этих файлах — 652091
          В среднем по 160 строк на файл.
          Вес: 43 метра
          Нагрузка — так, небольшой highload. (~150qps)

          Я даже не представляю себе как оценить размер необходиомого диска для этого проекта, чтоб на нем мог храниться кеш всех страниц.

          Заигрались с идеями, ИМХО…

          А за нестандартное мышление только респект! Направление верное, но надо шкурить…
            +1
            ААА… и еще забыл.
            нужен же еще и какой-то маленький файл starter.php, который будет исходя из REQUEST_URI, POST, GET и прочего составлять ключ для кеша и в случае отсутсвия кеша — бежать генерить… и это должен быть какой-то отдельный скрипт от движка.
              0
              Извините, но я совершенно не понял про кеш — что тут с кешем такого страшного должно случиться при таком подходе?
                +1
                вы пробовали оценить сколько у вас вариаций загрузки различного кода?
                например, хотя бы, в зависимости от REQUEST_URI
              +1
              Извините за дурацкий вопос, но как вы умудрились написать 43 Мб кода??? Куда столько? У меня есть серьезные подозрения что большая часть такого кода — сплошной копипастинг (например, модули, у которых 80% кода одинаково).
                0
                Да ну? :) у меня есть серьезные подозрения что в этом коде включены как минимум какой-нибудь фреймворк и ОРМ.

                Тем не менее, проект на 3-5мб кода я вполне себе представляю :) без всякого копипастинга :)
                  0
                  этот код писала команда программистов в течение 4-5 лет.
                  Что тут удивительного?
                  Некоторые алгоритмы повторяются из библиотеки в библиотеку, из модуля в модуль, но только с целью ускорения кода… Система постоянно развивается. Ее не возможно было спланировать всю целиком. Не исключаю, что 10-20% этого кода уже отмер (тоесть не используется по факту, но он рабочий).

                  Кстати мы когда то тоже задались этой проблемой, что для отображения списка скажем вот такой же странички как эта от модуля необходимо лишь получить статью, и комментарии.
                  Но кроме этого в модуле были еще и другие состояния и блоки… и они постоянно грузились…
                  Было предпринято наипростейшее решение — сделать все состояния, обработчики и просто методы в модуле через magiс метод __call(). Размер загружаемого кода резко сократился…
                    0
                    Хм, я негативно отношусь к magic методам.
                    В свое время экспериментировал с самонастраивающимися классами для данных.

                    Да, удобно, но при этом реально медленнее раз 10-30.
                      0
                      Интересно посмотреть на замер…
                      какая разница в нагрузке на CPU при интерпретации файла 150-200Кб и двух-трех файлов размером ~5Кб? Замеряли?
                        0
                        Нет нагрузку CPU не мерял.

                        Мерял лишь время выборки из БД и заполнения коллекций.
                        Даже не столько мерял, сколько столкнулся с этим уже в работе :)

                        Если в коллекции используются конкретные модели с заранее указанной структурой,
                        class box {
                        public $a;

                        public $z;
                        }

                        то время порядка 0.5-0.7с всего лишь для нескольких тысяч объектов.

                        А вот когда использовалась «универсальная» модель, которая строила себя по метаданным таблицы, а затем предоставляла доступ через magic методы к своим полям и методам,

                        class unibox {
                        public function __get() {}
                        public function __set() {}
                        public function __call() {}
                        }

                        то система задумывалась на 5-15с над теми же данными.

                        Уточнение в моделях было порядка 10-30 полей данных.

                        Получение служебной информации по таблице всего лишь +1 несложный запрос.
                        Таким образом magic-методы вызывались порядка 30-200т раз и именно это вызывало замедление работы скрипта с 0.5с до 15с

                        P.S. цифры несколько неточны, писал по памяти, но порядок такой.
                          0
                          мы немного о разном…
                          мы код прячем за _call метод и вызываем — один раз.
                          а вы кучу данных и обращения к ним за методы __get __set и вызывает много раз.
                            0
                            Мы все об одном и том же.
                            Когдо magic метод вызывается 1-2 раза — все отлично. А вот если оно вызывается много раз…

                            При частом использовании __call вы таки вызовете с его помощью какой-нибудь метод где-нибудь в цикле. И вот гложут меня смутные подозрения (потому как не проверял), что __call не быстрее __get/__set и у вас будут те же грабли :)
                              0
                              аа… ну дак именно по этой причине за __call вынесенны ТОЛЬКО состояния и обработчики, которые занимают основную часть сложного модуля. (я об этом писал)
                              А часто используемые методы написаны прям в классе.
                              Тут я с вами полностью согласен.
                +1
                Так как уж Вы процитировали меня в своём топике, выскажусь.

                «Мёртвый код»? Сударь, ваши PHP скрипты уже хостятся в огромной матрёшке «мёртвого кода» ( ОС -> Вебсервер -> PHP интерпритатор -> СУБД ) из «возможностей» которых используеться 2-3%. Может тогда резонно свою ОС написать, под сайт?

                Я не могу сейчас точно сказать как решена проблема ускорения парсинга PHP, просто потому, что им не занимаюсь, но на 99% уверен, что продукты Zend'а решают эту проблему, прогоните код через оптимизатор и сравните результаты. Что касается .NET и Java описанная вами «проблема» для них вообще не актуальна.

                Увеличение быстродействия — очень спорный момент, без тестов ничего не говорит.
                Все ваши плюсы можно без мазохизма имплементировать классическим ООП.

                Скину ка я сюда полную версию минусов с прошлого поста:

                — IDE работают с файлами
                — исходники это файлы, в итоге с ними можно делать любые файловые операции
                — поддержка, наверняка человек пришедший после вас на такой проект сочтёт вас идиотом
                — производительность, в большинстве случаев скрипты \ рантаймы могут применять какие-либо оптимизации, включая кеш, а ваши BLOB'ы уж никак сюда не впишуться
                — Распостранение, ох некрасиво таскать SQL дампы туда — сюда
                — Безопасность, прямой код инжекшн в случае проблем
                — Бекап, представляете, бывает так, что их не делают, и тогда любые ваши «кастомизации» on site коту под хвост если сломаеться база
                — Отладка отвратительна
                — Нормальная поддержка ОПП, — не возможна
                — Очень вероятны скрытые дефекты при работе с shared statеом
                — Eval ВСЕГДА дефакто будет медленее обычного выполнения
                — Версии \ бранчи \ мерджи \ итерации не возможны
                — Runtime migration, при переходе на новый рантайм ошибки совместимости не будут выловлены вовремя

                  +1
                  Многие ваши минусы можно снять одним махом:
                  — нормальной практикой для серьезных проектов является использование двух версий кода — для разработчиков и для непосредственной работы. Причем последняя создается в автоматическом режиме из первой. Таким образом имеем версию для разработчиков — кучу файлов, отладку, комментарии, отладочный код, расширенные сообщения для ошибок и пр. пр. А далее автоматом создается версия для настоящей работы — код шифруется от злобных хакеров :-), пакуется, вырезаются коментарии, распихивается по базам, в общем все что требуется для конкретного проекта. Главное в этом, что процесс делается автоматически (и эта часть должна быть надежна на все 100).
                    0
                    Она не будет надежна на все 100.
                    И разработчики будут допускать ошибки, а тестировщики будут их пропускать.

                    Как много программистов сейчас могут дебажить код под дампу памяти? А ведь именно это вам придется делать, когда прийдет фидбек об ошибке с вашего зашифрованного проекта. Причем ошибка у вас не будет вопроизводится.

                    P.S. попробуйте для развлечения подебажить запакованый javascript получите огромный оргазм…
                    если вам таки удастся продебажить или вам все же дадут в итоге незапакованную версию кода :)
                      0
                      Во-о-о-от, вы уже начинаете соглашаться :-)
                      То что вы описали, это уже попадает под исключительные случаи, из-за дополнительных условий типа
                      — ошибка не воспроизводится на версии для разработчиков. А это малая часть. И поверьте, мне приходилось дебажить упакованные скрипты и исправлять ошибки. В недавнем случае ошибка была как раз в процессе генерации рабочей версии. Но единичные случаи такого рода никак не приводят к отказу от использования описанного процесса работы над большим проектом и генерации рабочей версии из девелоперской.
                      Мир десктопного и серверного программного обеспечения работает по такой схеме. Вы же не поставляете клиентам версии со всей отладочной требухой, с исходниками и с отладочной информацией в исполняемых файлах. Вы надеетесь на 100% надежность компилятора, что он корректно переведет ваш код в исполняемый. И на деле случаются ошибки трансляторов-компиляторов влияют на работу программы. Но в 99.999% случаев все работает как задумано и ошибки находятся в логике программы и были пропущены тестировщиками.
                        +1
                        Хм, а я разве несоглашался?

                        Я указал вам на те подводные камни с которыми вы столкнетесь. И, несмотря на то, что я могу дебажить по дампу, удовольствия от этого мало. Хотя, конечно, дело привычки, можно и бинарный код, и packed javascript научится читать как обычный листинг.

                        P.S. и, да, я предпочитаю в продакшене незапакованый код, если это не касается тех частей которые можно быстро и безболезненно подменить отдельно от всей системы (как обычно и бывает, к примеру, с javascript).
                +1
                Может быть автор немного опередил своё время? :) На самом деле, нет таких вещей, которые лучше хранить в файлах, чем в базах данных (особенно заточенных под характер данных). Файловая система — это «недобаза данных». Чрезвычайно быстрая лишь в силу своей упрощённости.

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

                Возможно, не следовало сразу вываливать на неподготовленные головы две «технологии» одновременно — «кирпичики» и «код в БД». Хранение кирпичиков в файлах, даже вместе с атрибутами (в комментах или индексных файлах) было вполне возможно.
                  0
                  В предложенном подходе действительно много принципиальных отличий, что затрудняет понимание не только всего процесса, но и преимуществ подхода. Только прочитав теорию, конечно же нельзя понять, как это работает на практике
                0
                есть несколько вопросов

                а как написать блочные, нагрузочные, модульные и другие тесты при таком подходе? доставать код прямо из базы данных?

                профилировали ли вы из-за чего произошло уменьшение генерации кода — потому что стало меньше невыполняемого кода? а мне лично всегда казалось что одним из узких мест является именно база данных. хотелось бы увидеть данные профилирования
                  +1
                  еще вопрос — как себя ведет эта концепция при высоких нагрузках? не загинается ли база данных от запросов по доставанию кода который потом еще сделает сколько то там запросов к ней?
                    +3
                    Уменьшение строк кода на страницу происходит из за того, что мы полностью исключаем из нее код, который заведомо не может быть выполнен.
                    База данных не является здесь узким местом. Я выделил жирным в статье, и еще раз повторю, что при загрузке страницы пользователем, мы можем вообще не обращаться к нашей бд. Мы обращаемся к ней лишь 1 раз, когда генерируем новые коды страниц (например при изменении кода какого то модуля или еще чего либо)
                      0
                      понял, мне кажется таким подходом вы просто создаете себе дополнительные проблемы при тестировании кода
                        +1
                        Рискую сейчас сказать глупость, но разве PHP не использует т. н. «ленивые вычисления» (http://ru.wikipedia.org/wiki/Ленивые_вычисления). И если использует, то не наплевать ли PHP на «мертвый» код?
                          +1
                          Синтаксический разбор исходного кода происходит в любом случае, независимо от востребованности того или иного куска кода. А «ленивость вычислений» — это немножко другое ;-)
                            0
                            А, вот о чем речь! Видимо неправильно понял суть статьи. Ну, экономить на синтаксическом разборе = экономить на спичках ИМХО. Кроме того разбор все равно будет: надо ведь разобрать кодеген, а затем разобрать чего он там нагенерил. Так что будет ли ощутимый плюс во времени — большой вопрос. Кроме того запрос в базу тоже выполняется некоторое время.
                      +4
                      а чем плох __autoload?
                        0
                        Очень хорош, кстати, если пишем на классах.

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

                        Плюсы:
                        1) Автолоад в дальнейшем в самом простейшем случае состоять может из одной строки «require(имя_класса.class.php)». По-хорошему, конечно, нужна и проверка ентого файла на существование перед подключением
                        2) внутри classes я могу создать какую угодно структуру каталогов, если этого не надо, то и подкаталоги сканить не надо ))

                        Минусы:
                        1) каждый раз рекурсивно сканить каталог. Ну если напрягает такое положение дел, получившуюся строку path можно закэшировать, на продакшне — чуть ли не навсегда))
                        2) не знаю.

                        По мне так это вообще шик: не надо ничего подключать, просто создаешь экземпляр класса и вуаля — он создается безо всяких подключений файлов. И никаких баз.

                        У баз, конечно, есть килограммы преимуществ перед обычной файловой структурой. Но в этом ли случае их использовать, автор статьи?)))
                          0
                          По-хорошему, конечно, нужна и проверка ентого файла на существование перед подключением
                          а, собственно, зачем? такая проверка есть внутри require, который, в случае чего, выкинет fatal error и на этом выполнение программы закончится.
                            0
                            ну вот поэтому она и нужна, эта проверка )) чтобы никаких фатал ерроров пользователи не видели, незачем им это))

                            Да и вообще, в продакшне проверка файла подключаемого класса на существование — из разряда «проверить что 3=3» — ясен пень, что ну куда ж файл то денется?))
                              +1
                              чтобы никаких фатал ерроров пользователи не видели

                              set_error_handler прекрасно справляется с этой задачей. двойные проверки плодить незачем, по-моему.
                                –1
                                Т.к. require генерит E_FATAL при отсутствии файла, то у Вас не получится отловить ошибку с помощью set_error_handler. «The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.» © www.php.net
                                  +1
                                  Выполните у себя код:

                                  <?php
                                  
                                  function errorHandler($no, $str, $file, $line)
                                  {
                                  	die("gotcha!");
                                  }
                                  
                                  set_error_handler("errorHandler");
                                  
                                  require "no_such_file.php";
                                  
                                  ?>
                                  
                                    0
                                    Эх, ошибся. Извините.
                                      0
                                      Вас не за что извинять, судя по всему ошибка в документации (судя по ней, приведенный код работать не должен).

                                      Вы ошиблись только в типе ошибки require — он выкидывает E_ERROR.
                                0
                                Да и вообще, в продакшне проверка файла подключаемого класса на существование — из разряда «проверить что 3=3» — ясен пень, что ну куда ж файл то денется?))

                                именно! :) поэтому и незачем при каждом исполнении кода проверять есть ли файл по два раза.
                                  0
                                  ну вообще обычно делается 2 режима (константа) DEV|PROD вот в деве все возможны проверки в основном для понимания ошибки разработчиком в PROD по минимуму — несколько увеличивается скорость
                                  принцип такой, если в DEV у разработчка работает то и в PROD должно но в PROD все сообщения об ошибках отключаются полубому (ведь правда? ;))
                                0
                                Я думаю, что проекты, где файловые операции сильно влияют на производительность стоят opcode-кешеры, соотвественно, ничего рекурсивно сканить не надо.
                                  0
                                  ого!!!.. по моему вы не используете настоящие преимущества __autoload
                                    0
                                    какие, например?)
                                      +1
                                      Например один раз сканить папку с классами и кешировать результат. В __autoload банально проверять запись по ключу(имя класса) и делать require.

                                      ps. require вне __autoload делать не нужно. зачем тогда собственно нужен этот _autoload?
                                        0
                                        «При начале работы скрипта в переменную окружения path ini_set'ом загоняем classes и все ее подпапки.»
                                        — лишняя нагрузка на сервер

                                        «Автолоад в дальнейшем в самом простейшем случае состоять может из одной строки «require(имя_класса.class.php)».»
                                        — а как на счет коллизий?
                                        это произойдет когда встречаются два файла с одинаковыми именами и но эти файлы находятся в разных каталогах.
                                        вам придется следить за уникальностью имен всех файлов.

                                        не вижу смысла запускать рекурсию по каталогам и добавлять все найденные пути в include_path когда само имя класса говорит где искать.
                                        пример: calss DB_Table_Row — лежит в фале DB/Table/Row.class.php
                                        при $row = DB_Table_Row(); — autoload-у не составит труда найти класс
                                          –1
                                          «Лишняя нагрузка» при сканировании структуры каталогов может быть по сути один раз, потом результат на продакшне кэшируется, хоть навсегда. Я писал это в комменте выше.

                                          какие коллизии в именовании файлов?? Файлы именуются, например, имя_класса.class.php. Значит, имена классов одинаковые?? А чтобы не было коллизий с другими файлами, которые не в classes, надо файлам классов давать префикс/суффикс

                                          — лежит в файле DB/Table/Row.class.php

                                          Ну до таких извращений и такой мегавложенности папок в хранении классов доходить не собираюсь, если честно. Это будет организация хранения ради организации хранения, а не упрощения разработки и работы
                                            0
                                            Хм, а это не извращение. Это нормальная организация для проекта где больше 2-3х классов.

                                            Когда у меня одних структур три десятка, да моделей штук 8, да драйвера к разным устройствам вывода…

                                            Держать все в одной папке? Увольте.
                                              –1
                                              То, что Вы видите, называется дерево комментариев. И в ней разворачивается беседа. Ознакомились ли Вы с ней? Я бы сказал, что нет.

                                              — Держать все в одной папке?
                                              как я писал выше (http://habrahabr.ru/blogs/webdev/66309/#comment_1863308)
                                              > 2) внутри classes я могу создать какую угодно структуру каталогов,
                                              >если этого не надо, то и подкаталоги сканить не надо ))

                                              Но и заниматься чем-то вроде DB/Table/Row/Field/ — не понимаю зачем. Или если есть возможность, то надо истерично заюзать ее? )) Вполне хватить может 2-3х уровней, ИМХО. Но не в одной папке))
                                                +1
                                                То что вы пишите называется «смотрю в книгу вижу...»

                                                Вот смотрите:

                                                DB/Table/Abstract.php
                                                DB/Table/Mysql.php
                                                DB/Table/Postgresql.php

                                                Feed/Abstract.php
                                                Feed/RSS.php
                                                Feed/Atom.php

                                                Причем, заметьте подкаталоги сканить не надо вообще. Имя класса фактически путь к нему.

                                                Предложите свою структуру для хранения внутри вашего «classes», и рассмотрим преимущества и недостатки в сравнении с этим «извращенным», как вы выразились, методом.
                                                  +1
                                                  вроде в Zend Framework так реализовано?
                                                    0
                                                    так точно.
                                      0
                                      Autoload —фигня. Он провоцирует на использование невменяемых названий типа Zend_DB_Table_Abstract_Class — ну не бред ли? Руки же отвалятся писать.

                                      Кроме того, создавать объекты через new не всегда правильно, например объкт подключения к БД должен быть один, или там модель можно ичпользовать повторно а не создавать заново.

                                      Поэтому в хорошем фреймворке должен быть объект, генерирующий (или достающий из кеша, или еще откуда-нибудь) то, что его попросят. Простейший пример такого объекта есть в codeIgniter — $this->load->model('name'). такой поход во-первых не заставляет нас писать невменяемые имена классов, во-вторых не связывает местоположения файла класса с структурой файлов, в-третьих позволяет кешировать/переиспользовать ранее созданные объекты.

                                      Все остальные решения имхо — фигня с кучей недостатков.

                                        0
                                        1. Названия будут такими, какими Вы захотите. PHPшный автолоад не диктует сам по себе структуру каталогов в отличие от, скажем, явы и питона. Кроме того, сейчас можно использовать неймспейсы (чтобы руки не отваливались).

                                        2. Кто мешает использовать синглтоны? Абсолютно никто не мешает…

                                        3. Один из возможных подходов. Но не единственный.

                                        4. Категоричные суждения редко бывают истиными:)
                                          –1
                                          > 1. Названия будут такими, какими Вы захотите. PHPшный автолоад не диктует сам по себе структуру каталогов в отличие от, скажем, явы и питона. Кроме того, сейчас можно использовать неймспейсы (чтобы руки не отваливались).

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

                                          > 2. Кто мешает использовать синглтоны? Абсолютно никто не мешает…

                                          А в чем смысл раскидывать кучу синглтонов и писать мудреный autoload-код, если можно все это собрать в 1 специально предназначенном объекте? А когда кеширование сериализованных объектов (к примеру) будете добавлять, тоже всюду проходиться?

                                          Ну не знаю в общем.
                                          0
                                          А вот для того чтобы руки не отваливались используйте «нормальные» адекватные IDE с кошерным автокомплитом :)
                                          И читать такое несколько удобнее, чем именя а-ля pcntl_wtermsig()

                                          P.S. В редакторах типа vim тоже обычно бывыет автокомплит. Вот только он некошерный :) Потому что не контекстный.
                                          Он автоматически не подтянет методы касающиеся только контекста.
                                            0
                                            $this->load->model('name')

                                            а что с подсветкой будет?
                                              0
                                              С автодополнением? У меня его все равно нет, мне по барабану :) Но по моему ради автодополнения менять архитектуру — это немного… того… странно.
                                        +19
                                        Вы предлагаете кэшировать код вместо результатов?.. Ну я даже не знаю что вам на это сказать…

                                        А от повторения кода избавляет как минимум использование функций (вроде checkAdmin() написать не сложнее _CHECKADMIN), да и вообще современные парадигмы проектирования приложений решают эту проблему.

                                        P.S. Попадись мне приложение куски кода которого лежат в базе — я бы поседел.
                                          0
                                          Я ни в коем разе не предлагаю кешировать код вместо результатов.Где вы про это прочитали? )
                                          _CHECKADMIN был просто приведен для примера, чтобы можно было уловить суть обработки кода перед исполнением.
                                          Знаете, попадись мне приложение с кодом в базе года три назад, я бы тоже наверное поседел =)
                                          0
                                          А какой хостинг вы используете? На виртуалке обычно работа (нстройка) с БД сильно урезана. В том плане что рассчитана БД на какие-то более-менее типовые задачи.

                                          Насколько ваш метод требователен к настройкам БД?
                                            0
                                            Подойдет любая реляционная бд со стандартными настройками. Никаких особых настроек не требуется, потому что задачи здесь для нее ставятся тоже самые что ни на есть типовые :)
                                            +27
                                            Началось, лучще хуже.
                                            Статья очень сильно заставляет задуматься и убедиться что:
                                            1. Альтернатива есть всегда.
                                            2. Умение смотреть под разным углом — это плюс программисту.
                                            3. Всегда есть место открытиям новшествам и улучшениям.
                                            4. Месье знает толк в извращениях.
                                            • НЛО прилетело и опубликовало эту надпись здесь
                                              +4
                                              Заголовок, думается мне не совсем верный. Причем тут, собственно, БД вообще?
                                              На входе имеем «классический» код, который преобразуется в «кирпичики» в базе, из которых «собирается» сугубо исполняемый код для каждой страницы. Ну использована была БД в этом процессе, ну и что? :) На продакшен можно выкладывать уже «собранный» код, как я понимаю?

                                              И опять же, не понятна ремарка насчет средств разработки. Зачем Вам средства разработки на продакшене? Пишите все в любимой IDE, перегоняйте в кирпичи, потом через Codegen в собранный код, и назовите этот процесс «компиляцией» :) Причем, выделенное курсивом, вообще говоря, может (и должна) делать одна программа.

                                              Либо я что-то не так понял.
                                                0
                                                И еще, чтобы избежать недопониманий.
                                                Мне Ваш подход не нравится по ряду причин, но обсудить было бы интересно.
                                                И очень подозрительны цифры по ускорению кода. У Вас получается прирост производительности в 6 раз, при сокращении общего объема кода в 6 раз, при том, что объем непосредственно выполняемого кода остался прежним. Можно подумать, что все время у интерпретатора уходит на прочтение кода, а исполняется он мгновенно :)
                                                  +1
                                                  много времени уходит на инклуды файлов при отсутствии их кеширования. Но на прочтении и парсинге кода тоже получается экономия
                                                    +1
                                                    «Но на прочтении и парсинге кода тоже получается экономия „

                                                    А вы не забыли использовать echo вместо print и ординарные кавычки вместо двойных? Тоже ведь экономия… правда на спичках :)
                                                      0
                                                      Извините меня конечно, но если экономия на парсинге кода, это экономия на спичках, то зачем для PHP есть 3(!) кэшера байт-кода… Вам это странным и противоречащим вашим словам не кажется? + Всё зависит от файлов, иногда приходиться инклудить очень большие сгенерированные таблицы с данными, для оптимизации во время выполнения…
                                                  0
                                                  немного не так. Мы имели «классический» код и преобразовывали его в «кирпичики» только один раз — когда осуществляли переход от «классической» архитектуры. Сейчас уже вся работа идет напрямую с кирпичиками. На продакшене не всегда можно обойтись без бд с кирпичиками — хотя и можно собирать весь код заранее, чтобы потом не использовать бд, все же удобнее оказалось использовать Codegen, который часть кода выполняет из базы «на лету». (например я заранее собираю в страницу все, кроме представлений, а их загружаю уже «на лету» в зависимости, например, от скина пользователя)
                                                    0
                                                    понятно.
                                                    по-моему зацикленность именно на объеме кода у Вас излишне гипертрофирована :)
                                                    внизу mx2000 выразил то, что я думал, Вы и реализовали.
                                                    ну не вериться мне, что подключение к базе и выборка зависимостей это быстрее, чем исполнение уже подключенного кода, пусть даже часть из него «мертвого».

                                                    и что Вы подразумеваете под представлениями? я как-то не улавливаю связь между представлением (как классом) и скином пользователя. как мне видится, это просто разные шаблоны одного представления.
                                                      +2
                                                      Хорошо, если эта тема получит продолжение, то я обязательно специально приведу более подробные и разностороннии цифры по сравнению производительности.
                                                      Да, вам правильно видится — просто разные шаблоны
                                                  +1
                                                  ;) деплоймент превращается в сказку, указал фтп, вбил в настройках проекта логины и пароли для доступа к базе или внешним сервисами, нажал кнопочку Gen & Upload и вуаля.
                                                  Кстати сразу видно что месье сишник.
                                                  Подход интересен, было бы интересно взглянуть на codegen, там должна быть очень интересная структура.
                                                  Кстати на основе этой системы можно вполне сделать сервис собери сайт.
                                                  Идея интересная. Ждем продолжения и подробностей.
                                                    +2
                                                    А тем представьте еще такую вещь, если на этой базе выпустить CMS или просто пустить в массы движок:
                                                    Все пользователи движка могут коннектиться при годегене (и/или при загрузке кода «на лету») к _одной_ централизованной базе. Таким образом у всех пользователей будет последняя версия движка практически в режиме online. Или же можно просто создать что-то вроде репозитория, где будут находиться последнии версии «кирпичиков».
                                                      0
                                                      Но ведь и обновлять им после этого все придется.А я думаю перезаливка пусть и оптимизированных сгенерированных файлов будет не очень быстра. Опять же отслеживание совместимости между кирпичиками разных версий. Скорей всего будут отдельные репозитории. ^_^
                                                      Но идея интересная. Хотя мне кажется что такая CMS будет требовать несколько извращенного подхода к использованию
                                                        +2
                                                        так в том то и суть, что пользователю не придется ничего заливать и ничего не придется самому обновлять! пользователь будет иметь коннект ко внешней базе, где будут лежать обновления. Codegen коннектиться к этой базе и генерирует пользователю код «первой свежести». При том запуск кодегена может происходить автоматически, при обнаружении обновлений. И никаких вам закачек файлов или чего то подобного.

                                                        Про контроль версий. Не забывайте, что у кирпичиков есть атрибуты. На их основе нет никакой проблемы сделать контроль версий
                                                          +2
                                                          > На их основе нет никакой проблемы сделать контроль версий

                                                          Ой, Вы таки сначала сделайте, а потом говорите…
                                                            +2
                                                            Нет ничего плохого в том, что автор выносит на обсуждение идеи и планы (даже мечты), вполне доказав, что способен реализовать нечто подобное. Нельзя же чесать под одну гребёнку болтунов и прожектёров, и людей дела.
                                                              +1
                                                              Мечтать мы тут все умеем, делать — не все, но многие. Так что оценить чужой прожект, в общем, можем.

                                                              Тем более, что _сделанного_ автором мы всё-таки не видим, топик представляет собой просто декларацию о намерениях. Что реально из этого реализовано и как оно работает — никто не знает. Как с этим работать кому-то кроме автора — мы тоже не знаем. Минусы подхода очевидны (см. коммент от murr), автор их никак не комментирует и т. д. А говорить, что на атрибутах нет никакой проблемы построить контроль версий, ИМХО, может говорить только тот, кто никогда не строил контроля версий.
                                                                0
                                                                Автор вроде бы недвусмысленно, несколько раз, дал понять, что это не пустые намерения. Есть реализация. Не всего, о чём говориться, но основа есть. И рубить сплеча «ты сначала сделай, потом говори» — незаслуженно грубовато в данном конкретном случае.

                                                                Эпидемия какая-то на аргументы «вы этого никогда не делали, вы не знаете как это делать»… Просто скажите конкретно, в чём проблема с атрибутами. Нет настроения говорить по делу — может не стоит и начинать?

                                                                Кстати, murr высказался хоть и «в гневе», но всё же довольно конкретно. Позволю себе упростить его аргументы, не погрешив против истины, надеюсь:

                                                                1) Не пытайтесь усовершенствовать язык, не нравится — меняйте на другой.
                                                                2) Не ускоряйте то, что нельзя ускорить.
                                                                3) Ориентируйтесь на самое слабое звено, на самого тупого разработчика.

                                                                Хоть вопросы и не ко мне, на раз уж вы сами кивнули на этот коммент…

                                                                1) История изобретения языков знает удачные примеры, когда новый язык лишь немного усовершенствовал старый, пользовался его же компилятором, и лишь со временем для него писали свой собственный.
                                                                2) Автор пишет, что ускорение есть, даже по сравнению с кешированием. И это даже на очень молодой реализации. Глупо после этого утверждать, что чёрное — это белое, и ускорения там нет и быть не может.
                                                                3) В больших коммерческих проектах это неплохой принцип. Сам иногда ему следовал. В таких проектах вообще не место экспериментам. Ну так это же не значит, что экспериментировать не следует в принципе.

                                                                В общем и целом видно, что murr сильно обжёгся на неудачной реализации. Все же лично меня его несколько чрезмерно эмоциональные пассажи (в чём он и сам покаялся) не слишком впечатлили. Хотя безусловно, это не одни эмоции, рациональные моменты там есть. И конечно, имеет значение, что murr с этим столкнулся на практике. В отличии от нас обоих, насколько я понимаю :)
                                                                  0
                                                                  > Автор вроде бы недвусмысленно, несколько раз, дал понять, что это не пустые намерения. Есть реализация.

                                                                  Я думаю, правильнее будет автору самостоятельно говорить за себя. Тем более, что ни Вы (как я понимаю) ни я его кода не видели.

                                                                    0
                                                                    А я не за автора говорю, а за себя. Своими словами, не указывая на чужие комменты без особых на то причин :) Автор же мог просто не успеть отреагировать, или ему просто надоело отбиваться в одиночку. Он ведь и не обязан биться в одиночку, вы же не откажете ему в праве на поддержку сочувствующих? :)

                                                                    В общем, чем плоха система контроля версий на атрибутах и вообще на БД, то есть почему там без файловой системы не обойтись, я так и не услышал. Жаль, правда было интересно.

                                                                    Кстати, написать про реализацию Napolsky обещал, если будет проявлен интерес. Даже не знаю, не отбили ли у него охоту продолжать такой жёсткой критикой. Не видя кода, как вы правильно заметили :)
                                                                      0
                                                                      Дело не в файловой системе, разумсеется, версионировать можно всё что угодно. Дело в том, что ОДНИМИ атрибутами не обойтись — нужен контроль за переносим/переименованием кусков кода, нужно отслеживание авторства этих кусков, нужно версионирование проекта в целом, нужно уметь делать диффы и накатывать патчи, нужно уметь переключать текущую ветку/версию проекта, нужно чтобы при этом не терялась целостность и непротиворечивость кода (особенно в нашем случае, когда код размазан по всей базе)… То есть, нужно уметь всё то, что умеют нормальные VCS. Это отдельная и довольно сложная подсистема, которая, конечно, может использовать атрибуты и пр., но к ним сведена, думаю, быть не может.

                                                                      Автор замахнулся на большую концептуальную штуку. Её можно реализовать или хорошо и тщательно — с поддерживающим всё это фреймворком, реализующим какой-то теоретически полный набор абстракций, с паттернами проектирования под это чудо, с документацией (!) и т. д. — или её можно реализовать «как всегда».

                                                                      Делать «хорошо» в одно лицо и в закрытом режиме… ну, не знаю, у Кнута получалось, конечно, но в общем случае априори в это поверить трудно… А реализуя «как всегда», мы получим просто большой слабосвязный кусок геморроя, о чём тут все комментаторы и говорили.
                                                                        0
                                                                        Вот это уже по существу. Заметьте, насколько отличается от первой фразы «ой, Вы таки сначала сделайте». Теперь суть «претензии» понятна, и так же по существу можно ответить.

                                                                        Никто в здравом уме не будет спорить, что VCS штука сложная, и ещё сложнее её одному написать. Да ещё на базе нестандартной концепции.

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

                                                                        Возьму на себя смелость «истолковать», надеюсь, верно: автор своим топиком хотел привлечь других к реализации, а не пытается объять необъятное, в чём вы его заподозрили :)

                                                                        Хотя и сам сделал немало, но не преувеличивает свой вклад, а наоборот, иронизирует: «велосипеды», «путь воина». Я, конечно, понимаю, что моя оценка тоже субъективна. Но как-то слишком много негативной реакции. И за что? За то что человек пробует новое на свой страх и риск, и без всякого пафоса обо этом рассказывает. Постарался уравновесить негатив :)
                                                                          0
                                                                          > Но Napolsky нигде и не заикался вроде бы, что это легко

                                                                          Справедливости ради — именно заикался: «Про контроль версий. Не забывайте, что у кирпичиков есть атрибуты. На их основе нет никакой проблемы сделать контроль версий».

                                                                          На что я и среагировал, потому что это, ИМХО, крайне легкомысленный взгляд на подобную задачу.
                                                                            0
                                                                            Гм. Но ведь вы сами признали, что можно и на атрибутах, и с этим нет никакой проблемы, что «версионировать можно на чём угодно»? :)

                                                                            Ладно, я получил очередной урок в тему субъективности прочтения. Действительно, только автор может знать, что он имел ввиду. Надеюсь всё же, что не легкость реализации VCS как таковой, а лишь лёгкость замены нативных файлов на записи в базе в рамках концепции VCS.
                                                                  +1
                                                                  Топик не представляет собой декларацию о намерениях. Прочитайте внимательно, я там дал понять, что осознанно ушел от конкретно своей реализации подхода, и попытался лишь максимально просто и подробно передать основную суть (зачем сбиваться на конкретику, когда и так слишком много нового). Естественно, все, о чем говорилось в топике реализовано на практике, и используется на реальных проектах. Те кто просил ссылки на эти проекты(см комментарии выше) их получили.

                                                                  Насчет murr. Murr рассказал о своем горьком опыте, о тех проблемах, которые были конкретно в его случае. Я не могу комментировать проблемы чужой системы, тем более не зная ее. Большинство этих проблем описано в топике. на остальные я отвечал в комментариях.
                                                                    0
                                                                    В общем, надо видеть реализацию. Пока ощущение… настораживающее. Я понимаю, что Вы не можете отвечать за чьи-то ощущения, но тем не менее.
                                                      +7
                                                      Осталось докрутить один маленький шаг: вместо хранения кода в БД, сделать нормальный компилятор PHP -> PHP. Т.е. на входе имеем N файлов со сложными зависимостями, на выходе -> M файлов без зависимостей и лишней мишуры. Почему автор не дошел до этой точки — остается загадкой.
                                                        –2
                                                        Постойте, постойте, какой же это компилятор.
                                                        То что вы описали это будет лишь кеширующий алгоритм (доп. пройслойка, которая тем эффективенее чем больше хитов на конкретные наборы данных).
                                                        Проблема данного изобретения в том, что eaccelerator уже изобретен, успешно внедрен во множество проектов, и работает эффективно.
                                                          +1
                                                          А чем это не компилятор, если он разбирает исходный код в AST и потом на его основе генерит новый код? Или, по вашему, компилятор должен непременно native-код генерить?
                                                              0
                                                              Давайте не будем, а? Русскоязычная часть википедии далека от статуса авторитетного источника. Просто примите как факт, что я описал компилятор ;-)
                                                                +2
                                                                Ой какой полиглот нашелся :)
                                                                Вы еще поди и по английски то читать умеете? Не поленитесь тогда воспользоваться ссылкой.

                                                                en.wikipedia.org/wiki/Compiler
                                                                «A compiler is a computer program (or set of programs) that transforms source code written in a computer language (the source language) into another computer language (the target language, often having a binary form known as object code). The most common reason for wanting to transform source code is to create an executable program.»

                                                                Вы же предложили написать компилятор, который сделает преобразование PHP в PHP. и после этого вы его называете компилятор…

                                                                Более правильного название, нежели EXPLODER, это не подходит ;)
                                                                  +1
                                                                  Вот Вы, видимо, читать по-английски умеете, но вникать в суть написанного не утруждаетесь. Ключевое свойство компилятора — это преобразование кода с языка прикладной области (DSL) в язык системы выполнения кода.

                                                                  Скажите, Вас не смущает, что Google называет свой GWT компилятором с Java в Javascript? А то, что JSP компилируется в Java? А тот факт, что Lisp компилируется в Lisp? ;-)

                                                                  На крайний случай, вспомните, что Smarty компилируется в PHP.
                                                                    0
                                                                    про гугл и lisp утверждать не могу, т.к. не знаю и лениво тратить на это время…

                                                                    а вот про смарти могу сказать:
                                                                    Smarty code -> PHP code
                                                                    или вы будете утверждать, что шаблоны смарти пишутся на PHP?

                                                                    Вы же предлагаете PHP преобразовывать в PHP, просто вместо 12345 в одном файле будет написано 5! (пять факториал) файлов с разными комбинациями внутренностей.
                                                                    Вот собственно этим и будет заниматься ваш компилятор? я вас правильно понял или мы о разном?
                                                                    0
                                                                    PHP и «PHP без инклюдов» — это разные грамматики (иначе можно сказать, что PHP это такой Perl с некоторыми особенностями).
                                                              0
                                                              посмотри в словаре переводы слов compile и translate.

                                                              называть транслятор компилятором — это всё равно, что называть копир ксероксом ;-)
                                                              –2
                                                              средний размер кирпичика — 20-50 строк. Сколько файлов понадобиться для кода всего сайта? Ни одна тысяча ) Поэтому справляется я этой работой куда быстрее. Плюс самое важное в бд — возможность назначать «кирпичикам» атрибуты. Поэтому подобный кампилятор типа PHP -> PHP хотя и возможен, думаю выглядел бы куда сложнее и работал гораздо медленнее.
                                                                +1
                                                                Можно по подробней, например какие атрибуты вы используете у кирпичиков?
                                                                  0
                                                                  например атрибут `langpack` в котором хранится (и автоматически заполняется) часть единого языкового пакета, которая необходима для этого модуля. Таким образом скорость кода никак например не будет зависеть от размера языкового пакета и сокращает размер необходимой памяти.
                                                                  0
                                                                  кстати, во всей этой схеме именно возможность пользоваться атрибутами меня больше всего возбудила :)
                                                                    0
                                                                    Эм… я немного о другом) На входе мы имеем проект, написанный по всем канонам ООП и best practices, а на выходе — борщ нечитабельного, но быстрого (в рамках ZE) кода. Например, если в какой-то части графа юзается один-единственный статик метод некоего класса Foo::bar() — имеет смысл декларировать его как функцию. Если метод является однострочник — заменяем его вызов на inline.

                                                                    пример: haxe.org/api
                                                                      –1
                                                                      собственно это и делают всякие акселлераторы. на выходе получается байт-код — тот самый шустрый борщ.
                                                                        0
                                                                        Акселлераторы это не делают. Акселлераторы просто сохраняют байт код в быстром кеше, но они никак глубоко не оптимизируют ваш код.
                                                                          0
                                                                          могу поспорить, что пхп-шный байт-код ничего не знает об ооп ;-)
                                                                            0
                                                                            конечно не знает (хотя опять таки как посмотреть). Но по-моему мы с вами немного о разном говорим :)
                                                                              0
                                                                              почему же?
                                                                              в случае Foo::bar() и foo_bar() с точки зрения байт-кода — наверняка никакой разницы.

                                                                            0
                                                                            Автор, бог с ними акселлераторами :)

                                                                            Вы не ответили на один существенный вопрос

                                                                            Вот у вас страница А, где нужна RSS лента и работа с БД.
                                                                            Вот у вас страница Б, где тоже нужна RSS лента и работа с БД.

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

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

                                                                            Я правильно понимаю, что ваша методика никакая не оптимизация для проекта крупнее домашней странички (т.е. для любого проекта у которого больше 5-10 страниц)?
                                                                              0
                                                                              Вы правильно понимаете, что на каждой странице необходимый функционал будет дублироваться. А вот про домашнюю страничку вы уже понимаете неправильно: то, что код будет дублироваться, скажется лишь на том, что непосредственно на жестком диске будет у вас хранится больше кода. Так код этот будет чистым (без «мертвого» кода), то размер страниц будет относительно небольшим. итого даже на 200 страницах вы не потеряете много места. Но в конечном итоге, за счет прироста производительности и сокращения необходимых ресурсов (всех от оперативки до жесткого диска), вы все равно получите выигрышь.
                                                                                0
                                                                                Я вас огорчу.
                                                                                Потому как сокращения ресурсов не будет.

                                                                                Код будет дублиироваться и при кешировании. Понимаете, если у меня в 200х местах используется класс Table, то кешер его подгрузит всего 1 раз и будет использовать для всех. В вашем случае он будет подгружаться 200 раз.

                                                                                Вы экономите мифические затраты памяти на подгрузку всех 40мб фреймворка. И при этом сами создаете вполне не мифические 40мб дублированного кода, которые уже 100% будут подгружаться в память.
                                                                                  0
                                                                                  Чтобы расставить все точки над "і", давайте возьмем какую-нибудь несложную задачу, которую можно сделать с нуля за 24 часа, напишем ее и сравним.

                                                                                  Я понимаю, что вы можете быть сейчас заняты, но уж 2 часа в день на протяжении 2х недель вы сможете выделить? :)

                                                                                  А через 2 недели, берем полученные коды и проводим тестирование.
                                                                                    0
                                                                                    тест будет необъективен так как у нас будут разные коды, априори разной производительности. Поэтому тест стоит устраивать по другому принципу: взять «классическое» приложение (zend, wp, cms какую-нибудь) и переложить его код на мою архитектуру. И сравнить производительность. Вот это будет честный тест, не так ли?

                                                                                    Кстати спасибо за идею. Обязательно портрачу на это время и опубликую результаты
                                                                                      –1
                                                                                      Гм, а сравнивать «одинаковые» коды было бы крайне глупо? Вы не находите?

                                                                                      Или вы сомневаетесь в моей способности выдать код хоть сколько-нибудь сравимый с вашим по производительности? :)

                                                                                      Чем перелицовка существующего кода только вами, будет отличаться от предложенного мной варианта? :)
                                                                                      Ведь там вы тоже будете сравнивать свой код с чужим :) которые будут разными и «априори разной производительности» :)

                                                                                      Вобщем, боитесь, так и признайтесь.
                                                                                        0
                                                                                        >> Гм, а сравнивать «одинаковые» коды было бы крайне глупо?
                                                                                        >> Ведь там вы тоже будете сравнивать свой код с чужим :)

                                                                                        Вы абсолютно не поняли, что я имел в виду под «переложить на мою архитектуру», а уже обвиняете меня в том что я вас боюсь. Попробую объяснить на пальцах, что я имел в виду:

                                                                                        Я хотел взять какой нибудь скрипт (например для определенности вордпресс) и разложить его на кирпичики. Потом собрать его таким образом, которым собирает страницы мой кодеген. Таким образом мы получим не новый код, а новую компановку кода. То есть при запуске страницы будут выполнены в полной точности все строки кода, которые есть в стандартном вордпресс. В собранной версии от кодегена не будет ни одной новой строки. Просто будут убраны все инклуды и весь мертвый код. Надеюсь теперь вы меня поняли?
                                                                                          0
                                                                                          воистину это — адская работа — перелопачивать Вордпресс под свою интерпретацию. проще свое написать )
                                                                                            0
                                                                                            ну только так можно добиться по настоящему объективного теста :)
                                                                                            Тем более весь и не собирался — только одну страницу. Работы часа на 3, думаю не больше
                                                                                            0
                                                                                            Вот и чудно, что я не понял. Мне же лучше — меньше работы :)

                                                                                            Только не пытайтесь спрыгнуть.
                                                                                            Берите не вордпресс, с его удодской архитектурой, а ZF.
                                                                                            И вперед.

                                                                                            Недели 4 на компоновку вам хватит?
                                                                                      0
                                                                                      А вот тут вас ждет очень неприятная неожиданность: кешеры опкода не любят мелкие файлы. Такие вот ни противные. И если на классике тот же eAcsellerator даст увеличение производительности в 3-5 раз, то при монолите в 10-15 раз :)
                                                                                      Во вторник кстати опубликую статью, где будут рассмотрены вопросы влияния «мертвого» кода, инклудов и прочего. Заодно там будет рассмотрено как со всем этим справляется акселлератор.
                                                                                        0
                                                                                        Я вас огорчу уже в который раз, читал я заметку Котерова :)

                                                                                        Но в вашем конкретном случае у вас будет не 1 файл «монолит», а 20-200 достаточно тяжелых файлов с дублированным кодом.

                                                                                        Будет ли это существенно быстрее чем 1200-2200 (включая фреймворк) моих файлов? Сомневаюсь.
                                                                                        Из-за одного простого соображения — Время загрузки в моем случае линейно
                                                                                        «коэффицент» * («число страниц» + «число функций» + «новая функция»)
                                                                                        а у вас
                                                                                        «коэффицент монолитных страниц» * «число страниц» * («число функций» + «новая функция»)
                                                                                        t = k * (ns + nf + x)
                                                                                        t = k2 * ns * (nf + x)
                                                                                        По вашей информации k/k2 = от 3 до 5.

                                                                                        Точку пересечения сами найдете? :)
                                                                                          0
                                                                                          Молодцы, что вспомнили Котерова, если бы вы его читали по лучше и повнимательнее, то помнится он как то упоминал об акселлераторах и разнице в количетве/размере подключаемых файлов.

                                                                                          >>Будет ли это существенно быстрее чем 1200-2200 (включая фреймворк) моих файлов?
                                                                                          В разы.

                                                                                          >>Время загрузки в моем случае линейно
                                                                                          Время загрузки чего? О каком вемени идет речь?
                                                                                            0
                                                                                            Уф, вы немного медленный.

                                                                                            У Котерова сравнение — 800 файлов объемом 5мб загружаются медленее 1го файла 5мб в 22 раза. (в идеале)

                                                                                            На пальцах, в случае реального проекта — а) загружаться будут не все 800, а в лучшем случае 1/3 от их числа. Т.е. 300. (ну не используют на все 100% фреймворк). Более того загружаться они будут по мере надобности и всего 1 раз!
                                                                                            б) общий объем раздробленого загружаемого кода будет 5мб * 1/3 = 1.8мб
                                                                                            в) объем монолитного кода у вас увеличится в «число страниц» раз.
                                                                                            г) объем используемого кода ваш кодеген сокращает в 5ть раз. Т.е. 1.8/5 = 0.36 мб

                                                                                            Но вот эти 0.36мб у вас будут воткнуты в КАЖДУЮ СТРАНИЦУ. Т.е. уже при 10ти страницах вы загружаете в ДВА РАЗА БОЛЬШЕ кода.
                                                                                            В реальном крупном проекте (не домашней страничке) у вас легко будет и 20 и 40 страниц.

                                                                                            Вот теперь берите и проверьте что быстрее загружается 300 файлов объемом 1.8мб
                                                                                            или 40 файлов объемом 14,4мб. Все еще недошло?

                                                                                            P.S. Время загрузки того, чего вы ускоряете. Вся ваша предполагаемая экономия строится на ускорении загрузки кода. (причем строго говоря, кешер под ваш проект будет жрать памяти тоже больше, из-за тупого дублирования кода)
                                                                                              0
                                                                                              Вы говорите очень самоуверенно, но по моему вы немного не понимаете, как работают кешеры опкода и от чего зависит производительность.

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

                                                                                              Но производительность приложения зависит не от того, сколько оно кода занимает на сервере, а от скорости выполнения этого кода. То есть каждая из N страниц по предложенной архитектуре будет загружаться в разы быстрее чем при классической. И не важно сколько этих N страниц: 1,10,100 или 1000. При увеличении числа страниц будет только увеличиваться занимаемое место на диске для их кода, но это никак не будет влиять на скорость этих страниц. А производительность приложения(сайта), еще раз повторяю, складывается из скоростей каждого его скрипта (страницы). и оно не зависит от того, сколько суммарно занимают эти скрипты в исходных кодах.

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

                                                                                              Ферштейн? :)
                                                                                                0
                                                                                                Жесть. Нельзя быть настолько умным как вы, это меня просто убивает.

                                                                                                Еще раз, повторяю. У вас не будет КАЖДАЯ загружаться быстрее. Просто потому что эта КАЖДАЯ у вас больше в размере в разы. И с ростом вашего кода в сравнении с библиотечным все будет хуже и хуже.

                                                                                                Смотрите. Есть 10ть базовых классов они у нас подгрузились 1 раз для какой-то страницы и все!
                                                                                                Затем мы в 10ти страницах используем эти 10ть базовых классов. И они (О ЧУДО) не грузяться, а используются из кеша!
                                                                                                Общий объем «объем библиотеки» + «объем пользовательского кода»

                                                                                                У вас же, есть 10ть базовых классов, но используем мы только половину. Поэтому для 1 страницы мы подгружаем только 5ть (ОПА!!! ускорение в ДВА РАЗА!!), но делаем мы это КАЖДЫЙ РАЗ для КАЖДОЙ из 10ти страниц.
                                                                                                Общий объем «число пользовательских страниц» * «объем библиотеки»/2 + «объем пользовательского кода»

                                                                                                Вы математику учили?
                                                                                                Графики роста времени выполнения построить можете?

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

                                                                                                1. Объем кода библиотеки
                                                                                                2. Объем пользовательского кода.

                                                                                                Так вот для 2го все ясно — он примерно одинаков. Вы экономите на 1м.
                                                                                                С коэффициентом, скажем, 10.
                                                                                                Но вы экономите для КАЖДОЙ ОТДЕЛЬНОЙ страницы. Но проект у нас это не одна страница.

                                                                                                И того у нас получается что добавляется множитель — число страниц.

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

                                                                                                Итого уже для 10ти страниц разницы не будет, для 20 страниц вы будете в полной жопе.

                                                                                                Кешер опкода грузит ФАЙЛ, а не отдельную функцию. У вас файл — это монолитная страница!
                                                                                                Поэтому и кешировать он будет страницу целиком! И дублирование у вас будет еще и в памяти, а не только на диске.

                                                                                                Теперь доступно? Или повторить на бис для альтернативноодаренных?
                                                                                                  0
                                                                                                  И такой момент, скорость выполнения кода практически не зависит от размера файла.

                                                                                                  От размера файла зависит скорость трансляции кода в байткод или машинный код.
                                                                                                  Так вот вы пытаетесь сэкономить на времени трансляции кода.

                                                                                                    0
                                                                                                    от размера файла — почти нет (при условии кешера опкода). А вот от количества инклудов — да. Даже для кешеров опкода. Если кешер опкода на монолите даст до 10x+ до на сотни мелких файлов допустим только 3x+
                                                                                                    0
                                                                                                    хехе… Мне уже и смешно и грустно спорить с вами. Я абсолютно понимаю ход ваших мыслей, но жаль вы в упор не понимаете, что этот ход мыслей неверен. По-моему у меня в последний раз хватит сил что-либо вам объяснить.

                                                                                                    Вы признаете, что для 1 страницы мой способ будет быстрее. А теперь скажите, как наличие еще 1000 страниц повлияет на скорость загрузки этой страницы? У нас что, изменится от этого ее байт код? Или этот байт код будет медленнее доставаться из кеша?

                                                                                                    Да, байткода в кеше в общем случае будет больше (и то не для всех авселлераторов). Но даже при наличии сотен страниц это выльется не более чем в десяток мегабайт оперативки.
                                                                                                      0
                                                                                                      Все, я не могу. Убейте меня кто-нибудь тапком.
                                                                                                      Я ненавижу когда люди так откровенно тупят. Меня это настолько бесит, что заставляет нервничать.

                                                                                                      Вы понимаете что ваш способ будет быстрее не для ОДНОЙ, а для ПЕРВОЙ страницы проекта!!!

                                                                                                      А все последующие у вас будут грузится дольше!!! Потому что у меня библиотека УЖЕ БУДЕТ В КЕШЕ
                                                                                                      и НЕ БУДЕТ ГРУЗИТСЯ. А у вас она БУДЕТ ГРУЗИТСЯ КАЖДЫЙ РАЗ!!!

                                                                                                      Все, финиш.
                                                                                                        –1
                                                                                                        ну как я и отмечал выше, вы нихрена не понимаете в работе кешеров опкода. С какого перепугу у меня будет что-то грузится каждый раз при запуске страницы? кешер проделает бОльшую работу только когда ему надо будет транслировать страницы в байт код. Но это грубо говоря единоразовая операция. И после того, как кешер получил байт код, ни в моем ни в вашем случае ничего ниоткуда грузится больше не будет. Сходите прочитайте где-нибудь матчасть, и возможно тогда ваша самоуверенность не будет граничить с глупостью.
                                                                                                          0
                                                                                                          Стена там -----> убейтесь.

                                                                                                          У вас не страница будет грузится каждый раз. У вас будет КАЖДЫЙ РАЗ ГРУЗИТСЯ ТОТ ДУБЛИРОВАННЫЙ ФУНКЦИОНАЛ, КОТОРЫЙ ЛЕЖИТ В СТРАНИЦАХ.

                                                                                                          Те самые функции работы с БД, RSS и всем остальным. В библиотеке класс подгружается 1 раз из отдельного файла. У вас же этот класс или функция во избежания инклюдов лежит в КАЖДОМ ФАЙЛЕ. Я специально у вас уточнял этот момент.

                                                                                                          Дошло? Или нет?
                                                                                                            0
                                                                                                            >>В библиотеке класс подгружается 1 раз из отдельного файла. У вас же этот класс или функция во избежания инклюдов лежит в КАЖДОМ ФАЙЛЕ. Я специально у вас уточнял этот момент.

                                                                                                            ДА. Именно так

                                                                                                            Но он НЕ будет грузится каждый раз. Он грузится один раз в кеш. После этого байткод просто достается из кеша.
                                                                                                              0
                                                                                                              я уже не знаю как вам на пальцах объяснить принцип работы кешера опкода. Хорошо что у меня стальные нервы, но вы меня в самом деле скоро добьете.
                                                                                                                0
                                                                                                                Обязательно добью. Я извращенец. А вы — доцент Авас (хотя вряд ли вы знаете и помните Карцева).

                                                                                                                У вас есть три файла

                                                                                                                a.php, b.php, c.php

                                                                                                                В каждом лежит класс DB для работы с базой.

                                                                                                                Вызывается a.php — кешируется.

                                                                                                                вызывается b.php
                                                                                                                Теперь внимание, вопрос — каким местом кешер уже знает, что ему не надо читать и кешировать полфайла? Да ни каким! Он тупо читает и транслирует весь файл, блин. И только сделав эту ТУПУЮ НЕНУЖНУЮ РАБОТУ, он понимает, какой он идиот и что ему не надо кешировать. Но он УЖЕ ПОТРАТИЛ ВРЕМЯ.

                                                                                                                То же самое происходит и c.php

                                                                                                                Еще раз повторить?
                                                                                                                  0
                                                                                                                  Вы все правильно говорите, но у вас неправильное представление о том, как это влияет на конечную производительность.

                                                                                                                  Как часто кешеру опкода приходится транслировать страницу в байт код? ооооочень редко. В идеале только тогда, когда в коде страницы произошли какие либо изменения.

                                                                                                                  А как часто приходится выполнять код этой страницы? Десятки/сотни/тысячи раз в секунду (в зависимости от нагруженности проекта).

                                                                                                                  Поэтому и проиграв во времени, затраченное на транслирование в байт код, мы выигрываем в разы больше за счет того, что полученный байт код работает быстрее.

                                                                                                                  Вы поняли свое маленькое упущение?
                                                                                                                    0
                                                                                                                    Фу, печаль. Дальше дискутировать бесполезно.
                                                                                                                    Вы не понимаете тривиальных вещей, а я не обладаю достаточной полнотой информации, чтобы убить вас окончательно.

                                                                                                                    Пока я не найду детального описания, как кешер работает с отранслированными функциями и классами.

                                                                                                                    В простейшем наиболее разумном случае, он на них тупо плюет. А работает с файлами. Есть include файла смотрим по ключу (причем, ключем может быть имя файла!) в кеш, если нет — читаем файл, если есть — достаем байткод.

                                                                                                                    Тогда вы неправы абсолютно, потому как вы тупо сожрали памяти больше чем надо, потратили время на дисковую операцию и ничего не выиграли.

                                                                                                                    В более сложном варианте кешируются функции и классы. Но это нестолько хреновая идея. Потому что делая include файла мы не указываем какую из функций мы хотим получить.
                                                                                                                    Тем не менее, в этом случае у нас есть некоторый мифический прирост скорости за счет сокращения переходов по ключам в памяти (нет include — следовательно не надо ничего искать). Мы просто имеем цельный блок который нужно выполнить.
                                                                                                                    Эта оптимизация сродни разворачиванию циклов на асме в лапшу. Но PHP не ASM, и увеличение скорости не будет в разы, в лучшем случае пару процентов.

                                                                                                                    Так что все косвенные улики говорят за 1й вариант и ваше необъективное тестирование (вы сравнивали только одну первую страницу, для которой и есть выигрыш, а надо сравнивать с учетом повторного использования закешированного кода)
                                                                                                                      0
                                                                                                                      И, да, во втором случае —
                                                                                                                      переходы по ключам include встречаются сильно реже чем переходы по call функций и методов. Настолько сильно, что выигрышем от include можно фактически пренебречь. Вот если вы умудряетесь развернуть и функции в лапшу… тогда можно получить до десятков (в экзотических случаях до сотен) процентов прироста скорости работы.
                                                                                                                        0
                                                                                                                        неважно по чему происходят переходы. Важен факт подключения внешнего кода.
                                                                                                                        0
                                                                                                                        я мало понял, из того что вы написали выше. Поэтому мне легче сказать, что будет в моем случае, ибо у меня все просто. Имея N страниц у меня будут N опкодов в кеше. Для каждой странице по одному и кешеру ничего не нужно где то дополнительно искать/подключать
                                                                                                                      0
                                                                                                                      «Авас» — это еще Аркадий Райкин, уважаемый; Карцев — только потом :)
                                                                                                                      0
                                                                                                                      Теперь как работает библиотека.

                                                                                                                      У нас есть три файла

                                                                                                                      a.php, b.php, c.php, причем каждый из них меньше размером, потому что класс БД лежит
                                                                                                                      в DB.php

                                                                                                                      Вызывается a.php, выясняется, что ему нужен еще DB.php — все это читается и кешируется.

                                                                                                                      Вызывается b.php, выясняется, что ему нужен еще DB.php, но, опа, он уже у нас в кеше. Поэтому мы его достаем из кеша и АЛЛИЛУЙЯ!

                                                                                                                      То же самое и c.php

                                                                                                                      Как итог — мы имеем на 2*DB.php килобайт меньше дисковых операций и трансляции кода.

                                                                                                                      Вы же оптимизируете как раз «лишнюю» загрузку с диска.

                                                                                                                      Поэтому для 1й(одной и первой) страницы вы получите выигрышь. Для всех последующих вы будете проигрывать.
                                                                                +2
                                                                                Автор, Вы не пробовали использовать autoload в сочетании с кэшем опкода и хорошей разбивкой функций по объектам? Дело в том, что при нормальном проектировании проблемы «лишнего кода, который приходится тащить» нет вообще. Нормальном — это не когда каждый файл начинается с include('common.php'), в каковом common.php сидит всё на свете.
                                                                                  +38
                                                                                  Многие схожие мысли приходили в голову разработчикам системы, которую мне пришлось относительно недавно поддреживать. Там тоже код хранился в базе. По итогам двухлетней эксплуатации, разработки и поддержки системы я могу сказать только одно: ВСЕГДА ХРАНИТЕ КОД В БД, И НИКОГДА В ФАЙЛАХ*.

                                                                                  * потому что вы ненавидите этих паршивых никчемных лузеров-программистов, которые будут еб%#$ся с вашей системой, правда?

                                                                                  Опишу некоторые фенечки хранения кода в БД, на своем опыте:
                                                                                  1) Разработчикам пришлось релизовывать свой лоадер для кода, который очень скоро перестал поддерживать новые фичи развивающегося языка. Это мелочь, но ее нужно кому-то поддерживать!

                                                                                  2) Контроль версий — полный пиз#@ц. На основе БД бравые разрабочики слабали свою систему контроля версий. Постоянные кошмары «кто затер мой код?», постоянные проблемы с обновлениями у заказчика и т.д.

                                                                                  3) Еще один уровень абстракции — еще больше проблем на задницу. Т.к. продукт кроссплатформенный, то отгребали по полной проблемы интреграции на каком-то секретном сервере заказчика между каким-то линуксом (потом стало известно, что это РедХат), каким-то апп-сервером и некой БД. Поползли кодировки в цепочке вызовов Юзер-Сервер-ОС-Бд.

                                                                                  4) Полная задница с получением актуальной версии кода в сложной системе, в итоге-то, его все равно нужно представить как-то в файловой системе для редактора/ИДЕ. Зависимости кода в базе от другого кода в базе становятся такими неочевидным, что просто ужас.
                                                                                  Ваше «сведение «мертвого» кода к нулю» — это миф, код организуют в библиотеки не просто что бы в одном файле лежало, а по неким принциам (не важно какая парадигма) и зависимостей там с лихвой.

                                                                                  Ваши аргументы:
                                                                                  Скорость достигается кешированием и прекомпиляцией, а не перекладыванием работы с обычной файловой системы (нтфс, экст3?) на базу данных. «Старый файловый способ» в вашем случае в миллион раз лучше тем минимум тем, что скорость растет от замены ФС, не меняя НИ строчки кода.

                                                                                  Чем из наиболее мелких и простых частей состоит конструктор, тем быстрее система прийдет в состояние «полная жопа». Обычный рефакторинг будет похож на попытку расковырять пальцем бетон.

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

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

                                                                                  Не обижайтесь пожалуйста, но я для себя решил, что такой подход невероятно глупый (в нашем проекте). Любая проблема, которую он решает — надумана или отлично (и лучше и стандартнее) решается штатными средствами любой системы контроля версий. Размазывание зависимостей и полное отсуствие возможностей хотя бы тупо посмотреть структуру кода в файловой системе (я не говорю про тесты и т.д.), постоянные проблемы с получением актуальной версии кода — отличные примеры мегаантипаттернов.

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

                                                                                      1) Если язык либо задачи заставляют изобретать некие мета-паттерны/интерпритаторы над языком — следует посмотреть либо на смену языка/парадигмы, либо на смену архитектуры (либо на природу сходить, кваса попить и птичек послушать). Можно посмотреть питон или руби, прекрасные языки позволяющие делать метапрограммирование простой задачей, с хорошим сообществом. Попытки изобрести мета-интерпритатор интерпритируемого языка — плохие попытки. Попытки упростить архитектуру (в первую очередь для человека!) до максимума — хорошие попытки.

                                                                                      2) Ускорение работы системы в цепочках: Пользователь <-> Программа, Программа <-> Данные, Программа <-> Окружение, Данные <-> Окружение должно приходится на первую и вторую связь (грубо говоря: оптимизация работы самой программы c данными, оптимизация работы программы у клиента, а программа и данные в идеале должны быть максимально независимыми от окружения (в данном случае, php спокойно позволяет это делать). Попытка найти скорость там, где ее нет (аудиофилы могут расказать вам о «чистейшей безкислородной меди» в обычном полутораметровом сетевом кабеле за 500 баксов) — это плохой прием оптимизации. Кеширование или ускорение доступа к данным без существенного изменения кода — хороший прием.

                                                                                      3) Пока разработчиков раз, два и все — вроде бы все хорошо, но когда их пару десятков в разных городах — сложность поддержки системы возрастает по функции n^(n1-n2)*q, где n — общее число разрабочиков, n1 — число людей ДОСКОНАЛЬНО знающих архитектуру и код, n2 — число людей, плохо знающих архитектуру и код, а q — показатель тупости самого глупого разработчика. Ориентация на простоту для машины (в данном случае мнимую) — плохой прием. Ориентация на простоту поддержки и модернизации для пользователей системы (да, для самых тупых из них) — хороший прием.
                                                                                        +1
                                                                                        Ммм, функцию намудрил:
                                                                                        сложность = n ^ (n — n1) *q, где
                                                                                        n — общее число разрабочиков,
                                                                                        n1 число людей, плохо знающих архитектуру и код,
                                                                                        а q — показатель тупости самого глупого разработчика.
                                                                                          +1
                                                                                          наоборот
                                                                                      0
                                                                                      почти со всем согласен! :)

                                                                                      > Чем из наиболее мелких и простых частей состоит конструктор, тем…

                                                                                      чем проще кусок кода — тем более понятен он программисту. Это не значит, что он должен быть маленьким… он может быть и большим, но должен быть логичен.
                                                                                        –6
                                                                                        Была бы карма, плюсанул бы от души.
                                                                                        +10
                                                                                        Автор, вы когда-нибудь слышали о системах контроля версий?
                                                                                        А об оптимизаторах-прекомпиляторах типа APC или Zend Optimizer?
                                                                                        А ничего, что файловая система — это и так база данных, которая хранит в себе файлы?

                                                                                          +4
                                                                                          В общем поздравляю, модульное программирование вы для себя уже открыли, развивайтесь дальше. :)
                                                                                            0
                                                                                            на нападки обычно не отвечаю, но здесь лишь отмечу ту мысль что да, имея опыт как ООП так и компонентного программирования, в php я осознанно сделал шаг назад в сторону модульного программирования.
                                                                                              +4
                                                                                              Я не нападаю, правда. Я предложил темы, которые могут быть вам интересны: APC, Zend Optimizer, SVN, git.
                                                                                          +25
                                                                                          феерический ппц
                                                                                            –2
                                                                                            … а судя по тому, что в комментариях есть и добрые отзывы — становится все ппцатее и ппцатее…
                                                                                              +1
                                                                                              Знаете, все ужасаются от хранения кода в бд. Но здесь не маловажна доля предубеждения. Все слышали о том, как это ужасно, многие даже видели провальные попытки хранения _части_ кода в бд с ее евалом.
                                                                                              Но никто не пытался это реализовать на полную(говорю «на полную», потому что мне не известны случаи, когда как и в моем подходе в бд хранится абсолютно весь код, и при этом есть возможность вообще не использовать eval ) и посмотреть чуть глубже. Я же попробовал. И доказал (по крайней мере себе) что такой вариант имеет право на жизнь. Разве это плохо? :)
                                                                                                +1
                                                                                                Знаете, все ужасаются, то сложно ходить привязав руку к ноге, а ногу к уху. Но здесь не маловажна доля предубеждения. Я же попробовал. И доказал (по крайней мере себе) что такой вариант имеет право на жизнь. Разве это плохо? :)
                                                                                                  0
                                                                                                  А вы знаете, есть такая наука под названием Комбинаторика и теперь возьмем 200 различных функций, и предположим что все пересечения способны на жизнь, это где ж такой винт то взять чтобы все варианты поместить, это получается 200!=..., имхо просто баснословная циферка.
                                                                                                    0
                                                                                                    Вся ваша затея вышла из незнания того, что существуют решения, позволяющие ускорить выполнение PHP-кода, не прибегая к садомазохизму. APC, eAccelerator кэшируют в памяти сервера готовый байт-код.

                                                                                                    Кроме того, вы, очевидно, работаете один, это видно из того, что ваш подход означает не просто общий «феерический пипец » (с) ИнтенТ — он означает еще и капитальный пипец хранению версий, разрешению конфликтов: то есть вообще командной разработке.

                                                                                                    Я так считаю — сделали для себя такое чудовище — ну подождите, посмотрите на него. Оно чуть погодя проснется (это я вам гарантирую) и надерет вам задницу (и хорошо, если вам, а не кому-то еще, кто будет разгребать за вами эти Авгиевы конюшни). А вы сразу — «вот смотрите, что я сделал, что я сделал». Щас ведь еще стопицот пионеров побегут на работу с криками «теперь мы знаем — надо хранить код в БД!»
                                                                                                      0
                                                                                                      основная беда подобных препроцессоров заключается в отсутствии адэкватного бэктрейса…
                                                                                                  +2
                                                                                                  Данный подход можно использовать без извращений с БД — с помощью макросов.
                                                                                                  Есть уже готовые препроцессоры — универсальный M4 и препроцессор языка С.

                                                                                                  А вообще мне кажется — это нахуй ненужно, потомучто есть оптимизаторы кода и кеширование кода,
                                                                                                  есть fastcgi — когда можно слить весь код в один файл.
                                                                                                    +3
                                                                                                    не представляю разработку без автодополнения в IDE
                                                                                                      –1
                                                                                                      Вы что, не в Far-е кодите?
                                                                                                        0
                                                                                                        чур меня
                                                                                                      +1
                                                                                                      Увеличение скорости работы приложения за счет скорости работы программиста, трата времени на создание инструментов УДОБНЫХ для отладки и программирования этих блоков, увязывание всего этого в голове для начала, опять же именно работа с БД обычно является узким местом при разработке. Бррр, уже страшно!

                                                                                                      >>Время генерации страницы сократилось с 0.25-0.3 до 0.04-0.05 секунды
                                                                                                      >>(~600%. Напоминаю, что это без кеша в классике. с кешом цифра будет поменьше)
                                                                                                      Указанное Вами время генерации страницы является достижимой целью при правильной настройке сервера, как уже было сказано выше. Кстати, для интереса — включите кеширование, насколько меньше станет время генерации?

                                                                                                      Но чисто за реализацию этой идеи — браво, все говорили об этом, но попробовать ни у кого руки не доходили! Спасибо!
                                                                                                        +6
                                                                                                        Статья должна начинаться так:
                                                                                                        Работодатель вас гнобил и унижал? Вовремя не платил и выжимал все соки? Терпение кончилось и вы уже почти ушли, но хочется напоследок оставить о себе память? Но как же принести наибольшее количество проблем, формально оставшись в правовом поле и даже завершить текущие проекты.
                                                                                                        Я расскажу вам как!

                                                                                                        Мне как то достался сайт на typo3 c кучей кода сохраненной в БД. Хотя человек который его сделал действовал из лучших побуждений, тоже был «изобретатель» :)
                                                                                                        А так минусы вы указали верно, только добавить про контроль версий и невозможность работы в команде.
                                                                                                          +1
                                                                                                          Посмотри Zope. Там используется подобный подход. В документации описаны случаи когда выгоднее хранить исходники в файлах, а когда в БД.
                                                                                                          Невозможность полноценно использовать IDE

                                                                                                          Напиши webdav интерфейс, отдающий исходники из БД, подключай этот ресурс как сетевой диск и используй любую IDE, работающую с файлами. Это сильно проще, чем писать текстовый редактор.

                                                                                                            0
                                                                                                            в Zope исходники хранятся на файловой системе.
                                                                                                            возможно вы имели ввиду объекты Python script, Page Template которые дают возможность создавать скрипты через веб интерфейс, но реально не используется в больших проектах
                                                                                                            +5
                                                                                                            Автор как то не правильно понимает то как работают объекты. Мы как то проводили эксперимент. Два объекта: у первого 40 методов, у второго 200, вызывался один лишь метод каждого объекта в цикле на 10 млн. итераций. Разница в процессорном времени и памяти на столько мала, что огород из кусков кода в бд видится бессмысленным.
                                                                                                              0
                                                                                                              Ох как жестоко…

                                                                                                              У меня конечно тоже, иногда, после профайлинга с просмотром покрытия кода тоже возникают странные мысли о том, что слишком много лишнего кода имеется… но чтоб такое.

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

                                                                                                              А собственно пришел я вот к чему — банальное использование fastCGI. Имееца загрузчик который собирает наше приложение — загрузилось, отлично. Теперь висим как сервис и роутим запросы на наши контроллеры и что-то выполняем. Быстро, просто да и крависиво.
                                                                                                                +3
                                                                                                                ВЕЛОСИПЕДИЩЕ! :))))
                                                                                                                  0
                                                                                                                  Простите, а чем реализована подсветка кода в веб-интерфейсе?
                                                                                                                    0
                                                                                                                    на codepress (http://sourceforge.net/projects/codepress/). Правда пришлось его переписать чуть менее, чем полностью :)
                                                                                                                    +1
                                                                                                                    Расширяемость такого решения под большим вопросом.
                                                                                                                    Особенно когда на горизонтальную денег нет, а узкое место это бд.
                                                                                                                      +1
                                                                                                                      За хранение «живого» кода в БД нужно бить, причем не только по рукам.
                                                                                                                        0
                                                                                                                        Я бы такой код на поддержку не брал. Один eval чего стоит.
                                                                                                                          +2
                                                                                                                          Зато это отличный способ сохранить рабочее место! Захерячил весь код в базу и больше никто кроме тебя в нем не разберется. Профит!
                                                                                                                          0
                                                                                                                          Как эксперимент — забавно, но в продакшене…
                                                                                                                          Режешь левую резьбу на гайке — будь готов резать такую же резьбу на всех болтах.
                                                                                                                            0
                                                                                                                            идея очень похожа на движки имидборд. когда человек пишет новый пост, он сначала попадает в базу, а затем вызывается функция BuildThread(), которая извлекает все посты для данного треда из базы и пишет их в .html-файл. т.е. дальнейшие обращения к треду (чтение, а не запись новых постов) проходят вобще без вмешательства какого либо кода.
                                                                                                                              +1
                                                                                                                              это называется «кеширование»
                                                                                                                              0
                                                                                                                              А какой смысл убирать «мертвый код»? У вас там чтоли доисторический сервер, который часами парсит php и при этом жудко тормозит?
                                                                                                                                0
                                                                                                                                Нет, конечно же не часами. Но ради интереса проведите такой эксперимент: создайте файлы на 2000/5000/10000 строк пхп кода (просто объявление функций, без какого-либо выполнения). И натравите на них ab (ApacheBenchmark). Вы увидите, что количество запросов в секунду обратно пропорционально коду в файле :) Я не говорю, что на этом можно реально много выиграть на практике (проблему решают кешеры кода отчасти), но на это тоже стоит обращать внимание. Хотя бы в исследовательских целях
                                                                                                                                  0
                                                                                                                                  stas@dev ~ $ cat test.php
                                                                                                                                    +1
                                                                                                                                    мда круто хабра вырезает теги из сообщения, я не виноват :))

                                                                                                                                    stas@dev ~ $ cat test.php
                                                                                                                                    ?php

                                                                                                                                    echo '?php class foo {';

                                                                                                                                    for($i = 0; $i < $_SERVER['argv']['amount']; $i++) {
                                                                                                                                    echo 'public function test'.$i.'() {}';
                                                                                                                                    }

                                                                                                                                    echo '}';
                                                                                                                                    stas@dev ~ $ php test.php --amount 2000 > 2000.php
                                                                                                                                    stas@dev ~ $ php test.php --amount 5000 > 5000.php
                                                                                                                                    stas@dev ~ $ php test.php --amount 10000 > 10000.php
                                                                                                                                    stas@dev ~ $ time php 2000.php

                                                                                                                                    real 0m0.016s
                                                                                                                                    user 0m0.008s
                                                                                                                                    sys 0m0.008s
                                                                                                                                    stas@dev ~ $ time php 5000.php

                                                                                                                                    real 0m0.016s
                                                                                                                                    user 0m0.016s
                                                                                                                                    sys 0m0.000s
                                                                                                                                    stas@dev ~ $ time php 10000.php

                                                                                                                                    real 0m0.016s
                                                                                                                                    user 0m0.016s
                                                                                                                                    sys 0m0.000s
                                                                                                                                    0
                                                                                                                                    То есть, Вы признаёте, что поднятая Вами «проблема» вполне решаема стандартными способами, но в исследовательских целях захотелось извратиться?:) Замечу, что «извратиться в исследовательских целях» — дело более чем благородное, только надо и позиционировать это именно так.

                                                                                                                                    P. S. Открыл самый большой класс моего проекта, который мне крайне не нравится своей раздутостью. 1500 строк. Остальные классы — строк по 200-500 в среднем. А Вы действительно постоянно имеете дело с файлами по 5-10 тыс строк?
                                                                                                                                      0
                                                                                                                                      Да, я конечно признаю, что проблема (по крайней мере проиводительности) решаема связкой OOП-акселлератор-кеш. Правда не стоит сбрасывать со счетов «плюсы» атрибутов кусков кода и возможности произвольной модификации кода перед выполнением. И да, я во многом работал над этой системой именно в исследовательских целях. Это было что то новое и свежее, от чего я получал удовольствие :)

                                                                                                                                      Насчет строк кода: я имею ввиду строк кода на странице, которые приходится парсить php. У вас же на странице не один класс, правда? ;)
                                                                                                                                        0
                                                                                                                                        Модификация кода — это палка о двух концах. Обычно речь о модификации кода заходит при недостаточно продуманной объектной модели, когда не получается расширить какой-то функционал обычным образом и приходится «патчить» код или вывод. Чревато большими проблемами при отладке и рефакторинге…

                                                                                                                                        На странице (у меня нет понятия страницы в чистом виде, но пусть будет «при обращении к определённому урлу») у меня обычно классов, наверное, пять-шесть… Собственно контроллер запроса, шаблонизатор, ну и пара-тройка классов модели. При том что весь код уже лежит в кэше опкода.
                                                                                                                                          0
                                                                                                                                          Вот в этом «я имею ввиду строк кода на странице, которые приходится парсить php»
                                                                                                                                          я и вижу грабли. (писал ниже в комментариях)

                                                                                                                                          Дело в том что в случае опкодкешеров код парсится для каждого класса 1 раз при загрузке. И затем используется сколько угодно.

                                                                                                                                          У вас же будет как минимум дублирование объявлений классов и функций на каждой странице.
                                                                                                                                          А если не будет дублирования объявлений (например, за счет уникальных имен), то получите дублирование кода.
                                                                                                                                          Парситься это все будет «надцать» раз, например, класс работы с БД используется в 100 страницах и в каждой!!! странице он будет присутствовать. Где здесь ускорение работы? :)

                                                                                                                                          P.S. Т.е. до тех пор пока код фреймворка больше чем ваш проект, у вас будет небольшое ускорение. Как только они сравняются, или ваш проект станет больше… ускорение станет торможением.
                                                                                                                                            0
                                                                                                                                            дублирование классов и функций ни в коем случае не будет (так же как и дублирование кода под разными именами). Да и сам php даже не позволит вам продублировать функцию или класс и вылетит с ошибкой
                                                                                                                                              0
                                                                                                                                              Ну простите. Как это не будет?

                                                                                                                                              Вот у вас страница А, где нужна RSS лента и работа с БД.
                                                                                                                                              Вот у вас страница Б, где тоже нужна RSS лента и работа с БД.

                                                                                                                                              Что у вас собирается в код для этих страниц? :) Из вашего описания, я так понимаю, в код каждой страницы будет включен полный требуемый ими фукционал работы с БД. И не дай бог эти две страницы у нас еще и позволяют редактировать БД, то это тихий капут.
                                                                                                                                    +1
                                                                                                                                    Я не понял, может невнимательно читал, но все же — кто отслеживает зависимости между частями?
                                                                                                                                    Как обеспечивать хранение версий, типа как в системах контроля версий а-ля git и mercurial?
                                                                                                                                      0
                                                                                                                                      здесь тоже все очень гибко. Вы можете настроить централизованную систему управлениями версиями под свои нужды. Можете как в CVS разрешить редактирование одного кода многими разработчиками. Можете настроить так, что каждое новое изменение будет «пораждать» новый кирпичик (а в атрибуты ему например писать кто и что конкретно изменил, добавить текущю версию ). При том опять таки можете заставить собирать кодеген код из «кирпичиков» нужных версий, или нужных авторов. Вообще сама суть, что бд становится как бы нативной, открываются широкие возможности для отслеживания изменений кода или многопользовательской работы над ним
                                                                                                                                      +1
                                                                                                                                      А вот мне скоро достанется управлять провайдером у которого биллинг и внутренний документооборот так написаны, пхп в базе, дельфовый клиент для рендера, данные и код в одной базе, про параллельную разработку никто не слышал, контроля версий нет вообще.
                                                                                                                                      Страаашно. Но уже лет 6 работает как то…
                                                                                                                                        0
                                                                                                                                        А можно глянуть на живой прожект? ;)
                                                                                                                                        зы: если боитесь хайглоад, можно и в личку, буду очень признателен ;))
                                                                                                                                          0
                                                                                                                                          отправил