Last XML Items Isn't Removable From The XML

半世苍凉 提交于 2019-12-13 06:12:29

问题


I have two php documents that has this same logic. One document is "uploader.php, which writes to the xml once file is upload. The other document is "modifier.php", which writes to the xml once file the is removed. I have two issue with this logic. First issue is deleting last item in the xml list. It doesn't delete the last item and also duplicates the second to last items. Second issue is with it is logging a error on my "uploader.php".

$xml_generator = simplexml_load_file("../file.xml");

if ( $handle = opendir( $path_to_image_dir ) )
{
    while (false !== ($file = readdir($handle)))
    {
        if ( is_file($path.'/'.$file) && $file != "." && $file != ".." && $file != "Thumb.db" && $file != "Thumbs.db" && $file != ".DS_Store" )
        {
            $fileID = $i++;
            list( $width, $height ) = getimagesize($path.'/'.$file);
            $oldImage = $xml_generator->xpath('//images/image[id="'.$fileID.'"]')[0];
            if (!isset($oldImage))
            {
                $image = $xml_generator->addChild('image');
                $image->addChild('id', $fileID);
                $image->addChild('name', $file);
                $image->addChild('width', $width);
                $image->addChild('height', $height);
                $image->addChild('description', '-');
            }
            else
            {
                $oldImage->name = $file;
                $oldImage->width = $width;
                $oldImage->height = $height;
            }
        }
    }
    closedir($handle);
}

$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml_generator->asXML());
echo $dom->save('../file.xml');

Example of the First Issue

Image2.jpg is last item on the list. If I were to delete Image2.jpg, second to last item get duplicated while Image2.jpg remains on XML Document.

<image>
 <id>9</id>
 <name>Image1.jpg</name>
 <width>2551</width>
 <height>1435</height>
 <description>-</description>
</image>
<image>
 <id>10</id>
 <name>Image1.jpg</name>
 <width>2551</width>
 <height>1435</height>
 <description>-</description>
</image>
<image>
 <id>11</id>
 <name>Images2.jpg</name>
 <width>612</width>
 <height>612</height>
 <description>-</description>
</image>

Second Issue is Error Msg .

Undefined offset: 0 in uploader.php on line $oldImage = $xml_generator->xpath('//images/image[id="'.$fileID.'"]')[0];

I think both of these issues are related to the same problem, please help me solve this problem. Thanks!

Delete Code- this code can delete any item except for the last item on the list.

if(isset($_POST['delete'])){
    foreach($_POST['file'] as $file) {
        if(isset($file)) {
            if (unlink($path."/".$file)) {
                echo "Delete the file: $file<br />";
               if (!empty($_SERVER['HTTP_REFERER'])){
                    header("Location: " . $_SERVER['HTTP_REFERER']);
                } else {
                   echo "No referrer.";
                }
            } else {
                echo "Didn't manage to delete the file: $file<br />";
            }
        }
    }
    // very top code goes here.
}

回答1:


However this approach would fail in case images can have the same name or be equal which would be better if you generate a unique name for each uploaded image so it doesn't collide.

Change this line:

$oldImage = $xml_generator->xpath('//images/image[id="'.$fileID.'"]');
if (!isset($oldImage))

To:

$oldImage = $xml_generator->xpath('//images/image[name="'.$file.'"]');
if (count($oldImage) == 0)

To avoid the notices, change this:

else
{
    $oldImage->name = $file;

To:

else
{
    $oldImage = $oldImage[0];
    $oldImage->name = $file;

At your delete file you will have to exclude the element so it doesn't replicate.

Here is an example:

$filename = '../file.xml';
$xml = simplexml_load_file($filename);
if(isset($_POST['delete']))
{
    $deleted = 0;
    foreach($_POST['file'] as $file)
    {
        if(isset($file))
        {
            $image = $xml->xpath("//images/image[name='$file']");
            if (!empty($image))
            {
                if (unlink($path."/".$file))
                {
                    $deleted++;
                    $dom=dom_import_simplexml($image[0]);
                    $dom->parentNode->removeChild($dom);
                    echo "Delete the file: $file<br />";
                    if (!empty($_SERVER['HTTP_REFERER']))
                    {
                        header("Location: " . $_SERVER['HTTP_REFERER']);
                    }
                    else
                    {
                        echo "No referrer.";
                    }
                }
                else
                {
                    echo "Didn't manage to delete the file: $file<br />";
                }
            }
            else
            {
                echo "File not found: $file<br />";
            }
        }
    }
    // Avoid unnecessary saving the file
    if ($deleted > 0)
    {
        $dom = new DOMDocument('1.0');
        $dom->preserveWhiteSpace = false;
        $dom->formatOutput = true;
        $dom->loadXML($xml->asXML());
        $dom->save($filename);
    }
}

Keep in mind that this will also prevent people from deleting a file that does not exist on the XML as if they change the POST request to something else it would not.



来源:https://stackoverflow.com/questions/17731198/last-xml-items-isnt-removable-from-the-xml

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!