something happening in my script and i cant figure out whats going on, basically i have a array of products, and with this array im populating the items in the foreach loop to a xml file, the problema is that in the first nodes appears empty data, and im sure that i dont have emmpty data in the array, i already tried just printing the data in plaintext and works fine, only when im looping and creating the xml file.
My script:
$xml = new SimpleXMLElement('<products/>');
for ($i = 0; $i <= sizeof($catalog); ++$i) {
$track = $xml->addChild('product');
$track->addChild('name', $i . $catalog[$i]["name"]);
$track->addChild('brand', $catalog[$i]["brand"]);
}
Header('Content-type: text/xml');
print($xml->asXML());
Related
Currently have a file that is set to read a CSV file. The CSV file contains 1600 api queries. Then each api query then returns more queries that need to be run. I am using Xampp v3.2.2 on windows 10 and running php v5.6.15. When running the file through my browser it ran fine for the first 800+ records in the CSV before timing out. When I rerun the file now I get an error "Site can't be reach ERR_CONNECTION_RESET". Not sure what could be causing this. abbreviated version of the code is included below
<?php
error_reporting(E_ERROR | E_PARSE);
set_time_limit (28800);
$csv = array_map('str_getcsv', file('file.csv'));
for($i = 0; $i < count($csv); $i++){
if($csv[$i][2] == 1){ //this item in csv is flag to check if this item has been run yet
if($csv[$i][3] != 'NULL' && trim($csv[$i][3]) != ''){ // check to make sure there is a URL
$return = file_get_contents(trim($csv[$i][3])); //Get the contents that links to new api calls
if($return){
$isCall = array(); // array to store all new calls
$data = array(); // array to store all data to put in csv
$doc = new DOMDocument('1.0'); // create new DOM object
$doc->loadHTML($return); // load page string into DOM object
$links = $doc->getElementsByTagName('a'); // get all <a> tags on the page
if($links->length > 0){ // if there is at least one <a> tag on page
for($j = 0; $j < $links->length; $j++){ // loop through <a> tags
$isCall[]= $links->item($j)->getAttribute('href'); // get href attribute from <a> tag and push into array
}
for($x = 0; $x < count($isCall); $x++){ // loop through all the calls and search for data
$string = file_get_contents($isCall[$x]);
if($string) {
$thispage = new DOMDocument('1.0');
$thispage->loadHTML($string);
$pagedata = $thispage->getElementsByTagName('div');
if ($pagedata->length > 0) {
for($j = 0; $j < $pagedata->length; $j++) {
$data[] = $pagedata->item($j)->C14N();
}
}
}
if(count($data) >= 5) break; // limiting to 5 data points to be added to csv
}
}
if(!empty($data)) $csv[$i] = array_merge($csv[$i], $data); // if we have data points lets add them to the row in the csv
}
}
$csv[$i][2] = 2; // set the flag to 2
$fp = fopen('file.csv', 'w'); // write the contents to the csv each time through loops so if it fails we start at last completed record
foreach ($csv as $f) {
fputcsv($fp, $f);
}
fclose($fp);
}
}
?>
Usually ERR_CONNECTION_RESET is an error that occurs when the site you are trying to connect to is unable to establish that connection. This usually happens due to reasons like firewall blocking on issues with ISP cache etc.
However in your case, I feel that the site you are connecting to is voluntarily closing connection attempts because what you are trying to do is loop over and hit that API site 1600 times continuously.
The API site is allowing the first 800-odd attempts but after that it gets worried that you are perhaps a malicious script trying to harm it. Like a classical example of DOS (Denial Of Service) attempt.
You should check if there is any restriction to the number of attempts a client can make to the API site with a fixed time (like say 500 hits every 24 hours) or you should try to sleep N seconds after each hit to the site or after each X number of hits to the site.
still struggling with PHP and CSV file manipulation. I will try to ask this properly so I can get some help.
I have a CSV file with about 4000 lines/rows, and I wrote this code to create an array of the entire CSV, and pull the the LAST line of the CSV file out to use in my script. The code works to to all this wit success.
// CREATE ASSOCIATIVE ARRAY FROM LAST ROW OF CSV FILE
$csv = array();
if (FALSE !== $handle = fopen("Alabama-TEST.csv", "r"))
{
while (FALSE !== $row = fgetcsv($handle))
{
$csv[] = $row;
}
}
$new_csv = array();
foreach ($csv as $row)
{
$new_row = array();
for ($i = 0, $n = count($csv[0]); $i < $n; ++$i)
{
$new_row[$csv[0][$i]] = $row[$i];
}
$new_csv[] = $new_row;
}
The variable $new_row is the last row in the CSV and I am able to use the data fine. But when the script is finished running I want to delete this last row called $new_row.
Here is an example of my CSV file at the top view;
CITY ADDRESS STATE NAME
Birmingham 123 Park St. Alabama Franky
So I just want to remove the last row and keep the header at the top, for the next time the script runs. I've been trying for 3 days solid trying to figure this out, so I'm hoping some kind person who KNOWS WHAT THEY ARE DOING can help.
Here is the code I have tried to remove the last row;
$inp = file('Alabama-TEST.csv');
$out = fopen('Alabama-TEST.csv','w');
or ($i=0;$i<count($inp)-1;$i++)
fwrite($out,$inp[$i]);
fclose($out);
Since I'm using a large file at around 4000 rows, is there a way to do this without using too much memory?
You need to use array_pop on your array ($new_csv) and fputcsv to save the file:
array_pop($new_csv); // Removes the last element in the array
$out = fopen('Alabama-TEST-new.csv','w');
foreach ($new_csv as $row) { // sorry for writing it badly, try now
fputcsv($out, $row);
}
fclose($out);
I don't have an environment to test this, sorry.
So I have a problem with a script I'm working on. I have a folder full of JSON files called roster0.json, roster1, etc. etc.
$dir = "responses/";
$files = glob($dir . "roster*");
$failed = array();
$failcnt = 0;
if (isset($files)) {
$data = null;
for ($i = 0; $i < count($files); $i++) {
$data = json_decode(utf8_decode(file_get_contents($files[$i])));
if(isset($data)){
// Process stuff
When I var_dump($files) I get an array with over 100 paths "responses/roster0.json".
When I test $data I get a proper array of data.
However, once the loop goes to the next file, it never loads it, and never processes it.
Here's the crazy part. If I change the start of the for loop, e.g. $i = 20. It will load the 21st file in the directory and parse it and insert it into the db properly!
Ignoring the failcnt stuff at the bottom, here's the current version of the script in it's entirety. http://pastebin.com/yqyKi5Ag
PS - I have full WARNING/ERROR reporting on in PHP and not getting any error messages...HELP! Thanks!
When I was writing the insert string the ID was being duplicated and thus was invalid. Switched to auto-inc and tada. It works. Thanks for the assistance. –
I just can remove an item from a simpleXML element with:
unset($this->simpleXML->channel->item[0]);
but I can't with the a for:
$items = $this->simpleXML->xpath('/rss/channel/item');
for($i = count($items); $i > $itemsNumber; $i--) {
unset($items[$i - 1]);
}
some items are removed from $items (Netbeans Debug can confirm that) but when I get the path again (/rss/channel/item) nothing was deleted.
What's wrong?
SimpleXML does not handle node deletion, you need to use DOMNode for this.
Happily, when you import your nodes into DOMNode, the instances point to the same tree.
So, you can do that :
<?php
$items = $this->simpleXML->xpath('/rss/channel/item');
foreach ($items as $item) {
$node = dom_import_simplexml($item);
$node->parentNode->removeChild($node);
}
You're currently only, as you know, unsetting the item from the array.
To get the magical unsetting to work on the SimpleXMLElement, you have to either do as Xavier Barbosa suggested or give PHP a little nudge into firing off the correct unsetting behaviour.
The only change in the code snippet below is the additions of [0]. Heavy emphasis on the word magical.
$items = $this->simpleXML->xpath('/rss/channel/item');
for($i = count($items); $i > $itemsNumber; $i--) {
unset($items[$i - 1][0]);
}
With that said, I would recommend (as Xavier and Josh have) moving into DOM-land for manipulating the document.
Well I was racking my brain trying to figure out how to delete the last child from an xml document. Then I insert a new element at the top. This way there is always a set amount of items in my rss feed. I could not get the xpath stuff to work. That could be because of the free server I am using but anyways. This is what I did. My xml document is an rss feed so I have 6 elements before the items start. ie. title,description under the channel.
$file = 'newrss.xml';//get file
$fp = fopen($file, "rb") or die("cannot open file");//open the file
$str = fread($fp, filesize($file));//read the file
$xml = new DOMDocument();//new xml DOMDocument
$xml->formatOutput = true;
$xml->preserveWhiteSpace = false;
$xml->loadXML($str) or die("Error");//Load Document
// get document element
$root = $xml->documentElement;
$fnode = $root->firstChild;
$ori = $fnode->childNodes->item(6);//The 6th item starts the item nodes
//Get the number of items in my xml.
$nodeLength = $fnode->getElementsByTagName('item')->length;//count nodes
$itemNum=$nodeLength+5;//I added 5 so it starts from the first item
$lNode = $fnode->childNodes->item($itemNum);//Get the last child node
$fnode->removeChild($lNode);//finally remove that node.
I know this is not pretty but it works good. It took me forever to figure this out so I hope it will help someone else since I see this question a lot. If you are not interested in adding your new item to the top of the rss list then you could skip the $ori variable. Furthermore if you do leave out the $ori variable you will have to adjust the $itemNum so you remove the correct item.
I'm trying to edit some xml data. After this I want to save the data to file.
The problem is that the edited data isn't saved by simplexml but the node has changed.
$spieler = $xml->xpath("/planer/spieltag[#datum='" .$_GET['date']. "']/spielerliste/spieler");
for ( $i = 1; $i < 13; $i++ ){
if (!empty($_POST['spieler' .$i ])){
$spieler[$i-1] = $_POST['spieler' .$i];
}
}
var_dump($spieler);
$xml->asXML("data.xml");
var_dump() shows the new data, but asXML() doesn't.
Make sure your script has write permission to data.xml
The XPath result array elements aren't PHP ($ref = &$var) references to the actual tree nodes, so this line
$spieler[$i-1] = $_POST['spieler' .$i];
isn't modifying anything in the tree, you're simply overwriting an entry in a completely independent array.