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

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

ただいまの
回答率

89.13%

【PHP】APIで変数をjson方式に変換したい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,461

tajix_japan

score 86

もとのページは下記のようになっています。

http://example.com/moto.html?fm=woman

【no】1【name】Yamada【】<BR>
【no】2【name】Tanaka【】<BR>

これと同列の位置にphp (http://example.com/api_1.php) を置き、上記の文字をアプリに渡すAPIとしたいと考えています。

まずは、moto.html のデータをjson方式に変換するため、str_replaceを利用して変換します。

【PHP その1】

<?php

$crawler="http://example.com/moto.html?fm=woman";

$homepage = file_get_contents($crawler);

$moto = array("【no】", "【name】", "【】<BR>");
$api_1   = array("['no'=>'", "','name'=>'", "'],");

$newphrase = str_replace($moto, $api_1, $homepage);

echo $newphrase;

?>

これで無事 echo $newphrase; の部分が
['no'=>'1','name'=>'Yamada'],['no'=>'2','name'=>'Tanaka'],
とHTML上で表示されました。

一方、下記のようなjson方式で吐き出すPHPがあります。

【PHP その2】

<?php

function returnJson($resultArray){
  if(array_key_exists('callback', $_GET)){
    $json = $_GET['callback'] . "(" . json_encode($resultArray) . ");";
  }else{
    $json = json_encode($resultArray);
  }
  header('Content-Type: text/html; charset=utf-8');
  echo  $json;
  exit(0);
}

$type = $_REQUEST['user_type'];

//  ユーザリストの初期化
$user_list = [];
//  返却値の初期化
$result = [];

try {
  //  値の検証
  if (empty($type)) {
    throw new Exception("no type...");
  }

  //  ユーザリストの作成
  switch ($type) {
    case 'a':
      $user_list = 
[
['no'=>'10','name'=>'Yoshida'],
['no'=>'11','name'=>'Mori']
      ];
      break;

    default:
      //  不正な値
      throw new Exception("Invalid value...");
      break;
  }

  //  返却値の作成
  $result = [
    'result' => 'OK',
    'users' => $user_list
  ];
} catch (Exception $e) {
  $result = [
    'result' => 'NG',
    'message' => $e->getMessage()
  ];
}

//  JSONでレスポンスを返す
returnJson($result);
?>

上記のwebAPIを$type=aで叩くと

[{"no":"11","name":"Yoshida"},{"no":"12","name":"Mori"}]

が返ってきます。

【やりたいこと】

上記の2つを組み合わせて、

http://example.com/moto.html?fm=woman" にある

【no】1【name】Yamada【】<BR>
【no】2【name】Tanaka【】<BR>

[{"no":"1","name":"Yamada"},{"no":"2","name":"Tanaka"}]
のJSON方式で吐き出させたいと考えました。

【やってみたこと】

【PHPその2】にある
['no'=>'10','name'=>'Yoshida'],
['no'=>'11','name'=>'Mori']

の部分を
【PHPその1】にある
$newphrase に差し替えるだけで出来そうに感じました。
そこでPHPその1とその2を下記のように合体させました。

<?php

$crawler="http://example.com/moto.html";

$homepage = file_get_contents($crawler);

$moto = array("【no】", "【name】", "【】<BR>");
$api_1   = array("['no'=>'", "','name'=>'", "'],");

$newphrase = str_replace($moto, $api_1, $homepage);


function returnJson($resultArray){
  if(array_key_exists('callback', $_GET)){
    $json = $_GET['callback'] . "(" . json_encode($resultArray) . ");";
  }else{
    $json = json_encode($resultArray);
  }
  header('Content-Type: text/html; charset=utf-8');
  echo  $json;
  exit(0);
}

$type = $_REQUEST['user_type'];

//  ユーザリストの初期化
$user_list = [];
//  返却値の初期化
$result = [];

try {
  //  値の検証
  if (empty($type)) {
    throw new Exception("no type...");
  }

  //  ユーザリストの作成
  switch ($type) {
    case 'a':
      $user_list = 
[
$newphrase
      ];
      break;

    default:
      //  不正な値
      throw new Exception("Invalid value...");
      break;
  }

  //  返却値の作成
  $result = [
    'result' => 'OK',
    'users' => $user_list
  ];
} catch (Exception $e) {
  $result = [
    'result' => 'NG',
    'message' => $e->getMessage()
  ];
}

//  JSONでレスポンスを返す
returnJson($result);
?>

結果

{"result":"OK","users":[[""]]}
と、"result":"OK"は出るものの中身が吐き出されません。

echo $newphraseだとHTML上に吐き出すことができるのにです。
何が問題なのでしょうか?

どうすれば、$newphrase を 変数
['no'=>'1','name'=>'Yamada'],['no'=>'2','name'=>'Tanaka'],
として読んでくれるようになりますでしょうか?

よろしくお願いいたします。

追記
>$newphrase に代入したすぐ後の var_dump を採って追記いただけますか?

kei344様
有難うございます。

$_REQUEST['user_type']の部分を$type = 'a';とリクエストを受け取った形に変形してテストしました。

//$type = $_REQUEST['user_type'];

$type = 'a';

//  ユーザリストの初期化
$user_list = [];
//  返却値の初期化
$result = [];

try {
  //  値の検証
  if (empty($type)) {
    throw new Exception("no type...");
  }



  //  ユーザリストの作成
  switch ($type) {
    case 'a':
    case 'admin':
      $user_list = 

[
$newphrase
      ];
      break;

var_dump($newphrase);

以下同文

と記載してみました。

結果
{"result":"OK","users":[{"no":"1","name":"Yamada"},{"no":"2","name":"Tanaka"}]}

となるべきところが

{"result":"OK","users":["\ufeff[{"no":"1","name":"Yamada"},{"no":"2","name":"Tanaka"],"]}

と ["\ufeff 及び "]  のへんてこな文字が混じっていることがわかりました。

\ufeffをググるとBOM付でこれが出ると書かれていたのですが、確認したところBOM付で記載してはいません。改行コードも自動判定からLFに変更しましたがやはり変化がありません。

(遅くなりましたが環境はCent OS 6.8です)

当方は今回初めてAPIを作ることになるため、下記をベースに開発しています。
http://qiita.com/busyoumono99/items/9b5ffd35dd521bafce47
ここのサンプルの標準で用意されている下記のcace 'g'を追記し
$_REQUEST['user_type']の部分を$type = 'g';としてテストしました。

    case 'g':
    case 'guest':
      $user_list = [
        ['name'=>'香取','age'=>14],
        ['name'=>'草薙','age'=>15],
        ['name'=>'稲垣','age'=>15],
        ['name'=>'岡田','age'=>15],
        ['name'=>'森田','age'=>15],
        ['name'=>'三宅','age'=>15],
       ['name'=>'長野','age'=>15],
        ['name'=>'坂本','age'=>15],
        ['name'=>'井ノ原','age'=>15]
      ];
      break;
    default:


結果

{"result":"OK","users":[{"name":"\u9999\u53d6","age":14},{"name":"\u8349\u8599","age":15},{"name":"\u7a32\u57a3","age":15},{"name":"\u5ca1\u7530","age":15},{"name":"\u68ee\u7530","age":15},{"name":"\u4e09\u5b85","age":15},{"name":"\u9577\u91ce","age":15},{"name":"\u5742\u672c","age":15},{"name":"\u4e95\u30ce\u539f","age":15}]}

と普通にdump出来ます。

上記のテストから$newphraseを代入するとゴミ文字が入ってくることで表示出来なくなっていることがわかりました。

もう一歩だと思いますので何かアドバイスできることがございましたらよろしくお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2017/01/04 23:55

    $newphrase に代入したすぐ後の var_dump を採って追記いただけますか?

    キャンセル

回答 2

+3

ちょっと何をやろうとしているのか分かりません。
ので、一般的なJSONデータの返信の仕方の説明のあるリンクを参考まで。
ググって出てきたサイトなので、コード検証等してませんが、シンプルな記述なのでわかりやすいかと。

JSON形式のデータを返すAPI

今回、なぜかhttp://example.com/moto.html?fm=womanfile_get_contentsしてますが、普通は読み込んでいるサイトのデータはDB内の情報を元に表現しているので、参考サイトのコードの$valueを読み込んでいるサイトのDBデータで記載できれば、http://example.com/moto.html?fm=womanの情報を提供するAPIができるかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/07 14:13

    有難うございます。
    ゴミ文字問題は 
    $user_list = json_decode( '['.$json.']' );
    で解決できました。
    まだ最終完成には至りませんが、PHP部分についての問題は解決いたしました。
    有難うございました。

    キャンセル

  • 2017/01/07 15:53

    json_decode を利用するにしても、
    preg_match_all で置換/整理した方がいいですよ。

    (ん?preg_match_all での置換なら配列に入っているか。)

    まぁ、意図した出力になったのであれば、次の課題に進んだほうがイイですね。
    がんばってください。

    キャンセル

  • 2017/01/07 15:56

    了解です。有難うございました。

    キャンセル

checkベストアンサー

0

下記のように $newphrase を扱っておられますが、str_replace から返ってきているのはテキストです。なので、$user_list にはテキストが1要素入った配列が入ることになると思います。

$newphrase = str_replace($moto, $api_1, $homepage);
// (中略)
      $user_list = 
[
$newphrase
      ];
// こうなってしまうはず
$str="['no'=>'1','name'=>'Yamada'],['no'=>'2','name'=>'Tanaka'], ";
$ar=[$str];
var_dump($ar);
/*
array(1) {
  [0]=>;
  string(59) "['no'=>;'1','name'=>;'Yamada'],['no'=>;'2','name'=>;'Tanaka'], "
}
*/

なので、
['no'=>'1','name'=>'Yamada'],['no'=>'2','name'=>'Tanaka'], ではなく
{"no":"1","name":"Yamada"},{"no":"2","name":"Tanaka"}, となるように置換した上で最後のカンマを取り、json_decode して配列として扱ったほうが良いような。

$json='{"no":"1","name":"Yamada"},{"no":"2","name":"Tanaka"}'; // 最後のカンマが有るとデコードに失敗してNULLが返る
$user_list = json_decode( '['.$json.']' );
var_dump($user_list);
/*
array(2) {
  [0]=>;
  object(stdClass)#1 (2) {
    ["no"]=>;
    string(1) "1"
    ["name"]=>;
    string(6) "Yamada"
  }
  [1]=>;
  object(stdClass)#2 (2) {
    ["no"]=>;
    string(1) "2"
    ["name"]=>;
    string(6) "Tanaka"
  }
}
 */

【JSON】
http://www.json.org/json-ja.html

【非エンジニアに贈る「具体例でさらっと学ぶJSON」 | Developers.IO】
http://dev.classmethod.jp/etc/concrete-example-of-json/

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/07 14:12

    有難うございます。
    ゴミ文字問題は 
    $user_list = json_decode( '['.$json.']' );
    で解決できました。
    深く御礼申し上げます。
    助かりました。まだ最終完成には至りませんが、PHP部分についての問題は解決いたしました。
    有難うございました。

    キャンセル

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

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る