public function testMakeCopy() { $map0 = CMap::make(); $map0["one"] = "a"; $map0["two"] = "b"; $map0["three"] = "c"; $map1 = CMap::makeCopy($map0); $this->assertTrue($map0["one"] === $map1["one"] && $map0["two"] === $map1["two"] && $map0["three"] === $map1["three"]); $map0["one"] = "d"; $this->assertTrue($map1["one"] === "a"); }
/** * Composes a URL query into a query string ready to be used as a part of a URL and returns it. * * Any characters that cannot be represented literally in a valid query string come out percent-encoded. The * resulting query string never starts with "?". * * Because the characters in field named and field values are stored in their literal representations, the * resulting query string is always normalized, with only those characters appearing percent-encoded that really * require it for the query string to be valid and with the hexadecimal letters in percent-encoded characters * appearing uppercased. Also, no duplicate fields are produced in the resulting query string (even if the object * was constructed from a query string with duplicate fields in it) and "=" is added after any field name that goes * without a value and is not followed by "=". * * @param bool $sortFields **OPTIONAL. Default is** `false`. Tells whether the fields in the query string should * appear sorted in the ascending order, case-insensitively, and with natural order comparison used for sorting. * * @return CUStringObject The query string. */ public function queryString($sortFields = false) { assert('is_bool($sortFields)', vs(isset($this), get_defined_vars())); if (!CMap::isEmpty($this->m_query)) { $useQuery = CMap::makeCopy($this->m_query); // Recursively convert any CArray into a CMap for `http_build_query` function to accept the query. $useQuery = self::recurseQueryValueBeforeComposingQs($useQuery, 0); // Compose a preliminary query string. $queryString = http_build_query($useQuery, "", self::$ms_fieldDelimiters[0], PHP_QUERY_RFC1738); if (!is_cstring($queryString)) { return ""; } // Break the string into fields. $fields = CString::split($queryString, self::$ms_fieldDelimiters[0]); // Adjust the result of `http_build_query` function. $len = CArray::length($fields); for ($i = 0; $i < $len; $i++) { if (CString::find($fields[$i], "=")) { // Revert excessive percent-encoding of the square brackets next to the identifiers of // multidimensional data. $fields[$i] = CRegex::replaceWithCallback($fields[$i], "/(?:%5B(?:[^%]++|%(?!5B|5D))*+%5D)+?=/i", function ($matches) { $value = $matches[0]; $value = CString::replace($value, "%5B", "["); $value = CString::replace($value, "%5D", "]"); return $value; }); // Remove redundant indexing next to the identifiers of simple arrays. $fields[$i] = CRegex::replaceWithCallback($fields[$i], "/^.+?=/", function ($matches) { return CRegex::replace($matches[0], "/\\[\\d+\\]/", "[]"); }); } } if ($sortFields) { // Normalize the order of fields. CArray::sortStringsNatCi($fields); } $queryString = CArray::join($fields, self::$ms_fieldDelimiters[0]); return $queryString; } else { return ""; } }