jared_flack
jared_flack

Reputation: 1646

json_decode returning 1 when inside if condition

This is my code:

if(
    $jsonObj = json_decode($someJson) &&
    json_last_error() == JSON_ERROR_NONE
) {

    print_r($jsonObj);
}

Output is 1. Another way of writing it:

$jsonObj = json_decode($someJson);

if(
    $jsonObj &&
    json_last_error() == JSON_ERROR_NONE
) {

    print_r($jsonObj);
}

Output is a stdClass (what I want).

Why doesn't the first block of code work the same as the second? And maybe it would be fine to just write it like?:

$jsonObj = json_decode($someJson);

if(json_last_error() == JSON_ERROR_NONE) {

    print_r($jsonObj);
}

Upvotes: 0

Views: 706

Answers (4)

Stefano Sanfilippo
Stefano Sanfilippo

Reputation: 33046

This is because = has a lower priority with respect to logic operators:

if (
    $jsonObj = json_decode($someJson) &&
    json_last_error() == JSON_ERROR_NONE
)

Is:

if ($jsonObj = json_decode($someJson) && json_last_error() == JSON_ERROR_NONE)

Which groups as:

if ($jsonObj = (json_decode($someJson) && json_last_error() == JSON_ERROR_NONE))

So that this logical condition:

json_decode($someJson) && json_last_error() == JSON_ERROR_NONE

Is first evalued (result TRUE, represented by 1). Then, the result is assigned to $jsonObj, which becomes 1. Finally, the if clause is evalued.

Your first version is actually equivalent to:

$jsonObj = (json_decode($someJson) && json_last_error() == JSON_ERROR_NONE);
if ($jsonObj) {
    //....
}

Upvotes: 1

Orangepill
Orangepill

Reputation: 24645

change

if(
    $jsonObj = json_decode($someJson) &&
    json_last_error() == JSON_ERROR_NONE
) {

to

$jsonObj = json_decode($someJson);
if ($jsonObj && json_last_error() == JSON_ERROR_NONE){

The && is resolving before the = so you are assigning true

Upvotes: 0

Wrikken
Wrikken

Reputation: 70490

This:

$jsonObj = json_decode($someJson) && json_last_error() == JSON_ERROR_NONE

Means this:

$jsonObj = (json_decode($someJson) && json_last_error() == JSON_ERROR_NONE)

Which is:

$jsonObj = ($somenonemptyvar && true)

So, $jsonObj is true.

You might want to use:

($jsonObj = json_decode($someJson)) && json_last_error() == JSON_ERROR_NONE

And some reading: operator precedence

You second suggestion would work fine though, especially if falsy values (0,NULL, false, empty array...) are a valid result for your json_decode.

Upvotes: 1

Sean Bright
Sean Bright

Reputation: 120644

Because of operator precedence. Boolean AND (&&) has higher precedence than assignment (=) so the first statement is effectively:

$jsonObj = (json_decode($someJson) && json_last_error() == JSON_ERROR_NONE)

You'll need to add parentheses to get the outcome you want:

($jsonObj = json_decode($someJson)) && json_last_error() == JSON_ERROR_NONE

Upvotes: 7

Related Questions