المتغيرات المتغيرة تشير إلى صفائف أو كائنات متداخلة

StackOverflow https://stackoverflow.com/questions/2036547

سؤال

هل من الممكن إنشاء متغير متغير يشير إلى صفيف أو إلى كائنات متداخلة؟ يقول مستندات PHP على وجه التحديد أنك لا تستطيع الإشارة إلى Superglobals ولكن غير الواضح (بالنسبة لي على الأقل) إذا كان هذا ينطبق على الصفائف بشكل عام.

هنا هي جربتي في الصفيف var var.

     // Array Example
     $arrayTest = array('value0', 'value1');
     ${arrayVarTest} = 'arrayTest[1]';
     // This returns the correct 'value1'
     echo $arrayTest[1];
     // This returns null
     echo ${$arrayVarTest};   

إليك بعض الكود البسيط لإظهار ما أقصده عن طريق كائن Var Var.

     ${OBJVarVar} = 'classObj->obj'; 
     // This should return the values of $classObj->obj but it will return null  
     var_dump(${$OBJVarVar});    

هل أفتقد شيئا واضحا هنا؟

هل كانت مفيدة؟

المحلول

نهج عنصر الصفيف:

  • استخراج اسم مجموعة من السلسلة وتخزينه في $arrayName.
  • استخراج مؤشر الصفيف من السلسلة وتخزينها في $arrayIndex.
  • تحليلها بشكل صحيح بدلا من ككل.

الرمز:

$arrayTest  = array('value0', 'value1');
$variableArrayElement = 'arrayTest[1]';
$arrayName  = substr($variableArrayElement,0,strpos($variableArrayElement,'['));
$arrayIndex = preg_replace('/[^\d\s]/', '',$variableArrayElement);

// This returns the correct 'value1'
echo ${$arrayName}[$arrayIndex];

نهج خصائص الكائن:

  • تنفجر السلسلة التي تحتوي على الفصل والممتلكات التي تريد الوصول إليها بواسطة محدد (->).
  • تعيين هذين المتغيرين ل $class و $property.
  • تحليلها بشكل منفصل بدلا من ككل على var_dump()

الرمز:

$variableObjectProperty = "classObj->obj";
list($class,$property)  = explode("->",$variableObjectProperty);

// This now return the values of $classObj->obj
var_dump(${$class}->{$property});    

إنها تعمل!

نصائح أخرى

يستخدم = & لتعيين حسب المرجع:

 $arrayTest = array('value0', 'value1');
 $arrayVarTest = &$arrayTest[1];

 $arrayTest[1] = 'newvalue1'; // to test if it's really passed by reference

 print $arrayVarTest;

في echo $arrayTest[1]; اسم vars هو $arrayTest مع مؤشر الصفيف 1, ، و لا $arrayTest[1]. وبعد الأقواس هي PHP "الكلمات الرئيسية". نفسه مع طريقة تدوين -> المشغل أو العامل. لذلك ستحتاج إلى تقسيم.

// bla[1]
$arr = 'bla';
$idx = 1;
echo $arr[$idx];

// foo->bar
$obj = 'foo';
$method = 'bar';
echo $obj->$method;

ما تريد القيام به يبدو أشبه بتقييم رمز PHP (eval()). ولكن تذكر: eval هو الشر. ؛-)

كلا لا يمكنك القيام بذلك. يمكنك فقط القيام بذلك باستخدام أسماء المتغير والكائن والوظيفة.

مثال:

 $objvar = 'classObj';
 var_dump(${$OBJVarVar}->var);

يمكن أن تكون البدائل عبر eval () أو عن طريق القيام مسبقا.

$arrayTest = array('value0', 'value1');
$arrayVarTest = 'arrayTest[1]';

echo eval('return $'.$arrayVarTest.';');
eval('echo $'.$arrayVarTest.';');

هذا إذا كنت متأكدا جدا من ما سيكون الإدخال.

بواسطة المعالجة المسبقة:

function varvar($str){
  if(strpos($str,'->') !== false){
    $parts = explode('->',$str);
    global ${$parts[0]};
    return $parts[0]->$parts[1];
  }elseif(strpos($str,'[') !== false && strpos($str,']') !== false){
    $parts = explode('[',$str);
    global ${$parts[0]};
    $parts[1] = substr($parts[1],0,strlen($parts[1])-1);
    return ${$parts[0]}[$parts[1]];
  }else{
    return false;
  }
}

$arrayTest = array('value0', 'value1');
$test = 'arrayTest[1]';
echo varvar($test);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top