みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

MySQLの質問です。2

お世話になります。
以前質問させていただいたのですがごちゃごちゃになってしまったので項目など見直してもっと単純な作りにしたいと思います。
MySQLを使ったWEBアプリを作っているのですが、特にこだわりのcheckboxと地域のcheckboxで分けてフォームからPHPのプログラムで受けて展開させる方法がわかりません。

どなたかご教授いただけたらと思っております。

テーブルに関しては賛否両論ですが、まずは3つでやってみたいと思います。
1つのほうが簡単そうなのですが、せっかく作ったので。

SQL文の間違いなのはわかっているのですがどうしてもわかりません。
何卒よろしくお願い致します。

下記のようなフォームにしたいと思っております。
<h1>マンション物件の条件検索</h1>

<form name="search_form" action="mansion.php" method="post" >
<input type="hidden" name="cmd" value="search" />
<table>

<tr>
<th>価格帯</th>
<td>
<select name="price_min">
<option value="1" selected="selected">下限なし</option>
<option value="10000000">1000万</option>
<option value="15000000">1500万</option>

</select> ~
<select name="price_max">
<option value="999999999999" selected="selected">上限なし</option>
<option value="10000000">1000万</option>

</select>
</td>
</tr>
<tr>
<th>愛知県 - 名古屋市</th>

<td>
<td>
<input type="checkbox" name="chiiki_id[]" value="1" <?php if( $_REQUEST["chiiki_id"] == "1" ){ print( 'checked' ); } ?>/>
中村区
<input type="checkbox" name="chiiki_id[]" value="2" <?php if( $_REQUEST["chiiki_id"] == "2" ){ print( 'checked' ); } ?>/>
西区

</tr>

<tr>
<th>愛知県 - その他の地域</th>

<td>
<input type="checkbox" name="chiiki_id[]" value="1" <?php if( $_REQUEST["chiiki_id"] == "1" ){ print( 'checked' ); } ?>/>
尾張
<input type="checkbox" name="chiiki_id[]" value="2" <?php if( $_REQUEST["chiiki_id"] == "2" ){ print( 'checked' ); } ?>/>
三河

</td>
</tr>
<th>こだわり条件</th>

<td>
<input type="checkbox" name="kid[]" value="1" <?php if( $_REQUEST["kid"] == "1" ){ print( 'checked' ); } ?>/>
新築
<input type="checkbox" name="kid[]" value="2" <?php if( $_REQUEST["kid"] == "2" ){ print( 'checked' ); } ?>/>
南向き
<input type="checkbox" name="kid[]" value="3" <?php if( $_REQUEST["kid"] == "3" ){ print( 'checked' ); } ?>/>
セキュリティ充実

</td>
</tr>

</table>
<input type="submit" value="検索" class="Btn-gray button">
</form>

<p>&nbsp;</p>

<?php
//初期設定
//username,$password,$dbnameは適当に

if( $_REQUEST["cmd"] == "search" ){


$dsn = 'mysql:host=localhost;dbname=fudousan';
$username = 'xxxxx';
$password = 'xxxxxxx';
$data=array();

$sql = "SELECT t1.* FROM bukken as t1 ";

$flag=true;


//kid絞り込み
if(isset($_REQUEST["kid"]) and is_array($_REQUEST["kid"])){
$sql.="INNER JOIN (SELECT DISTINCT fid FROM fdou_kodawari WHERE kid in (";
$sql.=implode(",",array_fill(0,count($_REQUEST["kid"]), '?'));
$sql.=")) as t2 ON t1.id=t2.fid ";
$data=array_merge($data,$_REQUEST["kid"]);
$flag=false;
}

//WHERE句作成
$sql.= "WHERE 1 ";


//名古屋の地域checkbox


$sql = "SELECT t1.* FROM bukken as t1 ";

if(isset($_REQUEST["chiiki_id"]) and is_array($_REQUEST["chiiki_id"])){
$sql.="INNER JOIN (SELECT DISTINCT chiid FROM chiiki WHERE chiiki_id in (";
$sql.=implode(",",array_fill(0,count($_REQUEST["chiiki_id"]), '?'));
$sql.=")) as t2 ON t1.id=t2.chiid ";
$data=array_merge($data,$_REQUEST["chiiki_id"]);
$flag=false;
}

//WHERE句作成
$sql.= "WHERE 1 ";



//価格絞り込み
if(isset($_REQUEST["price_min"]) and $_REQUEST["price_min"]!==""){
$price_min=str_replace(",","",$_REQUEST["price_min"]);
}else{
$price_min=0;
}
if(isset($_REQUEST["price_max"]) and $_REQUEST["price_max"]!==""){
$price_max=str_replace(",","",$_REQUEST["price_max"]);
}else{
$price_max=100000000;
}
if(isset($_REQUEST["price_min"]) or isset($_REQUEST["price_max"])){
$sql.="AND price_min BETWEEN ? AND ? ";
array_push($data,$price_min,$price_max);
$flag=false;
}


//実行
$pdo = new PDO($dsn,$username,$password);
$stmt = $pdo->prepare($sql);
$stmt->execute($data);

$rows=array(

以下省略

使っている3つのテーブルです。

bukken

id、 bukken_name、 address 、price_min、 price_max、 station
1 名駅MID 愛知県名古屋市中村区 40770000、 55100000 名古屋駅
2 プレサン浄心 愛知県名古屋市西区 30800000、 40001000 浄心駅
3 アネシア八事 愛知県名古屋市昭和区50000000、 62510000 八事日赤
4 アメニ港明 愛知県名古屋市港区 25000000、 35000000 港区役所駅
5 ユーハウ上飯田 愛知県名古屋市北区 32000000、 43330000 上飯田駅
6 ローレル葵 愛知県名古屋市東区 30000000、 46000000 高岳駅
7 ライオンズ上小田井 愛知県名古屋市西区 35000000、 55000000 上小田井駅
8 ポレスターセントラル名西 愛知県名古屋市西区 28000000、 38000000 浄心駅


chiikiテーブル

chiid chiiki_id
1 1
2 2
3 3
4 4
5 15
6 6
7 2

fudou_kodawariテーブル

fid kid
1 1
1 2
1 3

投稿日時 - 2014-07-16 23:38:06

QNo.8681252

困ってます

このQ&Aは役に立ちましたか?

10人が「このQ&Aが役に立った」と投票しています

回答(9)

ANo.9

>ところでこのSQL文をtest.phpに組み込むのでしょうか?

>そしてどのように組み込んだらよいのでしょうか?

プログラムとデザインを分けるようにお伝えしましたが
SQLとプログラムも分けて考えてください。

まずはSQL文が動作することを確認する必要があります。
PHPとMySQLを利用しているということはphpMyAdminは運用していますよね?
もししていないようでしたらマストなツールなのでインストールをお勧めします。

なお最終的にはtest.phpで提案したphp相当のものに組み込んで
PDOで処理することになると思います。

実際のところ#7,8の内容には絞り込みのデータが書いていないので、
(「where 1」というのは全データを表示するという意味、これにANDで絞り込みの
SQL文をつないでいきます)
ユーザーから送られてきたデータをもとにどう絞り込みをしたいか仕様を固めてください

投稿日時 - 2014-07-28 11:35:32

お礼

いつもアドバイスいただき本当にありがとうございます。
今回もよろしくお願い致します。

>まずはSQL文が動作することを確認する必要があります。
>PHPとMySQLを利用しているということはphpMyAdminは運用していますよね?
>もししていないようでしたらマストなツールなのでインストールをお勧めします。

phpMyAdminはxampp内にあるのでいつもそれを使用しております。
yamabe.jp様にいただいたSQL文を動かしたところ物件単位の検索、物件詳細の検索
共に正常に表示されました。

>ユーザーから送られてきたデータをもとにどう絞り込みをしたいか仕様を固めてください

特にユーザーからの依頼と言うわけではなく、趣味でやっているので縛りは全く無いです。
プログラム組んでいくうちに相談している皆さんのスキルが高いのでWEBアプリがどんどん
大げさなものになっていきました。
でも懲りだしたらもっと切りがなかもしれないですが。

私としましては勉強になるのでありがたいです。


まず物件単位の検索、物件詳細の検索

そのあとandで絞込み検索を繋げていく

価格帯を下限~上限を設定してまず検索

andでまず地域を絞り込み地域自体はor条件

そしてさらにandでこだわり条件で絞込み
こだわり条件自体はand条件とor条件を選べるようにする仕様で
こだわり条件に~駅から何分という条件も入れて
いきたいと思っています。

また時間のある時に返答よろしくお願いいたします。

投稿日時 - 2014-07-29 16:19:31

ANo.8

#7つづき

//物件の詳細単位で集計

select
t2.shosai_id,shubetu_name,bukken_name,shosai_name,chiiki_name,address,price,madori,moyorieki,kodawari
from t_bukken as t1
left join t_shosai as t2 on t1.bukken_id=t2.bukken_id
inner join t_shubetu as t3 on t1.shubetu_id=t3.shubetu_id
inner join t_chiiki as t4 on t1.chiiki_id=t4.chiiki_id
left join (select t5.bukken_id,group_concat(eki_name,jikan,'分') as moyorieki from t_bukken_eki as t5
inner join t_eki as t6 on t5.eki_id=t6.eki_id
group by bukken_id
) as t7 on t1.bukken_id=t7.bukken_id
left join (
select t8.shosai_id,group_concat(kodawari_name) as kodawari from t_shosai_kodawari as t8
inner join t_kodawari as t9 on t8.kodawari_id=t9.kodawari_id
group by shosai_id
) as t10 on t2.shosai_id=t10.shosai_id
where 1
※where句に条件をつないでいく

//物件単位で集計
select
t1.bukken_id,bukken_name,shubetu_name,shosai_count,min_price,max_price,chiiki_name,address,moyorieki,kodawari
from t_bukken as t1
inner join (
select bukken_id,count(*) as shosai_count,min(price) as min_price,max(price) as max_price,kodawari
from t_shosai as t2
left join (
select t3.shosai_id,group_concat(kodawari_name) as kodawari from t_shosai_kodawari as t3
inner join t_kodawari as t4 on t3.kodawari_id=t4.kodawari_id
group by shosai_id
) as t5 on t2.shosai_id=t5.shosai_id
group by bukken_id
) as t6 on t1.bukken_id=t6.bukken_id
inner join t_shubetu as t7 on t1.shubetu_id=t7.shubetu_id
inner join t_chiiki as t8 on t1.chiiki_id=t8.chiiki_id
left join (select t9.bukken_id,group_concat(eki_name,jikan,'分') as moyorieki from t_bukken_eki as t9
inner join t_eki as t10 on t9.eki_id=t10.eki_id
group by bukken_id
) as t11 on t1.bukken_id=t11.bukken_id
where 1

投稿日時 - 2014-07-24 18:48:29

補足

いつもお世話になっております。

送っていただいたSQL文なのですが、自分なりに本やサイトなど、構文見ながら確認したのですが、なかなか完璧に理解することが難しいです。

このあたりはいろいろ作っていって慣れるしかないのかなと思います。

ところでこのSQL文をtest.phpに組み込むのでしょうか?

そしてどのように組み込んだらよいのでしょうか?

またお時間ございましたらご教授いただけるとありがたく思います。

投稿日時 - 2014-07-26 15:05:39

お礼

テーブル詳細とSQL文ありがとうございます。

こんな長いSQL文あるんですね!

しばらくテーブルを元に考えてみたいと思います。

投稿日時 - 2014-07-24 20:34:55

ANo.7

かなりぐちゃぐちゃですが、ひとまずこれで

//物件テーブル
create table t_bukken(bukken_id int not null primary key,bukken_name varchar(100),shubetu_id int,address varchar(200),chiiki_id int);
insert into t_bukken values
(1,'マンションA',1,'○○区あああ町1-1-1',1)
,(2,'マンションB',1,'○○区あああ町2-2-2',1)
,(3,'マンションC',1,'○○区いいい町3-3-3',1)
,(4,'アパートD',2,'○○区ううう町4-4',1)
,(5,'マンションE',1,'××区かかか町1-2-3',2)
,(6,'アパートF',2,'××区ききき町4-5-6',2)
,(7,'戸建G',3,'△△市さささ町10-10',4)
,(8,'戸建H',3,'△△市ししし町20-1',4)
,(9,'戸建I',3,'□□郡すすす町字せせせ100',6);

//詳細テーブル
create table t_shosai(shosai_id int not null primary key,shosai_name varchar(100),bukken_id int not null,price int,madori varchar(100));
insert into t_shosai values
(1,'101号室',1,200000,'4LDK')
,(2,'202号室',1,100000,'2DK')
,(3,'303号室',1,150000,'2LDK')
,(4,'102号室',2,100000,'2LDK')
,(5,'103号室',3,100000,'2DK')
,(6,'104号室',4,60000,'1K')
,(7,'105号室',5,100000,'2DK')
,(8,'1001号室',6,80000,'2K')
,(9,'',7,200000,'3LDK')
,(10,'',8,30000,'4LDK')
,(11,'',9,400000,'5LDK');
※物件=集合住宅案件は1件とし、部屋ごとのカウントは詳細とします

//種別テーブル
create table t_shubetu(shubetu_id int not null primary key,shubetu_name varchar(100));
insert into t_shubetu values
(1,'マンション')
,(2,'アパート')
,(3,'戸建')
,(99,'その他');

//地域テーブル
create table t_chiiki(chiiki_id int not null primary key,chiiki_name varchar(50));
insert into t_chiiki values
(1,'○○区')
,(2,'××区')
,(3,'●●区')
,(4,'△△市')
,(5,'▲▲市')
,(6,'□□郡');

//駅テーブル
create table t_eki(eki_id int not null primary key,eki_name varchar(50));
insert into t_eki values
(1,'新宿')
,(2,'代々木')
,(3,'原宿')
,(4,'渋谷');
※沿線と絡めたりするともう少し工夫が必要

//物件-駅テーブル
create table t_bukken_eki(bukken_id int not null,eki_id int not null,jikan int,unique(bukken_id,eki_id));
insert into t_bukken_eki values
(1,1,3)
,(1,2,5)
,(2,2,5)
,(2,3,1)
,(3,4,10)
,(4,4,20)
,(5,1,10)
,(6,1,10);
※物件と駅の組み合わせ、到達時間もいれておく

//こだわりテーブル
create table t_kodawari(kodawari_id int not null primary key,kodawari_name varchar(50));
insert into t_kodawari values
(1,'ペット可')
,(2,'駐車場あり')
,(3,'南向き')
,(4,'新築')
,(5,'セキュリティ');

//詳細-こだわりテーブル
create table t_shosai_kodawari(shosai_id int not null,kodawari_id int not null,unique(shosai_id,kodawari_id));
insert into t_shosai_kodawari values
(1,1)
,(1,2)
,(1,3)
,(2,1)
,(2,2)
,(3,1)
,(4,1)
,(5,1)
,(6,3)
,(7,1)
,(7,2)
,(7,3)
,(7,4)
,(7,5)
,(9,1)
,(9,4)
,(10,1)
,(11,1);
※物件の詳細とこだわりの組み合わせ

つづく

投稿日時 - 2014-07-24 18:45:25

ANo.6

ちょっと時間かかりそうなので、ひまなときやってみます
もう少しこの質問は閉じずにおいといてください

投稿日時 - 2014-07-24 11:16:30

お礼

了解です。
閉じずにお待ちしております。
お手数ですがよろしくお願い致します。

投稿日時 - 2014-07-24 18:00:09

ANo.5

http://localhost/suumo/mansion2/test.inc.htmのURLを開いてから
>仮に地域の中村区とこだわり条件の新築をしてから検索ボタンを押すと

http://localhost/suumo/mansion2/test.inc.htm?pri

>に変わりますのでプログラムの動作は正常に動いていると思います。

まぁわかりやすく例示していただいているのだと思いますが
localhostでのアクセス情報はこちらで確認できないのであしからず
ちなみにtest.inc.htmでチェックボックスが引き継がれるのは変ですね
私のサンプルはあくまでtest.phpがtest.inc.htmを参照する仕組みです。

>テーブルについてですが、addressは番地まで入れたいのですが余分に
>テーブルを作らずにbukkenテーブルの中にaddress
>と並行してchiiki_idを入れれば良いのでしょうか?

addressは変更される頻度が低く(区画整理や市町村統合などなければ)、
履歴も必要なさそうなので、とりあえずそのままaddressに番地まで
つっこんでしまえばいいと思います
ただ、文字列で登録されたaddressは検索性が低いので、市区町村単位で
正規化したchiiki_idを並行して設定した方がいいということです。

>1ページ内で地域から駅など全て表示させるのはユーザー目線で見たらちょっとどうなんだろう?と
>思ってしまいます。

駅名の一部もしくは全部からあいまい検索するのがベターだと思いますが、
○○駅ちかくの××条件の物件、など絞り込みに利用することを考えると
1ページないで処理する方がいいですね
ただし、駅名一覧を冗長表示するよりは最大3つまで駅が指定できるような
仕組みの方がいいかもしれません
ほんとは沿線を指定したり駅名のあいまい検索をしたりajaxで処理するとベターです

>station_bukkenはどう紐付けするのでしょう?

複数駅が指定できるようにするなら別テーブルで処理するのがベター
ただ駅の指定を3つまで・・・のように仕様を固めてしまうなら物件テーブル内に
station_idと到達時間を3つ分用意すればいいでしょう。
ただし、名古屋の鉄道状況がよくわからないので、駅の密集状況などによっては
指定した駅で絞り込みができないリスクもあります。
(別テーブルで処理する限りいくつでも紐づけられます)

結構複雑な条件になってきているので、一気に実装しようとせずに、順番に機能を
追加して、稼働が確認されてから次に進む方が効率的かもしれません。
(チェックボックスやセレクトボックスの処理は前回書いた回答で
解決しているようですから、あとはSQL文の書き方を拡張していく感じですかね)

投稿日時 - 2014-07-22 13:29:11

補足

いつもお世話になります。アドバイス何卒よろしくお願いいたします。

>ちなみにtest.inc.htmでチェックボックスが引き継がれるのは変ですね

このことが良くわからないです。
今のところこの問題は保留でいいでしょうか。
原因がわからないです。


確かにlocal環境は確認しようがないですね。失礼致しました。

>ただ、文字列で登録されたaddressは検索性が低いので、市区町村単位で
>正規化したchiiki_idを並行して設定した方がいいということです。

ではbukkenテーブル内にaddressとchiiki_idを作って分けていこうと思いますが、
わからないところがあります。
chiiki_idはチェックボックスになっているので数字を入れないといけないですよね?
市町村単位で入れるのは別カラムを作って入れるのでしょうか?
例えばbukkenテーブルの中にchiiki_id,address,の後にcityカラムの中に~区以降の住所とか。
間違っていたらすみません。

id ,bukken_name ,chiiki_id ,address, city, price_min ,price_max
1 ,名駅MID, 1, 愛知県名古屋市, 中村区則武本通x丁目xx番 ,40770000 55100000
2 ,プレサン浄心, 2, 愛知県名古屋市, 西区城西x丁目xxxx番x ,308000000 40001000
3 ,アネシア八事, 3, 愛知県名古屋市, 昭和区高峯町xxx番 ,50000000 62510000

上記の構造で大丈夫でしょうか?

間違っておりましたらお手数ですがテーブル構造がどんな感じか教えていただけるとありがたいです。

>○○駅ちかくの××条件の物件、など絞り込みに利用することを考えると
>1ページないで処理する方がいいですね

言われてみれば1ページ内のほうが確かにわかりやすそうです。



>指定した駅で絞り込みができないリスクもあります。
>(別テーブルで処理する限りいくつでも紐づけられます)

では別テーブルで作っていきます。

>stationテーブル、station_bukkenテーブルの二つが必要です。
>station_bukkenテーブルでは、
>物件ID、駅ID、時間
>を登録できるようにするといいでしょう。

この通りに作っていこうと思います。

stationテーブルは構造は

駅ID、駅名
で良いのでしょうか?

テーブルがこのように複雑な場合、SQL文が出にくい私にとってはハードルが高いですが、
何とか完成させたいと思っております。何卒よろしくお願いいたします。

投稿日時 - 2014-07-24 01:01:18

ANo.4

話を戻してデータの持ち方について

bukkenテーブルについて
>id、 bukken_name、 address 、price_min、 price_max、 station
となっていますが、

addressが、市区町村までしか登録しないのであれば、
chiikiテーブルにまとめて、chiiki_idだけ埋め込む方がすっきりします。
またaddressを番地まできっちり入れる場合はaddressに並行してchiiki_idを
埋め込んで検索性を高めます。

またstationについてはchiikiと同じようにstationテーブルを用意しておくとよいでしょう。
ただし、stationは1つしか選べないような仕組みはよくありません。
A駅から3分、B駅から5分、C駅から10分・・・的な複数選択できた方が
たとえばA駅に紐づいた物件を探したり、B駅から10分以内の物件を探したり
できるの有利です。

なので、複数選択可能な条件なので
stationテーブル、station_bukkenテーブルの二つが必要です。
station_bukkenテーブルでは、
物件ID、駅ID、時間
を登録できるようにするといいでしょう。

ちょどstationの管理はこだわりと同じ仕組みになりますね

ちなみにこだわりは、and検索とor検索のどちらもできるようにすると
ユーザービリティがあがります。

・and検索:「犬が飼える」かつ「南向き」の部屋を探すケース
(どんどん条件がきびしくなる)もあれば
・or検索:「犬が飼える」か「南向き」の部屋→犬が飼えれば向きはどうでもよく、
南向きなら犬はいいや・・・という割り切った考えの人もいるでしょう

また下限価格、上限価格については私の認識が甘かったのですが
物件内に複数あるのですね?
であれば建物と別に部屋を管理するテーブルが必要です
部屋ID 、物件ID、部屋番号(○○号室)、価格

のようなデータをもたないと、同じ建物内の複数物件が管理しづらいでしょう

投稿日時 - 2014-07-18 16:37:47

補足

お世話になります。
いつもご指導いただきありがとうございます。

ファイルを3つに分けて動作確認致しました。

http://localhost/suumo/mansion2/test.inc.htmのURLを開いてから
仮に地域の中村区とこだわり条件の新築をしてから検索ボタンを押すと

http://localhost/suumo/mansion2/test.inc.htm?price_min=1&price_max=999999999999&chiiki_id[]=1&kid[]=1

に変わりますのでプログラムの動作は正常に動いていると思います。

テーブルについてですが、addressは番地まで入れたいのですが余分にテーブルを作らずにbukkenテーブルの中にaddress
と並行してchiiki_idを入れれば良いのでしょうか?

stationの検索についてはあまり考えていなかったのですが、ユーザビリティーを考えるのであれば、
必要なものだろうと思います。

1ページ内で地域から駅など全て表示させるのはユーザー目線で見たらちょっとどうなんだろう?と
思ってしまいます。

この辺はどうすれば良いか迷っています。
駅は駅、地域は地域でページは分けたほうがいいかもしれません。
分けた場合はまずは地域から選択するページを作りたいと思います。


stationテーブルはkodawariと同じようにidと紐付ければ良いのですが、station_bukkenはどう紐付け
するのでしょう?

例えば時間のテーブルを作って駅(どんな駅でも良い)から何分というのが単純に作れていい気が
します。
この場合

station_time

物件ID、時間(選択肢 駅から?分)

でいいかもしれません。

こだわり条件はor条件とand条件で分けるのは良いと思います。
こんな考え方あるんですね。出来ればやってみたいと思います。


下限価格、上限価格につきましては最初の参考書のプログラムがそのまま残っていただけなのです。
特に深くは考えてなかったのですが、確かに物件別にも部屋番号が違うものがあり、値段も変わる
ので、テーブルは余分に必要ですね。

いろいろ書いてしまいましたが私には実現方法がわからないのでお時間ございましたらまたご教授
いただきたいと思っております。

投稿日時 - 2014-07-19 13:11:32

ANo.3

>test.inc.htmとtest.phpとcommon.phpの3つのファイルに
>分ければ良いのでしょうか?

そういうことです。
htmはあくまでテンプレートです。
ダイレクトにtest.inc.htmを開いても、htmlのレイアウトが確認できるので
htmlはそれだけで簡潔したファイルにしておくとよいです。
ファイル名についても特に深い意味はないですが、インクルードして使うファイル
とわかるようにしておくとファイル管理が後々楽です

>そして、test.phpとcommon.phpはファイルにそのままコピペで良いのでしょうか?
一応そのつもりで書いてあります。

>phpファイルの部分は高度すぎて理解できるかちょっとわからないです。
きちんとしたクラスの書き方はもうすこし修飾が必要なのですが、
とりあえず動くのを確認するという意味では、なんとなく理解できればよいでしょう
new testでインスタンスを作成して、execで実行して結果を出力している感じ
ロジックが見えやすいように関数はかなり無駄に展開してあります。

>デザインとプログラムを分けて効率化するにはここを理解しないことには進めないのでしょうか。

細かい関数を理解する必要はないと思いますよ、checkedやselectedをプログラムで
制御していることだけ理解し、ご自身で拡張できそうな問題ないでしょう。

>test.inc.htmはかなり部分的に省略してありますが
それこそhtmlタグからはじまりhtmlタグで閉じるフルのhtmlを書いてもらえばよいです

※注記
今回のご提案は、プログラムの不備にひっぱられてMySQLの質問がブレがちな点が
気になったためのものです。
テンプレートとプログラムが分かれていれば、MySQLの質問にhtmlの記述をどうする
こうすると悩む必要はなくなります。

とりあえず、3つのファイルに分ける処理をそのままコピペでいいので試してみてください
おいおい拡張していけばいいでしょう

投稿日時 - 2014-07-17 22:40:58

ANo.2

#1の続き

//common.php
<?PHP
class common
{
function include_parse($filename,$replacement=null,$nonerem=null,$label=null)
{
if(empty($filename)) return false;
$str=file_get_contents($filename);
$str=$this->replace_parse($str,$replacement);
return $str;
}
function replace_parse($str,$replacement=array())
{
$pattern='/\{(\$.+?)\}/';
$str=preg_replace_callback(
$pattern
,function ($matches) use ($replacement){
return self::replace_callback($matches,$replacement);
}
,$str);
return $str;
}
function replace_callback($matches,$replacement)
{
extract($replacement);
$ret="";
$evalstr='$ret=isset('.$matches[1].')?'.$matches[1].':"";';
eval($evalstr);
return $ret;
}
}
?>

もちろん、もうすこし工夫してチェックボックスやセレクトボックス自体を
DBからデータ取得して自動生成したりしてもよいかもしれません

投稿日時 - 2014-07-17 17:26:48

補足

お世話になります。
お答えいただきありがとうございます。

test.inc.htmとtest.phpとcommon.phpの3つのファイルに
分ければ良いのでしょうか?

そして、test.phpとcommon.phpはファイルにそのままコピペで良いのでしょうか?
phpファイルの部分は高度すぎて理解できるかちょっとわからないです。ちょっと時間がかかるかもしれません。

デザインとプログラムを分けて効率化するにはここを理解しないことには進めないのでしょうか。


test.inc.htmはかなり部分的に省略してありますが大雑把にいくとこれで大丈夫でしょうか?



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>05-11</title>
<link rel="stylesheet" type="text/css" href="../common/style.css"/>
</head>

<?php error_reporting( E_ALL ^ E_NOTICE ); ?>
<body id="S03-10">
<div id="main">

<h1>マンション物件の条件検索</h1>


<form>
<p>
価格帯:
<select name="price_min">
<option value="1"{$selected["price_min"][1]}>下限なし</option>
<option value="10000000"{$selected["price_min"][10000000]}>1000万</option>
<option value="15000000"{$selected["price_min"][15000000]}>1500万</option>
</select> ~
<select name="price_max">
<option value="999999999999"{$selected["price_max"][999999999999]}>上限なし</option>
<option value="10000000"{$selected["price_max"][10000000]}>1000万</option>
</select>
</p>
<p>
地域:
<input type="checkbox" name="chiiki_id[]" value="1"{$checked["chiiki_id"][1]}>中村区
<input type="checkbox" name="chiiki_id[]" value="2"{$checked["chiiki_id"][2]}>西区
<input type="checkbox" name="chiiki_id[]" value="3"{$checked["chiiki_id"][3]}>昭和区
<input type="checkbox" name="chiiki_id[]" value="4"{$checked["chiiki_id"][4]}>港区
<input type="checkbox" name="chiiki_id[]" value="5"{$checked["chiiki_id"][5]}>守山区
<input type="checkbox" name="chiiki_id[]" value="6"{$checked["chiiki_id"][6]}>東区
<input type="checkbox" name="chiiki_id[]" value="7"{$checked["chiiki_id"][7]}>中区
</p>
<p>
こだわり条件:
<input type="checkbox" name="kid[]" value="1"{$checked["kid"][1]}>新築
<input type="checkbox" name="kid[]" value="2"{$checked["kid"][2]}>南向き
<input type="checkbox" name="kid[]" value="3"{$checked["kid"][3]}>セキュリティ充実
<input type="submit" value="go">
</p>
</form>


</div>
</body>
</html>

投稿日時 - 2014-07-17 21:46:37

ANo.1

DBの件はひとまず置いておいて、ひとつ提案

徐々にPHPが肥大化してきたので、プログラムとデザインを分けた方がいいですね
また、プログラムもクラスを利用しましょう。
よく使う機能はまとめて再利用できるようにします。

チェックボックスの処理はこんな感じでやります
(上限に引っかかるのでcommon.phpは#2に)

//test.inc.htm
<form>
<p>
価格帯:
<select name="price_min">
<option value="1"{$selected["price_min"][1]}>下限なし</option>
<option value="10000000"{$selected["price_min"][10000000]}>1000万</option>
<option value="15000000"{$selected["price_min"][15000000]}>1500万</option>
</select> ~
<select name="price_max">
<option value="999999999999"{$selected["price_max"][999999999999]}>上限なし</option>
<option value="10000000"{$selected["price_max"][10000000]}>1000万</option>
</select>
</p>
<p>
地域:
<input type="checkbox" name="chiiki_id[]" value="1"{$checked["chiiki_id"][1]}>中村区
<input type="checkbox" name="chiiki_id[]" value="2"{$checked["chiiki_id"][2]}>西区
<input type="checkbox" name="chiiki_id[]" value="3"{$checked["chiiki_id"][3]}>昭和区
<input type="checkbox" name="chiiki_id[]" value="4"{$checked["chiiki_id"][4]}>港区
<input type="checkbox" name="chiiki_id[]" value="5"{$checked["chiiki_id"][5]}>守山区
<input type="checkbox" name="chiiki_id[]" value="6"{$checked["chiiki_id"][6]}>東区
<input type="checkbox" name="chiiki_id[]" value="7"{$checked["chiiki_id"][7]}>中区
</p>
<p>
こだわり条件:
<input type="checkbox" name="kid[]" value="1"{$checked["kid"][1]}>新築
<input type="checkbox" name="kid[]" value="2"{$checked["kid"][2]}>南向き
<input type="checkbox" name="kid[]" value="3"{$checked["kid"][3]}>セキュリティ充実
<input type="submit" value="go">
</p>
</form>

//test.php
<?PHP
$test=new test;
$test->exec();
class test
{
function __construct()
{
include_once "common.php";
$this->common=new common;
}
function exec()
{
$fname="x.htm";
$str=file_get_contents($fname);
$replacement=array(
"checked"=>$this->set_checked()
,"selected"=>$this->set_selected()
);
$str=$this->common->replace_parse($str,$replacement);
print $str;
}
function set_selected()
{
$selected=array();
$selected["price_min"]=$this->set_checked_price_min();
$selected["price_max"]=$this->set_checked_price_max();
return $selected;
}
function set_checked_price_min()
{
$default="1";
$array=array("1","10000000","15000000");
$selected=array();
foreach($array as $val){
$selected[$val]=($_REQUEST["price_min"]===$val)?" selected":"";
}
if(!isset($_REQUEST["price_min"])) $selected[$default]=" selected";
return $selected;
}
function set_checked_price_max()
{
$default="999999999999";
$array=array("999999999999","10000000");
$selected=array();
foreach($array as $val){
$selected[$val]=($_REQUEST["price_max"]===$val)?" selected":"";
}
if(!isset($_REQUEST["price_max"])) $selected[$default]=" selected";
return $selected;
}
function set_checked()
{
$checked["chiiki_id"]=$this->set_checked_chiiki_id();
$checked["kid"]=$this->set_checked_kid();
return $checked;
}
function set_checked_chiiki_id()
{
if(!isset($_REQUEST["chiiki_id"]) or !is_array($_REQUEST["chiiki_id"])) return false;
$array=array("1","2","3","4","5","6","7");
$checked=array();
foreach($array as $val){
$checked[$val]=in_array($val,$_REQUEST["chiiki_id"])?" checked":"";
}
return $checked;
}
function set_checked_kid()
{
if(!isset($_REQUEST["kid"]) or !is_array($_REQUEST["kid"])) return false;
$array=array("1","2","3");
$checked=array();
foreach($array as $val){
$checked[$val]=in_array($val,$_REQUEST["kid"])?" checked":"";
}
return $checked;
}
}
?>

投稿日時 - 2014-07-17 17:25:20

あなたにオススメの質問