回答編集履歴
7
短縮
answer
CHANGED
@@ -252,6 +252,21 @@
|
|
252
252
|
あとは自身のコードに考え方を反映するだけ!
|
253
253
|
頑張ってください。
|
254
254
|
|
255
|
+
ちなみに[短く書く](http://php.net/manual/ja/language.operators.comparison.php#language.operators.comparison.ternary)ならこう。
|
256
|
+
```php
|
257
|
+
function get(int $num):array{
|
258
|
+
$a = [
|
259
|
+
["id"=>1,
|
260
|
+
"name"=>"test"
|
261
|
+
],
|
262
|
+
["id"=>2,
|
263
|
+
"name"=>"test2"
|
264
|
+
],
|
265
|
+
];
|
266
|
+
return (array_key_exists($num,$a))?$a[$num]:[];
|
267
|
+
}
|
268
|
+
```
|
269
|
+
|
255
270
|
# デバッグについて
|
256
271
|
|
257
272
|
そういえば、各所でvar_dump()を入れられてデバッグをされていますが、本来確認しなければならない項目を確認していません。
|
6
修正
answer
CHANGED
@@ -198,8 +198,9 @@
|
|
198
198
|
複数人で同じプロジェクトで開発していたら、同じように使えるわけですし、引数って言っても変数です。変数は何が入っているか分からないもので、後から書き換え可能です。
|
199
199
|
|
200
200
|
実際のプログラムでは入力値が入ってきたりクエリストリングから受け取ったパラメータが入ってきたりして、本当に何が来るか分からないわけです。
|
201
|
-
もし新しいPHP環境であれば、[引数の型を制限](http://php.net/manual/ja/functions.arguments.php#functions.arguments.type-declaration)できます。
|
202
201
|
|
202
|
+
下記のようにして[引数の型を制限](http://php.net/manual/ja/functions.arguments.php#functions.arguments.type-declaration)します。
|
203
|
+
|
203
204
|
※とりあえず「それならこれでいい」のコードで
|
204
205
|
```php
|
205
206
|
function get(int $num){
|
@@ -220,7 +221,7 @@
|
|
220
221
|
確実に存在する値が引数として与えられるか保証はありませんよね。
|
221
222
|
この場合、2とか与えられたら下記のようなエラーが出ます。
|
222
223
|
|
223
|
-
`PHP Notice: Undefined offset: 2 in XXX.php on line 11`
|
224
|
+
`PHP Notice: Undefined offset: 2 in XXX.php on line 11`
|
224
225
|
|
225
226
|
未定義の[オフセット](https://wa3.i-3-i.info/word11923.html):2
|
226
227
|
|
5
修正
answer
CHANGED
@@ -198,7 +198,7 @@
|
|
198
198
|
複数人で同じプロジェクトで開発していたら、同じように使えるわけですし、引数って言っても変数です。変数は何が入っているか分からないもので、後から書き換え可能です。
|
199
199
|
|
200
200
|
実際のプログラムでは入力値が入ってきたりクエリストリングから受け取ったパラメータが入ってきたりして、本当に何が来るか分からないわけです。
|
201
|
-
もし新しいPHP環境であれば、引数の型を制限できます。
|
201
|
+
もし新しいPHP環境であれば、[引数の型を制限](http://php.net/manual/ja/functions.arguments.php#functions.arguments.type-declaration)できます。
|
202
202
|
|
203
203
|
※とりあえず「それならこれでいい」のコードで
|
204
204
|
```php
|
@@ -227,7 +227,7 @@
|
|
227
227
|
つまり、配列に存在しないポイント、という意味ですね。
|
228
228
|
※配列にキーが存在しない場合と同等です
|
229
229
|
|
230
|
-
阻止するために、「存在するキーが与えられていたら取得」としましょう。
|
230
|
+
阻止するために、[「存在するキーが与えられていたら取得」](http://php.net/manual/ja/function.array-key-exists.php)としましょう。
|
231
231
|
|
232
232
|
```php
|
233
233
|
function get(int $num):array{
|
@@ -245,7 +245,7 @@
|
|
245
245
|
return [];
|
246
246
|
}
|
247
247
|
```
|
248
|
-
ついでに、返り値の型も宣言しておき、存在した場合、そのまま返却、そうでない場合は空の配列を返すようにしました。
|
248
|
+
ついでに、[返り値の型も宣言](http://php.net/manual/ja/functions.returning-values.php#functions.returning-values.type-declaration)しておき、存在した場合、そのまま返却、そうでない場合は空の配列を返すようにしました。
|
249
249
|
これでひとまずいい感じにはできましたね。
|
250
250
|
|
251
251
|
あとは自身のコードに考え方を反映するだけ!
|
4
修正
answer
CHANGED
@@ -277,7 +277,7 @@
|
|
277
277
|
function getMouths($itemperpage, $currentpage)
|
278
278
|
{
|
279
279
|
var_dump($mouths);
|
280
|
-
//
|
280
|
+
//後略
|
281
281
|
}
|
282
282
|
```
|
283
283
|
こうしておけば、最初のNotice`PHP Notice: Undefined variable:`が出て気づけたでしょうね。
|
3
修正
answer
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
|
9
9
|
プログラムは指示したとおりにしか動きません。自分が思ったとおりに動くと思っていませんか?
|
10
10
|
その考えは今すぐ捨てましょう。
|
11
|
-
この内容で「なぜNULLになるのか」という質問が出る時点で質問者さんは思ったとおりコードを動かせる
|
11
|
+
この内容で「なぜNULLになるのか」という質問が出る時点で質問者さんは思ったとおりコードを動かせる域には到底達していません。
|
12
12
|
|
13
13
|
# ミニマムコード
|
14
14
|
|
@@ -285,10 +285,18 @@
|
|
285
285
|
|
286
286
|
デバッグの仕方、本来確認すべき項目はきちんとおさえるようにしないと、デバッグがデバッグになりません。気をつけましょう。
|
287
287
|
|
288
|
-
**質問者さんは思ったとおりコードを動かせる
|
288
|
+
**質問者さんは思ったとおりコードを動かせる域には到底達していません。**
|
289
289
|
|
290
|
+
----------
|
290
291
|
|
291
292
|
蛇足:
|
292
293
|
きちんと意味のある変数名つけてますか?
|
293
294
|
mouthって「口」ですけど。
|
294
|
-
「口コミ」なら「reviews」ですね。レビュー。
|
295
|
+
「口コミ」なら「reviews」ですね。レビュー。
|
296
|
+
他人が見ても意味が分かる内容にしておかないと、数ヵ月後自分が見たときも意味が分かりませんよ。
|
297
|
+
|
298
|
+
言語に限らず、下記のような記事はきちんと読んでおいて取り入れるようにしましょう。
|
299
|
+
- [良いコードを書く技術(まとめ)](https://qiita.com/NoriakiOshita/items/e60ab5bb01b90d927ae5)
|
300
|
+
- [プログラミング勉強を加速させる7つの習慣](https://qiita.com/YudaiTsukamoto/items/42a8df22ca4c6b327dfd)
|
301
|
+
- [初心者を戒めるPHP](https://qiita.com/tadsan/items/fb496e450fc27c8c4494)
|
302
|
+
- [初心者プログラマが犯しがちな過ち25選](https://qiita.com/rana_kualu/items/379eefb3a40c6b44cb92)
|
2
大幅修正
answer
CHANGED
@@ -1,1 +1,294 @@
|
|
1
|
+
質問者さんの過去質問を見ましたが、毎度されている**デバッグ依頼**ですね。
|
2
|
+
本来**非推奨な質問の域**ですが、今回だけ答えてみます。
|
3
|
+
今後同様の質問がしなくてもいいようになれば幸いですね(ニッコリ
|
4
|
+
|
5
|
+
# 結論から
|
6
|
+
|
7
|
+
[変数のスコープ](http://php.net/manual/ja/language.variables.scope.php)をきちんと理解されていないことから「なぜNULLになるのでしょうか」という質問になっています。
|
8
|
+
|
9
|
+
プログラムは指示したとおりにしか動きません。自分が思ったとおりに動くと思っていませんか?
|
10
|
+
その考えは今すぐ捨てましょう。
|
11
|
+
この内容で「なぜNULLになるのか」という質問が出る時点で質問者さんは思ったとおりコードを動かせる息には到底達していません。
|
12
|
+
|
13
|
+
# ミニマムコード
|
14
|
+
|
15
|
+
質問者さんのやろうとしていることは下記と同等です。
|
16
|
+
|
17
|
+
```php
|
18
|
+
$a = [
|
19
|
+
["id"=>1,
|
20
|
+
"name"=>"test"
|
21
|
+
],
|
22
|
+
["id"=>2,
|
23
|
+
"name"=>"test2"
|
24
|
+
],
|
25
|
+
];
|
26
|
+
|
27
|
+
function get($num){
|
28
|
+
$data = $a[$num];
|
29
|
+
return $data;
|
30
|
+
}
|
31
|
+
var_dump(get(1));
|
32
|
+
```
|
33
|
+
|
34
|
+
[require_once()](http://php.net/manual/ja/function.require-once.php)しているから状況が違う、
|
35
|
+
と思われたのであればマニュアルをきちんと読み直してください。
|
36
|
+
同等であるため[inlucde_once()](http://php.net/manual/ja/function.include-once.php)の方に説明がありますが、
|
37
|
+
`include_once 命令は、スクリプトの実行時に指定 したファイルを読み込み評価します`
|
38
|
+
これはPHPの場合、実行時にそこを通ったらそのプログラムを実行することを意味します。
|
39
|
+
|
40
|
+
つまり、コードが書いてあるのと同義です。
|
41
|
+
|
42
|
+
さて、本題のミニマムコードに戻りますが。
|
43
|
+
「デバッグ依頼である」と私が結論づけるのも無理がなく、上記、質問者さんのコードと同等のコードを実行するとエラーになります。
|
44
|
+
|
45
|
+
```
|
46
|
+
PHP Notice: Undefined variable: a in XXX.php on line 13
|
47
|
+
```
|
48
|
+
|
49
|
+
質問者さんのほうでも同じコードを実行してみてください。
|
50
|
+
もし上記Noticeが出ていないのでしたら、エラー表示がOnになっていません。
|
51
|
+
学習段階であったり本番リリース前であったり、不完全なコードの状態では何が起きるか分かりません。
|
52
|
+
必ずエラー表示をOnにしてください。
|
53
|
+
|
54
|
+
- [PHPのエラー表示設定について](https://qiita.com/shotets/items/3c95aef631b2c5eadae5)
|
55
|
+
※もしかしたら既に過去に指摘を受けているかもしれませんね。でもそれだけ大事です。
|
56
|
+
|
57
|
+
# PHPマニュアル確認
|
58
|
+
|
59
|
+
で、ここで私が「結論」にリンクを貼った[変数のスコープ](http://php.net/manual/ja/language.variables.scope.php)の項を見てみてください。
|
60
|
+
|
61
|
+
序盤に下記のようなコードがありますね。
|
62
|
+
```php
|
63
|
+
$a = 1; /* グローバルスコープ */
|
64
|
+
|
65
|
+
function test()
|
66
|
+
{
|
67
|
+
echo $a; /* ローカルスコープ変数の参照 */
|
68
|
+
}
|
69
|
+
|
70
|
+
test();
|
71
|
+
```
|
72
|
+
このコード、私のミニマムコードとよく似ていると思いませんか?
|
73
|
+
それはつまり、質問者さんのコードと同等であることを示します。
|
74
|
+
|
75
|
+
ちなみにこのコードも同じNoticeを出力します。
|
76
|
+
|
77
|
+
`Undefined variable: a`
|
78
|
+
「未定義の変数:a」
|
79
|
+
|
80
|
+
エラーの調べかたとか読み方「質問前にすること」は下記が参考になりますよ。
|
81
|
+
|
82
|
+
- [エラーメッセージの読み方と対処, 検索や質問の原則](https://qiita.com/cannorin/items/eb062aae88bfe2ad6fe5)
|
83
|
+
**「読んで理解して自身で実践できるようになるまで質問しない」くらいの気持ちで読んでください**
|
84
|
+
|
85
|
+
つまり、変数が未定義であることを指します。
|
86
|
+
なぜかって、それはコメントに書いてある通りで、
|
87
|
+
**PHPにおいて、関数は自身の中で定義された変数しか参照できないから** です。
|
88
|
+
それがコメントで書いてある「ローカルスコープ変数の参照」の意味です。
|
89
|
+
JavaScriptと同じ感覚ではいけません。PHPの仕様です。覚えましょう。
|
90
|
+
> PHPマニュアルより抜粋
|
91
|
+
このスクリプトは、出力を全く行いません。これは、echo 命令がローカ ル版の $a 変数を参照しているにもかかわらず、このスコープでは値が代入されていないからです。~中略~PHP では、グローバル変数は、関数の内部で使用する場合、関数の内部でグローバルとして宣言する必要があります。
|
92
|
+
|
93
|
+
# まず一歩目
|
94
|
+
|
95
|
+
[変数のスコープ](http://php.net/manual/ja/language.variables.scope.php)にあるようにglobalキーワードを使うとひとまずエラーが解消できます。
|
96
|
+
|
97
|
+
```php
|
98
|
+
$a = [
|
99
|
+
["id"=>1,
|
100
|
+
"name"=>"test"
|
101
|
+
],
|
102
|
+
["id"=>2,
|
103
|
+
"name"=>"test2"
|
104
|
+
],
|
105
|
+
];
|
106
|
+
|
107
|
+
function get($num){
|
108
|
+
global $a;
|
109
|
+
$data = $a[$num];
|
110
|
+
return $data;
|
111
|
+
}
|
112
|
+
var_dump(get(1));
|
113
|
+
```
|
114
|
+
|
115
|
+
出力結果
|
116
|
+
```
|
117
|
+
array(2) {
|
118
|
+
["id"]=>
|
119
|
+
int(2)
|
120
|
+
["name"]=>
|
121
|
+
string(5) "test2"
|
122
|
+
}
|
123
|
+
```
|
124
|
+
|
125
|
+
# 2歩目
|
126
|
+
|
127
|
+
でもこれって意味がありません。
|
128
|
+
globalキーワードを使う是非はひとまず置いといて、
|
129
|
+
変数$aってどこも使ってませんよね。このget()関数のためだけに使うのは意味がないです。
|
130
|
+
|
131
|
+
引数に渡すのがその次。
|
132
|
+
```php
|
133
|
+
$a = [
|
134
|
+
["id"=>1,
|
135
|
+
"name"=>"test"
|
136
|
+
],
|
137
|
+
["id"=>2,
|
138
|
+
"name"=>"test2"
|
139
|
+
],
|
140
|
+
];
|
141
|
+
function get($num,$a){
|
142
|
+
$data = $a[$num];
|
143
|
+
return $data;
|
144
|
+
}
|
145
|
+
var_dump(get(1,$a));
|
146
|
+
```
|
147
|
+
でも、わざわざ定義した変数を引数で渡すって変な感じですよね。
|
148
|
+
|
149
|
+
それならこの方がいい。
|
150
|
+
```php
|
151
|
+
function get($num){
|
152
|
+
$a = [
|
153
|
+
["id"=>1,
|
154
|
+
"name"=>"test"
|
155
|
+
],
|
156
|
+
["id"=>2,
|
157
|
+
"name"=>"test2"
|
158
|
+
],
|
159
|
+
];
|
160
|
+
$data = $a[$num];
|
161
|
+
return $data;
|
162
|
+
}
|
163
|
+
var_dump(get(1));
|
164
|
+
```
|
165
|
+
|
166
|
+
関数の中に定義してしまおうってことですね。
|
167
|
+
結局、変数$aはget()以外で直接どこからも参照されることがないのでしたら、これで充分です。
|
168
|
+
|
169
|
+
「データとしてしっかり持ちたいんだ」ということでしたら、
|
170
|
+
その変数$aをコード内に直接変数で持つのではなくデータベースで取得するか、クラスにしましょう。
|
171
|
+
|
172
|
+
```php
|
173
|
+
class a{
|
174
|
+
private $a = [
|
175
|
+
["id"=>1,
|
176
|
+
"name"=>"test"
|
177
|
+
],
|
178
|
+
["id"=>2,
|
179
|
+
"name"=>"test2"
|
180
|
+
],
|
181
|
+
];
|
182
|
+
function getByNum($num){
|
183
|
+
return $this->a[$num];
|
184
|
+
}
|
185
|
+
}
|
186
|
+
$obj_a = new a();
|
187
|
+
var_dump($obj_a->getByNum(1));
|
188
|
+
```
|
189
|
+
privateなので$obj_a->a;のようには参照できません。
|
1
|
-
[
|
190
|
+
- [プロパティのアクセス権](http://php.net/manual/ja/language.oop5.visibility.php)
|
191
|
+
|
192
|
+
|
193
|
+
# もう一歩
|
194
|
+
|
195
|
+
クラスのメンバーでも関数でもなんでも同じですが、メソッドって**引数に何が入ってくるか知りません**。
|
196
|
+
「プログラム組んでるんだから制御できるだろ」って思ったら大間違いです。
|
197
|
+
関数で準備した以上は、誰から実行されるかなんてわからないわけです。
|
198
|
+
複数人で同じプロジェクトで開発していたら、同じように使えるわけですし、引数って言っても変数です。変数は何が入っているか分からないもので、後から書き換え可能です。
|
199
|
+
|
200
|
+
実際のプログラムでは入力値が入ってきたりクエリストリングから受け取ったパラメータが入ってきたりして、本当に何が来るか分からないわけです。
|
201
|
+
もし新しいPHP環境であれば、引数の型を制限できます。
|
202
|
+
|
203
|
+
※とりあえず「それならこれでいい」のコードで
|
204
|
+
```php
|
205
|
+
function get(int $num){
|
206
|
+
$a = [
|
207
|
+
["id"=>1,
|
208
|
+
"name"=>"test"
|
209
|
+
],
|
210
|
+
["id"=>2,
|
211
|
+
"name"=>"test2"
|
212
|
+
],
|
213
|
+
];
|
214
|
+
$data = $a[$num];
|
215
|
+
return $data;
|
216
|
+
}
|
217
|
+
```
|
218
|
+
これでget("a")とか、int(整数型)以外を与えるとエラーが出るようになりました。
|
219
|
+
でも、これでも不十分です。
|
220
|
+
確実に存在する値が引数として与えられるか保証はありませんよね。
|
221
|
+
この場合、2とか与えられたら下記のようなエラーが出ます。
|
222
|
+
|
223
|
+
`PHP Notice: Undefined offset: 2 in XXX.php on line 11```
|
224
|
+
|
225
|
+
未定義の[オフセット](https://wa3.i-3-i.info/word11923.html):2
|
226
|
+
|
227
|
+
つまり、配列に存在しないポイント、という意味ですね。
|
228
|
+
※配列にキーが存在しない場合と同等です
|
229
|
+
|
230
|
+
阻止するために、「存在するキーが与えられていたら取得」としましょう。
|
231
|
+
|
232
|
+
```php
|
233
|
+
function get(int $num):array{
|
234
|
+
$a = [
|
235
|
+
["id"=>1,
|
236
|
+
"name"=>"test"
|
237
|
+
],
|
238
|
+
["id"=>2,
|
239
|
+
"name"=>"test2"
|
240
|
+
],
|
241
|
+
];
|
242
|
+
if(array_key_exists($num,$a)){
|
243
|
+
return $a[$num];
|
244
|
+
}
|
245
|
+
return [];
|
246
|
+
}
|
247
|
+
```
|
248
|
+
ついでに、返り値の型も宣言しておき、存在した場合、そのまま返却、そうでない場合は空の配列を返すようにしました。
|
249
|
+
これでひとまずいい感じにはできましたね。
|
250
|
+
|
251
|
+
あとは自身のコードに考え方を反映するだけ!
|
252
|
+
頑張ってください。
|
253
|
+
|
254
|
+
# デバッグについて
|
255
|
+
|
256
|
+
そういえば、各所でvar_dump()を入れられてデバッグをされていますが、本来確認しなければならない項目を確認していません。
|
257
|
+
|
258
|
+
ひとつめ。
|
259
|
+
「処理がここまで通ってるよ」という確認は必要ですが、sampleという文言だけではどこかは分かりません。
|
260
|
+
せめて一意になる数字にしましょう。
|
261
|
+
ちなみに下記のように書くとそのプログラムの行数が出ます。
|
262
|
+
```php
|
263
|
+
echo __LINE__."<br />\n";//重なってはいけないので改行を入れておく
|
264
|
+
```
|
265
|
+
|
266
|
+
ふたつめ。
|
267
|
+
確認しなければならない変数。
|
268
|
+
$mouthsという変数をグローバルスコープで下記のように確認したことで
|
269
|
+
```php
|
270
|
+
//表示される
|
271
|
+
//var_dump($mouths[0]);
|
272
|
+
```
|
273
|
+
getMouths()内で使えるぜ!と思ったかもしれませんが、根拠はどこですか?
|
274
|
+
|
275
|
+
いずれにしても、本当に使えるかどうか確認しなければなりませんよね。
|
276
|
+
```php
|
277
|
+
function getMouths($itemperpage, $currentpage)
|
278
|
+
{
|
279
|
+
var_dump($mouths);
|
280
|
+
//攻略
|
281
|
+
}
|
282
|
+
```
|
283
|
+
こうしておけば、最初のNotice`PHP Notice: Undefined variable:`が出て気づけたでしょうね。
|
284
|
+
(エラー表示OFFだとnullかな)
|
285
|
+
|
286
|
+
デバッグの仕方、本来確認すべき項目はきちんとおさえるようにしないと、デバッグがデバッグになりません。気をつけましょう。
|
287
|
+
|
288
|
+
**質問者さんは思ったとおりコードを動かせる息には到底達していません。**
|
289
|
+
|
290
|
+
|
291
|
+
蛇足:
|
292
|
+
きちんと意味のある変数名つけてますか?
|
293
|
+
mouthって「口」ですけど。
|
294
|
+
「口コミ」なら「reviews」ですね。レビュー。
|
1
修正
answer
CHANGED
@@ -1,1 +1,1 @@
|
|
1
|
-
|
1
|
+
[変数のスコープ](http://php.net/manual/ja/language.variables.scope.php)
|