วิธีการเข้ารหัส URL อย่างถูกต้องใน PHP?


100

search.php?query=your queryฉันทำหน้าค้นหาที่คุณพิมพ์คำค้นหาและส่งแบบฟอร์มการ PHP ฟังก์ชั่นใดดีที่สุดและฉันควรใช้ในการเข้ารหัส / ถอดรหัสคำค้นหา


2
คุณประสบปัญหาใด ๆ หรือไม่? เบราว์เซอร์และ PHP ควรจัดการสิ่งนี้โดยอัตโนมัติอยู่แล้ว (เช่นใส่foo barช่องข้อความสร้างfoo+barใน URL)
Felix Kling

@Felix ฉันจะเรียกสคริปต์ผู้ค้นหาโดยใช้file_get_contents
Click Upvote

คำตอบ:


187

สำหรับแบบสอบถาม URI ให้ใช้urlencode/ urldecode; สำหรับสิ่งอื่นที่ใช้rawurlencode/ rawurldecode.

ความแตกต่างระหว่างurlencodeและrawurlencodeก็คือ

  • urlencodeเข้ารหัสตามapplication / x-www-form-urlencoded (มีการเข้ารหัสช่องว่างด้วย+) while
  • rawurlencodeเข้ารหัสตามPercent-Encodingธรรมดา(พื้นที่ถูกเข้ารหัสด้วย%20)

application / x-www-form-urlencodedเป็นเพียงตัวแปรพิเศษของการเข้ารหัสเปอร์เซ็นต์และใช้กับการเข้ารหัสข้อมูลในรูปแบบ HTML เท่านั้น
Gumbo

1
@Click Upvote: พวกเขาไม่สามารถเปรียบเทียบในลักษณะนั้นได้ / x-www ฟอร์ม urlencoded การประยุกต์ใช้รูปแบบเป็นเข้ารหัสเปอร์เซ็นต์รูปแบบยกเว้นว่าพื้นที่ที่ถูกเข้ารหัสด้วยแทน+ %20และนอกจากนั้นapplication / x-www-form-urlencodedยังใช้เพื่อเข้ารหัสข้อมูลในรูปแบบในขณะที่Percent-Encodingมีการใช้งานทั่วไปมากกว่า
Gumbo

13
rawurlencode ()เข้ากันได้กับจาวาสคริปต์decodeURI ()ฟังก์ชั่น
ไคลฟ์แพ็ตเตอร์สัน

กฎนี้เป็นกฎเชิงประจักษ์เสมอไปหรือไม่? urldecodeผมหมายถึงเมื่อฉันต้องเข้ารหัสสตริงแบบสอบถามฉันใช้เสมอ แล้วเส้นทาง URI (เช่น/a/path with spaces/) และส่วน URI (เช่น#fragment) ล่ะ ฉันควรใช้rawurldecodeสำหรับสองสิ่งนี้เสมอหรือไม่?
tonix

หลักการง่ายๆคือสำหรับเส้นทาง (Like / my% 20folder /) ไปด้วยrawurlencode; แต่สำหรับช่อง POST และ GET ให้ไปกับurlencode(Like /? folder = my + folder) `
Soroush Falahati

23

ตลบตะแลงชื่อurlencode ()และurldecode ()

อย่างไรก็ตามคุณไม่จำเป็นต้องใช้urldecode()กับตัวแปรที่ปรากฏใน$_POSTและ$_GET.


4
คุณช่วยอธิบายให้ละเอียดได้ไหมว่าทำไม urldecode () ไม่ควรใช้กับ $ _POST เพราะฉันทำแบบนั้นมาตลอดโดยไม่มีปัญหา
sid

ฉันต้องเข้ารหัสพารามิเตอร์พื้นฐาน (เช่น"name=b&age=c&location=d") ที่ส่งไปยังไฟล์ PHP ผ่าน AJAX หรือไม่
oldboy

11

นี่คือกรณีการใช้งานของฉันซึ่งต้องใช้การเข้ารหัสจำนวนมากเป็นพิเศษ บางทีคุณอาจคิดว่ามันสร้างขึ้น แต่เราดำเนินการผลิต บังเอิญว่าสิ่งนี้ครอบคลุมการเข้ารหัสทุกประเภทดังนั้นฉันจึงโพสต์เป็นบทช่วยสอน

ใช้คำอธิบายกรณี

ใครบางคนเพิ่งซื้อบัตรของขวัญแบบเติมเงิน ("โทเค็น") บนเว็บไซต์ของเรา โทเค็นมี URL ที่สอดคล้องกันเพื่อแลกใช้ ลูกค้ารายนี้ต้องการส่งอีเมล URL ไปให้คนอื่น หน้าเว็บของเรามีmailtoลิงค์ที่ให้พวกเขาทำเช่นนั้น

โค้ด PHP

// The order system generates some opaque token
$token = 'w%a&!e#"^2(^@azW';

// Here is a URL to redeem that token
$redeemUrl = 'https://httpbin.org/get?token=' . urlencode($token);

// Actual contents we want for the email
$subject = 'I just bought this for you';
$body = 'Please enter your shipping details here: ' . $redeemUrl;

// A URI for the email as prescribed
$mailToUri = 'mailto:?subject=' . rawurlencode($subject) . '&body=' . rawurlencode($body);

// Print an HTML element with that mailto link
echo '<a href="' . htmlspecialchars($mailToUri) . '">Email your friend</a>';

หมายเหตุ: ข้างต้นถือว่าคุณกำลังส่งออกไปยังtext/htmlเอกสาร หากประเภทสื่อเอาต์พุตของคุณtext/jsonใช้เพียง$retval['url'] = $mailToUri;เพราะการเข้ารหัสเอาต์พุตถูกจัดการโดยjson_encode().

กรณีทดสอบ

  1. เรียกใช้โค้ดบนไซต์ทดสอบ PHP ( มีมาตรฐานที่ฉันควรพูดถึงที่นี่หรือไม่ )
  2. คลิกที่ลิงค์
  3. ส่งอีเมล
  4. รับอีเมล
  5. คลิกลิงก์นั้น

คุณควรเห็น:

"args": {
  "token": "w%a&!e#\"^2(^@azW"
}, 

และแน่นอนว่านี่คือการแสดง JSON $tokenด้านบน


mailto:คุณสามารถใช้ได้ในทาง$mailToUri 'mailto:?' . http_build_query(['subject'=>$subject, 'body'=>$body], null, '&', PHP_QUERY_RFC3986);เดียวกันและน้อยกว่า (เนื่องจากไม่ใช่ HTTP)
William Entriken

1

คุณสามารถใช้ฟังก์ชันการเข้ารหัส URL PHP มีไฟล์

rawurlencode() 

ฟังก์ชัน

ASP มีไฟล์

Server.URLEncode() 

ฟังก์ชัน

ใน JavaScript คุณสามารถใช้ไฟล์

encodeURIComponent() 

ฟังก์ชัน


0

ขึ้นอยู่กับประเภทของการเข้ารหัสมาตรฐาน RFC ที่คุณต้องการดำเนินการหรือหากคุณต้องการปรับแต่งการเข้ารหัสของคุณคุณอาจต้องการสร้างคลาสของคุณเอง

/**
 * UrlEncoder make it easy to encode your URL
 */
class UrlEncoder{
    public const STANDARD_RFC1738 = 1;
    public const STANDARD_RFC3986 = 2;
    public const STANDARD_CUSTOM_RFC3986_ISH = 3;
    // add more here

    static function encode($string, $rfc){
        switch ($rfc) {
            case self::STANDARD_RFC1738:
                return  urlencode($string);
                break;
            case self::STANDARD_RFC3986:
                return rawurlencode($string);
                break;
            case self::STANDARD_CUSTOM_RFC3986_ISH:
                // Add your custom encoding
                $entities = ['%21', '%2A', '%27', '%28', '%29', '%3B', '%3A', '%40', '%26', '%3D', '%2B', '%24', '%2C', '%2F', '%3F', '%25', '%23', '%5B', '%5D'];
                $replacements = ['!', '*', "'", "(", ")", ";", ":", "@", "&", "=", "+", "$", ",", "/", "?", "%", "#", "[", "]"];
                return str_replace($entities, $replacements, urlencode($string));
                break;
            default:
                throw new Exception("Invalid RFC encoder - See class const for reference");
                break;
        }
    }
}

ใช้ตัวอย่าง:

$dataString = "https://www.google.pl/search?q=PHP is **great**!&id=123&css=#kolo&email=me@liszka.com)";

$dataStringUrlEncodedRFC1738 = UrlEncoder::encode($dataString, UrlEncoder::STANDARD_RFC1738);
$dataStringUrlEncodedRFC3986 = UrlEncoder::encode($dataString, UrlEncoder::STANDARD_RFC3986);
$dataStringUrlEncodedCutom = UrlEncoder::encode($dataString, UrlEncoder::STANDARD_CUSTOM_RFC3986_ISH);

จะส่งออก:

string(126) "https%3A%2F%2Fwww.google.pl%2Fsearch%3Fq%3DPHP+is+%2A%2Agreat%2A%2A%21%26id%3D123%26css%3D%23kolo%26email%3Dme%40liszka.com%29"
string(130) "https%3A%2F%2Fwww.google.pl%2Fsearch%3Fq%3DPHP%20is%20%2A%2Agreat%2A%2A%21%26id%3D123%26css%3D%23kolo%26email%3Dme%40liszka.com%29"
string(86)  "https://www.google.pl/search?q=PHP+is+**great**!&id=123&css=#kolo&email=me@liszka.com)"

* ค้นหาข้อมูลเพิ่มเติมเกี่ยวกับมาตรฐาน RFC: https://datatracker.ietf.org/doc/rfc3986/ และurlencode เทียบกับ rawurlencode?

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.