php://memory IO stream and fgetcsv() - php

I want to parse csv-like string so I can emulate csv and assert it into a test case.
// init CSV-like string
$str = <<<EOD
1,john\r\n
2,smith\r\n
EOD;
// Open file Handler, puts the CSV-like string, rewind the file pointer
$fp = fopen('php://memory','r+');
fputs($fp,$str);
rewind($fp);
// Parse the CSV-like string
$parsed = [];
while (($data = fgetcsv($fp, 2048)) !== FALSE) {
$parsed[] = fgetcsv($fp);
}
var_dump($parsed);
But it won't parse into arrays. This is the output:
array (size=2)
0 =>
array (size=1)
0 => null
1 => boolean false

Remove the \r\n, not needed
Your moving the pointer twice per loop, change to $parsed[] = $data

... the code is nice, however, #Verbatim has fgetcsv() twice.

Related

I don't manage to parse properly a CSV file with "|" delimeter using PHP

I'm trying to parse a CSV file.
<?php
$url = 'https://flux.netaffiliation.com/feed.php?maff=3E9867FCP3CB0566CA125F7935102835L51118FV4';
$csv = array_map('str_getcsv', file($url), ["|"]);
echo '<pre>'; echo print_r ($csv); echo '</pre>';
?>
Here is a sample of what i get :
[1] => Array
(
[0] => 5016488133494|Ary And The Secret Of Seasons PS4|100001|9.99||Jeu > PS4|https://xht.micromania.fr/?P3CB0566CA125FS1UD41282b0253295V4|https://edge.disstg.commercecloud.salesforce.com/dw/image/v2/BCRB_STG/on/demandware.static/-/Sites-masterCatalog_Micromania/default/dw65159733/images/high-res/100001.jpg?sw=1000|JUST FOR GAMES|JUST FOR GAMES|Explorez le monde merveilleux de Valdi !||new|4.99|||||||2
)
Apparently, the parser doesn't take every "|" into account.
If you inspect your output, you'll notice that the split works on your first row. This is because (oddly) PHP only uses the extra args once per iteration, so you'd need to specify them for each row:
array_map('str_getcsv', file($url), ["|", "|", "|", ...]);
... which makes not a whole lot of sense to me, as you don't know how many rows you have. I'd just call it explicitly like this instead:
$csv = array_map(fn($line) => str_getcsv($line, '|'), file($file));
Or the older style:
$csv = array_map(function($line) { return str_getcsv($line, '|'); }, file($file));
Here's a script I suggest. It assembles csvArray as result, I hope you'll handle further:
<?php
$url='https://flux.netaffiliation.com/feed.php?maff=3E9867FCP3CB0566CA125F7935102835L51118FV4';
$file_name = 'csvToParse.csv';
$arrContextOptions=array(
"ssl"=>array(
"verify_peer"=>false,
"verify_peer_name"=>false,
),
);
file_put_contents($file_name, file_get_contents($url, false,
stream_context_create($arrContextOptions)));
$fopenCSVHandle=fopen($file_name, 'r');
$csvArray=array();
if ($fopenCSVHandle !== false){
while (($data = fgetcsv($fopenCSVHandle, 1000, "|")) !== FALSE) {
//echo('<br />single row $data=<br />');
//print_r($data);
$csvArray[]=$data;
}
//echo('<br />We got this $data from CSV:<br />');
//print_r($csvArray);
}
?>

JSON append issues, want to get it inside the same square bracket [duplicate]

I have this .json file:
[
{
"id": 1,
"title": "Ben\\'s First Blog Post",
"content": "This is the content"
},
{
"id": 2,
"title": "Ben\\'s Second Blog Post",
"content": "This is the content"
}
]
This is my PHP code:
<?php
$data[] = $_POST['data'];
$fp = fopen('results.json', 'a');
fwrite($fp, json_encode($data));
fclose($fp);
The thing is, I'm not exactly sure how to achieve it. I'm going to call this code above every time a form is submitted, so I need the ID to increment and to also keep the valid JSON structure with [ and {, is this possible?
$data[] = $_POST['data'];
$inp = file_get_contents('results.json');
$tempArray = json_decode($inp);
array_push($tempArray, $data);
$jsonData = json_encode($tempArray);
file_put_contents('results.json', $jsonData);
This has taken the above c example and moved it over to php. This will jump to the end of the file and add the new data in without reading all the file into memory.
// read the file if present
$handle = #fopen($filename, 'r+');
// create the file if needed
if ($handle === null)
{
$handle = fopen($filename, 'w+');
}
if ($handle)
{
// seek to the end
fseek($handle, 0, SEEK_END);
// are we at the end of is the file empty
if (ftell($handle) > 0)
{
// move back a byte
fseek($handle, -1, SEEK_END);
// add the trailing comma
fwrite($handle, ',', 1);
// add the new json string
fwrite($handle, json_encode($event) . ']');
}
else
{
// write the first event inside an array
fwrite($handle, json_encode(array($event)));
}
// close the handle on the file
fclose($handle);
}
You're ruining your json data by blindly appending text to it. JSON is not a format that can be manipulated like this.
You'll have to load your json text, decode it, manipulate the resulting data structure, then re-encode/save it.
<?php
$json = file_get_contents('results.json');
$data = json_decode($json);
$data[] = $_POST['data'];
file_put_contents('results.json', json_encode($data));
Let's say you've got [1,2,3] stored in your file. Your code could turn that into [1,2,3]4, which is syntactically wrong.
Sample code I used to append additional JSON array to JSON file.
$additionalArray = array(
'id' => $id,
'title' => $title,
'content' => $content
);
//open or read json data
$data_results = file_get_contents('results.json');
$tempArray = json_decode($data_results);
//append additional json to json file
$tempArray[] = $additionalArray ;
$jsonData = json_encode($tempArray);
file_put_contents('results.json', $jsonData);
If you want to add another array element to a JSON file as your example shows, open the file and seek to the end. If the file already has data, seek backwards one byte to overwrite the ] following the last entry, then write , plus the new data minus the initial [ of the new data. Otherwise, it's your first array element, so just write your array normally.
Sorry I don't know enough about PHP to post actual code, but I've done this in Obj-C and it's allowed me to avoid reading the whole file in first just to add onto the end:
NSArray *array = #[myDictionary];
NSData *data = [NSJSONSerialization dataWithJSONObject:array options:0 error:nil];
FILE *fp = fopen(fname, "r+");
if (NULL == fp)
fp = fopen(fname, "w+");
if (fp) {
fseek(fp, 0L, SEEK_END);
if (ftell(fp) > 0) {
fseek(fp, -1L, SEEK_END);
fwrite(",", 1, 1, fp);
fwrite([data bytes] + 1, [data length] - 1, 1, fp);
}
else
fwrite([data bytes], [data length], 1, fp);
fclose(fp);
}
append data to .json file with PHP
also keep with valid json structure
not append array.
append json to QuesAns.json file.
overwrite data in file
$data = $_POST['data'];
//$data=
array("Q"=>"QuestThird","A"=>"AnswerThird");
$inp = file_get_contents('QuesAns.json');
//$inp='[{"Q":"QuestFurst","A":"AnswerFirst"},{"Q":"Quest second","A":"AnswerSecond"}]';
/**Convert to array because array_push working with array**/
$tempArray = json_decode($inp,true);
array_push($tempArray, $data);
print_r($tempArray);
echo'<hr>';
$jsonData = json_encode($tempArray);
file_put_contents('QuesAns.json', $jsonData);
print($jsonData);
Output:
Array ( [0] => Array ( [Q] => QuestFurst [A] => AnswerFirst ) [1] => Array ( [Q] => Quest second [A] => AnswerSecond ) [2] => Array ( [Q] => QuestThird [A] => AnswerThird ) )
[{"Q":"QuestFurst","A":"AnswerFirst"},{"Q":"Quest second","A":"AnswerSecond"},{"Q":"QuestThird","A":"AnswerThird"}]
/*
* #var temp
* Stores the value of info.json file
*/
$temp=file_get_contents('info.json');
/*
* #var temp
* Stores the decodeed value of json as an array
*/
$temp= json_decode($temp,TRUE);
//Push the information in temp array
$temp[]=$information;
// Show what new data going to be written
echo '<pre>';
print_r($temp);
//Write the content in info.json file
file_put_contents('info.json', json_encode($temp));
}
I wrote this PHP code to add json to a json file.
The code will enclose the entire file in square brackets and separate the code with commas.
<?php
//This is the data you want to add
//I am getting it from another file
$callbackResponse = file_get_contents('datasource.json');
//File to save or append the response to
$logFile = "results44.json";
//If the above file does not exist, add a '[' then
//paste the json response then close with a ']'
if (!file_exists($logFile)) {
$log = fopen($logFile, "a");
fwrite($log, '['.$callbackResponse.']');
fclose($log);
}
//If the above file exists but is empty, add a '[' then
//paste the json response then close with a ']'
else if ( filesize( $logFile) == 0 )
{
$log = fopen($logFile, "a");
fwrite($log, '['.$callbackResponse.']');
fclose($log);
}
//If the above file exists and contains some json contents, remove the last ']' and
//replace it with a ',' then paste the json response then close with a ']'
else {
$fh = fopen($logFile, 'r+') or die("can't open file");
$stat = fstat($fh);
ftruncate($fh, $stat['size']-1);
fclose($fh);
$log = fopen($logFile, "a");
fwrite($log, ','.$callbackResponse. ']');
fclose($log);
}
?>
GoodLuck

Converting comma-separated API response to CSV

I am running an API, the response of this API is returning response in comma separated values.
I am returning response in $result.
Response:
lmd_id,status,title,description,code,categories,store,url,link,start_date,expiry_date,coupon_type 106864,new,"Gift Vouchers worth ₹2000 # for just ₹999","Get it for just ₹999",,"Gift Items","ABC Company",http://example1.com,http://example2.com,"2016-04-07 00:00:00","2016-05-01 00:00:00",sale
Below are the headers in response:
lmd_id,status,title,description,code,categories,store,url,link,start_date,expiry_date,coupon_type
Code I have tried:
function str_putcsv($result) {
# Generate CSV data from array
$fh = fopen('php://temp', 'rw'); # don't create a file, attempt
# to use memory instead
# write out the headers
fputcsv($fh, array_keys(current($result)));
# write out the data
foreach ( $result as $row ) {
fputcsv($fh, $row);
}
rewind($fh);
$csv = stream_get_contents($fh);
fclose($fh);
return $csv;
}
With the code above I am not able to find where this code is generating CSV.
Another code:
$fp = fopen('data.csv', 'w');
foreach($data as $line){
$val = explode(",",$line);
fputcsv($fp, $val);
}
fclose($fp);
Above code is generating file on FTP but there is no data in it. It is generating blank CSV.
I want to convert this response into CSV file and put it on a FTP or in the same directory.
You can just put everything in an array. And use int fputcsv ( resource $handle , array $fields [, string $delimiter = "," [, string $enclosure = '"' [, string $escape_char = "\" ]]] )
Example from php.net:
$list = array (
array('aaa', 'bbb', 'ccc', 'dddd'),
array('123', '456', '789'),
array('"aaa"', '"bbb"')
);
$fp = fopen('path/to/file.csv', 'w');
foreach ($list as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
read more about fgetcsv here

Format data in csv parsed from xml using php

Following is the code, i am trying to format the data extracted from the xml file into csv.By default its inserted row wise. I am trying to make it presentable and easy to interpret.
I am not a professional coder so please excuse me if my solution is not an optimised one.
<?php
header('Content-Type: application/excel');
header('Content-Disposition: attachment; filename="DynaMedResult.csv"');
//Using esearch utility capture WebEnv variable
$url= "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&term=DynaMed&usehistory=y&retmode=xml";
$xml = file_get_contents($url, false, $context); //Reads entire file into a string
$xml = simplexml_load_string($xml);
foreach ($xml->WebEnv as $WebenvSearch){
$WebEnv=$WebenvSearch;
}
//Using efetch utility and passing WebEnv variable parse the xml
$url= "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&term=DynaMed&WebEnv=$WebEnv&query_key=1&usehistory=y&retmode=xml";
$xml = file_get_contents($url, false, $context);
$xml = simplexml_load_string($xml); //Interprets a string of XML into an object
$fp = fopen('php://output', 'w');
foreach ($xml as $pubmedst){
$article=$pubmedst->MedlineCitation->Article->ArticleTitle;
$pmid=$pubmedst->MedlineCitation->PMID;
$journal1=$pubmedst->MedlineCitation->MedlineJournalInfo->MedlineTA;
$journal2=$pubmedst->MedlineCitation->MedlineJournalInfo->NlmUniqueID;
$pubyear=$pubmedst->MedlineCitation->Article->Journal->JournalIssue->PubDate->Year;
$pubmonth=$pubmedst->MedlineCitation->Article->Journal->JournalIssue->PubDate->Month;
$pubday=$pubmedst->MedlineCitation->Article->Journal->JournalIssue->PubDate->Day;
$authorl=$pubmedst->MedlineCitation->Article->AuthorList->Author->LastName;
$authorf=$pubmedst->MedlineCitation->Article->AuthorList->Author->ForeName;
$authori=$pubmedst->MedlineCitation->Article->AuthorList->Author->Initials;
$val1 = explode("\n", $article);
fputcsv($fp, $val1); //Format line as CSV and write to file pointer
$val2 = explode("\n", $pmid); //Splits a string by string in our case a newline
fputcsv($fp, $val2);
$val3 = explode("\n", $journal1.=$journal2);
fputcsv($fp, $val3);
$val4 = explode("\n", $authorl.=$authorf);
fputcsv($fp, $val4);
$val5 = explode("\n", $pubyear.=$pubmonth);
fputcsv($fp, $val5);
}
fclose($fp);
?>
As per the fputcsv() documentation, fputcsv() expects to be given an ARRAY of data to be output as csv data. You're passing in individual strings, so each string becomes a single "field" in a 1-column CSV file.
You need to build an array of data, then output the array:
$data[0] = 'foo';
$data[1] = 'bar';
$data[2] = 'baz';
fputcsv($fp, $data);
will produce
foo,bar,baz

Append data to a .JSON file with PHP

I have this .json file:
[
{
"id": 1,
"title": "Ben\\'s First Blog Post",
"content": "This is the content"
},
{
"id": 2,
"title": "Ben\\'s Second Blog Post",
"content": "This is the content"
}
]
This is my PHP code:
<?php
$data[] = $_POST['data'];
$fp = fopen('results.json', 'a');
fwrite($fp, json_encode($data));
fclose($fp);
The thing is, I'm not exactly sure how to achieve it. I'm going to call this code above every time a form is submitted, so I need the ID to increment and to also keep the valid JSON structure with [ and {, is this possible?
$data[] = $_POST['data'];
$inp = file_get_contents('results.json');
$tempArray = json_decode($inp);
array_push($tempArray, $data);
$jsonData = json_encode($tempArray);
file_put_contents('results.json', $jsonData);
This has taken the above c example and moved it over to php. This will jump to the end of the file and add the new data in without reading all the file into memory.
// read the file if present
$handle = #fopen($filename, 'r+');
// create the file if needed
if ($handle === null)
{
$handle = fopen($filename, 'w+');
}
if ($handle)
{
// seek to the end
fseek($handle, 0, SEEK_END);
// are we at the end of is the file empty
if (ftell($handle) > 0)
{
// move back a byte
fseek($handle, -1, SEEK_END);
// add the trailing comma
fwrite($handle, ',', 1);
// add the new json string
fwrite($handle, json_encode($event) . ']');
}
else
{
// write the first event inside an array
fwrite($handle, json_encode(array($event)));
}
// close the handle on the file
fclose($handle);
}
You're ruining your json data by blindly appending text to it. JSON is not a format that can be manipulated like this.
You'll have to load your json text, decode it, manipulate the resulting data structure, then re-encode/save it.
<?php
$json = file_get_contents('results.json');
$data = json_decode($json);
$data[] = $_POST['data'];
file_put_contents('results.json', json_encode($data));
Let's say you've got [1,2,3] stored in your file. Your code could turn that into [1,2,3]4, which is syntactically wrong.
Sample code I used to append additional JSON array to JSON file.
$additionalArray = array(
'id' => $id,
'title' => $title,
'content' => $content
);
//open or read json data
$data_results = file_get_contents('results.json');
$tempArray = json_decode($data_results);
//append additional json to json file
$tempArray[] = $additionalArray ;
$jsonData = json_encode($tempArray);
file_put_contents('results.json', $jsonData);
If you want to add another array element to a JSON file as your example shows, open the file and seek to the end. If the file already has data, seek backwards one byte to overwrite the ] following the last entry, then write , plus the new data minus the initial [ of the new data. Otherwise, it's your first array element, so just write your array normally.
Sorry I don't know enough about PHP to post actual code, but I've done this in Obj-C and it's allowed me to avoid reading the whole file in first just to add onto the end:
NSArray *array = #[myDictionary];
NSData *data = [NSJSONSerialization dataWithJSONObject:array options:0 error:nil];
FILE *fp = fopen(fname, "r+");
if (NULL == fp)
fp = fopen(fname, "w+");
if (fp) {
fseek(fp, 0L, SEEK_END);
if (ftell(fp) > 0) {
fseek(fp, -1L, SEEK_END);
fwrite(",", 1, 1, fp);
fwrite([data bytes] + 1, [data length] - 1, 1, fp);
}
else
fwrite([data bytes], [data length], 1, fp);
fclose(fp);
}
append data to .json file with PHP
also keep with valid json structure
not append array.
append json to QuesAns.json file.
overwrite data in file
$data = $_POST['data'];
//$data=
array("Q"=>"QuestThird","A"=>"AnswerThird");
$inp = file_get_contents('QuesAns.json');
//$inp='[{"Q":"QuestFurst","A":"AnswerFirst"},{"Q":"Quest second","A":"AnswerSecond"}]';
/**Convert to array because array_push working with array**/
$tempArray = json_decode($inp,true);
array_push($tempArray, $data);
print_r($tempArray);
echo'<hr>';
$jsonData = json_encode($tempArray);
file_put_contents('QuesAns.json', $jsonData);
print($jsonData);
Output:
Array ( [0] => Array ( [Q] => QuestFurst [A] => AnswerFirst ) [1] => Array ( [Q] => Quest second [A] => AnswerSecond ) [2] => Array ( [Q] => QuestThird [A] => AnswerThird ) )
[{"Q":"QuestFurst","A":"AnswerFirst"},{"Q":"Quest second","A":"AnswerSecond"},{"Q":"QuestThird","A":"AnswerThird"}]
/*
* #var temp
* Stores the value of info.json file
*/
$temp=file_get_contents('info.json');
/*
* #var temp
* Stores the decodeed value of json as an array
*/
$temp= json_decode($temp,TRUE);
//Push the information in temp array
$temp[]=$information;
// Show what new data going to be written
echo '<pre>';
print_r($temp);
//Write the content in info.json file
file_put_contents('info.json', json_encode($temp));
}
I wrote this PHP code to add json to a json file.
The code will enclose the entire file in square brackets and separate the code with commas.
<?php
//This is the data you want to add
//I am getting it from another file
$callbackResponse = file_get_contents('datasource.json');
//File to save or append the response to
$logFile = "results44.json";
//If the above file does not exist, add a '[' then
//paste the json response then close with a ']'
if (!file_exists($logFile)) {
$log = fopen($logFile, "a");
fwrite($log, '['.$callbackResponse.']');
fclose($log);
}
//If the above file exists but is empty, add a '[' then
//paste the json response then close with a ']'
else if ( filesize( $logFile) == 0 )
{
$log = fopen($logFile, "a");
fwrite($log, '['.$callbackResponse.']');
fclose($log);
}
//If the above file exists and contains some json contents, remove the last ']' and
//replace it with a ',' then paste the json response then close with a ']'
else {
$fh = fopen($logFile, 'r+') or die("can't open file");
$stat = fstat($fh);
ftruncate($fh, $stat['size']-1);
fclose($fh);
$log = fopen($logFile, "a");
fwrite($log, ','.$callbackResponse. ']');
fclose($log);
}
?>
GoodLuck

Categories