स्ट्रिंग की तुलना '==' बनाम 'strcmp ()' का उपयोग करके


334

ऐसा लगता है कि PHP का ===ऑपरेटर संवेदनशील है। तो क्या उपयोग करने का कोई कारण है strcmp()?

क्या निम्नलिखित की तरह कुछ करना सुरक्षित है?

if ($password === $password2) { ... }

10
केस-सेंसिटिविटी का क्या लेना-देना है strcmp?
kennytm

1
@ केनीटीएम: strcmpकेस-संवेदी है। कुछ भाषाओं में, VB की तरह, स्ट्रिंग तुलना नहीं हो सकती है, और इस तरह एक अलग परिणाम होगा। हालांकि PHP में ऐसा नहीं है।
cHao

13
@ जी: आप ===इसके बजाय उपयोग करना चाहते हैं ==क्योंकि '0XAB' == '0xab'यह सच है।
kennytm

17
का उपयोग करने के लिए === के बजाय == महत्वपूर्ण है, क्योंकि 0 से == के साथ किसी भी स्ट्रिंग की तुलना करना सच है जो स्पष्ट रूप से गलत है ...
कार्ल एडलर

4
@ केनी भी '0xAB' == '171'
सुरमा

जवाबों:


329

इसका उपयोग करने का कारण है strcmp

रिटर्न <0 यदि str1 str2 से कम है; > 0 यदि str1 str2 से अधिक है, और 0 यदि वे समान हैं।

===केवल रिटर्न trueया false, यह आपको नहीं बताता है कि "अधिक" स्ट्रिंग क्या है।


9
मेरे वर्तमान मामले में प्रतिष्ठित थियो, मुझे यह जानने की जरूरत नहीं है कि कौन सा तार अधिक है :)
Jiew मेंग

154
मिलान स्ट्रिंग्स के साथ स्ट्रैम्प ने 0.207852 सेकेंड का समय लिया। बिना मिलान वाले स्ट्रिंग्स के साथ strcmp ने 0.215276 सेकंड लिया === मैचिंग स्ट्रिंग्स के साथ 0.067122 सेकंड === लिया, जबकि गैर-मिलान वाले स्ट्रिंग्स ने 0.057305 सेकंड का समय

3
स्ट्रैम्प के लिए अन्य उपयोग यह छँटाई दिखाता है। छँटाई के बारे में अधिक स्पष्ट होना। strcmp () रिटर्न <0 यदि string2 से पहले string1 सॉर्ट करता है,> 0 अगर string2 से पहले string2 सॉर्ट करता है या यदि वे समान हैं। उदाहरण के लिए $ string_first = "aabo"; $ string_second = "aaao"; इको $ n = strcmp ($ string_first, $ string_second); शून्य से अधिक वापस आ जाएगा, क्योंकि आबाओ से पहले आआओ छँट रहा है।
HTML मैन

20
इस उत्तर को सबसे अधिक उत्थान क्यों मिलता है? मैं नीच कर रहा हूं, हालांकि यह जवाब है कि यह सवाल का हकदार है, लेकिन 'सही' जवाब नहीं। सही उत्तर 'यूज ===' होना चाहिए क्योंकि बहुत से लोग पहले से ही अन्य उत्तरों में कह चुके हैं।
8:१३ पर गूरिंज

2
@onur Güngör वास्तव में, यह करता है जवाब सेशन के सवाल है, जो है So is there any reason to use strcmp() ?, जबकि Postfuturist का जवाब नहीं है। ओह, नरक ... कोई भी इस सवाल का जवाब एक ही बार में संकलित करने के लिए लग रहा था उपयोग की strcmp(), प्रदर्शन की ===, और बुरा विश्वसनीयता की ==स्ट्रिंग तुलना के लिए ... इसलिए मैं मेरा सूची में जोड़ा।
बालमिपुर

222

आपको ==स्ट्रिंग तुलना के लिए कभी भी उपयोग नहीं करना चाहिए । ===ठीक है।

$something = 0;
echo ('password123' == $something) ? 'true' : 'false';

बस उपरोक्त कोड चलाएं और आप देखेंगे कि क्यों।

$something = 0;
echo ('password123' === $something) ? 'true' : 'false';

अब, यह थोड़ा बेहतर है।


19
== विभिन्न प्रकारों के लिए सिर्फ एक समस्या नहीं है। कभी-कभी यह अप्रत्याशित परिणाम देगा भले ही दोनों पक्ष एक स्ट्रिंग हों। कोशिश करें '1e3' == '1000'
एंटीमनी

3
कैसे करता है 0 == 'password123'?
एंडी लोबेल

24
@AndyLobel PHP एक संख्या के लिए 'पासवर्ड123' का उपयोग करता है, क्योंकि यह अन्य ऑपरेंड के बाद से एक विषम ढीली तुलना नियमों का उपयोग करता है, यह एक स्ट्रिंग है, जैसे कि सबसे अधिक, संख्या 0 के लिए coerces, और PHP तुलना के लिए सही है।
पोस्टफुटुरिस्ट

8
एक त्वरित var_dump ((int) 'password123'); मुझे पूरी तरह से समझने में मदद की कि ऐसा क्यों हुआ ... ** शर्मिंदा ** ... मुझे वास्तव में === ऑपरेटर पसंद है
कार्लटन

3
यह '==' का उपयोग करते हुए बीक्यूस है, यदि दो में से एक संकार्य संख्या के लिए अनुकूल है, तो php दोनों संचालकों को संख्याओं में परिणत करता है, और अधिक, यदि संख्या में स्ट्रिंग संख्या में डाली जाती है, तो यह मान शून्य लेता है, जिसके परिणामस्वरूप शून्य के बराबर होता है। इसलिए सरल '==' के साथ तुलना का परिणाम अवांछित हो सकता है
लुका सी।

98

==PHP में उपयोग न करें । यह वह नहीं करेगा जो आप अपेक्षा करते हैं। यहां तक ​​कि अगर आप तार से तार की तुलना कर रहे हैं, तो PHP उन्हें संक्षेप में तैरने के लिए डाल देगा और यदि वे संख्यात्मक दिखाई देते हैं तो संख्यात्मक तुलना करें।

उदाहरण के लिए '1e3' == '1000'सच है। आपको ===इसके बजाय उपयोग करना चाहिए ।


16
लेकिन आप सिर्फ === कर सकते हैं।
रोमन न्यूजा

11
@ रमन हाँ, लेकिन बहुत से PHP प्रोग्रामर नहीं जानते कि उन्हें ऐसा करना होगा। इसलिए चेतावनी।
सुरमा

5
@Antimony तो उन्हें क्यों नहीं बताया कि उन्हें आपके जवाब में क्या करना चाहिए ?
टिम

43

खैर .. इस php बग रिपोर्ट के अनुसार , आप 0wned भी प्राप्त कर सकते हैं।

<?php 
    $pass = isset($_GET['pass']) ? $_GET['pass'] : '';
    // Query /?pass[]= will authorize user
    //strcmp and strcasecmp both are prone to this hack
    if ( strcasecmp( $pass, '123456' ) == 0 ){
      echo 'You successfully logged in.';
    }
 ?>

यह आपको एक चेतावनी देता है, लेकिन फिर भी तुलना को दरकिनार कर देता है।
आप के ===रूप में @postfuturist का सुझाव दिया जाना चाहिए ।


5
वाह १। लिंक से उद्धरण: "यह फ़ंक्शन के लिए स्थापित व्यवहार है जो गलत तरीके के तर्क प्राप्त करता है (अशक्त) वापस लौटने के लिए"। यह आश्चर्यजनक है कि मैनुअल केवल यह कहता है: "रिटर्न <0 यदि str1 str2 से कम है, तो> 1 यदि str1 str2 से अधिक है, और 0 यदि वे समान हैं"। नल का उल्लेख एक संभावना के रूप में नहीं किया गया है, फिर भी इस तरह के मैन मैन पेज जैसे पृष्ठों पर इसका उल्लेख किया गया है। sigh
गेरी

लेकिन क्या ऐसा तब होता है जब फॉर्म विधि पोस्ट होती है ...?
3lokh

@ निखिलगॉर्ज यह करता है, यहाँ प्रश्न में कार्य strcmp है। इससे कोई फर्क नहीं पड़ता कि किन इनपुट्स की तुलना की जा रही है।
अजीथ

जबकि बग रिपोर्ट कहती है कि अशक्त वापस आना ठीक था, यह गलत है। सभी आधिकारिक PHP PHP 4.3 से PHP 7.3 तक रिलीज़ होते हैं, इन कार्यों से वापस नहीं आते हैं। मुझे संदेह है कि यह एक अल्फा या बीटा रिलीज़ हो सकता है, और बग के बंद होने के बावजूद अमान्य है, यह तय किया गया था। देखें 3v4l.org/Zq8tM 3.19 - विवरण, जो दर्शाते हैं कि यह HHVM 3.11 को प्रभावित करता है कि के लिए।
टिमो तिजहोफ

33

हमेशा याद रखें, जब तार की तुलना, आप का उपयोग करना चाहिए ===ऑपरेटर (सख्त तुलना) और नहीं == ऑपरेटर (ढीला तुलना)।


8
वास्तव में, मुझे लगता है कि यह कहना सुरक्षित है कि आपको किसी भी चीज़ की=== तुलना करते समय उपयोग करना चाहिए ।
रिंक.टेंडेंट .6

22

सभी उत्तरों को सारांशित करना:

  • ==स्ट्रिंग तुलना के लिए एक बुरा विचार है
    यह आपको कई मामलों में "आश्चर्यजनक" परिणाम देगा। इस पर भरोसा मत करो।

  • === ठीक है, और आपको सर्वश्रेष्ठ प्रदर्शन देगा।

  • strcmp() यदि आपको यह निर्धारित करने की आवश्यकता है कि कौन सा स्ट्रिंग "अधिक" है, तो आमतौर पर संचालन को छांटने के लिए उपयोग किया जाना चाहिए।


20

उपयोग करना ==खतरनाक हो सकता है।

ध्यान दें, यदि यह वैरिएबल को अन्य डेटा प्रकार में डालेगा, यदि दोनों में भिन्नता है।

उदाहरण:

  • echo (1 == '1') ? 'true' : 'false';
  • echo (1 == true) ? 'true' : 'false';

जैसा कि आप देख सकते हैं, ये दोनों अलग-अलग प्रकार के हैं, लेकिन इसका परिणाम यह है true, जो आपके कोड से अपेक्षा नहीं करेगा।

===हालांकि, परीक्षण के रूप में उपयोग करने की सिफारिश की जाती है, यह दिखाता है कि यह strcmp()इसके केस और असंवेदनशील विकल्प की तुलना में थोड़ा तेज है strcasecmp()

त्वरित गॉगलिंग इस गति की तुलना चिल्लाती है: http://snipplr.com/view/758/


1
कभी-कभी यह उन्हें एक अलग प्रकार तक ले जाता है, भले ही उनके पास पहले से ही एक ही प्रकार हो।
सुरमा

यहां तक ​​कि जब दो पूर्णांक कि तुलना एक पूर्णांक का प्रतिनिधित्व करती है जैसे कि "012" == "12"php ने दोनों तार के प्रकार को पूर्णांक में बदल दिया 12 == 12और फिर वापस आ गया true
GoTo


6

strcmp चल रहे वातावरण (Linux / Windows) के आधार पर विभिन्न मान लौटाएगा!

कारण यह है कि यह एक बग है जैसा कि बग रिपोर्ट कहती है https://bugs.php.net/bug.php?id=53999

कृपया ध्यान से संभालें !! धन्यवाद।


यह हमेशा 0 लौटेगा अगर तार बराबर हैं, हालांकि। हालांकि 0 से किसी भी अन्य मूल्य के बारे में देखभाल करने के बारे में सावधान रहना।
प्रो। फाल्कन कॉन्ट्रैक्ट ने 10

4

आप का उपयोग कर सकते हैं strcmp()यदि आप तार को शाब्दिक रूप से क्रमबद्ध करना / तुलना करना चाहते हैं । अगर आप सिर्फ समानता की जांच करना चाहते हैं तो ==ठीक है।


1
जैसे usort । वास्तव में, यह बहुत ज्यादा छँटाई के लिए बनाया गया है।
चार्ल्स

@Charles धन्यवाद। विकीपीडिया ने मेरी आँखों पर पानी फेर दिया।
cbednarski

1
छँटाई के बारे में अधिक स्पष्ट होना। strcmp () रिटर्न <0 यदि string2 से पहले string1 सॉर्ट करता है,> 0 अगर string2 से पहले string2 सॉर्ट करता है या यदि वे समान हैं। उदाहरण के लिए $ string_first = "aabo"; $ string_second = "aaao"; इको $ n = strcmp ($ string_first, $ string_second); शून्य से अधिक वापस आ जाएगा, क्योंकि आबाओ से पहले आआओ छँट रहा है।
HTML मैन

@postfuturist मुझे यकीन है कि यह एक टाइपो है और उनका मतलब है ===
ऐश

4

इसके अलावा समारोह छँटाई में मदद कर सकता है। छँटाई के बारे में अधिक स्पष्ट होना। strcmp () string2 से पहले अगर स्ट्रिंग 1 से कम हो तो 0 से कम रिटर्न देता है, अगर string2 से पहले string2 सॉर्ट करता है तो 0 या उससे अधिक होता है। उदाहरण के लिए

$first_string = "aabo";
$second_string = "aaao";
echo $n = strcmp($first_string,$second_string);

समारोह शून्य से अधिक वापस आ जाएगा, क्योंकि आबाओ से पहले एआओ छंटनी कर रहा है।


0

PHP वर्णानुक्रमिक छँटाई का उपयोग करने के बजाय, तुलना करने के लिए वर्ण के ASCII मान का उपयोग करें । लोअरकेस अक्षरों में राजधानियों की तुलना में अधिक ASCII मूल्य होता है। इस प्रकार की तुलना करने के लिए पहचान ऑपरेटर === का उपयोग करना बेहतर है । strcmp () बाइनरी सुरक्षित स्ट्रिंग तुलना करने के लिए एक फ़ंक्शन है। यह तर्क के रूप में दो तार लेता है और रिटर्न करता है <0 यदि str1 str2 से कम है; > 0 यदि str1 str2 से अधिक है, और 0 यदि वे समान हैं। एक केस-असंवेदनशील संस्करण भी है जिसका नाम स्ट्रैसेकम्प () है जो पहले स्ट्रिंग्स को लोअरकेस में परिवर्तित करता है और फिर उनकी तुलना करता है।


0

if ($password === $password2) { ... }पासवर्ड या पासवर्ड हैश की तुलना करते समय करना कोई सुरक्षित बात नहीं है जहाँ एक इनपुट उपयोगकर्ता द्वारा नियंत्रित किया जाता है।
उस स्थिति में यह एक टाइमिंग ऑरेकल बनाता है जो हमलावर को वास्तविक पासवर्ड हैश को निष्पादन समय के अंतर से प्राप्त करने की अनुमति देता है। इसके बजाय का
उपयोग करें if (hash_equals($password, $password2)) { ... }, क्योंकि hash_equals "टाइम अटैक सेफ स्ट्रिंग तुलना" करता है।

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