I'm making an API where the user sends an CSV to my page in binary code.
I need to read that CSV and read all rows in that CSV.
Inside that loop I'm adding each row to the DB.
I don't know how to do that.
Currently I'm using fgetcsv but that function can't be used to read binary files.
Thats only used for Posting CSV files in a POST.
I'm sending a CSV file through a HTTP request.
My result looks like this:
"person 1", "street 4", "test#gmail.com",,, "florida", "person 2", "street 5", "test2#gmail.com",,, "florida"
To iterate over each line and data in there you can use this format:
$lines = explode("\r\n", $data); // split the string by new lines
foreach($lines as $line){ // Loop over each line
$column = explode(",", $line); // split the line in 'columns'
$name = $column[0];
$street = $column[1];
}
Related
I was given a task to sort out data from a text file into JSON using PHP and object oriented principal.
The text file has information and is displayed as follows (ignore #):
#product_num:name:cost
5:tv:59.99
7:radio:10.99
I created a class and in this class I have one function that ignores any # or blank spaces from the data and puts the data in an array and json_encode it. When I echo this data it looks like this:
[{"1":"5:tv:59.99","2":"7:radio:10.99"}]
Is it possible to write other functions to separate the data further, for example so it looks more like:
[{"product_number":"5","name":"tv","cost":"59.99"},{"product_number":"7","name":"radio","cost":"10.99"}]
If so can anyone give me any pointers and tips because I have no idea where or how to begin even after numerous google searches.
There is a function inside PHP for reading value separated lines, like CSV; it's called fgetcsv which can also be used in object oriented PHP through SplFileObject::fgetcsv.
You will need to read each line, add the variable labels then append that to an array.
Depending on the size of the file you may need to optimize for memory usage as your array grows by saving as you proceed through the file.
<?php
$file = new SplFileObject('test.txt', 'r'); //Load the file
$file->current(); //Skip the first line (Side note: seek(1) did not appear to work while testing)
$result = [];
do { //While there are lines in the file
list($product_num, $name, $cost) = $file->fgetcsv(':'); //Break the line on the : delimiter into an array and populate the array into the three named values
$result[] = [ //Build the new json representation and add to result array
'product_num' => $product_num,
'name' => $name,
'cost' => $cost,
];
} while (!$file->eof());
file_put_contents('output.json', json_encode($result)); //Save the result
Your file format is basically a csv file and PHP has a CSV import function.
http://php.net/manual/en/function.fgetcsv.php
If you scroll down and check the CsvImporter example, you can copy/paste that and add a json_encode:
$importer = new CsvImporter("small.txt",true,":");
$data = $importer->get();
echo json_encode($data);
[{
"\ufeff#product_num": "5",
"name": "tv",
"cost": "59.99"
},
{
"\ufeff#product_num": "7",
"name": "radio",
"cost": "10.99"
}]
I have json file which contains multiple json objects.
Example
{"t":"abc-1","d":"2017-12-29 12:42:53"}
{"t":"abc-2","d":"2017-12-29 12:43:05"}
{"t":"abc-3","d":"2017-12-30 14:42:09"}
{"t":"code-4","d":"2017-12-30 14:42:20"}
Want to read this file and store into database, but I couldn't convert json to php array which further I can store into database.
I tried json_decode function, but its not working. I search for this but in every link its showing use json_decode. Below is my code
$filename = "folder/filename.json";
$data = file_get_contents($filename);
echo $data;
$tags = json_decode($data, true);
echo"<pre>";print_r($tags);exit;
$data is echoed but not the $tags.
Thanks in advance.
Make array of objects and use it later
$j = array_map('json_decode', file('php://stdin'));
print_r($j);
demo
If it's only four lines you can explode and json_decode each line and add it to an array.
$s = '{"t":"abc-1","d":"2017-12-29 12:42:53"}
{"t":"abc-2","d":"2017-12-29 12:43:05"}
{"t":"abc-3","d":"2017-12-30 14:42:09"}
{"t":"code-4","d":"2017-12-30 14:42:20"}';
$arr = explode(PHP_EOL, $s);
Foreach($arr as $line){
$json[] = json_decode($line,true);
}
Var_dump($json);
https://3v4l.org/97m0E
Multiple objects in a row should be enclosed in a json array and separated with comma like elements.So you need a [ ] at the start and end of the file.Also you could close the pre tag
Either you should fix the file generating that 'json' or you can use fgets to get one line at a time, and use json decode on every line
As pointed by other, JSON which you shared isn't valid. And, I think, it is stored in your file in same fashion. I would suggest to read this file line by line each line then you can decode.
$handle = fopen("folder/filename.json", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
$tags = json_decode($line, true);
echo"<pre>";print_r($tags);exit;
}
fclose($handle);
} else {
// error opening the file.
}
Assuming a file called `filename.json` contains the following lines
{"t":"abc-1","d":"2017-12-29 12:42:53"}
{"t":"abc-2","d":"2017-12-29 12:43:05"}
{"t":"abc-3","d":"2017-12-30 14:42:09"}
{"t":"code-4","d":"2017-12-30 14:42:20"}
So each one is a separate json entity
$filename = "folder/filename.json";
$lines=file( $filename );
foreach( $lines as $line ){
$obj=json_decode( $line );
$t=$obj->t;
$d=$obj->d;
/* do something with constituent pieces */
echo $d,$t,'<br />';
}
Your JSON is invalid, as it has multiple root elements
Fixing it like the following should work (note the [, ] and commas):
[
{"t":"abc-1","d":"2017-12-29 12:42:53"},
{"t":"abc-2","d":"2017-12-29 12:43:05"},
{"t":"abc-3","d":"2017-12-30 14:42:09"},
{"t":"code-4","d":"2017-12-30 14:42:20"}
]
If you cannot influence how the JSON file is created, you will need to create your own reader, as PHP is not built to support invalid formatting. You could separate the file by new lines and parse each one individually.
Is there way to append data to file on specific line or something similar like that?
I have an "handmade" array in my file, and I need to keep my beginning and end of the array.
I would like to have something like this:
$array = [
*create new line and write data here*,
*previous data*,
*previous data*,
*previous data*,
];
EDIT: I currently only know how to append data at the end of the file, and I haven't found proper solution. If I append my data with just file_put_contents();, it won't be in the array:
$array = [
*previous data*,
*previous data*,
*previous data*,
];
*create new line and write data here*,
EDIT: I got my answer. There is no efficient way to do this.
You can't add a line in a middle of a file.
You need to rewrite the file with something like this (not memory expensive) :
// Read your old file
$read = fopen('myfile', 'r');
// Create a new file
$write = fopen('myfile.tmp', 'w');
while (!feof($read)) {
$line = fgets($read);
if (stristr($line, '$arr = [')) { // For your case
$line .= "YOUR NEW LINE\n";
}
fputs($write, $line);
}
fclose($read);
fclose($write);
// Rename the new file
rename('myfile.tmp', 'myfile');
If writing to a file, there are not many (any, in my personal experience!) options for efficient prepending or mid-file inserts. Almost all of the working world relies on appending to files. You can do it, but only through basically rewriting the entire file. In essence, you have to "move all the other lines down", and that takes work.
If this is something you need done efficiently, consider a more appropriate data structure. Perhaps multiple arrays (e.g., perhaps in reverse order), multiple files, a sorting key for after load sorting, etc. But you are not likely to get around the issue of slow performance when prepending or inserting to on-disk files. (And if you do, likely involving some kernel editing, then consider making some money or helping the FOSS world out!)
If you are doing this in memory, then the data structures and access patterns are much more robust, and so you can do operations like array_unshift:
$arr = [
"line 1",
"line 2",
"line ..."
];
array_unshift($arr, "line 0");
# $arr is now: [
# "line 0",
# "line 1",
# "line 2",
# "line ..."
#];
To add elements at the beginning of an array use array_unshift:
$a=array ("content of a line", "another line");
array_unshift($a, "content to be added");
print_r($a); //print out to check
'array_push' does the same but add element(s) at the end of the array
I have a working system on which I get the data of two .csv file. And save all the data into array and then compare some of the data existing on both csv file. The system works well but later I found out that some of the rows doesn't display on the array. I think I don't use the proper code in reading a csv file. I want to edit/improve the system. This is my code on reading or getting the data from csv file.
$thedata = array();
$data = file("upload/payment.csv");
foreach ($data as $deposit){
$depositarray = explode(",", $deposit);
$depositlist = $depositarray;
$key = md5($depositlist[9] . $depositlist[10]);
$thedata[$key]['payment'] = array(
'name' => $depositlist[0],
'email' => $depositlist[1],
'modeofpayment' =>$depositlist[8],
'depositdate' => $depositlist[9],
'depositamount' => number_format($depositlist[10],2)
);
}
'<pre>',print_r($thedata),'</pre>';
//more code here for comaparing of datas...
1.) What is wrong with file("upload/payment.csv") when reading csv file?
2.) What is the best code in reading a csv file that is applicable on the
system, not changing the whole code. Should remain the foreach loop.
3.) Is fgetcsv much better for the existing code? What changes should be made?
Yes, You can use "fgetcsv" for this purpose.
The fgetcsv() function parses a line from an open file.This function returns the CSV fields in an array on success, or FALSE on failure and EOF.
check the examples given below
eg1 :
<?php
$file = fopen("contacts.csv","r");
print_r(fgetcsv($file));
fclose($file);
?>
eg 2:
<?php
$file = fopen("contacts.csv","r");
while(! feof($file))
{
print_r(fgetcsv($file));
}
fclose($file);
?>
Link : https://gist.github.com/jaywilliams/385876
I'm trying to write some php-code that takes $_GET-data as an input and saves it into a csv-file.
When running the code more than once my csv-file looks like this:
Date,Time,Temperature,"Air Humidity","Soil Humidity",Light,"Wind Direction","Wind Speed",Rain
2013-03-16,16:24:27,12,80,40,82,255,10,0
"2013-03-16,16:24:26,12,80,40,82,255,10,0
","""2013-03-16,16:24:26,12,80,40,82,255,10,0
",""",""""""2013-03-16,16:24:25,12,80,40,82,255,10,0
",""","""""",""""
",""",""""""
","""
"
As you can see, the program adds quotation marks and commas into my data that I don't want. This is apparently done by 'file("weather_data.csv")' but I don't know how to disable or work around this.
This is my code for now:
<?php
// Save received data into variables:
$temperature = $_GET["t"];
$airHumidity = $_GET["ha"];
$soilHumidity = $_GET["hs"];
$light = $_GET["l"];
$windDir = $_GET["wd"];
$windSpeed = $_GET["ws"];
$rain = $_GET["r"];
// Arrays for the column descriptor (first line in the csv-file) and the recent data:
$columnDescriptor = array("Date","Time","Temperature","Air Humidity","Soil Humidity","Light","Wind Direction","Wind Speed","Rain");
$recentData = array(date("Y-m-d"),date("H:i:s"),$temperature,$airHumidity,$soilHumidity,$light,$windDir,$windSpeed,$rain);
$fileContents = file("weather_data.csv");
array_shift($fileContents); // removes first field of $fileContents
$file = fopen("weather_data.csv","w");
fputcsv($file,$columnDescriptor);
fputcsv($file,$recentData);
fputcsv($file,$fileContents);
fclose($file);
?>
$fileContents is read as an array of strings, one entry per line of the CSV file but the actual CSV data is not parsed. The last fputcsv tries to write this data as CSV and escapes it (adding quotes and stuff). You need to add the old file contents ($fileContents) to your file with fwrite instead of fputcsv:
fwrite($file, implode("\n", $fileContents));