tab-delimited string to XML with PHP - php

I'm trying to write the tab-delimited content of a variable to XML like this:
$tsvData = str_getcsv($input, "\t");
foreach($tsvData as $line => $row) {
if($line > 0) {
$xmlWriter->writeElement('NAME', $row[0]);
$xmlWriter->writeElement('CAKE', $row[1]);
$xmlWriter->writeElement('BODYPART', $row[2]);
}
}
But it's only writing one character per XML tag instead of everything between each tab. When I use SplFileObject, geting the same tsv data but from a file, it works. What am I doing wrong with the str_getcsv function?
Thanks

The str_getcsv() function returns a 1-dimensional array, but you're treating it like it's returning a 2-dimensional array.
Edit:
To clarify, str_getcsv() has no concept of "lines". Instead of doing this:
$tsvData = str_getcsv($input, "\t");
Thinking that you'll get an array of lines, each one containing an array of columns, you have to do something like this:
$lines = explode("\n", $input);
$tsvData = array();
foreach ($lines as $line) {
$tsvData[] = str_getcsv($line, "\t");
}
// now $tsvData is a 2-dimensional array of lines/columns like you were wanting

Related

PHP Building an array with variables

I want to build an array to create a CSV file using variables. The $arraybuild variable will gather lines from a search so will never be the same amount of rows.
$arraybuild = "'aaa,bbb,ccc,dddd',";
$arraybuild .= "'123,456,789',";
$arraybuild .= "'\"aaa\",\"bbb\"'";
$list = array
(
$arraybuild
)
;
$file = fopen("contacts.csv","w");
foreach ($list as $line)
{
fputcsv($file,explode(',',$line));
}
fclose($file);
The problem is the result does not separate the lines, it places them all in the same line.
I want to get
aaa,bbb,ccc,dddd
123,456,789
"aaa","bbb"
What I am getting is
aaa bbb ccc dddd 123 456 789 "aaa" "bbb"
All in separate columns
Can someone please assist?
Push each rows to an array instead of concatenating to a string, then loop and add to csv
$arraybuild[] = "'aaa,bbb,ccc,dddd',";
$arraybuild[] = "'123,456,789',";
$arraybuild[] = "'\"aaa\",\"bbb\"'";
$file = fopen("contacts.csv","w");
foreach ($arraybuild as $line) {
fputcsv($file, explode(',', $line));
}
fclose($file);
In your code, you are concatenating all values to one string, separated by ,. After that, you are creating one array with one element in it (that long string).
So, it's not a surprise, that you are getting all of them on the same line.
To separate lines, you should create separate arrays inside the $list array. Each included array will be on the new line.
Try this:
<?php
$arraybuild1 = "'aaa,bbb,ccc,dddd',";
$arraybuild2 = "'123,456,789',";
$arraybuild3 = "'\"aaa\",\"bbb\"'";
$list = array
(
explode(',', $arraybuild1),
explode(',', $arraybuild2),
explode(',', $arraybuild3)
);
$file = fopen("contacts.csv", "w");
foreach ($list as $fields) {
fputcsv($file, $fields);
}
fclose($file);

How to trim the whitespace from an array in PHP

I'm trying to parse a CSV file and as part of it I would like to remove leading/trailing whitespace from all of my cells. Since it's a CSV file it's formatted like a 2D array. Initially I tried:
foreach($csv as $row){
foreach($row as $cell){
$cell = trim($cell);
}
}
However the result was untrimmed.
Next I tried using array_map as suggested here.
$csv = array_map('trim', $csv);
This gave me back an array of empty rows. So I also tried
foreach($csv as $row){
$row = array_map('trim', $row);
}
Which like my first attempt didn't change anything.
Here's the CSV data I'm using as my input:
First Name,Last Name,Contact Method,Phone, Email
John,Doe,Email,1-XXX-XXX-XXXX, john#example.com
Jane,Doe,Phone Call,1-XXX-XXX-XXXX,jane#example.com
In particular I was trying to get my script to trim the leading space in the last cell of the first row (" Email" => "Email").
You are not modifying the original array when you do the trim. You should get the values by reference in the foreach loop.
foreach($csv as &$row){
foreach($row as &$cell){
$cell = trim($cell);
}
}
From the documentation:
In order to be able to directly modify array elements within the loop
precede $value with &. In that case the value will be assigned by
reference.
You need to reference $row in order to make changes to the array (note the &):
foreach($csv as &$row){
$row = array_map('trim', $row);
}
If you are seeing it like you put here,
" Email" => "Email"
you'll have to trim it from the key, can you show how you are assigning the named headers. Because I would trim it there, but using array_map('trim', $data) will remove the whitespace, I do that all day long.
Well to just clean the keys you can do,
$keys = array_map( 'trim', array_keys($data) );
$data = array_combine( $keys, $data );
$input = [
'parent' => [
'child' => ' element to be trimmed '
]
];
array_walk_recursive($input, function (&$item) {
if (!is_array($item)) {
$item = trim($item);
}
});

Call a single cell from a .CSV using PHP

I've a problem to import a single cell in csv,
i have a csv file that contain 7 column and ~1420 row,
i need to read only the 4 column number in 1420's row, how can i do it?
<?php
$url = "wp-admin/ftp/test.csv";
$csvData = file_get_contents($url);
$lines = explode("\n", $csvData);
$array = array();
foreach ($lines as $line) {
$array[] = str_getcsv($line);
}
echo $array[1];
?>
with this i have an array to output with all cell in one row,
but i need to take the third number in that row, and not all of it.
I believe $array is multidimensional the following should print what you want:
echo $array[1419][3];
Otherwise you can print it to check how it is structured:
print_r($array);
UPDATE: unidimensional
foreach ($lines as $line) {
$array[] = str_getcsv($line)[3];//PHP 5.4
}
echo $array[1419];

multi-dimensional array possibly

I have two files that I need opened, I'm using php file to read them
$lines = file('/home/program/prog_conf.txt');
foreach ($lines as $line) {
$rows = preg_split('/\s+/', $line);
Followed by:
$lines = file('/home/domain/public_html/base/file2.cfg');
foreach ($lines as $line) {
$rows = preg_split('/=/', $line);
As I work with these two files, I need to pull info from the second one, which I seperated by =, however, I'm not sure this is the best thing to do. I wanted to add data checking from the database. The db details are in the second file like so:
dbname = databasename
dbuser = databaseuser
dbpass = databasepassword
If I echo the $rows[2], I get everything all the information I need on a single line, not on seperate lines. Meaning:
databasename databaseuser databasepassword
How do I split the information up so I can use the entries one by one?
How about:
$lines = file('/home/domain/public_html/base/file2.cfg');
$all_parts = array()
foreach ($lines as $line) {
//explode pulls apart a string based on the first value, so you could change that
//to a '=' if need be
array_merge($all_parts,explode(' ', $line));
}
This would get you all the parts of the file, one at a time, into an array. Which is what I think you wanted.
If not, just explode as needed
Maybe this aproach helps:
First as i see your second file has multiple lines, so what would do is something like this:
Assumin that every key as "db" in common we can do something like this.
$file = fopen("/home/domain/public_html/base/file2.cfg", "rb");
$contents = stream_get_contents($handle); // This function return better performance if the file isn't too large.
fclose($file);
// Assuming this is your return from the file
$contents = 'dbname = databasename dbuser = databaseuser dbpass = databasepassword';
$rows = preg_split('/db+/', $contents); // Splinting keys "db"
$result = array();
foreach($rows as $row){
$temp = preg_replace("/\s+/", '', $row); // Removing extract white spaces
$temp = preg_split("/=/", $temp); // Splinting by "="
$result[] = $temp[1]; // Getting the value only
}
var_dump ($result);
I hope this help you can try this code maybe with little modifications but works.

csv file into array , translation system for a site

I need help to solve this problem:
I have a csv file like this
hello,ciao
goodbye,arrivederci
as you can see I try to create a translation system for a site
now I want this csv file into an array, the resultant array must be the same of $langArray
<?php $langArray = array([it]=>array([hello]=>ciao,[goodbye]=>arrivederci)); ?>
I already have a solution using a Json file to have an array like this, and is most usefull that a csv file and I can use translation system also with javascript. but I want to know the way to do that with a csv file thank you
For reading a CSV file you should use fopen and fgetcsv, or for the short version str_getcsv (needs current PHP or compat library):
$csv = array_map("str_getcsv", file("it.csv"));
Then building the associative map requires a manual loop:
foreach ($csv as $line)
$translate["it"][ $line[0] ] = $line[1];
You could use explode to split your data once for the new line, then once for the comma, and fill an array with it.
<?php
$translations = array();
$data = 'hello,ciao
goodbye,arrivederci';
$words = explode("\n", $data);
foreach($words as $w) {
$parts = explode(',', $w);
$translations[$parts[0]] = $parts[1];
}
print_r($translations);
?>
http://codepad.viper-7.com/gCKoI9
<?php
$languageArray = ARRAY();
$my_csv_it = 'hello,ciao goodbye,arrivederci';
$tmp_array_it = explode(' ', $my_csv_it);
foreach ($tmp_array_it AS $text) {
$pairs = explode(',',$text);
$languageArray['it'][$pairs[0]] = $pairs[1];
}
print_r ($languageArray);
?>

Categories