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

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

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

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

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

解決済

2回答

1270閲覧

基本的には同じ処理だが、値の部分が微妙に違ってくる時 PHP

Z-TALBO

総合スコア525

PHP

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

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

2クリップ

投稿2017/02/07 09:59

編集2017/02/07 10:45

###はじめに
同じような処理をしている時など、オブジェクト指向とかで簡潔にという事が言われたりもしていますが、、、

今やっている条件の分岐だったりも確かに同じ処理を何度か書く必要が出てきています。
しかし、これだったらこれ、あれだったらあれという部分においてその辺も含めてすっきり書けるものか、もう、このままズラズラ書くものか考えています。

アドバイス等いただければと思います。

###基本的にやっていること
1.A,B,C,Dのいずれかを選択
2.WorkIn, WorkOut, RestIn, RestOutのいずれかを選択
3.送信
4.1,2の値が両方セットされてなければ何もしない、セットされれば次の処理
5.送信された時のYmd,Hiを取得
6.データベースで1の値とYmdを使ってSELECT
7.データが無ければInsert処理へ
8.データが有ったらUpdate処理へ
※このUpdate処理の部分で少し考えています。。。

###データベース

MySQL

1tablename Test 2id int not null primary key auto_increment, 3Name varchar(2), 4TimeDate date, 5WorkIn time, 6WorkOut time, 7RestIn time, 8RestOut time

###Update部分
とりあえずInsertまでの部分に関しては共通の動きばかりなので、ここでは取り上げません。

PHP

1// データベースにアクセスしてデータのチェック 2$tableCheck = TableCheckDb($Name, $TimeDate); 3if($tableCheck === false) { 4 // データが無いので、WorkIn~RestOutまでどれを押されてもInsert処理させる 5} else { 6 // データがあったので、その値もチェックしていく必要がある 7 // 1.そもそも上記②の値のどれが送られたかで条件分岐がはじまる 8 if($value === "WorkIn") { 9 10 } elseif($value === "WorkOut") { 11 12 } elseif($value === "RestIn") { 13 14 } elseif($value === "RestOut") { 15 16 }

PHP

1// 今回はこちらをテストとして記載していきます 2if($value === "WorkIn") { 3 // 選択されたのがWorkInだった時 4 // データ自体は存在しているが、$tableCheck["WorkIn"]に値があるのかどうか? 5 if($tableCheck["WorkIn"] !== "00:00:00") { 6 // 既に入っている場合は今回では処理を終了とする 7 return; 8 } else { 9 // データはあるが、WorkInにはまだ時刻が入っていない場合 10 // データがあるので下記のような値がテーブルにあるとします 11 /* 12 * id 1 13 * Name A 14 * TimeDate '2017-02-07' 15 * WorkIn '00:00:00' 16 * WorkOut '00:00:00' 17 * RestIn '00:00:00' 18 * RestOut '00:00:00' 19 */ 20 // 今回はUpdateなので、基本的な部分はテーブルからの値をそのまま使い、WorkInの部分だけ送信された時の時刻を入れることにします 21 $this->id = $tableCheck["id"]; 22 $this->Name = $tableCheck["Name"]; 23 $this->WorkIn = $WorkIn // date('H:i')で取得した値 24 $this->WorkOut = $tableCheck["WorkOut"]; 25 $this->RestIn = $tableCheck["RestIn"]; 26 $this->RestOut = $tableCheck["RestOut"]; 27 $this->_Update(// 値をセット); 28}

Updateの部分自体は共通で良いと思うのですが、
今回の場合WorkInならWorkIn以外はテーブルのデータ、
WorkOutならWorkOut以外がテーブルのデータという事になろうかと思います。

それぞれを作ってもいいのですが、、、
function WorkIn_Upとかみたいに、、、
もし、すっきりこれで行けるかもという方法、又はそもそもこういうやり方自体が遠回りなやり方なんだとは思うのですが、、、アドバイス等いただければと思います。

今回は、これだけといえばこれだけですので、わざわざより書いた方が早いかもしれませんが、ここから項目の増化なりなんなりに応用できるかなと思ったので、、、

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

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

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

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

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

guest

回答2

0

ベストアンサー

私だったら下記の様に書きますね。Ifを書くのは避けられそうになかったので、できるだけ集約しました。
少しは見通しが良くなると思います。

php

1 public function update(){ 2 // データベースにアクセスしてデータのチェック 3 $tableCheck = TableCheckDb($Name, $TimeDate); 4 if($tableCheck === false) { 5 // データが無いので、WorkIn~RestOutまでどれを押されてもInsert処理させる 6 } else { 7 // 既に入っている場合は今回では処理を終了とする 8 if(!$this->checkValue($tablecheck, $value)){ 9 return; 10 } 11 // データがあったので、その値もチェックしていく必要がある 12 // 1.そもそも上記②の値のどれが送られたかで条件分岐がはじまる 13 $this->id = $tableCheck["id"]; 14 $this->Name = $tableCheck["Name"]; 15 $this->WorkIn = $tableCheck["WorkIn"]; // date('H:i')で取得した値 16 $this->WorkOut = $tableCheck["WorkOut"]; 17 $this->RestIn = $tableCheck["RestIn"]; 18 $this->RestOut = $tableCheck["RestOut"]; 19 //ここで入ってきたパラメータによって、内容を上書きする 20 //$infoには実際に設定したい$WorkIn等を入れておく想定 21 $this->updateTableCheck($value,$Info); 22       $this->_Update(// 値をセット); 23 24 } 25 } 26 27 /** 28 * テーブルに値が入っていればfalseを返す 29 * @param type $tablecheck 30 * @param type $value 31 * @return boolean 32 */ 33 private function checkValue($tablecheck,$value){ 34 if($tableCheck[$value] !== "00:00:00"){ 35 return false; 36 } 37 return true; 38 } 39 40 /** 41 * TableCheckを条件に応じてTableChekを上書きする。 42 * @param type $tableCheck 43 * @param type $value 44 */ 45 private function updateTableCheck($value,$Info){ 46 //実際には$workinとかの情報を引数としてArrayに詰めて渡す。 47 if($value === "WorkIn") { 48 $this->WorkIn = $Array['WorkIn']; 49 } elseif($value === "WorkOut") { 50 $this->WorkOut = $Array['WorkOut']; 51 } elseif($value === "RestIn") { 52 $this->RestIn = $Array['RestIn']; 53 } elseif($value === "RestOut") { 54 $this->RestOut = $Array['RestOut']; 55 } 56 }

投稿2017/02/08 01:29

編集2017/02/08 01:44
motuo

総合スコア3027

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

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

Z-TALBO

2017/02/08 08:14

回答感謝いたします! 見通しがわかりやすくなり、こちらの回答を元に、現在実際にテストしているコードと置き換えつつ書いてみましたが、一つのメソッドのコード量も分散され、わかりやすくなりました! まだまだ、そもそもの設計部分などで荒さがあるかと思いますが、少しずつ綺麗に書けるようにしていきたいと思います。
guest

0

こんにちは。
私でしたら、テーブル構造が示されたとおりであればおそらくズラズラ書くことにすると思います。

ここでは、別の方法をお示ししたいと思います。

1.テーブルは次のようにします。DB 不明なので、適宜合わせていただければと思います。

SQL

1tablename Test 2id int not null primary key auto_increment, 3Name varchar(2), 4TimeDate date, 5TimeStamp time, 6TimeKind char(1)

2.受信したときは、Insertだけを行います。TimeKind には、タイムスタンプの種別として、識別文字 WorkIn='a', WorkOut='b', RestIn='c', RestOut='d'(もっと増やせる...)などのように入れます。数値でも列挙型でもよいでしょう。

3.WorkIn, WorkOut, RestIn, RestOutデータを取り出すときに、次のようなSQL文を発行します。

SQL

1SELECT 2 Test.Name, 3 Test.TimeDate, 4 MIN(TestWorkIn.TimeStamp) WorkIn 5 MAX(TestWorkOut.TimeStamp) WorkOut, 6 MIN(TestRestIn.TimeStamp) RestIn, 7 MAX(TestRestOut.TimeStamp) RestOut 8 From Test 9LEFT JOIN Test AS TestWorkIn ON TestWorkIn.Name=Test.Name AND TestWorkIn.TimeDate=Test.TimeDate AND TestWorkIn.TimeKind='a' 10LEFT JOIN Test AS TestWorkOut ON TestWorkOut.Name=Test.Name AND TestWorkOut.TimeDate=Test.TimeDate AND TestWorkOut.TimeKind='b' 11LEFT JOIN Test AS TestRestIn ON TestRestIn.Name=Test.Name AND TestRestIn.TimeDate=Test.TimeDate AND TestRestIn.TimeKind='c' 12LEFT JOIN Test AS TestRestOut ON TestRestOut.Name=Test.Name AND TestRestOut.TimeDate=Test.TimeDate AND TestRestOut.TimeKind='d' 13GROUP BY Test.Name, Test.TimeDate 14ORDER BY Test.Name, Test.TimeDate

RestIn などの送信がない場合はNULLで返ります。NULL以外で返したい場合は、DBによりますがSQL文中にNVLやISNULLなどを使用して置き換えます。

同日・同一人物について同じ種類の送信がされた場合、WorkIn, RestInはいちばん最初の時刻(MINによる)、WorkOut, RestOutはいちばん遅い時刻(MAX)が採用されます。一旦WorkOutしたけど、追加の仕事をしてWorkingTimeが伸びた場合を考慮しています。2.のときに同一条件の送信が登録されていたら、種別に応じて無視するか、古いレコードを削除して追加するかUpdateするようにすれば、GROUP BY などの集合演算が不要になり、レコード数も無駄がなくなります。ただ、タイムカード関連の運用は利用者のトラブル(他人のを間違えて押してしまった、カードがうまく認識されなかったなど)がつきものであり、ログ的にデータを記録をしておくと便利なので、私はひたすらInsertさせるように作ります。

ご参考になれば幸いです。

投稿2017/02/08 01:21

編集2017/02/08 01:22
hsk

総合スコア728

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

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

Z-TALBO

2017/02/08 08:10

回答大変感謝いたします。 私では、はっきり言ってまだこちら側から考えていくというのを全く思いつきませんでした。。。 そして、Insertの後はUpdateだろうという固まった考えでありましたが、Insertだけさせることで、ログとしての機能も持たせていくという事で、とても参考になりました! 試してみたいと思います!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問