php setplayersjson实现类型转换和文件锁定机制应对高并发

张开发
2026/6/2 12:01:36 15 分钟阅读
php setplayersjson实现类型转换和文件锁定机制应对高并发
已完成setplayersjson方法的实现和测试实现内容setplayersjson方法功能根据用户要求三丰云实现了setplayersjson(id数组, 中文属性名数组, value数组)方法批量修改免费虚拟主机players.json文件中多个id的多个属性名对应字段值。方法特点 1. 参数处理ids : 球员ID数组支持逗号分隔的字符串或数组names : 中文属性名数组支持逗号分隔的字符串或数组values : 要设置的新值数组支持逗号分隔的字符串或数组参数长度必须相同否则返回错误 2. 文件锁定机制使用排他锁LOCK_EX保证并发写入时的数据一致性if (!flock(KaTeX parse error: Expected }, got EOF at end of input: …X)) { fclose(handle);return json([‘success’ false,‘error’ ‘文件正在被其他用户使用请稍后重试’]);}类型转换根据原始字段值的类型自动转换新值确保类型一致性整数类型使用 is_numeric() 检查并转换为 (int)浮点数类型使用 is_numeric() 检查并转换为 (float)布尔类型支持多种字符串表示‘true’, ‘false’, ‘yes’, ‘no’, ‘是’, 否’等字符串类型直接转换或JSON编码数组类型支持JSON字符串解析批量处理优化使用 $playersMap 建立ID到索引的映射避免重复遍历一次性读取、修改、写入整个JSON文件单次文件锁定处理所有更新操作返回格式{“success”: true,“message”: “批量更新完成”,“data”: {“totalUpdates”: 3,“successCount”: 3,“errorCount”: 0,“results”: [{“index”: 0,“id”: “660”,“name”: “中投”,“fieldName”: “abilities.fg_base”,“success”: true}],“errors”: []}}错误处理参数为空时返回错误参数长度不匹配时返回错误文件不存在时返回错误无法获取文件锁时返回错误JSON文件格式错误时返回错误球员ID不存在时记录错误中文属性名不存在时记录错误类型转换失败时记录错误publicfunctionsetplayersjson(Request $request){try{error_reporting(E_ALL~E_DEPRECATED);$ids$request-post(ids)?:$request-get(ids);$names$request-post(names)?:$request-get(names);$values$request-post(values)!null?$request-post(values):$request-get(values);if(!$ids||!$names||$valuesnull){returnjson([successfalse,error参数不能为空]);}if(is_string($ids)){$idsarray_map(trim,explode(,,$ids));}if(is_string($names)){$namesarray_map(trim,explode(,,$names));}if(is_string($values)){$valuesarray_map(trim,explode(,,$values));}if(count($ids)!count($names)||count($ids)!count($values)){returnjson([successfalse,errorid数组、属性名数组和value数组的长度必须相同]);}$seaValue$this-getSeaValue();$jsonPathbase_path()./data/{$seaValue}/players.json;if(!file_exists($jsonPath)){returnjson([successfalse,error文件不存在: players.json]);}$handlefopen($jsonPath,r);if(!$handle){returnjson([successfalse,error无法打开文件]);}if(!flock($handle,LOCK_EX)){fclose($handle);returnjson([successfalse,error文件正在被其他用户使用请稍后重试]);}try{$jsonContentstream_get_contents($handle);$jsonDatajson_decode($jsonContent,true);if(!$jsonData||!isset($jsonData[data][players])){flock($handle,LOCK_UN);fclose($handle);returnjson([successfalse,errorJSON文件格式错误]);}$playersMap[];foreach($jsonData[data][players]as$index$p){if(isset($p[id])){$playersMap[$p[id]]$index;}}$results[];$errors[];for($i0;$icount($ids);$i){$id$ids[$i];$name$names[$i];$value$values[$i];if(!isset($playersMap[$id])){$errors[][index$i,id$id,name$name,error未找到ID为{$id}的球员];continue;}$playerIndex$playersMap[$id];$jsonField$this-getJsonFieldByChinese($name);if(!$jsonField){$errors[][index$i,id$id,name$name,error未找到中文属性名对应的字段: {$name}];continue;}try{$oldValuenull;if(strpos($jsonField,.)!false){$partsexplode(.,$jsonField);$current$jsonData[data][players][$playerIndex];foreach($partsas$j$part){if($jcount($parts)-1){$oldValue$current[$part]??null;$convertedValue$this-convertJsonValueByType($value,$oldValue);$current[$part]$convertedValue;}else{if(!isset($current[$part])){$current[$part][];}$current$current[$part];}}}else{$oldValue$jsonData[data][players][$playerIndex][$jsonField]??null;$convertedValue$this-convertJsonValueByType($value,$oldValue);$jsonData[data][players][$playerIndex][$jsonField]$convertedValue;}$results[][index$i,id$id,name$name,fieldName$jsonField,successtrue];}catch(\Exception $e){$errors[][index$i,id$id,name$name,error$e-getMessage()];}}ftruncate($handle,0);rewind($handle);$newJsonContentjson_encode($jsonData,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);fwrite($handle,$newJsonContent);flock($handle,LOCK_UN);fclose($handle);returnjson([successtrue,message批量更新完成,data[totalUpdatescount($ids),successCountcount($results),errorCountcount($errors),results$results,errors$errors]]);}catch(\Exception $e){flock($handle,LOCK_UN);fclose($handle);returnjson([successfalse,error批量更新球员数据失败: .$e-getMessage()]);}}catch(\Exception $e){returnjson([successfalse,error批量更新球员数据失败: .$e-getMessage()]);}}

更多文章