2013-09-26 8 views
5

का उपयोग कर एक्सेस सरणी मुझे php में सरणी तक पहुंचने में कोई समस्या है।गतिशील पथ

$path = "['a']['b']['c']"; 
$value = $array.$path; 

कोड के उपरोक्त भाग में मेरे पास $ सरणी नामक एक बहुआयामी सरणी है।

$path एक गतिशील मान है जो मुझे डेटाबेस से प्राप्त होगा।

अब मैं $ पथ का उपयोग कर $ सरणी से मूल्य पुनर्प्राप्त करना चाहता हूं लेकिन मैं सक्षम नहीं हूं।

$value = $array.$path 

मुझे रिटर्न

Array['a']['b']['c'] 

बल्कि मूल्य से।

मुझे आशा है कि मैंने अपने प्रश्न को सही तरीके से समझाया है।

+0

$ value = $ array [$ path] आज़माएं; – Pupil

+0

मैंने कोशिश की लेकिन यह $ array [['a'] ['b'] ['c']] जैसी कुछ व्याख्या करता है। तो यह मेरे लिए काम नहीं करता –

+0

'$ path = ['a'] ['b'] ['c']' मान्य PHP वाक्यविन्यास नहीं है। क्या यह एक स्ट्रिंग है? –

उत्तर

11

आपके पास दो विकल्प हैं। सबसे पहले (बुराई) eval() फ़ंक्शन का उपयोग करने के लिए - यानी अपनी स्ट्रिंग को कोड के रूप में समझें।

दूसरा आपके पथ को पार्स करना है। यही कारण है कि हो जाएगा:

//$path = "['a']['b']['c']"; 
preg_match_all("/\['(.*?)'\]/", $path, $rgMatches); 
$rgResult = $array; 
foreach($rgMatches[1] as $sPath) 
{ 
    $rgResult=$rgResult[$sPath]; 
} 
+0

'\ [(\ "|') (। *?) (\ 1) \]' और '$ rgMathces [2]' –

+0

का उपयोग करने के लिए एक मामूली सुधार होगा आपका कोड लंबवत तरीके से काम करता है जो पहले होता है $ rgResult ['a'] के लिए $ rgResult ['b'] और फिर $ rgResult ['c']। मुझे $ rgResult ['a'] ['b'] ['c'] –

+0

@ExplosionPills वास्तव में, मेरा कोड सिर्फ विश्लेषण विचार के लिए एक नमूना है।वास्तविक स्थिति अधिक जटिल हो सकती है (जैसे '$ path = "[$ a [$ b] [$ c [$ d]]] [$ e]" 'e t.c.) –

2

Kohana framework "Arr" class (API) एक विधि (Arr::path) है कि तुम क्या अनुरोध कर रहे हैं करने के लिए कुछ ऐसा ही है। यह केवल एक सरणी और पथ लेता है (. के साथ delimiter के रूप में) और यदि पाया जाता है तो मान देता है। आप अपनी आवश्यकताओं के अनुरूप इस विधि को संशोधित कर सकते हैं।

public static function path($array, $path, $default = NULL, $delimiter = NULL) 
{ 
    if (! Arr::is_array($array)) 
    { 
     // This is not an array! 
     return $default; 
    } 

    if (is_array($path)) 
    { 
     // The path has already been separated into keys 
     $keys = $path; 
    } 
    else 
    { 
     if (array_key_exists($path, $array)) 
     { 
      // No need to do extra processing 
      return $array[$path]; 
     } 

     if ($delimiter === NULL) 
     { 
      // Use the default delimiter 
      $delimiter = Arr::$delimiter; 
     } 

     // Remove starting delimiters and spaces 
     $path = ltrim($path, "{$delimiter} "); 

     // Remove ending delimiters, spaces, and wildcards 
     $path = rtrim($path, "{$delimiter} *"); 

     // Split the keys by delimiter 
     $keys = explode($delimiter, $path); 
    } 

    do 
    { 
     $key = array_shift($keys); 

     if (ctype_digit($key)) 
     { 
      // Make the key an integer 
      $key = (int) $key; 
     } 

     if (isset($array[$key])) 
     { 
      if ($keys) 
      { 
       if (Arr::is_array($array[$key])) 
       { 
        // Dig down into the next part of the path 
        $array = $array[$key]; 
       } 
       else 
       { 
        // Unable to dig deeper 
        break; 
       } 
      } 
      else 
      { 
       // Found the path requested 
       return $array[$key]; 
      } 
     } 
     elseif ($key === '*') 
     { 
      // Handle wildcards 

      $values = array(); 
      foreach ($array as $arr) 
      { 
       if ($value = Arr::path($arr, implode('.', $keys))) 
       { 
        $values[] = $value; 
       } 
      } 

      if ($values) 
      { 
       // Found the values requested 
       return $values; 
      } 
      else 
      { 
       // Unable to dig deeper 
       break; 
      } 
     } 
     else 
     { 
      // Unable to dig deeper 
      break; 
     } 
    } 
    while ($keys); 

    // Unable to find the value requested 
    return $default; 
} 
0

मैं अपरिभाषित सूचकांक त्रुटियों फेंकने के बिना नेस्टेड सरणी का उपयोग करने के लिए एक सुरुचिपूर्ण समाधान खोजने के लिए उम्मीद कर रहा था, और इस पोस्ट गूगल पर उच्च हिट। मैं पार्टी के लिए देर हो चुकी हूं, लेकिन मैं भविष्य के आगंतुकों के लिए वजन करना चाहता था।

एक साधारण isset($array['a']['b']['c'] सुरक्षित रूप से नेस्टेड मानों की जांच कर सकता है, लेकिन आपको समय से पहले पहुंचने के लिए तत्वों को जानने की आवश्यकता है। मुझे बहुआयामी सरणी तक पहुंचने के लिए डॉट नोटेशन पसंद है, इसलिए मैंने अपनी एक कक्षा लिखी। यह PHP 5.6 की आवश्यकता है।

यह कक्षा डॉट-नोटेशन में लिखे गए एक स्ट्रिंग पथ को पार करती है और सरणी या सरणी जैसी वस्तु (सुरक्षित ArrayAccess लागू) के नेस्टेड मानों को सुरक्षित रूप से एक्सेस करती है। सेट नहीं होने पर यह मान या NULL वापस कर देगा।

use ArrayAccess; 

class SafeArrayGetter implements \JsonSerializable { 

/** 
* @var array 
*/ 
private $data; 

/** 
* SafeArrayGetter constructor. 
* 
* @param array $data 
*/ 
public function __construct(array $data) 
{ 
    $this->data = $data; 
} 

/** 
* @param array $target 
* @param array ...$indices 
* 
* @return array|mixed|null 
*/ 
protected function safeGet(array $target, ...$indices) 
{ 
    $movingTarget = $target; 

    foreach ($indices as $index) 
    { 
     $isArray = is_array($movingTarget) || $movingTarget instanceof ArrayAccess; 
     if (! $isArray || ! isset($movingTarget[ $index ])) return NULL; 

     $movingTarget = $movingTarget[ $index ]; 
    } 

    return $movingTarget; 
} 

/** 
* @param array ...$keys 
* 
* @return array|mixed|null 
*/ 
public function getKeys(...$keys) 
{ 
    return static::safeGet($this->data, ...$keys); 
} 

/** 
* <p>Access nested array index values by providing a dot notation access string.</p> 
* <p>Example: $safeArrayGetter->get('customer.paymentInfo.ccToken') == 
* $array['customer']['paymentInfo']['ccToken']</p> 
* 
* @param $accessString 
* 
* @return array|mixed|null 
*/ 
public function get($accessString) 
{ 
    $keys = $this->parseDotNotation($accessString); 

    return $this->getKeys(...$keys); 
} 

/** 
* @param $string 
* 
* @return array 
*/ 
protected function parseDotNotation($string) 
{ 
    return explode('.', strval($string)); 
} 

/** 
* @return array 
*/ 
public function toArray() 
{ 
    return $this->data; 
} 

/** 
* @param int $options 
* @param int $depth 
* 
* @return string 
*/ 
public function toJson($options = 0, $depth = 512) 
{ 
    return json_encode($this, $options, $depth); 
} 

/** 
* @param array $data 
* 
* @return static 
*/ 
public static function newFromArray(array $data) 
{ 
    return new static($data); 
} 

/** 
* @param \stdClass $data 
* 
* @return static 
*/ 
public static function newFromObject(\stdClass $data) 
{ 
    return new static(json_decode(json_encode($data), TRUE)); 
} 

/** 
* Specify data which should be serialized to JSON 
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php 
* @return array data which can be serialized by <b>json_encode</b>, 
* which is a value of any type other than a resource. 
* @since 5.4.0 
*/ 
function jsonSerialize() 
{ 
    return $this->toArray(); 
} 
} 
संबंधित मुद्दे