Ошибка проверки динамического шаблона в PHP

Я пытаюсь создать CMS на PHP и немного беспокоюсь о создании системы шаблонов. Я не хочу использовать Smarty или Twig, потому что я не хочу полагаться на внешние фреймворки, пока не смогу свободно программировать себя. Это все о том, как улучшить свое обучение (с моей точки зрения).

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

Вот основной обзор того, как он работает.

(очень) простой шаблон шаблона:

<html>

{output $randomNumber}

{output $databaseDump} <div>{output $databaseAndUsersPasswords}</div> </html>

Получает анализируемый мой парсер:

<html>

<?php echo $randomNumber?>

<?php echo $databaseDump?> <div><?php echo $databaseAndUsersPasswords?></div> </html>

Затем я использую eval для запуска анализируемого шаблона.

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

Кроме того, как вы думаете, я хорошо использую регулярное выражение и str_replace для анализа шаблона? Я читал некоторые другие решения, но все это выглядит ужасно сложным, я не могу найти ядро ​​своей системы синтаксического анализа.

Пожалуйста, критикуйте мои методы, которые вам нравятся. Я здесь, чтобы учиться.

4
nl ja de
Независимо от того, что вы делаете, вы никогда не используете eval для анализа чего-либо. Есть ли причина, по которой вы не можете/не хотите просто использовать простой PHP в качестве механизма шаблонов?
добавлено автор PeeHaa, источник
@HankyPanky, не могли бы вы рассказать? Вам нужен пример ошибки? @PeeHaa это может быть немного педантичным, но меня беспокоили скобки «{}», используемые в конструкциях PHP, и если бы они просто путают конструктора. Кроме того, как бы я мог вывести многомерный массив в виде отформатированной таблицы, не создавая путаницу конструктора? Однако вы публикуете разумный аргумент, который я рассматриваю, но я не уверен. Я понимаю, что это будет намного быстрее. Я просто смотрю на подобных PHPBB, это выглядит более профессионально для меня. В конечном итоге ни один из них не изменит конечного пользователя.
добавлено автор Sam, источник
ошибки, например?
добавлено автор Hanky Panky, источник
Если вы создаете PHP-код, вы можете просто использовать include :)
добавлено автор Ja͢ck, источник

2 ответы

Если вы хотите все или ничего, вы можете просто настроить обработчик ошибок и позволить ему генерировать исключения:

function exception_error_handler($errno, $errstr, $errfile, $errline ) {
    if (error_reporting()) {
       //the @ operator wasn't used, throw it.
        throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
    }
}
set_error_handler("exception_error_handler");

После этого вы можете include() создать сгенерированный скрипт внутри блока try {} catch и использовать буферизацию вывода для предотвращения нежелательного вывода:

try {
    ob_start();//stop output

    include '/path/to/script';

    ob_end_flush();//flush buffer and stop output buffering
} catch (ErrorException $e) {
    ob_end_clean();//clear buffer and stop output buffering
}

See also: ErrorException


Что касается написания собственного шаблонного движка, я использую это правило:

Если это похоже на PHP, используйте PHP!

Синтаксис, который почти напоминает PHP, будет так же трудно изучать для дизайнеров, как сам PHP, но те усилия, которые вы проводите, убедившись, что шаблоны не срабатывают, ваш собственный парсер определенно осязаемы.

Если вы хотите что-то, что лучше сплетено для дизайнеров, посмотрите этот проект под названием PHPTAL , который использует атрибуты XHTML для подстановки переменных и объявления циклов цикла, макросов и т. д.


More on error reporting and logging: Error logging, in a smooth way

4
добавлено
Если это похоже на PHP, используйте PHP! ++
добавлено автор PeeHaa, источник
Спасибо за это. Я рассматривал использование буферизации вывода на eval (если возможно), но, похоже, что eval сейчас не может быть и речи. Кроме того, я не видел никаких преимуществ для сохранения файла, а затем сразу же загружался, за исключением кеша, конечно. Я хорошо прочитаю сообщение о регистрации ошибок. Благодаря!
добавлено автор Sam, источник
@Sam. Компиляция шаблона каждый раз может быть больше налогообложения, чем вы думаете ;-) В некоторых случаях многие компоненты загружаются в процесс, который в противном случае не был бы необходим после компиляции. Вы также можете использовать кеширование кода операции (APC), если вы пишете промежуточные файлы.
добавлено автор Ja͢ck, источник
+1 Отличный ответ, полный полезных ресурсов. Кстати, этот ответ должен иметь больше оборотов, ИМХО.
добавлено автор Leri, источник

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

Я бы использовал образец MVC и допустил загрузку контроллера просматривать и передавать ему необходимую информацию без обработки в качестве скрипта .

Образец:


Базовый контроллер:

abstract class Controller {
    protected function Render($view, $data = array()) {
        $viewStr = file_get_contents(__PATH_TO_VIEW__.$view.'.html');

        $viewStr = preg_replace_callback('/\{(\w+)\}/',
                                        function ($matches) use ($data) {
                                            return isset($data[$matches[1]]) ?
                                                          $data[$matches[1]] : '';
                                        }, $viewStr);
        echo $viewStr;
    }
}

Пользовательский контроллер:

class MyController extends Controller {
    public function index() {
        $this->Render('myView', array('test' => 'some test string'));
    }
}

Пользовательский вид ( myView.html в этом примере):

{test}

Выход должен быть:

некоторая тестовая строка


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

Постскриптум Не стесняйтесь адаптировать это достаточно к существующему коду. ;)

1
добавлено
Привет, спасибо за это. Я на самом деле пытаюсь включить все это в приложение MVC, но, возможно, я ошибаюсь. То, что вы там сделали, похоже на то, что я делал, полагая, что читаю его правильно. Где шаблон содержит заполнители, и вы используете модель для ее рендеринга. У вас есть фантастическое решение, но мне просто интересно, что происходит с такими вещами, как массивы данных. Я использую немного HTML в моем PHP или что-то в этом роде? В принципе, предварительно создайте содержимое таблицы, затем поменяйте ее на местозаполнитель?
добавлено автор Sam, источник
Спасибо. Это очень интересно. Я нашел это особенно хорошим: stackoverflow.com/questions/5863870/… . У меня есть много чтения, чтобы сделать сейчас. Благодарю. Я все еще немного запутался относительно того, как происходит рендеринг. Я еще раз посмотрю.
добавлено автор Sam, источник
Вот как я понимаю вашу версию и в основном, как я это делал: шаблон содержит заполнители. Сценарий импортирует источник шаблона. Затем скрипт использует регулярное выражение для выгрузки заполнителя и замены его данными, содержащимися в массиве. Затем шаблон повторяется. Я прав?
добавлено автор Sam, источник
@Sam На самом деле контроллер отображает данные в placeholder. Таким образом, ваш скрипт не будет обрабатывать работу дизайнера, а выводит его. Для получения более подробных пояснений см. эти ответы .
добавлено автор Leri, источник
@Sam Допустим, у меня есть 10 сообщений, которые мне нужно сделать. Шаблон каждого сообщения одинаков, поэтому я загружу этот шаблон для каждого элемента, чем передаю его в мой основной шаблон, который имеет что-то вроде: {posts} . Это первое решение, которое пришло мне в голову. Возможно, это улучшилось.
добавлено автор Leri, источник
@Sam, точно ..
добавлено автор Leri, источник
phpGeeks
phpGeeks
3 620 участник(ов)

Best PHP chat Еще: @dbGeeks - базы данных @phpGeeksJunior - новичкам @moscowProgers - IT Москва @ebanoePhp - весёлый канал о PHP @laravel_pro - Laravel @jobGeeks - вакансии @jsChat - JS Правила: https://t.me/phpGeeks/764859 ДР - 28.03.2016

PHP
PHP
1 309 участник(ов)

Группа про современный PHP. Обсуждаем ООП, TDD, BDD, DDD, SOLID, GRASP и прочие крутые базворды Для ознакомления: https://gist.github.com/mkusher/711bd46f0b62fbae851182e6fb3b1839 Группа PHP для новичков @phpGeeksJunior Вакансии: https://t.me/fordev

PHP — вакансии, поиск работы и аналитика
PHP — вакансии, поиск работы и аналитика
1 251 участник(ов)

Публикуем вакансии и запросы на поиск работы по направлению PHP, Laravel, Symfony, Yii и т.д. Здесь всё: full-time, part-time, remote и разовые подработки. См. также: @qa_jobs, @devops_jobs, @javascript_jobs, @nodejs_jobs, @uiux_jobs, @products_jobs

phpGeeksJunior
phpGeeksJunior
980 участник(ов)

Группа для новичков. Не стесняйтесь задавать вопросы по php. Не флудить!!!! Правила и полезные ссылки https://gist.github.com/exileed/a53dd0617b35a705ff44b38c8028e6a5 Бест от пхпгикс https://t.me/best_of_phpgeeks

phpclub.ru
phpclub.ru
872 участник(ов)

Официальный чат phpclub.ru - остерегайтесь подделок #rules Правила группы - уважайте друг друга. Скриншоты -> ссылками. Код -> pastebin.com. Вакансии строго -> https://goo.gl/4bNxym, в чат ссылку. За рекламу и мат - БАН!

Devall | PHP
Devall | PHP
272 участник(ов)

Пристанище для восходящих звёзд разработки, которые перейдут на более адекватные языки. http://combot.org/chat/-1001014863761 Инвайт: j.mp/devallphp