Вызов функций 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. Не то чтобы это плохо, но это объясняет мою инерцию... Я собираюсь найти способы облегчить жизнь, поэтому сейчас я ищу шаблоны.
16 ответов
Я бы не стал использовать 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());
Не уверен, что вы считаете это более элегантным...
Для полноты вы также можете использовать !${''}
взлом парсера черной магии:
echo <<<EOT
One month ago was ${!${''} = date('Y-m-d H:i:s', strtotime('-1 month'))}.
EOT;
Попробуйте это (либо как глобальную переменную, либо создайте ее в случае необходимости):
<?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()}
По сути, мы упаковываем все функции в экземпляр класса и используем 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 в свой буфер, выполняя любые функции / методы и назначая любые переменные по пути. Затем вы просто записываете содержимое буфера в переменную и делаете с ней все, что хотите.
Таким образом, если вы не хотите отображать его на странице прямо сейчас, вам не нужно этого делать. Вы можете зацикливаться и продолжать добавлять строку перед ее выводом.
Я думаю, что это лучший способ, если вы не хотите использовать шаблонизатор.
Нашел хорошее решение с функцией обтекания здесь: 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)}";
Этот фрагмент будет определять переменные с именами определенных вами функций в пределах области действия пользователя и связывать их со строкой, которая содержит то же имя. Позвольте мне продемонстрировать.
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;
Теперь будет работать.
Сегодня это немного элегантнее на php 7.x
<?php
$test = function(){
return 'it works!';
};
echo <<<HEREDOC
this is a test: {$test()}
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 как на движок шаблонов - я сам не пробовал никаких других, но он мне помог.
Если вы хотите придерживаться своего текущего подхода без шаблонов, что плохого в буферизации вывода? Это даст вам гораздо больше гибкости, чем объявление переменных, которые являются строковыми именами функций, которые вы хотите вызвать.
Вы забываете о лямбда-функции:
$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, добавляя суффикс после каждого имени поля. Это типичная задача на стороне сервера.
<div><?=<<<heredoc
Use heredoc and functions in ONE statement.
Show lower case ABC="
heredoc
. strtolower('ABC') . <<<heredoc
". And that is it!
heredoc
?></div>
Ребята должны заметить, что он также работает со строками в двойных кавычках.
http://www.php.net/manual/en/language.types.string.php
Интересный совет в любом случае.
<?php
echo <<<ETO
<h1>Hellow ETO</h1>
ETO;
тебе стоит попробовать это. после завершения ВТО; Команда, которую вы должны дать войти.