urlencode बनाम rawurlencode?


380

यदि मैं एक वैरिएबल का उपयोग करके URL बनाना चाहता हूं तो स्ट्रिंग को एनकोड करने के लिए मेरे पास दो विकल्प हैं। urlencode()और rawurlencode()

वास्तव में क्या अंतर हैं और किसे प्राथमिकता दी जाती है?


1
मैं वास्तव में एक को चुनने के कुछ कारणों को देखना चाहता हूं (उदाहरण के लिए एक या दूसरे के साथ आने वाली समस्याएं), मैं (और मैं दूसरों से अपेक्षा करता हूं) सिर्फ एक को चुनने और इसे हमेशा के लिए उपयोग करने में सक्षम होना चाहता हूं। कम से कम उपद्रव, इसलिए मैंने इस प्रश्न पर एक इनाम शुरू किया है।
Kzqai

29
@Tllvak: अगर आप सिर्फ एक चुनना चाहते हैं, तो चुनें rawurlencode। आप शायद ही कभी एक सिस्टम में चले जाएँगे, जब दिए गए स्थान के रूप में इनकोडिंग चोक हो जाती है %20, जबकि सिस्टम जो कि रिक्त स्थान पर चोक हो +जाते हैं, अधिक सामान्य होते हैं।
एनोमि

जवाबों:


326

यह आपके उद्देश्य पर निर्भर करेगा। यदि अन्य प्रणालियों के साथ इंटरऑपरेबिलिटी महत्वपूर्ण है, तो ऐसा लगता है कि रॉर्लेंकोडोड जाने का रास्ता है। एक अपवाद विरासत प्रणाली है जो क्वेरी स्ट्रिंग को% 20 के बजाय + के रूप में एन्कोड किए गए रिक्त स्थान की प्रपत्र-एन्कोडिंग शैली का पालन करने की उम्मीद करती है (जिस स्थिति में आपको urlencode की आवश्यकता होती है)।

rawurlencode RFC 1738 से पहले PHP 5.3.0 और RFC 3986 के बाद आता है (देखें http://us2.php.net/manual/en/function.rawurlencode.php )

एक स्ट्रिंग देता है जिसमें सभी गैर-अल्फ़ान्यूमेरिक वर्णों को छोड़कर -_ ~ को दो प्रतिशत अंकों के बाद एक प्रतिशत (%) चिह्न के साथ बदल दिया जाता है। यह शाब्दिक वर्णों को विशेष URL सीमांकक के रूप में व्याख्या करने से बचाने के लिए »RFC 3986 में वर्णित एन्कोडिंग है, और URL को चरित्र रूपांतरण (जैसे कुछ ईमेल सिस्टम) के साथ ट्रांसमिशन मीडिया द्वारा मंगाई जाने से बचाने के लिए।

RFC 3986 बनाम 1738 पर ध्यान दें। php 5.3 से पहले rawurlencode ने ~RFC 1738 के अनुसार tilde character ( ) को इनकोड किया । PHP 5.3 के अनुसार, हालांकि, rawurlencode RFC 3986 का अनुसरण करता है जो कि tilde वर्ण को एन्कोड नहीं करता है।

urlencode प्लस चिन्हों के रूप में रिक्त स्थान को %20कूटता है (जैसा कि rawurlencode में नहीं किया गया है) (देखें http://us2.php.net/manual/en/function.urlencode.php )

एक स्ट्रिंग देता है जिसमें सभी गैर-अल्फ़ान्यूमेरिक वर्णों को छोड़कर -_। एक प्रतिशत (%) चिह्न के साथ दो हेक्स अंक और रिक्त स्थान प्लस (+) के संकेत के रूप में प्रतिस्थापित किए गए हैं। यह उसी तरह एन्कोड किया गया है जैसे कि WWW फॉर्म से पोस्ट किया गया डेटा एनकोड किया गया है, यह उसी तरह है जैसे एप्लिकेशन / x-www-form-urlencoded मीडिया प्रकार में। यह ऐतिहासिक कारणों से »RFC 3986 एन्कोडिंग (rawurlencode () देखें) से भिन्न है, रिक्त स्थान प्लस (+) संकेतों के रूप में एन्कोड किए गए हैं।

यह RFC 1866 में एप्लिकेशन / x-www-form-urlencoded के लिए परिभाषा से मेल खाती है ।

अतिरिक्त पढ़ना:

आप http://bytes.com/groups/php/5624-urlencode-vs-rawurlencode पर चर्चा देखना चाहते हैं ।

इसके अलावा, RFC 2396 एक देखने लायक है। RFC 2396 मान्य URI सिंटैक्स को परिभाषित करता है। जिस भाग में हम रुचि रखते हैं वह 3.4 क्वेरी घटक से है:

एक क्वेरी घटक के भीतर, वर्ण आरक्षित हैं।";", "/", "?", ":", "@",
"&", "=", "+", ",", and "$"

जैसा कि आप देख सकते हैं, +क्वेरी स्ट्रिंग में एक आरक्षित वर्ण है और इस प्रकार RFC 3986 (जैसा कि rawurlencode) के अनुसार इनकोड करना होगा।


27
तो कौन सा प्रचलित है?
गैरी विल्बोबी

79
rawurlencode। इस मामले में मानक के साथ जाएं। urlencode को केवल विरासत उपयोग के लिए रखा गया है
जोनाथन फिंगलैंड

2
महान धन्यवाद, मैं क्या सोचा था, मैं सिर्फ एक दूसरे की राय चाहता था इससे पहले कि मैं बहुत सारे कोड अपडेट करना शुरू कर दूं।
गैरी विल्लोबी

3
मुझे लगता है कि यह rawurlencode है जो रिक्त स्थान को सांकेतिक शब्दों में बदलना नहीं करता है लेकिन% 20s के रूप में है
BigName

2
@Pindatjuh: आपके द्वारा उद्धृत किया गया भाग एक अपवाद है विरासत प्रणाली जो क्वेरी स्ट्रिंग को% 20 के बजाय + के रूप में एन्कोड किए गए रिक्त स्थान की प्रपत्र-एन्कोडिंग शैली का पालन करने की अपेक्षा करती है (इस मामले में आपको urlencode की आवश्यकता होती है) का अर्थ है कि रॉउरेंडेकोड अधिकांश स्थिति के लिए सही है , कुछ प्रणालियाँ रिक्त स्थान को + (प्लस चिन्ह) के रूप में कूटबद्ध करने की अपेक्षा करती हैं। ऐसी प्रणालियों के लिए, urlencode बेहतर विकल्प है।
जोनाथन फिंगलैंड

213

सबूत PHP के स्रोत कोड में है।

मैं आपको भविष्य में किसी भी समय इस तरह की चीज़ का पता लगाने की एक त्वरित प्रक्रिया के माध्यम से ले जाऊंगा। मेरे साथ सहन करें, बहुत सारे सी सोर्स कोड होंगे जिन्हें आप स्किम कर सकते हैं (मैं इसे समझाता हूं)। यदि आप कुछ सी पर ब्रश करना चाहते हैं, तो शुरू करने के लिए एक अच्छी जगह हमारे एसओ विकी है

स्रोत डाउनलोड करें (या इसे ऑनलाइन ब्राउज़ करने के लिए http://lxr.php.net/ का उपयोग करें), फ़ंक्शन नाम के लिए सभी फ़ाइलों को grep करें, आपको कुछ इस तरह मिलेगा:

PHP 5.3.6 (लिखने के समय सबसे हाल का) फ़ाइल url.c में उनके मूल 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);
}

ठीक है, तो यहाँ क्या अलग है?

वे दोनों मूल रूप से क्रमशः दो अलग-अलग आंतरिक कार्यों को बुला रहे हैं: php_raw_url_encode और php_url_encode

तो उन कार्यों के लिए देखो!

आओ हम 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);
}

और हां, 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;
}

इससे पहले कि मैं आगे बढ़ूँ , ईबीसीडीआईसी एक और चरित्र सेट है , जो एएससीआईआई के समान है, लेकिन कुल प्रतियोगी है। PHP दोनों से निपटने का प्रयास करता है। लेकिन मूल रूप से, इसका मतलब यह है कि बाइट EBCDIC 0x4c बाइट LASCII में नहीं है , यह वास्तव में एक है <। मुझे यकीन है कि आपको यहाँ भ्रम दिखाई देगा।

यदि वेब सर्वर ने इसे परिभाषित किया है, तो ये दोनों फ़ंक्शन EBCDIC का प्रबंधन करते हैं।

इसके अलावा, वे दोनों hexcharsकुछ मूल्यों को प्राप्त करने के लिए एक सरणी ऑफ़ द चार्स (थिंक स्ट्रिंग प्रकार) लुक-अप का उपयोग करते हैं, सरणी को इस प्रकार वर्णित किया गया है:

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

इसके अलावा, कार्य वास्तव में अलग हैं, और मैं उन्हें ASCII और EBCDIC में समझाने जा रहा हूं।

ASCII में अंतर:

URLENCODE:

  • इनपुट स्ट्रिंग की एक शुरुआत / अंत लंबाई की गणना करता है, मेमोरी आवंटित करता है
  • थोड़ी देर लूप के माध्यम से चलता है, जब तक हम स्ट्रिंग के अंत तक नहीं पहुंचते तब तक वेतन वृद्धि
  • वर्तमान चरित्र को पकड़ लेता है
  • यदि वर्ण ASCII चार 0x20 (यानी, एक "स्थान") के बराबर है, +तो आउटपुट स्ट्रिंग में एक संकेत जोड़ें ।
  • यदि यह स्थान नहीं है, और यह अल्फ़ान्यूमेरिक ( isalnum(c)) भी नहीं है , और यह भी नहीं है और _, -या .चरित्र, तो हम, %सरणी स्थिति 0 के लिए एक संकेत आउटपुट करते हैं, hexcharsसरणी के लिए लुकअप के लिए os_toasciiसरणी के लिए एक सरणी देखें ( (वर्तमान चरित्र) की कुंजी के लिए अपाचे से एक सरणी जो हेक्स कोड में अनुवाद करता हैc ), हम तब बिटवाइस 4 से दाएं शिफ्ट करते हैं, उस मान को चरित्र 1 में असाइन करते हैं, और स्थिति 2 में हम उसी लुकअप को असाइन करते हैं, सिवाय इसके कि हम पूर्ववत करें एक तार्किक और यह देखने के लिए कि मान 15 (0xF) है, और उस स्थिति में 1 लौटाएं, या 0 अन्यथा। अंत में, आप कुछ एन्कोडेड के साथ समाप्त करेंगे।
  • यदि यह समाप्त होता है तो यह एक स्थान नहीं है, यह अल्फ़ान्यूमेरिक या _-.वर्णों में से एक है , यह बिल्कुल वही है जो यह है।

RAWURLENCODE:

  • स्ट्रिंग के लिए मेमोरी आवंटित करता है
  • फ़ंक्शन कॉल में प्रदान की गई लंबाई के आधार पर Iterates (URLENCODE के साथ फ़ंक्शन में गणना नहीं की गई है)।

नोट: कई प्रोग्रामर ने शायद लूप के लिए इस तरह से कभी नहीं देखा है, यह कुछ हद तक हैक है और सबसे अधिक-लूप के साथ उपयोग किए जाने वाले मानक सम्मेलन पर ध्यान नहीं देते हैं, यह असाइन करता है xऔर y, len0 तक पहुंचने के लिए बाहर निकलने के लिए चेक करता है , और दोनों को बढ़ाता है xऔर y। मुझे पता है, यह वह नहीं है जिसकी आप अपेक्षा करेंगे, लेकिन यह मान्य कोड है।

  • वर्तमान चरित्र को एक मिलान वर्ण स्थिति में असाइन करता है str
  • यह जाँचता है कि क्या वर्तमान वर्ण अल्फ़ान्यूमेरिक है, या वर्णों में से एक है _-., और यदि ऐसा नहीं है, तो हम URLENCODE के साथ लगभग वही असाइनमेंट करते हैं जहाँ यह लुकअप्स को बेहतर बनाता है, हालाँकि, हम अलग-अलग वृद्धि करते हैं, इसका उपयोग करते y++हुए to[1], क्योंकि यह है स्ट्रिंग्स को अलग-अलग तरीकों से बनाया जा रहा है, लेकिन अंत में एक ही लक्ष्य तक पहुँच सकते हैं।
  • जब लूप किया जाता है और लंबाई चली जाती है, यह वास्तव में स्ट्रिंग को समाप्त करता है, \0बाइट को निर्दिष्ट करता है ।
  • यह एन्कोडेड स्ट्रिंग लौटाता है।

अंतर:

  • अंतरिक्ष के लिए UrlEncode चेक, एक + संकेत प्रदान करता है, RawURLEncode नहीं करता है।
  • UrlEncode \0स्ट्रिंग को बाइट असाइन नहीं करता है , RawUrlEncode करता है (यह एक म्यूट बिंदु हो सकता है)
  • वे अलग तरीके से पुनरावृत्ति करते हैं, एक विकृत विकृतियों के साथ बह निकला हो सकता है, मैं केवल यह सुझाव दे रहा हूं और मैंने इसकी जांच नहीं की है।

वे मूल रूप से अलग तरह से पुनरावृति करते हैं, एक ASCII 20 की स्थिति में एक + संकेत प्रदान करता है।

EBCDIC में अंतर:

URLENCODE:

  • ASCII के साथ समान पुनरावृत्ति सेटअप
  • फिर भी "स्पेस" कैरेक्टर को + साइन करने के लिए। नोट-- मुझे लगता है कि इसे EBCDIC में संकलित करने की आवश्यकता है या आप बग के साथ समाप्त होंगे? क्या कोई इसे संपादित और पुष्टि कर सकता है?
  • यह जाँच करता है कि क्या वर्तमान चार पहले एक चार है 0, .या होने के अपवाद के साथ -, या उससे कम है, Aलेकिन चार से अधिक है 9, या इससे अधिक है Zऔर इससे कम है, aलेकिन नहीं _या इससे अधिक z(हाँ, EBCDIC काम करने के लिए गड़बड़ है)। यदि यह उनमें से किसी से मेल खाता है, तो ASCII संस्करण में पाया गया एक समान लुकअप करें (यह केवल os_toascii में लुकअप की आवश्यकता नहीं है)।

RAWURLENCODE:

  • ASCII के साथ समान पुनरावृत्ति सेटअप
  • URL एनकोड के EBCDIC संस्करण में वर्णित समान जांच, इस अपवाद के साथ कि यदि यह इससे अधिक है z, तो यह ~URL एनकोड से बाहर है।
  • ASCII RawUrlEncode के रूप में समान कार्यभार
  • फिर भी \0वापसी से पहले स्ट्रिंग को बाइट को जोड़ना ।

ग्रैंड सारांश

  • दोनों एक ही हेक्सचार लुकअप टेबल का उपयोग करते हैं
  • URIEncode \ 0, कच्चे करता है के साथ एक स्ट्रिंग समाप्त नहीं करता है।
  • यदि आप EBCDIC में काम कर रहे हैं, तो मैं RawUrlEncode का उपयोग करने का सुझाव दूंगा, क्योंकि यह प्रबंधित करता है ~कि UrlEncode नहीं करता है ( यह एक रिपोर्ट की गई समस्या है )। यह ध्यान देने योग्य है कि ASCII और EBCDIC 0x20 दोनों स्थान हैं।
  • वे अलग तरह से पुनरावृत्ति करते हैं, एक तेज हो सकता है, कोई स्मृति या स्ट्रिंग आधारित कारनामों से ग्रस्त हो सकता है।
  • URIEncode में एक जगह बनाता है +, RawUrlEncode %20सरणी लुकअप के माध्यम से एक जगह बनाता है ।

अस्वीकरण: मैंने वर्षों में सी को नहीं छुआ है, और मैंने वास्तव में लंबे समय में EBCDIC को नहीं देखा है। अगर मैं कहीं गलत हूं, तो मुझे बताएं।

सुझाए गए कार्यान्वयन

इन सबके आधार पर, रॉर्लेंकोड सबसे अधिक बार जाने का मार्ग है। जैसा कि आप जोनाथन फिंगलैंड के उत्तर में देखते हैं, ज्यादातर मामलों में इसके साथ रहना चाहिए। यह URI घटकों के लिए आधुनिक योजना से संबंधित है, जहां urlencode पुराने स्कूल के रास्ते को करता है, जहां + का अर्थ है "स्थान।"

यदि आप पुराने प्रारूप और नए प्रारूपों के बीच रूपांतरण करने की कोशिश कर रहे हैं, तो सुनिश्चित करें कि आपका कोड ऊपर नहीं जाता है और कुछ ऐसा है जो एक डिकोड किया गया है + गलती से डबल-एन्कोडिंग द्वारा अंतरिक्ष में प्रवेश करता है, या इसके चारों ओर समान "उफ़" परिदृश्य। अंतरिक्ष / 20% / + मुद्दा।

यदि आप पुराने सॉफ़्टवेयर के साथ एक पुराने सिस्टम पर काम कर रहे हैं जो नए प्रारूप को पसंद नहीं करता है, तो urlencode के साथ रहें, हालांकि, मेरा मानना ​​है कि% 20 वास्तव में पीछे की ओर संगत होगा, जैसा कि पुराने मानक% 20 के तहत काम किया गया था, बस नहीं किया गया था पसंदीदा। यदि आप खेलने के लिए तैयार हैं, तो इसे शॉट दें, हमें बताएं कि यह आपके लिए कैसे काम करता है।

मूल रूप से, आपको कच्चे के साथ रहना चाहिए, जब तक कि आपका ईबीसीडीआईसी सिस्टम आपको वास्तव में घृणा न करे। वर्ष 2000 के बाद बने किसी भी सिस्टम पर अधिकांश प्रोग्रामर कभी भी EBCDIC में नहीं चलेंगे, शायद 1990 भी (जो कि धक्का दे रहा है, लेकिन अभी भी मेरी राय में संभव है)।


मुझे दोहरे एन्कोडिंग के बारे में चिंता करने की आवश्यकता नहीं है, आखिरकार मुझे पता होना चाहिए कि मैंने क्या एन्कोड किया है क्योंकि यह एन्कोडिंग है जो मैं सोचता हूं। चूँकि मैं एक संगतता मोड के साथ प्राप्त होने वाली हर चीज को डीकोड करता हूं, जो जानता है कि अंतरिक्ष के लिए इलाज कैसे करें + मैं समान रूप से उन समस्याओं के बारे में कभी नहीं आया हूं जो आप यहां के बारे में चेतावनी देने की कोशिश करते हैं। मैं स्रोत को देखकर समझ सकता हूं कि क्या हम नहीं जानते कि कुछ क्या करता है, लेकिन वास्तव में हमने यहां क्या सीखा है कि हम पहले से ही दोनों कार्यों को निष्पादित करने से पहले से नहीं जानते थे। मुझे पता है कि मैं पक्षपाती हूं लेकिन मैं मदद नहीं कर सकता लेकिन लगता है कि यह रास्ता खत्म हो गया। हालांकि प्रयास पर यश! =)
निकल-

2
+1, इस भाग के लिए: "मेरा मानना ​​है कि% 20 वास्तव में पीछे की ओर संगत होगा, जैसा कि पुराने मानक% 20 के तहत काम किया गया था, बस पसंद नहीं किया गया"
ग्रास डबल

3
अच्छा जवाब है, लेकिन शायद थोड़ा overkill?
rinogo

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

पैदावार

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

जबकि

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

पैदावार

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

अंतर asd%20asdबनाम होने काasd+asd

urlencode RFC 1738 से एन्कोडिंग स्पेस के +बजाय भिन्न होता है%20


28

यदि आप किसी अन्य वातावरण में परिणाम का उपयोग करने जा रहे हैं, तो उदाहरण के लिए, जावास्क्रिप्ट का एक व्यावहारिक कारण।

PHP में urlencode('test 1')रिटर्न 'test+1'जबकि rawurlencode('test 1')रिटर्न 'test%201'परिणाम के रूप में।

लेकिन अगर आप "डिकोड" करने की जरूरत है जावास्क्रिप्ट में इस का उपयोग कर decodeURI () समारोह तो decodeURI("test+1")आप दे देंगे "test+1", जबकि decodeURI("test%201")आप दे देंगे "test 1"परिणाम के रूप में।

दूसरे शब्दों में PHP में urlencode से प्लस ("+") तक एन्कोड किया गया स्पेस ("") जावास्क्रिप्ट में डिकोड्यूरी द्वारा ठीक से डिकोड नहीं किया जाएगा ।

ऐसे मामलों में रॉर्लेंकोड PHP फ़ंक्शन का उपयोग किया जाना चाहिए।


6
यह अब तक का सबसे अच्छा जवाब है जो मैंने देखा है। यह उपयोग के लिए एक सुझाव प्रदान करता है, एक वास्तविक दुनिया उदाहरण द्वारा। इसके अतिरिक्त, यह संक्षिप्त है।
डॉटनचेन

यह एक अच्छा उदाहरण है, हालांकि मैं पसंद करता हूं json_encodeऔर JSON.parseउस उद्देश्य के लिए।
फेब्रिआसो मैटे

21

मेरा मानना ​​है कि रिक्त स्थान को इनकोड किया जाना चाहिए:

  • %20 जब URL पथ घटक के अंदर उपयोग किया जाता है
  • +URL क्वेरी स्ट्रिंग घटक या प्रपत्र डेटा के अंदर उपयोग किए जाने पर ( 17.13.4 सामग्री प्रकार देखें )

निम्न उदाहरण के सही उपयोग से पता चलता rawurlencodeहै और urlencode:

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

आउटपुट:

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

यदि आप पथ और क्वेरी स्ट्रिंग घटकों को अन्य तरीके से राउंड को एनकोड करते हैं तो क्या होता है? निम्नलिखित उदाहरण के लिए:

http://example.com/category/latest+songs/search?q=lady%20gaga
  • वेबसर्वर के latest+songsबजाय निर्देशिका के लिए दिखेगाlatest songs
  • क्वेरी स्ट्रिंग पैरामीटर qशामिल होगाlady gaga

2
"क्वेरी स्ट्रिंग पैरामीटर qमें lady gaga" होगा अन्यथा इसमें और क्या होगा? ऐसा qलगता है कि क्वेरी पैरामीटर $_GETउपयोग किए गए rawurlencodeया urlencodePHP 5.2+ में परवाह किए बिना उसी मान को पास किया गया है । हालाँकि, प्रारूप urlencodeमें एनकोड application/x-www-form-urlencodedहोता है जो GET अनुरोधों के लिए डिफ़ॉल्ट है इसलिए मैं आपके दृष्टिकोण से जा रहा हूँ। +1
फैब्रीको मैटे

2
मैं स्पष्ट करने के लिए दोनों कि चाहता था +और %20जब क्वेरी स्ट्रिंग में इस्तेमाल अंतरिक्ष के रूप में डीकोड कर रहे हैं।
सलमान एक

5

अंतर वापसी मूल्यों में है, अर्थात:

urlencode () :

एक स्ट्रिंग देता है जिसमें सभी गैर-अल्फ़ान्यूमेरिक वर्णों को छोड़कर -_। एक प्रतिशत (%) चिह्न के साथ दो हेक्स अंक और रिक्त स्थान प्लस (+) के संकेत के रूप में प्रतिस्थापित किए गए हैं। यह उसी तरह एन्कोड किया गया है जैसे कि WWW फॉर्म से पोस्ट किया गया डेटा एनकोड किया गया है, यह उसी तरह है जैसे एप्लिकेशन / x-www-form-urlencoded मीडिया प्रकार में। यह ऐतिहासिक कारणों से »RFC 1738 एन्कोडिंग (rawurlencode () देखें) से भिन्न है, रिक्त स्थान प्लस (+) संकेतों के रूप में एन्कोड किए गए हैं।

रॉर्लेंकोड () :

एक स्ट्रिंग देता है जिसमें सभी गैर-अल्फ़ान्यूमेरिक वर्णों को छोड़कर -_। दो प्रतिशत अंकों के बाद एक प्रतिशत (%) चिन्ह के साथ प्रतिस्थापित किया गया है। यह शाब्दिक वर्णों को विशेष URL सीमांकक के रूप में व्याख्या करने से बचाने के लिए RFC 1738 में वर्णित एन्कोडिंग है, और URL को चरित्र रूपांतरण (जैसे कुछ ईमेल सिस्टम) के साथ ट्रांसमिशन मीडिया द्वारा मंगाई जाने से बचाने के लिए।

दोनों बहुत समान हैं, लेकिन उत्तरार्द्ध (रॉर्लेंकोड) एक '%' और दो हेक्स अंकों के साथ रिक्त स्थान को बदल देगा, जो पासवर्ड कूटबन्धन के लिए उपयुक्त है या ऐसे, जहाँ '+' उदाहरण के लिए नहीं है:

echo '<a href="ftp://user:', rawurlencode('foo @+%/'),
     '@ftp.example.com/x.txt">';
//Outputs <a href="ftp://user:foo%20%40%2B%25%2F@ftp.example.com/x.txt">

2
ओपी पूछता है कि कैसे पता करें कि किसका उपयोग करना है, और कब। यह जानते हुए कि प्रत्येक रिक्त स्थान के साथ क्या करता है, ओपी को निर्णय लेने में मदद नहीं करता है यदि वह अलग-अलग रिटर्न मानों के महत्व को नहीं जानता है।
डॉटनचेन

5

1. वास्तव में क्या अंतर हैं और

अंतर केवल उसी तरीके से है जिस तरह से रिक्त स्थान का इलाज किया जाता है:

urlencode - विरासत कार्यान्वयन के आधार पर रिक्त स्थान को + में परिवर्तित करता है

rawurlencode - RFC 1738 पर आधारित रिक्त स्थान का% 20 में अनुवाद करता है

अंतर का कारण यह है क्योंकि + यूआरएल में आरक्षित और मान्य (अनएन्कोडेड) है।

2. जो पसंद किया जाता है?

मैं वास्तव में एक के बाद एक को चुनने के कुछ कारणों को देखना चाहता हूं ... मैं सिर्फ एक को चुनना चाहता हूं और इसे कम से कम उपद्रव के साथ हमेशा के लिए उपयोग करना चाहता हूं।

पर्याप्त रूप से, मेरे पास एक सरल रणनीति है जिसे मैं इन निर्णयों को बनाते समय पालन करता हूं जो मैं इस उम्मीद में आपके साथ साझा करूंगा कि यह मदद कर सकता है।

मुझे लगता है कि यह HTTP / 1.1 विनिर्देशन RFC 2616 था जिसे " सहिष्णु अनुप्रयोग " कहा जाता है

अनुरोध-पंक्ति को पार्स करते समय स्थिति-रेखा और सर्वर को पार्स करने में ग्राहक सहिष्णु होना चाहिए।

जब इन सवालों के साथ सामना करना पड़ता है तो सबसे अच्छी रणनीति हमेशा जितना संभव हो उतना उपभोग करने और मानकों का अनुपालन करने के लिए होता है।

इसलिए मेरी सलाह है कि rawurlencodeमानकों का उपयोग करते हुए RFC 1738 एनकोडेड स्ट्रैंथ का उत्पादन करें और urldecodeबैकवर्ड कम्पेटिबल होने के लिए उपयोग करें और जिस भी चीज़ का आप उपभोग कर सकते हैं, उसे साथ रखें।

अब आप बस इसके लिए मेरा शब्द ले सकते हैं लेकिन यह साबित करते हैं कि हम इसे ...

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

ऐसा प्रतीत होता है कि PHP के मन में वास्तव में यही था, भले ही मैं कभी भी दोनों में से किसी भी एक प्रारूप से इनकार नहीं कर रहा हूँ, मैं आपकी रणनीति के रूप में अपनाने के लिए बेहतर रणनीति के बारे में सोच सकता हूँ, क्या आप कर सकते हैं?

एन ज्वॉय!


4

urlencode : यह ऐतिहासिक कारणों से »RFC 1738 एन्कोडिंग (rawurlencode () देखें) से भिन्न है, रिक्त स्थान प्लस (+) संकेतों के रूप में एन्कोड किए गए हैं।


2

रिक्त स्थान %20बनाम के रूप में+

rawurlencode()अधिकांश मामलों में उपयोग करने के लिए मैंने जो सबसे बड़ा कारण देखा है, वह यह है कि urlencodeटेक्स्ट स्पेस को +(प्लस साइन्स) के rawurlencodeरूप में एनकोड किया जाता है, जहां उन्हें आमतौर पर देखा जाता है %20:

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

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

मैंने विशेष रूप से कुछ एपीआई एंडपॉइंट्स देखे हैं जो एन्कोडेड टेक्स्ट क्वेरीज़ को %20एक स्थान के लिए देखने की अपेक्षा करते हैं और परिणामस्वरूप, यदि प्लस चिह्न का उपयोग किया जाता है तो असफल हो जाते हैं। जाहिर है कि यह एपीआई कार्यान्वयन के बीच अंतर करने वाला है और आपका माइलेज भिन्न हो सकता है।


1

मेरा मानना ​​है कि urlencode क्वेरी पैरामीटर्स के लिए है, जबकि rawurlencode पाथ सेगमेंट के लिए है। यह मुख्य रूप से %20पथ खंड बनाम +क्वेरी पैरामीटर के लिए है। इस उत्तर को देखें जो रिक्त स्थान के बारे में बात करता है: कब अंतरिक्ष को प्लस (+) या% 20 पर एनकोड करना है?

हालाँकि %20अब क्वेरी पैरामीटर के रूप में भी काम करता है, यही वजह है कि rawurlencode हमेशा सुरक्षित होता है। हालाँकि, प्लस चिह्न का उपयोग किया जाता है जहाँ उपयोगकर्ता क्वेरी पैरामीटर के संपादन और पठनीयता का अनुभव करते हैं।

ध्यान दें कि यह साधन rawurldecodeडिकोड नहीं करता +रिक्त स्थान में ( http://au2.php.net/manual/en/function.rawurldecode.php )। यही कारण है कि $ _GET हमेशा स्वचालित रूप से गुजरता है urldecode, जिसका अर्थ है कि +और %20दोनों रिक्त स्थान में डिकोड किए गए हैं।

यदि आप चाहते हैं कि एन्कोडिंग और डिकोडिंग इनपुट और आउटपुट के बीच सुसंगत हो और आपने हमेशा क्वेरी मापदंडों के लिए उपयोग करने +और न करने के %20लिए चुना है , तो urlencodeक्वेरी पैरामीटर (कुंजी और मान) के लिए ठीक है।

निष्कर्ष यह है:

पथ सेगमेंट - हमेशा rawurlencode / rawurldecode का उपयोग करें

क्वेरी पैरामीटर्स - डिकोडिंग के लिए हमेशा urldecode (स्वचालित रूप से किया गया) का उपयोग करें, एन्कोडिंग के लिए, दोनों rawurlencode या urlencode ठीक है, बस एक को चुनना है, विशेष रूप से URL की तुलना करते समय।


0

सरल * rawurlencode पथ - पथ "से पहले का हिस्सा है?" - रिक्त स्थान को% 20 के रूप में एन्कोड किया जाना चाहिए * क्वेरी स्ट्रिंग को urlencode - क्वेरी स्ट्रिंग "" के बाद का हिस्सा है? -स्थानों को बेहतर रूप से एन्कोड किया गया है क्योंकि "+" = रॉउरलेंकोड आम तौर पर अधिक संगत है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.