PHP HTML String into CSV - php

Going around in circles so hopefully someone can put me right.
Generating a CSV through PHP and using my data from MySQL. Data is inputted by the user via TinyMCE so has various "p" tags etc that I obviously need to strip out which I can do successfully, however the string in the csv still gets displayed in various different cells even after being stripped.
I've tried using strip_tags() and preg matching "/n" and "/r" and all sorts to remove line breaks but no luck as it still appears on new cells.
I'm using a semi colon as the seperator in the csv.
An example of a string i'm trying to strip all html from would be<p>I would like to join because it looks fun</p><p> </p><p>Help me.</p>. It only happens when their is more than one tag or something - if the string is simply one line, it works no issues.
Heres the csv code i'm using:
echo 'Username;Email;Date joined;Reason for joining'."\r\n";
foreach($users as $user) {
$csv_data .= $user->username . ';' . $user->email. ';' . date("d/m/y", $user->time_created) . ';' . $user->reason_for_joining .';'."\r\n";
}
echo $csv_data;
Where am i going wrong?
Thanks guys :)

The CSV format has more pitfalls than one might imagine (as you are experiencing). Therefore, don't reinvent the wheel and use fputcsv, which correctly escapes everything that needs escaping.
fputcsv expects to write to a file, but you can give it a fake file to write to instead, as outlined here:
$fp = fopen('php://output', 'w');
$delimiter = ';';
$headers = array('Username', 'Email', 'Date joined', 'Reason for joining');
fputcsv($fp, $headers, $delimiter);
foreach ($users as $user) {
$fields = array($user->...);
fputcsv($fp, $fields, $delimiter);
}
fclose($fp);

you forgot the "\r" for the first echo,
supposed to be:
echo 'Username;Email;Date joined;Reason for joining'."\r\n";
and better set $csv_data to blank before the 'for' loop.
and if either 'username', 'email', 'reason_for_joining' has the semicolon,
the code will generate a mal-formed csv.

Related

How to correctly use implode php

So I have this code:
$datas .= '"' . implode('", "', $body["id"].",".$body["prefecture_id"].",".$body["industry_id"].",".$body["offset"].",".$body["name"].",".$email . ",".$body["tel"].",".$body["fax"].",".$body["address"].",".$body["address_coordinate"].",".$body["url"].",".$body["image_url"].",".$body["flexible_1"].",".$body["flexible_2"].",".$body["flexible_3"].",".$body["flexible_4"].",".$body["flexible_5"].",".$body["flexible_6"].",".$body["flexible_7"].",".$body["flexible_8"].",".$body["flexible_9"].",".$body["flexible_10"].",".$body["sequence"].",".$body["del_flg"].",".$body["create_date"].",".$body["create_user"].",".$body["update_date"].",".$body["update_user"]).'"'."\r\n";
I want it to look like this:
"KN01001","01","4","500","Starbuck's","admin#starbucks.com","09-232-821","09-232-822","Upper G/F SM, Juan Luna Extension"
Problem is address has comma, so this would separate it.
I really could not construct it right. Please help
this code is from a CSV convert function. In the CSV file each column is separated by a comma.
But my problem is that I have several columns that contains also comma. I would like that those commas in the columns remain as it is.
Instead of rolling your own CSV encoding function it might be better to use the built in fputcsv().
$out = fopen("php://memory", "w");
foreach($something as $body) {
fputcsv($out, $body);
}
rewind($out);
$data = stream_get_contents($out);
You'll need to adapt the code to order the columns if you want but that's the basic method (Don't forget to close $out either).
To save holding the entire CSV in memory (if this was a file download/export mechanism) you could open php://output instead and write/flush directly to the web-server/browser.
To answer your question directly implode() takes an array as a second argument but you've given it a string so change it to this (and add all the fields):
$datas .= '"' . implode('", "', [$body["id"], $body["prefecture_id"], $body["industry_id"], $body["offset"], ...]) . "\"\r\n";
can you use fgetcsv() instead of implode? This would handle the
$fileHandle = fopen("filename.csv", "r");
while (($row = fgetcsv($fileHandle, 0, ",")) !== FALSE) {
var_dump($row);
//$row is an array of all the columns in the csv regardless of commas in the dat
}
Otherwise if you must use implode, is the data that has a comma enclosed in speech marks: "some date, with a comma". If so you could use a regex to ignore the commas within the speechmarks. I can't see your data so its hard to say.

How to format I/O data from script

I was using a script to exclude a list of words from another list of keywords. I would like to change the format of the output. (I found the script on this website and I have made some modification.)
Example:
Phrase from outcome: my word
I would like to add quotes: "my word"
I was thinking that I should put the outcome in new-file.txt and after to rewrite it, but I do not understand how to capture the result. Please, kindly give me some tips. It's my first script :)
Here is the code:
<?php
$myfile = fopen("newfile1.txt", "w") or die("Unable to open file!");
// Open a file to write the changes - test
$file = file_get_contents("test-action-write-a-doc-small.txt");
// In small.txt there are words that will be excluded from the big list
$searchstrings = file_get_contents("test-action-write-a-doc-full.txt");
// From this list the script is excluding the words that are in small.txt
$breakstrings = explode(',',$searchstrings);
foreach ($breakstrings as $values){
if(!strpos($file, $values)) {
echo $values." = Not found;\n";
}
else {
echo $values." = Found; \n";
}
}
echo "<h1>Outcome:</h1>";
foreach ($breakstrings as $values){
if(!strpos($file, $values)) {
echo $values."\n";
}
}
fwrite($myfile, $values); // write the result in newfile1.txt - test
// a loop is missing?
fclose($myfile); // close newfile1.txt - test
?>
There is also a little mistake in the script. It works fine however before entering the list of words in test-action-write-a-doc-full.txt and in test-action-write-a-doc-small.txt I have to put a break for the first line otherwise it does not find the first word.
Example:
In test-action-write-a-doc-small.txt words:
pick, lol, file, cool,
In test-action-write-a-doc-full.txt wwords:
pick, bad, computer, lol, break, file.
Outcome:
Pick = Not found -- here is the mistake.
It happens if I do not put a break for the first line in .txt
lol = Found
file = Found
Thanks in advance for any help! :)
You can collect the accepted words in an array, and then glue all those array elements into one text, which you then write to the file. Like this:
echo "<h1>Outcome:</h1>";
// Build an array with accepted words
$keepWords = array();
foreach ($breakstrings as $values){
// remove white space surrounding word
$values = trim($values);
// compare with false, and skip empty strings
if ($values !== "" and false === strpos($file, $values)) {
// Add word to end of array, you can add quotes if you want
$keepWords[] = '"' . $values . '"';
}
}
// Glue all words together with commas
$keepText = implode(",", $keepWords);
// Write that to file
fwrite($myfile, $keepText);
Note that you should not write !strpos(..) but false === strpos(..) as explained in the docs.
Note also that this method of searching in $file will maybe give unexpected results. For instance, if you have "misery" in your $file string then the word "is" (if separated by commas in the original file) will be refused, as it is found in $file. You might want to review this.
Concerning the second problem
The fact that it does not work without first adding a line-break in your file leads me to think it is related to the Byte-Order Mark (BOM) that appears in the beginning of many UTF-8 encoded files. The problem and possible solutions are discussed here and elsewhere.
If indeed it is this problem, there are two solutions I would propose:
Use your text editor to save the file as UTF-8, but without BOM. For instance, notepad++ has this possibility in the encoding menu.
Or, add this to your code:
function removeBOM($str = "") {
if (substr($str, 0,3) == pack("CCC",0xef,0xbb,0xbf)) {
$str = substr($str, 3);
}
return $str;
}
and then wrap all your file_get_contents calls with that function, like this:
$file = removeBOM(file_get_contents("test-action-write-a-doc-small.txt"));
// In small.txt there are words that will be excluded from the big list
$searchstrings = removeBOM(file_get_contents("test-action-write-a-doc-full.txt"));
// From this list the script is excluding the words that are in small.txt
This will strip these funny bytes from the start of the string taken from the file.

Proper way to use PHP fputcsv function to export CSV file

What I want to do is, to export some dataset for Excel without using extra, 3rd party, heavy libraries.
The problem is, when I export the file, first row looks well, but starting from second row, it puts all $row data into first field of current row.
So I get file with first row properly placed in right columns and starting from second row instead of columns I see whole text in first field seperated by delimiter (comma)
Here is code snippet that I use for result.
$counter=0;
$file = fopen("sample.csv", "w");
foreach ($registrants as $registrant) {
$row = [
'Fullname' => $registrant->fullname,
'Phone' => $registrant->phone,
'Email' => $registrant->email,
];
if ($counter == 0)
fputcsv($file, array_keys($row));
fputcsv($file, $row);
$counter++;
}
fclose($file);
Also tried to
fputcsv($file, array_values($row), ';', ' ');
No success. What am I doing wrong? What is proper way to see correct result on all Excel versions regardless of OS or Excel locale and etc.?

PHP to CSV line break issue

I use the following code to get data from a form and save it as csv.
$cvsData = $name . "," . $address . "\n";
$fp = fopen("file.csv", "a");
if ($fp) {
fwrite($fp, $cvsData); // Write information to the file
fclose($fp); // Close the file
}
When someone enters a comma or line break in address field it breaks the formatting. So how can i escape it so that the whole address stays in the same field ?
Put each data item inside quotation marks. A pair of quotation marks inside a quoted value signifies a single quotation mark. e.g.
"Daniel Norton","Congress Ave.
Austin (""Keeping it weird""), TX"
Referring to your example:
$data = str_replace('"','""',$data);
$address = str_replace('"','""',$address);
$cvsData = "\"$data\",\"$address\"\n";
Better still, just use the PHP function fputcsv.
fputcsv($fp,array($data,$address));
CSV is totally dependent on the software used to read it.
Have a look at http://www.csvreader.com/csv_format.php for some details on how certain programs expect CSV data.
I have created a CSV class that can handle most of these situations. You might want to have a look at it.
https://gist.github.com/1786683
And to answer your question, using that class you could
$csv = CSV::newExcel();
$cvsData = $csv->row($name, $address);
// etc...

How to concatenate two strings using fgetcsv and fputcsv?

I'm creating a script that will read a csv file and display it on a textarea using fgetcsv.
$handle = #fopen($filePath, "r");
if ($handle)
{
while (($buffer = fgetcsv($handle, 1000,",")) !== false)
{
foreach($buffer as $buff){
echo $buff."\n";
}
}
}
The format of the csv is
"line1-content1","line1-content2"
"line2-content1","line2-content2"
Using fgetcsv, the content will display inside the textarea without double-quote and comma. Can I format it so that it will also display the duoble quotes and comma?
Then upon saving it using fputcsv
$file_to_load = $_GET['filepath'];
$filePath = $dir.$file_to_load;
$trans = trim($_POST['txtarea']);
$keyarr = split("\n",$trans);
$fp = fopen($filePath, 'w');
foreach (array ($keyarr) as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
Looking on the csv file, it saved the csv but displays it like this
"line1-content1
","line1-content2
","line2-content1
","line2-content2"
It separates the "line1-content1" and "line1-content2" into two lines and put a comma after the end of every line.
Now I want to keep the formatting of #2. How will I code it?
Can you guide me into the right direction? Thanks!
Sounds like you want to display the actual raw CSV text, not the parsed data within the CSV. Instead of using fgetcsv(), just use fgets() and you'll get the text line without any parsing, preserving the quotes and commas.
As for fputcsv, it's going to write out what you pass into it, so make sure that whatever's coming back from the form is cleaned up (e.g. extra line breaks stripped out).

Categories