Json, zpracování, generování a formátování v PHP

Pro snadný přenos strukturovaných dat mezi klientem a serverem vznikl datový formát Json.

Převod z PHP pole / objektu do JSON

V PHP ho z pole vygenerujeme relativně snadno:

$users = [
	'name' => 'Jan',
	'surname' => 'Barasek',
	'role' => [
		'admin',
		'moderator',
	],
];

echo json_encode($users);

Vygeneruje:

{"name":"Jan","surname":"Barasek","role":["admin","moderator"]}

Formátování Jsonu | Vylepšení čitelnosti

Což ovšem nemusí být vždy dobře čitelné pro člověka, proto můžeme výstup vylepšit druhým parametrem:

echo json_encode($users, JSON_PRETTY_PRINT);

Vygeneruje:

{
	"name": "Jan",
	"surname": "Barasek",
	"role": [
		"admin",
		"moderator"
	]
}

Formátování Jsonu | Vlastní formátovací pravidla

Běžné formátování Jsonu přes PHP nemá žádné další nastavení a musíme se spokojit pouze s tímto výstupem. Pokud chceme například místo mezer odsazovat tabulátory (nebo jakkoli pozměnit pravidla generování), musíme si to naprogramovat sami.

Tato funkce umí již základní formátování a stačí ji jen pozměnit:

function prettyJsonPrint($json) {
    $result = '';
    $level = 0;
    $in_quotes = false;
    $in_escape = false;
    $ends_line_level = NULL;
    $json_length = strlen($json);

    for ($i = 0; $i < $json_length; $i++) {
        $char = $json[$i];
        $new_line_level = NULL;
        $post = '';
        if ($ends_line_level !== NULL) {
            $new_line_level = $ends_line_level;
            $ends_line_level = NULL;
        }
        if ($in_escape) {
            $in_escape = false;
        } else if ($char === '"') {
            $in_quotes = !$in_quotes;
        } else if (!$in_quotes) {
            switch ($char) {
                case '}':
                case ']':
                    $level--;
                    $ends_line_level = NULL;
                    $new_line_level = $level;
                    break;

                case '{':
                case '[':
                    $level++;
                case ',':
                    $ends_line_level = $level;
                    break;

                case ':':
                    $post = ' ';
                    break;

                case " ":
                case "\t":
                case "\n":
                case "\r":
                    $char = '';
                    $ends_line_level = $new_line_level;
                    $new_line_level = NULL;
                    break;
            }
        } else if ($char === '\\') {
            $in_escape = true;
        }
        if ($new_line_level !== NULL) {
            $result .= "\n" . str_repeat("\t", $new_line_level);
        }
        $result .= $char . $post;
    }

    return $result;
}

Funkce převzata z: https://stackoverflow.com/a/9776726/6777550

Například vstup:

{"key1":[1,2,3],"key2":"value"}

Naformátuje jako:

{
	"key1": [
		1,
		2,
		3
	],
	"key2": "value"
}

Což je mnohem lépe čitelné (kvůli důslednému odsazení každého prvku).

Formátování Jsonu | Vlastní obarvení výstupu

Někdy se může hodit barevné zvýraznění klíčů, samotných dat a také jednotlivých formátovacích prvků (zejména uzavírací závorky).

Například vstup:

{"access": {"token": {"issued_at": "2008-08-16T14:10:31.309353", "expires": "2008-08-17T14:10:31Z", "id": "MIICQgYJKoZIhvcIegeyJpc3N1ZWRfYXQiOiAi"}, "serviceCatalog": [], "user": {"username": "ajay", "roles_links": [], "id": "16452ca89", "roles": [], "name": "ajay"}}}

Naformátuje jako:

{
  "access": {
    "token": {
      "issued_at""2008-08-16T14:10:31.309353"
      "expires""2008-08-17T14:10:31Z"
      "id""MIICQgYJKoZIhvcIegeyJpc3N1ZWRfYXQiOiAi"
    }, 
    "serviceCatalog": [
    ], 
    "user": {
      "username""ajay"
      "roles_links": [
      ], 
      "id""16452ca89"
      "roles": [
      ], 
      "name""ajay"
    }
  }
}

To lze implementovat následující funkcí:

function jsonColorFormater($json, $indentation = "\t") {
    $crl = 0;
    $ss = false;
    $buffer = '';
    for ($c = 0; $c < strlen($json); $c++) {
        if ($json[$c] == '}' || $json[$c] == ']') {
            $crl--;
            $buffer .= "\n" . str_repeat($indentation, $crl);
        }
        if ($json[$c] == '"' && (@$json[$c - 1] == ',' || @$json[$c - 2] == ',')) {
            $buffer .= "\n" . str_repeat($indentation, $crl);
        }
        if ($json[$c] == '"' && !$ss) {
            $buffer .= '<span style="color:'.((@$json[$c - 1] == ':' || @$json[$c - 2] == ':') ? '#35D' : '#C22').';">';
        }
        $buffer .= $json[$c];
        if ($json[$c] == '"' && $ss) $buffer .= '</span>';
        if ($json[$c] == '"') $ss = !$ss;
        if ($json[$c] == '{' || $json[$c] == '[') {
            $crl++;
            $buffer .= "\n". str_repeat($indentation, $crl);
        }
    }

    // Vrátí HTML zdroj
    return '<pre>' . $buffer . '</pre>';
}

// Takto stačí zavolat a vrátí formátovaný výstup
// echo jsonColorFormater($data, '  ');

Funkce převzata a radikálně přepsána z: https://stackoverflow.com/a/20953262/6777550

Převod z JSON do PHP pole / objektu

Lze realizovat funkcí json_decode(), která z Jsonu vyrobí datovou strukturu, s kterou musíme pracovat, jako s objektem:

$json = '{"name":"Jan","surname":"Barasek","role":["admin","moderator"]}';
$decode = json_decode($json);

echo $decode->name; // Vrátí 'Jan'

// echo $decode->role;
//      Toto nejde, protože property role
//      obsahuje pole, musíme iterovat.

echo '<ul>';
foreach ($decode->role as $role) {
     echo '<li>' . $role . '</li>'; // Postupně vypíše role za odrážky
}
echo '</ul>';

Zpracování v javascriptu

Například v knihovně jQuery lze řetězec s JSON naparsovat do objektu velice snadno:

var json = '{"name":"Jan","surname":"Barasek","role":["admin","moderator"]}';
var parser = $.parseJSON(json);

document.write('Jméno: ' + parser.name);
console.log(parser); // Vypíše do konzole celý objekt pro možnost ladění

Potřebujete poradit s PHP?

Nabízím trénink vývojářů, konzultace, školení a analýzu návrhových vzorů. Osobně v Praze nebo přes Skype.

Napište mi: jan@barasek.com
Lektor: Jan Barášek

Pomohl Vám tento článek?

TopList counter