वेरिएबल एरे? ... या कुछ एरे-लाइक की तरह कैसे चेक करें?


90

मैं foreachएक चर के साथ एक लूप का उपयोग करना चाहता हूं , लेकिन यह चर कई अलग-अलग प्रकार के हो सकते हैं, NULLउदाहरण के लिए।

इसलिए इससे पहले कि foreachमैं इसका परीक्षण करूं:

if(is_array($var)){
  foreach($var as ...

लेकिन मुझे एहसास हुआ कि यह एक वर्ग भी हो सकता है जो Iteratorइंटरफ़ेस को लागू करता है। शायद मैं अंधा हूं लेकिन यह कैसे जांचना है कि क्या वर्ग इंटरफ़ेस को लागू करता है? क्या is_aफंक्शन या inheritsऑपरेटर जैसा कुछ है ? मैंने पाया class_implements, मैं इसका उपयोग कर सकता हूं, लेकिन शायद कुछ सरल है?

और दूसरा, अधिक महत्वपूर्ण, मुझे लगता है कि यह फ़ंक्शन मौजूद है, यह जांचने के लिए पर्याप्त होगा कि क्या चर is_arrayया "इम्प्लीमेंट Iteratorइंटरफ़ेस" या मुझे कुछ और के लिए परीक्षण करना चाहिए?


2
अगर ($ वार इंस्टाफॉरेक्टर)
एलेक्सी

हाँ, मुझे इतना यकीन था कि यह काम नहीं करेगा जो मैनुअल को भी नहीं देखता ...
Voitcus

जवाबों:


79

यदि आप foreachकिसी फ़ंक्शन के अंदर उपयोग कर रहे हैं और आप किसी सरणी या ट्रैवर्सेबल ऑब्जेक्ट की अपेक्षा कर रहे हैं, तो आप उस फ़ंक्शन को संकेत के साथ टाइप कर सकते हैं:

function myFunction(array $a)
function myFunction(Traversable)

यदि आप foreachकिसी फ़ंक्शन के अंदर उपयोग नहीं कर रहे हैं या आप उम्मीद कर रहे हैं कि आप दोनों इस निर्माण का उपयोग कर सकते हैं यह जाँचने के लिए कि क्या आप चर पर पुनरावृत्ति कर सकते हैं:

if (is_array($a) or ($a instanceof Traversable))

धन्यवाद। मुझे उम्मीद है कि यह पर्याप्त है और इसमें कोई अन्य भाषा निर्माण नहीं होंगे जो इसे पुनरावृत्त कर सकते हैं।
वोइटस्कस

मुझे is_arrayमहंगा पड़ा था । संगणकीय लागत सरणी के आकार के साथ बढ़ती हुई प्रतीत हुई (जिसका कोई मतलब नहीं है क्योंकि यह जाँच रहा है कि क्या यह सरणी है)। लेकिन यह मेरे साथ एक पुस्तकालय में हुआ। लिंक्ड प्रश्न में मेरी टिप्पणी देखें । instanceof Traversableसरणियों के साथ काम करेंगे ? मुझे इसके प्रदर्शन का परीक्षण करने का मौका नहीं मिला।
ADTC

@ADTC AFAIR एक सरणी Traversableतो हां का एक उदाहरण है ।
जूता

1
@ शोहो मैंने यहाँ कोशिश की । $var = array(1,2,3);परिणामों के साथ हैं: is_array($var) = trueऔर $var instanceof Traversable = false
ADTC

@ADTC हाँ, बस जाँच की गई। ऐरे लागू Iteratorनहीं करते हैं और इसलिए साथ काम नहीं करते हैं Traversable
जूता

15

foreachसरणियों और वस्तुओं को संभाल सकते हैं। आप इसके साथ देख सकते हैं:

$can_foreach = is_array($var) || is_object($var);
if ($can_foreach) {
    foreach ($var as ...
}

आपको विशेष रूप से जांचने की आवश्यकता नहीं है Traversableक्योंकि अन्य लोगों ने अपने उत्तर में यह संकेत दिया है, क्योंकि सभी ऑब्जेक्ट - जैसे सभी सरणियाँ - PHP में ट्रैवर्सेबल हैं।

अधिक तकनीकी रूप से:

foreachसभी प्रकार के ट्रैवर्सेबल्स के साथ कार्य करता है, अर्थात सरणियों के साथ, सादे वस्तुओं के साथ (जहां सुलभ गुण ट्रैवर्स किए गए हैं) और Traversableऑब्जेक्ट्स (या बल्कि ऑब्जेक्ट जो आंतरिक get_iteratorहैंडलर को परिभाषित करते हैं )।

( स्रोत )

सामान्य PHP प्रोग्रामिंग में कहा जाता है, जब भी एक चर है

  • एक सरणी
  • एक वस्तु

और नहीं है

  • शून्य
  • संसाधन
  • एक स्केलर

आप इस foreachपर उपयोग कर सकते हैं ।


5

आप Traversableएक साधारण फ़ंक्शन के साथ उदाहरण देख सकते हैं । यह इस Iteratorवजह से काम करेगाIterator extends Traversable

function canLoop($mixed) {
    return is_array($mixed) || $mixed instanceof Traversable ? true : false;
}

"? सच: गलत" हिस्सा बेमानी है। Instof परिणामस्वरूप पहले से ही एक बूल मान देता है।
लिनास


0

कार्य

<?php

/**
 * Is Array?
 * @param mixed $x
 * @return bool
 */
function isArray($x) : bool {
  return !isAssociative($x);
}

/**
 * Is Associative Array?
 * @param mixed $x
 * @return bool
 */
function isAssociative($x) : bool {
  if (!is_array($array)) {
    return false;
  }
  $i = count($array);
  while ($i > 0) {
    if (!isset($array[--$i])) {
      return true;
    }
  }
  return false;
}

उदाहरण

<?php

$arr = [ 'foo', 'bar' ];
$obj = [ 'foo' => 'bar' ];

var_dump(isAssociative($arr));
# bool(false)

var_dump(isAssociative($obj));
# bool(true)

var_dump(isArray($obj));
# bool(false)

var_dump(isArray($arr));
# bool(true)

0

PHP 7.1 के बाद से iterableइस उद्देश्य के लिए एक छद्म प्रकार है । टाइप-हिंटिंग iterableकिसी भी सरणी के साथ-साथ Traversableइंटरफ़ेस के किसी भी कार्यान्वयन को स्वीकार करता है। PHP 7.1 ने भी फंक्शन की शुरुआत की is_iterable()। पुराने संस्करणों के लिए, नए अंतर्निहित सुविधाओं के बिना समकक्ष प्रकार के प्रवर्तन को पूरा करने के लिए अन्य उत्तर यहां देखें।

फेयर प्ले: जैसा कि ब्लैकहोल ने बताया है, यह प्रश्न Iterable ऑब्जेक्ट्स और अरै टाइप हिन्टिंग का डुप्लिकेट प्रतीत होता है ? और उसका जवाब खदान की तुलना में आगे विस्तार में है।

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