2012-02-06 101 views
-1

我在执行一个应该从文件中解析json字符串的脚本时遇到问题,要么用相同的id覆盖对象,要么将其添加到json数组中,并将其写回文件。该脚本在for循环中调用,以便我试图使用flock来防止在解析json字符串之前覆盖文件,但结果看起来非常奇怪,我不知道出了什么问题。下面是该脚本:PHP同时文件访问/ flock()问题

$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”,另一种正确用户ID以.json和log.json。该日志看起来最好,因为所有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":[]}]} 

干杯, 丹尼尔

+0

好像它可能会更容易和更快的使用数据库呢?如果我们可以看到输出结果旁边的输出结果可能会有所帮助。 – dqhendricks 2012-02-06 23:19:54

回答

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. 使用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

     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. 解除锁定操纵你怎么需要它的对象,并将其写回的编码JSON字符串并关闭文件。

     flock($file, LOCK_UN); 
         fclose($file); 
        } 
    }