使用PHP json_decode解析JavaScript JSON

时间:2018-09-05 20:10:22

标签: javascript php json

我在以下情况下运行:我从html页提取JSON字符串并将其传递给json_decode,有时成功,有时json_decode返回null,如何改善我的解决方案要与json_decode做到100%JSON兼容?

这是我提取的字符串,抱歉,它太长了:https://pastebin.com/aMavjffY

我的解决方案:

$json_str = html_entity_decode( THE_STRING_FROM_PASTBIN, ENT_QUOTES );
$lots_json = explode( ';', $json_str );
$num_items = count( $lots_json ) - 1;
$lot_json = '';
for( $i = 0; $i < $num_items; ++$i ) {
    // $lot_json will have now a valid JSON that can be parse with JavaScript JSON.parse()
    $lot_json = str_replace( 'ECAT.lot[\'' . ($i + 1) . '\']=', '', $lots_json[$i] );
    $original_lot_json = $lot_json;

    // Convert any " to a character chosen by us to not break the JSON format
    // but we have to convert it back to '
    // ALso convert 's to ***s and than get it back
    $lot_json = str_replace( '"', '***', $lot_json );

    $lot_json = str_replace( array( "{'", "':", ": '", ":'", "',", ",'", "'}", "['", "']" ), 
                             array( '{"', '":', ': "', ':"', '",', ',"', '"}', '["', '"]' ), $lot_json );

    // Convert it back
    $lot_json = str_replace( '***', '\'', $lot_json );

    $tmp_lot_json = $lot_json;
    $lot_json = json_decode( $lot_json, 1 );
    if( $lot_json == null ) {
        echo 'doGetItemUrlList json_decode fails ' . print_r( $tmp_lot_json, 1 );
        echo 'doGetItemUrlList original_lot_json ' . print_r( $original_lot_json, 1 )  );
    }
}

1 个答案:

答案 0 :(得分:0)

正如大家已经说过的那样,您的数据不是有效的JSON,它是JavaScript对象,但根本不是有效的Json,但是您可以构建自己的假Json解码器。例如,我删除了数据中的分配并缩短了长度。 ..

给了这个假冒的杰森:

$fake=<<<'EOL'
{'id':'299','saleName':'Yellow Ball: The Frank and Lorna Dunphy 
Collection 
Online','lotItemId':'8T76S','saleNumber':'L18622','image':'/content/dam/stb/lots/L18/L18622/L18622_8T76S_1.jpg','gua
ranteeLine':'DAMIEN 
HIRST','title':'FRANK','path':'/data/events/2018/yellowball-online-l18622/catalogue/lot_167810653','order':29900,'jc
rLastModifiedDate':1529396163248,'isSE':false,'isSold':false,'isPast':false,'video':'','audio':'','objectDate':'','e
stimateTxt':'<img src="/content/dam/default/lotSymbols/symb_ArtistResaleRight.gif" />400-600 
GBP','lowEst':400.0,'highEst':600.0,'currency':'GBP','salePrice':0.0,'artist':'Hirst, Damien','medium':['Works on 
paper'],'genre':['Contemporary'],'type':['Figurative','Portrait'],'vintage':[],'size':[],'category':[],'isArtnet':fa
lse,'isRegAvail':true,'isBidCutoff':86400000,'isEstRequest':false,'hasBidLive':false,'startTime':1537538400834,'endT
ime':1537549200834,'hasBidLive':false,'isRestrict':false,'isLiveNow':false,'isWine':false,'isClosed':false,'showRegT
oBidLink':true,'isHideSaleTime':false,'featVidPath':'','useExternal':false,'featVidId':'','featBlogPath':'','wineLin
k':'http://www.sothebyswinelive.com/main.cfm?P=WebcastRegistrationForm','bidNowLink':'/en/attend-auction.bidlive.htm
l/2018/yellowball-online-l18622','addToCalLink':'/data/events/2018/yellowball-online-l18622','regToBidLink':'2018/ye
llowball-online-l18622','preSaleLot':true,'condRep':'/en/auctions/ecatalogue/2018/yellowball-online-l18622/lot.299.h
tml#conditionsOfSaleModal','soldPast':false,'isLiveNowWine':false,'onlineBiddingAvailableWine':false,'bidNowLinkWine
': '','altTitle':'FRANK'}
EOL
;

您可以构建如下功能:

         function fakeJsonDecode($data){

            return  eval('return '.join('',array_slice(array_map(
                  function($v){
                      if(is_array($v)){
                        $v[1]=str_replace('’','"',$v[1]);
                        $v[1]=str_replace('‘','"',$v[1]);
                        $v[1]=trim($v[1]);
                        if(!empty($v[1])&&$v[1][0]==='<'&&$v[1][strlen($v[1])-1]==='>')
                            $v[1]=substr($v[1],1,-1);
                        $v=$v[1];
                    }else{
                        if($v==='{') $v='[';
                        if($v==='}') $v=']';
                        if($v===':') $v='=>';
                        if($v==='<') $v='"';
                        if($v==='>') $v='"';
                    }

                    return $v;

                },token_get_all('<?php '.$data.' ?>')),1,-1)).';');


        }

        print_r(fakeJsonDecode($fake));

,输出为:

Array
(
    [id] => 299
    [saleName] => Yellow Ball: The Frank and Lorna Dunphy 
Collection 
Online
    [lotItemId] => 8T76S
    [saleNumber] => L18622
    [image] => /content/dam/stb/lots/L18/L18622/L18622_8T76S_1.jpg
    [gua
ranteeLine] => DAMIEN 
HIRST
    [title] => FRANK
    [path] => /data/events/2018/yellowball-online-l18622/catalogue/lot_167810653
    [order] => 29900
    [jc
rLastModifiedDate] => 1529396163248
    [isSE] => 
    [isSold] => 
    [isPast] => 
    [video] => 
    [audio] => 
    [objectDate] => 
    [e
stimateTxt] => 400-600 
GBP
    [lowEst] => 400
    [highEst] => 600
    [currency] => GBP
    [salePrice] => 0
    [artist] => Hirst, Damien
    [medium] => Array
        (
            [0] => Works on 
paper
        )

    [genre] => Array
        (
            [0] => Contemporary
        )

    [type] => Array
        (
            [0] => Figurative
            [1] => Portrait
        )

    [vintage] => Array
        (
        )

    [size] => Array
        (
        )

    [category] => Array
        (
        )

    [isArtnet] => 
    [isRegAvail] => 1
    [isBidCutoff] => 86400000
    [isEstRequest] => 
    [hasBidLive] => 
    [startTime] => 1537538400834
    [endT
ime] => 1537549200834
    [isRestrict] => 
    [isLiveNow] => 
    [isWine] => 
    [isClosed] => 
    [showRegT
oBidLink] => 1
    [isHideSaleTime] => 
    [featVidPath] => 
    [useExternal] => 
    [featVidId] => 
    [featBlogPath] => 
    [wineLin
k] => http://www.sothebyswinelive.com/main.cfm?P=WebcastRegistrationForm
    [bidNowLink] => /en/attend-auction.bidlive.htm
l/2018/yellowball-online-l18622
    [addToCalLink] => /data/events/2018/yellowball-online-l18622
    [regToBidLink] => 2018/ye
llowball-online-l18622
    [preSaleLot] => 1
    [condRep] => /en/auctions/ecatalogue/2018/yellowball-online-l18622/lot.299.h
tml#conditionsOfSaleModal
    [soldPast] => 
    [isLiveNowWine] => 
    [onlineBiddingAvailableWine] => 
    [bidNowLinkWine
] => 
    [altTitle] => FRANK
)

所以您需要在function上使用我的$original_lot_json