如何在PHP中将utf8编码为像浏览器一样的url?

When entering this url into the Browser: http://www.google.com/?q=ä

The sent url is actually http://www.google.com/?q=%C3%A4

I want to do the same conversion using Php - how to do that?

What I tried:

$url = 'http://www.google.com/?q=ä'; //utf8 encoded

echo rawurlencode($url);
//gives http%3A%2F%2Fwww.google.com%2F%3Fq%3D%C3%A4

$u = parse_url($url);
echo $url['scheme'].'://'.$url['host'].$url['path'].'?'.rawurlencode($url['query']);
//gives http://www.google.com/?q%3D%C3%A4

The above url ist just a simple example, I need a generic solution that also works with

http://www.example.com/ä
http://www.example.com/ä?foo=ä&bar=ö
http://www.example.com/Περιβάλλον?abc=Περιβάλλον

The answer provided here is not generic enough: How to encode URL using php like browsers do

Ok, took me some time, but I think I have the universal solution:

function safe_urlencode($txt){
  // Skip all URL reserved characters plus dot, dash, underscore and tilde..
  $result = preg_replace_callback("/[^-\._~:\/\?#\\[\\]@!\$&'\(\)\*\+,;=]+/",
    function ($match) {
      // ..and encode the rest!  
      return rawurlencode($match[0]);
    }, $txt);
  return ($result);
}

Basically it splits the string using URL reserved characters (http://www.ietf.org/rfc/rfc3986.txt) + some more characters (because I think the "dot" should be also left alone) and does rawurlencode() on the rest.

echo safe_urlencode("http://www.google.com/?q=ä");
// http://www.google.com/?q=%C3%A4

echo safe_urlencode("http://www.example.com/Περιβάλλον?abc=Περιβάλλον");
// http://www.example.com/%CE%A0%CE%B5%CF%81%CE%B9%CE%B2%CE%AC%CE%BB%CE%BB%CE%BF%CE%BD?abc=%CE%A0%CE%B5%CF%81%CE%B9%CE%B2%CE%AC%CE%BB%CE%BB%CE%BF%CE%BD
// ^ This is some funky stuff, but it should be right

Looks that you want encode the query part of the URI without modify schema and host.

Preamble

There are no generic functions shipped by the language to achieve that because is not possible for the language to know if you will use the encoded string for a redirect or as query argument (?url=http%3A%3A....)

So the developer have to extract the part to encode as you did.

Answer

Encapsulate your own code as a function.

function encodeUrlQuery($url) {
  $u = parse_url($url);
  return $u['scheme'].'://'.$u['host'].$u['path'].'?'.rawurlencode($u['query']);
}

echo encodeUrl('http://www.google.com/?q=ä');