-1

ファイルからjson文字列を解析し、同じIDでオブジェクトを上書きするか、json配列に追加してファイルに書き戻すスクリプトの実装に問題があります。スクリプトは for ループで呼び出されるため、flock を使用して、json 文字列が解析される前にファイルが上書きされないようにしようとしましたが、結果は非常に奇妙に見え、何が問題なのかわかりません。スクリプトは次のとおりです。

$method = $_SERVER['REQUEST_METHOD'];

$file = fopen($userid . '.json', 'c+');
flock($file, LOCK_EX);

$jsonStr = (filesize($userid . '.json') == 0 ) ? '{"success": true}' : fread($file, filesize($userid . '.json'));
$jsonObj = json_decode($jsonStr);

if($method === 'POST') {
$dataStr = file_get_contents('php://input');
$dataObj = json_decode($dataStr);

$replacements = array();
if(isset($jsonObj->images)) {
    foreach($jsonObj->images as $idx=>$image) {
            if($image->id == $dataObj->id) {
                $replacements += array($idx => $dataObj);
            }
    }
    if(count($replacements)==0) {
        array_push($replacements, $dataObj);
    }
    $jsonObj->images = array_replace($jsonObj->images, $replacements);
} else {
    //$jsonObj = new stdClass();
    $jsonObj->images = new stdClass(); 
    $jsonObj->images = array($dataObj);
}


fwrite($file, json_encode($jsonObj));
file_put_contents('log.json', json_encode($dataObj), FILE_APPEND);

echo '{"success":true, "images":' . $dataStr . '}';
} else if($method === 'GET') {
echo $jsonStr;
}

fclose($file);

その結果、「.json」と呼ばれる 3 つのファイルと、正しくuserid .json と log.json の 3 つのファイルが得られることがあります。26 個のオブジェクトすべてが正しく表示されているため、ログは最適に見えますが、以前に存在するオブジェクトをチェックしていません。「.json」は空白で、非常に奇妙に見えます。

{"success":true,"images":[{"id":"f9f4b6ee-8b7b-414e-98f4-47ed5ee3c594","top":1200,"left":4050,"clicks":0,"affinity":[]}]}
{"success":true,"images":[{"id":"034c7661-9466-4651-b860-7e049e1543ac","top":900,"left":600,"clicks":0,"affinity":[]}]}
{"images":[{"id":"eebc35ec-6c0e-416a-9516-061df821083d","top":1800,"left":3300,"clicks":0,"affinity":[]}]}
{"images":[{"id":"e09da5b9-2e65-4a12-94cd-4745b354a256","top":1200,"left":1200,"clicks":0,"affinity":[]}]}
{"images":[{"id":"b023a259-4554-48a5-acd8-cb4215e6a391","top":1350,"left":1500,"clicks":0,"affinity":[]}]}
{"images":[{"id":"6521d8c3-461c-4fcd-b69d-69f14ae37418","top":600,"left":3750,"clicks":0,"affinity":[]}]}
{"images":[{"id":"4c082c1a-d4ae-4c1c-bfc4-ed36980f5db2","top":3150,"left":600,"clicks":0,"affinity":[]}]}
{"images":[{"id":"22dbdea2-4936-4353-825e-9af6e6f2ca93","top":3000,"left":2100,"clicks":0,"affinity":[]}]}
{"images":[{"id":"a7ba32d4-912e-489d-8f9b-e412bc1629c1","top":2850,"left":3750,"clicks":0,"affinity":[]}]}
{"images":[{"id":"b258148d-1779-4f17-ae5e-1160aa0a34b9","top":750,"left":4050,"clicks":0,"affinity":[]}]}
{"images":[{"id":"21c1c9d1-a7a6-48d2-a4ba-174c0fe248a3","top":1650,"left":750,"clicks":0,"affinity":[]}]}
{"images":[{"id":"bfed2f56-7876-4eb2-a217-e0f71f4455ee","top":3300,"left":1500,"clicks":0,"affinity":[]}]}
{"images":[{"id":"7f13b674-5d07-444f-bf6d-463758c96788","top":1650,"left":1950,"clicks":0,"affinity":[]}]}
{"images":[{"id":"fb8711f2-ba10-44d7-9038-02cae6438506","top":1800,"left":450,"clicks":0,"affinity":[]}]}
{"images":[{"id":"ac83e869-e4fb-4eee-8d2e-4d26762101d9","top":750,"left":1800,"clicks":0,"affinity":[]}]}
{"images":[{"id":"069a7595-2271-4430-b324-974115df7b80","top":2550,"left":1800,"clicks":0,"affinity":[]}]}
{"images":[{"id":"ea9ab2fc-e179-4f56-9ce7-8af456911b33","top":1950,"left":750,"clicks":0,"affinity":[]}]}
{"images":[{"id":"9b997ae3-0c66-4f78-937a-2fde2470d7d7","top":300,"left":300,"clicks":0,"affinity":[]}]}
{"images":[{"id":"f860dea4-3b27-4401-999b-72ce45022110","top":1200,"left":1950,"clicks":0,"affinity":[]}]}
{"images":[{"id":"2633c107-8a51-4e9c-bc2c-f87c30f7359d","top":750,"left":2100,"clicks":0,"affinity":[]}]}
{"images":[{"id":"bebcb2bb-c2f0-4e4d-b202-b05090eacf49","top":3600,"left":3600,"clicks":0,"affinity":[]}]}
{"images":[{"id":"460f961e-f1dd-4329-95be-d30770a37b83","top":2400,"left":1200,"clicks":0,"affinity":[]}]}
{"images":[{"id":"ee9b254f-fe6a-4ece-a662-e934625e992a","top":3600,"left":600,"clicks":0,"affinity":[]}]}
{"images":[{"id":"4e047ea9-345e-4cf9-a066-d0b431820c61","top":2100,"left":1350,"clicks":0,"affinity":[]}]}
{"images":[{"id":"8bbb5327-6d39-40e1-919e-d7b70e13fc2b","top":2700,"left":1200,"clicks":0,"affinity":[]}]}
{"images":[{"id":"0c50c0ec-e18b-4917-9787-bad245eed798","top":1200,"left":2550,"clicks":0,"affinity":[]}]}

私も例外を取得します:

<b>Strict Standards</b>:  Creating default object from empty value in <b>C:\xampp\htdocs\gallery\store.php</b> on line <b>38</b><br />

手順を正しく理解していなかったと思います。何か助けていただければ幸いです。

編集:私が望む結果は、次のようになります:

{"success":true,"images":[{"id":"f9f4b6ee-8b7b-414e-98f4-47ed5ee3c594","top":1200,"left":4050,"clicks":0,"affinity":[]},
{"id":"034c7661-9466-4651-b860-7e049e1543ac","top":900,"left":600,"clicks":0,"affinity":[]},{"id":"eebc35ec-6c0e-416a-9516-061df821083d","top":1800,"left":3300,"clicks":0,"affinity":[]},
{"id":"e09da5b9-2e65-4a12-94cd-4745b354a256","top":1200,"left":1200,"clicks":0,"affinity":[]},
{"id":"b023a259-4554-48a5-acd8-cb4215e6a391","top":1350,"left":1500,"clicks":0,"affinity":[]},
{"id":"6521d8c3-461c-4fcd-b69d-69f14ae37418","top":600,"left":3750,"clicks":0,"affinity":[]},
{"id":"4c082c1a-d4ae-4c1c-bfc4-ed36980f5db2","top":3150,"left":600,"clicks":0,"affinity":[]},
{"id":"22dbdea2-4936-4353-825e-9af6e6f2ca93","top":3000,"left":2100,"clicks":0,"affinity":[]},
{"id":"a7ba32d4-912e-489d-8f9b-e412bc1629c1","top":2850,"left":3750,"clicks":0,"affinity":[]},
{"id":"b258148d-1779-4f17-ae5e-1160aa0a34b9","top":750,"left":4050,"clicks":0,"affinity":[]},
{"id":"21c1c9d1-a7a6-48d2-a4ba-174c0fe248a3","top":1650,"left":750,"clicks":0,"affinity":[]},
{"id":"bfed2f56-7876-4eb2-a217-e0f71f4455ee","top":3300,"left":1500,"clicks":0,"affinity":[]},
{"id":"7f13b674-5d07-444f-bf6d-463758c96788","top":1650,"left":1950,"clicks":0,"affinity":[]},
{"id":"fb8711f2-ba10-44d7-9038-02cae6438506","top":1800,"left":450,"clicks":0,"affinity":[]},
{"id":"ac83e869-e4fb-4eee-8d2e-4d26762101d9","top":750,"left":1800,"clicks":0,"affinity":[]},
{"id":"069a7595-2271-4430-b324-974115df7b80","top":2550,"left":1800,"clicks":0,"affinity":[]},
{"id":"ea9ab2fc-e179-4f56-9ce7-8af456911b33","top":1950,"left":750,"clicks":0,"affinity":[]},
{"id":"9b997ae3-0c66-4f78-937a-2fde2470d7d7","top":300,"left":300,"clicks":0,"affinity":[]},
{"id":"f860dea4-3b27-4401-999b-72ce45022110","top":1200,"left":1950,"clicks":0,"affinity":[]},
{"id":"2633c107-8a51-4e9c-bc2c-f87c30f7359d","top":750,"left":2100,"clicks":0,"affinity":[]},
{"id":"bebcb2bb-c2f0-4e4d-b202-b05090eacf49","top":3600,"left":3600,"clicks":0,"affinity":[]},
{"id":"460f961e-f1dd-4329-95be-d30770a37b83","top":2400,"left":1200,"clicks":0,"affinity":[]},
{"id":"ee9b254f-fe6a-4ece-a662-e934625e992a","top":3600,"left":600,"clicks":0,"affinity":[]},
{"id":"4e047ea9-345e-4cf9-a066-d0b431820c61","top":2100,"left":1350,"clicks":0,"affinity":[]},
{"id":"8bbb5327-6d39-40e1-919e-d7b70e13fc2b","top":2700,"left":1200,"clicks":0,"affinity":[]},
{"id":"0c50c0ec-e18b-4917-9787-bad245eed798","top":1200,"left":2550,"clicks":0,"affinity":[]}]}

乾杯、ダニエル

4

1 に答える 1

0

私はついにそれを動作させました、そして同時ファイルアクセスで問題を抱えている他の人のために、ここに私の解決策があります:

  1. ファイルが存在するかどうかを確認し、存在しない場合は、ファイルを作成してデータ構造を設定します(厳密な標準エラーを防ぐため)。

    $filename = $userid . '.json';
    if(!file_exists($filename)) {
        $file = fopen($filename, 'w');
        if(flock($file, LOCK_EX)) {
            fwrite($file, '{"success": true, "images": []}');
            flock($file, LOCK_UN);
            fclose($file);
        }
    }
    
  2. 2番目のパラメーターとしてc+を使用してファイルを開きます(w +はファイルサイズを0に設定します)。排他ロックを取得できるかどうかを確認します。ファイルを読み取り、後で上書きするために巻き戻します。

    else {
        $file = fopen($userid . '.json', 'c+');
        if(flock($file, LOCK_EX)) {
            $jsonStr = fread($file, filesize($userid . '.json'));
            $jsonObj = json_decode($jsonStr);
            rewind($file);
    
  3. オブジェクトを必要な方法で操作し、fwriteを使用してエンコードされたjson文字列として書き戻します

            if($method === 'POST') {
                $dataStr = file_get_contents('php://input');
                if(isset($dataStr) &&$dataStr != '') {
                    $dataObj = json_decode($dataStr);
                    $replace = -1;
                    foreach($jsonObj->images as $idx=>$image) {
                        if($image->id == $dataObj->id) {
                            $replace = $idx;
                        }
                    }
                    if($replace != -1) {
                        $img = $jsonObj->images;
                        $img[$replace] = $dataObj;
                        $jsonObj->images = $img;
                    } else {
                        array_push($jsonObj->images, $dataObj);
                    }
                    fwrite($file, json_encode($jsonObj));
                }
                echo '{"success":true, "images":' . $dataStr . '}';
            } else if($method === 'GET') {
                echo $jsonStr;
            }
    
  4. ロックを解除してファイルを閉じます。

            flock($file, LOCK_UN);
            fclose($file);
        }
    }
    
于 2012-02-07T12:35:53.543 に答える