- 締切済み
PHPとPostgreSQLを使用した勤怠管理システム
現在、PHPとPostgreSQLを使用して勤怠管理システムを 作成しているのですが、解らない事があるので質問させて下さい。 この手の事で色々と質問しているのですが、ツギハギだらけでDBにも 負荷をかけてしまうような作りになってしまったので 一から作り直しているところです。 ご教授の程、よろしくお願いします。 1)今月15日から来月14日までの曜日つき日付を取得する 2)労働時間を入力してチェックボックスを押せば、日付と労働時間がDBに登録される 3)チェックを押したとき、DBに該当データがあれば、INSERT。 4)チェックを押したとき、DBに該当データがなければ、UPDATE という処理を行いと思います。 以下に以前のコードを記載します。 $weekday = array("日","月","火","水","木","金","土"); //曜日の配列作成 $now = time(); // UNIXタイムスタンプを取得 $year = date('Y', $now); // 年を指定された書式で書式化する $month = date('m', $now); // 月を指定された書式で書式化する $day = date('d', $now); // 日を指定された書式で書式化する // 現在の日付が15日未満だったら、月をマイナスする if($day < MONTH_HARF){ $month--; } // 指定した月の日数を取得 $numOfDays = date('t', mktime(0, 0, 0, $month, 1, $year)); // 日付が指定した月の日数以下ならば for($d = 0; $d < $numOfDays; $d++){ // $dateに15日から末日+14日までの値をyyyy年mm月dd日の形で代入 $date = date("Y年m月d日", mktime(0, 0, 0, $month, 15+$d, $year)); // $wに0~6までの数字に対応した曜日を代入 $w = date("w", mktime(0, 0, 0, $month, $d+1, $year)); // $ymddateに15日から末日+14日までの値をyyyymmdの形で代入 $ymddate = date("Ymd", mktime(0, 0, 0, $month, 15+$d, $year)); //1行の定義:日付(曜日) $line = $weekday[$w]; // 読み込まれた休日と表示されている日付が同じならば、$wに0を代入(日曜日) if($holiday_plasticOperation == $date){ $w = 0; } switch($w){ case 0: //日曜日の文字色 $style = "color:#C30;"; break; case 6: //土曜日の文字色 $style = "color:#03C;"; break; default: //月~金曜日の文字色 $style = "color:#333;"; } echo "<TD WIDTH=100>$date</TD><TD title='$yy'><span style=.$style.>$line</span></TD>"; echo "<TD><INPUT TYPE='text' NAME='work_time[$ymddate]' VALUE='$work_Time' TABINDEX=1 SIZE='7' STYLE='ime-mode: inactive;'></TD>"; echo "<TD><INPUT TYPE='CHECKBOX' NAME='work_check[]' VALUE='$ymddate' TABINDEX=2></TD>"; } どうか、ご教授の程よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- taketan_mydns_jp
- ベストアンサー率58% (450/773)
こんにちは。 DBに負担をかけない(当然最終的なパフォーマンスも)と言う事がメインでしょうから、その点だけ。 私もPostgreSQLで凝った作りでパフォーマンスが一気に落ちてしまい苦労した事があります。たくさんのクエリが一度に集中すると、まったくパフォーマンスが落ちてしまう、と言う事も経験しました。 私がとった対処方法としては、DBはクエリの度にHDDにアクセスしますので、クエリ回数を減らす事をまず主眼に置き、作りなおしました。 恐らくサーバのメモリ環境はそれほどプアでないでしょうから、PHP側で出来るだけ多くの処理をさせてしまうようにします。 一ヶ月分の該当データをまずSELECTして、PHPのメモリ上に置きます。 その後POSTされてきたデータの内容を見て、クエリをまとめます。 最後に一気にまとめたクエリを実行します。 とりあえずこうすれば二度のクエリで実行出来る事になるでしょうから、DBがロックされている時間も僅かだと思います。 私は全体的な見直しで数分かかっていた処理を数秒まで縮める事が出来ました(これは前任者のプログラミングがいかに悪いか、と言う事にもなりますけどね)。 また、これはもっと根本的な設計に関わるでしょうが、不必要なデータのお蔵入り、確定データのテーブル作成等も重要な事だと思います。 サーバの環境をいじれるのなら、PostgreSQLのチューニング(メモリ環境やvacum等)も大事です。 参考まで。
- gogo-tea
- ベストアンサー率75% (25/33)
>という形になると思いますが、どのように実現すればよいか解らず困っております。 実現する方法がわからない部分は具体的にどの部分なのかというのがいまいちはっきりしないのでお答えしにくいのですが・・・、 TDをechoしている部分を見ていて思ったのですが、work_checkのvalueは $ymddateではなく$dとかにしてチェックの入っている位置としての配列にしてみてはどうでしょうか。 work_timeも添え字をつけずにwork_time[]としたとして 仮にデータが --------------------- 日付 チェック 労働時間 20070415 レ 8 20070416 9 20070417 レ 7 20070418 レ 10 20070419 12 --------------------- とすると $work_check = array([0]=>0 [1]=>2 [2]=>3) $work_time = array([0]=>8 [1]=>9 [2]=>7 [3]=>10 ・・・) という形で受け取れるかと思うのであとは日付も同じように順番に $arrdate = array([0]=>20070415 [1]=>20070416 ・・・) といった配列を作れば、 14~30日のどこにチェックが入ってPOSTされたかわかるので ループさせながらSQLでデータがあるかチェックし、INSERT・UPDATEの処理をする。 という案はどうでしょうか。 あまりスマートな方法ではないですし、実際に動かしていないので処理抜けがあるかもしれませんが。。
- gogo-tea
- ベストアンサー率75% (25/33)
チェックボックスを使うということは、チェックされた複数行をボタン1つでいっぺんに追加・更新を行うということですよね? idはこのページを表示している時点で取得できてるはずなのでそのままhiddenでPOSTなりセッションなりで次のページで取得できますよね。 日付の取得方法がわからないというのは現在のページでは >echo "<TD><INPUT TYPE='CHECKBOX' NAME='work_check[]' VALUE='$ymddate' TABINDEX=2></TD>"; と書かれているので、次のページで受け取る方法がわからないということでしょうか? だとすれば次のページの先頭にでも if(isset($_POST['work_check'])){ $chk = $_POST['work_check']; print_r($chk); } のようにしてチェックされた日付がちゃんと受け取れるか確認してみたらどうかと思います。 ちなみにwork_check[]という形でPOSTするとwork_checkは array(work_check[0],work_check[1],work_check[2]) のような配列になると思うので、受け取るページ側での処理も配列として受け取って配列として処理をしなければいけないと思います。
> DBの該当データの有無によってINSERT、UPDATEを使い分ける DBに該当データがあるかないかを判断する方法はおわかりですか? if (該当データあり) { insert文を発行; } else { update文を発行; } という処理になるであろう、ということはおわかりですか? 上に書いた処理をphpでどのように書けばよいかはおわかりですか?
お礼
miraiya様、お世話になっております。 質問ばかりで申し訳ございません。 DBに該当データがあるかないかを判断する方法 $sql = "SELECT * FROM work_tbl WHERE id = 'ログインしている人のID', day = '日付?';"; $result = pg_query($con, $sql) if(result) { pg_query($con, "INSERT ~"); } else { pg_query($con, "UPDATE~"); } という処理になると思います。 しかし、肝心のチェックをつけた箇所だけINSERT、UPDATEするという処理 PHPで表示させている日付の取得方法などが解りません。 解りにくい質問ではあると思いますが、ご教授・参考になる考え方など… お待ちしております。 よろしくお願いします。
- Bonjin
- ベストアンサー率43% (418/971)
で、質問は何でしょう?
補足
Bonjin様、失礼しました。 DBに大きな負荷をかけてしまい、壊しそうになっていたので 頭が混乱しておりました… 当方が行いたい処理として -------------------------------- 日付 | 労働時間 | チェックボックス -------------------------------- というフォームがあり、日付はPHPで表示しております。 労働時間を入力し、 チェックを押したとき、DBに該当データがあれば、INSERTを… チェックを押したとき、DBに該当データがなければ、UPDATEを… という処理を行いたいのですが、DBの該当データの有無によってINSERT、UPDATEを使い分ける知識が無いため、皆様のお力をお借りしたいと思っております。
補足
gogo-tea様、いつもお世話になっております。 >複数行をボタン1つでいっぺんに追加・更新を行うということですよね その通りでございます。 労働時間を入力し登録ボタンを押せば、そのままのページに再表示されるように作ろうと思っております。 チェックボタンを押して登録ボタンを押したとき、自分の考えてるロジックは PHP側で count("調べるカラム")とし if(~){ // SELECTして該当データがあればUPATE } else { SELECTして該当データがなければINSERT } という形になると思いますが、どのように実現すればよいか解らず 困っております。