質問するログイン新規登録

回答編集履歴

5

追記

2019/02/06 03:14

投稿

m.ts10806
m.ts10806

スコア80888

answer CHANGED
@@ -138,4 +138,9 @@
138
138
  その場合だとSQLインジェクションの対策もきちんとやってるか?
139
139
  というのが大事になります。
140
140
  prepare→bindValueの流れは必須ですね。
141
- 今回はそこまで求められていないので書いていませんが。
141
+ 今回はそこまで求められていないので書いていませんが。
142
+
143
+ -------
144
+
145
+ あと、この記事は読んでいただきたい。
146
+ - [エラーメッセージの読み方と対処, 検索や質問の原則](https://qiita.com/cannorin/items/eb062aae88bfe2ad6fe5)

4

調整

2019/02/06 03:14

投稿

m.ts10806
m.ts10806

スコア80888

answer CHANGED
@@ -116,7 +116,7 @@
116
116
 
117
117
  function connect_db(){
118
118
  try{
119
- $dbh = new PDO("mysql:dbname=***;host=***;charset=utf8mb4"
119
+ return new PDO("mysql:dbname=***;host=***;charset=utf8mb4"
120
120
  ,"***"
121
121
  ,"***",
122
122
  [
@@ -128,8 +128,6 @@
128
128
  var_dump($e);
129
129
  die();
130
130
  }
131
-
132
- return $dbh;
133
131
  }
134
132
 
135
133
  var_dump(get_sql_data($sql,false));

3

調整

2019/02/06 02:45

投稿

m.ts10806
m.ts10806

スコア80888

answer CHANGED
@@ -82,7 +82,7 @@
82
82
  return $dbh;
83
83
  }
84
84
 
85
- var_dump(get_sql_data("select * from hosts",false));
85
+ var_dump(get_sql_data($sql,false));
86
86
 
87
87
  ```
88
88
 
@@ -116,9 +116,9 @@
116
116
 
117
117
  function connect_db(){
118
118
  try{
119
- $dbh = new PDO("mysql:dbname=test;host=localhost;charset=utf8mb4"
119
+ $dbh = new PDO("mysql:dbname=***;host=***;charset=utf8mb4"
120
- ,"root"
120
+ ,"***"
121
- ,"",
121
+ ,"***",
122
122
  [
123
123
  PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
124
124
  PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
@@ -132,7 +132,7 @@
132
132
  return $dbh;
133
133
  }
134
134
 
135
- var_dump(get_sql_data("select * from hosts",false));
135
+ var_dump(get_sql_data($sql,false));
136
136
  ```
137
137
 
138
138
  mysqli版でもpdo版でもですが、本来はSQLには色々あって、

2

調整

2019/02/06 02:41

投稿

m.ts10806
m.ts10806

スコア80888

answer CHANGED
@@ -56,6 +56,7 @@
56
56
  var_dump($e);
57
57
  die();
58
58
  }
59
+ //dbの解放は余程でかい処理をする以外は自動でされるのでなくてもいいと思う。
59
60
  }
60
61
 
61
62
  function connect_db(){
@@ -80,6 +81,63 @@
80
81
  }
81
82
  return $dbh;
82
83
  }
84
+
85
+ var_dump(get_sql_data("select * from hosts",false));
86
+
83
87
  ```
84
88
 
85
- 蛇足コメントも読んでください。
89
+ 蛇足コメントも読んでください。
90
+
91
+ # 蛇足コード
92
+
93
+ ちなみにPDO版。結果は同じ。
94
+ ```php
95
+ <?php
96
+ function get_sql_data(String $sql,Bool $record_count = true):array{
97
+ $dbh = connect_db();
98
+
99
+ try{
100
+ $stmt = $dbh->query($sql);
101
+
102
+ //データを返す
103
+ if($record_count){
104
+ //レコード数取得
105
+ return ["count"=>$stmt->rowCount()];
106
+ } else {
107
+ //レコード返却
108
+ return $stmt->fetchAll();
109
+ }
110
+
111
+ }catch(PDOException $e){
112
+ var_dump($e);
113
+ die();
114
+ }
115
+ }
116
+
117
+ function connect_db(){
118
+ try{
119
+ $dbh = new PDO("mysql:dbname=test;host=localhost;charset=utf8mb4"
120
+ ,"root"
121
+ ,"",
122
+ [
123
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
124
+ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
125
+ ]
126
+ );
127
+ } catch (PDOException $e) {
128
+ var_dump($e);
129
+ die();
130
+ }
131
+
132
+ return $dbh;
133
+ }
134
+
135
+ var_dump(get_sql_data("select * from hosts",false));
136
+ ```
137
+
138
+ mysqli版でもpdo版でもですが、本来はSQLには色々あって、
139
+ 例えばSELECTだとwhere句がついてきたりします。
140
+ その場合だとSQLインジェクションの対策もきちんとやってるか?
141
+ というのが大事になります。
142
+ prepare→bindValueの流れは必須ですね。
143
+ 今回はそこまで求められていないので書いていませんが。

1

修正

2019/02/06 02:40

投稿

m.ts10806
m.ts10806

スコア80888

answer CHANGED
@@ -25,4 +25,61 @@
25
25
  確かにmysql→mysqliへの移行をしたいのは分かりますが、
26
26
  [PDOとmysqliはどっちを使うべき?](https://teratail.com/questions/40450)の質問の回答にあるように、移植性が非常に良くなく、質問者さんのように問題を潰したと思ったらまた問題が・・・と問題対応しているだけで疲弊してしまいます。
27
27
 
28
- できれば上記記事にあるようなPDOへの移行を強くすすめます。
28
+ できれば上記記事にあるようなPDOへの移行を強くすすめます。
29
+
30
+ # サンプルコード:
31
+
32
+ 答えは「1つ目で出ているエラーではmysqli_connect()の結果linkを第1引数に渡していない」
33
+ これは何度もコメントしています。
34
+ そこを入れればとりあえず1つ進むはず。
35
+
36
+ けど、せっかくPHP7ですし、無駄な記述も多いのでPHP7っぽい要素を入れて書き換えてみた。
37
+ ※文字コードはUTF8前提。もし違うならそこは書き加えてください。その場合の動作の保障はしませんのでエラーが出たら自身で追ってみてください。
38
+ ```php
39
+ <?php
40
+ function get_sql_data(String $sql,Bool $record_count = true):array{
41
+ $dbh = connect_db();
42
+ try{
43
+ $rs = mysqli_query($dbh,$sql);
44
+
45
+ //データを返す
46
+ if($record_count){
47
+ //レコード数取得
48
+ return ["count"=>mysqli_num_rows($rs)];
49
+ } else {
50
+ //レコード返却
51
+ //蛇足コメント:whileでfetchしても結局全行取り出すならmysqli_fetch_allで第2引数オプション指定するだけでいい
52
+ return mysqli_fetch_all($rs,MYSQLI_ASSOC);
53
+ }
54
+
55
+ }catch(mysqli_sql_exception $e){
56
+ var_dump($e);
57
+ die();
58
+ }
59
+ }
60
+
61
+ function connect_db(){
62
+ try{
63
+ //蛇足コメント:元のコードではSERVER_NAMEとかで分岐させているけどかなり古いやり方。
64
+ //それなら設定ファイルを別にもってそこから読み出すようにした方がいい。定数定義のファイルとか。「環境毎に変わらない情報」なので。コードを何度も書き換えることになるのでメンテナンス性が悪い
65
+ $dbh = mysqli_connect("***", "***", "***", "***"); //MySQL接続
66
+
67
+ //蛇足コメント:SET NAMESは基本使わない。それならmysqli()クラスでnewしてset_charset()した方が自然
68
+ /* 例:PHPマニュアルより引用
69
+ $mysqli = new mysqli("***", "***", "***", "***");
70
+ $mysqli->set_charset('utf8');
71
+ */
72
+ if (mysqli_connect_errno()) {
73
+ printf("Connect failed: %s\n", mysqli_connect_error());
74
+ die();
75
+ }
76
+ //蛇足コメント:これで捕捉できるかは未確認。でもtry-catchは必須。PDOExceptionのほうが正直扱いやすい
77
+ }catch(mysqli_sql_exception $e){
78
+ var_dump($e);
79
+ die();
80
+ }
81
+ return $dbh;
82
+ }
83
+ ```
84
+
85
+ 蛇足コメントも読んでください。