/// <summary> /// Casts object to given PHP array. /// </summary> /// <param name="instance">Object instance, cannot be <c>null</c>.</param> /// <param name="arr">Array to be filled with object instance properties.</param> public static void InstanceFieldsToPhpArray(object instance, PhpArray arr) { Debug.Assert(instance != null); Debug.Assert(arr != null); // PhpTypeInfo var tinfo = PhpTypeInfoExtension.GetPhpTypeInfo(instance.GetType()); // iterate through type and its base types for (var t = tinfo; t != null; t = t.BaseType) { // iterate through instance fields foreach (var f in t.DeclaredFields.InstanceFields) { arr[FieldAsArrayKey(f, t)] = PhpValue.FromClr(f.GetValue(instance)).DeepCopy(); } // TODO: CLR properties } // PhpArray __runtime_fields var runtime_fields = tinfo.GetRuntimeFields(instance); if (runtime_fields != null && runtime_fields.Count != 0) { // all runtime fields are considered public var enumerator = runtime_fields.GetFastEnumerator(); while (enumerator.MoveNext()) { arr[enumerator.CurrentKey] = enumerator.CurrentValue.DeepCopy(); } } }
/// <summary> /// Reads types from given assembly, /// reflects PHP user types and stores them into <see cref="_typesMap"/>. /// </summary> void UpdateMapNoLock(Assembly ass) { Debug.Assert(ass != null); foreach (var t in ass.GetExportedTypes()) { if (!t.IsAbstract || !t.IsSealed) // => !IsStatic { var tinfo = PhpTypeInfoExtension.GetPhpTypeInfo(t); var rpath = tinfo.RelativePath; if (rpath != null) // => PHP user type { // TODO: skip types from PHAR archives if (_typesMap.TryGetValue(tinfo.Name, out var tinfos)) { // very rare case Array.Resize(ref tinfos, tinfos.Length + 1); tinfos[tinfos.Length - 1] = tinfo; } else { tinfos = new[] { tinfo }; } _typesMap[tinfo.Name] = tinfos; } } } }