urlencode vs rawurlencode?

380

Jika saya ingin membuat URL menggunakan variabel saya punya dua pilihan untuk menyandikan string. urlencode()dan rawurlencode().

Apa perbedaan sebenarnya dan mana yang lebih disukai?

Gary Willoughby
sumber
1
Saya benar-benar ingin melihat beberapa alasan untuk memilih satu dari yang lain (misalnya masalah yang mungkin dihadapi dengan satu atau yang lain), saya (dan saya berharap orang lain) ingin dapat hanya memilih satu dan menggunakannya selamanya dengan paling tidak ribut, jadi saya sudah mulai hadiah pada pertanyaan ini.
Kzqai
29
@Tchalvak: Jika Anda ingin memilih satu saja, pilih rawurlencode. Anda jarang akan berjalan ke sistem yang tersedak ketika diberi spasi yang dikodekan %20, sedangkan sistem yang tersedak seperti +yang lebih umum.
Anomie

Jawaban:

326

Itu akan tergantung pada tujuan Anda. Jika interoperabilitas dengan sistem lain adalah penting maka tampaknya rawurlencode adalah cara untuk pergi. Satu-satunya pengecualian adalah sistem lawas yang mengharapkan string kueri mengikuti gaya pengkodean bentuk ruang yang dikodekan sebagai + alih-alih% 20 (dalam hal ini Anda perlu urlencode).

rawurlencode mengikuti RFC 1738 sebelum PHP 5.3.0 dan RFC 3986 sesudahnya (lihat http://us2.php.net/manual/en/function.rawurlencode.php )

Mengembalikan string di mana semua karakter non-alfanumerik kecuali -_ ~ telah diganti dengan tanda persen (%) diikuti oleh dua digit hex. Ini adalah pengkodean yang dijelaskan dalam »RFC 3986 untuk melindungi karakter literal dari ditafsirkan sebagai pembatas URL khusus, dan untuk melindungi URL agar tidak hancur oleh media transmisi dengan konversi karakter (seperti beberapa sistem email).

Catatan pada RFC 3986 vs 1738. rawurlencode sebelum php 5.3 mengkodekan karakter tilde ( ~) menurut RFC 1738. Namun, pada PHP 5.3, bagaimanapun, rawurlencode mengikuti RFC 3986 yang tidak memerlukan pengkodean karakter tilde.

urlencode mengkodekan spasi sebagai tanda plus (tidak %20seperti yang dilakukan pada rawurlencode) (lihat http://us2.php.net/manual/en/function.urlencode.php )

Mengembalikan string di mana semua karakter non-alfanumerik kecuali -_. telah diganti dengan tanda persen (%) diikuti oleh dua digit heksa dan spasi yang dikodekan sebagai tanda plus (+). Itu dikodekan dengan cara yang sama bahwa data yang diposting dari formulir WWW dikodekan, itu adalah cara yang sama seperti dalam jenis media application / x-www-form-urlencoded. Ini berbeda dengan pengkodean »RFC 3986 (lihat rawurlencode ()) karena alasan historis, spasi dikodekan sebagai tanda tambah (+).

Ini sesuai dengan definisi untuk aplikasi / x-www-form-urlencoded di RFC 1866 .

Bacaan tambahan:

Anda mungkin juga ingin melihat diskusi di http://bytes.com/groups/php/5624-urlencode-vs-rawurlencode .

Juga, RFC 2396 layak untuk dilihat. RFC 2396 mendefinisikan sintaksis URI yang valid. Bagian utama yang kami minati adalah dari 3.4 Komponen Kueri:

Dalam komponen permintaan, karakter dicadangkan.";", "/", "?", ":", "@",
"&", "=", "+", ",", and "$"

Seperti yang Anda lihat, itu +adalah karakter yang dicadangkan dalam string kueri dan karenanya harus dikodekan sesuai RFC 3986 (seperti dalam rawurlencode).

Jonathan Fingland
sumber
27
Jadi yang mana yang lebih disukai?
Gary Willoughby
79
rawurlencode. pergi dengan standar dalam hal ini. urlencode hanya disimpan untuk penggunaan sebelumnya
Jonathan Fingland
2
Terima kasih banyak, itulah yang saya pikir, saya hanya ingin pendapat kedua sebelum saya mulai memperbarui banyak kode.
Gary Willoughby
3
Saya pikir itu rawurlencode yang tidak menyandikan spasi sebagai tanda plus tetapi sebagai% 20s
BigName
2
@Patatjuh: Bagian yang Anda kutip Satu-satunya pengecualian adalah sistem legacy yang mengharapkan string kueri untuk mengikuti gaya bentuk-pengkodean ruang yang dikodekan sebagai + alih-alih% 20 (dalam hal ini Anda memerlukan urlencode) artinya sementara rawurlencode tepat untuk sebagian besar situasi , beberapa sistem mengharapkan spasi dikodekan sebagai tanda + (plus). Untuk sistem seperti itu, urlencode adalah pilihan yang lebih baik.
Jonathan Fingland
213

Bukti ada dalam kode sumber PHP.

Saya akan membawa Anda melalui proses cepat tentang bagaimana mencari tahu hal semacam ini sendiri di masa depan kapan saja Anda inginkan. Bersabarlah, akan ada banyak kode sumber C yang bisa Anda lewati (saya jelaskan). Jika Anda ingin memoles C, tempat yang baik untuk memulai adalah SO wiki kami .

Unduh sumbernya (atau gunakan http://lxr.php.net/ untuk menjelajahnya secara online), ambil semua file untuk nama fungsi, Anda akan menemukan sesuatu seperti ini:

PHP 5.3.6 (terbaru pada saat penulisan) menjelaskan dua fungsi dalam kode C asli mereka dalam file url.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);
}

Oke, jadi apa yang berbeda di sini?

Keduanya sama-sama memanggil dua fungsi internal yang berbeda: php_raw_url_encode dan php_url_encode

Jadi pergi mencari fungsi-fungsi itu!

Mari kita lihat 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);
}

Dan tentu saja, 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;
}

Satu pengetahuan singkat sebelum saya bergerak maju, EBCDIC adalah rangkaian karakter lain , mirip dengan ASCII, tetapi merupakan pesaing total. PHP mencoba untuk menangani keduanya. Tetapi pada dasarnya, ini berarti byte EBCDIC 0x4c byte bukan Ldi ASCII, itu sebenarnya a <. Saya yakin Anda melihat kebingungan di sini.

Kedua fungsi ini mengelola EBCDIC jika server web telah menetapkannya.

Selain itu, keduanya menggunakan array karakter chars (think string type) hexcharsuntuk mendapatkan beberapa nilai, array digambarkan seperti itu:

/* 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";

Selain itu, fungsinya sangat berbeda, dan saya akan menjelaskannya dalam ASCII dan EBCDIC.

Perbedaan dalam ASCII:

URLENCODE:

  • Menghitung panjang mulai / akhir dari string input, mengalokasikan memori
  • Berjalan melalui loop sementara, bertambah hingga kami mencapai akhir string
  • Raih karakter yang sekarang
  • Jika karakter sama dengan ASCII Char 0x20 (yaitu, "spasi"), tambahkan +tanda ke string output.
  • Jika bukan spasi, dan juga bukan alfanumerik ( isalnum(c)), dan juga bukan dan _,, -atau .karakter, maka kita, menampilkan %tanda ke posisi array 0, melakukan pencarian array ke hexcharsarray untuk pencarian os_toasciiarray () sebuah array dari Apache yang menerjemahkan char ke hex code) untuk kunci c(karakter sekarang), kita kemudian menggeser bitwise ke kanan dengan 4, menetapkan nilai itu ke karakter 1, dan ke posisi 2 kita menetapkan pencarian yang sama, kecuali kita membentuk sebelumnya a logis dan untuk melihat apakah nilainya 15 (0xF), dan mengembalikan 1 dalam kasus itu, atau 0 sebaliknya. Pada akhirnya, Anda akan berakhir dengan sesuatu yang dikodekan.
  • Jika pada akhirnya itu bukan spasi, itu alfanumerik atau salah satu _-.karakter, itu menghasilkan persis apa itu.

RAWURLENCODE:

  • Mengalokasikan memori untuk string
  • Iterasi berdasarkan panjang yang disediakan dalam panggilan fungsi (tidak dihitung dalam fungsi seperti dengan URLENCODE).

Catatan: Banyak programmer mungkin belum pernah melihat for loop iterate dengan cara ini, ini agak peretasan dan bukan konvensi standar yang digunakan dengan sebagian besar untuk-loop, perhatikan, itu menugaskan xdan y, memeriksa untuk keluar pada lenmencapai 0, dan meningkatkan keduanya xdan y. Saya tahu, itu bukan yang Anda harapkan, tapi itu kode yang valid.

  • Tetapkan karakter sekarang ke posisi karakter yang cocok di str.
  • Ia memeriksa apakah karakter saat ini adalah alfanumerik, atau salah satu _-.karakter, dan jika tidak, kami melakukan tugas yang hampir sama seperti dengan URLENCODE di mana ia membentuk pencarian sebelumnya, namun, kami menambah secara berbeda, menggunakan y++daripada to[1], ini karena string sedang dibangun dengan cara yang berbeda, tetapi mencapai tujuan yang sama pada akhirnya.
  • Ketika loop selesai dan panjangnya hilang, itu benar-benar mengakhiri string, menetapkan \0byte.
  • Ini mengembalikan string yang disandikan.

Perbedaan:

  • UrlEncode memeriksa ruang, memberikan tanda +, RawURLEncode tidak.
  • UrlEncode tidak menetapkan \0byte ke string, RawUrlEncode tidak (ini mungkin titik diperdebatkan)
  • Mereka beralih secara berbeda, seseorang mungkin cenderung meluap dengan string yang cacat, saya hanya menyarankan ini dan saya belum benar - benar menyelidiki.

Mereka pada dasarnya beralih secara berbeda, seseorang memberikan tanda + pada acara ASCII 20.

Perbedaan dalam EBCDIC:

URLENCODE:

  • Pengaturan iterasi yang sama dengan ASCII
  • Masih menerjemahkan karakter "spasi" menjadi tanda + . Catatan - Saya pikir ini perlu dikompilasi dalam EBCDIC atau Anda akan berakhir dengan bug? Dapatkah seseorang mengedit dan mengkonfirmasi ini?
  • Hal memeriksa apakah char sekarang adalah char sebelum 0, dengan pengecualian menjadi .atau -, OR kurang dari Anamun lebih besar dari arang 9, OR lebih besar dari Zdan kurang dari atapi bukan _. ATAU lebih besar dari z(yeah, EBCDIC agak kacau untuk bekerja dengannya). Jika cocok dengan semua itu, lakukan pencarian serupa seperti yang ditemukan di versi ASCII (hanya saja tidak memerlukan pencarian di os_toascii).

RAWURLENCODE:

  • Pengaturan iterasi yang sama dengan ASCII
  • Pemeriksaan yang sama seperti yang dijelaskan dalam versi EBCDIC dari URL Encode, dengan pengecualian jika lebih besar dari zitu, tidak termasuk ~dari URL encode.
  • Tugas yang sama dengan kode ASCII RawUrlEncode
  • Masih menambahkan \0byte ke string sebelum kembali.

Ringkasan Besar

  • Keduanya menggunakan tabel pencarian hexchars yang sama
  • URIEncode tidak mengakhiri string dengan \ 0, raw tidak.
  • Jika Anda bekerja di EBCDIC, saya sarankan menggunakan RawUrlEncode, karena ia mengelola ~UrlEncode yang tidak ( ini masalah yang dilaporkan ). Perlu dicatat bahwa ASCII dan EBCDIC 0x20 sama-sama ruang.
  • Mereka beralih secara berbeda, satu mungkin lebih cepat, satu mungkin rentan terhadap eksploitasi berbasis memori atau string.
  • URIEncode membuat spasi menjadi +, RawUrlEncode membuat spasi menjadi %20melalui pencarian array.

Penafian: Saya belum menyentuh C selama bertahun-tahun, dan saya belum melihat EBCDIC dalam waktu yang sangat lama. Jika saya salah di suatu tempat, beri tahu saya.

Implementasi yang disarankan

Berdasarkan semua ini, rawurlencode adalah cara untuk pergi sebagian besar waktu. Seperti yang Anda lihat dalam jawaban Jonathan Fingland, tetap gunakan dalam kebanyakan kasus. Ini berkaitan dengan skema modern untuk komponen URI, di mana urlencode melakukan sesuatu dengan cara lama, di mana + berarti "ruang."

Jika Anda mencoba mengonversi antara format lama dan format baru, pastikan kode Anda tidak naik dan mengubah sesuatu yang diberi tanda + diterjemahkan menjadi ruang dengan penyandian ganda tanpa sengaja, atau skenario "oops" serupa di sekitar ini ruang / 20% / + masalah.

Jika Anda bekerja pada sistem yang lebih lama dengan perangkat lunak yang lebih tua yang tidak menyukai format baru, tetap menggunakan urlencode, namun, saya yakin% 20 akan benar-benar kompatibel, seperti di bawah standar lama% 20 bekerja, hanya saja tidak lebih disukai. Cobalah jika Anda ingin bermain-main, beri tahu kami cara kerjanya untuk Anda.

Pada dasarnya, Anda harus tetap menggunakan mentah, kecuali jika sistem EBCDIC Anda benar-benar membenci Anda. Sebagian besar programmer tidak akan pernah mengalami EBCDIC pada sistem apa pun yang dibuat setelah tahun 2000, bahkan mungkin tahun 1990 (itu mendorong, tetapi masih mungkin menurut saya).

Penyamaran
sumber
Saya tidak pernah perlu khawatir tentang pengkodean ganda setelah semua saya harus tahu apa yang saya telah dikodekan karena saya melakukan pengkodean saya akan berpikir. Karena saya mendekode semua yang saya terima dengan mode kompatibilitas yang tahu cara memperlakukan + untuk ruang, saya sama-sama tidak pernah menemukan masalah yang Anda coba peringatkan di sini. Saya dapat memahami melihat sumbernya jika kita tidak tahu apa yang dilakukan sesuatu, tetapi apa sebenarnya yang kita pelajari di sini yang belum kita ketahui dari hanya menjalankan kedua fungsi. Saya tahu saya bias tetapi saya tidak bisa tidak berpikir ini terlalu berlebihan. Kudos atas upaya ini! =)
nickl-
2
+1, untuk bagian ini: "Saya percaya% 20 akan benar-benar kompatibel, karena di bawah standar lama% 20 berfungsi, tidak disukai"
Gras Double
3
Jawaban yang bagus, tapi mungkin sedikit berlebihan?
rinogo
38
echo rawurlencode('http://www.google.com/index.html?id=asd asd');

hasil panen

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

sementara

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

hasil panen

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

Perbedaannya adalah asd%20asdvsasd+asd

urlencode berbeda dari RFC 1738 dengan menyandikan spasi sebagai +ganti%20

naik opelet
sumber
28

Salah satu alasan praktis untuk memilih satu dari yang lain adalah jika Anda akan menggunakan hasilnya di lingkungan lain, misalnya JavaScript.

Dalam PHP urlencode('test 1')kembali 'test+1'sementara rawurlencode('test 1')kembali 'test%201'sebagai hasilnya.

Tetapi jika Anda perlu "mendekode" ini dalam JavaScript menggunakan fungsi decodeURI () maka decodeURI("test+1")akan memberi Anda "test+1"saat decodeURI("test%201")akan memberi Anda "test 1"hasilnya.

Dengan kata lain spasi ("") yang disandikan oleh urlencode menjadi plus ("+") di PHP tidak akan diterjemahkan dengan benar oleh decodeURI dalam JavaScript.

Dalam kasus seperti itu, fungsi PHP rawurlencode harus digunakan.

Neven Boyanov
sumber
6
Sejauh ini, inilah jawaban terbaik yang pernah saya lihat. Ini memberikan saran untuk digunakan, kembali dengan contoh dunia nyata. Selain itu, ringkas.
dotancohen
Ini adalah contoh yang bagus, meskipun saya lebih suka json_encodedan JSON.parseuntuk tujuan itu.
Fabrício Matté
21

Saya percaya spasi harus disandikan sebagai:

  • %20 bila digunakan di dalam komponen jalur URL
  • +bila digunakan di dalam komponen string kueri URL atau data formulir (lihat 17.13.4 Jenis konten formulir )

Contoh berikut menunjukkan penggunaan rawurlencodedan urlencode:

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

Keluaran:

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

Apa yang terjadi jika Anda menyandikan komponen jalur dan kueri string sebaliknya? Untuk contoh berikut:

http://example.com/category/latest+songs/search?q=lady%20gaga
  • Server web akan mencari direktori latest+songsalih-alihlatest songs
  • Parameter string kueri qakan berisilady gaga
Salman A
sumber
2
"Parameter string kueri qakan berisi lady gaga" Apa lagi yang akan dikandungnya? Parameter kueri qtampaknya memiliki nilai yang sama diteruskan ke $_GETarray terlepas dari menggunakan rawurlencodeatau urlencodedalam PHP 5.2+. Meskipun, urlencodemengkodekan dalam application/x-www-form-urlencodedformat yang default untuk permintaan GET jadi saya akan pergi dengan pendekatan Anda. +1
Fabrício Matté
2
Saya ingin menjelaskan bahwa keduanya +dan %20diterjemahkan sebagai ruang ketika digunakan dalam string kueri.
Salman A
5

Perbedaannya adalah dalam nilai kembali, yaitu:

urlencode () :

Mengembalikan string di mana semua karakter non-alfanumerik kecuali -_. telah diganti dengan tanda persen (%) diikuti oleh dua digit heksa dan spasi dikodekan sebagai tanda plus (+). Itu dikodekan dengan cara yang sama bahwa data yang diposting dari formulir WWW dikodekan, itu adalah cara yang sama seperti dalam jenis media application / x-www-form-urlencoded. Ini berbeda dengan pengkodean »RFC 1738 (lihat rawurlencode ()) karena alasan historis, spasi dikodekan sebagai tanda tambah (+).

rawurlencode () :

Mengembalikan string di mana semua karakter non-alfanumerik kecuali -_. telah diganti dengan tanda persen (%) diikuti oleh dua digit hex. Ini adalah pengkodean yang dijelaskan dalam »RFC 1738 untuk melindungi karakter literal dari ditafsirkan sebagai pembatas URL khusus, dan untuk melindungi URL agar tidak hancur oleh media transmisi dengan konversi karakter (seperti beberapa sistem email).

Keduanya sangat mirip, tetapi yang terakhir (rawurlencode) akan menggantikan spasi dengan '%' dan dua digit hex, yang cocok untuk menyandi kata sandi atau semacamnya, di mana '+' tidak misalnya:

echo '<a href="ftp://user:', rawurlencode('foo @+%/'),
     '@ftp.example.com/x.txt">';
//Outputs <a href="ftp://user:foo%20%40%2B%25%[email protected]/x.txt">
karim79
sumber
2
OP bertanya bagaimana cara mengetahui mana yang harus digunakan, dan kapan. Mengetahui apa yang dilakukan masing-masing dengan spasi tidak membantu OP untuk membuat keputusan jika dia tidak tahu pentingnya nilai pengembalian yang berbeda.
dotancohen
5

1. Apa perbedaan sebenarnya dan

Satu-satunya perbedaan adalah dalam cara ruang diperlakukan:

urlencode - berdasarkan implementasi lama mengkonversi spasi menjadi +

rawurlencode - berdasarkan RFC 1738 menerjemahkan spasi menjadi% 20

Alasan perbedaannya adalah karena + dicadangkan dan valid (tidak terenkripsi) dalam url.

2. mana yang lebih disukai?

Saya benar-benar ingin melihat beberapa alasan untuk memilih salah satu dari yang lain ... Saya ingin dapat memilih satu dan menggunakannya selamanya dengan sedikit keributan.

Cukup adil, saya memiliki strategi sederhana yang saya ikuti ketika membuat keputusan ini yang akan saya bagikan kepada Anda dengan harapan itu dapat membantu.

Saya pikir itu adalah spesifikasi HTTP / 1.1 RFC 2616 yang menyerukan " Aplikasi toleran "

Klien HARUS toleran dalam menguraikan Status-Line dan server toleran saat menguraikan Request-Line.

Ketika dihadapkan dengan pertanyaan seperti ini, strategi terbaik adalah selalu mengkonsumsi sebanyak mungkin dan menghasilkan apa yang sesuai standar.

Jadi saran saya adalah menggunakan rawurlencodeuntuk menghasilkan string yang disandikan standar RFC 1738 dan digunakan urldecodeagar kompatibel dengan belakang dan mengakomodasi apa pun yang mungkin Anda temui untuk dikonsumsi.

Sekarang Anda bisa mengambil kata saya untuk itu tetapi mari kita buktikan kalau kita ...

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

Tampaknya PHP memiliki pemikiran yang persis seperti ini, walaupun saya belum pernah menemukan orang yang menolak salah satu dari kedua format tersebut, saya tidak dapat memikirkan strategi yang lebih baik untuk diadopsi sebagai strategi defacto Anda, bukan?

nJoy!

nickl-
sumber
4

urlencode : Ini berbeda dengan pengkodean »RFC 1738 (lihat rawurlencode ()) karena alasan historis, spasi dikodekan sebagai tanda plus (+).

Remus Rusanu
sumber
2

Ruang dikodekan sebagai %20vs+

Alasan terbesar yang saya lihat digunakan rawurlencode()dalam kebanyakan kasus adalah karena urlencodemenyandikan ruang teks sebagai +(plus tanda) di mana rawurlencodemenyandikannya sebagai yang biasa dilihat %20:

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

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

Saya telah secara khusus melihat titik akhir API tertentu yang menerima kueri teks yang dikodekan berharap melihat %20spasi dan sebagai hasilnya, gagal jika tanda tambah digunakan sebagai gantinya. Jelas ini akan berbeda antara implementasi API dan jarak tempuh Anda mungkin berbeda.

Jake Wilson
sumber
1

Saya percaya urlencode adalah untuk parameter kueri, sedangkan rawurlencode adalah untuk segmen path. Ini terutama disebabkan oleh %20untuk segmen jalur vs +untuk parameter kueri. Lihat jawaban ini yang berbicara tentang spasi: Kapan menyandikan spasi ke plus (+) atau% 20?

Namun %20sekarang juga berfungsi dalam parameter kueri, itulah sebabnya rawurlencode selalu lebih aman. Namun tanda plus cenderung digunakan di mana pengalaman pengguna dalam mengedit dan keterbacaan parameter kueri menjadi penting.

Perhatikan bahwa ini berarti rawurldecodetidak memecahkan kode +ke spasi ( http://au2.php.net/manual/en/function.rawurldecode.php ). Inilah sebabnya $ _GET selalu dilewati secara otomatis urldecode, yang berarti bahwa +dan %20keduanya diterjemahkan ke dalam spasi.

Jika Anda ingin pengkodean dan dekode konsisten antara input dan output dan Anda telah memilih untuk selalu menggunakan +dan bukan %20untuk parameter kueri, maka boleh untuk parameter urlencodekueri (kunci dan nilai).

Kesimpulannya adalah:

Segmen Jalur - selalu gunakan rawurlencode / rawurldecode

Parameter Kueri - untuk mendekode selalu menggunakan urldecode (dilakukan secara otomatis), untuk pengkodean, baik rawurlencode atau urlencode baik-baik saja, cukup pilih satu yang konsisten, terutama ketika membandingkan URL.

CMCDragonkai
sumber
0

simple * rawurlencode path - path adalah bagian sebelum "?" - spasi harus disandikan sebagai% 20 * urlencode string kueri - String kueri adalah bagian setelah "?" -spasi disandikan lebih baik karena "+" = rawurlencode lebih kompatibel secara umum

haysam elmasry
sumber