29

「ベスト プラクティス」の観点から言えば、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;
?>
4

11 に答える 11

27

そういうことをやるなら、ロジックとデザインを分けたいですね。

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

優先すべきは考え方です。私は人々が Smarty で衝撃的なことを行い、最終的には Smarty でサイトを開発する人々になるのを見てきました。そして、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 を詳しく調べる必要があるかどうかを判断する前に、少なくともその設計されたタスクに PHP を使用してみてください。


さらに、テンプレート エンジンを使用することにした場合は、デフォルトで HTML をエスケープするエンジンを入手してみてください。「オプトイン」ではなく「オプトアウト」します。XSS の頭痛の種を大幅に節約できます。Smarty はこの点で弱く、そのため、内容にナイーブなテンプレートが多数記述されています。

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

一般的に、Smarty テンプレートがどのように機能するかです。問題は、$dangerous_value が任意の HTML になる可能性があることです。これにより、どこにでも追跡不可能なスパゲッティ コードを含む、さらに悪いコーディング プラクティスが発生することになります。

あなたが検討するテンプレート言語は、この懸念に応える必要があります。例えば:

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

このように、搾取への入り口がデフォルトの動作であるのとは対照的に、搾取への潜在的な入り口がテンプレートで簡単に識別できます。

于 2008-11-04T11:11:33.783 に答える
14

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

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

(実際、制限が厳しすぎるテンプレート システムは、純粋に表示目的の補助コードを書かなければならなくなり、表示上の問題でビジネス ロジックを混乱させる可能性があります。これは得策ではありません!)

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

最後に、htmlspecialchars() を思い出してください。Web ページにプレーン テキストを入力する必要がある場合は常に、これを使用する必要があります。そうしないと、いたるところで XSS になります。この質問がそれと直接関係ないことは承知していますが、 < ?php echo($title) ?> を含むサンプル コードまたはエスケープなしの同等のフレームワークを投稿するたびに、セキュリティ災害領域の継続を奨励しています。ほとんどの PHP アプリは次のようになりました。

于 2008-11-04T11:40:02.493 に答える
7

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

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

于 2008-11-04T09:34:32.857 に答える
4

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

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

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

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

于 2008-11-04T09:58:24.867 に答える
1

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

PHPをHTMLに挿入するのは高速で簡単ですが、非常に高速になり、保守が非常に困難になります。それは非常に迅速で非常に汚いアプローチです...

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

于 2008-11-04T09:48:06.730 に答える
1

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

于 2008-11-04T09:37:28.887 に答える
1

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

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);
?>
于 2008-11-04T09:57:57.007 に答える
1

フレームワークを使用していない場合、または独自のテンプレート システムを持たないフレームワークを使用している場合は、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 の素晴らしいところは、HTML をそのように見て、そのように変更できることです。デザイナーは HTML を理解することができ、さまざまな場所からビットとピースをまとめようとしてコードを調べる必要がありません。彼女が何をしているかを見てください。一方、ページでどのように表示されるかを気にすることなく、ロジックを変更できます。コードがコンパクトになり、読みやすくなるため、おそらく間違いも少なくなります。

于 2008-11-04T10:05:47.550 に答える
1

PHP を使い始めたときに知っていればよかったと思うこと: 重いものを扱うプログラム コードは、HTML 出力からできるだけ離すこと。そうすれば、それらは両方とも、大きく、かなり連続した、読み取り可能なチャンクにとどまります。

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

于 2008-12-02T00:56:44.353 に答える
0

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

<?php if($a):?>
[SOME MARKUP]
<?php else: ?>
[SOME OTHER MARKUP]
<? endif; ?>
于 2008-11-04T10:13:59.203 に答える