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

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

ただいまの
回答率

89.55%

PHPでJSONを書き換える方法

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 973

phiilo_

score 1

既出でしたらすみません。PHP7です。

下記ようなJSONがあります。
ファイル名:area.json

[
  {
    "no.1": "東京",
    "no.2": "神奈川",
    "no.3": "千葉",
    "no.4": "埼玉",
    "no.5": "ブラジル",
    "no.6": "佐賀",
    "no.7": "北海道",
    "no.8": "大分",
    "no.9": "愛知",
    "no.10": "静岡"
  },
  {
    "no.100": "フィリピン",
    "no.101": "山梨",
    "no.102": "青森",
    "no.103": "秋田",
    "no.104": "福島",
    "no.105": "福岡",
    "no.106": "鹿児島",
    "no.107": "沖縄",
    "no.108": "ロシア",
    "no.109": "新潟"
  }
]

下記PHPでは、JSONファイル(area.json)を読み込んで、一部の値を書き換えて、
テキストでJSONを組み立てて再度JSONファイルとして保存しています。

<?php

//読み込み
$url = "./area.json";
$json = file_get_contents($url);
$json = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
$arr = json_decode($json,true); //All Json Data.
//print_r($arr[0]);

$i00 = 0;
foreach($arr[0] as $key1 => $val1){

  $aaa[$i00] = $key1;
  $bbb[$i00] = $val1;
  $i00++;

}

$i01 = 0;
foreach($arr[1] as $key2 => $val2){

  $ccc[$i01] = $key2;
  $ddd[$i01] = $val2;
  $i01++;

}

$bbb[0] = "上海"; // $arr[0]['name']の東京を上海に書き換える

$JSON = <<< EOF
[
  {
    "$aaa[0]":"$bbb[0]",
    "$aaa[1]":"$bbb[1]",
    "$aaa[2]":"$bbb[2]",
    "$aaa[3]":"$bbb[3]",
    "$aaa[4]":"$bbb[4]",
    "$aaa[5]":"$bbb[5]",
    "$aaa[6]":"$bbb[6]",
    "$aaa[7]":"$bbb[7]",
    "$aaa[8]":"$bbb[8]",
    "$aaa[9]":"$bbb[9]"
  },
  {
    "$ccc[0]":"$ddd[0]",
    "$ccc[1]":"$ddd[1]",
    "$ccc[2]":"$ddd[2]",
    "$ccc[3]":"$ddd[3]",
    "$ccc[4]":"$ddd[4]",
    "$ccc[5]":"$ddd[5]",
    "$ccc[6]":"$ddd[6]",
    "$ccc[7]":"$ddd[7]",
    "$ccc[8]":"$ddd[8]",
    "$ccc[9]":"$ddd[9]"
  }
]
EOF;

//上書き
$data = json_decode($JSON,true);
$json = fopen('./area.json', 'w+b');
fwrite($json, json_encode($data));
fclose($json);

一応やりたい事はできていて、個人的に読みやすいかとは思うのですが、
泥臭くてあまり良いコードではないなぁと思っており、データ容量が大きく
なった場合、処理も大変になってきそうです。

「普通はこうする」、「そのやり方はおかしい」、
「こんなやり方もある」、「いや、こんなやり方が適切」
など教えていただきたいです。
是非よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • Takumiboo

    2019/02/27 11:14

    「一部の値を書き換えて」というのが、
    ・一番最初の値(今回であればno.1:東京)を書き換えたいのか、
    ・「東京」を書き換えたいのか
    など、ふわっとしている定義なので、回答もまちまちになってしまうと思います。
    書き換えたいものが決まっているならpapininianusさんの書かれているように、
    $arr[0]["no.1"] = "上海";
    $json = json_encode($arr);
    で済む話なので。

    キャンセル

  • phiilo_

    2019/02/27 11:50

    ・一番最初の値(今回であればno.1:東京)を書き換えたい、です。
    papininianusさんの回答も大変参考になりました。

    キャンセル

回答 3

checkベストアンサー

+5

整形したJSONを出力したいということでしょうか?

<?php
$url = "area.json";
$json = file_get_contents($url);
$json = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
$arr = json_decode($json,true);

$idx_a=0;
$idx_b=0;
$arr[$idx_a][array_keys($arr[$idx_a])[$idx_b]] = "上海";
$json=json_encode($arr, JSON_UNESCAPED_UNICODE| JSON_PRETTY_PRINT);
print $json;

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/27 11:01

    インデックスで書き換えたいようなのでちょっと修正しました

    キャンセル

  • 2019/02/27 11:07

    ファイルを上書きするところは、追記しました。短くて、とても良いですね。今のところyambejp様の回答がベストかもしれません。

    キャンセル

  • 2019/02/27 11:48

    今回もベストアンサーとさせていただきました。
    今後ともよろしくお願いいたします。

    キャンセル

+3

上海への書き換えが、jsonの配列の最初の要素の、最初に取り出された項目のvalueだとするとこういう感じではないでしょうか。
$aaaとか$bbbとかの存在意義が分かりません。
書き換えがno.1であると知られているなら$arr[0]["no.1"] = "上海"で終わりです。

<?php
$json = <<<EOF
[
  {
    "no.1": "東京",
    "no.2": "神奈川",
    "no.3": "千葉",
    "no.4": "埼玉",
    "no.5": "ブラジル",
    "no.6": "佐賀",
    "no.7": "北海道",
    "no.8": "大分",
    "no.9": "愛知",
    "no.10": "静岡"
  },
  {
    "no.100": "フィリピン",
    "no.101": "山梨",
    "no.102": "青森",
    "no.103": "秋田",
    "no.104": "福島",
    "no.105": "福岡",
    "no.106": "鹿児島",
    "no.107": "沖縄",
    "no.108": "ロシア",
    "no.109": "新潟"
  }
]
EOF;
$arr = json_decode($json);
$res = [];
$updateFirst = false;
foreach($arr as $row) {
    $cur = [];
    foreach($row as $key => $value) {
        if(!$updateFirst) {
            $value = "上海";
            $updateFirst = true;
        }
        $cur[$key] = $value;
    }
    $res[] = $cur;
}
$json = json_encode($res);

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/27 11:06

    書き換えがno.1であると知られている場合はたしかに。あとで一部使わせていただくかもしれません。

    キャンセル

+2

array_combineという関数があって(リファレンス)、キーと値を合わせて1つの配列を作れますので、巨大なヒアドキュメントでJSONを起こす必要はありません。

$bbb[0] = "上海"; // $arr[0]['name']の東京を上海に書き換える

$data = [
  array_combine($aaa, $bbb), array_combine($ccc, $ddd)
];

// 残りのコードは同じ

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/27 11:03

    たしかに。できました。

    キャンセル

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

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

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