PHP

2013-08-29 7 views
6

में ऑपरेटर प्राथमिकता को समझना मेरे पास उत्पादन में निम्न कोड है जो एक अनंत लूप का कारण बनता प्रतीत होता है।PHP

$z=1; 
while (!$apns = $this->getApns($streamContext) && $z < 11) 
{ 
    myerror_log("unable to conncect to apple. sleep for 2 seconds and try again"); 
    $z++; 
    sleep(2); 
} 

पूर्वता नियम कैसे लागू किया जा रहा है कि इस व्यवहार का कारण?

http://php.net/manual/en/language.operators.precedence.php

मैं डॉक्स में इस नोट को देखें:

= यद्यपि अधिकांश अन्य ऑपरेटरों की तुलना में कम पूर्वता है, पीएचपी अभी भी निम्न के समान भाव की अनुमति देगा: अगर ($ एक = foo()), में जो मामला foo() का वापसी मान $ ए में डाल दिया जाता है।

जो मुझे लगता है कि = पहले मूल्यांकन किया जाना चाहिए। फिर ! तो & &, जो एक अनंत लूप का कारण नहीं बनता है।

+0

क्या आप का उपयोग करने के 'मतलब ==' (तुलना) के बजाय ' = '(असाइनमेंट) आपके लूप लूप में? – vimist

+1

नहीं, यह कथन वास्तव में इसका मतलब है कि' = 'के बाईं ओर'! 'मान्य है।' && 'अभी भी असाइन किए जाने वाले मान का हिस्सा है। – Dave

+2

भी: नहीं। बीएडी। इस तरह कोड न करें। यह घृणास्पद है। – Dave

उत्तर

2

आपका कोड इस तरह मूल्यांकन कर रही है:

while (!($apns = ($this->getApns($streamContext) && ($z < 11)))) 

जिसके कारण आप अनंत लूप को देखने के (जैसे ही $z >= 11 के रूप में, $apns झूठी है, इसलिए हालत हमेशा सच है)। इस प्राथमिकता का कारण यह है कि विशेष नियम केवल पर पर लागू होने वाले असाइनमेंट के पर लागू होते हैं (= से कम प्राथमिकता रखते हैं)। इसका दाहिने ओर बुलियन ऑपरेटर पर कोई प्रभाव नहीं पड़ता है, जो किसी भी तरह की भाषा में व्यवहार करता है।

आपकी शैली खराब है। इस प्रयास करें, जो और अधिक पठनीय है और केवल $z के अंतिम मूल्य में अलग है (और है कि अगर महत्वपूर्ण है आप break बयान ठीक कर सकते हैं।

for($z = 1; $z < 11; ++ $z) { 
    // note extra brackets to make it clear that we intend to do assignment not comparison 
    if(($apns = $this->getApns($streamContext))) { 
     break; 
    } 
    myerror_log("unable to conncect to apple. sleep for 2 seconds and try again"); 
    sleep(2); 
} 
+0

तो मुझे लगता है कि $ apns कभी भी बुलियन मूल्य के अलावा कुछ भी सौंपा नहीं होगा। सही? शेष कोड जो सेब से जुड़ता है और पुश संदेश भेजता है, कभी काम नहीं करेगा। – digidigo

+0

'$ apns' जो भी 'getApns' रिटर्न प्राप्त करेगा। यह एक आम पैटर्न है; यह तब तक प्रभावी रूप से इंतजार कर रहा है जब तक '$ apns' सच नहीं है (यानी गैर-शून्य) फिर कोड के साथ जारी है।ध्यान दें कि चूंकि तुलना असाइनमेंट के बाद लागू की जाती है, इसलिए इसका मान उस मूल्य पर कोई प्रभाव नहीं पड़ता है जो '$ apns' में है। लेकिन अगर आप इस शर्त से असाइनमेंट को विभाजित करके स्पष्ट करना चाहते हैं, तो यह भी अच्छा है। – Dave

+1

मेरी पिछली टिप्पणी (अब संपादित) के विपरीत, PHP का '&&' और '||' * * * मानों को 'सत्य' या 'झूठी' में परिवर्तित करें, इसलिए आपका प्रारंभिक कोड हमेशा 'सत्य' या 'गलत' रखेगा '$ apns' में, जिसका अर्थ है कि यह कभी काम नहीं करेगा। मेरे द्वारा पोस्ट किया गया कोड काम करेगा। – Dave

2

आपका कोड कारण है कि यह अच्छी आदत है हमेशा कोष्ठक में सभी शर्तों डाल करने के स्पष्ट उदाहरण है (और एक ही कोड ब्लॉक करने के लिए लागू होता है। यहां तक ​​कि oneliners { और } से घिरा होना चाहिए)। तो त्रुटि प्रवण के बजाय:

while (!$apns = $this->getApns($streamContext) && $z < 11) 

while (!($apns = $this->getApns($streamContext)) && ($z < 11)) 

करते हैं और आप सुरक्षित हो जाएगा।

संबंधित मुद्दे

 संबंधित मुद्दे