Вызов функций PHP внутри строк HEREDOC

В 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 заблокирован в строке, которая имеет несколько недостатков

  • Нет опции для WYSIWYG
  • Отсутствие завершения кода для HTML из IDE
  • Выход (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; вы должны ввести ввод.