Fix oneof message in array constructor (#5727)

diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index d4c29b5..ba3b11b 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -366,17 +366,29 @@
       const upb_msgdef* submsgdef = upb_fielddef_msgsubdef(field);
       PHP_PROTO_HASHTABLE_VALUE desc_php = get_def_obj(submsgdef);
       Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, desc_php);
-      zend_property_info* property_info;
-      PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg));
+
+      CACHED_VALUE* cached = NULL;
+      if (upb_fielddef_containingoneof(field)) {
+        void* memory = slot_memory(intern->descriptor->layout,
+                                   message_data(intern), field);
+        int property_cache_index =
+            intern->descriptor->layout->fields[upb_fielddef_index(field)]
+                .cache_index;
+        cached = OBJ_PROP(Z_OBJ_P(msg), property_cache_index);
+        *(CACHED_VALUE**)(memory) = cached;
+      } else {
+        zend_property_info* property_info;
+        PHP_PROTO_FAKE_SCOPE_BEGIN(Z_OBJCE_P(msg));
 #if PHP_MAJOR_VERSION < 7
-      property_info =
-          zend_get_property_info(Z_OBJCE_P(msg), &key, true TSRMLS_CC);
+        property_info =
+            zend_get_property_info(Z_OBJCE_P(msg), &key, true TSRMLS_CC);
 #else
-      property_info =
-          zend_get_property_info(Z_OBJCE_P(msg), Z_STR_P(&key), true);
+        property_info =
+            zend_get_property_info(Z_OBJCE_P(msg), Z_STR_P(&key), true);
 #endif
-      PHP_PROTO_FAKE_SCOPE_END;
-      CACHED_VALUE* cached = OBJ_PROP(Z_OBJ_P(msg), property_info->offset);
+        PHP_PROTO_FAKE_SCOPE_END;
+        cached = OBJ_PROP(Z_OBJ_P(msg), property_info->offset);
+      }
 #if PHP_MAJOR_VERSION < 7
       SEPARATE_ZVAL_IF_NOT_REF(cached);
 #endif
diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php
index 93b7b29..a9ad793 100644
--- a/php/tests/generated_class_test.php
+++ b/php/tests/generated_class_test.php
@@ -1447,6 +1447,20 @@
         }
     }
 
+    public function testOneofMessageInArrayConstructor()
+    {
+        $m = new TestMessage([
+            'oneof_message' => new Sub(),
+        ]);
+    }
+
+    public function testOneofStringInArrayConstructor()
+    {
+        $m = new TestMessage([
+            'oneof_string' => 'abc',
+        ]);
+    }
+
     #########################################################
     # Test message equals.
     #########################################################