99

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 スタイルを逆にする必要があります。それは悪いことではありませんが、それは私の慣性を説明しています..私は人生を楽にする方法を考え出すつもりなので、今テンプレートを調べています.

4

17 に答える 17

76

本当にこれを行いたいが、クラスを使用するよりも少し簡単な場合は、次を使用できます。

function fn($data) {
  return $data;
}
$fn = 'fn';

$my_string = <<<EOT
Number of seconds since the Unix Epoch: {$fn(time())}
EOT;
于 2012-05-23T04:06:59.510 に答える
53

個人的には、このためにHEREDOCをまったく使用しません。それは、優れた「テンプレート構築」システムにはなりません。すべてのHTMLは文字列に固定されますが、これにはいくつかの欠点があります。

  • WYSIWYGのオプションはありません
  • IDEからのHTMLのコード補完はありません
  • ロジックファイルにロックされた出力(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');
于 2008-09-19T19:10:54.043 に答える
45

私は次のことをします:

$string = <<< heredoc
plain text and now a function: %s
heredoc;
$string = sprintf($string, testfunction());

これがよりエレガントだと思うかどうかはわかりません...

于 2008-09-19T18:59:53.973 に答える
17

完全を期すために、!${''} 黒魔術の パーサー ハックを使用することもできます。

echo <<<EOT
One month ago was ${!${''} = date('Y-m-d H:i:s', strtotime('-1 month'))}.
EOT;
于 2016-03-24T14:31:31.647 に答える
17

これを試してください(グローバル変数として、または必要に応じてインスタンス化してください):

<?php
  class Fn {
    public function __call($name, $args) {
      if (function_exists($name)) {
        return call_user_func_array($name, $args);
      }
    }
  }

  $fn = new Fn();
?>

これで、すべての関数呼び出しがインスタンスを通過し$fnます。したがって、既存の関数testfunction()はヒアドキュメントで次のように呼び出すことができます{$fn->testfunction()}

基本的に、すべての関数をクラス インスタンスにラップし、PHP の__call magicメソッドを使用して、呼び出す必要がある実際の関数にクラス メソッドをマップします。

于 2009-12-22T18:11:55.970 に答える
10

少し遅れましたが、たまたま見つけました。将来の読者のために、私がおそらく行うことは次のとおりです。

出力バッファを使用するだけです。したがって、基本的には、ob_start() を使用してバッファリングを開始し、その中に関数や変数などを含む「テンプレート ファイル」を含め、バッファの内容を取得して文字列に書き込み、バッファを閉じます。次に、必要な変数をすべて使用し、任意の関数を実行できます。IDE で HTML 構文の強調表示を引き続き使用できます。

これが私が意味することです:

テンプレート ファイル:

<?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 をバッファーに含め、関数/メソッドを実行し、途中で変数を割り当てます。次に、バッファの内容を変数に記録し、それを使ってやりたいことを実行します。

そうすれば、その瞬間にページにエコーしたくない場合でも、そうする必要はありません。出力する前に、ループして文字列に追加し続けることができます。

テンプレート エンジンを使用したくない場合は、これが最善の方法だと思います。

于 2009-09-06T20:49:04.003 に答える
6

このスニペットは、ユーザースコープ内で定義した関数の名前で変数を定義し、それらを同じ名前を含む文字列にバインドします。実演させてください。

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;

今すぐ動作します。

于 2010-12-08T13:02:34.787 に答える
5

ヒアドキュメントを使用すると、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;

残念ながら、質問で関数を変数にバインドすることは良い提案でしたが、最終的にはコードに複雑さのレベルが追加され、価値がなくなり、コードが読みにくくなります。ヒアドキュメントの主な利点。

于 2011-06-17T10:54:50.923 に答える
4

テンプレート エンジンとしてSmartyを見てみたいと思います。自分で他のエンジンを試したことはありませんが、うまくいきました。

テンプレートを使用しない現在のアプローチに固執したい場合、出力バッファリングの何が悪いのでしょうか? 呼び出したい関数の文字列名である変数を宣言するよりもはるかに柔軟です。

于 2008-09-19T23:42:49.287 に答える
2

@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 構文の適切な使用法は、データベースで主従関係を持つ巨大なフォームを生成することです。FOR コントロール内で HEREDOC 機能を使用して、各フィールド名の後にサフィックスを追加できます。これは典型的なサーバー側のタスクです。

于 2013-01-18T04:24:58.050 に答える
2

少し遅れましたが、まだです。これはヒアドキュメントで可能です!

PHPマニュアルの「複雑な(中)構文」セクションをご覧ください

于 2011-04-08T22:58:01.283 に答える
1

二重引用符で囲まれた文字列でも機能することに注意してください。

http://www.php.net/manual/en/language.types.string.php

とにかく興味深いヒント。

于 2010-05-10T11:20:13.147 に答える