PHP appendChild выдает приятную фатальную ошибку. Неперехваченное исключение «DOMException» с сообщением «Ошибка запроса иерархии — как я могу добавить html ПОСЛЕ тега»

В моем фрагменте кода я пытаюсь найти все теги img с помощью PHP DOM, сразу после этого добавить еще один тег img, а затем обернуть все это в div, т.е.

<!-- From this... -->
<img src="originalImage.jpg" />

<!-- ...to this... -->
<div class="wrappingDiv">
    <img src="originalImage.jpg" />
    <img src="newImage.jpg" />
</div>

Это PHP, который я искажаю и пытаюсь:

$dom = new domDocument;
$dom->loadHTML($the_content_string);
$dom->preserveWhiteSpace = false;
    //get all images and chuck them in an array
$images = $dom->getElementsByTagName('img');
foreach ($images as $image) {
            //create the surrounding div
    $div = $image->ownerDocument->createElement('div');
    $image->setAttribute('class','main-image');
        $added_a = $image->parentNode->insertBefore($div,$image);
        $added_a->setAttribute('class','theme-one');
        $added_a->appendChild($image);
            //create the second image
    $secondary_image = $image->ownerDocument->createElement('img');
    $added_img = $image->appendChild($secondary_image);
    $added_img->setAttribute('src', $twine_img_url);
    $added_img->setAttribute('class', $twine_class);
    $added_img->appendChild($image);
    }

echo $dom->saveHTML();

Все до того места, где я создаю переменную $added_img, работает нормально. Ну по крайней мере не ошибается. Последние четыре строчки убивают его.

Я явно делаю что-то относительно идиотское... Любые милые, милые люди могут указать, где я накосячил?


person Gem    schedule 12.07.2012    source источник


Ответы (1)


Первый:

Вы пытаетесь добавить и изображение к изображению здесь (но, конечно, в HTML изображение не может иметь дочернее изображение, добавьте изображения в div):

$added_img = $image->appendChild($secondary_image);

должно быть

$added_img = $added_a->appendChild($secondary_image);

и снова здесь:

$added_img->appendChild($image);

должно быть:

$added_a->appendChild($image);

Но это вообще не сработает, потому что NodeList жив. Как только вы добавите одно новое изображение, это изображение является частью $images, вы столкнетесь с бесконечным циклом. Поэтому сначала заполните массив исходными изображениями вместо использования NodeList.

$imageList= $dom->getElementsByTagName('img');
$images=array();
for($i=0;$i<$imageList->length;++$i)
{
  $images[]=$imageList->item($i);
}
person Dr.Molle    schedule 12.07.2012
comment
Хорошо, просто чтобы прояснить для себя, что, как вы говорите, я делаю в своем коде: - person Gem; 12.07.2012
comment
Итак, просто чтобы прояснить для себя, что, по-твоему, я делаю в своем коде? изображение, а не просто добавлять второе изображение после исходного изображения? Это правильно? Во-вторых, вы говорите, что, поскольку я переназначаю это $image, это затем добавляется в массив $images и в основном добавляет изображения внутри изображений внутри изображений до бесконечности? Просто хочу прояснить это, я ненавижу не понимать вещи должным образом! - person Gem; 12.07.2012
comment
Первое предположение верно. Что касается второго: проблема не в $image-переменной, проблема в $images. $images — это ссылка на NodeList, живую коллекцию всех <img/> внутри документа. Каждый раз, когда вы добавляете новое изображение (или удаляете изображение), этот NodeList будет изменяться. Итак, в этом случае здесь: когда вы добавляете новое изображение, следующий цикл будет обращаться к вновь созданному изображению. - person Dr.Molle; 12.07.2012
comment
Аааа, понятно, так что $images не является снимком узлов в конкретный момент времени, когда я назначил ему getElementsByTagName(), это представление узлов в реальном времени и обновляется, потому что я напрямую влияю Это. Намного понятнее, спасибо :) Поэтому я должен создать отдельный массив для изображений, как вы предлагаете, запустить его через цикл for, а ЗАТЕМ использовать foreach... Хорошо, я попробую, спасибо! - person Gem; 12.07.2012
comment
ОК, ПОТРЯСАЮЩЕ, ТЕПЕРЬ я кое-что получаю! Единственная проблема заключается в том, что второе изображение добавляется как первый дочерний элемент div. Есть ли способ указать, в какую позицию идет ребенок, ИЛИ мне придется клонировать тег исходного изображения, вставить второе изображение, вставить тег клонированного изображения, а затем удалить исходное изображение, потому что это звучит немного неэффективно. ..? - person Gem; 12.07.2012
comment
ЖДАТЬ!! Он уже делает то, что я хочу, я просто инструмент! Спасибо Dr.Molle, вы легенда! - person Gem; 12.07.2012