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

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

ただいまの
回答率

87.49%

同じようなメニューが並ぶので、PHPでまとめて出力したいのですが…

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 513

score 16

実現したいこと

こんな感じのメニューがたくさん並ぶHTMLを考えています。

以下はとりあえず「fluits」だけ書きましたが、「drinks」とかそのようなものがいっぱい並ぶ感じです。(それぞれ構造は一緒ですが、<li>の数が異なります。)

これを、HTML静的にたくさん書くよりも、PHPでやってみたいと思いました。

<div data-main_menu="fluits">    
    <ul>    
        <li data-sub_menu="fluits_a">
            <p>fluits_aのp</p>
        </li>
        <li data-sub_menu="fluits_b">
            <p>fluits_bのp</p>
        </li>
    </ul>
</div>

<!-- 上の fluits と同様の構造で、 drinks などがたくさん並ぶ -->

試したこと

あれやこれやと調べてみましたところ、一気に出力する関数を作り、その中で可変的な部分を配列にしておいて、それをforeachで回しながら順に連結して、最後に出力してあげればいいのかな?と思いました。

その結果として下のソースコードになったのですが、いかんせん、初心者すぎて歯が立たず、にっちもさっちもいかなくなってしまったため、書き方を教えて頂ければと思います。宜しくお願い致します。

<?php
// 一気に出力する関数
function echo_menus(){

    // <li>の数はfluitsは2つでdrinksは3つ、のように異なる
    $fluits_a = 'fluits_aのp';
    $fluits_b = 'fluits_bのp';
    $drinks_a = 'drinks_aのp';
    $drinks_b = 'drinks_bのp';
    $drinks_c = 'drinks_cのp';

    $sub_menus = array(
        'fluits' => array(
            'fluits_a' => $fluits_a,
            'fluits_b' => $fluits_b
        ),
        'drinks' => array(
            'drinks_a' => $drinks_a,
            'drinks_b' => $drinks_b,
            'drinks_c' => $drinks_c
        )
    );

    foreach( $sub_menus as $sub_menu ){

        $ret = '<div data-main_menu="'.$sub_menu.'">';
        $ret .= '    <ul>';

        foreach( $sub_menu as $key=>$k ){
            $ret .= '       <li data-sub_menu="'.$key.'">';
            $ret .= '           <p>'.$k.'</p>';
            $ret .= '       </li>';
        }   

        $ret .= '    </ul>';
        $ret .= '</div>';
    } 

    echo $ret;
}

echo_menus();

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2019/06/11 10:55

    (質問文は編集できます)「にっちもさっちもいかなくなってしまった」とは「何」が「どのように」わからないのか、「何をしたときに」「どうなると思って」「どうなったのか」を、出ているエラーなどと併せて、具体的に記述されたほうが回答を得られやすいと思います。

    キャンセル

  • moimoimoi

    2019/06/11 11:17

    なるほど気を付けます。ありがとうございます。

    キャンセル

回答 2

checkベストアンサー

+1

どこまでが共通部分なのか切り分けてください

<?PHP
$a=[
  [
    "menu"=>"fluits",
    "elems"=>[
      ["menu"=>"fluits_a","content"=>"fluits_aの内容"],
      ["menu"=>"fluits_b","content"=>"fluits_bの内容"],
      ]
    ],
  [
    "menu"=>"drinks",
    "elems"=>[
      ["menu"=>"drinks_a","content"=>"drinks_aの内容"],
      ["menu"=>"drinks_b","content"=>"drinks_bの内容"],
      ["menu"=>"drinks_c","content"=>"drinks_cの内容"],
      ],
    ],
  ];

foreach($a as $val){
print "<div data-main_menu=\"{$val["menu"]}\">\n";
print "<ul>\n";
foreach($val["elems"] as $sub){
print "<li data-sub_menu=\"{$sub["menu"]}\">\n";
print "<p>{$sub["content"]}</p>\n";
print "</li>\n";
}
print "</ul>\n";
print "</div>\n";
}

変数の展開

  • ダブルクォート内のダブルクォートをエスケープ
print "<div class=\"momotarou\" data-main_menu=\"{$val["menu"]}\">\n";
  • ダブルクォート内はシングルクォートでくくる
print "<div class='momotarou' data-main_menu='{$val["menu"]}'>\n";
  • ヒアドキュメント
print <<<eof
<div class="momotarou" data-main_menu="{$val["menu"]}">

eof; 

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/11 11:34

    改行だけのだめに「PHP_EOL」というのも長いですね。わたしも「\n」を使うようにします。

    printとの違いわかりにくくて、そういっていただけると安心します。

    ダブルクオーテーションかどうかで大きな違いになりますねそれは。気を付けたいと思います。
    実はクラス名をつけようと考えていたのですが、次のようにしたら仰る展開ができずあせりました。

    print "<div data-main_menu=\"{$val["menu"]}\">\n";

    ↓展開できなくなった!

    print '<div class="momotarou" data-main_menu=\"{$val["menu"]}\">\n';

    このようにクラス名をつけるならば、教えて頂いたその書き方ではなくて、質問のような書き方になりますよね?(何度も申し訳ございません追加で。これで最後です。)

    キャンセル

  • 2019/06/11 11:40 編集

    > print '<div class="momotarou" data-main_menu=\"{$val["menu"]}\">\n';

    外側をシングルクォートでくくると変数は展開されません
    (かつ改行も判断されません)
    ※見づらいので回答分に追記しておきました

    キャンセル

  • 2019/06/11 11:48

    あ、エスケープ、めちゃんこ便利!なるほど。こういうことだったんですね。いつも「こっちがシングルだから、えーっと、こっちをダブルにして…」とかやってました。エスケープすれば全部ダブルでいいんだ。なるほどー。
    ご回答編集まで、どうもありがとうございます。お手数おかけしました。最後まで誠にありがとうございます。

    キャンセル

0

        $ret = '<div data-main_menu="'.$sub_menu.'">';

で内容がリセットされているので、drinksの部分だけ出力されますね。
あと、上の状態だと、$sub_menuのところはArrayになっているのでは?

        foreach( $sub_menu as $key=>$k ){


と同じようなことをすれば、キーが出力されると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/06/11 11:16

    なるほどその段階ではまたArrayでしたか。ありがとうございます。

    キャンセル

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

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る