View Full Version : unset problem
I am Abby
04-29-2010, 01:47 PM
I tested the foreach with an echo so it works but now I'm getting strange results with 'unset'. One thing I tried shut down my Appache server another just adds "</myquotes>" to the end of the .xml which is better than nothing but not good enough.
the php:
$dcount = array();
$dcount = $_POST["dcount"];
$dfile = '../sidebar.xml';
$dxml = simplexml_load_file($dfile);
foreach($dxml->children() as $dkid)
{
if(in_array($dkid->id, $dcount))
{
unset($dxml->myquotes->$dcount);
//usenet($dxml->myquotes->$dcount); - This one adds "</myquotes> to existing file
//unset($dxml->$dkid->id); - This one shuts off my Appache server
//$dxml = $dxml->asXML();
$dxml = $dxml->asXML($dfile);
}
}
the xml structure
<sidebar>
<myquotes>
<id>10001</id>
<thequote>It's elementry my dear Watson...</thequote>
<reference>Sherlock Holmes</reference>
</myquotes>
</sidebar>
Have you tried
foreach($dxml->children() as $dkid){
if(in_array($dkid->id, $dcount)){
unset($dkid);
}
}
?
I am Abby
04-29-2010, 04:12 PM
What I now have doesn't give me any errors but doesn't modify my xml.
// Deleting an Announcement)
if ( $_POST['deletechecker'] == 1 )
{
$dcount = array();
$dcount = $_POST["dcount"];
$dfile = '../sidebar.xml';
$dxml = simplexml_load_file($dfile);
foreach($dxml->children() as $dkid)
{
if(in_array($dkid->id, $dcount))
{
unset($dkid);
}
}
}
Shouldn't I have a '$dxml->save("../sidebar.xml");' somewhere after the if statment?
What I now have doesn't give me any errors but doesn't modify my xml.
// Deleting an Announcement)
if ( $_POST['deletechecker'] == 1 )
{
$dcount = array();
$dcount = $_POST["dcount"];
$dfile = '../sidebar.xml';
$dxml = simplexml_load_file($dfile);
foreach($dxml->children() as $dkid)
{
if(in_array($dkid->id, $dcount))
{
unset($dkid);
}
}
}
Shouldn't I have a '$dxml->save("../sidebar.xml");' somewhere after the if statment?
yeah, sorry. I meant for you to keep that line at the end, but I didn't copy it.
$dxml = $dxml->asXML($dfile);
I am Abby
04-30-2010, 03:23 AM
It seems to be writing the full original xml back to itself. I know this because I have the xml open in dreamweaver...when I try to delete an entry from the web page I get a message in dreamweaver telling me it has been updated. However it's still the same as before.
And I know the foreach works correctly because I had it echoing back the id without a problem.
if ( $_POST['deletechecker'] == 1 )
{
$dcount = array();
$dcount = $_POST["dcount"];
$dfile = '../sidebar.xml';
$dxml = simplexml_load_file($dfile);
foreach($dxml->children() as $dkid)
{
if(in_array($dkid->id, $dcount))
{
unset($dkid);
}
}
$dxml = $dxml->asXML($dfile);
I tried moving the last line up under the unset($dkid) but that didn't work at all.
let me set this up and do some testing. I'll let you know.
OKAY...
If you know the node structure of your xml, this works:
xml:
<sidebar>
<myquotes>
<id>10001</id>
<thequote>It's elementry my dear Watson...</thequote>
<reference>Sherlock Holmes</reference>
</myquotes>
</sidebar>
$file = 'sidebar.xml';
$xml = simplexml_load_file($file);
// $dcount is the <id> of the item you wish to delete
$i = 0;
foreach($xml as $kid){
if($kid->id == $dcount){
unset($xml->myquotes[$i]); break;
}
$i ++;
}
$xml = $xml->asXML($file);
this loops though the xml nodes and deletes the one who's <id> matches $dcount. Notice that we must already know the node structure (e.g., we already know that the $xml->children() are named <myquotes> ). This will be fine for your application, but it's not very dynamic.
The break; is important for two reasons:
1) You probably only want to delete one quote. If there's another that mistakenly has the same <id>, it will go too.
2) The foreach() loop counts the elements it will loop through - and therefore, expects to loop x times. After you unset() the desired variable, there is one fewer element available, and so you'll get a warning for trying to loop over a non-existent element:
Warning: main() [function.main]: Node no longer exists in /blah/blah/blah on line whatever
It still works fine, but I want to get it right.
I am Abby
05-03-2010, 01:24 PM
The code is still printing the original .xml back to itself. Is it possible that other parts of my page could be messing with the code to delete objects? I use a DOMDocuments object to update my counter…I did this before I learned that Simplexml was better…could that be causing the problem? But then this code does not activate unless you are adding a new quote. I'm starting to pull my hair out in frustration...me bald is not pretty.
Below is my entire page…could there be something the code that interferes with the deleting of objects?
<?php
//Adding New Announcement
if ( isset($_POST['iquote']) && !empty($_POST['iquote']) )
{
//Save new Announcement to sidebar.xml
$insertcount = $_POST["newcount"];
$insertquote = $_POST["iquote"];
$insertref = $_POST["iref"];
$file = '../sidebar.xml';
$xml = simplexml_load_file($file);
// add new <myquote>
$newItem = $xml->addChild('myquotes');
// add new <id> to <myquote>
$newItem->addChild('id', $insertcount);
// add new <thequote> to <myquote>
$newItem->addChild('thequote', $insertquote);
// add new <reference> to <myquote>
$newItem->addChild('reference', $insertref);
// convert $xml object to string
// and save to sidebar.xml file
$xml = $xml->asXML($file);
//Set and Update Counter to sidebarcounter.xml
$updatecount = $_POST["newcount"] + 1;
$counters = array();
$counters [] = array(
'numcount' => $updatecount
);
$doc = new DOMDocument();
$doc->formatOutput = true;
$r = $doc->createElement( "counters" );
$doc->appendChild( $r );
foreach ( $counters as $mycount )
{
$b = $doc->createElement ( "mycount" );
$numcount = $doc->createElement( "numcount" );
$numcount->appendChild(
$doc->createTextNode( $mycount['numcount'])
);
$b->appendChild( $numcount );
$r->appendChild( $b );
}
$doc->save("../sidebarcounter.xml");
header('Location: '.$_SERVER['PHP_SELF'].'?iquote='.$iquote);
}
// Deleting an Announcement)
if ( $_POST['deletechecker'] == 1 )
{
// $dcount = array();
$dcount = $_POST["dcount"];
$file = '../sidebar.xml';
$xml = simplexml_load_file($file);
echo $dcount;
// $dcount is the <id> of the item you wish to delete
$i = 0;
foreach($xml as $kid){
if($kid->id == $dcount){
unset($xml->myquotes[$i]); break;
}
$i ++;
}
$xml = $xml->asXML($file);
}
?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Announcements</title>
<script language="javascript">
function addhidden(){
document.insertsidebar.deletechecker.value = 1;
}
function subhidden(){
document.insertsidebar.deletechecker.value = 0;
}
</script>
</head>
<body onLoad="subhidden()">
<form action="<?php echo $PHP_SELF;?>" method="post" enctype="multipart/form-data" name="insertsidebar" id="insertsidebar">
<input type="hidden" name="deletechecker" id="deletechecker">
<?php
//get count
$doc = new DOMDocument();
$doc->load('../sidebarcounter.xml');
$getcount = $doc->getElementsByTagName( "mycount" );
$newnumcount = $getcount->item(0)->nodeValue;
echo"<input type='hidden' name='newcount' id='newcount' value=$newnumcount>"
?>
<h3>Add New Sidebar Anouncement</h3>
<p>
<label>Quote
<input name="iquote" type="text" id="iquote" size="140" />
</label>
</p>
<p>
<label>Reference
<input type="text" name="iref" id="iref" />
</label>
<label>
<input type="submit" name="submit" id="submit" value="Submit" />
</label>
</p>
<?php
//list all entries to delete
$file = '../sidebar.xml';
$xml = simplexml_load_file($file);
foreach($xml->children() as $myquote)
{
echo"
<hr>
Quote: ".$myquote->thequote."<br />
Reference: ".$myquote->reference."<br />
<input type=\"checkbox\" name=\"dcount[]\" id=\"dcount[]\" value=".$myquote->id." onClick=\"addhidden()\" /> Delete Item";
}
?>
</form>
</body>
</html>
The other two files are:
sidebarcounter.xml
<counters>
<mycount>10009</mycount>
</counters>
sidebar.xml
<sidebar>
<myquotes>
<id>10008</id>
<thequote>the quote goes here</thequote>
<reference>who said it</reference>
</myquotes>
</sidebar>
thanks
djr33
05-03-2010, 05:00 PM
Please use [code] tags around your code while posting, every time.
I am Abby
05-03-2010, 05:09 PM
Will do, sorry.
I will look at that more closely when I get home, but if you think something could be interfering then put the "deleting" code on a separate page, by itself, and see if it works then. If it does, than something is interfering within the main script.
I am Abby
05-04-2010, 02:39 PM
After getting rid of the other php code, I still had the same problem.
keep troubleshooting...
// Deleting an Announcement)
if ( $_POST['deletechecker'] == 1 )
{
// check that the code is being triggered
echo $_POST['deletechecker'];
// $dcount = array();
// the above line IS COMMENTED OUT in your script, correct?
$dcount = $_POST["dcount"];
// Check that we're getting the correct $dcount value
echo $dcount;
$file = '../sidebar.xml';
$xml = simplexml_load_file($file);
$i = 0;
foreach($xml as $kid){
// see what we're comparing $dcount to each time
echo $kid->id;
if($kid->id == $dcount){
// see if script finds a match
echo $kid->id.' is equal to '.$dcount;
// make sure it's the right entry
echo $xml->myquotes[$i];
unset($xml->myquotes[$i]); break;
}
$i ++;
}
$xml = $xml->asXML($file);
}
I am Abby
05-04-2010, 04:26 PM
I think I found the problem but do not understand.
when I echo $dcount, the reply is "Array" and becuase of this it is never equal to $kid->id.
The question is why is $dcount = Array instead of being an array?
I saw this before which lead me to comment out "$dcount = array();"
djr33
05-04-2010, 05:07 PM
It IS an array. That's what you want. "echo" can only work with strings.
When you use "echo"+[non-string] the result will be a warning of sorts, like "array" or "resource" (for something like a mysql query).
(array(1)==array(1)) is true.
(array(1)==array(2)) is false.
There's no reason you can't match arrays.
But if you want to "echo" an array, you need to use another function. The common one is print_r($array);.
I am Abby
05-04-2010, 06:59 PM
print_r($dcount) worked fine.
So the problem seems to be on the line
if($kid->id == $dcount); when I do an echo
$kid->id; I get nothing back.
Or is the problem with the foreach line
foreach($xml as $kid){ I get no response from
echo $kid;
I am Abby
05-04-2010, 07:34 PM
The problem has to be in the if statements. I just changed it to a not equal statement and echoed "hello" which was triggered for every record in my .xml file.
To echo on an array you had to do the print_r($array)...do we also need a trick for using them in if statements?
something like
if(in_array($kid->id, $dcount))
I am Abby
05-04-2010, 07:37 PM
I love you guys. It works!
I thought that might be the problem - we added that a while back because you might have had multiple entries to delete. But then, I saw that the $dcount = array(); line was commented out, so I figured it was something else. But it's still an array because your html inputs are named "dcount[]". Duh.
I'm glad you got it figured out!
I am Abby
05-05-2010, 12:26 PM
I thought that might be the problem - we added that a while back because you might have had multiple entries to delete. But then, I saw that the $dcount = array(); line was commented out, so I figured it was something else. But it's still an array because your html inputs are named "dcount[]". Duh.
I wondered why I didn't need the
$dcount = array(); when I had to have it with the counter array. This is a good site to learn...thanks.
djr33
05-05-2010, 05:33 PM
array() is a blank array and you can use this to set the variable as an array before you do anything. But you can also just use $var[] to set the "next" (starting at 0) part of the array.
One reason for force $var=array(); at the start is that if you don't it's possible to have conflicts of variable type, like if for some reason the system assumes you're working with a string. But in general the important thing is the way in which you store data to the variable.
It's similar to:
$var = ''; //set a a blank string [establish type]
$var = 'Hello World'; //set a value to the string
Of course it's not particularly useful in that case, but that's about the same as using array(); to start an array.
In some cases, array() can be useful, such as if you might get no results but want it to still evaluate true when using is_array() or you want to use it in a foreach loop:
$var = array();
while (something) {
$var[] = something;
}
foreach($var as $v) {
echo $v;
}
array() establishes it as an array with no values-- it can act like an array in foreach. Now if you DO have data entered into it from t he while loop then it'll be like normal. But if you DON'T then it won't give you an error trying to send a non-existing array through the foreach loop. This happens a lot with databases, for example. You may get no results when you search, so first setting it as a blank array helps avoid problems.
Powered by vBulletin® Version 4.2.2 Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.