private PhpArray ReadArray(bool assoc, bool num) { PhpArray arr = new PhpArray(); for (int i = 0; i < this.m_dr.FieldCount; i++) { if (this.m_dr.IsDBNull(i)) { if (assoc) { arr.Add(this.m_dr_names[i], PhpValue.Null); } if (num) { arr.Add(i, PhpValue.Null); } } else { var value = PhpValue.FromClr(this.m_dr.GetValue(i)); if (assoc) { arr.Add(this.m_dr_names[i], value); } if (num) { arr.Add(i, value); } } } return(arr); }
/// <summary> /// Gets a contents of a specified cell from a specified query result resource. /// </summary> /// <param name="resultHandle">Query result resource.</param> /// <param name="row">Row index.</param> /// <param name="field">Column (field) integer index or string name.</param> /// <returns>The value of the cell or a <B>null</B> reference (<B>false</B> in PHP) on failure (invalid resource or row/field index/name).</returns> /// <remarks> /// Result is affected by run-time quoting. /// </remarks> public static PhpValue mysql_result(PhpResource resultHandle, int row, PhpValue field) { var result = MySqlResultResource.ValidResult(resultHandle); if (result == null) { return(PhpValue.False); } string field_name; object field_value; if (field.IsEmpty) { field_value = result.GetFieldValue(row, result.CurrentFieldIndex); } else if ((field_name = PhpVariable.AsString(field)) != null) { field_value = result.GetFieldValue(row, field_name); } else { field_value = result.GetFieldValue(row, (int)field.ToLong()); } return(PhpValue.FromClr(field_value)); // TODO: Core.Convert.Quote(field_value, context); }
/// <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> /// Evaluates the given XPath expression and returns a typed result if possible. /// </summary> /// <param name="expr">The expression to evaluate.</param> /// <param name="contextnode">The context node for doing relative XPath queries. By default, the queries are /// relative to the root element.</param> /// <param name="registerNodeNS">Can be specified to disable automatic registration of the context node namespace.</param> /// <returns>A typed result if possible or a <see cref="DOMNodeList"/> containing all nodes matching the /// given <paramref name="expr"/>.</returns> public PhpValue evaluate(string expr, DOMNode contextnode = null, bool registerNodeNS = true) { XPathNavigator navigator = GetNavigator(contextnode); if (navigator == null) { return(PhpValue.Create(false)); } var nsManager = registerNodeNS ? NamespaceManagerFull : NamespaceManagerExplicit; object result; try { result = navigator.Evaluate(expr, nsManager); } catch (Exception ex) { DOMException.Throw(ExceptionCode.SyntaxError, ex.Message); return(PhpValue.Create(false)); } // the result can be bool, double, string, or iterator XPathNodeIterator iterator = result as XPathNodeIterator; if (iterator != null) { return(PhpValue.FromClass(IteratorToList(iterator))); } else { return(PhpValue.FromClr(result)); } }
public object this[int index] { get { var enumerator = PhpSession.GetFastEnumerator(); while (enumerator.MoveNext()) { if (0 == index--) { return(enumerator.CurrentValue.ToClr()); } } throw IndexOutOfRangeException(); } set { var enumerator = PhpSession.GetFastEnumerator(); while (enumerator.MoveNext()) { if (0 == index--) { Operators.SetValue(ref enumerator.CurrentValue, PhpValue.FromClr(value)); return; } } throw IndexOutOfRangeException(); } }
public static PhpArray collection2array(Context ctx, Dictionary <string, object> dic) { PhpArray arr = PhpArray.NewEmpty(); foreach (KeyValuePair <string, object> item in dic) { if (item.Value is List <object> ) { arr.Add(item.Key, collection2array(ctx, item.Value as List <object>)); } else if (item.Value is Dictionary <string, object> ) { arr.Add(item.Key, collection2array(ctx, item.Value as Dictionary <string, object>)); } else { int intKey = 0; dynamic key; if (int.TryParse(item.Key, out intKey)) { key = intKey; } else { key = item.Key; } arr.Add(new IntStringKey(key), PhpValue.FromClr(item.Value)); } } return(arr); }
/// <summary> /// Gets a contents of a specified cell from a specified query result resource. /// </summary> /// <param name="ctx">PHP context.</param> /// <param name="resultHandle">Query result resource.</param> /// <param name="rowIndex">Row index.</param> /// <param name="field">Column (field) integer index or string name.</param> /// <returns>The value of the cell or <B>false</B> on failure (invalid resource or row index).</returns> public static PhpValue mssql_result(Context ctx, PhpResource resultHandle, int rowIndex, PhpValue field) { var result = PhpSqlDbResult.ValidResult(resultHandle); if (result == null) { return(PhpValue.False); } string field_name; object field_value; if (field.IsNull) { field_value = result.GetFieldValue(rowIndex, result.CurrentFieldIndex); } else if ((field_name = PhpVariable.AsString(field)) != null) { field_value = result.GetFieldValue(rowIndex, field_name); } else { field_value = result.GetFieldValue(rowIndex, (int)field.ToLong()); } if (field_value == null) { return(PhpValue.False); } return(PhpValue.FromClr(field_value)); // Core.Convert.Quote(field_value, context); }
/// <summary> /// Returns a PhpArray containing data from collumns in the row and move to the next row. /// Returns false if there are no more rows. /// </summary> /// <param name="intKeys">Whether to add integer keys.</param> /// <param name="stringKeys">Whether to add string keys.</param> /// <returns>A PHP array containing the data.</returns> public PhpArray FetchArray(bool intKeys, bool stringKeys) { if (TryReadRow(out object[] oa, out string[] names)) { var array = new PhpArray(names.Length); for (int i = 0; i < names.Length; i++) { var quoted = PhpValue.FromClr(oa[i]); // Core.Utilities.StringUtils.AddDbSlashes(oa[i].ToString()); if (intKeys) { array[i] = quoted; } if (stringKeys) { array[names[i]] = quoted; } } return(array); } else { return(null); } }
private protected PhpArray ReadNamed(int from = 0) { if (Result.TryReadRow(out var oa, out var names)) { var arr = new PhpArray(oa.Length); for (int i = from; i < oa.Length; i++) { var value = PhpValue.FromClr(oa[i]); ref var bucket = ref arr.GetItemRef(new IntStringKey(names[i])); if (Operators.IsSet(bucket)) { var nested = bucket.AsArray(); if (nested != null) { nested.Add(value); } else { bucket = new PhpArray(2) { bucket, value }; } } else { bucket = value; } } return(arr); }
public virtual PhpValue call(Context ctx, PhpString name, PhpArray args) { string responseJson = null; try { // 创建ID RpcId rpcId = new RpcId(Guid.NewGuid().ToString()); // 将List<object>或者Dictionary<string, object>隐式转换成RpcParameters RpcParameters rpcParameters = ArrayUtil.array2collection(ctx, args); // 构建请求 RpcRequest rpcRequest = new RpcRequest(rpcId, name.ToString(ctx), rpcParameters); // 发送请求 RpcResponse rpcResponse = _client.SendRequestAsync(rpcRequest, "").Result; // 获取响应 PhpValue returnJson = JsonSerialization.json_decode(ctx, new PhpString(rpcResponse.Result.ToString()), true); return(PhpValue.Create(new PhpArray() { { new IntStringKey("id"), PhpValue.Create(rpcResponse.Id.StringValue) }, { new IntStringKey("jsonrpc"), PhpValue.Create("2.0") }, { new IntStringKey("result"), !returnJson.IsArray ? PhpValue.FromClr(rpcResponse.Result) : returnJson }, })); } catch (Exception ex) { if (ex.InnerException is RpcClientInvalidStatusCodeException) { responseJson = (ex.InnerException as RpcClientInvalidStatusCodeException)?.Content; } } return(String.IsNullOrEmpty(responseJson) ? PhpValue.False : JsonSerialization.json_decode(ctx, new PhpString(responseJson), true)); }
/// <summary> /// Returns the current row of a result set as an object. /// </summary> public object fetch_object(string class_name = null, PhpArray class_params = null) { if (string.IsNullOrEmpty(class_name) || nameof(stdClass).Equals(class_name, StringComparison.OrdinalIgnoreCase)) { return(_result.FetchStdClass()); } if (_result.TryReadRow(out object[] oa, out string[] names)) { // instantiate class dynamically: var ctx = _result.Connection.Context; var phpt = ctx.GetDeclaredTypeOrThrow(class_name, autoload: true); var obj = phpt.Creator(ctx, (class_params == null) ? Array.Empty <PhpValue>() : class_params.GetValues()); // set object properties using reflection: for (int i = 0; i < names.Length; i++) { // TODO: Operators.PropertySetValue( obj, names[i], FromClr(oa[i]) ); var p = TypeMembersUtils.GetDeclaredProperty(phpt, names[i]) ?? TypeMembersUtils.GetRuntimeProperty(phpt, names[i], obj); p.SetValue(ctx, obj, PhpValue.FromClr(oa[i])); } // return(obj); } else { return(null); } }
protected override void FetchCurrent(ref PhpValue key, ref PhpValue value) { var entry = _enumerator.Current; key = PhpValue.FromClr(entry.Key); value = PhpValue.FromClr(entry.Value); }
/// <summary> /// Retrieves a value of a constant. /// </summary> /// <param name="ctx">Current runtime context.</param> /// <param name="name">The name of the constant.</param> /// <returns>The value.</returns> public static PhpValue constant(Context ctx, string name) { var sepidx = name.IndexOf(':'); if (sepidx < 0) { // a global constant return(ctx.GetConstant(name)); } else { // a class constant if (sepidx + 1 < name.Length && name[sepidx + 1] == ':') { var cname = name.Substring(sepidx + 2); for (var tdecl = ctx.GetDeclaredType(name.Remove(sepidx), true); tdecl != null; tdecl = tdecl.BaseType) { object value; if (tdecl.DeclaredFields.TryGetConstantValue(ctx, cname, out value)) { return(PhpValue.FromClr(value)); } } } return(PhpValue.Void); } }
/// <summary> /// Returns a PhpArray containing data from collumns in the row and move to the next row. /// Returns false if there are no more rows. /// </summary> /// <param name="intKeys">Whether to add integer keys.</param> /// <param name="stringKeys">Whether to add string keys.</param> /// <returns>A PHP array containing the data.</returns> public PhpArray FetchArray(bool intKeys, bool stringKeys) { // no more data if (!this.ReadRow()) { return(null); } Debug.Assert(currentRowIndex >= 0 && currentRowIndex < RowCount); var oa = CurrentSet.Rows[currentRowIndex]; var row = new PhpArray(FieldCount); for (int i = 0; i < FieldCount; i++) { var quoted = PhpValue.FromClr(oa[i]); // Core.Utilities.StringUtils.AddDbSlashes(oa[i].ToString()); if (intKeys) { row[i] = quoted; } if (stringKeys) { row[CurrentSet.Names[i]] = quoted; } } return(row); }
/// <summary> /// Gets a contents of a specified cell from a specified query result resource. /// </summary> /// <param name="resultHandle">Query result resource.</param> /// <param name="row">Row index.</param> /// <param name="field">Column (field) integer index or string name.</param> /// <returns>The value of the cell or a <B>null</B> reference (<B>false</B> in PHP) on failure (invalid resource or row/field index/name).</returns> /// <remarks> /// Result is affected by run-time quoting. /// </remarks> public static PhpValue mysql_result(PhpResource resultHandle, int row, PhpValue field = default) { var result = MySqlResultResource.ValidResult(resultHandle); if (result == null) { return(PhpValue.False); } object field_value; if (!Operators.IsSet(field)) { field_value = result.GetFieldValue(row, result.CurrentFieldIndex); } else if (field.IsString(out var field_name)) { field_value = result.GetFieldValue(row, field_name); } else { field_value = result.GetFieldValue(row, (int)field); } return(PhpValue.FromClr(field_value)); // TODO: Core.Convert.Quote(field_value, context); }
/// <summary> /// Adds PHP handler to the event. /// </summary> public void addEventElapsed(Context ctx, IPhpCallable handler) { void HandlerDelegate(object sender, ElapsedEventArgs args) { handler.Invoke(ctx, PhpValue.FromClr(sender), PhpValue.FromClass(args)); } timer.Elapsed += new System.Timers.ElapsedEventHandler(HandlerDelegate); }
public override PhpArray Load(IHttpPhpContext webctx) { var ctx = (Context)webctx; var httpContext = GetHttpContext(webctx); EnsureSessionId(httpContext); var session = httpContext.Session; var underlyingstate = session.GetContainer(); // use the underlying IHttpSessionState because Session will be changed to our handler then // session contains both ASP.NET session and PHP session variables PhpArray result = null; // serialized $_SESSION array if (session[PhpSessionVars] is byte[] data && data.Length != 0) { if (Serializer.TryDeserialize(ctx, data, out var value)) { result = value.ArrayOrNull(); } } foreach (string name in session) { if (name == PhpSessionVars) { continue; } if (result == null) { result = new PhpArray(session.Count); } if (underlyingstate != null) { result[name] = new SessionValue(underlyingstate, name); } else { // in case we won't get IHttpSessionState: var value = PhpValue.FromClr(session[name]); //if (value.IsObject) //{ // // NOTE: values that are bound to specific Context are stored using PHP serialization into PhpSessionVars array // // CONSIDER: what if value has a reference to a Context - clone the value? //} result[name] = value; } } return(result ?? PhpArray.NewEmpty()); }
/// <summary> /// Adds the event listener with .NET args type specification. /// </summary> public static void AddEventListener <TEventArgs>(Context ctx, object target, string eventName, IPhpCallable handler) { void HandlerDelegate(object sender, TEventArgs args) { handler.Invoke(ctx, PhpValue.FromClr(sender), PhpValue.FromClass(args)); } var eventReflection = target.GetType().GetEvent(eventName); eventReflection.AddEventHandler(target, (EventHandler <TEventArgs>)HandlerDelegate); }
/// <summary> /// Fetch single scalar value from the result set. /// </summary> public PhpValue fetch_column(int column = 0) { if (_result.CheckFieldIndex(column)) // TODO: throw ValueError { if (_result.TryReadRow(out var oa, out _)) { return(PhpValue.FromClr(oa[column])); } } return(PhpValue.False); }
public void ClrConversion() { // CLR -> Value -> CLR var objects = new object[] { 0L, 1L, true, 1.2, new object(), "Hello", new PhpArray() }; var values = PhpValue.FromClr(objects); Assert.AreEqual(objects.Length, values.Length); for (int i = 0; i < objects.Length; i++) { Assert.AreEqual(objects[i], values[i].ToClr()); } }
public override PhpArray Load(IHttpPhpContext webctx) { var ctx = (Context)webctx; var httpContext = GetHttpContext(webctx); EnsureSessionId(httpContext); var session = httpContext.Session; // session contains both ASP.NET session and PHP session variables PhpArray result = null; // serialized $_SESSION array if (session[PhpSessionVars] is byte[] data) { if (Serializer.TryDeserialize(ctx, data, out var value)) { result = value.ArrayOrNull(); } } // .NET session items if (session.Mode == SessionStateMode.InProc) { foreach (string name in session) { if (name == PhpSessionVars) { continue; } if (result == null) { result = new PhpArray(session.Count); } var value = PhpValue.FromClr(session[name]); //if (value.IsObject) //{ // // CONSIDER: what if value has reference to a different Context - change it? clone the value? do not store it into the session in the first place? //} result[name] = value; } } else { // TODO: deserialize .NET session variables // CONSIDER: isn't it too much of overhead? } return(result ?? PhpArray.NewEmpty()); }
public override CompileResult Execute(IEnumerable <FunctionArgument> arguments, ParsingContext context) { // 参数转换 // 1. 转换EPPlus内部的类型 // 2. 转换EPPlus4PHP的类型(PhpValue类型,不用处理) PhpArray args = PhpArray.NewEmpty(); foreach (FunctionArgument arg in arguments) { PhpValue val = PhpValue.Null; if (arg.Value is PhpValue v) { val = v; } else /* EPPlus内部类型 */ { if (arg.IsExcelRange && arg.Value is EpplusExcelDataProvider.RangeInfo rangeInfo) { string rangeAddress = rangeInfo.Address.Address; Range range = new Range(rangeInfo.Worksheet.Cells[rangeAddress], _package.is1base); val = PhpValue.FromClr(range); } else { val = PhpValue.FromClr(arg.Value); } } args.AddValue(val); } // 上下文 PhpArray contextArr = PhpArray.NewEmpty(); // context.Scopes.Current.Address对于区域地址有问题 // 暂时不用 // contextArr.Add(context.Scopes.Current.Address); // 获取结果 PhpValue ret = _callback.__invoke(PhpValue.Create(args), PhpValue.Create(contextArr)); // 结果可能存在两种类型 // 1. 可直接转换的类型或者可直接字面表达的值 // 2. Result类型 // 将结果转换为Result类型 // 将Result转换为EPPlus的Result类型 // object val = null; // ExcelDataType dt = ExcelDataType.Empty; return(CreateResult(ret, ExcelDataType.Unknown)); }
/// <summary> /// Returns a single column from the next row of a result set. /// </summary> /// <param name="column_number">0-indexed number of the column you wish to retrieve from the row. If no value is supplied, PDOStatement::fetchColumn() fetches the first column</param> /// <returns>Single column from the next row of a result set or FALSE if there are no more rows</returns> public virtual PhpValue fetchColumn(int?column_number = default) { if (Result.CheckRowIndex(Result.CurrentRowIndex)) { int idx = column_number.HasValue ? column_number.Value : Result.FetchNextField(); if (Result.CheckFieldIndex(idx)) { return(PhpValue.FromClr(Result.GetFieldValue(Result.CurrentRowIndex, idx))); } } // return(PhpValue.False); }
public void SetValue(object value) { var x = PhpValue.FromClr(value); // if (Variable.IsAlias) { Variable.Alias.Value = Type.HasValue ? ConvertParam(x, Type.Value) : x; } else { throw new InvalidOperationException(); } }
/// <summary> /// Converts a W3C .NET object to the corresponding W3C PHP object. /// </summary> public static PhpValue DotNetToPhp(object arg) { // Result Tree Fragment (XSLT) / Node (XPath) XPathNavigator nav = arg as XPathNavigator; if (nav != null) { return(PhpValue.FromClass(DOMNode.Create(nav.UnderlyingObject as XmlNode))); } // Node Set (XPath) - XPathNavigator[] XPathNavigator[] navs = arg as XPathNavigator[]; if (navs != null) { PhpArray array = new PhpArray(navs.Length); for (int i = 0; i < navs.Length; i++) { var node = DOMNode.Create(navs[i].UnderlyingObject as XmlNode); if (node != null) { array.Add(node); } } return(PhpValue.Create(array)); } // Node Set (XPath) - XPathNodeIterator XPathNodeIterator iter = arg as XPathNodeIterator; if (iter != null) { PhpArray array = new PhpArray(); foreach (XPathNavigator navigator in iter) { var node = DOMNode.Create(navigator.UnderlyingObject as XmlNode); if (node != null) { array.Add(node); } } return(PhpValue.Create(array)); } // Number (XPath), Boolean (XPath), String (XPath) return(PhpValue.FromClr(arg)); }
public static List <ReflectionParameter> ResolveReflectionParameters(ReflectionFunctionAbstract function, MethodInfo[] overloads) { var parameters = new List <ReflectionParameter>(); for (int mi = 0; mi < overloads.Length; mi++) { var ps = overloads[mi].GetParameters(); var implicitps = Core.Reflection.ReflectionUtils.ImplicitParametersCount(ps); // number of implicit compiler-generated parameters int pi = implicitps; for (; pi < ps.Length; pi++) { var p = ps[pi]; var allowsNull = p.IsNullable(); var defaultValue = p.HasDefaultValue ? PhpValue.FromClr(p.RawDefaultValue) : default(PhpValue); var isVariadic = p.GetCustomAttribute <ParamArrayAttribute>() != null; int index = pi - implicitps; if (index == parameters.Count) { if (mi != 0) // we are adding and optional parameter! { if (defaultValue.IsDefault) // optional parameter has not specified default value, set void so it is treated as optional { defaultValue = PhpValue.Void; } } parameters.Add(new ReflectionParameter(function, index, p.ParameterType, allowsNull, isVariadic, p.Name, defaultValue)); } else { // update existing Debug.Assert(index < parameters.Count); parameters[index].AddOverload(p.ParameterType, allowsNull, isVariadic, p.Name, defaultValue); } } // remaining parameters have to be marked as optional for (var index = pi - implicitps; index < parameters.Count; index++) { parameters[index].SetOptional(); } } // return(parameters); }
/// <inheritDoc /> public PhpValue getAttribute(int attribute) { if (Enum.IsDefined(typeof(PDO_ATTR), attribute)) { object value = this.getAttribute((PDO_ATTR)attribute); return(PhpValue.FromClr(value)); } if (attribute > (int)PDO_ATTR.ATTR_DRIVER_SPECIFIC) { return(this.m_driver.GetAttribute(this, attribute)); } //TODO : what to do on unknown attribute ? return(PhpValue.Null); }
/// <summary> /// Gets fields as PHP array with associative string keys. /// </summary> public PhpArray FetchAssocArray() { if (TryReadRow(out object[] oa, out string[] names)) { var array = new PhpArray(names.Length); for (int i = 0; i < names.Length; i++) { array[names[i]] = PhpValue.FromClr(oa[i]); } return(array); } else { return(null); } }
public object this[string name] { get { return(PhpSession.TryGetValue(name, out var value) ? value.ToClr() : UnderlayingContainer[name]); } set { PhpSession[name] = PhpValue.FromClr(value); // copy to underlaying container as well // in case PhpSession won't get persisted UnderlayingContainer[name] = value; } }
/// <summary> /// Enumerates instance fields of given object. /// </summary> /// <param name="instance">Object which fields will be enumerated.</param> /// <param name="keyFormatter">Function converting field to a <typeparamref name="TKey"/>.</param> /// <param name="keyFormatter2">Function converting </param> /// <param name="predicate">Optional. Predicate filtering instance fields.</param> /// <param name="ignoreRuntimeFields">Whether to ignore listing runtime fields.</param> /// <returns>Enumeration of fields and their values, including runtime fields.</returns> /// <typeparam name="TKey">Enumerated pairs key. Usually <see cref="IntStringKey"/>.</typeparam> public static IEnumerable <KeyValuePair <TKey, PhpValue> > EnumerateInstanceFields <TKey>(object instance, Func <FieldInfo, PhpTypeInfo, TKey> keyFormatter, Func <IntStringKey, TKey> keyFormatter2, Func <FieldInfo, bool> predicate = null, bool ignoreRuntimeFields = false) { Debug.Assert(instance != null); // PhpTypeInfo var tinfo = instance.GetPhpTypeInfo(); // 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) { // perform visibility check if (predicate == null || predicate(f)) { yield return(new KeyValuePair <TKey, PhpValue>( keyFormatter(f, t), PhpValue.FromClr(f.GetValue(instance)))); } } // TODO: CLR properties } // PhpArray __runtime_fields if (ignoreRuntimeFields == false) { Debug.Assert(keyFormatter2 != null); var runtime_fields = tinfo.GetRuntimeFields(instance); if (runtime_fields != null && runtime_fields.Count != 0) { // all runtime fields are considered public, // no visibility check needed var enumerator = runtime_fields.GetFastEnumerator(); while (enumerator.MoveNext()) { yield return(new KeyValuePair <TKey, PhpValue>(keyFormatter2(enumerator.CurrentKey), enumerator.CurrentValue)); } } } }