त्रुटि संदेश "सख्त मानक: केवल चर संदर्भ द्वारा पारित किया जाना चाहिए"


81
$el = array_shift($instance->find(..))

उपरोक्त कोड किसी तरह सख्त मानकों की चेतावनी की रिपोर्ट करता है, लेकिन यह नहीं होगा:

function get_arr(){
    return array(1, 2);
}
$el = array_shift(get_arr());

तो यह वैसे भी चेतावनी कब रिपोर्ट करेगा?


1
$ उदाहरण क्या है-> खोज (..) वापसी?
सिल्वर लाइट

2
यहाँ समाधान है: stackoverflow.com/questions/9848295/…
ajaristi

मुझे लगता है कि उदाहरण (या तर्क) प्रश्न में गलत तरीका हो सकता है, क्योंकि दूसरा उदाहरण ( get_arr()फ़ंक्शन) सख्त मानकों के नोटिस (PHP 5.2 और PHP 5.5 का परीक्षण ) का उत्पादन करता है
MrWhite

जवाबों:


93

निम्नलिखित कोड पर विचार करें:

error_reporting(E_STRICT);
class test {
    function test_arr(&$a) {
        var_dump($a);
    }
    function get_arr() {
        return array(1, 2);
    }
}

$t = new test;
$t->test_arr($t->get_arr());

यह निम्न आउटपुट उत्पन्न करेगा:

Strict Standards: Only variables should be passed by reference in `test.php` on line 14
array(2) {
  [0]=>
  int(1)
  [1]=>
  int(2)
}

कारण? test::get_arr()विधि एक चर नहीं है और सख्त मोड के तहत यह एक चेतावनी उत्पन्न होगा। यह व्यवहार अत्यंत गैर सहज ज्ञान युक्त के रूप में है get_arr()विधि देता है एक सरणी मूल्य।

सख्त मोड में इस त्रुटि को प्राप्त करने के लिए, या तो विधि के हस्ताक्षर को बदल दें ताकि यह एक संदर्भ का उपयोग न करे:

function test_arr($a) {
    var_dump($a);
}

चूँकि आप अपना हस्ताक्षर नहीं बदल सकते हैं, array_shiftआप एक मध्यवर्ती चर का भी उपयोग कर सकते हैं:

$inter = get_arr();
$el = array_shift($inter);

7
@ user198729: मैं एक स्पष्टीकरण की तलाश कर रहा था या इसे भी ठीक कर रहा था, और पाया कि आप पहले आइटम के लिए वर्तमान () का उपयोग कर सकते हैं। Alas end () अंतिम के लिए काम नहीं करता है क्योंकि यह "अंतिम तत्व के लिए आंतरिक पॉइंटर को आगे बढ़ाता है"। करंट (array_reverse (somefunction) ()) काम करता है (हाँ, यह मूर्खतापूर्ण है)
MSpreij

1
प्रयोग currentयह धारणा बनाता है कि सरणी सूचक पहले तत्व पर है। यह ज्यादातर मामलों में एक मान्य धारणा हो सकती है, लेकिन एक को देखने के लिए।
cmbuckley

1
@ निश्चित रूप से, फिर इसमें वही मुद्दा होगा array_shift()जो यह संशोधित करने के लिए एक संदर्भ की उम्मीद करता है :-)
cmbuckley

1
@ user198729 $intermediateकोष्ठक की एक अतिरिक्त जोड़ी का उपयोग करके आप मूल्य से बच सकते हैं । $el = array_shift( ( get_arr() ) );। देखें stackoverflow.com/questions/9848295/…
च्लोए

1
@ च्लोए यह सबसे शानदार समाधान है जो मैंने कोड को सरल रखने के लिए देखा है !! धन्यवाद!
hargobind

7

$instance->find() एक चर के लिए एक संदर्भ देता है।

जब आप इस संदर्भ को किसी फ़ंक्शन में तर्क के रूप में उपयोग करने का प्रयास कर रहे हैं, तो इसे पहले एक चर में संग्रहीत किए बिना प्राप्त करें।

यह मेमोरी लीक को रोकने में मदद करता है और संभवतः अगले PHP संस्करणों में एक त्रुटि बन जाएगा।

यदि यह लिखा गया है तो आपका दूसरा कोड ब्लॉक एक त्रुटि फेंक देगा ( &फ़ंक्शन हस्ताक्षर में ध्यान दें ):

function &get_arr(){
    return array(1, 2);
}
$el = array_shift(get_arr());

तो एक त्वरित (और इतना अच्छा नहीं) ठीक हो जाएगा:

$el = array_shift($tmp = $instance->find(..));

मूल रूप से, आप पहले एक अस्थायी चर के लिए एक असाइनमेंट करते हैं और चर को तर्क के रूप में भेजते हैं।


यह अब काम करना चाहिए (इसकी जाँच की)। संदर्भ वापस करने के लिए आपको इसे विधि हस्ताक्षर पर घोषित करना होगा, न कि विवरणी कथन (मेरी गलती)।
सागी

नहीं, मैं हस्ताक्षर नहीं बदल सकता। @ pygorex1 के मध्यवर्ती चर इसे हल कर सकते हैं, लेकिन यह बेमानी लगता है, है ना?
user198729

मुझे पता है कि आप हस्ताक्षर नहीं बदल सकते, बस समझाया कि यह कैसे होता है। आप है अस्थायी (= मध्यवर्ती) का उपयोग करना है, लेकिन आप एक ही पंक्ति में यह कर सकते हैं। मेरा दूसरा कोड स्निपेट देखें।
सगी

4
मैंने आपके दूसरे स्निपेट की कोशिश की, काम नहीं कर रहा। यह केवल एक अलग लाइन में काम करता है
user198729

3
वास्तव में। असाइनमेंट असाइन किया गया मान लौटाता हैarray_shift($tmp = $instance->find(..))के मान को असाइन करता $instance->find(..)है $tmpऔर फिर असाइनमेंट के मूल्य को पास करता है है array_shift()- जो कि $tmpखुद को पारित करने के समान नहीं है, इसलिए असाइनमेंट के बिना मूल स्थिति से बेहतर नहीं है।
फिल्स

6

त्रुटि का कारण आंतरिक PHP प्रोग्रामिंग डेटा संरचनाओं फ़ंक्शन, array_shift () [php.net/end] का उपयोग है।

फ़ंक्शन एक पैरामीटर के रूप में एक सरणी लेता है। यद्यपि एक एम्परसेंड को array_shift()मैनुअल के प्रोटोटाइप में दर्शाया गया है ", उस फ़ंक्शन की विस्तारित परिभाषा में निम्नलिखित कोई सावधानी संबंधी दस्तावेज नहीं है, न ही कोई स्पष्ट स्पष्टीकरण है कि पैरामीटर वास्तव में संदर्भ द्वारा पारित किया गया है।

शायद यह / समझा / है। हालांकि, मुझे समझ में नहीं आया, इसलिए मेरे लिए त्रुटि के कारण का पता लगाना मुश्किल था।

कोड पुन: प्रस्तुत करें:

function get_arr()
{
    return array(1, 2);
}
$array = get_arr();
$el = array_shift($array);

3

यह कोड:

$monthly_index = array_shift(unpack('H*', date('m/Y')));

इसे में बदलने की आवश्यकता है:

$date_time = date('m/Y');
$unpack = unpack('H*', $date_time);
array_shift($unpack);

3

दूसरा स्निपेट या तो काम नहीं करता है और इसीलिए।

array_shiftएक संशोधक फ़ंक्शन है, जो इसके तर्क को बदलता है। इसलिए यह उम्मीद करता है कि इसका पैरामीटर एक संदर्भ होगा, और आप ऐसी चीज का संदर्भ नहीं दे सकते हैं जो एक चर नहीं है। रासमस के स्पष्टीकरण यहां देखें: सख्त मानक: केवल चर को संदर्भ द्वारा पारित किया जाना चाहिए


0

खैर, इस तरह के स्पष्ट मामलों में, आप हमेशा फ़ंक्शन के सामने "@" का उपयोग करके संदेशों को दबाने के लिए PHP बता सकते हैं।

$monthly_index = @array_shift(unpack('H*', date('m/Y')));

यह सभी को दबाने के लिए सर्वोत्तम प्रोग्रामिंग प्रथाओं में से एक नहीं हो सकता है इस तरह से त्रुटियों , लेकिन कुछ मामलों में (जैसे यह) यह काम आता है और स्वीकार्य है।

परिणामस्वरूप, मुझे यकीन है कि आपका मित्र 'सिस्टम प्रशासक' कम प्रदूषित होने से प्रसन्न होगा error.log


मुझे नहीं पता कि इस उत्तर को किसने अस्वीकार किया, लेकिन प्रस्तुत समाधान काम नहीं करता है और यह एक PHP मानक तकनीक है। वास्तव में निराशाजनक ... अगली बार मैं अब किसी सवाल का जवाब नहीं दे सकता ...:
जूलियो मार्ची

5
मुझे लगता है कि यह इसलिए था क्योंकि त्रुटि संदेश को दबाने से कोड के साथ समस्या ठीक नहीं होती है। जब भविष्य में PHP रिलीज़ में इस प्रकार की त्रुटि E_STRICT से E_ERROR में बदल जाती है तो आपका क्या होगा और आपका कोड अब नहीं चलता है, और कोई त्रुटि / आउटपुट भी उत्पन्न नहीं करता है?
ल्यूक

@TinoDidriksen, मैं कुछ "बुरी आदतों" के खिलाफ सलाह देने के कारणों से समझता हूं और सहमत हूं, खासकर नई पीढ़ियों के लिए। हालाँकि, एक संसाधन मौजूद है जब (और यदि) का उपयोग करना सुरक्षित है और प्रस्तावित संदर्भ के लिए लागू है। यदि त्रुटि दमनकर्ता "@" को समाप्त कर दिया जाता, तो उसे भाषा से ही हटा दिया जाता। "Eval" के रूप में ही (यह बुराई हो सकती है, लेकिन इसके उद्देश्य हैं)। मैं जिस चीज के खिलाफ हूं, वह कुछ संसाधनों के उपयोग के बारे में नहीं है बल्कि एक सलाह के सामान्यीकरण के बारे में है। प्रस्तावित मामले के लिए विशिष्ट रूप से, इसका उपयोग करने के लिए कोई नुकसान नहीं होगा, न कि डिबगिंग उद्देश्यों के लिए भी।
जूलियो मार्ची
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.