2009-07-28 15 views
31

मैं पिछले डेवलपर द्वारा किए गए कुछ कोड के माध्यम से काम कर रहा हूं। मैं PHP के लिए काफी नया हूं इसलिए मैं सोच रहा हूं कि इस समस्या के लिए कोई ज्ञात पैटर्न या समाधान है या नहीं।PHP सरणी और 'अपरिभाषित सूचकांक' त्रुटियों का समाधान

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

/* snip */ 
"text" => $link . $top_pick_marker . $output['author'] . " " . " " . 
           $output['new_icon'] . $output['rec_labels'] . "   " 
        . $output['admin_link'] 
        . $output['alternate_title'] 
        . $output['access_info'] 
        . $output['description'] 
        . $output['url'] 
        . $output['subject_terms'] 
        . $output['form_subdivisions'] 
        . $output['dates_of_coverage'] 
        . $output['update_frequency'] 
        . $output['place_terms'], 
    /* snip */ 

तो मैं जानता हूँ कि मैं isset() यहाँ प्रत्येक आइटम के लिए उपयोग कर सकते हैं: यहाँ मैं देख रहा हूँ कोड का एक विशिष्ट खंड है। मुझे चीजों को थोड़ा पुनर्व्यवस्थित करना होगा और अब सभी समेकन को हटा देना होगा। क्या ऐसा करने का कोई और आसान तरीका है या क्या मैं बस इसके साथ अटक गया हूं?

+7

+1 - यह वास्तव में एक अच्छा सवाल है। PHP के "पुराने दिनों" में, इन E_NOTICE त्रुटियों को नहीं फेंक दिया गया था, और अनियंत्रित सरणी अनुक्रमणिका का संदर्भ देना बहुत आम था। जाहिर है यह एक बुरी आदत है, लेकिन PHP के ढीले टाइपिंग के साथ करना आसान है। E_NOTICES अब आपके कोड को कसने में मदद करने के लिए एक अच्छा टूल है। हालांकि, मुझे सरणी को शामिल करने वाले सभी चेकों पर 'isset()' या 'खाली()' को कॉल करने के लिए सरासर टेडियम मिलता है। – zombat

उत्तर

22

चित्रा बाहर क्या कुंजी $ उत्पादन सरणी में हैं, और रिक्त स्ट्रिंग के साथ में लापता लोगों को भरें।

$keys = array_keys($output); 
$desired_keys = array('author', 'new_icon', 'admin_link', 'etc.'); 

foreach($desired_keys as $desired_key){ 
    if(in_array($desired_key, $keys)) continue; // already set 
    $output[$desired_key] = ''; 
} 
+0

यह इंडेक्स कुंजी की एक बड़ी सूची के लिए एक अच्छा समाधान है। मैं पोस्टर की समस्या के लिए ऐसा कुछ उपयोग करूंगा। – zombat

+0

मैं डिफ़ॉल्ट को ** शून्य ** –

+0

पर सेट करना पसंद करता हूं यह बहुत अच्छा है अगर आपका '$ आउटपुट' सरणी बहु-आयामी है। – cdmo

4

शुरुआत में सरणी में प्रत्येक इंडेक्स सेट करें (या $output सरणी का उपयोग करने से पहले) शायद आपके मामले के लिए सबसे आसान समाधान होगा।

उदाहरण

$output['admin_link'] = "" 
$output['alternate_title'] = "" 
$output['access_info'] = "" 
$output['description'] = "" 
$output['url'] = "" 

इसके अलावा वास्तव में अपने मामले के लिए प्रासंगिक नहीं है, लेकिन जहां कहा आप PHP के लिए नए थे और यह वास्तव में तुरंत स्पष्ट isset() कई तर्क ले जा सकते हैं नहीं है। इस की जगह में तो:

if(isset($var1) && isset($var2) && isset($var3) ...){ 
    // all are set 
} 

आप कर सकते हैं:

if(isset($var1, $var2, $var3)){ 
    // all are set 
} 
10

आप संयोजन खोने के बिना isset() का उपयोग कर सकते हैं:

//snip 
$str = 'something' 
. (isset($output['alternate_title']) ? $output['alternate_title'] : '') 
. (isset($output['access_info']) ? $output['access_info'] : '') 
. //etc. 

तुम भी सेट होने पर इससे स्ट्रिंग वापस जाने के लिए एक समारोह लिख सकता है - यह शायद बहुत ही कुशल नहीं है:

function getIfSet(& $var) { 
    if (isset($var)) { 
     return $var; 
    } 
    return null; 
} 

$str = getIfSet($output['alternate_title']) . getIfSet($output['access_info']) //etc 

आपको नोटिस नहीं मिलेगा क्योंकि चर संदर्भ द्वारा पारित किया गया है।

+0

उसने किया कहें कि वह 'जारीकर्ता' का उपयोग नहीं करना चाहता था, लेकिन यह अभी भी 'जारीकर्ता' के साथ ऐसा करने का "सबसे अच्छा" तरीका है। – MitMaro

+0

इसके अलावा इस तरह से लागू करना मुश्किल नहीं होगा क्योंकि आप संभवत: रेगेक्स खोज का उपयोग कर सकते हैं और इसे स्वचालित रूप से करने के लिए प्रतिस्थापित कर सकते हैं। – MitMaro

+0

@ मितमारो - सहमत हुए। मुझे स्ट्रिंग आउटपुट या कॉन्सटेनेशन के लिए इस समस्या को संभालने के लिए टर्नरी ऑपरेटर बहुत आसान लगता है। सरणी कुंजियों की एक छोटी संख्या के लिए, यह विधि अच्छी तरह से काम करती है। – zombat

-2

आप एक अच्छा छोटा फ़ंक्शन का उपयोग करने का प्रयास कर सकते हैं जो मान को वापस कर देगा यदि यह मौजूद है या खाली स्ट्रिंग नहीं है। यह मैं क्या उपयोग है:

function arrayValueForKey($arrayName, $key) { 
    if (isset($GLOBALS[$arrayName]) && isset($GLOBALS[$arrayName][$key])) { 
     return $GLOBALS[$variable][$key]; 
    } else { 
     return ''; 
    } 
} 

तो फिर तुम इसे इस तरह उपयोग कर सकते हैं:

echo ' Values: ' . arrayValueForKey('output', 'admin_link') 
       . arrayValueForKey('output', 'update_frequency'); 

और यह किसी भी त्रुटि के ऊपर फेंक नहीं होगा!

आशा है कि इससे मदद मिलती है!

+0

केवल तर्कों का उपयोग करने के बजाय 'ग्लोबल्स' का उपयोग क्यों करें? – grantwparks

+0

ग्लोबल्स का उपयोग करना ऐसा करने का एक अच्छा तरीका होगा क्योंकि यह फ़ंक्शन में तीसरे तर्क से बचाता है, चीजों को साफ और सरल बनाने के लिए बार-बार उपयोग करता है। माना जाता है कि यह ओओ PHP का उपयोग करते समय काम नहीं करेगा, लेकिन सरल चीजों के लिए यह सरणी तक पहुंचने के लिए सामान्य रूप से आवश्यक होने की तुलना में अधिक कोड के साथ बहुत अच्छा काम करेगा। –

5

यदि आप पुराने कोड को बनाए रखते हैं, तो संभवतः आप "सबसे अच्छा संभव कोड" का लक्ष्य नहीं रख सकते हैं ... यह एक मामला है, जब मेरी राय में, आप error_reporting स्तर को कम कर सकते हैं।

ये "अपरिभाषित सूचकांक" केवल नोटिस होना चाहिए; इसलिए, आप नोटिस को बाहर करने के लिए error_reporting स्तर सेट कर सकते हैं।

एक समाधान इस तरह, error_reporting समारोह के साथ है:

// Report all errors except E_NOTICE 
error_reporting(E_ALL^E_NOTICE); 

इस समाधान के साथ अच्छी बात आपको सूचनाएँ बाहर करने के लिए केवल जब यह आवश्यक (माना है उदाहरण के लिए, यह सेट कर सकते हैं, अगर वहाँ है उस तरह के कोड के साथ केवल एक या दो फाइलें)

एक अन्य समाधान php.ini में इसे सेट करना होगा (यदि आप कई अनुप्रयोगों पर काम कर रहे हैं तो ऐसा अच्छा विचार नहीं हो सकता है, हालांकि यह मुखौटा हो सकता है उपयोगी नोटिस); php.ini में error_reporting देखें।

लेकिन मैं जोर देता हूं: यह केवल स्वीकार्य है क्योंकि आप पुराने एप्लिकेशन को बनाए रखते हैं - आपको नया कोड विकसित करते समय ऐसा नहीं करना चाहिए!

+1

व्यक्तिगत रूप से मुझे नहीं लगता कि आपको कभी भी पुराने कोड में किसी भी 'त्रुटियों' को छिपाना चाहिए। अधिक संभावना है कि पुराने कोड में त्रुटियों को छुपाया जाएगा और उन्हें ठीक करने के लिए कोई प्रोत्साहन नहीं होगा। – MitMaro

+0

मैं सहमत हूं, और मुझे ऐसा करना पसंद नहीं है; लेकिन, कभी-कभी, वास्तव में कोई अन्य तरीका नहीं है, यदि आप काम करने में सक्षम होना चाहते हैं (कम से कम यदि आपके पास उनको सही करने के लिए पर्याप्त समय नहीं है); विशेष रूप से जब एप्लिकेशन किसी ऐसे व्यक्ति द्वारा विकसित किया गया है जो नहीं जानता कि नोटिस क्या हैं और दोनों सक्षम हैं और उन्हें टालने के लिए ... –

6

SquareRootOf2 के जवाब पर एक बदलाव है, लेकिन इस $ उत्पादन चर का पहला प्रयोग से पहले रखा जाना चाहिए:

$keys = array('key1', 'key2', 'etc'); 
$output = array_fill_keys($keys, ''); 
+0

मुझे "लूप का उपयोग न करने" का विचार पसंद है और PHP फ़ंक्शंस का उपयोग करना पसंद करते हैं। मेरा सुझाव है 'array_merge() 'जैसे' $ output = array_merge ($ incomplete_output, $ output) 'का उपयोग करना है? मुझसे +1 –

1

एक ही विचार माइकल झरना

से CodeIgniter

// Lets you determine whether an array index is set and whether it has a value. 
// If the element is empty it returns FALSE (or whatever you specify as the default value.) 
function element($item, $array, $default = FALSE) 
{ 
    if (! isset($array[$item]) OR $array[$item] == "") 
    { 
     return $default; 
    } 

    return $array[$item]; 
} 
-3
foreach($i=0; $i<10; $i++){ 
    $v = @(array)$v; 
    // this could help defining $v as an array. 
    //@ is to supress undefined variable $v 

    array_push($v, $i); 
} 
के रूप में
2

यह एक छोटा सा समाधान है (PHP 5.3+):

$output['alternate_title'] = $output['alternate_title'] ?:''; 

आपको वैरिएबल का मान मिलता है, अगर यह झूठी, या झूठी अभिव्यक्ति का मूल्यांकन नहीं करता है। ('12 'के बाद एक)

"अगर सही" पैरामीटर के बिना, टर्नरी ऑपरेटर का उपयोग करके, परीक्षण अभिव्यक्ति (पहला वाला) का परिणाम वापस आ जाएगा क्योंकि अपरिभाषित मूल्यांकन गलत है, झूठी अभिव्यक्ति होगी लौटा हुआ।

पीएचपी 7 में थोड़ा और अधिक सुरुचिपूर्ण अशक्त कोलेसिंग ऑपरेटर है:

$output['alternate_title'] = $output['alternate_title'] ?? ''; 

2

यह सबसे तेजी से समाधान मैं है ('? =' ऐसा लगता है कि एक डिफ़ॉल्ट असाइनमेंट ऑपरेटर के साथ अच्छा होगा) के बारे में सोच सकते हैं, लेकिन अब तक सबसे अच्छा नहीं है। तो एक "आपातकालीन समाधान" के रूप में देखते:

// ... 
. @$output['admin_link'] 
. @$output['alternate_title'] 
. @$output['access_info'] 
// ... 

@ सभी पीएचपी चेतावनी और त्रुटियों को रोकता है।

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