В PHP описания строк HEREDOC действительно полезны для вывода блока html. Вы можете заставить его анализировать переменные, просто префикс их с помощью $, но для более сложного синтаксиса (например, $ var [2] [3]) вам нужно разместить выражение внутри {} фигурных скобок.
В PHP 5 можно фактически совершать вызовы функций внутри {} скобок внутри строки HEREDOC, но вам нужно пройти небольшую работу. Само имя функции должно храниться в переменной, и вы должны называть ее, как динамически называемую функцию. Например:
$fn = 'testfunction'; function testfunction() { return 'ok'; } $string = <<< heredoc plain text and now a function: {$fn()} heredoc;
Как вы можете видеть, это немного более грязно, чем просто:
$string = <<< heredoc plain text and now a function: {testfunction()} heredoc;
Есть и другие способы, помимо первого примера кода, такие как выключение HEREDOC для вызова функции или изменение проблемы и выполнение чего-то вроде:
?> <!-- directly output html and only breaking into php for the function --> plain text and now a function: <?PHP print testfunction(); ?>
Последнее имеет тот недостаток, что вывод напрямую помещается в выходной поток (если только я не использую буферизацию вывода), что может и не быть тем, что я хочу.
Итак, суть моего вопроса: есть ли более элегантный способ приблизиться к этому?
Редактирование на основе ответов: Конечно, похоже, что какой-то механизм шаблонов сделает мою жизнь намного проще, но для меня это потребует от меня в первую очередь моего обычного PHP-стиля. Не то, что это плохо, но это объясняет мою инертность. Я собираюсь выяснить способы облегчения жизни, так что теперь я просматриваю шаблоны.
Я лично не использовал бы HEREDOC для этого. Это просто не делает для хорошей системы создания шаблонов. Весь ваш HTML заблокирован в строке, которая имеет несколько недостатков
Получите базовый механизм шаблонов или просто используйте PHP с включенными в него – поэтому язык имеет разделители <?php
и ?>
.
template_file.php
<html> <head> <title><?php echo $page_title; ?></title> </head> <body> <?php echo getPageContent(); ?> </body>
index.php
<?php $page_title = "This is a simple demo"; function getPageContent() { return '<p>Hello World!</p>'; } include('template_file.php');
Если вы действительно хотите это сделать, но немного проще, чем использовать класс, который вы можете использовать:
function fn($data) { return $data; } $fn = 'fn'; $my_string = <<<EOT Number of seconds since the Unix Epoch: {$fn(time())} EOT;
Я бы сделал следующее:
$string = <<< heredoc plain text and now a function: %s heredoc; $string = sprintf($string, testfunction());
Не уверен, что вы считаете, что это более элегантно …
Попробуйте это (либо как глобальную переменную, либо создайте ее, когда вам это нужно):
<?php class Fn { public function __call($name, $args) { if (function_exists($name)) { return call_user_func_array($name, $args); } } } $fn = new Fn(); ?>
Теперь любой вызов функции проходит через экземпляр $fn
. Таким образом, существующую функцию функции testfunction()
можно вызвать в heredoc с {$fn->testfunction()}
В основном мы обертываем все функции в экземпляр класса и используем метод __call magic
PHP для __call magic
метода класса с фактической функцией, которая должна быть вызвана.
Я немного опоздал, но я случайно наткнулся на него. Для будущих читателей, вот что я, вероятно, сделаю:
Я бы просто использовал выходной буфер. Таким образом, вы начинаете буферизацию с помощью ob_start (), затем включаете свой «файл шаблона» с любыми функциями, переменными и т. Д. Внутри него, получаете содержимое буфера и записываете их в строку, а затем закрываете буфер. Затем вы использовали любые переменные, которые вам нужны, вы можете запускать любую функцию, и у вас все еще есть подсветка синтаксиса HTML, доступная в вашей среде IDE.
Вот что я имею в виду:
Файл шаблона:
<?php echo "plain text and now a function: " . testfunction(); ?>
Автор сценария:
<?php ob_start(); include "template_file.php"; $output_string = ob_get_contents(); ob_end_clean(); echo $output_string; ?>
Таким образом, скрипт включает template_file.php в свой буфер, запускает любые функции / методы и назначает любые переменные на этом пути. Затем вы просто записываете содержимое буфера в переменную и выполняете то, что хотите.
Таким образом, если вы не хотите повторять это на странице прямо в эту секунду, вам не обязательно это делать. Вы можете выполнить цикл и продолжить добавление в строку перед ее выводом.
Я думаю, что это лучший способ пойти, если вы не хотите использовать шаблонный движок.
Этот фрагмент определит переменные с именем ваших определенных функций в пределах userscope и привяжет их к строке, содержащей одно и то же имя. Позвольте мне продемонстрировать.
function add ($int) { return $int + 1; } $f=get_defined_functions();foreach($f[user]as$v){$$v=$v;} $string = <<< heredoc plain text and now a function: {$add(1)} heredoc;
,function add ($int) { return $int + 1; } $f=get_defined_functions();foreach($f[user]as$v){$$v=$v;} $string = <<< heredoc plain text and now a function: {$add(1)} heredoc;
Сейчас будет работать.
Я думаю, использование heredoc отлично подходит для генерации HTML-кода. Например, я считаю следующее почти полностью нечитаемым.
<html> <head> <title><?php echo $page_title; ?></title> </head> <body> <?php echo getPageContent(); ?> </body>
Однако, чтобы добиться простоты, вы должны оценить функции перед тем, как начать. Я не считаю, что это такое ужасное ограничение, поскольку при этом вы в конечном итоге отделяете свои вычисления от отображения, что обычно является хорошей идеей.
Я думаю, что следующее достаточно читаемо:
$page_content = getPageContent(); print <<<END <html> <head> <title>$page_title</title> </head> <body> $page_content </body> END;
К сожалению, несмотря на то, что это было хорошее предложение, которое вы задали в своем вопросе, чтобы связать функцию с переменной, в конце она добавляет уровень сложности к коду, что не стоит, и делает код менее читаемым, что главное преимущество heredoc.
Я бы посмотрел на Smarty как на механизм шаблонов – я сам не пробовал никаких других, но он сделал меня хорошо.
Если вы хотите придерживаться своего текущего подхода без шаблонов, что плохого в буферизации вывода? Это даст вам гораздо большую гибкость, чем объявление переменных, которые являются именами названий функций, которые вы хотите вызвать.
нашел приятное решение с функцией обертывания здесь: http://blog.nazdrave.net/?p=626
function heredoc($param) { // just return whatever has been passed to us return $param; } $heredoc = 'heredoc'; $string = <<<HEREDOC \$heredoc is now a generic function that can be used in all sorts of ways: Output the result of a function: {$heredoc(date('r'))} Output the value of a constant: {$heredoc(__FILE__)} Static methods work just as well: {$heredoc(MyClass::getSomething())} 2 + 2 equals {$heredoc(2+2)} HEREDOC; // The same works not only with HEREDOC strings, // but with double-quoted strings as well: $string = "{$heredoc(2+2)}";
Для полноты вы также можете использовать черную магию !${''}
:
echo <<<EOT One month ago was ${!${''} = date('Ymd H:i:s', strtotime('-1 month'))}. EOT;
Вы в значительной степени описываете, что происходит в шаблоне. Вы, очевидно, хорошо знаете php. Вы рассматривали возможность взглянуть на фактический шаблонный двигатель?
Немного поздно, но все же. Это возможно в heredoc!
Посмотрите в руководстве по php, раздел «Комплексный (фигурный) синтаксис»,
Вот хороший пример с использованием предложения @CJDennis:
function double($i) { return $i*2; } function triple($i) { return $i*3;} $tab = 'double'; echo "{$tab(5)} is $tab 5<br>"; $tab = 'triple'; echo "{$tab(5)} is $tab 5<br>";
Например, хорошее использование синтаксиса HEREDOC – это генерация огромных форм с отношением master-detail в базе данных. Можно использовать функцию HEREDOC внутри элемента управления FOR, добавляя суффикс после каждого имени поля. Это типичная задача на стороне сервера.
Ребята должны отметить, что он также работает с строками с двойными кавычками.
http://www.php.net/manual/en/language.types.string.php
Интересный отзыв в любом случае.
<div><?=<<<heredoc Use heredoc and functions in ONE statement. Show lower case ABC=" heredoc . strtolower('ABC') . <<<heredoc ". And that is it! heredoc ?></div>
вы забыли о лямбда-функции:
$or=function($c,$t,$f){return$c?$t:$f;}; echo <<<TRUEFALSE The best color ever is {$or(rand(0,1),'green','black')} TRUEFALSE;
Вы также можете использовать функцию create_function
<?php echo <<<ETO <h1>Hellow ETO</h1> ETO;
тебе следует это попробовать . после окончания ETO; вы должны ввести ввод.