2016-06-17 7 views
4

Smartyのようなテンプレートエンジンを使わずにプレゼンテーションとロジックを分離しようとしています。私がこれまで行ってきたことは動いていますが、私が望むよりも多くのPHPを自分のプレゼンテーションに入れずに、特定のことをどうやって行うのかはわかりません。例えば、今、私はこのようなものがあります:プレゼンテーション(HTML)とロジック(PHP)を別々に保つ

product_list.php

try { 
     $query = $conn->prepare("SELECT p.id, p.name, p.description, IFNULL(url, title) AS url, GROUP_CONCAT(c.category SEPARATOR ', ') AS category, 
      FROM products p 
      LEFT JOIN product_categories pc ON p.id = pc.product_id 
      LEFT JOIN categories c ON pc.category_id = c.id 
      WHERE p.active = 1 
      GROUP BY p.id"); 
     $query->execute(); 
     $result = $query->fetchAll(PDO::FETCH_ASSOC); 
    } 
    catch (PDOException $e) { 
      echo $e->getMessage(); 
    } 
include('templates/product_list_tpl.php'); 

product_list_tpl.php

<div class="card"> 
    <div class="product-list with-header"> 
     <div class="product-list-header center-align"> 
      <h2><?= $header_title; ?></h2> 
     </div> 
     <?php foreach ($result as $row): ?> 
      <!-- Some Product Info --> 
      Category:&nbsp;<?= $row['category']; ?> 
     <?php endforeach; ?> 
    </div> 
</div> 

上記の例では、いくつかの製品が一つのカテゴリを持つことになりますが、いくつかは複数あります。カンマ区切りのリストでうまく表示されますが、カテゴリ名をリンクにしたいと考えています。私は私が以下のようなことをすることができることを知っているが、それは私にとっては厄介なようだ。

<div class="card"> 
    <div class="product-list with-header"> 
     <div class="product-list-header center-align"> 
      <h2><?= $div_title; ?></h2> 
     </div> 
     <?php foreach ($result as $row): ?> 
      <?php $categories = explode(', ', $row['category']); ?> 
      <div class="product-list-item avatar"> 
       <img src="img/product/<?= $row['id']; ?>.jpg" alt="<?= $row['title']; ?>" class="square"> 
       <a href="product/<?= generate_link($row['url']); ?>" class="title bold"><?= $row['title']; ?></a> 
       <p class="caption"><?= $row['caption']; ?></p> 
       <div class="item-bottom"> 
        <span class="responsive"><?= $row['description']; ?></span> 
        <p> 
         Category:&nbsp; 
         <?php foreach ($categories as $key => $category): ?> 
          <a href="category/<?= strtolower($category); ?>"><?= $category; ?></a> 
          <?= (sizeof($categories) > 1 && $key == end($categories)) ? ',&nbsp;' : ''; ?> 
         <?php endforeach; ?> 
        </p> 
        <p> 
         <span>Rating:&nbsp;<?= $row['rating']; ?></span> 
         <span class="right">Rated&nbsp;<?= $row['rated']; echo ($row['rated'] == 1) ? '&nbsp;time' : '&nbsp;times'; ?></span> 
        </p> 
       </div> 
      </div> 
     <?php endforeach; ?> 
    </div> 
</div> 

ありがとうございます。また、私がサンプルコードで使用した一般的な分離形式の入力を誰かが持っているなら、それを聞いてみたいと思います。私はちょうど8年の休憩の後にコーディングに戻っています。

編集:コメントが示唆した@Devonによると、endforeachが追加され、3番目のコードブロックのインデントが改善されました。

EDIT:私が以前に除外したHTMLを含むように3番目のコードブロックを更新し、探している出力を得るために必要なすべてのPHP機能を追加しました。それは動作しますが、IMOはこのようにして、私が持っていた小さな分離を取り除きます。私は今、基本的には、私のデータベース呼び出しで1つのファイルと、この混乱で別のファイルを持っています。私は、適切なビジネスロジック/プレゼンテーションロジック分離のために正しい方向に進まないような気がします。

どこが間違っていますか?

+3

phpの代わりに、これはちょうどわずかに異なる構文で、これに似ています。 IMOは、テンプレート言語を使用する唯一の本当の利点は、特定のセクションでPHPへのアクセスを制限することです。 – jeroen

+3

私はあなたの例に何か間違っているとは思わない。 foreachで反復することは完全に正常です。インデントを修正して読みやすくし、2番目のforeachを閉じるようにしてください。 – Devon

+1

@jeroenテンプレート言語には他にも多くの利点があります。レイアウトを拡張し、コンテンツのセクションと定義するセクションを定義することは、巨大なものです。また、プレゼンテーション層の依存関係としてPHPを削除したい人もいます。 – Devon

答えて

3

長尺のような複雑な論理:
(sizeof($categories) > 1 && $key == end($categories)) ? ',&nbsp;' : '';
は、フロントエンド開発者を邪魔する図であってはなりません。このコードラインは何ですか? これはどうしますか?バックエンドの開発者が私に何かより使いやすいものを与えなかったのはなぜですか? MVCの力の一部は懸念の分離だけでなく、バ​​ックエンドとフロントエンドの開発者の作業を分離して維持する です。

<?php foreach ($result as $row): ?>のようなコードには、動作していることに関する情報が含まれていません。 DIV、Ps、およびSPANも制御不能です。
これは私がビューヘルパーのファンである理由です。私がお勧めしたい

function displayItems($items) 
{ 
    foreach ($items as $item) 
    { 
     $categories = explode(', ', $item['category']); 
     $id = $item['id']; 
     $title = $item['title']; 
     $url = $item['url']; 
     $caption = $item['caption']; 
     $description = $item['description']; 
     $rating = $item['rating']; 
     $rated = $item['rated']; 
     include('product_list_item_tpl.php'); 
    } 
} 

product_list_item_tpl:

product_list_tpl.php

<div class="card"> 
    <div class="product-list with-header"> 
     <div class="product-list-header center-align"> 
      <h2><?= $div_title; ?></h2> 
     </div> 
     <?= displayItems($items); ?> 
    </div> 
</div> 

ビューヘルパーは、上記使用します。PHP

<div class="product-list-item avatar"> 
    <img src="img/product/<?= $id; ?>.jpg" alt="<?= $title; ?>" class="square"> 
    <a href="product/<?= generate_link($url); ?>" class="title bold"><?= $title; ?></a> 
    <p class="caption"><?= $caption; ?></p> 
    <div class="item-bottom"> 
    <span class="responsive"><?= $description; ?></span> 
    <p> 
     Category:&nbsp; 
     <?php displayCategories($categories); ?> 
    </p> 
    <p> 
     <span>Rating:&nbsp;<?= $rating; ?></span> 
     <span class="right">Rated&nbsp;<?= $rated; ?>&nbsp;<?= isPluarl($rated)?'times':'time'; ?></span> 
    </p> 
    </div> 
</div> 

上で使用ビューヘルパー:私はあなたが前に使用していたものから$key == end($categories)一部を反転

function isPlural($number) 
{ 
    return $number != 1; 
} 

function displayCategories($categories) 
{ 
    $last = end($categories); 
    $count = sizeof($categories); 
    foreach ($categories as $key => $category) 
    { 
     $cat = strtolower($category); 
     $isLast = $category == $last; 
     include('product_list_category_tpl.php'); 
    } 
} 

product_list_category_tpl.php

<a href="category/<?= $cat; ?>"><?= $category; ?></a> 
<?= ($count > 1 && !$isLast) ? ',&nbsp;' : ''; ?> 

注意!$isLast$key$categoryにスワップしました。このロジックは、2つのカテゴリが同じ名前を持つ可能性があるため、依然として汚いと感じます。おそらくcount($categories)$i++を併用すると、それが最後のループかどうかを判断する方がよいでしょう。

編集:これはうまく動作し、それが値ではなくキーに依存しているような従来上記の問題を回避し
:あなたが使用するどのようなテンプレート言語この周りに現実的な方法は、ありません

function displayCategories($categories) 
{ 
    end($categories); 
    $last = key($categories); 
    $count = sizeof($categories); 
    foreach ($categories as $key => $category) 
    { 
     $cat = strtolower($category); 
     $isLast = $key == $last; 
     include('product_list_category_tpl.php'); 
    } 
} 
+0

詳細な返信いただきありがとうございます。これはちょうど私が探していた答えのようなものです。それは間違いなく私の論理を適切に分離する正しい道を私に手伝ってくれました。 – Jay

関連する問題