]> granicus.if.org Git - php/commitdiff
Add get_mangled_object_vars() function
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 14 May 2019 12:27:10 +0000 (14:27 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 11 Jun 2019 08:28:29 +0000 (10:28 +0200)
UPGRADING
Zend/tests/get_mangled_object_vars.phpt [new file with mode: 0644]
Zend/zend_builtin_functions.c
ext/opcache/Optimizer/zend_func_info.c

index f5695a58a679308340aed040e2dcafb700db076b..6c610858342f0ce984e831002144d68b944e4ef5 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -337,6 +337,12 @@ PHP 7.4 UPGRADE NOTES
 6. New Functions
 ========================================
 
+- Core:
+  . Added get_mangled_object_vars($object) function, which returns the mangled
+    object properties. It returns the same result as (array) $object, with the
+    exception that it ignores overloaded array casts, such as used by
+    ArrayObject.
+
 - OpenSSL:
   . Added openssl_x509_verify(mixed cert, mixed key) function that verifies the
     signature of the certificate using a public key. A wrapper around the
diff --git a/Zend/tests/get_mangled_object_vars.phpt b/Zend/tests/get_mangled_object_vars.phpt
new file mode 100644 (file)
index 0000000..7355485
--- /dev/null
@@ -0,0 +1,49 @@
+--TEST--
+get_mangled_object_vars() function
+--FILE--
+<?php
+
+class A {
+    public $pub = 1;
+    protected $prot = 2;
+    private $priv = 3;
+}
+class B extends A {
+    private $priv = 4;
+}
+
+$obj = new B;
+$obj->dyn = 5;
+$obj->{"6"} = 6;
+
+var_export(get_mangled_object_vars($obj));
+echo "\n";
+
+class AO extends ArrayObject {
+    private $priv = 1;
+}
+
+$ao = new AO(['x' => 'y']);
+$ao->dyn = 2;
+var_export(get_mangled_object_vars($ao));
+echo "\n";
+var_export((array) $ao);
+echo "\n";
+
+?>
+--EXPECT--
+array (
+  '' . "\0" . 'B' . "\0" . 'priv' => 4,
+  'pub' => 1,
+  '' . "\0" . '*' . "\0" . 'prot' => 2,
+  '' . "\0" . 'A' . "\0" . 'priv' => 3,
+  'dyn' => 5,
+  6 => 6,
+)
+array (
+  '' . "\0" . 'AO' . "\0" . 'priv' => 1,
+  'dyn' => 2,
+)
+array (
+  'x' => 'y',
+)
index 6275e9997f69df8835324d0b03ba69d95b3b2aa2..2d0db8f7126b74d49e889c5bd5b73cd2aa61bc51 100644 (file)
@@ -56,6 +56,7 @@ static ZEND_FUNCTION(is_subclass_of);
 static ZEND_FUNCTION(is_a);
 static ZEND_FUNCTION(get_class_vars);
 static ZEND_FUNCTION(get_object_vars);
+static ZEND_FUNCTION(get_mangled_object_vars);
 static ZEND_FUNCTION(get_class_methods);
 static ZEND_FUNCTION(trigger_error);
 static ZEND_FUNCTION(set_error_handler);
@@ -145,6 +146,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_get_object_vars, 0, 0, 1)
        ZEND_ARG_INFO(0, obj)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_get_mangled_object_vars, 0, 0, 1)
+       ZEND_ARG_INFO(0, obj)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_get_class_methods, 0, 0, 1)
        ZEND_ARG_INFO(0, class)
 ZEND_END_ARG_INFO()
@@ -264,6 +269,7 @@ static const zend_function_entry builtin_functions[] = { /* {{{ */
        ZEND_FE(is_a,                   arginfo_is_subclass_of)
        ZEND_FE(get_class_vars,         arginfo_get_class_vars)
        ZEND_FE(get_object_vars,        arginfo_get_object_vars)
+       ZEND_FE(get_mangled_object_vars,        arginfo_get_mangled_object_vars)
        ZEND_FE(get_class_methods,      arginfo_get_class_methods)
        ZEND_FE(trigger_error,          arginfo_trigger_error)
        ZEND_FALIAS(user_error,         trigger_error,          arginfo_trigger_error)
@@ -1238,6 +1244,31 @@ ZEND_FUNCTION(get_object_vars)
 }
 /* }}} */
 
+/* {{{ proto array get_mangled_object_vars(object obj)
+   Returns an array of mangled object properties. Does not respect property visibility. */
+ZEND_FUNCTION(get_mangled_object_vars)
+{
+       zval *obj;
+       HashTable *properties;
+
+       ZEND_PARSE_PARAMETERS_START(1, 1)
+               Z_PARAM_OBJECT(obj)
+       ZEND_PARSE_PARAMETERS_END();
+
+       properties = Z_OBJ_HT_P(obj)->get_properties(obj);
+       if (!properties) {
+               ZVAL_EMPTY_ARRAY(return_value);
+               return;
+       }
+
+       properties = zend_proptable_to_symtable(properties,
+               (Z_OBJCE_P(obj)->default_properties_count ||
+                Z_OBJ_P(obj)->handlers != &std_object_handlers ||
+                GC_IS_RECURSIVE(properties)));
+       RETURN_ARR(properties);
+}
+/* }}} */
+
 static int same_name(zend_string *key, zend_string *name) /* {{{ */
 {
        zend_string *lcname;
index 02b0b7b8072a24873ccdc51a3299f02ee1699f0e..78985275ebba3c587e24345bf8f7b95849023612 100644 (file)
@@ -239,6 +239,7 @@ static const func_info_t func_infos[] = {
        F0("is_a",                    MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE), // TODO: inline
        F1("get_class_vars",          MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF),
        FN("get_object_vars",         MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF),
+       FN("get_mangled_object_vars", MAY_BE_NULL | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF),
        F1("get_class_methods",       MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING),
        F0("method_exists",           MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),
        F0("property_exists",         MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_TRUE),