我有一个脚本来计算单词的频率并将结果保存到json文件中。当它再次运行时,它会读取现有的json文件,合并结果,然后重写json文件。这可能在请求中重复发生,并且可能有许多同时发出的请求,因此我使用flock()
来尝试防止错误。我让它在昨天运行一段时间并获得了良好的数据,但今天早上我检查了文件已损坏。 (仍然是一个很好的文本文件,但是json被打破了。)
以下是我的代码的相关部分:
if(is_file('/home/myuser/public_html/word_counts.json'))
{
$prevoius_counts=json_decode(file_get_contents('/home/myuser/public_html/word_counts.json'),true);
}
if(!$prevoius_counts)
{
$prevoius_counts=array();
}
$new_counts=count_words($item->Description,$item->IDENTIFIER); //Creates an array like: array('the'=>20,'it'=>15,'spectacular'=>1);
$combined_counts=sum_associatve(array($new_counts,$prevoius_counts)); like array_merge, but sums duplicate keys instead of overwriting.
$fh=fopen('/home/myuser/public_html/word_counts.json','c'); //this will always be over-written with new data, but the "c" prevents it from being truncated to 0 bytes
if (flock($fh, LOCK_EX))
{
fwrite($fh, json_encode($combined_counts));
flock($fh, LOCK_UN); // release the lock
}
fclose($fh);
function count_words($description,$unique=null){
// /([\s_;?!\/\(\)\[\]{}<>\r\n"]|\.$|(?<=\D)[:,.\-]|[:,.\-](?=\D))/
// /([\s\-_,:;?!\/\(\)\[\]{}<>\r\n"]|(?<!\d)\.(?!\d))/
// http://rick.measham.id.au/paste/explain.pl?regex=
// http://stackoverflow.com/questions/20006448
$to_be_counted=strtolower($description);
$to_be_counted.=' BLOCKS '.$unique;
$words=preg_split('/([\s_;?!\/\(\)\[\]{}<>\r\n"]|\.$|(?<=\D)[:,.]|[:,.](?=\D))/', $to_be_counted, null, PREG_SPLIT_NO_EMPTY);
return array_count_values ($words);
}
function sum_associatve($arrays){
$sum = array();
foreach ($arrays as $array) {
foreach ($array as $key => $value) {
if (isset($sum[$key])) {
$sum[$key] += $value;
} else {
$sum[$key] = $value;
}
}
}
return $sum;
}
因为它工作了一段时间但最后写了坏json,我不知道它是否是文件锁定问题,或者我是否有一些问题,其中json_encode返回坏数据......?
答案 0 :(得分:0)
这似乎有效,但我仍然不能100%确定它能得到所有东西:
if (flock($fh, LOCK_EX))
{
ftruncate($fh, 0);
fwrite($fh, json_encode($combined_counts));
flock($fh, LOCK_UN); // release the lock
}
fclose($fh);