php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
json_encoder.c
Go to the documentation of this file.
1/*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: Omar Kilani <omar@php.net> |
14 | Jakub Zelenka <bukka@php.net> |
15 +----------------------------------------------------------------------+
16*/
17
18#ifdef HAVE_CONFIG_H
19#include <config.h>
20#endif
21
22#include "php.h"
23#include "ext/standard/html.h"
24#include "zend_smart_str.h"
25#include "php_json.h"
26#include "php_json_encoder.h"
27#include "zend_portability.h"
28#include <zend_exceptions.h>
29#include "zend_enum.h"
30#include "zend_property_hooks.h"
31#include "zend_lazy_objects.h"
32
33static const char digits[] = "0123456789abcdef";
34
35static zend_always_inline bool php_json_check_stack_limit(void)
36{
37#ifdef ZEND_CHECK_STACK_LIMIT
38 return zend_call_stack_overflowed(EG(stack_limit));
39#else
40 return false;
41#endif
42}
43
44static int php_json_determine_array_type(zval *val) /* {{{ */
45{
46 zend_array *myht = Z_ARRVAL_P(val);
47
48 if (myht) {
49 return zend_array_is_list(myht) ? PHP_JSON_OUTPUT_ARRAY : PHP_JSON_OUTPUT_OBJECT;
50 }
51
53}
54/* }}} */
55
56/* {{{ Pretty printing support functions */
57
58static inline void php_json_pretty_print_char(smart_str *buf, int options, char c) /* {{{ */
59{
61 smart_str_appendc(buf, c);
62 }
63}
64/* }}} */
65
66static inline void php_json_pretty_print_indent(smart_str *buf, int options, php_json_encoder *encoder) /* {{{ */
67{
68 int i;
69
71 for (i = 0; i < encoder->depth; ++i) {
72 smart_str_appendl(buf, " ", 4);
73 }
74 }
75}
76/* }}} */
77
78/* }}} */
79
80static
81#if defined(_MSC_VER) && defined(_M_ARM64)
82// MSVC bug: https://developercommunity.visualstudio.com/t/corrupt-optimization-on-arm64-with-Ox-/10102551
84#else
85inline
86#endif
87bool php_json_is_valid_double(double d) /* {{{ */
88{
89 return !zend_isinf(d) && !zend_isnan(d);
90}
91/* }}} */
92
93static inline void php_json_encode_double(smart_str *buf, double d, int options) /* {{{ */
94{
95 size_t len;
96 char num[ZEND_DOUBLE_MAX_LENGTH];
97
98 zend_gcvt(d, (int)PG(serialize_precision), '.', 'e', num);
99 len = strlen(num);
101 num[len++] = '.';
102 num[len++] = '0';
103 num[len] = '\0';
104 }
105 smart_str_appendl(buf, num, len);
106}
107/* }}} */
108
109#define PHP_JSON_HASH_PROTECT_RECURSION(_tmp_ht) \
110 do { \
111 if (_tmp_ht) { \
112 GC_TRY_PROTECT_RECURSION(_tmp_ht); \
113 } \
114 } while (0)
115
116#define PHP_JSON_HASH_UNPROTECT_RECURSION(_tmp_ht) \
117 do { \
118 if (_tmp_ht) { \
119 GC_TRY_UNPROTECT_RECURSION(_tmp_ht); \
120 } \
121 } while (0)
122
123static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */
124{
125 int r, need_comma = 0;
126 HashTable *myht, *prop_ht;
127 zend_refcounted *recursion_rc;
128
129 if (php_json_check_stack_limit()) {
132 smart_str_appendl(buf, "null", 4);
133 }
134 return FAILURE;
135 }
136
137 if (Z_TYPE_P(val) == IS_ARRAY) {
138 myht = Z_ARRVAL_P(val);
139 recursion_rc = (zend_refcounted *)myht;
140 prop_ht = NULL;
141 r = (options & PHP_JSON_FORCE_OBJECT) ? PHP_JSON_OUTPUT_OBJECT : php_json_determine_array_type(val);
142 } else if (Z_OBJ_P(val)->properties == NULL
143 && Z_OBJ_HT_P(val)->get_properties_for == NULL
144 && Z_OBJ_HT_P(val)->get_properties == zend_std_get_properties
145 && Z_OBJ_P(val)->ce->num_hooked_props == 0
146 && !zend_object_is_lazy(Z_OBJ_P(val))) {
147 /* Optimized version without rebuilding properties HashTable */
148 zend_object *obj = Z_OBJ_P(val);
149 zend_class_entry *ce = obj->ce;
151 zval *prop;
152
153 if (GC_IS_RECURSIVE(obj)) {
155 smart_str_appendl(buf, "null", 4);
156 return FAILURE;
157 }
158
160
161 smart_str_appendc(buf, '{');
162
163 ++encoder->depth;
164
165 for (int i = 0; i < ce->default_properties_count; i++) {
167 if (!prop_info) {
168 continue;
169 }
170 if (ZSTR_VAL(prop_info->name)[0] == '\0' && ZSTR_LEN(prop_info->name) > 0) {
171 /* Skip protected and private members. */
172 continue;
173 }
174 prop = OBJ_PROP(obj, prop_info->offset);
175 if (Z_TYPE_P(prop) == IS_UNDEF) {
176 continue;
177 }
178
179 if (need_comma) {
180 smart_str_appendc(buf, ',');
181 } else {
182 need_comma = 1;
183 }
184
185 php_json_pretty_print_char(buf, options, '\n');
186 php_json_pretty_print_indent(buf, options, encoder);
187
189 options & ~PHP_JSON_NUMERIC_CHECK, encoder) == FAILURE &&
191 buf->s) {
192 ZSTR_LEN(buf->s) -= 4;
193 smart_str_appendl(buf, "\"\"", 2);
194 }
195
196 smart_str_appendc(buf, ':');
197 php_json_pretty_print_char(buf, options, ' ');
198
199 if (php_json_encode_zval(buf, prop, options, encoder) == FAILURE &&
202 return FAILURE;
203 }
204 }
205
207 if (encoder->depth > encoder->max_depth) {
210 return FAILURE;
211 }
212 }
213 --encoder->depth;
214
215 if (need_comma) {
216 php_json_pretty_print_char(buf, options, '\n');
217 php_json_pretty_print_indent(buf, options, encoder);
218 }
219 smart_str_appendc(buf, '}');
220 return SUCCESS;
221 } else {
222 zend_object *obj = Z_OBJ_P(val);
224 if (obj->ce->num_hooked_props == 0) {
225 recursion_rc = (zend_refcounted *)prop_ht;
226 } else {
227 /* Protecting the object itself is fine here because myht is temporary and can't be
228 * referenced from a different place in the object graph. */
229 recursion_rc = (zend_refcounted *)obj;
230 }
232 }
233
234 if (recursion_rc && GC_IS_RECURSIVE(recursion_rc)) {
236 smart_str_appendl(buf, "null", 4);
238 return FAILURE;
239 }
240
242
243 if (r == PHP_JSON_OUTPUT_ARRAY) {
244 smart_str_appendc(buf, '[');
245 } else {
246 smart_str_appendc(buf, '{');
247 }
248
249 ++encoder->depth;
250
251 uint32_t i = myht ? zend_hash_num_elements(myht) : 0;
252
253 if (i > 0) {
255 zval *data;
256 zend_ulong index;
257
258 ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, data) {
259 zval tmp;
260 ZVAL_UNDEF(&tmp);
261
262 if (r == PHP_JSON_OUTPUT_ARRAY) {
264
265 if (need_comma) {
266 smart_str_appendc(buf, ',');
267 } else {
268 need_comma = 1;
269 }
270
271 php_json_pretty_print_char(buf, options, '\n');
272 php_json_pretty_print_indent(buf, options, encoder);
273 } else if (r == PHP_JSON_OUTPUT_OBJECT) {
274 if (key) {
275 if (ZSTR_VAL(key)[0] == '\0' && ZSTR_LEN(key) > 0 && Z_TYPE_P(val) == IS_OBJECT) {
276 /* Skip protected and private members. */
277 continue;
278 }
279
280 /* data is IS_PTR for properties with hooks. */
281 if (UNEXPECTED(Z_TYPE_P(data) == IS_PTR)) {
283 if ((prop_info->flags & ZEND_ACC_VIRTUAL) && !prop_info->hooks[ZEND_PROPERTY_HOOK_GET]) {
284 continue;
285 }
286 data = zend_read_property_ex(prop_info->ce, Z_OBJ_P(val), prop_info->name, /* silent */ true, &tmp);
287 if (EG(exception)) {
290 return FAILURE;
291 }
292 }
293
294 if (need_comma) {
295 smart_str_appendc(buf, ',');
296 } else {
297 need_comma = 1;
298 }
299
300 php_json_pretty_print_char(buf, options, '\n');
301 php_json_pretty_print_indent(buf, options, encoder);
302
304 options & ~PHP_JSON_NUMERIC_CHECK, encoder) == FAILURE &&
306 buf->s) {
307 ZSTR_LEN(buf->s) -= 4;
308 smart_str_appendl(buf, "\"\"", 2);
309 }
310 } else {
311 if (need_comma) {
312 smart_str_appendc(buf, ',');
313 } else {
314 need_comma = 1;
315 }
316
317 php_json_pretty_print_char(buf, options, '\n');
318 php_json_pretty_print_indent(buf, options, encoder);
319
320 smart_str_appendc(buf, '"');
321 smart_str_append_long(buf, (zend_long) index);
322 smart_str_appendc(buf, '"');
323 }
324
325 smart_str_appendc(buf, ':');
326 php_json_pretty_print_char(buf, options, ' ');
327 }
328
329 if (php_json_encode_zval(buf, data, options, encoder) == FAILURE &&
333 zval_ptr_dtor(&tmp);
334 return FAILURE;
335 }
336 zval_ptr_dtor(&tmp);
338 }
339
341
342 if (encoder->depth > encoder->max_depth) {
346 return FAILURE;
347 }
348 }
349 --encoder->depth;
350
351 /* Only keep closing bracket on same line for empty arrays/objects */
352 if (need_comma) {
353 php_json_pretty_print_char(buf, options, '\n');
354 php_json_pretty_print_indent(buf, options, encoder);
355 }
356
357 if (r == PHP_JSON_OUTPUT_ARRAY) {
358 smart_str_appendc(buf, ']');
359 } else {
360 smart_str_appendc(buf, '}');
361 }
362
364 return SUCCESS;
365}
366/* }}} */
367
369 smart_str *buf, const char *s, size_t len,
370 int options, php_json_encoder *encoder) /* {{{ */
371{
372 unsigned int us;
373 size_t pos, checkpoint;
374 char *dst;
375
376 if (len == 0) {
377 smart_str_appendl(buf, "\"\"", 2);
378 return SUCCESS;
379 }
380
382 double d;
383 int type;
384 zend_long p;
385
386 if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) {
387 if (type == IS_LONG) {
388 smart_str_append_long(buf, p);
389 return SUCCESS;
390 } else if (type == IS_DOUBLE && php_json_is_valid_double(d)) {
391 php_json_encode_double(buf, d, options);
392 return SUCCESS;
393 }
394 }
395
396 }
397 checkpoint = buf->s ? ZSTR_LEN(buf->s) : 0;
398
399 /* pre-allocate for string length plus 2 quotes */
400 smart_str_alloc(buf, len+2, 0);
401 smart_str_appendc(buf, '"');
402
403 pos = 0;
404
405 do {
406 static const uint32_t charmap[8] = {
407 0xffffffff, 0x500080c4, 0x10000000, 0x00000000,
408 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};
409
410 us = (unsigned char)s[pos];
411 if (EXPECTED(!ZEND_BIT_TEST(charmap, us))) {
412 pos++;
413 len--;
414 if (len == 0) {
415 smart_str_appendl(buf, s, pos);
416 break;
417 }
418 } else {
419 if (pos) {
420 smart_str_appendl(buf, s, pos);
421 s += pos;
422 pos = 0;
423 }
424 us = (unsigned char)s[0];
425 if (UNEXPECTED(us >= 0x80)) {
427 us = php_next_utf8_char((unsigned char *)s, len, &pos, &status);
428
429 /* check whether UTF8 character is correct */
430 if (UNEXPECTED(status != SUCCESS)) {
432 /* ignore invalid UTF8 character */
434 /* Use Unicode character 'REPLACEMENT CHARACTER' (U+FFFD) */
436 smart_str_appendl(buf, "\xef\xbf\xbd", 3);
437 } else {
438 smart_str_appendl(buf, "\\ufffd", 6);
439 }
440 } else {
441 ZSTR_LEN(buf->s) = checkpoint;
444 smart_str_appendl(buf, "null", 4);
445 }
446 return FAILURE;
447 }
448
449 /* Escape U+2028/U+2029 line terminators, UNLESS both
450 JSON_UNESCAPED_UNICODE and
451 JSON_UNESCAPED_LINE_TERMINATORS were provided */
454 || us < 0x2028 || us > 0x2029)) {
455 smart_str_appendl(buf, s, pos);
456 } else {
457 /* From http://en.wikipedia.org/wiki/UTF16 */
458 if (us >= 0x10000) {
459 unsigned int next_us;
460
461 us -= 0x10000;
462 next_us = (unsigned short)((us & 0x3ff) | 0xdc00);
463 us = (unsigned short)((us >> 10) | 0xd800);
464 dst = smart_str_extend(buf, 6);
465 dst[0] = '\\';
466 dst[1] = 'u';
467 dst[2] = digits[(us >> 12) & 0xf];
468 dst[3] = digits[(us >> 8) & 0xf];
469 dst[4] = digits[(us >> 4) & 0xf];
470 dst[5] = digits[us & 0xf];
471 us = next_us;
472 }
473 dst = smart_str_extend(buf, 6);
474 dst[0] = '\\';
475 dst[1] = 'u';
476 dst[2] = digits[(us >> 12) & 0xf];
477 dst[3] = digits[(us >> 8) & 0xf];
478 dst[4] = digits[(us >> 4) & 0xf];
479 dst[5] = digits[us & 0xf];
480 }
481 s += pos;
482 len -= pos;
483 pos = 0;
484 } else {
485 s++;
486 switch (us) {
487 case '"':
489 smart_str_appendl(buf, "\\u0022", 6);
490 } else {
491 smart_str_appendl(buf, "\\\"", 2);
492 }
493 break;
494
495 case '\\':
496 smart_str_appendl(buf, "\\\\", 2);
497 break;
498
499 case '/':
501 smart_str_appendc(buf, '/');
502 } else {
503 smart_str_appendl(buf, "\\/", 2);
504 }
505 break;
506
507 case '\b':
508 smart_str_appendl(buf, "\\b", 2);
509 break;
510
511 case '\f':
512 smart_str_appendl(buf, "\\f", 2);
513 break;
514
515 case '\n':
516 smart_str_appendl(buf, "\\n", 2);
517 break;
518
519 case '\r':
520 smart_str_appendl(buf, "\\r", 2);
521 break;
522
523 case '\t':
524 smart_str_appendl(buf, "\\t", 2);
525 break;
526
527 case '<':
529 smart_str_appendl(buf, "\\u003C", 6);
530 } else {
531 smart_str_appendc(buf, '<');
532 }
533 break;
534
535 case '>':
537 smart_str_appendl(buf, "\\u003E", 6);
538 } else {
539 smart_str_appendc(buf, '>');
540 }
541 break;
542
543 case '&':
545 smart_str_appendl(buf, "\\u0026", 6);
546 } else {
547 smart_str_appendc(buf, '&');
548 }
549 break;
550
551 case '\'':
553 smart_str_appendl(buf, "\\u0027", 6);
554 } else {
555 smart_str_appendc(buf, '\'');
556 }
557 break;
558
559 default:
560 ZEND_ASSERT(us < ' ');
561 dst = smart_str_extend(buf, 6);
562 dst[0] = '\\';
563 dst[1] = 'u';
564 dst[2] = '0';
565 dst[3] = '0';
566 dst[4] = digits[(us >> 4) & 0xf];
567 dst[5] = digits[us & 0xf];
568 break;
569 }
570 len--;
571 }
572 }
573 } while (len);
574
575 smart_str_appendc(buf, '"');
576
577 return SUCCESS;
578}
579/* }}} */
580
581static zend_result php_json_encode_serializable_object(smart_str *buf, zval *val, int options, php_json_encoder *encoder) /* {{{ */
582{
584 zend_object *obj = Z_OBJ_P(val);
585 uint32_t *guard = zend_get_recursion_guard(obj);
586 zval retval, fname;
587 zend_result return_code;
588
589 ZEND_ASSERT(guard != NULL);
590
591 if (ZEND_GUARD_IS_RECURSIVE(guard, JSON)) {
594 smart_str_appendl(buf, "null", 4);
595 }
596 return FAILURE;
597 }
598
599 ZEND_GUARD_PROTECT_RECURSION(guard, JSON);
600
601 ZVAL_STRING(&fname, "jsonSerialize");
602
603 if (FAILURE == call_user_function(NULL, val, &fname, &retval, 0, NULL) || Z_TYPE(retval) == IS_UNDEF) {
604 if (!EG(exception)) {
605 zend_throw_exception_ex(NULL, 0, "Failed calling %s::jsonSerialize()", ZSTR_VAL(ce->name));
606 }
607 zval_ptr_dtor(&fname);
608
610 smart_str_appendl(buf, "null", 4);
611 }
613 return FAILURE;
614 }
615
616 if (EG(exception)) {
617 /* Error already raised */
619 zval_ptr_dtor(&fname);
620
622 smart_str_appendl(buf, "null", 4);
623 }
625 return FAILURE;
626 }
627
628 if ((Z_TYPE(retval) == IS_OBJECT) &&
629 (Z_OBJ(retval) == Z_OBJ_P(val))) {
630 /* Handle the case where jsonSerialize does: return $this; by going straight to encode array */
632 return_code = php_json_encode_array(buf, &retval, options, encoder);
633 } else {
634 /* All other types, encode as normal */
635 return_code = php_json_encode_zval(buf, &retval, options, encoder);
637 }
638
640 zval_ptr_dtor(&fname);
641
642 return return_code;
643}
644/* }}} */
645
646static zend_result php_json_encode_serializable_enum(smart_str *buf, zval *val, int options, php_json_encoder *encoder)
647{
649 if (ce->enum_backing_type == IS_UNDEF) {
651 smart_str_appendc(buf, '0');
652 return FAILURE;
653 }
654
655 zval *value_zv = zend_enum_fetch_case_value(Z_OBJ_P(val));
656 return php_json_encode_zval(buf, value_zv, options, encoder);
657}
658
660{
661again:
662 switch (Z_TYPE_P(val))
663 {
664 case IS_NULL:
665 smart_str_appendl(buf, "null", 4);
666 break;
667
668 case IS_TRUE:
669 smart_str_appendl(buf, "true", 4);
670 break;
671 case IS_FALSE:
672 smart_str_appendl(buf, "false", 5);
673 break;
674
675 case IS_LONG:
676 smart_str_append_long(buf, Z_LVAL_P(val));
677 break;
678
679 case IS_DOUBLE:
680 if (php_json_is_valid_double(Z_DVAL_P(val))) {
681 php_json_encode_double(buf, Z_DVAL_P(val), options);
682 } else {
684 smart_str_appendc(buf, '0');
685 }
686 break;
687
688 case IS_STRING:
690
691 case IS_OBJECT:
692 if (instanceof_function(Z_OBJCE_P(val), php_json_serializable_ce)) {
693 return php_json_encode_serializable_object(buf, val, options, encoder);
694 }
695 if (Z_OBJCE_P(val)->ce_flags & ZEND_ACC_ENUM) {
696 return php_json_encode_serializable_enum(buf, val, options, encoder);
697 }
698 /* fallthrough -- Non-serializable object */
700 case IS_ARRAY: {
701 /* Avoid modifications (and potential freeing) of the array through a reference when a
702 * jsonSerialize() method is invoked. */
703 zval zv;
704 int res;
705 ZVAL_COPY(&zv, val);
706 res = php_json_encode_array(buf, &zv, options, encoder);
707 zval_ptr_dtor_nogc(&zv);
708 return res;
709 }
710
711 case IS_REFERENCE:
712 val = Z_REFVAL_P(val);
713 goto again;
714
715 default:
718 smart_str_appendl(buf, "null", 4);
719 }
720 return FAILURE;
721 }
722
723 return SUCCESS;
724}
725/* }}} */
size_t len
Definition apprentice.c:174
bool exception
Definition assert.c:30
strchr(string $haystack, string $needle, bool $before_needle=false)
char s[4]
Definition cdf.c:77
DNS_STATUS status
Definition dns_win32.c:49
zend_ffi_type * type
Definition ffi.c:3812
zval * zv
Definition ffi.c:3975
zend_string * res
Definition ffi.c:4692
zval * val
Definition ffi.c:4262
zend_ffi_ctype_name_buf buf
Definition ffi.c:4685
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
PHPAPI unsigned int php_next_utf8_char(const unsigned char *str, size_t str_len, size_t *cursor, zend_result *status)
Definition html.c:351
PHP_JSON_API zend_class_entry * php_json_serializable_ce
Definition json.c:33
zend_result php_json_encode_zval(smart_str *buf, zval *val, int options, php_json_encoder *encoder)
zend_result php_json_escape_string(smart_str *buf, const char *s, size_t len, int options, php_json_encoder *encoder)
#define PHP_JSON_HASH_UNPROTECT_RECURSION(_tmp_ht)
#define PHP_JSON_HASH_PROTECT_RECURSION(_tmp_ht)
unsigned const char * pos
Definition php_ffi.h:52
#define PG(v)
Definition php_globals.h:31
#define PHP_JSON_NUMERIC_CHECK
Definition php_json.h:67
#define PHP_JSON_UNESCAPED_SLASHES
Definition php_json.h:68
#define PHP_JSON_PARTIAL_OUTPUT_ON_ERROR
Definition php_json.h:71
#define PHP_JSON_INVALID_UTF8_IGNORE
Definition php_json.h:76
#define PHP_JSON_HEX_TAG
Definition php_json.h:62
#define PHP_JSON_FORCE_OBJECT
Definition php_json.h:66
#define PHP_JSON_PRETTY_PRINT
Definition php_json.h:69
@ PHP_JSON_ERROR_UNSUPPORTED_TYPE
Definition php_json.h:51
@ PHP_JSON_ERROR_DEPTH
Definition php_json.h:44
@ PHP_JSON_ERROR_UTF8
Definition php_json.h:48
@ PHP_JSON_ERROR_INF_OR_NAN
Definition php_json.h:50
@ PHP_JSON_ERROR_NON_BACKED_ENUM
Definition php_json.h:54
@ PHP_JSON_ERROR_RECURSION
Definition php_json.h:49
#define PHP_JSON_UNESCAPED_LINE_TERMINATORS
Definition php_json.h:73
#define PHP_JSON_HEX_AMP
Definition php_json.h:63
#define PHP_JSON_OUTPUT_ARRAY
Definition php_json.h:83
#define PHP_JSON_OUTPUT_OBJECT
Definition php_json.h:84
#define PHP_JSON_HEX_APOS
Definition php_json.h:64
#define PHP_JSON_UNESCAPED_UNICODE
Definition php_json.h:70
#define PHP_JSON_HEX_QUOT
Definition php_json.h:65
PHP_JSON_API size_t int options
Definition php_json.h:102
#define PHP_JSON_PRESERVE_ZERO_FRACTION
Definition php_json.h:72
#define PHP_JSON_INVALID_UTF8_SUBSTITUTE
Definition php_json.h:79
struct _php_json_encoder php_json_encoder
unsigned char key[REFLECTION_KEY_LEN]
zend_constant * data
p
Definition session.c:1105
php_json_error_code error_code
uint32_t num_hooked_props
Definition zend.h:207
zend_string * name
Definition zend.h:149
int default_properties_count
Definition zend.h:158
uint32_t enum_backing_type
Definition zend.h:221
struct _zend_property_info ** properties_info_table
Definition zend.h:170
zend_class_entry * ce
Definition zend_types.h:560
ZEND_API zval * zend_read_property_ex(zend_class_entry *scope, zend_object *object, zend_string *name, bool silent, zval *rv)
Definition zend_API.c:5187
#define ZVAL_STRING(z, s)
Definition zend_API.h:956
#define call_user_function(function_table, object, function_name, retval_ptr, param_count, params)
Definition zend_API.h:687
struct _zval_struct zval
strlen(string $string)
#define ZEND_ACC_ENUM
#define OBJ_PROP(obj, offset)
struct _zend_property_info zend_property_info
#define ZEND_ACC_VIRTUAL
ZEND_API ZEND_COLD zend_object * zend_throw_exception_ex(zend_class_entry *exception_ce, zend_long code, const char *format,...)
#define EG(v)
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
#define ZEND_HASH_FOREACH_KEY_VAL_IND(ht, _h, _key, _val)
Definition zend_hash.h:1203
int32_t zend_long
Definition zend_long.h:42
uint32_t zend_ulong
Definition zend_long.h:43
struct _zend_string zend_string
ZEND_API HashTable * zend_get_properties_for(zval *obj, zend_prop_purpose purpose)
ZEND_API uint32_t * zend_get_recursion_guard(zend_object *zobj)
ZEND_API HashTable * zend_std_get_properties(zend_object *zobj)
#define zend_release_properties(ht)
@ ZEND_PROP_PURPOSE_JSON
#define zend_never_inline
#define zend_isinf(a)
#define ZEND_FALLTHROUGH
#define EXPECTED(condition)
#define zend_always_inline
#define ZEND_ASSERT(c)
#define ZEND_BIT_TEST(bits, bit)
#define zend_isnan(a)
#define UNEXPECTED(condition)
struct _zend_array zend_array
@ ZEND_PROPERTY_HOOK_GET
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
ZEND_API char * zend_gcvt(double value, int ndigit, char dec_point, char exponent, char *buf)
#define ZEND_DOUBLE_MAX_LENGTH
Definition zend_strtod.h:48
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define IS_TRUE
Definition zend_types.h:603
#define ZVAL_UNDEF(z)
#define Z_REFVAL_P(zval_p)
#define IS_FALSE
Definition zend_types.h:602
#define Z_STRVAL_P(zval_p)
Definition zend_types.h:975
#define IS_UNDEF
Definition zend_types.h:600
#define Z_ARRVAL_P(zval_p)
Definition zend_types.h:987
#define IS_STRING
Definition zend_types.h:606
#define IS_PTR
Definition zend_types.h:624
#define ZEND_GUARD_IS_RECURSIVE(pg, t)
Definition zend_types.h:645
struct _zend_array HashTable
Definition zend_types.h:386
#define Z_OBJ_P(zval_p)
Definition zend_types.h:990
#define IS_ARRAY
Definition zend_types.h:607
#define Z_OBJ_HT_P(zval_p)
Definition zend_types.h:993
#define IS_DOUBLE
Definition zend_types.h:605
#define Z_PTR_P(zval_p)
#define Z_STRLEN_P(zval_p)
Definition zend_types.h:978
#define IS_NULL
Definition zend_types.h:601
#define Z_OBJCE_P(zval_p)
@ FAILURE
Definition zend_types.h:61
#define IS_OBJECT
Definition zend_types.h:608
#define IS_LONG
Definition zend_types.h:604
#define IS_REFERENCE
Definition zend_types.h:610
#define ZVAL_COPY(z, v)
struct _zend_refcounted zend_refcounted
Definition zend_types.h:95
#define ZEND_GUARD_PROTECT_RECURSION(pg, t)
Definition zend_types.h:646
ZEND_RESULT_CODE zend_result
Definition zend_types.h:64
#define GC_IS_RECURSIVE(p)
Definition zend_types.h:865
#define Z_TYPE(zval)
Definition zend_types.h:659
#define Z_DVAL_P(zval_p)
Definition zend_types.h:969
#define ZEND_GUARD_UNPROTECT_RECURSION(pg, t)
Definition zend_types.h:647
#define Z_LVAL_P(zval_p)
Definition zend_types.h:966
#define Z_OBJ(zval)
Definition zend_types.h:989
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
zval retval
zend_property_info * prop_info