PHP parse CSV by columns - php

I would like to ask for help with this task: I have CSV for example like this:
column1$column2$column3
123$xyz$321
456$zyx$654
And I would like to parse it by PHP to Arrays by columns / headers -> for example
$column1 = {123,456}
$column2 = {xyz,zyx}
$column3 = {321,654}
Thanks everyone.

Consider the following code and explanations:
$file = file("example.csv"); // read the file to an array
$cols = array();
for ($i=1;$i<count($file);$i++) { // loop over $file,
// starting in the second line
$row = explode('$', $file[$i]); // make an array with explode
for ($j=0;$j<count($row);$j++) // loop over the $row array
array_push($cols["column".$j], $row[$j]);
// push it to the cols array
}
print_r($cols);
What are your curly brackets supposed to do? In PHP an array is formed with [].
Rather than reading the whole file to an array you could as well read each line and push it to the cols array.

Related

Foreach returns only first record, stops

This should be very simple, but I'm getting odd behavior I've never seen before. Here is the code:
<?php
$csv = array_map('str_getcsv',file('dummy.csv'));
$n=1;
foreach($csv as $key=>$val) {
$sql = "UPDATE table set field = '$val[$key]' WHERE id = $n";
echo $sql."\n";
$n++;
}
?>
The .csv file is 260 simple text phrases that show up properly with print_r($csv);. The above code gives proper output but stops after the first record. Why?
str_getcsv returns an array.
array_map also returns an array.
So, your $csv is an array with an array within it.
After your line $csv = array_map('str_getcsv',file('dummy.csv'));, add the line $csv = $csv[0]; This pulls out the inner array. Then you should get the expected results without changing the remainder of your code.

Return row from an array if contains a value from another array with a different value format

I need to compare 2 different format arrays. The goal is to print from file1 only that rows which contain value from file2.
I suppose that I have to load both files into 2 arrays and compare it. I tried array_intersect(), in_array() and array_key_exists(), nothing works for me.
Here is the example of data files:
File 1:
2.26.81.0,4,10146128,10165054
82.132.227.75,7,10146130,10166530,10166093
91.206.0.35,10,10150898,10165809
88.145.18.102,3,10169097,10141126,21729395
File 2:
10146128
10146130
Result should looks like this:
2.26.81.0,4,10146128,10165054
82.132.227.75,7,10146130,10166530,10166093
I have loaded both files in 2 arrays and I need to compare them now
$bought = fopen('f_data.csv', 'r');
$visited = fopen('l_data.csv', 'r');
$line = fgets($bought);
while(! feof($bought)) {
$line = fgets($bought);
$bought_f[] = $line;
}
$line2 = fgets($visited);
while(! feof($visited)) {
$line2 = fgets($visited);
$visited_f[] = $line2;
}
The functions you used didn't work because you converted the first file in an array putting each line into an array element, but since each line not a value but a list of values you should create a two-dimensional array (an array of arrays), so each array element contains just a value. For example you can do that using file() and explode():
// getting an array with an element for each line
$file1=file("file1.csv");
$length=count($file1);
// converting each line in an array of the comma-separated values
for ($i=0;$i<$length;$i++) {
$file1[$i]=explode(",",$file1[$i]);
}
//for file2 using file() is enough as each line only contains one value
$file2=file("file2.csv");
In this way $file1[0][0] is2.26.81.0, $file1[0][1] is 4, $file1[0][2] is 10146128 and so on. Then, you have several options, the most basic one is using a double loop:
foreach ($file1 as $line) {
foreach ($file2 as $value) {
// code for checking if $value is contained in $line and store/print the result
}
}
Depending of what you need using in_array() for comparison and implode() for converting the line back to a comma-separated string would do the job.
Also note that if the first file can contain several values of the second file in the same line you can get duplicate results, in that case the solution would be stop checking the values of the second array as soon as you get a match.

Text file data to an associative array in PHP and search data

I'm a beginner in PHP. I have a text file like this:
Name-Id-Number
Abid-01-80
Sakib-02-76
I can take the data as an array but unable to take it as an associative array. I want to do the following things:
Take the data as an associative array in PHP.
Search Number using ID.
Find out the total of Numbers
I believe I understand what you want, and it's fairly simple. First you need to read the file into a php array. That can be done with something like this:
$filedata = file($filename, FILE_IGNORE_NEW_LINES);
Now build your desired array using a foreach() loop, explode and standard array assignment. Your search requirement is unclear, but in this example, I make the associated array element into an array that is also an associative array with keys for 'id' and 'num'.
As you create the new array, you can compute your sum, as demonstrated.
<?php
$filedata = array('Abid-01-80', 'Sakib-02-76');
$lineArray = array();
$numTotal = 0;
foreach ($filedata as $line) {
$values = explode('-', $line);
$numTotal += $values[2];
$lineArray[$values[0]] = array('id' => $values[1], 'num' => $values[2]);
}
echo "Total: $numTotal\n\n";
var_dump($lineArray);
You can see this code demonstrated here
Updated response:
Keep in mind that notices are not errors. They are notifiying you that your code could be cleaner, but are typically suppressed in production.
The undefined variable notices are coming because you are using:
$var += $var without having initialized $var previously. Note that you were inconsistent in this practice. For example you initialized $numTotal, so you didn't get a notice when you used the same approach to increment it.
Simply add just below $numTotal = 0:
$count = 0;
$countEighty = 0;
Your other notices are occurring most likely due to a blank line or string in your input that does not follow the pattern expected. When explode is executed it is not returning an array with 3 elements, so when you try and reference $values = explode('-', $line); you need to make sure that $line is not an empty string before you process it. You could also add a sanity check like:
enter code hereif (count($values) === 3) { // It's ok to process

Access php array index issue

After use fgetcsv() function I get an array, then I use a foreach() and I get a "simple" associative array like:
Array
(
[ix,radical,variant,simplified,pinyin,english,strokes] => 1,一,,,yi1,one,1
)
Then I try to access any element and I fail:
echo $record['ix'];
Notice: Undefined index: ix
echo next($record); // return nothing!
Maybe is offtopic (not centred in php language) but I'm using some lib (not necessary of course from PHP commenter in http://php.net/manual/es/function.fgetcsv.php)
<?php
require "..\CsvImporter.lib.php";
$importer = new CsvImporter('my_route\\my.csv',true);
while($records = $importer->get())
{
// debug
print_r($records[0]);
exit;
foreach ($records as $record)
{
\\ ..
}
}
And my screen output is
Array ( [ix,radical,variant,simplified,pinyin,english,strokes] => 1,一,,,yi1,one,1 )
My data:
ix,radical,variant,simplified,pinyin,english,strokes
1,一,,,yi1,one,1
2,丨,,,gun3,line,1
3,丶,,,zhu3,dot,1
So how is possible I'm unable to access any key ?
As you posted your data above. Your csv importer giving you each row with comma. So you need to explode it then use however you want to use
Example code \
$i=0;
while($records = $importer->get())
{
if($i>0) //skip first row it is heading
{
$data = explode(',',$records);
print_r($data);
// now `$data[0]` contains `ix` value for your first csv row and so on
}
$i++;
}
I used some lib and the default delimiter was "\t" so something like 'ix,radical,variant,simplified,pinyin,english,strokes' was THE key and '一,,,yi1,one,1' the only value
Now, I see the problem I can do it easy:
$f = 'file.csv';
$separator = ',';
$file = file_get_contents($f);
// bi-dimensional array
$regs = array_map(function($reg){return (explode($separator,$reg));},explode("\n",$file));
Thanks all!

Storing array within an array using PHP

foreach ($topicarray as $key=>$value){
$files = mysql_query("mysqlquery");
while($file = mysql_fetch_array($files)){ extract($file);
$topicarray[$value] = array( array($id=>$title)
);
}
}
The first foreach loop is providing me with an array of unique values which forms a 1-dimensional array.
The while loop is intended to store another array of values inside the 1-dimensional array.
When the while loop returns to the beginning, it is overwriting it. So I only ever get the last returned set of values in the array.
My array ends up being a two dimensional array with only one value in each of the inner arrays.
Feels like I'm missing something very basic here - like a function or syntax which prevents the array from overwriting itself but instead, adds to the array.
Any ideas?
Step 1. Replace $topicarray[$value] with $topicarray[$value][]
Step 2. ???
Step 3. Profit
Make $topicarray[$value] an array of rows, instead of one row. Also, don't use extract here.
foreach ($topicarray as $key => $value) {
$rows = array();
$files = mysql_query("mysqlquery");
while($file = mysql_fetch_array($files)) {
$rows[] = array($file['id'] => $file['title']);
}
$topicarray[$value] = $rows;
}
Also, you should switch to PDO or MySQLi.

Categories