回答編集履歴

7

短縮

2019/02/20 02:18

投稿

m.ts10806
m.ts10806

スコア80850

test CHANGED
@@ -506,6 +506,36 @@
506
506
 
507
507
 
508
508
 
509
+ ちなみに[短く書く](http://php.net/manual/ja/language.operators.comparison.php#language.operators.comparison.ternary)ならこう。
510
+
511
+ ```php
512
+
513
+ function get(int $num):array{
514
+
515
+ $a = [
516
+
517
+ ["id"=>1,
518
+
519
+ "name"=>"test"
520
+
521
+ ],
522
+
523
+ ["id"=>2,
524
+
525
+ "name"=>"test2"
526
+
527
+ ],
528
+
529
+ ];
530
+
531
+ return (array_key_exists($num,$a))?$a[$num]:[];
532
+
533
+ }
534
+
535
+ ```
536
+
537
+
538
+
509
539
  # デバッグについて
510
540
 
511
541
 

6

修正

2019/02/20 02:18

投稿

m.ts10806
m.ts10806

スコア80850

test CHANGED
@@ -398,7 +398,9 @@
398
398
 
399
399
  実際のプログラムでは入力値が入ってきたりクエリストリングから受け取ったパラメータが入ってきたりして、本当に何が来るか分からないわけです。
400
400
 
401
+
402
+
401
- 新しいPHP環境であれば、[引数の型を制限](http://php.net/manual/ja/functions.arguments.php#functions.arguments.type-declaration)できます。
403
+ 下記のように[引数の型を制限](http://php.net/manual/ja/functions.arguments.php#functions.arguments.type-declaration)ます。
402
404
 
403
405
 
404
406
 
@@ -442,7 +444,7 @@
442
444
 
443
445
 
444
446
 
445
- `PHP Notice: Undefined offset: 2 in XXX.php on line 11```
447
+ `PHP Notice: Undefined offset: 2 in XXX.php on line 11`
446
448
 
447
449
 
448
450
 

5

修正

2019/02/20 01:33

投稿

m.ts10806
m.ts10806

スコア80850

test CHANGED
@@ -398,7 +398,7 @@
398
398
 
399
399
  実際のプログラムでは入力値が入ってきたりクエリストリングから受け取ったパラメータが入ってきたりして、本当に何が来るか分からないわけです。
400
400
 
401
- もし新しいPHP環境であれば、引数の型を制限できます。
401
+ もし新しいPHP環境であれば、[引数の型を制限](http://php.net/manual/ja/functions.arguments.php#functions.arguments.type-declaration)できます。
402
402
 
403
403
 
404
404
 
@@ -456,7 +456,7 @@
456
456
 
457
457
 
458
458
 
459
- 阻止するために、「存在するキーが与えられていたら取得」としましょう。
459
+ 阻止するために、[「存在するキーが与えられていたら取得」](http://php.net/manual/ja/function.array-key-exists.php)としましょう。
460
460
 
461
461
 
462
462
 
@@ -492,7 +492,7 @@
492
492
 
493
493
  ```
494
494
 
495
- ついでに、返り値の型も宣言しておき、存在した場合、そのまま返却、そうでない場合は空の配列を返すようにしました。
495
+ ついでに、[返り値の型も宣言](http://php.net/manual/ja/functions.returning-values.php#functions.returning-values.type-declaration)しておき、存在した場合、そのまま返却、そうでない場合は空の配列を返すようにしました。
496
496
 
497
497
  これでひとまずいい感じにはできましたね。
498
498
 

4

修正

2019/02/20 01:10

投稿

m.ts10806
m.ts10806

スコア80850

test CHANGED
@@ -556,7 +556,7 @@
556
556
 
557
557
  var_dump($mouths);
558
558
 
559
- //
559
+ //
560
560
 
561
561
  }
562
562
 

3

修正

2019/02/20 01:04

投稿

m.ts10806
m.ts10806

スコア80850

test CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  その考えは今すぐ捨てましょう。
20
20
 
21
- この内容で「なぜNULLになるのか」という質問が出る時点で質問者さんは思ったとおりコードを動かせるには到底達していません。
21
+ この内容で「なぜNULLになるのか」という質問が出る時点で質問者さんは思ったとおりコードを動かせるには到底達していません。
22
22
 
23
23
 
24
24
 
@@ -572,9 +572,11 @@
572
572
 
573
573
 
574
574
 
575
- **質問者さんは思ったとおりコードを動かせるには到底達していません。**
575
+ **質問者さんは思ったとおりコードを動かせるには到底達していません。**
576
+
577
+
578
+
576
-
579
+ ----------
577
-
578
580
 
579
581
 
580
582
 
@@ -585,3 +587,17 @@
585
587
  mouthって「口」ですけど。
586
588
 
587
589
  「口コミ」なら「reviews」ですね。レビュー。
590
+
591
+ 他人が見ても意味が分かる内容にしておかないと、数ヵ月後自分が見たときも意味が分かりませんよ。
592
+
593
+
594
+
595
+ 言語に限らず、下記のような記事はきちんと読んでおいて取り入れるようにしましょう。
596
+
597
+ - [良いコードを書く技術(まとめ)](https://qiita.com/NoriakiOshita/items/e60ab5bb01b90d927ae5)
598
+
599
+ - [プログラミング勉強を加速させる7つの習慣](https://qiita.com/YudaiTsukamoto/items/42a8df22ca4c6b327dfd)
600
+
601
+ - [初心者を戒めるPHP](https://qiita.com/tadsan/items/fb496e450fc27c8c4494)
602
+
603
+ - [初心者プログラマが犯しがちな過ち25選](https://qiita.com/rana_kualu/items/379eefb3a40c6b44cb92)

2

大幅修正

2019/02/20 01:01

投稿

m.ts10806
m.ts10806

スコア80850

test CHANGED
@@ -1 +1,587 @@
1
+ 質問者さんの過去質問を見ましたが、毎度されている**デバッグ依頼**ですね。
2
+
3
+ 本来**非推奨な質問の域**ですが、今回だけ答えてみます。
4
+
5
+ 今後同様の質問がしなくてもいいようになれば幸いですね(ニッコリ
6
+
7
+
8
+
9
+ # 結論から
10
+
11
+
12
+
13
+ [変数のスコープ](http://php.net/manual/ja/language.variables.scope.php)をきちんと理解されていないことから「なぜNULLになるのでしょうか」という質問になっています。
14
+
15
+
16
+
17
+ プログラムは指示したとおりにしか動きません。自分が思ったとおりに動くと思っていませんか?
18
+
19
+ その考えは今すぐ捨てましょう。
20
+
21
+ この内容で「なぜNULLになるのか」という質問が出る時点で質問者さんは思ったとおりコードを動かせる息には到底達していません。
22
+
23
+
24
+
25
+ # ミニマムコード
26
+
27
+
28
+
29
+ 質問者さんのやろうとしていることは下記と同等です。
30
+
31
+
32
+
33
+ ```php
34
+
35
+ $a = [
36
+
37
+ ["id"=>1,
38
+
39
+ "name"=>"test"
40
+
41
+ ],
42
+
43
+ ["id"=>2,
44
+
45
+ "name"=>"test2"
46
+
47
+ ],
48
+
49
+ ];
50
+
51
+
52
+
53
+ function get($num){
54
+
55
+ $data = $a[$num];
56
+
57
+ return $data;
58
+
59
+ }
60
+
61
+ var_dump(get(1));
62
+
63
+ ```
64
+
65
+
66
+
67
+ [require_once()](http://php.net/manual/ja/function.require-once.php)しているから状況が違う、
68
+
69
+ と思われたのであればマニュアルをきちんと読み直してください。
70
+
71
+ 同等であるため[inlucde_once()](http://php.net/manual/ja/function.include-once.php)の方に説明がありますが、
72
+
73
+ `include_once 命令は、スクリプトの実行時に指定 したファイルを読み込み評価します`
74
+
75
+ これはPHPの場合、実行時にそこを通ったらそのプログラムを実行することを意味します。
76
+
77
+
78
+
79
+ つまり、コードが書いてあるのと同義です。
80
+
81
+
82
+
83
+ さて、本題のミニマムコードに戻りますが。
84
+
85
+ 「デバッグ依頼である」と私が結論づけるのも無理がなく、上記、質問者さんのコードと同等のコードを実行するとエラーになります。
86
+
87
+
88
+
89
+ ```
90
+
91
+ PHP Notice: Undefined variable: a in XXX.php on line 13
92
+
93
+ ```
94
+
95
+
96
+
97
+ 質問者さんのほうでも同じコードを実行してみてください。
98
+
99
+ もし上記Noticeが出ていないのでしたら、エラー表示がOnになっていません。
100
+
101
+ 学習段階であったり本番リリース前であったり、不完全なコードの状態では何が起きるか分かりません。
102
+
103
+ 必ずエラー表示をOnにしてください。
104
+
105
+
106
+
107
+ - [PHPのエラー表示設定について](https://qiita.com/shotets/items/3c95aef631b2c5eadae5)
108
+
109
+ ※もしかしたら既に過去に指摘を受けているかもしれませんね。でもそれだけ大事です。
110
+
111
+
112
+
113
+ # PHPマニュアル確認
114
+
115
+
116
+
117
+ で、ここで私が「結論」にリンクを貼った[変数のスコープ](http://php.net/manual/ja/language.variables.scope.php)の項を見てみてください。
118
+
119
+
120
+
121
+ 序盤に下記のようなコードがありますね。
122
+
123
+ ```php
124
+
125
+ $a = 1; /* グローバルスコープ */
126
+
127
+
128
+
129
+ function test()
130
+
131
+ {
132
+
133
+ echo $a; /* ローカルスコープ変数の参照 */
134
+
135
+ }
136
+
137
+
138
+
139
+ test();
140
+
141
+ ```
142
+
143
+ このコード、私のミニマムコードとよく似ていると思いませんか?
144
+
145
+ それはつまり、質問者さんのコードと同等であることを示します。
146
+
147
+
148
+
149
+ ちなみにこのコードも同じNoticeを出力します。
150
+
151
+
152
+
153
+ `Undefined variable: a`
154
+
155
+ 「未定義の変数:a」
156
+
157
+
158
+
159
+ エラーの調べかたとか読み方「質問前にすること」は下記が参考になりますよ。
160
+
161
+
162
+
163
+ - [エラーメッセージの読み方と対処, 検索や質問の原則](https://qiita.com/cannorin/items/eb062aae88bfe2ad6fe5)
164
+
165
+ **「読んで理解して自身で実践できるようになるまで質問しない」くらいの気持ちで読んでください**
166
+
167
+
168
+
169
+ つまり、変数が未定義であることを指します。
170
+
171
+ なぜかって、それはコメントに書いてある通りで、
172
+
173
+ **PHPにおいて、関数は自身の中で定義された変数しか参照できないから** です。
174
+
175
+ それがコメントで書いてある「ローカルスコープ変数の参照」の意味です。
176
+
177
+ JavaScriptと同じ感覚ではいけません。PHPの仕様です。覚えましょう。
178
+
179
+ > PHPマニュアルより抜粋
180
+
181
+ このスクリプトは、出力を全く行いません。これは、echo 命令がローカ ル版の $a 変数を参照しているにもかかわらず、このスコープでは値が代入されていないからです。~中略~PHP では、グローバル変数は、関数の内部で使用する場合、関数の内部でグローバルとして宣言する必要があります。
182
+
183
+
184
+
185
+ # まず一歩目
186
+
187
+
188
+
189
+ [変数のスコープ](http://php.net/manual/ja/language.variables.scope.php)にあるようにglobalキーワードを使うとひとまずエラーが解消できます。
190
+
191
+
192
+
193
+ ```php
194
+
195
+ $a = [
196
+
197
+ ["id"=>1,
198
+
199
+ "name"=>"test"
200
+
201
+ ],
202
+
203
+ ["id"=>2,
204
+
205
+ "name"=>"test2"
206
+
207
+ ],
208
+
209
+ ];
210
+
211
+
212
+
213
+ function get($num){
214
+
215
+ global $a;
216
+
217
+ $data = $a[$num];
218
+
219
+ return $data;
220
+
221
+ }
222
+
223
+ var_dump(get(1));
224
+
225
+ ```
226
+
227
+
228
+
229
+ 出力結果
230
+
231
+ ```
232
+
233
+ array(2) {
234
+
235
+ ["id"]=>
236
+
237
+ int(2)
238
+
239
+ ["name"]=>
240
+
241
+ string(5) "test2"
242
+
243
+ }
244
+
245
+ ```
246
+
247
+
248
+
249
+ # 2歩目
250
+
251
+
252
+
253
+ でもこれって意味がありません。
254
+
255
+ globalキーワードを使う是非はひとまず置いといて、
256
+
257
+ 変数$aってどこも使ってませんよね。このget()関数のためだけに使うのは意味がないです。
258
+
259
+
260
+
261
+ 引数に渡すのがその次。
262
+
263
+ ```php
264
+
265
+ $a = [
266
+
267
+ ["id"=>1,
268
+
269
+ "name"=>"test"
270
+
271
+ ],
272
+
273
+ ["id"=>2,
274
+
275
+ "name"=>"test2"
276
+
277
+ ],
278
+
279
+ ];
280
+
281
+ function get($num,$a){
282
+
283
+ $data = $a[$num];
284
+
285
+ return $data;
286
+
287
+ }
288
+
289
+ var_dump(get(1,$a));
290
+
291
+ ```
292
+
293
+ でも、わざわざ定義した変数を引数で渡すって変な感じですよね。
294
+
295
+
296
+
297
+ それならこの方がいい。
298
+
299
+ ```php
300
+
301
+ function get($num){
302
+
303
+ $a = [
304
+
305
+ ["id"=>1,
306
+
307
+ "name"=>"test"
308
+
309
+ ],
310
+
311
+ ["id"=>2,
312
+
313
+ "name"=>"test2"
314
+
315
+ ],
316
+
317
+ ];
318
+
319
+ $data = $a[$num];
320
+
321
+ return $data;
322
+
323
+ }
324
+
325
+ var_dump(get(1));
326
+
327
+ ```
328
+
329
+
330
+
331
+ 関数の中に定義してしまおうってことですね。
332
+
333
+ 結局、変数$aはget()以外で直接どこからも参照されることがないのでしたら、これで充分です。
334
+
335
+
336
+
337
+ 「データとしてしっかり持ちたいんだ」ということでしたら、
338
+
339
+ その変数$aをコード内に直接変数で持つのではなくデータベースで取得するか、クラスにしましょう。
340
+
341
+
342
+
343
+ ```php
344
+
345
+ class a{
346
+
347
+ private $a = [
348
+
349
+ ["id"=>1,
350
+
351
+ "name"=>"test"
352
+
353
+ ],
354
+
355
+ ["id"=>2,
356
+
357
+ "name"=>"test2"
358
+
359
+ ],
360
+
361
+ ];
362
+
363
+ function getByNum($num){
364
+
365
+ return $this->a[$num];
366
+
367
+ }
368
+
369
+ }
370
+
371
+ $obj_a = new a();
372
+
373
+ var_dump($obj_a->getByNum(1));
374
+
375
+ ```
376
+
377
+ privateなので$obj_a->a;のようには参照できません。
378
+
1
- [変数のスコープ](http://php.net/manual/ja/language.variables.scope.php)
379
+ - [プロパティアクセ](http://php.net/manual/ja/language.oop5.visibility.php)
380
+
381
+
382
+
383
+
384
+
385
+ # もう一歩
386
+
387
+
388
+
389
+ クラスのメンバーでも関数でもなんでも同じですが、メソッドって**引数に何が入ってくるか知りません**。
390
+
391
+ 「プログラム組んでるんだから制御できるだろ」って思ったら大間違いです。
392
+
393
+ 関数で準備した以上は、誰から実行されるかなんてわからないわけです。
394
+
395
+ 複数人で同じプロジェクトで開発していたら、同じように使えるわけですし、引数って言っても変数です。変数は何が入っているか分からないもので、後から書き換え可能です。
396
+
397
+
398
+
399
+ 実際のプログラムでは入力値が入ってきたりクエリストリングから受け取ったパラメータが入ってきたりして、本当に何が来るか分からないわけです。
400
+
401
+ もし新しいPHP環境であれば、引数の型を制限できます。
402
+
403
+
404
+
405
+ ※とりあえず「それならこれでいい」のコードで
406
+
407
+ ```php
408
+
409
+ function get(int $num){
410
+
411
+ $a = [
412
+
413
+ ["id"=>1,
414
+
415
+ "name"=>"test"
416
+
417
+ ],
418
+
419
+ ["id"=>2,
420
+
421
+ "name"=>"test2"
422
+
423
+ ],
424
+
425
+ ];
426
+
427
+ $data = $a[$num];
428
+
429
+ return $data;
430
+
431
+ }
432
+
433
+ ```
434
+
435
+ これでget("a")とか、int(整数型)以外を与えるとエラーが出るようになりました。
436
+
437
+ でも、これでも不十分です。
438
+
439
+ 確実に存在する値が引数として与えられるか保証はありませんよね。
440
+
441
+ この場合、2とか与えられたら下記のようなエラーが出ます。
442
+
443
+
444
+
445
+ `PHP Notice: Undefined offset: 2 in XXX.php on line 11```
446
+
447
+
448
+
449
+ 未定義の[オフセット](https://wa3.i-3-i.info/word11923.html):2
450
+
451
+
452
+
453
+ つまり、配列に存在しないポイント、という意味ですね。
454
+
455
+ ※配列にキーが存在しない場合と同等です
456
+
457
+
458
+
459
+ 阻止するために、「存在するキーが与えられていたら取得」としましょう。
460
+
461
+
462
+
463
+ ```php
464
+
465
+ function get(int $num):array{
466
+
467
+ $a = [
468
+
469
+ ["id"=>1,
470
+
471
+ "name"=>"test"
472
+
473
+ ],
474
+
475
+ ["id"=>2,
476
+
477
+ "name"=>"test2"
478
+
479
+ ],
480
+
481
+ ];
482
+
483
+ if(array_key_exists($num,$a)){
484
+
485
+ return $a[$num];
486
+
487
+ }
488
+
489
+ return [];
490
+
491
+ }
492
+
493
+ ```
494
+
495
+ ついでに、返り値の型も宣言しておき、存在した場合、そのまま返却、そうでない場合は空の配列を返すようにしました。
496
+
497
+ これでひとまずいい感じにはできましたね。
498
+
499
+
500
+
501
+ あとは自身のコードに考え方を反映するだけ!
502
+
503
+ 頑張ってください。
504
+
505
+
506
+
507
+ # デバッグについて
508
+
509
+
510
+
511
+ そういえば、各所でvar_dump()を入れられてデバッグをされていますが、本来確認しなければならない項目を確認していません。
512
+
513
+
514
+
515
+ ひとつめ。
516
+
517
+ 「処理がここまで通ってるよ」という確認は必要ですが、sampleという文言だけではどこかは分かりません。
518
+
519
+ せめて一意になる数字にしましょう。
520
+
521
+ ちなみに下記のように書くとそのプログラムの行数が出ます。
522
+
523
+ ```php
524
+
525
+ echo __LINE__."<br />\n";//重なってはいけないので改行を入れておく
526
+
527
+ ```
528
+
529
+
530
+
531
+ ふたつめ。
532
+
533
+ 確認しなければならない変数。
534
+
535
+ $mouthsという変数をグローバルスコープで下記のように確認したことで
536
+
537
+ ```php
538
+
539
+ //表示される
540
+
541
+ //var_dump($mouths[0]);
542
+
543
+ ```
544
+
545
+ getMouths()内で使えるぜ!と思ったかもしれませんが、根拠はどこですか?
546
+
547
+
548
+
549
+ いずれにしても、本当に使えるかどうか確認しなければなりませんよね。
550
+
551
+ ```php
552
+
553
+ function getMouths($itemperpage, $currentpage)
554
+
555
+ {
556
+
557
+ var_dump($mouths);
558
+
559
+ //攻略
560
+
561
+ }
562
+
563
+ ```
564
+
565
+ こうしておけば、最初のNotice`PHP Notice: Undefined variable:`が出て気づけたでしょうね。
566
+
567
+ (エラー表示OFFだとnullかな)
568
+
569
+
570
+
571
+ デバッグの仕方、本来確認すべき項目はきちんとおさえるようにしないと、デバッグがデバッグになりません。気をつけましょう。
572
+
573
+
574
+
575
+ **質問者さんは思ったとおりコードを動かせる息には到底達していません。**
576
+
577
+
578
+
579
+
580
+
581
+ 蛇足:
582
+
583
+ きちんと意味のある変数名つけてますか?
584
+
585
+ mouthって「口」ですけど。
586
+
587
+ 「口コミ」なら「reviews」ですね。レビュー。

1

修正

2019/02/20 00:55

投稿

m.ts10806
m.ts10806

スコア80850

test CHANGED
@@ -1 +1 @@
1
- **変数のスコープ**
1
+ [変数のスコープ](http://php.net/manual/ja/language.variables.scope.php)