web-dev-qa-db-ja.com

PHPを介してHTMLを挿入する最良の方法は何ですか?

「ベストプラクティス」の観点から言えば、PHPを使用してHTMLを挿入するための最良の方法は何だと思いますか。今のところ、私は次のいずれかの方法(ほとんどは後者)を使用していますが、どちらが最適だと思うか知りたいです。

<?php
  if($a){
?>
[SOME MARKUP]
<?php
  }
  else{
?>
[SOME OTHER MARKUP]
<?php
  }
?>

とは対照的に:

<?php
  unset($out);
  if($a) $out = '[SOME MARKUP]';
  else $out = '[OTHER MARKUP]';
  print $out;
?>
26
Brayn

あなたがそのように物事を行うつもりなら、あなたはあなたの論理とデザインを分離したいと思うでしょう、本当です。

ただし、これを行うためにSmartyを使用する必要はありません。

優先順位は考え方についてです。私は人々がSmartyで衝撃的なことをするのを見ました、そしてそれは最終的にサイトを開発する人々に変わりますin Smarty、そしてそれからいくつかの明るいsparkは彼らがテンプレートを書く必要があると決めるでしょうSmartyのエンジン(ばかげたアイデアの可能性を過小評価しないでください)。

コードを2つの部分に分割し、標準に準拠するように強制すると、パフォーマンスが大幅に向上します。

PageLogic.php

<?php 

  $pageData = (object)(array());  // Handy trick I learnt. 

  /* Logic Goes here */


 $pageData->foo = SomeValue; 

 ob_start(); 
 require("layout.php"); 
 ob_end_flush();

Layout.php

 <html>
   <!-- etc -->
   <?php for ( $i = 1; $i < 10; $i++ ){ ?>
    <?php echo $pageData->foo[$i]; ?>
   <?php } ?>
   <!-- etc -->
</html>

PHPはテンプレートエンジンとして作成されているため、Smartyを詳しく調べる必要があるかどうかを評価する前に、少なくともtryして設計されたタスクに使用する必要があります。 。


さらに、テンプレートエンジンを使用する場合は、HTMLをデフォルトでエスケープするものを入手してみてください。そうすると、「オプトイン」ではなく「オプトアウト」します。 XSSの頭痛の種をたくさん減らすことができます。 Smartyはこの点で弱く、そのため、コンテンツにナイーブなテンプレートがたくさん書かれています。

{if $cond}
    {$dangerous_value}
{else}
    {$equally_dangerous_value}
{/if}

一般的に、Smartyテンプレートの使い方です。問題は$ dangerous_valueが任意のHTMLである可能性があることであり、これはさらにmoreどこにでも追跡不可能なスパゲッティコードを使用した悪いコーディング慣行につながります。

検討するテンプレート言語shouldこの懸念に応えます。例えば。:

{$code_gets_escaped} 
{{$code_gets_escaped_as_a_uri}}
{{{$dangerous_bare_code}}}

このように、悪用への入り口が[〜#〜] default [〜#〜]の動作であるのとは対照的に、悪用の可能性のある出入り口はテンプレートで簡単に識別できます。

25
Kent Fredric

-典型的なヒステリックな「代わりに[私のお気に入りのテンプレートシステム]を使用してください!」の投稿には-1。すべてのPHP投稿、ネイティブPHP回答がワンライナーであっても、すべてのワンライナーJavaScript質問がいっぱいになるのと同じように、常にこれに縮退します「代わりに[私のお気に入りのフレームワーク]を使用してください!」。恥ずかしいです。

真剣に、私たちは知っているビジネスロジックとプレゼンテーションの懸念を分離することについて。 PHP、Smarty、またはまったく異なるものを問わず、任意のテンプレートシステムでそれを行うことができます—またはnotそれを行う—。たくさんの考えなしにあなたの懸念を魔法のように分離するテンプレートシステムはありません。

(実際、制限が厳しすぎるテンプレートシステムでは、純粋にプレゼンテーション用の補助コードを記述しなければならず、プレゼンテーション上の懸念でビジネスロジックが乱雑になる可能性があります。これは勝利ではありません!)

尋ねられた質問に答えるために、最初の例はOKですが、インデントが悪いために読むのが非常に困難です。より読みやすい方法については、monzeeの例を参照してください。 :表記または{}のいずれかを使用できますが、読みやすくするために重要なことは、HTMLとPHPを単一の「整形式」のインデントされた階層として保持することです。

そして最後の嘆願:htmlspecialchars()を覚えておいてください。プレーンテキストがWebページに入る必要があるたびに、これ必須を使用するか、フロア全体でXSSを使用します。この質問がそれに直接関係していないことは知っていますが、<?php echo($ title)?>を含むサンプルコードまたはエスケープせずに同等のフレームワークを投稿するたびに、セキュリティ災害地域の継続を奨励しています。ほとんどのPHPアプリになっています。

14
bobince

最も重要な考慮事項は、ロジックをプレゼンテーションから分離しておくことです。結合が少ないほど、両方に対する将来の変更がはるかに簡単になります。

smarty のようなある種のテンプレートシステムの使用を検討することもできます。

7
Ken

このような非常に単純なケースでは、PHPをテンプレートとして使用することは問題ありません。ただし、単純なロジックを超える場合(そしておそらくそうなるでしょう)、使用することをお勧めします。テンプレートエンジン。

デフォルトでPHPビュースクリプトを使用するZendFrameworkでは、これを行うための推奨される方法は次のようになります。

<?php if ($a) : ?>
    [MARKUP HERE]
<?php else : ?>
    [SOME MORE MARKUP]
<?php endif ?>

構文がより冗長になると、中括弧を使用するよりも、条件付きブロックを一目で照合するのがはるかに簡単になります。

4
monzee

テンプレートエンジンを使用して、ロジック(PHPコード)をプレゼンテーション(HTML)から完全に分離することをお勧めします。

PHPをHTMLに挿入するのは速くて簡単ですが、非常に速く面倒になり、保守が非常に困難です。これはvery迅速で非常に汚いアプローチ..

PHPで利用可能なすべてのテンプレートエンジンのどれが優れているかについては、たとえば次の質問を参照してください。

2
Treb

必須いずれかの方法で行う場合は、中括弧を使用してください。 PHPでHTMLをエコーし​​ないでください。

1
PartialOrder

テンプレートエンジンが非常に面倒だと思われる場合は、独自の貧乏人のテンプレートエンジンを作成できます。この例は間違いなく改善されるべきであり、すべてのタスクに適しているわけではありませんが、小規模なサイトには適している可能性があります。あなたにアイデアを与えるためだけに:

template.inc:

<html><head><title>%title%</title></head><body>
%mainbody%
Bla bla bla <a href="%linkurl%">%linkname%</a>.
</body></html>

index.php:

<?php
$title = getTitle();
$mainbody = getMainBody();
$linkurl = getLinkUrl();
$linkname = getLinkName();
$search = array("/%title%/", "/%mainbody%/", "/%linkurl%/", "/%linkname%/");
$replace = array($title, $mainbody, $linkurl, $linkname);
$template = file_get_contents("template.inc");
print preg_replace($search, $replace, $template);
?>
1
neu242

フレームワークを使用していない場合、または独自のテンプレートシステムを持たないフレームワークを使用している場合は、Smartyは問題ありません。

それ以外の場合、ほとんどのPHPフレームワークと若い世代のCMSには、独自のテンプレートシステムがあります。

一般に、テンプレートシステムの概念は、ほとんどHTMLのみを含むファイル(ビュー/テンプレートファイル)と、データまたはビジネスロジックのみを含むファイル(モデルファイルまたはコントローラーファイル)を持つことです。

テンプレートファイルは次のようになります(SilverStripeの例)。

<?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <% base_tag %>
        $MetaTags
        <link rel="stylesheet" type="text/css" href="tutorial/css/layout.css" />
    </head>
    <body>
        <div id="Main">
            <ul id="Menu1">
                <% control Menu(1) %>
                <li class="$LinkingMode">
                    <a href="$Link" title="Go to the &quot;{$Title}&quot; page">$MenuTitle</a>
                </li>
                <% end_control %>
            </ul>
            <div id="Header">
                <h1>$Title</h1>
            </div>
            <div id="ContentContainer">
                $Layout
            </div>
            <div id="Footer">
                <span>Some Text</span>
            </div>
        </div>
     </body>
</html>

ページがクライアントに送信される前にデータが挿入される場所に挿入される非HTMLコード部分はごくわずかであることがわかります。

その場合、コードは(簡略化して)次のようになります。

<?php
  unset($out);
  if($a) $out = '[SOME CONTENT TO INSERT INTO THE TEMPLATE]';
  else $out = '[SOME ALTERNATIVE CONTENT]';
  templateInsert($out);
?>

それの素晴らしいところ:あなたのHTMLはそのように見え、そのように変更されることができ、あなたのデザイナーはそれを理解することができ、彼女がしていることを見てください。一方、ページ上でどのように表示されるかを心配することなく、ロジックを変更できます。コードがコンパクトで読みやすいため、間違いが少なくなる可能性があります。

1
markus

私が最初にPHPを使い始めたときに知っておいてほしいことがあります。それは、手間のかかるプログラムコードをHTML出力からできるだけ遠ざけることです。そうすれば、両方とも大きく、かなり連続した、読み取り可能なチャンクにとどまります。

これを行うための最良の方法は、静的HTMLファイルを作成することです最初、おそらくいくつかの偽のデータを使用して、デザインを正しく調べてから、PHP出力の動的な部分を取得し、両方を接着するコード(その部分をどのように行うかはあなた次第です-他の人が示唆しているようにSmartyでそれを行うことができます)。

1
user42092

どちらでもない。 Smarty を使用します。内部ロジックを表示ロジックから分離することにより、保守がはるかに簡単なコードを構築できます。 (PHPとHTMLを完全に分離しようとしたPHPLibの古いテンプレートシステムのパスをとらないでください。表示ロジックをコアビジネスロジックと混合する必要があり、非常に面倒です。)絶対にPHPコードでHTMLスニペットを生成する必要があります。2番目のメソッドを使用しますが、変数をSmartyに渡します。

1
Jeremy Weathers

Smartyを使用しないでください-PHPはそれ自体がテンプレートシステムです。次の構文の使用を検討してください。

<?php if($a):?>
[SOME MARKUP]
<?php else: ?>
[SOME OTHER MARKUP]
<? endif; ?>
0
adnam