【问题标题】:Why is json not valid?为什么json无效?
【发布时间】:2014-10-20 08:08:53
【问题描述】:

我想用 jquery 发出一个 json 请求来填充 wysihtml5 文本区域,但它不起作用

$("#calendarAnchor").click(function(event) {
            $.getJSON( "php/databaseHandler.php?action=GET_DATE_DETAILS&day=1&month=11&year=2014&username=bd107a66ba", function( json ) {
                alert( "JSON Data: " + json ); // not executed
            });             
        });

当我将我的 json 放入 jsonlint 时,它不会验证

({'id': '1124','day': '1','month': '11','year': '2014','red_day': 'ja','name_day': ['Allhelgona'],'images':[{'id': '2','url': 'svala_mini15.png','description': 'Idag är det soligt','category_id': '1','slot_id': '0'},{'id': '1','url': 'img/arstider/host/Flyttfagel_sadesarla_mini15.png','description': 'Idag regnar det, men vi har kul ändå!','category_id': '1','slot_id': '1'}],'holidays':[{'id': '1','name': 'Allhelgon','description': 'Nu firar man!'}],'dateDescription':[{'description': 'Idag!'}]})

W为什么 json 无效?我应该更改输出还是使用 jquery 其他方式来读取字段?输出json的php是

function getDateDetails($day, $month, $year, $username, $db){
$sql = <<<SQL
SELECT calendar_dates.id, 
calendar_dates.day, 
calendar_dates.month, 
calendar_dates.year,
calendar_dates.name_day,
calendar_dates.red_day 
FROM calendar_dates 
WHERE calendar_dates.day=$day 
AND calendar_dates.month=$month 
AND calendar_dates.year=$year
SQL;

    $ret = "{";
    $isFirst = true;

    if(!$result = $db->query($sql)){
        die('There was an error running the query [' . $db->error . ']');
    }

    while($row = $result->fetch_assoc()){
        if($isFirst){
            $names = join("','", array_filter(explode(";", "'" . $row['name_day'] . "'")));
            $imagesJson = getImagesJson($row['id'], $username, $db);
            $holidaysJson = getHolidaysJson($row['id'], $username, $db);
            $dateDescriptionJson = getDateDescriptionJson($row['id'], $username, $db);

            $ret .= "'id': '" . $row['id'] . "',";
            $ret .= "'day': '" . $row['day'] . "',";
            $ret .= "'month': '" . $row['month'] . "',";
            $ret .= "'year': '" . $row['year'] . "',";
            $ret .= "'red_day': '" . $row['red_day'] . "',";
            $ret .= "'name_day': [";


            $ret .= $names;             
            $ret .= "],";
            $ret .= "'images':";
            $ret .= $imagesJson . ",";
            $ret .= "'holidays':";
            $ret .= $holidaysJson . ",";
            $ret .= "'dateDescription':";
            $ret .= $dateDescriptionJson . ",";
            $isFirst = false;
        }

    }

    $ret = rtrim($ret, ",");
    $ret .= "}";

    return($ret);
}

更新

在 Dave 的帮助下,这是有效的 json

{
    "id": "1124",
    "day": "1",
    "month": "11",
    "year": "2014",
    "red_day": "ja",
    "name_day": [
        "Allhelgon "
    ],
    "images": [
        {
            "id": "2",
            "url": "mini15.png",
            "description": "Idag är det soligt!",
            "category_id": "1",
            "slot_id": "0"
        },
        {
            "id": "1",
            "url": "sadesarla_mini15.png",
            "description": "Idag regnar det!",
            "category_id": "1",
            "slot_id": "1"
        }
    ],
    "holidays": [
        {
            "id": "1",
            "name": "Allhelgon",
            "description": "Nu!"
        }
    ],
    "dateDescription": [
        {
            "description": "Idag!"
        }
    ]
}

我的新 php(仍然存在来自users.username = '$username' 的注入漏洞?)是

function getDateDescription($dateId, $username, $db){
$sql = <<<SQL
SELECT calendar_date_description.description
FROM calendar_date_description
INNER JOIN calendar_users
ON calendar_users.username = '$username'
WHERE calendar_date_description.user_id= calendar_users.id
AND calendar_date_description.date_id = $dateId
SQL;

$ret = "[";
$description ="";
    if(!$result = $db->query($sql)){
        die('There was an error running the query [' . $db->error . ']');
    }

    while($row = $result->fetch_assoc()){
        $description = $row['description'];
    }

    return($description);   
}

function getDateDetails($day, $month, $year, $username, $db){

$sql = <<<SQL
SELECT calendar_dates.id, 
calendar_dates.day, 
calendar_dates.month, 
calendar_dates.year,
calendar_dates.name_day,
calendar_dates.red_day 
FROM calendar_dates 
WHERE calendar_dates.day=$day 
AND calendar_dates.month=$month 
AND calendar_dates.year=$year
SQL;

    //$ret = "{";
    $isFirst = true;

    if(!$result = $db->query($sql)){
        die('There was an error running the query [' . $db->error . ']');
    }

$ret = array();

while ($row = $result->fetch_assoc()) {
    $names               = array_filter(explode(";", $row['name_day']));
    $dateDescriptionJson = getDateDescription($row['id'], $username, $db);

    $ret = array(
        'id'              => $row['id'],
        'day'             => $row['day'],
        'month'           => $row['month'],
        'year'            => $row['year'],
        'red_day'         => $row['red_day'],
        'name_day'        => $names,
        'dateDescription' => $dateDescriptionJson
    );
}

$ret = json_encode($ret);

return ($ret);
}

【问题讨论】:

  • JSON 需要为属性名称和值添加双引号。这就是为什么最好使用适当的 JSON 库来创建 JSON 字符串,即 json_encode。
  • 另外,数组只能以[]开头,对象只能以{}开头,不能以()开头
  • 检测到注入漏洞 + 当有json_encode 这样的东西时,为什么有人会手动将 JSON 串起来?
  • @fatman: 并没有,return 语句中的() 只是多余的,但不是返回字符串的一部分

标签: php jquery json mysqli wysihtml5


【解决方案1】:

我很高兴能提供帮助,但我实际上是在推荐 json_encode。问题来自单引号,但根本问题是您正在手动构建这个复杂的 JSON 字符串。有时我会这样做,但仅在极少数情况下,例如一级 JSON 字符串 {"error":"true"},但对您而言并非如此。

请改用此方法:

$ret = array();

while ($row = $result->fetch_assoc()) {
    $names               = array_filter(explode(";", $row['name_day']));
    $imagesJson          = getImages($row['id'], $username, $db);
    $holidaysJson        = getHolidays($row['id'], $username, $db);
    $dateDescriptionJson = getDateDescription($row['id'], $username, $db);

    $ret = array(
        'id'              => $row['id'],
        'day'             => $row['day'],
        'month'           => $row['month'],
        'year'            => $row['year'],
        'red_day'         => $row['red_day'],
        'name_day'        => $names,
        'images'          => $imagesJson,
        'holidays'        => $holidaysJson,
        'dateDescription' => $dateDescriptionJson
    );
}

$ret = json_encode($ret);

return ($ret);

我会强烈建议将所有内容保留为 PHP 数组格式,然后当数据准备好输出到客户端时,再进行最终的 json_encode。

所以这意味着:

getImagesJson       -> getImages
getHolidaysJson     -> getHolidays
dateDescriptionJson -> dateDescription

这些函数将返回 PHP 数组而不是 JSON。这将允许您更轻松地跨函数操作数据。只需将相同的技术应用于这些功能,这将使您的生活变得更加轻松。

【讨论】:

    猜你喜欢
    • 2012-02-06
    • 1970-01-01
    • 2020-02-23
    • 2011-11-18
    • 2020-09-05
    • 1970-01-01
    • 1970-01-01
    • 2016-12-18
    • 2013-07-13
    相关资源
    最近更新 更多