Làm thế nào để mã hóa đúng URL một chuỗi trong PHP?


97

Tôi đang tạo một trang tìm kiếm, nơi bạn nhập một truy vấn tìm kiếm và biểu mẫu được gửi đến search.php?query=your query. Hàm PHP nào là tốt nhất và tôi nên sử dụng để mã hóa / giải mã truy vấn tìm kiếm?


2
Bạn có gặp bất kỳ vấn đề? Trình duyệt và PHP sẽ tự động xử lý điều này (ví dụ: đưa foo barvào trường văn bản, tạo foo+bartrong URL).
Felix Kling,

@Felix Tôi sẽ gọi tập lệnh cho người tìm kiếm bằng cách sử dụngfile_get_contents
Nhấp vào ủng hộ

Câu trả lời:


183

Đối với truy vấn URI, hãy sử dụng urlencode/ urldecode; cho bất cứ điều gì khác sử dụng rawurlencode/ rawurldecode.

Sự khác biệt giữa urlencoderawurlencode


application / x-www-form-urlencoded chỉ là một biến thể đặc biệt của Percent-Encoding và chỉ được áp dụng để mã hóa dữ liệu biểu mẫu HTML.
Gumbo

1
@Click Upvote: Không thể so sánh chúng theo cách đó. Các application / x-www-form-urlencoded định dạng các Percent-Encoding dạng ngoại trừ việc không gian được mã hóa với +thay vì %20. Và bên cạnh đó, application / x-www-form-urlencoded được sử dụng để mã hóa dữ liệu biểu mẫu trong khi Percent-Encoding có cách sử dụng chung hơn.
Gumbo

12
rawurlencode () là tương thích với javascript decodeURI () chức năng
Clive Paterson

Quy tắc này có luôn là quy tắc thực nghiệm không? Ý tôi là, khi tôi cần mã hóa một chuỗi truy vấn, tôi luôn sử dụng urldecode. Sau đó, những gì về đường dẫn URI (ví dụ /a/path with spaces/) và phân đoạn URI (ví dụ #fragment). Tôi có nên luôn luôn sử dụng rawurldecodecho hai?
tonix

Một nguyên tắc nhỏ là đối với các đường dẫn (Like / my% 20folder /) hãy đi với rawurlencode; nhưng đối với POST và GET lĩnh vực đi với urlencode(Giống như / folder = thư mục của tôi +?) `
Soroush Falahati

22

Các cunningly tên urlencode ()urldecode () .

Tuy nhiên, bạn không cần phải sử dụng urldecode()trên các biến xuất hiện trong $_POST$_GET.


4
bạn có thể vui lòng giải thích tại sao urldecode () không nên được sử dụng với $ _POST. bởi vì tôi đã làm điều đó từ nhiều năm nay mà không gặp bất kỳ vấn đề gì.
sid

tôi có cần mã hóa các thông số cơ bản (ví dụ "name=b&age=c&location=d") được gửi đến tệp PHP qua AJAX không?
oldboy

9

Đây là trường hợp sử dụng của tôi, yêu cầu số lượng mã hóa đặc biệt. Có thể bạn nghĩ rằng nó đã tạo ra, nhưng chúng tôi chạy điều này trên sản xuất. Thật trùng hợp, điều này bao gồm mọi loại mã hóa, vì vậy tôi đăng dưới dạng hướng dẫn.

Mô tả ca sử dụng

Ai đó vừa mua thẻ quà tặng trả trước ("mã thông báo") trên trang web của chúng tôi. Token có các URL tương ứng để đổi chúng. Khách hàng này muốn gửi URL qua email cho người khác. Trang web của chúng tôi bao gồm một mailtoliên kết cho phép họ làm điều đó.

Mã 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>';

Lưu ý: ở trên giả sử bạn đang xuất ra một text/htmltài liệu. Nếu loại phương tiện đầu ra của bạn text/jsonthì chỉ cần sử dụng $retval['url'] = $mailToUri;vì mã hóa đầu ra được xử lý bởijson_encode() .

Trường hợp thử nghiệm

  1. Chạy mã trên trang web thử nghiệm PHP ( trang web chính tắc nào mà tôi nên đề cập ở đây không? )
  2. Nhấp vào liên kết
  3. Gửi email
  4. Nhận email
  5. Nhấp vào liên kết đó

Bạn nên thấy:

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

Và tất nhiên đây là đại diện JSON $tokenở trên.


mailto:Bạn có thể sử dụng một cách tương đương và ít ngữ nghĩa hơn (vì không phải là HTTP) $mailToUri 'mailto:?' . http_build_query(['subject'=>$subject, 'body'=>$body], null, '&', PHP_QUERY_RFC3986);.
William Entriken

0

Bạn có thể sử dụng các chức năng mã hóa URL PHP có

rawurlencode() 

chức năng

ASP có

Server.URLEncode() 

chức năng

Trong JavaScript, bạn có thể sử dụng

encodeURIComponent() 

chức năng.


0

Dựa trên loại mã hóa tiêu chuẩn RFC bạn muốn thực hiện hoặc nếu bạn cần tùy chỉnh mã hóa của mình, bạn có thể muốn tạo lớp của riêng mình.

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

Sử dụng ví dụ:

$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);

Sẽ xuất:

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)"

* Tìm hiểu thêm về các tiêu chuẩn RFC: https://datatracker.ietf.org/doc/rfc3986/urlencode so với rawurlencode?

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.