0

I am trying to display some values from my JSON but fail on two whereas the rest works perfectly. I suspect it has something to do with the characters within, but have no idea on how to proceed.

Tried tricks:

  1. UTF-8-ing everything
  2. Regexing the JSON directly
  3. Decode, Encode with JSON_PRETTY_PRINT/JSON_UNESCAPED_UNICODE and Decode again
  4. and some more I can't remember anymore...

Any pointers on how to tackle this greatly appreciated:

var_dump of $json

{
    "products":{
        "product":[{
            "@id":"1",
            "name":"First Name",
            "fetchers":{
                "fetcher":[{
                    "@fetcherId":"1",
                    "link1":"http:\/\/www.example.com\/pv\/?1&NAME=[[first-name\/1\/?refID=1\/first-name]]&denk5=[[1]]",
                    "link2":"http:\/\/www.example.com\/pc\/?1&NAME=[[first-name\/1\/?refID=1\/first-name]]&denk5=[[1]]"
                }]
            }
        },{
            "@id":"2",
            "name":"Second Name",
            "fetchers":{
                "fetcher":[{
                    "@fetcherId":"2",
                    "link1":"http:\/\/www.example.com\/pv\/?1&NAME=[[second-name\/2\/?refID=2\/second-name]]&denk5=[[2]]",
                    "link2":"http:\/\/www.example.com\/pc\/?1&NAME=[[second-name\/2\/?refID=2\/second-name]]&denk5=[[2]]"
                }]
            }
        }]
    }
}

PHP Code

<?php
$json = json_decode($json,true);
foreach($json['products']['product'] as $data) {
    echo $data['@id'].'<br/>';
    echo $data['name'].'<br/>';
    echo $data['fetchers']['fetcher']['@fetcherId'].'<br/>';
    echo $data['fetchers']['fetcher']['link1'].'<br/>';
    echo $data['fetchers']['fetcher']['link2'].'<br/>';
}

Expected result

1
First Name
1
http://www.example.com/pv/?1&amp;NAME=[[first-name/1/?refID=1/first-name]]&amp;denk5=[[1]]
http://www.example.com/pc/?1&amp;NAME=[[first-name/1/?refID=1/first-name]]&amp;denk5=[[1]]
2
Second Name
2
http://www.example.com/pv/?1&amp;NAME=[[second-name/2/?refID=2/second-name]]&amp;denk5=[[2]]
http://www.example.com/pc/?1&amp;NAME=[[second-name/2/?refID=2/second-name]]&amp;denk5=[[2]]

What I get

1
First Name
1
 <- link1 empty
 <- link2 empty
2
Second Name
2
 <- link1 empty
 <- link2 empty

What am I missing?

EDIT @Brad solution works perfectly.

2 Answers 2

4

Your problem has nothing to do with JSON, and nothing to do with character encoding. It's that you're not picking the right element. $data['fetchers']['fetcher'] is an array. If you want the first element, use [0].

foreach($json['products']['product'] as $data) {
    echo $data['@id'].'<br/>';
    echo $data['name'].'<br/>';
    echo $data['fetchers']['fetcher'][0]['@fetcherId'].'<br/>';
    echo $data['fetchers']['fetcher'][0]['link1'].'<br/>';
    echo $data['fetchers']['fetcher'][0]['link2'].'<br/>';
}

Also, don't forget to use htmlspecialchars() around any arbitrary data used in the context of HTML.

Sign up to request clarification or add additional context in comments.

6 Comments

unfortunately, this always gives me the first iteration @fetcherId, link1 and link2 ... (id 1), and doesn't go through the foreach. any other way without hardcoding the iteration number in it?
@DKOATED You only have one in your data. Add more if that's relevant. And yes, all you have to do is have another foreach within your foreach to loop through. foreach ($data['fetchers']['fetcher'] as $fetcher)
My foreach goes through both products/product just fine (see my output above). it's just the link1 and link2 in both iterations not showing up ... perhaps I am just misunderstanding totally ... i could count iterations and set [0] with the iteration count? seems really hacky ...
I did: this is my output: 1, First Name, 1, link1/pv/?1&amp;NAME=[[first-name/1/?refID=1/first-name]]&amp;denk5=[[1]], link2/pc/?1&amp;NAME=[[first-name/1/?refID=1/first-name]]&amp;denk5=[[1]] 2, Second Name, 2, link1/pv/?1&amp;NAME=[[first-name/1/?refID=1/first-name]]&amp;denk5=[[1]], link2/pc/?1&amp;NAME=[[first-name/1/?refID=1/first-name]]&amp;denk5=[[1]]
@DKOATED It works if you try it. I put it on codepad for you: codepad.org/jV31Lymh There's nothing hacky about it... your data is messy. If that's the format your data is in, that's what you must do. If you will actually have more elements than one in fetcher, just add a foreach loop like I said.
|
1

Its not about the JSON data, you can access them properly this way. Consider this example:

$json_string = '{"products":{"product":[{"@id":"1","name":"First Name","fetchers":{"fetcher":[{"@fetcherId":"1","link1":"http:\/\/www.example.com\/pv\/?1&amp;NAME=[[first-name\/1\/?refID=1\/first-name]]&amp;denk5=[[1]]","link2":"http:\/\/www.example.com\/pc\/?1&amp;NAME=[[first-name\/1\/?refID=1\/first-name]]&amp;denk5=[[1]]"}]}},{"@id":"2","name":"Second Name","fetchers":{"fetcher":[{"@fetcherId":"2","link1":"http:\/\/www.example.com\/pv\/?1&amp;NAME=[[second-name\/2\/?refID=2\/second-name]]&amp;denk5=[[2]]","link2":"http:\/\/www.example.com\/pc\/?1&amp;NAME=[[second-name\/2\/?refID=2\/second-name]]&amp;denk5=[[2]]"}]}}]}}';
$json_data = json_decode($json_string, true);
$data = array();
foreach($json_data['products']['product'] as $key => $value) {
    echo '@id => ' . $value['@id'] . '<br/>';
    echo 'name => ' .$value['name'] . '<br/>';
    if(isset($value['fetchers'])) {
        $fetchers = reset($value['fetchers']['fetcher']); // <-- set pointer to first which is zero index
        echo 'fetcher_id => ' . $fetchers['@fetcherId'] . '<br/>';
        echo 'link1 => ' . $fetchers['link1'] . '<br/>';
        echo 'link2 => ' . $fetchers['link2'] . '<br/>';
    }
    echo '<br/>';
}


?>

Should yield something like this:

@id => 1
name => First Name
fetcher_id => 1
link1 => http://www.example.com/pv/?1&NAME=[[first-name/1/?refID=1/first-name]]&denk5=[[1]]
link2 => http://www.example.com/pc/?1&NAME=[[first-name/1/?refID=1/first-name]]&denk5=[[1]]

@id => 2
name => Second Name
fetcher_id => 2
link1 => http://www.example.com/pv/?1&NAME=[[second-name/2/?refID=2/second-name]]&denk5=[[2]]
link2 => http://www.example.com/pc/?1&NAME=[[second-name/2/?refID=2/second-name]]&denk5=[[2]]

1 Comment

thanks @kevinabelita, Brad's solution works perfectly on my end.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.