<?php
/**
 * JSON解析辅助类
 * 用于处理数据库中存储的非标准JSON数据
 */

class JsonHelper {
    
    /**
     * 清理并解析JSON字符串
     * @param string $json JSON字符串
     * @return array|false 解析成功返回数组，失败返回false
     */
    public static function parse($json) {
        if (empty($json)) {
            return [];
        }
        
        // 首先尝试直接解析
        $result = json_decode($json, true);
        if ($result !== null || json_last_error() === JSON_ERROR_NONE) {
            return $result;
        }
        
        // 直接解析失败，进行清理
        $cleaned = self::clean($json);
        
        // 再次尝试解析
        $result = json_decode($cleaned, true);
        if ($result !== null || json_last_error() === JSON_ERROR_NONE) {
            return $result;
        }
        
        // 如果还是失败，记录错误并返回false
        return false;
    }
    
    /**
     * 清理JSON字符串
     * @param string $json JSON字符串
     * @return string 清理后的字符串
     */
    public static function clean($json) {
        // 移除UTF-8 BOM
        $json = preg_replace('/^\xEF\xBB\xBF/', '', $json);
        
        // 步骤1: 替换换行符为转义的\n
        $json = str_replace("\r\n", "\\n", $json);
        $json = str_replace("\r", "", $json);
        $json = str_replace("\n", "\\n", $json);
        
        // 步骤2: 转义反斜杠（除了已经转义的\n）
        $placeholder = "\x00NEWLINE\x00";
        $json = str_replace("\\n", $placeholder, $json);
        $json = str_replace("\\", "\\\\", $json);
        $json = str_replace($placeholder, "\\n", $json);
        
        // 步骤3: 处理其他特殊字符
        // 转义制表符
        $json = str_replace("\t", "\\t", $json);
        
        // 移除其他控制字符
        $json = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F]/', '', $json);
        
        return $json;
    }
    
    /**
     * 验证JSON字符串是否有效
     * @param string $json JSON字符串
     * @return bool 是否有效
     */
    public static function isValid($json) {
        if (empty($json)) {
            return true;
        }
        json_decode($json);
        return json_last_error() === JSON_ERROR_NONE;
    }
    
    /**
     * 获取JSON解析错误信息
     * @return string 错误信息
     */
    public static function getLastError() {
        return json_last_error_msg();
    }
}
