Вопрос

В 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 из IDEs
  • Выходные данные (HTML) привязаны к логическим файлам
  • В конечном итоге вам придется использовать хаки, подобные тому, что вы пытаетесь сделать сейчас, для создания более сложных шаблонов, таких как зацикливание

Получите базовый шаблонизатор или просто используйте PHP с includes - вот почему язык имеет <?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()}

По сути, мы оборачиваем все функции в экземпляр класса и используем 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 в свой буфер, запуская любые функции / методы и назначая любые переменные по пути.Затем вы просто записываете содержимое буфера в переменную и делаете с ним все, что хотите.

Таким образом, если вы не хотите повторять это на странице прямо в эту секунду, вам не нужно этого делать.Вы можете выполнять цикл и продолжать добавлять к строке перед ее выводом.

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

Для полноты картины вы также можете использовать !${''} черная магия взлом синтаксического анализатора:

echo <<<EOT
One month ago was ${!${''} = date('Y-m-d H:i:s', strtotime('-1 month'))}.
EOT;

Этот фрагмент определит переменные с именем ваших определенных функций в 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;

Теперь будет работать.

Я думаю, что использование 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.

нашел хорошее решение с функцией переноса здесь: 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)}";

Я бы взглянул на Умный как шаблонизатор - я сам не пробовал никаких других, но это сослужило мне хорошую службу.

Если вы хотите придерживаться своего нынешнего подхода sans шаблоны, что такого плохого в буферизации вывода?Это даст вам гораздо больше гибкости, чем необходимость объявлять переменные, которые являются простыми именами функций, которые вы хотите вызвать.

Немного поздно, но все же.Это возможно в 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 внутри a ДЛЯ управления, добавляя суффикс после каждого имени поля.Это типичная задача на стороне сервера.

вы забываете о лямбда-функции:

$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

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

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
echo <<<ETO
<h1>Hellow ETO</h1>
ETO;

тебе стоит попробовать это .после завершения ETO;команда, которую вы должны дать, вводится.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top