urlencode 대 rawurlencode?


380

변수를 사용하여 URL을 만들려면 문자열을 인코딩하는 두 가지 선택이 있습니다. urlencode()그리고 rawurlencode().

차이점은 무엇이며 어떤 것이 선호됩니까?


1
나는 다른 하나를 선택 해야하는 몇 가지 이유 (예 : 하나 또는 다른 문제가 발생할 수있는 문제)를 정말로보고 싶습니다. 나는 (다른 사람들은) 하나를 골라 영원히 사용할 수 있기를 바랍니다. 최소한의 소란을 피우 므로이 질문에 현상금을 시작했습니다.
Kzqai

29
@Tchalvak : 하나만 선택하려면을 선택하십시오 rawurlencode. 로 인코딩 된 공간이 주어질 때 질식하는 시스템을 거의 사용하지 않는 %20반면, 인코딩 된 공간 +을 더 일반적으로 인코딩 하는 시스템은 거의 사용하지 않습니다 .
Anomie

답변:


326

그것은 당신의 목적에 달려 있습니다. 다른 시스템과의 상호 운용성이 중요하다면 rawurlencode가 좋은 방법입니다. 한 가지 예외는 쿼리 문자열이 % 20 대신 +로 인코딩 된 형식의 공백을 양식 인코딩 스타일을 따르는 것으로 예상하는 레거시 시스템입니다 (이 경우 urlencode가 필요함).

rawurlencode 는 PHP 5.3.0 및 RFC 3986 이전의 RFC 1738을 따릅니다 ( http://us2.php.net/manual/en/function.rawurlencode.php 참조 ).

-_. ~를 제외한 모든 영숫자가 아닌 문자가 백분율 (%) 부호로 대체되고 두 개의 16 진 숫자가있는 문자열을 리턴합니다. 이것은 리터럴 문자가 특수 URL 분리 문자로 해석되지 않도록 보호하고 문자 변환 (일부 이메일 시스템과 같은)을 사용하여 전송 매체에 의해 URL이 엉망이되는 것을 방지하기 위해»RFC 3986에 설명 된 인코딩입니다.

php 5.3 이전의 rawurlencode ~는 RFC 1738에 따라 물결표 문자 ( )를 인코딩했습니다 . 그러나 PHP 5.3에서 rawurlencode는 물결표 문자 인코딩이 필요하지 않은 RFC 3986을 따릅니다.

urlencode 는 공백을 더하기 부호로 인코딩합니다 ( %20rawurlencode 에서와는 달리 ) ( http://us2.php.net/manual/en/function.urlencode.php 참조 )

영숫자가 아닌 모든 문자가 -_을 제외한 문자열을 반환합니다. 는 퍼센트 (%) 기호와 두 개의 16 진수 및 플러스 (+) 기호로 인코딩 된 공백으로 대체되었습니다. WWW 양식에서 게시 된 데이터가 인코딩되는 방식과 동일한 방식으로 인코딩됩니다. 이는 application / x-www-form-urlencoded 미디어 유형과 동일한 방식입니다. 이것은 역사적 이유로 공백이 더하기 (+) 부호로 인코딩된다는 점에서»RFC 3986 인코딩 (rawurlencode () 참조)과 다릅니다.

이는 RFC 1866의 application / x-www-form-urlencoded에 대한 정의에 해당합니다 .

추가 자료 :

http://bytes.com/groups/php/5624-urlencode-vs-rawurlencode 에서 토론을 볼 수도 있습니다 .

또한 RFC 2396 을 살펴볼 가치가 있습니다. RFC 2396은 유효한 URI 구문을 정의합니다. 우리가 관심을 갖는 주요 부분은 3.4 쿼리 구성 요소입니다.

쿼리 구성 요소 내에서 문자 가 예약됩니다.";", "/", "?", ":", "@",
"&", "=", "+", ",", and "$"

보시다시피 +쿼리 문자열에 예약 문자가 있으므로 RFC 3986에 따라 (rawurlencode에서와 같이) 인코딩해야합니다.


27
그래서 어느 것이 선호됩니까?
Gary Willoughby

79
rawurlencode. 이 경우 표준을 따르십시오. 를 urlencode은 기존 사용 유지
조나단 Fingland을

2
고마워, 그 생각, 나는 많은 코드를 업데이트하기 전에 두 번째 의견을 원했다.
Gary Willoughby

3
공백을 더하기 부호가 아니라 % 20s로 인코딩하는 것은 rawurlencode라고 생각합니다.
BigName

2
@Pindatjuh : 인용 부분 한 가지 예외는 쿼리 문자열이 % 20 대신 +로 인코딩 된 형식의 공백 형식 (예 : urlencode가 필요함)을 따르는 레거시 시스템을 의미하지만 rawurlencode는 대부분의 상황에 적합합니다. 일부 시스템에서는 공백이 + (더하기 부호)로 인코딩 될 것으로 예상합니다. 이러한 시스템의 경우 urlencode가 더 나은 선택입니다.
Jonathan Fingland 1

213

증명은 PHP의 소스 코드에 있습니다.

앞으로 언제든지 원하는대로 이러한 종류의 정보를 찾는 방법에 대한 빠른 프로세스를 안내합니다. 저와 함께, 당신이 훑어 볼 수있는 많은 C 소스 코드가있을 것입니다 (나는 그것을 설명합니다). 일부 C를 마무리하려면 SO wiki를 시작하는 것이 좋습니다 .

소스를 다운로드하거나 ( http://lxr.php.net/ 을 사용 하여 온라인으로 탐색) 함수 이름의 모든 파일을 grep하면 다음과 같은 것을 찾을 수 있습니다.

PHP 5.3.6 (가장 최근 작성 당시)은 url.c 파일에서 네이티브 C 코드의 두 가지 기능을 설명합니다 .

RawUrlEncode ()

PHP_FUNCTION(rawurlencode)
{
    char *in_str, *out_str;
    int in_str_len, out_str_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
                              &in_str_len) == FAILURE) {
        return;
    }

    out_str = php_raw_url_encode(in_str, in_str_len, &out_str_len);
    RETURN_STRINGL(out_str, out_str_len, 0);
}

UrlEncode ()

PHP_FUNCTION(urlencode)
{
    char *in_str, *out_str;
    int in_str_len, out_str_len;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &in_str,
                              &in_str_len) == FAILURE) {
        return;
    }

    out_str = php_url_encode(in_str, in_str_len, &out_str_len);
    RETURN_STRINGL(out_str, out_str_len, 0);
}

좋아, 여기서 뭐가 달라?

둘 다 본질적으로 두 가지 다른 내부 함수를 호출합니다 : php_raw_url_encodephp_url_encode

그런 기능들을 찾으십시오!

php_raw_url_encode를 보자

PHPAPI char *php_raw_url_encode(char const *s, int len, int *new_length)
{
    register int x, y;
    unsigned char *str;

    str = (unsigned char *) safe_emalloc(3, len, 1);
    for (x = 0, y = 0; len--; x++, y++) {
        str[y] = (unsigned char) s[x];
#ifndef CHARSET_EBCDIC
        if ((str[y] < '0' && str[y] != '-' && str[y] != '.') ||
            (str[y] < 'A' && str[y] > '9') ||
            (str[y] > 'Z' && str[y] < 'a' && str[y] != '_') ||
            (str[y] > 'z' && str[y] != '~')) {
            str[y++] = '%';
            str[y++] = hexchars[(unsigned char) s[x] >> 4];
            str[y] = hexchars[(unsigned char) s[x] & 15];
#else /*CHARSET_EBCDIC*/
        if (!isalnum(str[y]) && strchr("_-.~", str[y]) != NULL) {
            str[y++] = '%';
            str[y++] = hexchars[os_toascii[(unsigned char) s[x]] >> 4];
            str[y] = hexchars[os_toascii[(unsigned char) s[x]] & 15];
#endif /*CHARSET_EBCDIC*/
        }
    }
    str[y] = '\0';
    if (new_length) {
        *new_length = y;
    }
    return ((char *) str);
}

그리고 물론 php_url_encode :

PHPAPI char *php_url_encode(char const *s, int len, int *new_length)
{
    register unsigned char c;
    unsigned char *to, *start;
    unsigned char const *from, *end;

    from = (unsigned char *)s;
    end = (unsigned char *)s + len;
    start = to = (unsigned char *) safe_emalloc(3, len, 1);

    while (from < end) {
        c = *from++;

        if (c == ' ') {
            *to++ = '+';
#ifndef CHARSET_EBCDIC
        } else if ((c < '0' && c != '-' && c != '.') ||
                   (c < 'A' && c > '9') ||
                   (c > 'Z' && c < 'a' && c != '_') ||
                   (c > 'z')) {
            to[0] = '%';
            to[1] = hexchars[c >> 4];
            to[2] = hexchars[c & 15];
            to += 3;
#else /*CHARSET_EBCDIC*/
        } else if (!isalnum(c) && strchr("_-.", c) == NULL) {
            /* Allow only alphanumeric chars and '_', '-', '.'; escape the rest */
            to[0] = '%';
            to[1] = hexchars[os_toascii[c] >> 4];
            to[2] = hexchars[os_toascii[c] & 15];
            to += 3;
#endif /*CHARSET_EBCDIC*/
        } else {
            *to++ = c;
        }
    }
    *to = 0;
    if (new_length) {
        *new_length = to - start;
    }
    return (char *) start;
}

앞으로 나아 가기 전에 한 가지 간단한 지식으로 EBCDIC은 ASCII와 비슷한 또 다른 문자 집합 이지만 전체 경쟁자입니다. PHP는 두 가지 모두를 처리하려고 시도합니다. 그러나 기본적으로 이것은 바이트 EBCDIC 0x4c 바이트가 LASCII 가 아니라는 것을 의미 합니다 <. 실제로는 입니다. 나는 당신이 여기 혼란을 확신합니다.

웹 서버가 정의한 경우이 두 기능 모두 EBCDIC을 관리합니다.

또한 둘 다 문자 배열 (문자열 유형 생각) hexchars조회를 사용하여 일부 값을 가져옵니다. 배열은 다음과 같이 설명됩니다.

/* rfc1738:

   ...The characters ";",
   "/", "?", ":", "@", "=" and "&" are the characters which may be
   reserved for special meaning within a scheme...

   ...Thus, only alphanumerics, the special characters "$-_.+!*'(),", and
   reserved characters used for their reserved purposes may be used
   unencoded within a URL...

   For added safety, we only leave -_. unencoded.
 */

static unsigned char hexchars[] = "0123456789ABCDEF";

그 외에도 기능이 실제로 다르므로 ASCII 및 EBCDIC으로 설명하겠습니다.

ASCII의 차이점 :

URLENCODE :

  • 입력 문자열의 시작 / 종료 길이를 계산하고 메모리를 할당합니다
  • while 루프를 따라 걸으며 줄 끝에 도달 할 때까지 증가합니다.
  • 현재의 캐릭터를 잡는다
  • 문자가 ASCII Char 0x20과 같은 경우 (즉, "공백") +출력 문자열에 부호를 추가하십시오 .
  • 이 공간이 아니다, 그것은 (또한 숫자 아닌 경우 isalnum(c)도), 그리고되지 않으며 _, -또는 .문자, 그때 우리는, 출력 %배열 위치 0에 기호의에 배열 모양을 수행 hexchars하기위한 조회에 배열 os_toascii배열 ( (현재 문자) 의 키에 대해 Apache 에서 char을 16 진 코드로 변환 하는 배열 인 경우 c, 우리는 비트를 4 씩 오른쪽으로 시프트하고 해당 값을 문자 1에 할당하고 위치 2에 동일한 조회를 지정합니다. 논리적이고 값이 15 (0xF)인지 확인하고이 경우 1을 반환하고 그렇지 않으면 0을 반환합니다. 결국에는 인코딩 된 것으로 끝납니다.
  • 공백이 아닌 경우 영숫자 또는 _-.문자 중 하나이며 정확히 그대로 출력됩니다.

RAWURLENCODE :

  • 문자열에 메모리를 할당
  • 함수 호출에서 제공된 길이 (URLENCODE와 같이 함수에서 계산되지 않음)를 기준으로 반복합니다.

참고 : 많은 프로그래머는 아마 루프으로 반복이 방법을, 그것은 다소 hackish입니다 본 적이 아닌 표준 규칙은, 관심을 지불-루프, 그것은 할당 대부분의 사용 xy에, 종료에 대한 검사를 len0에 도달하고, 단위 모두 xy. 나는 그것이 당신이 기대하는 것이 아니라 유효한 코드라는 것을 알고 있습니다.

  • 에서 현재 문자를 일치하는 문자 위치에 할당합니다 str.
  • 현재 문자가 영숫자인지 또는 _-.문자 중 하나 인지 확인하고 그렇지 않은 경우 URLENCODE와 거의 동일한 할당을 수행하지만 조회를 수행 할 때는을 사용 y++하지 않고 다르게 증가 to[1]합니다. 현은 다른 방식으로 건축되고 있지만 어쨌든 같은 목표에 도달합니다.
  • 루프가 완료되고 길이가 사라지면 실제로 문자열을 종료하고 \0바이트를 할당합니다 .
  • 인코딩 된 문자열을 반환합니다.

차이점 :

  • UrlEncode는 공백을 확인하고 + 부호를 할당하지만 RawURLEncode는 그렇지 않습니다.
  • UrlEncode는 \0문자열에 바이트를 할당하지 않고 RawUrlEncode는 바이트를 할당합니다.
  • 그것들은 다르게 반복되며, 잘못된 문자열로 넘칠 수 있습니다. 나는 단지 이것을 제안 하고 실제로 조사 하지 않았습니다 .

기본적으로 다르게 반복됩니다. ASCII 20의 경우 + 기호가 할당됩니다.

EBCDIC의 차이점 :

URLENCODE :

  • ASCII와 동일한 반복 설정
  • 여전히 "공백"문자를 + 부호로 변환합니다 . 참고-이것이 EBCDIC으로 컴파일되어야한다고 생각합니까? 아니면 버그가 생길까요? 누군가 이것을 편집하고 확인할 수 있습니까?
  • 이것은 검사, 본 CHAR 전에 숯불 경우 0있는 Being을 제외 .하거나 -, OR 미만 A이지만보다 숯 9, OR 보다 크를 Z이하와 a아니지만 _. 또는 보다 큽니다 z(예, EBCDIC는 약간 엉망입니다). 그 중 하나와 일치하면 ASCII 버전에서와 비슷한 검색을 수행하십시오 (os_toascii에서 검색하지 않아도 됨).

RAWURLENCODE :

  • ASCII와 동일한 반복 설정
  • URL 인코딩의 EBCDIC 버전에 설명 된 것과 동일하지만 z, 보다 크면 ~URL 인코딩에서 제외됩니다 .
  • ASCII RawUrlEncode와 동일한 할당
  • \0반환하기 전에 문자열에 바이트를 계속 추가합니다 .

그랜드 요약

  • 둘 다 동일한 16 진 룩업 테이블을 사용합니다.
  • URIEncode는 \ 0으로 문자열을 종료하지 않으며 raw는 종료합니다.
  • EBCDIC에서 작업하는 경우 RawUrlEncode를 사용하는 것이 좋습니다. ~UrlEncode가 관리 하지 않기 때문입니다 ( 보고 된 문제 ). ASCII와 EBCDIC 0x20은 모두 공백입니다.
  • 그것들은 다르게 반복되고, 하나는 더 빠르며, 메모리 또는 문자열 기반 악용에 취약 할 수 있습니다.
  • URIEncode는 공간을로 +만들고 RawUrlEncode는 %20배열 조회 를 통해 공간을 만듭니다 .

면책 조항 : 몇 년 동안 C를 만지지 않았으며 실제로 오랫동안 EBCDIC을 보지 못했습니다. 어딘가에 틀렸다면 알려주십시오.

제안 된 구현

이 모든 것을 바탕으로 rawurlencode는 대부분의 시간을가는 길입니다. Jonathan Fingland의 답변에서 볼 수 있듯이 대부분의 경우에 충실하십시오. urlencode가 구식 방식으로 +를 "공간"으로 사용하는 URI 구성 요소에 대한 최신 체계를 처리합니다.

이전 형식과 새 형식을 변환하려는 경우 코드가 손상되지 않도록 확인하고 실수로 이중 인코딩 또는 이와 유사한 "oops"시나리오를 통해 디코딩 된 + 부호가있는 것을 공백으로 바꾸십시오. 공간 / 20 % / + 문제.

새로운 형식을 선호하지 않는 구형 소프트웨어로 구형 시스템에서 작업하는 경우 urlencode를 사용하십시오. 그러나 이전 표준 % 20에서 작동했던 것처럼 % 20은 실제로 이전 버전과 호환됩니다. 선호합니다. 당신이 놀러 다니면 기회를주십시오. 어떻게 당신을 위해 일했는지 알려주십시오.

EBCDIC 시스템이 실제로 당신을 미워하지 않는 한 기본적으로, 당신은 날 것으로 고수해야합니다. 대부분의 프로그래머는 2000 년 이후, 심지어 1990 년 이후에 만들어진 시스템에서 EBCDIC를 절대로 사용하지 않을 것입니다.


더블 인코딩에 대해 걱정할 필요가 없었습니다. 결국 내가 생각한 인코딩을 수행하기 때문에 인코딩 한 내용을 알아야합니다. 공간을 처리하는 방법을 알고있는 호환성 모드로받은 모든 것을 해독하기 때문에 여기서 경고하려고하는 문제를 겪지 않았습니다. 우리가 무엇을하는지 모르는 경우 소스를 보는 것을 이해할 수 있지만 여기서 단순히 두 기능을 모두 실행하여 알지 못했던 것을 여기서 정확히 알게되었습니다. 나는 편견이 있다는 것을 알고 있지만 도울 수는 없지만 이것이 선상에 있다고 생각합니다. 노력에 찬사! =)
nickl-

2
+1,이 부분 : "저는 이전 표준 % 20에서 작동했던 것처럼 선호하지 않았기 때문에 % 20이 실제로 이전 버전과 호환 될 것입니다"
Gras Double

3
좋은 대답이지만 약간 과잉일까요?
rinogo

38
echo rawurlencode('http://www.google.com/index.html?id=asd asd');

수확량

http%3A%2F%2Fwww.google.com%2Findex.html%3Fid%3Dasd%20asd

동안

echo urlencode('http://www.google.com/index.html?id=asd asd');

수확량

http%3A%2F%2Fwww.google.com%2Findex.html%3Fid%3Dasd+asd

인 차이 asd%20asdasd+asd

urlencode는 +대신 공백을 인코딩하여 RFC 1738과 다릅니다.%20


28

다른 환경에서 하나를 선택해야하는 실질적인 이유 중 하나는 다른 환경 (예 : JavaScript)에서 결과를 사용하려는 경우입니다.

PHP에서는 결과가 urlencode('test 1')반환 'test+1'되는 동안 rawurlencode('test 1')반환합니다 'test%201'.

당신이 "디코드"필요하지만 자바 스크립트에서이 사용 decodeURI () 다음 기능을 decodeURI("test+1")당신을 줄 것이다 "test+1"동안 decodeURI("test%201")당신을 줄 것이다 "test 1"결과로.

다시 말해, PHP에서 urlencode 에 의해 플러스 ( "+")로 인코딩 된 공백 ( "") 은 JavaScript의 decodeURI 에 의해 올바르게 디코딩되지 않습니다 .

이러한 경우 rawurlencode PHP 함수를 사용해야합니다.


6
이것은 내가 본 최고의 답변입니다. 실제 예제를 통해 사용 제안을 제공합니다. 또한 간결합니다.
dotancohen

내가 선호하지만 그것은 좋은 예입니다 json_encode그리고 JSON.parse그 목적을 위해.
Fabrício Matté 2013

21

공백은 다음과 같이 인코딩되어야한다고 생각합니다.

  • %20 URL 경로 구성 요소 내에서 사용될 때
  • +URL 쿼리 문자열 구성 요소 또는 양식 데이터 내에서 사용되는 경우 ( 17.13.4 양식 내용 유형 참조 )

다음 예는 rawurlencode및 의 올바른 사용법을 보여줍니다 urlencode.

echo "http://example.com"
    . "/category/" . rawurlencode("latest songs")
    . "/search?q=" . urlencode("lady gaga");

산출:

http://example.com/category/latest%20songs/search?q=lady+gaga

다른 방식으로 경로 및 쿼리 문자열 구성 요소를 인코딩하면 어떻게됩니까? 다음 예의 경우 :

http://example.com/category/latest+songs/search?q=lady%20gaga
  • 웹 서버는 디렉토리 latest+songs대신 디렉토리 를 찾습니다latest songs
  • 쿼리 문자열 매개 변수 qlady gaga

2
"쿼리 문자열 매개 변수 q에는 lady gaga"다른 것이 포함되어 있습니까? 쿼리 매개 변수 q는 PHP 5.2+ $_GET를 사용 rawurlencode하거나 사용하지 않고 동일한 값을 배열에 전달한 것으로 보입니다 urlencode. 그래도 GET 요청의 기본 형식으로 urlencode인코딩 application/x-www-form-urlencoded하므로 귀하의 접근 방식을 사용합니다. +1
Fabrício Matté

2
난 둘 다 명확히하고 싶었 +%20쿼리 문자열에 사용하면 공간으로 디코딩된다.
살만 A

5

차이점은 반환 값에 있습니다.

urlencode () :

영숫자가 아닌 모든 문자가 -_을 제외한 문자열을 반환합니다. 는 퍼센트 (%) 기호와 두 개의 16 진수 및 플러스 (+) 기호로 인코딩 된 공백으로 대체되었습니다. WWW 양식에서 게시 된 데이터가 인코딩되는 방식과 동일한 방식으로 인코딩됩니다. 이는 application / x-www-form-urlencoded 미디어 유형과 동일한 방식입니다. 이것은 역사적 이유로 공백이 더하기 (+) 기호로 인코딩된다는 점에서»RFC 1738 인코딩 (rawurlencode () 참조)과 다릅니다.

rawurlencode () :

영숫자가 아닌 모든 문자가 -_을 제외한 문자열을 반환합니다. 퍼센트 (%) 기호와 두 개의 16 진수로 교체되었습니다. 이것은 리터럴 문자가 특수 URL 구분 기호로 해석되지 않도록 보호하고 문자 변환 (일부 이메일 시스템과 같은)을 사용하여 전송 매체에 의해 URL이 엉망이되는 것을 방지하기 위해 RFC 1738에 설명 된 인코딩입니다.

두 개는 매우 유사하지만 후자 (rawurlencode)는 공백을 '%'와 두 개의 16 진수로 바꾸어 암호를 인코딩하는 데 적합합니다. 예를 들어 '+'가 다음과 같지 않은 경우 :

echo '<a href="ftp://user:', rawurlencode('foo @+%/'),
     '@ftp.example.com/x.txt">';
//Outputs <a href="ftp://user:foo%20%40%2B%25%2F@ftp.example.com/x.txt">

2
OP는 사용 방법과시기를 묻는 방법을 묻습니다. 공백으로 각각의 기능을 알면 다른 반환 값의 중요성을 모르는 경우 OP가 결정을 내리는 데 도움이되지 않습니다.
dotancohen

5

1. 정확히 차이점과

유일한 차이점은 공백이 처리되는 방식에 있습니다.

urlencode-레거시 구현을 기반으로 공백을 +로 변환

rawurlencode- RFC 1738 기반으로 공간을 % 20으로 변환

차이점이있는 이유는 URL에서 +가 예약되어 있고 유효 (인코딩되지 않은)이기 때문입니다.

2. 어느 것이 선호됩니까?

나는 다른 하나를 선택 해야하는 몇 가지 이유를 정말로보고 싶습니다 ... 나는 단지 하나를 골라서 최소한의 소란없이 영원히 사용할 수 있기를 원합니다.

공정하게도, 나는 이러한 결정을 내릴 때 따라야 할 간단한 전략을 가지고 있습니다.

" 허용 애플리케이션 " 을 요구 하는 HTTP / 1.1 사양 RFC 2616 인 것 같습니다.

클라이언트는 요청 라인을 구문 분석 할 때 Status-Line을 구문 분석 할 때 허용되며 서버는 허용해야합니다.

이와 같은 질문에 직면 할 때 최선의 전략은 항상 가능한 한 많이 소비하고 표준을 준수하는 것을 생산하는 것입니다.

그래서 제 충고는 rawurlencode표준을 준수하는 RFC 1738 인코딩 문자열을 생성하고 urldecode이전 버전과 호환되며 소비 할 수있는 모든 것을 수용하는 데 사용하는 것입니다.

이제 내 말을 받아 들일 수는 있지만 우리가 그것을 증명할 수 있도록하겠습니다.

php > $url = <<<'EOD'
<<< > "Which, % of Alice's tasks saw $s @ earnings?"
<<< > EOD;
php > echo $url, PHP_EOL;
"Which, % of Alice's tasks saw $s @ earnings?"
php > echo urlencode($url), PHP_EOL;
%22Which%2C+%25+of+Alice%27s+tasks+saw+%24s+%40+earnings%3F%22
php > echo rawurlencode($url), PHP_EOL;
%22Which%2C%20%25%20of%20Alice%27s%20tasks%20saw%20%24s%20%40%20earnings%3F%22
php > echo rawurldecode(urlencode($url)), PHP_EOL;
"Which,+%+of+Alice's+tasks+saw+$s+@+earnings?"
php > // oops that's not right???
php > echo urldecode(rawurlencode($url)), PHP_EOL;
"Which, % of Alice's tasks saw $s @ earnings?"
php > // now that's more like it

PHP는이 두 가지 형식 중 하나를 거부하는 사람을 본 적이 없어도이 사실을 염두에두고있는 것처럼 보이지만 사실상의 전략으로 채택하는 더 나은 전략을 생각할 수 없습니까?

조이!


4

urlencode : 역사적 이유로 공백은 더하기 (+) 부호로 인코딩된다는 점에서»RFC 1738 인코딩 (rawurlencode () 참조)과 다릅니다.


2

%20vs로 인코딩 된 공백+

rawurlencode()대부분의 경우 에 사용 하는 가장 큰 이유 urlencode는 텍스트 공간을 +(더하기 기호)로 rawurlencode인코딩하여 일반적으로 사용 되는 텍스트 공간을 인코딩 하기 때문입니다 %20.

echo urlencode("red shirt");
// red+shirt

echo rawurlencode("red shirt");
// red%20shirt

인코딩 된 텍스트 쿼리를 허용하는 특정 API 끝 점이 %20공백 을 볼 것으로 예상 하고 더하기 기호를 대신 사용하면 실패합니다. 분명히 이것은 API 구현마다 다르며 마일리지는 다를 수 있습니다.


1

urlencode는 쿼리 매개 변수에 대한 것이고 rawurlencode는 경로 세그먼트에 대한 것입니다. 이는 주로 %20경로 세그먼트와 +쿼리 매개 변수 때문입니다. 공백에 대해 이야기하는이 답변을 참조하십시오 : 공백을 플러스 (+) 또는 % 20으로 인코딩 할 때?

그러나 %20이제 쿼리 매개 변수에서도 작동하므로 rawurlencode가 항상 더 안전합니다. 그러나 더하기 부호는 쿼리 매개 변수의 편집 및 가독성에 대한 사용자 경험이 중요한 경우에 사용되는 경향이 있습니다.

이것은 공백으로 rawurldecode해독되지 않음을 의미 +합니다 ( http://au2.php.net/manual/en/function.rawurldecode.php ). 는 $ _GET은 항상 자동으로 통과됩니다 이유입니다 urldecode, 어떤 수단 +%20두 공간으로 디코딩됩니다.

입력과 출력간에 인코딩과 디코딩의 일관성을 유지 하고 쿼리 매개 변수가 +아닌 항상 사용하도록 선택한 경우 쿼리 매개 변수 (키 및 값)에 적합합니다.%20urlencode

결론은 다음과 같습니다.

경로 세그먼트-항상 rawurlencode / rawurldecode를 사용하십시오.

쿼리 매개 변수-디코딩을 위해 항상 urldecode (자동으로 완료)를 사용하고 인코딩에는 rawurlencode 또는 urlencode가 모두 적합합니다. 특히 URL을 비교할 때 하나를 선택하십시오.


0

간단한 * rawurlencode 경로-경로는 "?"앞 부분입니다 -공백은 % 20으로 인코딩해야합니다. * 쿼리 문자열을 urlencode합니다.-쿼리 문자열은 "?"뒤에 오는 부분입니다. 공백은 "+"로 더 잘 인코딩됩니다. = rawurlencode는 일반적으로 더 호환됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.