回答編集履歴

3

制御文字削除について追記

2017/09/10 08:42

投稿

Tomak
Tomak

スコア1652

test CHANGED
@@ -285,3 +285,81 @@
285
285
  ```
286
286
 
287
287
 
288
+
289
+ #### 追記3
290
+
291
+
292
+
293
+ コメント欄で頂いた、エラーのJSON文字列をコピーしたところ先頭になぜか`BOM(\ufeff)`が入っていました。何かBOM付ファイルを参照していたりしないでしょうか?
294
+
295
+
296
+
297
+ DBから値を取得して配列を作成するときに、\n→<br>が必要な場合は`nl2br()`を行ってから下記のコードのように`制御文字コード`を削除するようにします。
298
+
299
+
300
+
301
+ 下記のコードでもJsonの構文エラーが出る場合は、Jsonをそもそも表示する前に制御文字が出力されている可能性があるので、`ob_start(), ob_end_clean()`の行をコメントアウトしてみます。
302
+
303
+ `ob_start(), ob_end_clean()`間ですべての出力を切り捨てて、制御文字が出力されないようにします。
304
+
305
+
306
+
307
+ ```php
308
+
309
+ /* garally2.php */
310
+
311
+ //ob_start();
312
+
313
+ require_once('./php/ponta.php');// DBに接続
314
+
315
+
316
+
317
+ $db->query('set names utf8');
318
+
319
+ $ps = $db->query('select * from wan2 order by ban desc');
320
+
321
+ $users = [];
322
+
323
+
324
+
325
+ while ($row = $ps->fetchObject())
326
+
327
+ {
328
+
329
+ foreach (['ban','nam','ttl','mes','gaz','dat'] as $column) {
330
+
331
+ //制御文字を削除
332
+
333
+ $value = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $row->{$column});
334
+
335
+ //nl2br()付制御文字削除
336
+
337
+ //$value = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', nl2br($row->{$column}));
338
+
339
+ $users[] = [$column => $value];
340
+
341
+ }
342
+
343
+ }
344
+
345
+
346
+
347
+ //ob_start()からここまでの出力を切り捨て
348
+
349
+ //ob_end_clean();
350
+
351
+
352
+
353
+ //日本語をユニコードエスケープしない(JSON_UNESCAPED_UNICODE)
354
+
355
+ //JSONをインデントと改行をつけて見やすい形式で表示(JSON_PRETTY_PRINT)
356
+
357
+ echo json_encode($debug + $users, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
358
+
359
+
360
+
361
+ exit();
362
+
363
+ ```
364
+
365
+

2

回答追記2

2017/09/10 08:41

投稿

Tomak
Tomak

スコア1652

test CHANGED
@@ -82,7 +82,7 @@
82
82
 
83
83
 
84
84
 
85
- #### 追記
85
+ #### 追記
86
86
 
87
87
 
88
88
 
@@ -123,3 +123,165 @@
123
123
  ですので、`jQuery`のバージョンをダウングレードしてみるのも良いかもしれません。
124
124
 
125
125
 
126
+
127
+
128
+
129
+ #### 追記2
130
+
131
+
132
+
133
+ **■Jsonエンコードエラーチェック**
134
+
135
+ Jsonのエンコードでエラーが発生している場合は下記のコードのように`json_last_error()`でチェックすることができます。エンコードエラーが発生していない場合は、下記のように`Json Lintチェッカー`で構文チェックします。
136
+
137
+
138
+
139
+ **■Jsonエンコードオプション**
140
+
141
+ その他、Jsonエンコードではオプションを複数渡すことができます。PHPマニュアルの[jsonの定義済み定数](http://php.net/manual/ja/json.constants.php)を参照してください。日本語のユニコードエスケープをさせないようにしたり、Json文字列の構文チェックすることを念頭に置いてインデントと改行でフォーマットして表示することも可能です。
142
+
143
+
144
+
145
+ **■Json Lintチェッカー**
146
+
147
+ Jsonフォーマットは下記のような`Json Lint`でチェックできます。このようなチェッカーサイトでは、ピンポイントでどの行がフォーマットエラーなのか表示してくれます。
148
+
149
+ [https://jsonlint.com/](https://jsonlint.com/)
150
+
151
+
152
+
153
+ ブラウザのデバッグ(`F12`)の「`ネットワーク`」などから**レスポンスソース(JSON文字列)をそのまま上記サイトにコピー&ペースト**してJsonフォーマットをチェックします。
154
+
155
+
156
+
157
+ ```php
158
+
159
+ /* garally2.php */
160
+
161
+ require_once('./php/ponta.php');// DBに接続
162
+
163
+
164
+
165
+ $db->query('set names utf8');
166
+
167
+ $ps = $db->query('select * from wan2 order by ban desc');
168
+
169
+ $users = [];
170
+
171
+
172
+
173
+ while ($row = $ps->fetchObject())
174
+
175
+ {
176
+
177
+ $users[] = array(
178
+
179
+ 'ban'=> $row->ban
180
+
181
+ ,'nam' => $row->nam
182
+
183
+ ,'ttl' => $row->ttl
184
+
185
+ ,'mes' => $row->mes
186
+
187
+ ,'gaz' => $row->gaz
188
+
189
+ ,'dat' => $row->dat
190
+
191
+ );
192
+
193
+ }
194
+
195
+
196
+
197
+ //JSONエンコードしてみる(エラーチェック用)
198
+
199
+ json_encode($users, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
200
+
201
+
202
+
203
+ $debug = [];
204
+
205
+
206
+
207
+ //JSONエンコードエラーチェック
208
+
209
+ switch (json_last_error()) {
210
+
211
+ case JSON_ERROR_NONE :
212
+
213
+ $debug = ['SUCCESS' => 'エラーは発生しませんでした'];
214
+
215
+ break;
216
+
217
+ case JSON_ERROR_DEPTH :
218
+
219
+ $debug = ['FAIL' => '配列の深さが最大値を超えました'];
220
+
221
+ break;
222
+
223
+ case JSON_ERROR_STATE_MISMATCH :
224
+
225
+ $debug = ['FAIL' => 'JSON の形式が無効、あるいは壊れています'];
226
+
227
+ break;
228
+
229
+ case JSON_ERROR_CTRL_CHAR :
230
+
231
+ $debug = ['FAIL' => '制御文字エラー。おそらくエンコーディングが違います'];
232
+
233
+ break;
234
+
235
+ case JSON_ERROR_SYNTAX :
236
+
237
+ $debug = ['FAIL' => '構文エラー'];
238
+
239
+ break;
240
+
241
+ case JSON_ERROR_UTF8 :
242
+
243
+ $debug = ['FAIL' => '正しくエンコードされていないなど、不正な形式の UTF-8 文字'];
244
+
245
+ break;
246
+
247
+ case JSON_ERROR_RECURSION :
248
+
249
+ $debug = ['FAIL' => 'エンコード対象の値に再帰参照が含まれています'];
250
+
251
+ break;
252
+
253
+ case JSON_ERROR_INF_OR_NAN :
254
+
255
+ $debug = ['FAIL' => 'エンコード対象の値に NAN あるいは INF が含まれています'];
256
+
257
+ break;
258
+
259
+ case JSON_ERROR_UNSUPPORTED_TYPE :
260
+
261
+ $debug = ['FAIL' => 'エンコード不可能な型の値が渡されました'];
262
+
263
+ break;
264
+
265
+ default :
266
+
267
+ $debug = ['FAIL' => '不明なエラー - Unknown error'];
268
+
269
+ break;
270
+
271
+ }
272
+
273
+
274
+
275
+ //日本語をユニコードエスケープしない(JSON_UNESCAPED_UNICODE)
276
+
277
+ //JSONをインデントと改行をつけて見やすい形式で表示(JSON_PRETTY_PRINT)
278
+
279
+ echo json_encode($debug + $users, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
280
+
281
+
282
+
283
+ exit();
284
+
285
+ ```
286
+
287
+

1

追記

2017/09/10 03:10

投稿

Tomak
Tomak

スコア1652

test CHANGED
@@ -79,3 +79,47 @@
79
79
  });
80
80
 
81
81
  ```
82
+
83
+
84
+
85
+ #### 追記
86
+
87
+
88
+
89
+ うまくいかない原因として、JavaScriptが原因なのかPHPが原因なのか明確にします。
90
+
91
+ `garally2.php`を下記のようにしてみます。正しく表示されればPHPが原因ということになります。逆に正しく表示されない場合は、JavaScriptが原因ということになります。
92
+
93
+
94
+
95
+ Content-Typeは上記に書いたように`dataType`を指定すれば普通は必要ありません。
96
+
97
+
98
+
99
+ ```php
100
+
101
+ //garally2.php
102
+
103
+ echo json_encode(array(
104
+
105
+ 'ban' => 'ban1',
106
+
107
+ 'nam' => 'nam1',
108
+
109
+ 'ttl' => 'ttl1',
110
+
111
+ 'gaz' => 'gaz1',
112
+
113
+ 'dat' => 'dat1',
114
+
115
+ ));
116
+
117
+ ```
118
+
119
+
120
+
121
+ JavaScriptコンソールには「Parse Error」となっているので必ずなにかJson文字列として認識できない文字列が入っているはずですが、`jQuery`のバグの可能性もあります。
122
+
123
+ ですので、`jQuery`のバージョンをダウングレードしてみるのも良いかもしれません。
124
+
125
+