PHPの質問です。


以下のようなPHP文を作りました。


$sql1 = "SELECT *
FROM ken LEFT JOIN ken_option ON ken.ken_option_select1 = ken_option.ken_option_id ";

$sql2 = "SELECT *
FROM ken LEFT JOIN ken_option ON ken.ken_option_select2 = ken_option.ken_option_id ";

$sql3 = "SELECT *
FROM ken LEFT JOIN ken_option ON ken.ken_option_select3 = ken_option.ken_option_id ";

これが「$sql10」まで続いています。
あまりにも冗長すぎるので、forで簡略化したいと思います。

$countsという変数を1から10まで増やしていけばいいと思うのですが、それを上記PHP文にどのようにはめ込んでいくのかわかりません。

for($counts = 1;$counts = 10;$counts++ ){

****************************

}

上記******の部分はどのように書けばいいでしょうか??

よろしくお願いします。

回答の条件
  • 1人2回まで
  • 登録:2007/03/21 23:43:18
  • 終了:2007/03/28 23:45:40

回答(4件)

id:nandedarou No.1

nandedarou回答回数230ベストアンサー獲得回数342007/03/21 23:53:54

ポイント23pt
for ($counts = 1; $counts <= 10; $counts++) {
    $sql_name = 'sql'.$counts;
    $$sql_name = sprintf("SELECT * FROM ken LEFT JOIN ken_option ON ken.ken_option_select%s = ken_option.ken_option_id ;",$counts);
}

これで、どうでしょうか?

id:tokyosmash

おかげ様で無事にクリアしました。

変数の概念や、文字列の取り扱いなどを少しだけ体得できたと思います。

いつもありがとうございます。

2007/03/22 13:37:40
id:Mook No.2

Mook回答回数1312ベストアンサー獲得回数3912007/03/22 00:33:42

ポイント23pt

ご希望の回答ではないかも知れませんが、一度に10ものSQL 文を作成する必要はないと思いますので、関数で実装し、順番に処理をしたらどうでしょうか。

<?
// 関数の定義:同じファイル内であれば、どこで定義してもOK 
function selectOption( $optionNumber ) {
    $sql  = "SELECT * FROM ken ";
    $sql .= "LEFT JOIN ken_option ON ken.ken_option_select{$optionNumber} = ken_option.ken_option_id;";

  // $sql の実行
  // 結果の処理(集計、表示等)
}

// 各 SQL の処理の実行
for( $i=1 ; $i<=10 ; $i++ ) {
    selectOption( $i );
}
?>

このようにした方がスマートだと思います。

id:tokyosmash

自分で関数が作れるんですね。

VBAを少しかじった事があるのですが似ていますね。

これは勉強になりました!

2007/03/22 13:35:22
id:toteri No.3

yoccola回答回数52ベストアンサー獲得回数32007/03/22 01:03:36

ポイント22pt

一文で書いてみました。

for($counts = 1;$counts <= 10;$counts++ ){

${sql.$counts} = "SELECT * FROM ken LEFT JOIN ken_option ON ken.ken_option_select{$count} = ken_option.ken_option_id ";

}

結果は一緒ですが。

($counts = 10 の部分で“<”が抜けていたので追加しました)

id:kurukuru-neko No.4

kurukuru-neko回答回数1844ベストアンサー獲得回数1552007/03/22 01:49:15

ポイント22pt

SELECT *

FROM ken LEFT JOIN ken_option

ON ken_option.ken_option_id

in (

ken.ken_option_select1,

ken.ken_option_select2,

ken.ken_option_select3,

ken.ken_option_select4,

ken.ken_option_select5,

ken.ken_option_select6,

ken.ken_option_select7,

ken.ken_option_select8,

ken.ken_option_select9,

ken.ken_option_select10)

書いた方が早くありませんか?

id:tokyosmash

コメント欄のスクリプトありがとうございます。

勉強も兼ねて作っているものなので、ぜひぜひ試してみたいと思います。

2007/03/22 13:37:52
  • id:nandedarou
    $counts = 1;
    $sql_name = 'sql'.$counts;
    このとき、PHPでは、
    $sql1 は、$$sql_name として表現できます。
    だから、
    $$sql_name = '「内容」';
    print( $sql1 );
    とすると、
    「内容」と表示されます。
  • id:nandedarou
    私の回答SQL文の最後の ; が抜けていると思い、; を付け加えましたが、もし、付け加える必要がなかったら、削除して下さい。
  • id:tokyosmash
    みなさんありがとうございます。

    nandedarouさんの方法でやっていますが、途中まではうまくいきました。$sql1,$sql2,$sql3にはきちんと文字列が入っているようです。echoで出力させて確認しました。

    しかしその後そのSQLを使ってMySQLに接続する際にエラーが出てしまいます。



    $res1 = mysql_query($center_option_sql1);
    while ( $row1 = mysql_fetch_array( $res1, MYSQL_ASSOC ) ) {
    echo $row1['ken_id'];
    }

    大幅に省略しているのですが、作ったスクリプトは以上のように続きます。

    そしてmysql_fetch_array(): supplied argument is not a valid MySQL result resourceエラーが出てしまいます。

    小1時間トライ&エラーしてますが。。
  • id:Mook
    $res1 = mysql_query($center_option_sql1);
    が失敗しているんじゃないですか?

    $res1 = mysql_query($center_option_sql1) or die('Invalid query: ' . mysql_error());

    としてみては、どうでしょうか。
  • id:kurukuru-neko
    回答のken_idを抽出している
    事から

    ===============================
    推定処理

    ken_optionは何らかな商品マスターのようなもの。

    kenは、何らかの商品で
    購入する時の追加オプションを指定として
    ken_option_select1~10がある。

    処理としては、kenで指定された
    オプションの商品マスターのID一覧
    が取得したい。
    ===============================

    重複除外なら回答の
    select
    *

    select
    distinct ken.出力カラム名
    に変更

  • id:nandedarou
    エラーメッセージを見ると
    $res1 = mysql_query($center_option_sql1);
    で失敗しているように感じます。

    $center_option_sql1
    の変数名が間違っているということはありませんか?
  • id:tokyosmash
    遅くまでみなさんありがとうございます。
    未だにうまくいきませんが、もう少し粘ってみます。


    >kurukuru_nekoさん
    自分のやりたい事を簡単に言うと
    GoogleMAPで、東京都のページにアクセスしたら「新宿駅付近」「東京駅付近」へ移動するボタンを表示して、他の県であればまた別のボタンを表示させたいのです。
    それぞれの県ごとに表示するボタンをデータベースに登録しておく、といった感じです。
    PHPとMySQLに加えてJavaScript(GoogleMapAPI)が登場するのでちょっと自分には手に負えない状態になってます。


    質問文のようなSQL文を10個書けば問題ないのですが、もしボタンを11個以上表示させたい場合はその都度追加しなければなりません。これでは柔軟性・拡張性が無いというか、スマートではないですよね。

    自分はPHPもSQLもJavascriptもほとんどわからないので、「スマートさ」は捨ててスクリプトを自力で書いてみたのですが、あまりにも冗長過ぎて300行近くなってしまったのです。

  • id:nandedarou
    テーブル構成が正確にわからないので、推測で書きますが、次のようにプログラムを変更してもいいように感じます。

    (1).ken_optionテーブルのデータを全て取得し、配列として保存。
    (2).表示したい都道府県のデータをkenテーブルから取得し、(1)とは別の配列に保存。
    (3).(2)のデータを表示する際に、ken_option_select1~10に対応する(1)のオプションデータを表示する。

    また、PHPとSQLを同時に覚えるのが大変なら、
    まずは、SQL文は、SELECT、FROM、WHERE、ORDER BYなど、必要最小限にして、
    後の処理はPHPでやるという方針も可能なので検討してみる余地があると思います。
  • id:tokyosmash
    >nandedarouさん

    ちょっとだけ進みました。

    for ($counts = 1; $counts <= 10; $counts++) {

    $sql_name = 'sql'.$counts;
    $$sql_name = sprintf("SELECT * FROM ken LEFT JOIN ken_option ON ken.ken_option_select%s = ken_option.ken_option_id",$counts);

    $res_name = 'res'.$counts;
      $$res_name = sprintf("mysql_query($sql%s)",$counts);

    }

    このように書いたのですが、$res1をechoで出力してみると
    mysql_query(1)
    になっているのです。

    mysql_query($sql1)
    と出力しなければ。sprintf内でおかしな事になっているみたいです。

    リファレンス見ながらなんとなく野生の勘で

    $$res_name = sprintf("mysql_query(\$sql%s)",$counts);

    と$sqlの前に\を付けてみたら正常に出力されました。

    ただ、それでもsupplied argument is not a valid MySQL といつものエラーが出てしまいます。他にも原因があるようです。
    もう少し頑張ってみます。
  • id:nandedarou
    $res1 に 文字列として、「mysql_query($sql1)」を保存しているようですが、なんのためにやっているのですか?

  • id:tokyosmash
    while ( $row1 = mysql_fetch_array( $res1, MYSQL_ASSOC ) ) {

    *****色々と********

    }

    このためです。
    「色々と」の部分で配列からデータを引っ張ってきて表示させています。ここでエラーが発生しているんですよね。
  • id:nandedarou
    私のコメントの2つ目にも書きましたが、SQL文の文末に;はついていますか?(先ほどのコメントについていませんでしたよ)

    おそらく、やりたいことは、
    $$res_name = sprintf("mysql_query(\$sql%s)",$counts);
    ではなく
    $$res_name = mysql_query($$sql_name);
    ではありませんか?
  • id:tokyosmash
    できました!
    $$res_name = mysql_query($$sql_name);
    これで出来ました。本当にありがとうございます。

    $$res_name = sprintf("mysql_query(\$sql%s)",$counts);
    これがなぜダメだったのかイマイチわかっていないのですが。。

  • id:nandedarou
    PHPファイルに直接書いた。
    mysql_query($$sql_name);
    は、phpエンジンにとっては、命令文です。
    phpは、SQL文を実行し、データベースからデータを持ってきます。

    sprintf("mysql_query(\$sql%s)",$counts)
    は、文字列として、「mysql_query($sql1)」を返します。
    文字列はphpにとっても、あくまで単なる文字です。
    SQL文を実行するようなことはありません。
    文字として、「mysql_query($sql1)」を返すだけです。
  • id:tokyosmash
    なるほど・・。
    丁寧な説明ありがとうございます。
    確かに言われてみるとその通りですよね。
    今回も長々と付き合ってくださって感謝です。

    手元に「独習PHP」と「PHPポケットリファレンス(技術評論社)」があるのですが、もう少し初心者向けの本を読んで勉強します。

  • id:nandedarou
    解決してよかったですね!

    参考書としては、サンプルスクリプトがついているもの
    (CDがついているか、Webからダウンロードできるもの)
    がいいと思います。

    サンプルスクリプトを実行してから、解説を読むと理解が早いです。

    理解したら、少し自分なりに変更してみて、実行してみて下さい。
    自分の思い通りに変更できたら、正しく理解したということです。

  • id:kurukuru-neko

    >もしボタンを11個以上表示させたい場合はその

    可能なら今のうちにテーブル構成を多少変更
    しておいた方がよいと思われます。

    テーブル構造は推定

    ken: 各県毎の表示項目がある
       現在はken.ken_option_select1~10

    ken_option: kenのken_option_select1~10
       の実際に表示する実データや表示方法が
       入っている。

    当然県により数option数が違うことも
    考えられます。

    例1:テーブル分割
    ken_option_select1~10を別テーブルに分割

    ken: ken_option_select1~10を
       別テーブルへ移動その参照キーを追加
    ken.select_key 別テーブルの参照キー

    [NEW]
    ken_select: 選択表示項目
    create table ken_select
    select_key int, // ken.select_key連結キー
    select_no int, // 表示の順番1~N
    select_option_id int, // 現在のselect1~10の内容
    // ユニークキー
    primary key(select_key,select_no),
    // 検索キー
    index (select_key),
    index (select_option_id)
    );

    select
    distinct
    ken_select.select_no,ken_option.*
    from ken
    inner join ken_select
    on ken.select_key = ken_select.select_key and ken.ken_id = '東京'
    inner join ken_option using(select_option_id)
    order by ken_select.select_no

    例2:カラム分割
    ken_option_select1~10をカラム分割
    ken: ken_option_select1~10を
       表示番号と、参照キーに分離
    ken.select_no 表示順1~N
    ken.select_option_id 参照キー

    select
    distinct
    ken.select_no,ken_option.*
    from ken
    inner join ken_option on
    ken.select_option_id = ken_option.select_option_id and ken.ken_id = '東京'
    order by ken.select_no

    http://www.db.is.kyushu-u.ac.jp/rinkou/sql/index.html
  • id:nandedarou
    VBやってたんですね。私も本格的なプログラムはVBから始めました。VBが親切すぎる為、他の言語に移ったときには、非常に苦労しました。

    Web上のプログラムを覚える為に、私の場合、まず、掲示板を作りました。投稿が多くなったら、例えば10個ずつ表示し、ページ切り替えができる掲示板ができれば、ほとんどのWebプログラムはその応用に過ぎません。

    みんな始めは苦労します。頑張って下さいね!

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません