PHP'de bir dizeyi doğru bir şekilde URL kodlaması nasıl yapılır?


98

Bir arama sorgusu yazdığınız ve formun gönderildiği bir arama sayfası yapıyorum search.php?query=your query. Hangi PHP işlevi en iyisidir ve arama sorgusunu kodlamak / kodunu çözmek için kullanmalıyım?


2
Herhangi bir sorun yaşıyor musunuz? Tarayıcılar ve PHP bunu otomatik olarak halihazırda halletmelidir (örneğin foo barbir metin alanı koymak foo+bar, URL'de oluşturur ).
Felix Kling

@Felix Arama komut dosyasını kullanarak arayacağımfile_get_contents
36'da Ek Oyu tıklayın

Yanıtlar:


185

URI sorgusu için urlencode/ urldecode; başka herhangi bir şey için rawurlencode/ kullanın rawurldecode.

Arasındaki fark urlencodeve rawurlencodeolmasıdır


application / x-www-form-urlencoded , Yüzde Kodlamanın yalnızca özel bir varyantıdır ve yalnızca HTML form verilerini kodlamak için uygulanır.
Gumbo

1
@ Upvote'a tıklayın: Bu şekilde karşılaştırılamazlar. Uygulama / x-www-form-urlencoded biçimi olan Yüzde-Encoding alanı ile kodlanır dışında biçimi +yerine %20. Bunun yanı sıra application / x-www-form-urlencoded form verilerini kodlamak için kullanılırken Yüzde Kodlama daha genel bir kullanıma sahiptir.
Gumbo

13
rawurlencode () JavaScript uyumlu decodeURI () işlev
Clive Paterson

Bu kural her zaman ampirik mi? Demek istediğim, bir sorgu dizesini kodlamam gerektiğinde her zaman kullanırım urldecode. Öyleyse, URI yolu (ör. /a/path with spaces/) Ve URI parçası (ör. #fragment)? rawurldecodeBu ikisi için her zaman kullanmalı mıyım ?
tonix

İyi bir genel kural, yolların (Like / my% 20folder /) birlikte gitmesidir rawurlencode; ancak POST ve GET alanları için urlencode(Beğen /? klasörüm + klasörüm) ``
Soroush Falahati

23

Kurnazca adlandırılmış urlencode () ve urldecode () .

Ancak, ve urldecode()içinde görünen değişkenler üzerinde kullanmanız gerekmemelidir .$_POST$_GET


4
urldecode () neden $ _POST ile kullanılmaması gerektiğini açıklar mısınız? çünkü bunu çağlardan beri sorunsuz yapıyorum.
sid

"name=b&age=c&location=d"AJAX aracılığıyla bir PHP dosyasına gönderilen temel parametreleri (örneğin ) kodlamam gerekir mi?
oldboy

11

İşte olağanüstü miktarda kodlama gerektiren kullanım durumum. Belki uydurduğunu düşünüyorsunuz, ama bunu prodüksiyon üzerinde yürütüyoruz. Tesadüfen, bu her tür kodlamayı kapsar, bu yüzden bir eğitim olarak gönderiyorum.

Durum açıklamasını kullan

Birisi web sitemizden ön ödemeli bir hediye kartı ("jeton") satın aldı. Jetonların kullanılması için karşılık gelen URL'leri vardır. Bu müşteri URL'yi başka birine e-posta ile göndermek istiyor. Web sayfamız, mailtobunu yapmalarına izin veren bir bağlantı içerir .

PHP kodu

// 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>';

Not: Yukarıdakiler bir text/htmlbelgeye çıktı aldığınızı varsayar . Çıktı ortam türünüz ise, text/jsono zaman kullanın $retval['url'] = $mailToUri;çünkü çıktı kodlaması işlenir json_encode().

Test durumu

  1. Kodu bir PHP test sitesinde çalıştırın ( burada bahsetmem gereken kanonik bir site var mı? )
  2. Linke tıklayınız
  3. E-postayı gönder
  4. E-postayı alın
  5. O bağlantıya tıklayın

Görmelisin:

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

Ve elbette bu, $tokenyukarıdaki JSON temsilidir .


Eşit ve anlamsal olarak daha az (çünkü mailto:HTTP olmadığı için) kullanabilirsiniz $mailToUri 'mailto:?' . http_build_query(['subject'=>$subject, 'body'=>$body], null, '&', PHP_QUERY_RFC3986);.
William Entriken

0

URL Kodlama İşlevlerini kullanabilirsiniz PHP'nin sahip olduğu

rawurlencode() 

işlevi

ASP,

Server.URLEncode() 

işlevi

JavaScript'te

encodeURIComponent() 

işlevi.


0

Ne tür bir RFC standart kodlaması gerçekleştirmek istediğinize bağlı olarak veya kodlamanızı özelleştirmeniz gerekiyorsa kendi sınıfınızı oluşturmak isteyebilirsiniz.

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

Örnek kullanın:

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

Çıktı:

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 standartları hakkında daha fazla bilgi edinin: https://datatracker.ietf.org/doc/rfc3986/ ve urlencode vs rawurlencode?

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.