本文目录导读:

- 使用 json_last_error() 和 json_last_error_msg()
- 封装成函数
- 使用 try-catch 配合异常处理
- 使用 try-catch 块(PHP 7.3+)
- 完整的JSON验证和转换函数
- 使用中间件方式(适用于框架)
- 最佳实践建议
在PHP项目中,处理JSON解析失败的情况,可以使用以下几种方法来捕获错误:
使用 json_last_error() 和 json_last_error_msg()
<?php
$jsonString = '{"name": "John", age: 30}'; // 错误的JSON格式
$data = json_decode($jsonString);
if (json_last_error() !== JSON_ERROR_NONE) {
$errorCode = json_last_error();
$errorMessage = json_last_error_msg();
echo "JSON解析失败!\n";
echo "错误代码: " . $errorCode . "\n";
echo "错误信息: " . $errorMessage . "\n";
}
?>
封装成函数
<?php
function safeJsonDecode($json, $assoc = false, $depth = 512, $options = 0) {
$data = json_decode($json, $assoc, $depth, $options);
if (json_last_error() !== JSON_ERROR_NONE) {
switch (json_last_error()) {
case JSON_ERROR_DEPTH:
throw new \Exception('超出最大堆叠深度');
case JSON_ERROR_STATE_MISMATCH:
throw new \Exception('JSON格式错误或语法错误');
case JSON_ERROR_CTRL_CHAR:
throw new \Exception('发现意外控制字符');
case JSON_ERROR_SYNTAX:
throw new \Exception('JSON语法错误');
case JSON_ERROR_UTF8:
throw new \Exception('字符编码错误');
default:
throw new \Exception('未知JSON错误: ' . json_last_error_msg());
}
}
return $data;
}
// 使用示例
try {
$jsonString = '{"name": "John", "age": 30}'; // 正确的JSON
$data = safeJsonDecode($jsonString);
print_r($data);
} catch (\Exception $e) {
echo "捕获到异常: " . $e->getMessage() . "\n";
}
?>
使用 try-catch 配合异常处理
<?php
class JsonParseException extends \Exception {
private $jsonInput;
public function __construct($message, $jsonInput = '', $code = 0) {
parent::__construct($message, $code);
$this->jsonInput = $jsonInput;
}
public function getJsonInput() {
return $this->jsonInput;
}
}
function parseJsonSafely($jsonString) {
$data = json_decode($jsonString, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new JsonParseException(
json_last_error_msg(),
$jsonString,
json_last_error()
);
}
return $data;
}
// 使用示例
try {
$jsonString = '{"name": "John", "data": [1, 2, 3}'; // 错误的JSON
$result = parseJsonSafely($jsonString);
var_dump($result);
} catch (JsonParseException $e) {
echo "JSON解析失败: " . $e->getMessage() . "\n";
echo "原始输入: " . $e->getJsonInput() . "\n";
echo "错误代码: " . $e->getCode() . "\n";
// 记录日志
error_log("JSON Parse Error: " . $e->getMessage() . " Input: " . $e->getJsonInput());
// 返回默认值
$result = [];
}
?>
使用 try-catch 块(PHP 7.3+)
<?php
// PHP 7.3 引入了 JSON_THROW_ON_ERROR 常量
try {
$jsonString = '{"name": "John", "age": 30}'; // 错误的JSON
$data = json_decode($jsonString, true, 512, JSON_THROW_ON_ERROR);
print_r($data);
} catch (\JsonException $e) {
echo "JSON解析错误: " . $e->getMessage() . "\n";
echo "错误码: " . $e->getCode() . "\n";
// 错误处理
$data = ['default' => 'value']; // 使用默认值
}
?>
完整的JSON验证和转换函数
<?php
class JsonHandler {
/**
* 安全解析JSON字符串
*
* @param string $jsonStr JSON字符串
* @param bool $assoc 是否转换为关联数组
* @param mixed $default 解析失败时返回的默认值
* @return mixed
*/
public static function safeDecode($jsonStr, $assoc = true, $default = null) {
if (!is_string($jsonStr) || empty(trim($jsonStr))) {
return $default;
}
$data = json_decode($jsonStr, $assoc);
if (json_last_error() !== JSON_ERROR_NONE) {
// 记录错误信息
self::logError($jsonStr);
// 尝试修复JSON
$fixed = self::tryFixJson($jsonStr);
if ($fixed !== null) {
return json_decode($fixed, $assoc);
}
return $default;
}
return $data;
}
/**
* 记录JSON错误日志
*/
private static function logError($jsonStr) {
$error = json_last_error_msg();
$debugInfo = [
'error' => $error,
'input_length' => strlen($jsonStr),
'input_preview' => substr($jsonStr, 0, 100),
'timestamp' => date('Y-m-d H:i:s')
];
error_log("JSON Parse Error: " . json_encode($debugInfo));
}
/**
* 尝试修复常见的JSON错误
*/
private static function tryFixJson($jsonStr) {
// 尝试修复单引号代替双引号
$fixed = preg_replace('/\'([^\']*)\'/', '"$1"', $jsonStr);
// 尝试添加缺少的引号到键名
$fixed = preg_replace('/(\w+):/i', '"$1":', $fixed);
// 移除尾部逗号
$fixed = preg_replace('/,\s*([\]}])/', '$1', $fixed);
// 测试修复后的JSON
json_decode($fixed);
if (json_last_error() === JSON_ERROR_NONE) {
return $fixed;
}
return null;
}
}
// 使用示例
$json = '{"name": "John", age: 30}'; // 错误的JSON(age没有引号)
$result = JsonHandler::safeDecode($json, true, ['error' => '解析失败']);
print_r($result);
?>
使用中间件方式(适用于框架)
<?php
class JsonMiddleware {
public function handleRequest($requestData) {
try {
$jsonData = json_decode($requestData, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new \InvalidArgumentException('无效的JSON数据');
}
return $jsonData;
} catch (\Exception $e) {
// 返回标准错误响应
return [
'success' => false,
'error' => [
'code' => 400,
'message' => '请求数据格式错误',
'details' => $e->getMessage()
]
];
}
}
}
?>
最佳实践建议
- 始终验证JSON格式:不要假设所有输入都是有效的JSON
- 使用异常处理:通过try-catch统一处理错误
- 记录日志:记录失败的JSON输入以便调试
- 提供默认值:解析失败时返回合理的默认值
- 考虑安全性:避免在错误信息中暴露敏感数据
选择哪种方法取决于你的具体需求和PHP版本,对于现代PHP项目(7.3+),推荐使用 JSON_THROW_ON_ERROR 配合 try-catch。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播