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?
php
urlencode
url-encoding
Gary Willoughby
sumber
sumber
rawurlencode
. Anda jarang akan berjalan ke sistem yang tersedak ketika diberi spasi yang dikodekan%20
, sedangkan sistem yang tersedak seperti+
yang lebih umum.Jawaban:
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 )
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
%20
seperti yang dilakukan pada rawurlencode) (lihat http://us2.php.net/manual/en/function.urlencode.php )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:
Seperti yang Anda lihat, itu
+
adalah karakter yang dicadangkan dalam string kueri dan karenanya harus dikodekan sesuai RFC 3986 (seperti dalam rawurlencode).sumber
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 ()
UrlEncode ()
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
Dan tentu saja, php_url_encode:
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
L
di 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)
hexchars
untuk mendapatkan beberapa nilai, array digambarkan seperti itu:Selain itu, fungsinya sangat berbeda, dan saya akan menjelaskannya dalam ASCII dan EBCDIC.
Perbedaan dalam ASCII:
URLENCODE:
+
tanda ke string output.isalnum(c)
), dan juga bukan dan_
,,-
atau.
karakter, maka kita, menampilkan%
tanda ke posisi array 0, melakukan pencarian array kehexchars
array untuk pencarianos_toascii
array () sebuah array dari Apache yang menerjemahkan char ke hex code) untuk kuncic
(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._-.
karakter, itu menghasilkan persis apa itu.RAWURLENCODE:
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
x
dany
, memeriksa untuk keluar padalen
mencapai 0, dan meningkatkan keduanyax
dany
. Saya tahu, itu bukan yang Anda harapkan, tapi itu kode yang valid.str
._-.
karakter, dan jika tidak, kami melakukan tugas yang hampir sama seperti dengan URLENCODE di mana ia membentuk pencarian sebelumnya, namun, kami menambah secara berbeda, menggunakany++
daripadato[1]
, ini karena string sedang dibangun dengan cara yang berbeda, tetapi mencapai tujuan yang sama pada akhirnya.\0
byte.Perbedaan:
\0
byte ke string, RawUrlEncode tidak (ini mungkin titik diperdebatkan)Mereka pada dasarnya beralih secara berbeda, seseorang memberikan tanda + pada acara ASCII 20.
Perbedaan dalam EBCDIC:
URLENCODE:
0
, dengan pengecualian menjadi.
atau-
, OR kurang dariA
namun lebih besar dari arang9
, OR lebih besar dariZ
dan kurang daria
tapi bukan_
. ATAU lebih besar dariz
(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:
z
itu, tidak termasuk~
dari URL encode.\0
byte ke string sebelum kembali.Ringkasan Besar
~
UrlEncode yang tidak ( ini masalah yang dilaporkan ). Perlu dicatat bahwa ASCII dan EBCDIC 0x20 sama-sama ruang.+
, RawUrlEncode membuat spasi menjadi%20
melalui 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).
sumber
hasil panen
sementara
hasil panen
Perbedaannya adalah
asd%20asd
vsasd+asd
urlencode berbeda dari RFC 1738 dengan menyandikan spasi sebagai
+
ganti%20
sumber
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'
sementararawurlencode('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"
saatdecodeURI("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.
sumber
json_encode
danJSON.parse
untuk tujuan itu.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
rawurlencode
danurlencode
:Keluaran:
Apa yang terjadi jika Anda menyandikan komponen jalur dan kueri string sebaliknya? Untuk contoh berikut:
latest+songs
alih-alihlatest songs
q
akan berisilady gaga
sumber
q
akan berisilady gaga
" Apa lagi yang akan dikandungnya? Parameter kueriq
tampaknya memiliki nilai yang sama diteruskan ke$_GET
array terlepas dari menggunakanrawurlencode
atauurlencode
dalam PHP 5.2+. Meskipun,urlencode
mengkodekan dalamapplication/x-www-form-urlencoded
format yang default untuk permintaan GET jadi saya akan pergi dengan pendekatan Anda. +1+
dan%20
diterjemahkan sebagai ruang ketika digunakan dalam string kueri.Perbedaannya adalah dalam nilai kembali, yaitu:
urlencode () :
rawurlencode () :
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:
sumber
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?
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 "
Ketika dihadapkan dengan pertanyaan seperti ini, strategi terbaik adalah selalu mengkonsumsi sebanyak mungkin dan menghasilkan apa yang sesuai standar.
Jadi saran saya adalah menggunakan
rawurlencode
untuk menghasilkan string yang disandikan standar RFC 1738 dan digunakanurldecode
agar 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 ...
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!
sumber
sumber
Ruang dikodekan sebagai
%20
vs+
Alasan terbesar yang saya lihat digunakan
rawurlencode()
dalam kebanyakan kasus adalah karenaurlencode
menyandikan ruang teks sebagai+
(plus tanda) di manarawurlencode
menyandikannya sebagai yang biasa dilihat%20
:Saya telah secara khusus melihat titik akhir API tertentu yang menerima kueri teks yang dikodekan berharap melihat
%20
spasi dan sebagai hasilnya, gagal jika tanda tambah digunakan sebagai gantinya. Jelas ini akan berbeda antara implementasi API dan jarak tempuh Anda mungkin berbeda.sumber
Saya percaya urlencode adalah untuk parameter kueri, sedangkan rawurlencode adalah untuk segmen path. Ini terutama disebabkan oleh
%20
untuk segmen jalur vs+
untuk parameter kueri. Lihat jawaban ini yang berbicara tentang spasi: Kapan menyandikan spasi ke plus (+) atau% 20?Namun
%20
sekarang 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
rawurldecode
tidak memecahkan kode+
ke spasi ( http://au2.php.net/manual/en/function.rawurldecode.php ). Inilah sebabnya $ _GET selalu dilewati secara otomatisurldecode
, yang berarti bahwa+
dan%20
keduanya diterjemahkan ke dalam spasi.Jika Anda ingin pengkodean dan dekode konsisten antara input dan output dan Anda telah memilih untuk selalu menggunakan
+
dan bukan%20
untuk parameter kueri, maka boleh untuk parameterurlencode
kueri (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.
sumber
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
sumber