I am using the following code to pull a CSV file from a website that i do not have control over. and many of times i get the undefined index or headers already sent but all the data is there at the bottom. i want to write a script to open the file and remove all lines until it gets to the actual header line that should be in a csv.
the # of lines changes every time i pull it...
the current example has 49107 lines that i don't need before the part i want to parse.. This is a small part of the first 15 lines of code and about 20 lines of code before what i REALLY WANT from the file.
<pre class="cake-debug"><b>Notice</b> (8): Undefined index: name [<b>APP/controllers/loads_controller.php</b> line <b>327</b>]<div id="cakeErr1-trace" class="cake-stack-trace" style="display: none;">Code | Context<div id="cakeErr1-code" class="cake-code-dump" style="display: none;"><pre><code><span style="color: #000000"> $data[$i]['Load']['drop_date'] = date('m/d/Y' strtotime($value['Load']['drop']));</span></code>
<code><span style="color: #000000"> $data[$i]['Load']['pickup_city'] = $value['Pickup']['city'];</span></code>
"<span class=""code-highlight""><code><span style=""color: #000000""> $data[$i]['Load']['pickup_state'] = $value['Pickup']['State']['name'];</span></code></span></pre></div><pre id=""cakeErr1-context"" class=""cake-context"" style=""display: none;"">$order = ""Load.load_number ASC"""
"$fields = array("
" ""*"""
)
"$conditions = array("
" ""Load.active"" => true"
)
"$results = array("
" array("
" ""Load"" => array()"
" ""Pickup"" => array()"
" ""Destination"" => array()"
)
$result = array(
"Load" => array(
"name" => "ICE CREAM OR RELATED",
"load_number" => "8891517",
"trailer_type" => "R",
"phone_number1" => "800-555-8287",
"phone_number2" => "800-555-8287",
"pickup_date" => "03/09/2014",
"drop_date" => "03/09/2014",
"pickup_city" => "Indianapolis",
"pickup_state" => "Indiana",
"pickup_zipcode" => "46201",
"destination_city" => "London",
"destination_state" => "Kentucky",
"destination_zipcode" => "40741"
)
)
$fp=</pre><pre class="stack-trace">header - [internal], line ??
LoadsController::csv() - APP/controllers/loads_controller.php, line 360
Dispatcher::_invoke() - CORE/cake/dispatcher.php, line 204
Dispatcher::dispatch() - CORE/cake/dispatcher.php, line 170
[main] - APP/webroot/index.php, line 83</pre></div>
</pre>name,load_number,trailer_type,phone_number1,phone_number2,pickup_date,drop_date,pickup_city,pickup_state,pickup_zipcode,destination_city,destination_state,destination_zipcode
"FOOD OR KINDRED PROD",8831029,R,800-555-8287,800-555-8287,03/09/2014,03/10/2014,Aurora,Illinois,60504,"West Memphis",Arkansas,72301
"FOOD OR KINDRED PROD",8831031,R,800-555-8287,800-555-8287,03/12/2014,03/13/2014,Aurora,Illinois,60504,Ashley,Indiana,46705
This is how I would like the file to look after removing the lines that should not be there...
name,load_number,trailer_type,phone_number1,phone_number2,pickup_date,drop_date,pickup_city,pickup_state,pickup_zipcode,destination_city,destination_state,destination_zipcode
FOOD OR KINDRED PROD,8831029,R,800-555-8287,800-555-8287,3/9/2014,3/10/2014,Aurora,Illinois,60504,West Memphis,Arkansas,72301
FOOD OR KINDRED PROD,8831031,R,800-555-5555,800-555-5555,3/12/2014,3/13/2014,Aurora,Illinois,60504,Ashley,Indiana,46705
Currently i am using this code to get my CSV
set_time_limit (24 * 60 * 60);
// folder to save downloaded files to. must end with slash
$destination_folder = 'downloads/';
$url = 'http://www.somesite.com/loads/csv';
$newfname = $destination_folder . 'loads1.csv';
$file = fopen ($url, "rb");
if ($file) {
$newf = fopen ($newfname, "wb");
if ($newf)
while(!feof($file)) {
fwrite($newf, fread($file, 1024 * 8 ), 1024 * 8 );
}
}
if ($file) {
fclose($file);
}
if ($newf) {
fclose($newf);
}
and this Code to parse it
$selectfile1 = "https://www.somesite.com/downloads/loads1.csv";
// check mime type - application/octet-stream
$content = file($selectfile1);
$posted_content = array();
list($rownum, $row) = each($content);
$posted_content[0] = explode(",", $row);
array_push($posted_content[0], "ID");
$count = 0;
// iterate each row (1 post)
while (list($rownum, $row) = each($content))
{
$count++;
$cols = "ShipAfterDate, ShipBeforeDate, EquipmentID, LengthID, VendorCode, LoadCount, Rate, CargoDescription, Notes,Phone1, Phone2, PostDate,";
$vals = "";
// extract fields from row columns
$items = explode(",", $row);
list( $Description, $OrderNumber, $EquipmentCode, $Phone1, $Phone2, $ShipDate, $DeliveryDate, $OriginCity, $OriginState, $OriginZip, $DestinationCity, $DestinationState, $DestinationZip
) = $items;
array_push($posted_content, $items);
Check out 'fgetcsv' (PHP manual) which just returns false if there's a parse error or the actual CSV values if not. It might be not the fastest solution to unsuccessfully parse 50k lines, but I think it should work nevertheless
Related
I have the following PHP Code:
<?php
$file = "Links.txt";
$parts = new SplFileObject($file); // this is your array of words
foreach($parts as $word) {
$content = file_get_contents($word);
parse_str($content, $ytarr);
echo $ytarr['title'];
unset($content);
}
?>
Please note:
The Links.txt file includes multiple external URL's, on each line is only one URL. Example:
www.External-URL-number-ONE.com
www.External-URL-number-TWO.com
www.External-URL-number-THREE.com
Each of this URL have the 'title' item in the variable $content (after filling it by "file_get_contents($word);".
For troubleshooting purpose, I tested each URL by adding it in the "links.txt" single. The result was for each URL successful. The issue occours, if I add multiple URL's. In that case, the behavior is:
Error message and result:
Notice: Undefined index: title in C:\xampp\htdocs\PHPexample\index.php on line 13
Display the Title of "www.External-URL-number-THREE.com"
How can I fix this problem? It should work also with multiple lines.
Thanks in advance.
EDIT:
The content of the variable $content is:
Array (
[reason] => Invalid parameters.
[status] => fail
[errorcode] => 2
)
Array (
[ISD] => 928398
[enable] => 1
[list] => 39/9339/30
[AMP] =>
[host] =>
[title] => This_Is_the_Title_Three
[token] => 1
)
UPDATE
I have used the isset() for checking the array before access it. And only the last for each loop have an index.
Read the file and read line by line
<?PHP
$file = "Links.txt";
$handle = #fopen($file, "r");
if ($handle) {
// Read line by line
while (($word = fgets($handle)) !== false) {
$content = file_get_contents($word);
// parse_str($content, $ytarr); // parse_str don't work in this case
//echo #$ytarr['title'];
//unset($content);
echo getDataTag($content, 'title');
}
fclose($handle);
}
//This is a dirty solution
function getDataTag($str, $tag){
$str = str_replace('+',' ',$str);
$data = explode(($tag.'='),$str);
$data = explode('&',$data[1]);
return $data[0];
}
?>
I have 2 different php files that am using to fetch data from an API and one JSON file for storing the data. I want that when i run each of the PHP files on the server, my Json file would store array from both PHP files. E.g:
store.json
{
"articles": [{
"author": "Rozina Sabur",
"title": "John Cleese to return to new BBC sitcom Edith - despite saying he would never be back",
"description": "Almost 40 years on from his starring role in Fawlty Towers, John Cleese is set to return to the BBC for a new sitcom.",
"url": "http:\/\/www.telegraph.co.uk\/news\/2017\/04\/11\/john-cleese-return-new-bbc-sitcom-edith-despite-saying-would\/",
"publishedAt": "2017-04-11T22:10:11Z"
}]
"players": [
{
"name": "Marcos Alonso",
"position": "Left-Back",
"nationality": "Spain",
"contractUntil": "2021-06-30",
"marketValue": "9,000,000 €"
}]
}
first.php
$url = ('myAPI.com');
$jsondata = file_get_contents($url);
$data = json_decode($jsondata, true);
$values = array();
$resp = array();
$date = date('Y-m-d H:m:s');
//get the employee details
foreach ($data['players'] as $myp) {
$name = $myp['name'];
$posi = $myp['position'];
$nation = $myp['nationality'];
$market = $myp['marketValue'];
$values[] = array('name' => $name, 'position' => $posi, 'nationality' => $nation, 'marketValue' => $market, 'created' => $date);
}
$resp['players'] = $values; //HERE IS THE PART (PLATERS)
$fp = fopen('myJson.json', 'w');
fwrite($fp, json_encode($resp));
fclose($fp);
second.php The code is pretty much like that of first.php just API diff.
.......
........
$values[] = array('author' => $author, 'title' => $title, 'description' => $descrip, 'url' => $ur, 'publishedAt' => $publish);
}
$resp['articles'] = $values; //HERE IS THE MAIN POINT (ARTICLES)
$fp = fopen('myJson.json', 'w');
fwrite($fp, json_encode($resp));
fclose($fp);
My problem is, when I run first.php the array replaces that of second.php and vise versa. How to I fix it so that array from both PHP file store in the JSON file like in the store.php file above.
Other ideas on best practices other than 2 diff php files are welcome.
Thanks
Because both programs are opening the file as 'w'
Change it to this
$fp = fopen('myJson.json','a');
just as a note, this will not be a valid 'single json file', but a file of valid json lines.
$fp = fopen('myJson.json', 'a');
fwrite($fp, json_encode($resp));
fclose($fp);
use a flag to keep last data
Add this method to a PHP file and require this file in your two PHP files.
function storeJson($data, $type)
{
$prevData = file_get_contents('store.json');
$arrayData = json_decode($prevData, true);
if(in_array($type, array_keys($arrayData))) {
$arrayData[$type] = $data;
$fp = fopen('store.json', 'w');
fwrite($fp, json_encode($arrayData));
fclose($fp);
}
}
In first.php file at the end call the method
storeJson($resp, 'players');
In the second.php file
storeJson($resp, 'articles');
So I have a TXT file that is disjointed. How do I parse it so that it can use string matches to figure out data?
From the sample below I want:
timestamp =
src=
dst=
user=
agent=
request:
url=
The value should be NULL if it was not found on the line. I tried using preg_match() but it does not execute the entire file. No outputs.
Thank you.
Sample.txt
2016-02-24 13:54:23 Local0.Info 172.16.120.4 1 1456311263.806656820
ASD_MX600 flows src=108.177.15.189 dst=213.130.115.218 protocol=udp
sport=443 dport=61907 pattern: 1 all
2016-02-24 13:54:23 Local0.Info 172.16.120.4 1 1456311263.500015263
ASD_MX600 urls src=172.16.41.15:62490 dst=144.76.76.148:80
mac=00:1B:0D:63:84:00
user=CN=Smith\John,OU=S-HS,OU=SAcc,DC=abc,DC=org,DC=ab
agent='Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101
seb/2.0 SEBKEY' request: GET
http://something.com/theme/image.php/clean/page/1455532301/icon
2016-02-24 14:29:14 Local0.Info 172.16.120.4 1 1456313354.489880924
ASD_MX600 urls src=172.16.41.143:57256 dst=74.125.232.155:443
mac=00:1C:B0:10:A8:00 request: UNKNOWN
https://4780928.fls.doubleclick.net/...
Also, I had asked a similar question here -> Complex parsing a text file in PHP - but there was no room to ask an additional extension to the same so posting a new question. Thank you.
SK
PS: Code I have tried but does not work.
EXAMPLE 1
$myfile = fopen("C:\Documents and Settings\Administrator\Desktop\LogCatcher Script\SyslogCatchAll-2016-02-25.txt", "r") or die("Unable to open file!");
// Output one line until end-of-file
while(!feof($myfile)) {
$line = fgets($myfile) . "<br>";// you can do the explode and assignment here.
//example
$row_data = explode(" ", $line); //FIRST BLAST
$timestamp = $row_data[0] ; //Pick up the timestamp for Column 1
$timestamp;
//SECOND BLAST
$remainingData = explode(" ",$row_data[3]); //chop it off
$src = $remainingData[4];
$src = ltrim($src, "src=");
$dst= $remainingData[5];
$dst = ltrim($dst, "dst=");
$usr = $remainingData[7];
if (preg_match('/user=/',$usr))
{
$usr = ltrim($usr, "user=");
}
else {
$usr = "No User Found";
}
... This is where it starts to spasm out since not every line has"user="...
EXAMPLE 2
Another way I tried using another user's code.
<?php
$rows = explode("\n", file_get_contents('sample.txt'));
$result = array();
foreach ($rows as $row) {
if (trim($row) == "") {
continue;
}
$timeMatches = array();
$reTime = "/([0-9-]* [0-9:]*) /";
preg_match($reTime, $row, $timeMatches);
$re = "/src=(.*) dst=(.*) mac=(.*) user=(.*) agent=(.*) request: (.*) (.*)/";
$matches = array();
preg_match($re, $row, $matches);
$result[] = array('time' => $timeMatches[1], 'src' => $matches[1]
, 'dst' => $matches[2], 'mac' => $matches[3]
, 'user' => $matches[4], 'agent' => $matches[5]
, 'method' => $matches[6], 'url' => $matches[7]);
}
var_dump($result);
?>
Runs and displays nothing. Just ends.
I am very new to php. I'd really appreciate all the help here.
I am using sftp to login to a server and get a file. I am only interested in the last line in that file. The last line seperated by tabs. I would like to store the 15, 16, 19 and 20, and 21st col values to 5 different variables. The last line looks like this:
7 1 0 59422170 306669 20188 20386 0 0 39787 59981 2014 67796 48953 2 7 90 1 1.81 11.3 12:19:50
When I issue this cCurl command the get the file, how would I read the last line in this file and parse out the certain columns in the last line?
<?php
$user="user";
$pass="pass";
$c = curl_init("sftp://$user:$pass#server1/vmstat");
curl_setopt($c, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($c);
curl_close($c);
#echo $data;
?>
$data = explode("\n", $data);
$last_line = end($data);
$parts = explode("\t", $last_line);
Why use php?
With input file:
7 1 0 59422170 306669 20188 20386 0 0 39787 59981 2014 67796 48953 2 7 90 1 1.81 11.3 12:19:50
and command line:
tail -n1 myfile | sed 's/\s\s*/ /g' | cut -d' ' -f15,16,19,20,21
result is:
2 7 1.81 11.3 12:19:50
Last line
Might be overkill if the file is small, but wrote this function a while ago. Returns the last n lines of a file/stream.
function tail($file, $lines = 10, $buffer = 4096)
{
if(is_resource($file) && (get_resource_type($file) == 'file' || get_resource_type($file) == 'stream'))
$f = $file;
elseif(is_string($file))
$f = fopen($file, 'rb');
else
throw new Exception('$file must be either a resource (file or stream) or a filename.');
$output = '';
$chunk = '';
fseek($f, -1, SEEK_END);
if(fread($f, 1) != "\n")
$lines -= 1;
while(ftell($f) > 0 && $lines >= 0)
{
$seek = min(ftell($f), $buffer);
fseek($f, -$seek, SEEK_CUR);
$output = ($chunk = fread($f, $seek)).$output;
fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR);
$lines -= substr_count($chunk, "\n");
}
while($lines++ < 0)
$output = substr($output, strpos($output, "\n")+1);
fclose($f);
return $output;
}
Columns
If tab separated, simply do a split and assign what you want to variables.
$columns = explode("\t",$line);
$foo = $columns[15];
...
I am trying to pull data out of a CSV file and generate a http_build_query to submit as a http post
My data looks like this:
First,Last,Address,City,St,Zip,email,phone,dob,optindate,ipaddress,url
Abbey,Johnson,4004 S. Parker Dr. 206,Sioux Falls,SD,55106,abbey#email.com,6053451657,06/18/1924,4/19/2008 11:58:34,12.174.252.216,http://www.ecoupons.com/
My code looks like this:
<?PHP
$file_handle = fopen("test.2", "r");
while (!feof($file_handle) ) {
$line_of_text = fgetcsv($file_handle, 1024);
$data = array('firstname' => "$line_of_text[0]",
'lastname' => "$line_of_text[1]",
'address' => "$line_of_text[2]",);
echo http_build_query($data) . "\n";
}
fclose($file_handle);
?>
My result is:
firstname=Abbey&lastname=Johnson&address=4004+S.+Louise+Ave.+206
firstname=&lastname=&address=
I am not sure why the second line without the data is created and how do I keep the white spaces in the array data?
Thanks!
Your CSV does does seem to be valid or readable (can't see the new line ) so i use a simple of mine
Your address contains , which affects the way fgetcsv reads the file
Try
$fp= fopen("log.txt", "r");
while (!feof($fp) ) {
list($firstname,$lastname,$address) = fgetcsv($fp);
$data = array('firstname' => $firstname,
'lastname' => $lastname,
'address' => $address);
echo http_build_query($data) . PHP_EOL;
}
Output
firstname=Abbey&lastname=Johnso&address=4004+S.+Louise+Ave.+206