В 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. Не то чтобы это плохо, но это объясняет мою инерцию ... Я за то, чтобы придумать способы облегчить жизнь, поэтому сейчас я изучаю шаблоны.
Text {$string1} Text {$string2} Text
heredoc.Ответы:
Лично я бы вообще не использовал 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');
источник
<?=$valueToEcho;?>
или<%=$valueToEcho;%>
зависит от ваших настроек INI.<?=$title?>
это намного лучше, чем <? Php echo $ title; ?>. Обратной стороной является то, что для распространения многие ini имеют короткие теги. Но знаете что ?? Начиная с PHP 5.4 , короткие теги включены в PHP независимо от настроек ini! Так что, если вы кодируете с требованием 5.4+ (допустим, вы используете черты характера, например), продолжайте и используйте эти замечательные короткие теги !!Если вы действительно хотите сделать это, но немного проще, чем использование класса, вы можете использовать:
function fn($data) { return $data; } $fn = 'fn'; $my_string = <<<EOT Number of seconds since the Unix Epoch: {$fn(time())} EOT;
источник
$my_string = "Half the number of seconds since the Unix Epoch: {$fn(time() / 2 . ' Yes! Really!')}";
$fn = function fn($data) { return $data; };
$fn = function ($data) { return $data; };
$fn=function($data){return $data;};
Я бы сделал следующее:
$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_user_func_array
, последний раз в комментариях на php.net: php.net/manual/en/function.call-user-func-array.php # 97473Для полноты картины можно также использовать взлом парсера
!${''}
черной магии:echo <<<EOT One month ago was ${!${''} = date('Y-m-d H:i:s', strtotime('-1 month'))}. EOT;
источник
false == ''
. Определите переменную с именем длины 0 (''
). Установите желаемое значение (${''} = date('Y-m-d H:i:s', strtotime('-1 month'))
). Отменить его (!
) и преобразовать в переменную (${false}
).false
необходимо преобразовать в строку, а(string)false === ''
. Если вы попытаетесь напечатать ложное значение, вместо этого появится ошибка. Следующая строка работает как truthy и falsy значений, за счет того , чтобы быть еще более нечитаемым:"${(${''}=date('Y-m-d H:i:s', strtotime('-1 month')))!=${''}}"
.NAN
, используйте"${(${''} = date('Y-m-d H:i:s', strtotime('-1 month')) )==NAN}"
.Я немного опоздал, но случайно наткнулся на это. Для будущих читателей вот что я, вероятно, сделал бы:
Я бы просто использовал выходной буфер. Таким образом, вы начинаете буферизацию с помощью 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 в свой буфер, выполняя любые функции / методы и по ходу назначая любые переменные. Затем вы просто записываете содержимое буфера в переменную и делаете с ней все, что хотите.
Таким образом, если вы не хотите отображать его на странице прямо в эту секунду, вам не нужно. Вы можете зацикливаться и продолжать добавлять к строке перед ее выводом.
Я думаю, что это лучший вариант, если вы не хотите использовать движок шаблонов.
источник
Этот фрагмент будет определять переменные с именами ваших определенных функций в пределах пользовательской области и связывать их со строкой, содержащей то же имя. Позвольте мне продемонстрировать.
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;
Теперь будет работать.
источник
нашел хорошее решение с функцией обертывания здесь: 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)}";
источник
Я думаю, что использование 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 как на шаблонизатор - я сам не пробовал никаких других, но он мне хорошо помог.
Если вы хотели придерживаться своего текущего подхода без шаблонов, что плохого в буферизации вывода? Это даст вам гораздо больше гибкости, чем необходимость объявления переменных, которые являются строковыми именами функций, которые вы хотите вызвать.
источник
вы забываете о лямбда-функции:
$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
источник
Немного поздно, но все же. Это возможно в 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 можно использовать для создания огромных форм с отношениями "главный-подробный" в базе данных. Можно использовать функцию 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>
источник
Сегодня это немного более элегантно на php 7.x
<?php $test = function(){ return 'it works!'; }; echo <<<HEREDOC this is a test: {$test()} HEREDOC;
источник
<?php echo <<<ETO <h1>Hellow ETO</h1> ETO;
тебе стоит попробовать это . после окончания ВЭТО; команда вы должны дать ввод.
источник