كيفية استخدام متغير للوصول إلى عنصر معين ضمن مجموعة متعددة الأبعاد؟

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

سؤال

أنا أستخدم المصفوفات في PHP لتعديل بيانات XML وكتابتها مرة أخرى.هذه هي بنية XML (مبسطة لغرض العرض التوضيحي):

<docs>
  <folder>
    <name>Folder name</name>
    <date>20.06.2009</date>
    <folder>
      <name>Subfolder1</name>
      <date></date>
    </folder>
    <folder>
      <name>Subfolder1</name>
      <date></date>
    </folder>
    <file>
      <name></name>
    </file>
  </folder>
  <name></name>
  <date></date>
</docs>

استخدام هذا الرمز, ، ثم يتم تحليل هذا وتحويله إلى مصفوفة متعددة الأبعاد:

Array
(
    [docs] => Array
        (
            [_c] => Array
                (
                    [folder] => Array
                        (
                            [_c] => Array
                                (
                                    [name] => Array
                                        (
                                            [_v] => Folder name
                                        )

                                    [date] => Array
                                        (
                                            [_v] => 20.06.2009
                                        )

                                    [folder] => Array
                                        (
                                            [0] => Array
                                                (
                                                    [_c] => Array
                                                        (
                                                            [name] => Array
                                                                (
                                                                    [_v] => Subfolder1
                                                                )

                                                            [date] => Array
                                                                (
                                                                    [_v] => 
                                                                )

                                                        )

                                                )

                                            [1] => Array
                                                (
                                                    [_c] => Array
                                                        (
                                                            [name] => Array
                                                                (
                                                                    [_v] => Subfolder1
                                                                )

                                                            [date] => Array
                                                                (
                                                                    [_v] => 
                                                                )

                                                        )

                                                )

                                        )

                                    [file] => Array
                                        (
                                            [_c] => Array
                                                (
                                                    [name] => Array
                                                        (
                                                            [_v] => 
                                                        )

                                                )

                                        )

                                )

                        )

                    [name] => Array
                        (
                            [_v] => 
                        )

                    [date] => Array
                        (
                            [_v] => 
                        )

                )

        )

)

طويلة، وأنا أعلم.ولكن الآن إلى القضية الفعلية.إذا كنت أرغب في إضافة ملف آخر إلى مجلد فرعي يسمى المجلد الفرعي2 في هذه الحالة، لا توجد مشكلة في القيام بذلك يدويًا عندما ترى الهيكل:

array_push($array['docs']['_c']['folder']['_c']['folder'][1], $newfile);

الآن عندما أريد القيام بذلك عبر الوظيفة التي تعرف فقط المسار إلى المجلد (مثل المستندات/اسم المجلد/المجلد الفرعي2)، يجب على الخوارزمية تحليل بنية المصفوفة (تحقق من اسم كل [مجلد]، وتحقق مما إذا كان هناك مجلد واحد أو أكثر ['_c'] أو [رقم]) - كل شيء جيد، لكن لا يمكنني العثور على طريقة لإنشاء متغير من شأنه أن يكون له "مجموعة مصفوفة"المسار لهذا الملف الجديد.

كنت أفكر في مكان ما على هذا المنوال:

$writepath = "['docs']['_c']['folder']...[1]"; // path string
array_push($array{$writepath}, $newfile);

بالطبع هذا ليس بناء جملة صالح.

إذًا، كيف يمكنني إنشاء متغير يحتوي على مسار عبر عناصر المصفوفة؟لقد أجريت القليل من البحث على w3c وphp.net ولم أجد أي معلومات مفيدة حول المصفوفات متعددة الأبعاد...

إذا كان لدى أي شخص أي اقتراحات أخرى بخصوص البنية وتحويل/معالجة XML وما إلى ذلك.وبكل الوسائل، أعلم أنها ليست طريقة كافية للتعامل مع البيانات.

شكرا على أي مساهمة ،

إريك


يحرر:وبخصوص المرجع هل يمكن الرجوع إلى المرجع؟هل ستكون هذه هي الطريقة لتحريك "المؤشر" عبر مجموعة من المصفوفات؟شيء من هذا القبيل:

$pointer = &$array['docs'];
if (key($pointer) == '_c') { $pointer = &$pointer['_c']; }
else (
  // create an array with '_c' key instead of empty '_v' array
)

بناء الجملة هذا لا يعمل.

يحرر:بناء الجملة يعمل ، لا يهم ...شكرا على مساعداتكم ياشباب!

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

المحلول

على الرغم من أن هذا ليس كذلك بالضبط إجابة لسؤالك:بدلاً من رمز الصفيف xml<-> الذي تستخدمه استطاع يستخدم SimpleXML وإمكانيات XPath الخاصة به.

<?php
$xml = '<docs>
  <folder>
    <name>Folder name</name>
    <date>20.06.2009</date>
    <folder>
      <name>Subfolder1</name>
      <date></date>
    </folder>
    <folder>
      <name>Subfolder2</name>
      <date></date>
      <folder>
        <name>Subfolder3</name>
        <date></date>
      </folder>
    </folder>
  </folder>
</docs>';

$doc = new SimpleXMLElement($xml); $pathToParentelement = '//folder[name="Subfolder3"]'; $element = $doc->xpath($pathToParentelement); isset($element[0]) or die('not found');
$newFolder = $element[0]->addChild("folder"); $newFolder->name = "Subfolder4.1"; $newFolder->date = date(DATE_RFC822);
// let's see the result echo $doc->asxml();

$pathToParentelement هو أكثر أو أقل مسار الكتابة الخاص بك.

نصائح أخرى

قد يساعد استخدام المراجع.

يمكنك أولاً كتابة دالة تُرجع مرجعًا إلى الجزء المحدد من المصفوفة لسلسلة مسار.على سبيل المثال، get_path_array("Documents") سيعود $array['docs']['_c']['folder']['_c']['folder'][1], $newfile)

<?php
function &get_path_array($path_str)
{
    // your code to seek to seek the path in the array
    return $result;
}
>?php

الآن لإضافة عنصر، يمكنك القيام بذلك فقط

array_push(get_path_array("docs/Folder name/Subfolder2"), $newfile);

هل هذا ما كنت تبحث عنه؟

(يرى مراجع PHP لمزيد من المعلومات)

يحرر:ردًا على تعليق إريك (من الصعب جدًا إدراجه في تعليق)

أعتقد أنك قد تكون مرتبكًا بشأن كيفية عمل المصفوفات.لا يوجد حقًا أي شيء مثل المصفوفات متعددة الأبعاد في لغة php، فقط المصفوفات التي تخزن صفائف أخرى.على سبيل المثال،

<?php
$a = array(array(1,2,3), array(4,5,6));
$b = $a[1];
echo $b[0];
?>

سيتم إخراج "4".

لاحظ أنه في الكود أعلاه، $b هي نسخة من $a[1], ، تغيير $b لن يؤثر $a[1].ومع ذلك، باستخدام المراجع، يمكن جعل هذا يعمل:

<?php
$a = array(array(1,2,3), array(4,5,6));
$b = &$a[1]; // the & make $b a reference to $a[1]
$b[0] = 4242;
print_r($a);
?>

النواتج:

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 2
            [2] => 3
        )

    [1] => Array
        (
            [0] => 4242
            [1] => 5
            [2] => 6
        )

)

لذلك ليست هناك حاجة أبدًا لإنشاء السلسلة $array['doc']['path'], ، ما عليك سوى استخدام حلقة للبحث عن المصفوفة الصحيحة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top