Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/240.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP中数字索引数组的最短可能查询字符串_Php_Arrays_Query String - Fatal编程技术网

PHP中数字索引数组的最短可能查询字符串

PHP中数字索引数组的最短可能查询字符串,php,arrays,query-string,Php,Arrays,Query String,我在寻找最简洁的URL,而不是最短的PHP代码。我不想让我的用户被PHP在编码数组时创建的可怕URL吓坏 如果您只是通过以下方式填充数组($fn),PHP将在查询字符串中执行大量重复操作: 生成的$url为 http://example.com/?c=asdf&fs[0]=5&fs[1]=12&fs[3]=99 如何将其降至最低(使用PHP或PHP中易于实现的方法)?有多种可能的方法: serialize+base64-可以吞并任何对象,但数据开销非常可怕 内爆+base64-仅限于数组,强制

我在寻找最简洁的URL,而不是最短的PHP代码。我不想让我的用户被PHP在编码数组时创建的可怕URL吓坏

如果您只是通过以下方式填充数组(
$fn
),PHP将在查询字符串中执行大量重复操作:

生成的
$url

http://example.com/?c=asdf&fs[0]=5&fs[1]=12&fs[3]=99

如何将其降至最低(使用PHP或PHP中易于实现的方法)?

有多种可能的方法:

  • serialize+base64-可以吞并任何对象,但数据开销非常可怕
  • 内爆+base64-仅限于数组,强制用户查找未使用的字符作为分隔符,数据开销小得多
  • 内爆-不安全的字符串。需要严格的数据控制
  • 结果如下:

    YTOZONTPOJA7CzoxNJOIc29TZSB1BNHZMUGZGF0YSI7ATOxO6MTIiYMJ09AHR0CDOVLYI7ATOYOYO6NTOINtYU6ZU1Io30=
    一些不安全的数据&&==http://65535
    C29TZSB1BNHZMUGZG0YXWMJIY9PWH0DHA6LY98NJU1MZU=
    

    虽然serialize+base64结果非常长,但内爆+serialize为GET提供了安全的可管理长度输出…除了结尾处的
    =

    有多种可能的方法:

  • serialize+base64-可以吞并任何对象,但数据开销非常可怕
  • 内爆+base64-仅限于数组,强制用户查找未使用的字符作为分隔符,数据开销小得多
  • 内爆-不安全的字符串。需要严格的数据控制
  • 结果如下:

    YTOZONTPOJA7CzoxNJOIc29TZSB1BNHZMUGZGF0YSI7ATOxO6MTIiYMJ09AHR0CDOVLYI7ATOYOYO6NTOINtYU6ZU1Io30=
    一些不安全的数据&&==http://65535
    C29TZSB1BNHZMUGZG0YXWMJIY9PWH0DHA6LY98NJU1MZU=
    
    虽然serialize+base64结果非常长,但内爆+serialize为GET提供了安全的可管理长度的输出…除了结尾处的
    =

    默认PHP方式
    http\u build\u query
    所做的是将数组序列化为URL的常用方法。PHP在
    $\u GET
    中自动反序列化它

    当只想序列化一个(非关联)整数数组时,可以使用其他选项

    小阵列 对于小数组,转换为下划线分隔列表非常方便和高效。这是通过
    $fs=内爆('''',$fs)
    完成的。那么您的URL将如下所示:

    http://example.com/?c=asdf&fs=5_12_99
    
    缺点是,您必须显式地
    分解('''u',$'u GET['fs'])
    才能将值作为数组返回

    也可以使用其他分隔符。下划线被认为是字母数字,因此很少有特殊意义。在URL中,它通常用作空间替换(例如,MediaWiki)。在带下划线的文本中使用时很难区分。连字符是另一种常用的空格替换。它也常被用作减号。逗号是一个典型的列表分隔符,但与中的下划线和连字符不同,逗号是由
    http\u build\u query
    进行百分比编码的,几乎在任何地方都有特殊意义。竖杆(“管道”)也存在类似情况

    大型阵列 当URL中有大数组时,您应该首先停止编码,开始思考。这几乎总是表明设计不好。POST HTTP方法不是更合适吗?难道您没有任何更可读、更节省空间的方法来标识已寻址的资源吗

    理想情况下,URL应该易于理解和(至少部分)记住。在里面放一个大斑点真是个坏主意

    现在我警告你了。如果您仍然需要在URL中嵌入一个大数组,请继续。尽可能多地压缩数据,-对它们进行编码以将二进制blob转换为文本,并对文本进行清理以嵌入URL

    修改的base64 嗯。或者最好使用一个。我的选择之一是使用

    • -
      而不是
      +
    • \u
      而不是
      /
    • 省略填充
      =
    这将在每个字符上保存两个字节,否则将采用百分比编码。也不需要调用
    urlencode
    函数

    压缩 应该在gzip()和bzip2()之间进行选择。不想花费时间进行比较,对于块大小的任何设置,gzip在几个相对较小的输入(大约100个字符)上看起来更好

    包装 但是什么数据应该输入到压缩算法中呢

    在C语言中,可以将整数数组转换为字符数组(字节),并将其交给压缩函数。这是最明显的做事方式。在PHP中,最明显的方法是将所有整数转换为字符串形式的十进制表示,然后使用分隔符进行连接,并且仅在压缩之后。真是浪费空间

    所以,让我们使用C方法!我们将消除分隔符和其他浪费的空间,并使用以下代码将每个整数编码为2个字节:

    警告:
    pack
    unpack
    行为在这种情况下取决于机器。字节顺序可能在机器之间更改。但我认为在实践中这不会是一个问题,因为应用程序不会同时在两个具有不同端性的系统上运行。但是,在集成多个系统时,可能会出现问题。此外,如果切换到具有不同endianity的系统,则使用原始endianity的链接将断开

    共同编码 现在,打包、压缩和修改base64,一应俱全:

    function url_embed_array($arr) {
        return url_base64_encode(gzcompress(pack_nums($arr)));
    }
    function url_parse_array($data) {
        return unpack_nums(gzuncompress(url_base64_decode($data)));
    }
    
    看。这比OP的答案要好,在他的40元素数组中,我的解产生91个字符,而他的解产生98个字符。当使用
    范围(1,1000)
    (生成
    数组(1,2,3,…,1000)
    )作为基准时。这大约好25%

    为了完整性,OP的解决方案是

    function url_embed_array($arr) {
        return urlencode(base64_encode(gzcompress(implode(',', $arr))));
    }
    
    默认PHP方式
    http\u build\u query
    所做的是
    define('URL_BASE64_FROM', '+/');
    define('URL_BASE64_TO', '-_');
    function url_base64_encode($data) {
        $encoded = base64_encode($data);
        if ($encoded === false) {
            return false;
        }
        return str_replace('=', '', strtr($encoded, URL_BASE64_FROM, URL_BASE64_TO));
    }
    function url_base64_decode($data) {
        $len = strlen($data);
        if (is_null($len)) {
            return false;
        }
        $padded = str_pad($data, 4 - $len % 4, '=', STR_PAD_RIGHT);
        return base64_decode(strtr($padded, URL_BASE64_TO, URL_BASE64_FROM));
    }
    
    define('PACK_NUMS_FORMAT', 'n*');
    function pack_nums($num_arr) {
        array_unshift($num_arr, PACK_NUMS_FORMAT);
        return call_user_func_array('pack', $num_arr);
    }
    function unpack_nums($packed_arr) {
        return unpack(PACK_NUMS_FORMAT, $packed_arr);
    }
    
    function url_embed_array($arr) {
        return url_base64_encode(gzcompress(pack_nums($arr)));
    }
    function url_parse_array($data) {
        return unpack_nums(gzuncompress(url_base64_decode($data)));
    }
    
    function url_embed_array($arr) {
        return urlencode(base64_encode(gzcompress(implode(',', $arr))));
    }
    
    $fs = array(5, 12, 99);
    $fs_no_array = implode(',', $fs);
    $url = "http://$_SERVER[HTTP_HOST]/?" .
        http_build_query(array('c' => 'asdf', 's' => 'jkl')) . '&fs=' . $fs_no_array;
    
    $fs = array_map('intval', explode(',', $_GET['fs']));
    
    $fs_compressed = urlencode(base64_encode(gzcompress($fs_no_array)));
    
    $fs_decompressed = gzuncompress(base64_decode($_GET['fs']));
    $fs = array_map('intval', explode(',', $fs_decompressed));
    
    $fs = array(7,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,52,53,54,61);
    
    $fs = array(7,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,52,53,54,61);