Completed
Pull Request — master (#7)
by Patrick
04:03
created

class.SerializableObject.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * An easily serializable class
4
 *
5
 * This file describes a serializable object
6
 *
7
 * PHP version 5 and 7
8
 *
9
 * @author Patrick Boyd / [email protected]
10
 * @copyright Copyright (c) 2015, Austin Artistic Reconstruction
11
 * @license http://www.apache.org/licenses/ Apache 2.0 License
12
 */
13
14
/**
15
 * An object that can be serialized and accessed as an array.
16
 *
17
 * This class can be serialized to various formats
18
 */
19
class SerializableObject implements ArrayAccess, JsonSerializable
20
{
21
    /**
22
     * Create the object from an array
23
     *
24
     * @param array $array The array of object properties
25
     */
26
    public function __construct($array = false)
27
    {
28
        if($array !== false)
29
        {
30
            if(is_object($array))
31
            {
32
                $array = get_object_vars($array);
33
            }
34
            if(is_array($array))
35
            {
36
                foreach($array as $key => $value)
37
                {
38
                    $this->{$key} = $value;
39
                }
40
            }
41
        }
42
    }
43
44
    /**
45
     * Serialize the object into a format consumable by json_encode
46
     *
47
     * @return mixed The object in a more serialized format
48
     */
49
    public function jsonSerialize()
50
    {
51
        return $this;
52
    }
53
54
    /**
55
     * Convert the object into an XML string
56
     *
57
     * @return string The XML format of the object
58
     */
59
    public function xmlSerialize()
60
    {
61
        $xml = new XmlWriter();
62
        $xml->openMemory();
63
        $xml->startDocument('1.0');
64
        if(version_compare(PHP_VERSION, '7.0.0', '>='))
65
        {
66
            $this->php7XmlSerialize($xml);
67
        }
68
        else
69
        {
70
            $this->oldPhpSerialize($xml);
71
        }
72
        $xml->endElement();
73
        return $xml->outputMemory(true);
74
    }
75
76
    private function php7XmlSerialize(XMLWriter $xml)
77
    {
78
        if(isset($this[0]))
79
        {
80
            $xml->startElement('Array');
81
            $this->array2XML($xml, 'Entity', get_object_vars($this));
82
            $xml->endElement();
83
        }
84
        else
85
        {
86
            $this->object2XML($xml, $this);
87
        }
88
    }
89
90
    private function oldPhpSerialize(XMLWriter $xml)
91
    {
92
        $tmp = json_decode(json_encode($this), false);
93
        $tmpA = get_object_vars($tmp);
94
        if(isset($tmpA[0]))
95
        {
96
            $xml->startElement('Array');
97
            $this->array2XML($xml, 'Entity', $tmpA);
98
            $xml->endElement();
99
        }
100
        else
101
        {
102
            $this->object2XML($xml, $tmp);
103
        }
104
    }
105
106
    /**
107
     * Convert an object to XML without document tags
108
     *
109
     * @param XmlWriter $xml The XMLWriter to write the object to
110
     * @param mixed $data The data to serialze to XML
111
     */
112
    private function object2XML(XMLWriter $xml, $data)
113
    {
114
        foreach($data as $key => $value)
115
        {
116
            if(is_array($value) || is_numeric($key))
117
            {
118
                $this->array2XML($xml, $key, (array)$value);
119
            }
120
            else if(is_object($value))
121
            {
122
                $xml->startElement($key);
123
                $this->object2XML($xml, $value);
124
                $xml->endElement();
125
            }
126
            else
127
            {
128
                if($key[0] === '$')
129
                {
130
                    $xml->writeElement(substr($key, 1), $value);
131
                }
132
                else
133
                {
134
                    $key = strtr($key, array(' '=>'', ','=>''));
135
                    $xml->writeElement($key, $value);
136
                }
137
            }
138
        }
139
    }
140
141
    /**
142
     * Determine if an array has any string keys
143
     *
144
     * @param array $array The array to test
145
     * 
146
     * @return boolean True if the array has string keys, false otherwise
147
     */
148
    private function arrayHasStringKeys(array $array)
149
    {
150
        return count(array_filter(array_keys($array), 'is_string')) > 0;
151
    }
152
153
    /**
154
     * Convert an array to XML without document tags
155
     *
156
     * @param XmlWriter $xml The XMLWriter to write the object to
157
     * @param string $keyParent The key of the parent object
158
     * @param mixed $data The data to serialze to XML
159
     */
160
    private function array2XML(XMLWriter $xml, $keyParent, $data)
161
    {
162
        $data = array_values($data);
163
        $count = count($data);
164
        for($i = 0; $i < $count; $i++)
165
        {
166
            $value = $data[$i];
167
            if(is_array($value) && isset($value[0]))
168
            {
169
                $xml->startElement($keyParent);
170
                $this->array2XML($xml, 'Child', $value);
171
                $xml->endElement();
172
            }
173
            else if(is_array($value) && $this->arrayHasStringKeys($value))
174
            {
175
                $xml->startElement($keyParent);
176
                $this->object2XML($xml, $value);
177
                $xml->endElement();
178
            }
179
            else if(is_object($value))
180
            {
181
                $xml->startElement($keyParent);
182
                $this->object2XML($xml, $value);
183
                $xml->endElement();
184
            }
185
            else
186
            {
187
                $xml->writeElement($keyParent, $value);
188
            }
189
        }
190
    }
191
192
    /**
193
     * Convert json back to an object
194
     *
195
     * @param string $json The JSON string to deserialize back into an object
196
     *
197
     * @return SerializableObject The object the json deserializes into 
198
     */
199
    public static function jsonDeserialize($json)
200
    {
201
        $array = json_decode($json, true);
202
        return new self($array);
203
    }
204
205
    /**
206
     * Convert the object to a serizlized string
207
     *
208
     * @param string $fmt The format to serialize into
209
     * @param array|false $select Which fields to include
210
     *
211
     * @return string The object in string format
212
     */
213
    public function serializeObject($fmt = 'json', $select = false)
214
    {
215
        $copy = $this;
216
        if($select !== false)
217
        {
218
            $copy = new self();
219
            $count = count($select);
220
            for($i = 0; $i < $count; $i++)
221
            {
222
                $copy->{$select[$i]} = $this->offsetGet($select[$i]);
223
            }
224
        }
225
        switch($fmt)
226
        {
227
            case 'json':
228
                return json_encode($copy);
229
            default:
230
                throw new Exception('Unsupported fmt '.$fmt);
231
        }
232
    }
233
234
    /**
235
     * Function to allow the caller to set a value in the object via object[offset] = value
236
     *
237
     * @param string $offset The key to set
238
     * @param mixed $value The value for the key
239
     */
240
    public function offsetSet($offset, $value)
241
    {
242
        $this->{$offset} = $value;
243
    }
244
245
    /**
246
     * Function to allow the caller to determin if a value in the object is set
247
     *
248
     * @param string $offset The key to determine if it has a value
249
     *
250
     * @return boolean Does the key have a value?
251
     */
252
    public function offsetExists($offset)
253
    {
254
        return isset($this->{$offset});
255
    }
256
257
    /**
258
     * Function to allow the caller to delete the value in the object for a key
259
     *
260
     * @param string $offset The key to unset
261
     */
262
    public function offsetUnset($offset)
263
    {
264
        unset($this->{$offset});
265
    }
266
267
    /**
268
     * Function to allow the caller to obtain the value for a key
269
     *
270
     * @param string $offset The key to return the value for
271
     *
272
     * @return mixed the value in the key
273
     */
274
    public function offsetGet($offset)
275
    {
276
        return $this->{$offset};
277
    }
278
}
279
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
280
?>
0 ignored issues
show
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
281