JsonHelper::nameValue()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
crap 2
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipbox/skeleton/blob/master/LICENSE
6
 * @link       https://github.com/flipbox/skeleton
7
 */
8
9
namespace Flipbox\Skeleton\Helpers;
10
11
use JsonSerializable;
12
13
/**
14
 * @author Flipbox Factory <[email protected]>
15
 * @since 2.0.0
16
 */
17
class JsonHelper
18
{
19
    /**
20
     * Encodes an arbitrary variable into JSON format
21
     *
22
     * @param mixed $var any number, boolean, string, array, or object to be encoded.
23
     * If var is a string, it will be converted to UTF-8 format first before being encoded.
24
     * @return string JSON string representation of input var
25
     */
26
    public static function encode($var): string
27
    {
28
        switch (gettype($var)) {
29
            case 'boolean':
30
                return $var ? 'true' : 'false';
31
32
            case 'NULL':
33
                return 'null';
34
35
            case 'integer':
36
                return (int)$var;
37
38
            case 'double':
39
            case 'float':
40
                return str_replace(',', '.', (float)$var); // locale-independent representation
41
42
            case 'string':
43
                return json_encode($var);
44
45
            case 'array':
46
                /*
47
                 * As per JSON spec if any array key is not an integer
48
                 * we must treat the the whole array as an object. We
49
                 * also try to catch a sparsely populated associative
50
                 * array with numeric keys here because some JS engines
51
                 * will create an array with empty indexes up to
52
                 * max_index which can cause memory issues and because
53
                 * the keys, which may be relevant, will be remapped
54
                 * otherwise.
55
                 *
56
                 * As per the ECMA and JSON specification an object may
57
                 * have any string as a property. Unfortunately due to
58
                 * a hole in the ECMA specification if the key is a
59
                 * ECMA reserved word or starts with a digit the
60
                 * parameter is only accessible using ECMAScript's
61
                 * bracket notation.
62
                 */
63
64
                // treat as a JSON object
65
                if (is_array($var) &&
66
                    count($var) &&
67
                    (array_keys($var) !== range(0, sizeof($var) - 1))
68
                ) {
69
                    return '{' .
70
                        join(
71
                            ',',
72
                            array_map(
73
                                [
74
                                    JsonHelper::class,
75
                                    'nameValue'
76
                                ],
77
                                array_keys($var),
78
                                array_values($var)
79
                            )
80
                        ) . '}';
81
                }
82
83
                // treat it like a regular array
84
                return '[' . join(',', array_map(array(JsonHelper::class, 'encode'), $var)) . ']';
85
86
            case 'object':
87
                // Check for the JsonSerializable interface available in PHP5.4
88
                // Note that instanceof returns false in case it doesn't know the interface.
89
                if (interface_exists('JsonSerializable', false) && $var instanceof JsonSerializable) {
0 ignored issues
show
Bug introduced by
The class JsonSerializable does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
90
                    // We use the function defined in the interface instead of json_encode.
91
                    // This way even for PHP < 5.4 one could define the interface and use it.
92
                    return self::encode($var->jsonSerialize());
93
                } elseif ($var instanceof \Traversable) {
94
                    $vars = [];
95
                    foreach ($var as $k => $v) {
96
                        $vars[$k] = $v;
97
                    }
98
                } else {
99
                    $vars = get_object_vars($var);
100
                }
101
                return '{' .
102
                    join(
103
                        ',',
104
                        array_map(
105
                            [
106
                                JsonHelper::class,
107
                                'nameValue'
108
                            ],
109
                            array_keys($vars),
110
                            array_values($vars)
111
                        )
112
                    ) . '}';
113
114
            default:
115
                return '';
116
        }
117
    }
118
119
    /**
120
     * array-walking function for use in generating JSON-formatted name-value pairs
121
     *
122
     * @param string $name name of key to use
123
     * @param mixed $value reference to an array element to be encoded
124
     *
125
     * @return   string  JSON-formatted name-value pair, like '"name":value'
126
     * @access   private
127
     */
128
    protected static function nameValue($name, $value)
129
    {
130
        return self::encode(strval($name)) . ':' . self::encode($value);
131
    }
132
}
133