如何在 url 字符串中仅编码查询参数?

How to encode only queryparams in a url string?

我只想使用下面给出的php、url字符串在url字符串中编码queryparams

https://torrentz-proxy.com/search?q=linux format 2015 added<6m leech>1 seed>1#12345

urlencode() 给出 https%3A%2F%2Ftorrentz-proxy.com%2Fsearch%3Fq%3Dlinux+format+2015+added%3C6m+leech%3E1+seed%3E1

其实我需要https://torrentz-proxy.com/search?q=linux%20format%202015%20added%3C6m%20leech%3E1%20seed%3E1#12345

如何做到这一点?是否有任何本机 php 函数可以执行此操作?

编辑

URL 是自动生成的(不是我生成的),示例如

http://example.com/abc?a=1 a&b=2 b&c=3+c#123

使用这样的东西:

<?php

$url = 'https://torrentz-proxy.com/search?q=linux format 2015 added<6m leech>1 seed>1#12345';

$questPos = strpos($url, '?q');
$query = explode('#', substr($url, $questPos+3));
$encodedUrl = substr($url, 0, $questPos+3) . urlencode($query[0]);

foreach (array_slice($query, 1) as $frag) {
    $encodedUrl .= '#' . $frag;
}

var_dump($encodedUrl);

将输出: string(89) "https://torrentz-proxy.com/search?q=linux+format+2015+added%3C6m+leech%3E1+seed%3E1#12345"

您需要解析 URL,提取查询参数值,对其进行编码,然后重新构建 URL。

function query_param_encode($url)
{
    $url = parse_url($url);
    $url_str = "";
    if (isset($url['scheme']))
        $url_str .= $url['scheme'].'://';
    if (isset($url['host']))
        $url_str .= $url['host'];
    if (isset($url['path']))
        $url_str .= $url['path'];
    if (isset($url['query']))
    {
        $query = explode('&', $url['query']);
        foreach ($query as $j=>$value)
        {
            $value = explode('=', $value, 2);
            if (count($value) == 2)
                $query[$j] = urlencode($value[0]).'='.urlencode($value[1]);
            else
                $query[$j] = urlencode($value[0]);
        }
        $url_str .= '?'.implode('&', $query);
    }
    if (isset($url['fragment']))
        $url_str .= '#'.$url['fragment'];

    return $url_str;
}

这会将您的 URL 编码为

https://torrentz-proxy.com/search?q=linux+format+2015+added%3C6m+leech%3E1+seed%3E1#12345
http://example.com/abc?a=1+a&b=2+b&c=3%2Bc#123

这样就可以了

    function encodeURI($url) {
    // http://php.net/manual/en/function.rawurlencode.php
    // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURI
    $unescaped = array(
        '%2D'=>'-','%5F'=>'_','%2E'=>'.','%21'=>'!', '%7E'=>'~',
        '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')'
    );
    $reserved = array(
        '%3B'=>';','%2C'=>',','%2F'=>'/','%3F'=>'?','%3A'=>':',
        '%40'=>'@','%26'=>'&','%3D'=>'=','%2B'=>'+','%24'=>'$'
    );
    $score = array(
        '%23'=>'#'
    );
    return strtr(rawurlencode($url), array_merge($reserved,$unescaped,$score));

   }

我发现这个 here 可以替代 JS 的 encodeURI()

最简单的方法是:

  • 用爆炸
  • 获得基础url
  • 仅对查询字符串进行编码(先解码以确保不进行两次编码)
  • 确保将 # 替换为 %23
$myUrl = 'https://torrentz-proxy.com/search?q=linux format 2015 added<6m leech>1 seed>1#12345';
$finalUrl = explode("?", $myUrl)[0] . "?" . urlencode(urldecode(parse_url(str_replace('#', '%23', $myUrl), PHP_URL_QUERY)))

这是一个完整的编码查询字符串 "https://torrentz-proxy.com/search?q%3Dlinux+format+2015+added%3C6m+leech%3E1+seed%3E1%2312345"

然后,如果您愿意(根据您的问题的要求)再次将 %23 替换为 #

$finalUrl = str_replace('%23', '#', $finalUrl);