Beispiel #1
0
        public static PhpArray array_fill_keys(PhpArray keys, PhpValue value)
        {
            if (keys == null)
            {
                // PhpException.ArgumentNull("keys");
                // return null;
                throw new ArgumentNullException();
            }

            var result = new PhpArray(keys.Count);
            var iterator = keys.GetFastEnumerator();
            while (iterator.MoveNext())
            {
                IntStringKey key;
                if (Core.Convert.TryToIntStringKey(iterator.CurrentValue, out key) && !result.ContainsKey(key))
                {
                    result[key] = value;
                }
            }

            // makes deep copies of all added items:
            //result.InplaceCopyOnReturn = true;
            return result;
        }
Beispiel #2
0
        /// <summary>
        /// Adds items of "array" to "result" merging those whose string keys are the same.
        /// </summary>
        private static bool MergeRecursiveInternal(PhpArray/*!*/ result, PhpArray/*!*/ array, bool deepCopy)
        {
            var visited = new HashSet<object>();    // marks arrays that are being visited

            using (var iterator = array.GetFastEnumerator())
                while (iterator.MoveNext())
                {
                    var entry = iterator.Current;
                    if (entry.Key.IsString)
                    {
                        if (result.ContainsKey(entry.Key))
                        {
                            // the result array already contains the item => merging take place
                            var xv = result[entry.Key];
                            var y = entry.Value.GetValue();

                            // source item:
                            PhpValue x = xv.GetValue();

                            // if x is not a reference then we can reuse the ax array for the result
                            // since it has been deeply copied when added to the resulting array:
                            PhpArray item_result = (deepCopy && x.IsArray && !xv.IsAlias) ? x.Array : new PhpArray();

                            if (x.IsArray && y.IsArray)
                            {
                                var ax = x.Array;
                                var ay = y.Array;

                                if (ax != item_result)
                                    ax.AddTo(item_result, deepCopy);

                                if (visited.Add(ax) == false && visited.Add(ay) == false)
                                    return false;

                                // merges ay to the item result (may lead to stack overflow, 
                                // but only with both arrays recursively referencing themselves - who cares?):
                                bool finite = MergeRecursiveInternal(item_result, ay, deepCopy);

                                visited.Remove(ax);
                                visited.Remove(ay);

                                if (!finite) return false;
                            }
                            else
                            {
                                if (x.IsArray)
                                {
                                    if (x.Array != item_result)
                                        x.Array.AddTo(item_result, deepCopy);
                                }
                                else
                                {
                                    /*if (x != null)*/
                                    item_result.Add(deepCopy ? x.DeepCopy() : x);
                                }

                                if (y.IsArray) y.Array.AddTo(item_result, deepCopy);
                                else /*if (y != null)*/ item_result.Add(deepCopy ? y.DeepCopy() : y);
                            }

                            result[entry.Key] = PhpValue.Create(item_result);
                        }
                        else
                        {
                            // PHP does no dereferencing when items are not merged:
                            result.Add(entry.Key, (deepCopy) ? entry.Value.DeepCopy() : entry.Value);
                        }
                    }
                    else
                    {
                        // PHP does no dereferencing when items are not merged:
                        result.Add((deepCopy) ? entry.Value.DeepCopy() : entry.Value);
                    }
                }

            return true;
        }
Beispiel #3
0
        /// <summary>
        /// Checks if a key exists in the array.
        /// </summary>
        /// <param name="key">The key to be searched for.</param>
        /// <param name="array">The array where to search for the key.</param>
        /// <returns>Whether the <paramref name="key"/> exists in the <paramref name="array"/>.</returns>
        /// <remarks><paramref name="key"/> is converted before the search.</remarks>
        /// <exception cref="PhpException"><paramref name="array"/> argument is a <B>null</B> reference (Warning).</exception>
        /// <exception cref="PhpException"><paramref name="key"/> has type which is illegal for array key.</exception>
        public static bool array_key_exists(IntStringKey key, PhpArray array)
        {
            if (array == null)
            {
                // TODO: PhpException.ArgumentNull("array");
                return false;
            }

            return array.ContainsKey(key);

            //if (Core.Convert.ObjectToArrayKey(key, out array_key))
            //    return array.ContainsKey(array_key);

            //PhpException.Throw(PhpError.Warning, CoreResources.GetString("illegal_offset_type"));
            //return false;
        }
        /// <summary>
        /// Loads $_SERVER from <see cref="HttpRequest.ServerVariables"/>.
        /// </summary>
        protected override PhpArray InitServerVariable()
        {
            var array = new PhpArray(32);

            var request         = _httpctx.Request;
            var serverVariables = request.ServerVariables;

            // adds variables defined by ASP.NET and IIS:
            foreach (string name in serverVariables)
            {
                // gets all values associated with the name:
                string[] values = serverVariables.GetValues(name);

                if (values == null)
                {
                    continue;   // http://phalanger.codeplex.com/workitem/30132
                }
                // adds all items:
                if (name != null)
                {
                    foreach (string value in values)
                    {
                        Superglobals.AddVariable(array, name, value, null);
                    }
                }
                else
                {
                    // if name is null, only name of the variable is stated:
                    // e.g. for GET variables, URL looks like this: ...&test&...
                    // we add the name of the variable and an emtpy string to get what PHP gets:
                    foreach (string value in values)
                    {
                        Superglobals.AddVariable(array, value, string.Empty, null);
                    }
                }
            }

            //// adds argv, argc variables:
            //if (RegisterArgcArgv)
            //{
            //    array["argv"] = PhpValue.Create(new PhpArray(1) { request.QueryString });
            //    array["argc"] = PhpValue.Create(0);
            //}

            // additional variables defined in PHP manual:
            array["PHP_SELF"] = (PhpValue)request.Path;

            try
            {
                array["DOCUMENT_ROOT"] = (PhpValue)request.MapPath("/"); // throws exception under mod_aspdotnet
            }
            catch
            {
                array["DOCUMENT_ROOT"] = PhpValue.Null;
            }

            array["SERVER_ADDR"]     = (PhpValue)serverVariables["LOCAL_ADDR"];
            array["REQUEST_URI"]     = (PhpValue)request.RawUrl;
            array["REQUEST_TIME"]    = (PhpValue)Utilities.DateTimeUtils.UtcToUnixTimeStamp(_httpctx.Timestamp.ToUniversalTime());
            array["SCRIPT_FILENAME"] = (PhpValue)request.PhysicalPath;

            //IPv6 is the default in IIS7, convert to an IPv4 address (store the IPv6 as well)
            if (request.UserHostAddress.Contains(":"))
            {
                array["REMOTE_ADDR_IPV6"] = (PhpValue)request.UserHostAddress;

                if (request.UserHostAddress == "::1")
                {
                    array["REMOTE_ADDR"] = array["SERVER_ADDR"] = (PhpValue)"127.0.0.1";
                }
                else
                {
                    foreach (IPAddress IPA in Dns.GetHostAddresses(request.UserHostAddress))
                    {
                        if (IPA.AddressFamily.ToString() == "InterNetwork")
                        {
                            array["REMOTE_ADDR"] = (PhpValue)IPA.ToString();
                            break;
                        }
                    }
                }
            }

            // PATH_INFO
            // should contain partial path information only
            // note: IIS has AllowPathInfoForScriptMappings property that do the thing ... but ISAPI does not work then
            // hence it must be done here manually

            if (array.ContainsKey("PATH_INFO"))
            {
                string path_info   = array["PATH_INFO"].AsString();
                string script_name = array["SCRIPT_NAME"].AsString();

                // 'ORIG_PATH_INFO'
                // Original version of 'PATH_INFO' before processed by PHP.
                array["ORIG_PATH_INFO"] = (PhpValue)path_info;

                // 'PHP_INFO'
                // Contains any client-provided pathname information trailing the actual script filename
                // but preceding the query string, if available. For instance, if the current script was
                // accessed via the URL http://www.example.com/php/path_info.php/some/stuff?foo=bar,
                // then $_SERVER['PATH_INFO'] would contain /some/stuff.

                // php-5.3.2\sapi\isapi\php5isapi.c:
                //
                // strncpy(path_info_buf, static_variable_buf + scriptname_len - 1, sizeof(path_info_buf) - 1);    // PATH_INFO = PATH_INFO.SubString(SCRIPT_NAME.Length);

                array["PATH_INFO"] = (PhpValue)((script_name.Length <= path_info.Length) ? path_info.Substring(script_name.Length) : string.Empty);
            }

            //
            return(array);
        }