質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Smarty

Smartyは、PHPアプリケーションで使用されるテンプレートエンジンです。

EC-CUBE

EC-CUBEは、主に日本国内で開発されているECコンテンツ管理システムです。ロックオン社のECKitを元にしてオープンソース化され、商品管理・受注管理・顧客管理・売上集計などECに特化した様々な機能を備えています。

Q&A

解決済

3回答

5492閲覧

【Smarty】foreachにて配列の中身を出力する際、内容が同じ要素は出力しないようにしたい

katsuo_isono

総合スコア63

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Smarty

Smartyは、PHPアプリケーションで使用されるテンプレートエンジンです。

EC-CUBE

EC-CUBEは、主に日本国内で開発されているECコンテンツ管理システムです。ロックオン社のECKitを元にしてオープンソース化され、商品管理・受注管理・顧客管理・売上集計などECに特化した様々な機能を備えています。

0グッド

0クリップ

投稿2016/04/28 03:20

【やりたいこと】
Smartyのtpl内でforeachを使って配列の中身を出力する際、内容が全く同じ要素がある場合、その要素は出力しないようにしたい

【現状】
同じ要素が複数出力されてしまっている

【背景】
EC-CUBE2.13を使用してサイトを作成しています。
list.tplで「ある特定のカテゴリーの商品において、その商品すべてのメーカーの一覧を表示させる」という処理を記述しています。
コードは下記の通りです。

list.tpl

1 <!--▼メーカー一覧--> 2 <!--{if $arrSearchData.category_id == 1}--><!-- 特定のカテゴリーページのみ表示 --> 3 <ul class="makerlist_area"> 4 <!--{foreach from=$arrAllProducts item=maker name=foo}--> 5 <li class="maker_name">・<a href="<!--{$smarty.const.ROOT_URLPATH}-->products/list.php?category_id=1&maker_id=<!--{$maker.maker_id|h}-->"><!--{$maker.maker_name|h}--></a></li> 6 <!--{/foreach}--> 7 </ul> 8 <!--{/if}--> 9 <!-- ▲メーカー一覧--> 10

代替案として、JSを用いて「makerlist_areaクラスの中で、全く同じ要素が存在する場合1つだけ表示させる処理を加える」というアイデアも思いついたのですが、
どうせなら綺麗にforeachの中で処理したいと思い、何かいい方法がないか、投稿させて頂きました。

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

選抜メーカーリスト用のブロックを追加して
templateに渡す前に配列をフィルタリングしたほうがいいと思います。

--------------以下 追記--------------
私ならこうするかな?..的なところを大まかに追記しておきます

Smartyにはtemplate上でarray_uniqueを実行する関数は用意されていませんので
あらかじめ 必要なデータを絞り込んで 配列を作り直す必要があると思います、

まず、EC-CUBEの管理画面→デザイン設定→ブロック設定から ブロックを新規に作成
(ここでは仮にブロック名:メーカーリスト ファイル名:maker_list.tplとします)

データベースのdtb_blocテーブルに追加されたメーカーリストのレコード上でphp_pathフィールドにphpのパスを指定します。
(何処のディレクトリでも構いませんがここでは解かり易く仮に frontparts/bloc/maker_list.phpとします)

EC-CUBE内のディレクトリhtmlfrontpartsblocフォルダーにデータベースのdtb_blocで指定したmaker_list.phpを設置します。

一先ずここまでの操作で 管理画面→デザイン設定→レイアウト設定で必要なページにメーカーリストブロックを配置すればmaker_list.phpの内容がサイト内に表示されるようになります。

maker_list.phpの内容ですが..今回は登録済みのデータを抜粋して表示するだけですので、面倒なEC-CUBE独自の手順を踏んでテンプレートを介さなくても
PHPで直接データを出力してセキュリティー上、何の問題もないと思います。

php

1<?php 2 3if(isset($_GET['category_id'])){ 4・・・・・・・・・//`$_GET['category_id']`にエスケープ処理くらいは必要 5}else{ 6・・・・・・・・・ 7} 8 9require_once realpath(dirname(__FILE__)) . '/../../../data/config/config.php'; 10//(data/frontparts/bloc/からのパスを想定 EC-CUBEで登録したDB情報の定数を取得) 11 try { 12 $pdo = new PDO(DB_TYPE.':host='.DB_SERVER.';dbname='.DB_NAME.';charset=utf8',DB_USER,DB_PASSWORD,array(PDO::ATTR_EMULATE_PREPARES => false)); 13 //これで繋がるはずです。 14 $pdo->query('SET NAMES utf8'); 15 $stmt = $pdo->query("********"); 16 17 ・・・・・・・・・ 18 ・・・・・・・・・ 19 ・・・・・・・・・ 20 } catch (PDOException $e) { 21 exit($e->getMessage()); 22 } 23 24//あとは`foreach`なりなんなりで`echo `なり`print`なり

//こんな感じで必要な処理を記述してください。

ちなみに.dtb_productsテーブルとdtb_makerテーブルは 双方のmaker_idフィールドで直接紐付されていますがdtb_categorydtb_products_classで繋がってます。
DBの構造はdocsフォルダ内にtable_definition.xlsで保存されてますから確認してください。

投稿2016/04/28 04:43

編集2016/05/02 12:47
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

katsuo_isono

2016/05/02 09:38

ご返信遅くなり申し訳ありません! ご回答ありがとうございます。 こちらの内容で、指定したカテゴリIDのページを開いている場合に、selectで重複なしのメーカー一覧を表示するという実装を試してみます。 まだ$pdo->queryの処理が上手くいってませんが…
退会済みユーザー

退会済みユーザー

2016/05/02 12:33 編集

検証した訳ではないので 何処か間違ってたらごめんなさい><; $_GET['category_id']のパラメータを$category_idに代入したとして $stmt = $pdo->query(" SELECT `dtb_maker`.`maker_id` AS `markerid`, `dtb_maker`.`name` AS `markername` FROM `dtb_maker` LEFT JOIN `dtb_products` ON (`dtb_maker`.`maker_id` = `dtb_products`.`maker_id`) LEFT JOIN `dtb_products_class` ON(`dtb_products`.`product_id` = `dtb_products_class`.`product_id`) WHERE `dtb_products_class`.`classcategory_id1` = '$category_id' OR `dtb_products_class`.`classcategory_id2` = '$category_id' "); while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) { $markerdata[] = $data; } $marker = array_unique($markerdata); foreach($marker as $val){ echo $val['markerid'].'=>'.$val['markername']; } こんな感じで行けませんかね?
katsuo_isono

2016/05/06 05:22

ご回答ありがとうございます。 $category_idは固定(表示させたいのは特定のカテゴリーリスト1ページのみ)ですので、 pdoの構文を下記のように致しました。 $stmt = $pdo->query("SELECT `dtb_maker`.`maker_id` AS `markerid`, `dtb_maker`.`name` AS `markername` FROM `dtb_maker` LEFT JOIN `dtb_products` ON (`dtb_maker`.`maker_id` = `dtb_products`.`maker_id`) LEFT JOIN `dtb_product_categories` ON(`dtb_products`.`product_id` = `dtb_product_categories`.`product_id`) WHERE `dtb_product_categories`.`category_id` = ●●"); また、$makerdataは多次元配列のため、第二引数にSORT_REGULARを入れることで正常に重複削除ができ、画面上にも表示されました! とても詳しいご回答ありがとうございます!!
退会済みユーザー

退会済みユーザー

2016/05/06 08:29

無事に解決して良かったです..♪ わざわざコメント ありがとうございます^^
guest

0

『foreachの中で処理をする』、よりも『foreachで回す前に処理をする』ほうがいいのではないかな?と思います。
array_uniqueを使えば簡単ですし。

投稿2016/04/28 04:40

ao_love

総合スコア441

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

katsuo_isono

2016/05/02 09:42

ご返信遅くなり申し訳ありません! ご回答ありがとうございます。 表示するページ内の全商品IDとメーカーIDを取得し、メーカーIDを取得する際に メーカーIDが同じ場合は表示させない、という処理で対応しようと思います。
guest

0

新しく配列を宣言して、その配列に$maker.maker_idが存在しなければければ表示処理とその配列に$maker.maker_idを入れる、というのはどうでしょうか。

投稿2016/04/28 04:11

fixmiura

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

katsuo_isono

2016/05/02 09:39

ご返信遅くなり申し訳ありません! ご回答ありがとうございます。 大まかな流れの参考にさせて頂きました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問