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

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

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

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

4回答

4303閲覧

PHP DBから抽出データ、配列、SESSION、class

Z-TALBO

総合スコア525

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

1グッド

0クリップ

投稿2016/05/19 10:24

###はじめに
たぶん、何やってんだろう?という質問内容かと思いますが、アドバイスをいただければと思います。

###やりたいこと
漠然としてはいますが、たぶんclassを作るのに、すごい遠回りをし始めているんだと思います。

そして、MVCなどの考え的なのはなんとなくわかるのですが、イマイチclassとかの部分がまだ理解できておりません。

とりあえず、例えばですが、、、

<select> <option></option> <?php $dbh = connectDb(); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $sql = "SELECT id, name FROM users ORDER BY id ASC"; $stmt = prepare($sql); $stmt->execute(); while ($row = $stmt->fetch()) : $id = $row['id']; $name = $row['name']; ?> <option value="<?= $id; ?>"><?= $name; ?></option> <?php endwhile; ?> </select>

上記のように、SelectのoptionをDBから引っ張ってきて作成するというものがあるとします。

これだけで、普通にできているのですが、あえて、、、処理をわけてわざわざ複雑な感じにしてみたいと思います。
※なんでするの?というのは、とりあえず聞かないでください、、、、

###とりあえず考えてみたこと
classとかの部分が勉強不足なので、とりあえず処理を分けるということだけを考えてみました。

[index.php] <!-- select_box --> <?php select_box(); ?>
[db.php] function select_db() { $dbh = connectDb(); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $sql = "SELECT id, name FROM users ORDER BY id ASC"; $stmt = prepare($sql); $stmt->execute(); $rows = $stmt->fetchAll(); $_SESSION['rows'] = $rows; }
[processing.php] function select_box() { select_db(); $cnt = count($_SESSION['rows']); echo "<select name='select_box'><option></option>"; for ($i = 0; $i <= $cnt; $i++) { $select['id'] = $_SESSION['rows'][$i]['staff_id']; $select['name'] = $_SESSION['rows'][$i]['name']; echo "<option value=" . $select['id'] . ">" . $select['name'] . "</option>"; } echo "</select>";

###とりあえずの結果
表示することはとりあえずできました。

###問題等
処理を分けるという考え方だけなら、indexは表示だけ、dbがDBからのデータを抽出しただけ、processingでデータを加工?したという感じ?になったような気はしますが、、、
とりあえず、よくわかってない部分で、、、
1.これでデータを取得したら、なぜかデータの最後に空白ができてた。
当然最初に<option></option>があるので、最初は空白ですが、その後データの最後にまた空白ができてしまっていました。

2.上記はとりあえず独学と、いろいろ質問させてもらったりサイトを見たのを使いながらゴリゴリ書いていきましたが、これをもう少しこうすれば?というアドバイスやヒントなどいただければと思って質問いたしました。

ここは、こうしたほうがわかりやすい。
ここは、無駄でなくてもいいはず。
さらにここは省略するべきなど、、、ご意見いただけますでしょうか?

なんじゃこの書き方は?と思われるでしょうが、参考のために、、、

yodel👍を押しています

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

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

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

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

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

guest

回答4

0

ベストアンサー

2.上記はとりあえず独学と、いろいろ質問させてもらったりサイトを見たのを使いながらゴリゴリ書いていきましたが、これをもう少しこうすれば?というアドバイスやヒントなどいただければと思って質問いたしました。

基本的な文法や使い方がわかってきている段階に見えますので、
ここいらで書籍を使って学習することをお勧めします。
もちろんネットで学習できることも多いですし、書籍でもダメなものはありますが、
「なぜ処理をまとめた方が便利なのか」という部分の学習も含めてコードが設計されていることが多いので、
効率よく学習出来ることが多いです。

例えば今回のケースだと
戻り値の使い道についてピンと来ていないように見えます。

PHP

1[db.php] 2function select_db() { 3$dbh = connectDb(); 4$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 5$sql = "SELECT id, name FROM users ORDER BY id ASC"; 6$stmt = prepare($sql); 7$stmt->execute(); 8$rows = $stmt->fetchAll(); 9$_SESSION['rows'] = $rows; 10}

だと切り出しただけであんまり意味が無いです。
具体的には、結果を$_SESSIONに格納してしまっているので、
どこか別のタイミングで呼ばれたとしても$_SESSIONを意図せず汚してしまうことになります。

なので例えば

PHP

1function select_db() { 2$dbh = connectDb(); 3$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 4$sql = "SELECT id, name FROM users ORDER BY id ASC"; 5$stmt = prepare($sql); 6$stmt->execute(); 7$rows = $stmt->fetchAll(); 8return $rows; 9}

と、結果を戻り値で返すようにしてやって

PHP

1[processing.php] 2function select_box() { 3$rows = select_db(); 4$cnt = count($rows); 5echo "<select name='select_box'><option></option>"; 6for ($i = 0; $i <= $cnt; $i++) { 7$select['id'] = $rows[$i]['staff_id']; 8$select['name'] = $rows[$i]['name']; 9echo "<option value=" . $select['id'] . ">" . $select['name'] . "</option>"; 10} 11echo "</select>";

としてやれば、select_db()は別の場所で使っても問題の無い関数になります(処理の再利用が出来るようになったので、別ページで同じことをしようとした時に同じコードをコピペしなくてよくなります)

同様に、
引数についても正しく使えば便利で
例えば

PHP

1function select_db($order,$sort) { 2$dbh = connectDb(); 3$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 4$sql = "SELECT id, name FROM users ORDER BY :order :sort"; 5$stmt = $dbh->prepare($sql); 6$stmt->bindValue(':order', $order, PDO::PARAM_STR); 7$stmt->bindValue(':sort', $sort, PDO::PARAM_STR); 8$stmt->execute(); 9$rows = $stmt->fetchAll(); 10return $rows; 11}

とすれば、呼び出すタイミングでソートするキーと昇順/降順を指定するだけで、実際に実行されるSQLを変更することが出来て便利だったりします。

投稿2016/05/19 10:52

tanat

総合スコア18709

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

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

Z-TALBO

2016/05/19 23:41

回答ありがとうございます! 確かにreturnの返り値や引数という部分がぴんと来ていませんでした。。。 SESSIONもこんなにやるとUNSETも増えたりで、なんか大変だよな、、、とは思っていたのですが、、、そこに気づけませんでした。 大変参考になりました!ありがとうございます!
guest

0

MVCは自信ないのでoptionの件だけ・・・

最後のoptionが空になるのはfor ($i = 0; $i <= $cnt; $i++)のせいですね
count($_SESSION['rows'])でデータ数を取得していますが実際のデータは0から始まるので
for ($i = 0; $i < $cnt; $i++)としてあげてください。

$data配列のデータ数が2の場合は$data[0]$data[1]の2つだけと考えて見てください。

投稿2016/05/19 10:32

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Z-TALBO

2016/05/19 10:36

あっ!そうですよね! よく忘れるんです、、、0からなの、、、 ありがとうございます!
guest

0

基本的にDBのクラスからはHTMLを出力したりするのはメンテしにくくなるので、単純に配列出会ったり、オブジェクトを返すだけにしたほうが汎用性が上がります。
スケルトンで書いてみましたが、以下のようにクラスを実装してみては?

php

1<?php 2 3class MySQL 4{ 5 6 /** 7 * ホスト 8 */ 9 private $host = 'localhost'; 10 11 /** 12 * データベース 13 */ 14 private $database = 'database'; 15 16 /** 17 * ユーザー 18 */ 19 private $user = 'root'; 20 21 /** 22 * パスワード 23 */ 24 private $pass = ''; 25 26 /** 27 * DSN 28 */ 29 private $dsn = null; 30 31 /** 32 * 接続 33 */ 34 private $dbh = null; 35 36 /** 37 * コンストラクタ 38 */ 39 public function __construct() 40 { 41 $this->connect(); 42 } 43 44 /** 45 * 接続する 46 * @return $dbh 47 */ 48 private function connect() 49 { 50 $this->dsn = "mysql:dbname={$this->database};host={$this->host};charset=utf8"; 51 $this->dbh = new PDO($this->dsn, $this->user, $this->pass); 52 } 53 54 /** 55 * SELECT 56 * @param string $sql 57 * @param array $arrParams 58 * @return array 59 */ 60 public function select($sql, $arrParams) 61 { 62 // @todo 63 return $arrRecords; 64 } 65 66 /** 67 * UPDATE 68 * @param string $sql 69 * @param array $arrParams 70 * @return bool 71 */ 72 public function update($sql, $arrParams) 73 { 74 // @todo 75 return $bool; 76 } 77 78 /** 79 * INSERT 80 * @param string $sql 81 * @param array $arrParams 82 * @return int 83 */ 84 public function insert($sql, $arrParams) 85 { 86 // @todo 87 return $insertId; 88 } 89 90} 91 92

投稿2016/05/19 10:52

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Z-TALBO

2016/05/19 23:38

回答ありがとうございます! クラスの実装に関してアドバイスいただき、大変参考になります! クラス部分の作り方など参考にさせていただきます!
guest

0

とりあえず自分の好みでいうとこんな感じかなあ

[index.php] <!-- select_box --> <select name='select_box'><option></option> <?php echo select_box(); ?> </select> [db.php] function select_db($sql) { $dbh = connectDb(); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $stmt = prepare($sql); $stmt->execute(); return $stmt->fetchAll(); } [processing.php] function select_box() { $sql = "SELECT id, name FROM users ORDER BY id ASC"; $ret = ''; foreach (select_db($sql) as $row) { $id = $row['id']; $name = $row['name']; $ret .= "<option value=" . $id . ">" . $name . "</option>\n"; } return $ret; }

投稿2016/05/19 10:47

takasima20

総合スコア7458

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

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

Z-TALBO

2016/05/19 23:37

回答ありがとうございます! なんだか、スッキリしました。 for文で考えていたので、foreachの方も参考にいたします! indexの方で<select>タグはやはり出しておいたほうが、いいですね。 nameが~ってなった時にfunctionを見に行かなくて済みます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問