I have a file with many rows,each row have the following format:
1519382994.85#MSG#Something went wrong
So, for each row i have three field divided by #. A number, a message type and a string.
Now i want to read the file and split the contents.
I made it in this way:
//Opening the logger file
$myfile = file_get_contents("operations.txt", "r") or die("Unable to open file!");
$rows = explode("\n", $myfile);
$num_rows = count($rows);
$fieldList = array();
//Parsing rows using '#'
foreach ($rows as $row => $data) {
$row_data = explode('#', $data);
array_push($fieldList, (string)$row_data[0]);
array_push($fieldList, (string)$row_data[1]);
array_push($fieldList, (string)$row_data[2]);
}
The code is working well but i'd like to have an array of array and this kind of data:
0: Array [ "112323.76", "MSG", "Hello"]
1: Array [ "453435.78", "MSG", "Bye"] etc..
I tryed with this code but i'm doing something wrong.
$last=0;
$result = array();
for ($i = 0; $i < $num_rows; $i++) {
array_push($result, (string) $fieldList[$last], (string) $fieldList[$last+1],(string) $fieldList[$last+2]);
//echo $fieldList[$last].'<br>';
//echo $fieldList[$last+1].'<br>';
//echo $fieldList[$last+2].'<br>';
$last=$last+3;
}
I'm a newbie in PHP someone can help me please and tell me what i'm doing wrong? Tanx a Lot for your time
You could probably make use of the built-in fgetcsv:
array fgetcsv ( resource $handle [, int $length = 0 [, string $delimiter = "," [, string $enclosure = '"' [, string $escape = "\\" ]]]] )
This could look like:
$rows = [];
if (false !== ($handle = fopen("path/to/file", "r")))
{
while (false !== ($row = fgetcsv($handle, 1000, ",")))
{
array_push($rows, $row);
}
fclose($handle);
}
Don't know if it would be a lot faster, but looks a lot easier to me. The main benefits of this over file() and explode() are:
There is no need to have the entire file in RAM at once, processing could be done one row at a time.
it is easy to support other "Character Seperated Values" type files where fields may be quoted ($enclosure)
Just needed some modifications in your code. Added comments to modified lines-
$myfile = file_get_contents("operations.txt", "r") or die("Unable to open file!");
$rows = explode("\n", $myfile);
$num_rows = count($rows);
$finalFieldList = array(); // new array
//Parsing rows using '#'
foreach ($rows as $row => $data) {
$fieldList = array(); // temporary array
$row_data = explode('#', $data);
array_push($fieldList, (string)$row_data[0]);
array_push($fieldList, (string)$row_data[1]);
array_push($fieldList, (string)$row_data[2]);
array_push($finalFieldList, $fieldList); // it will push to final array containing all 3 values
}
Related
I'm looking to read a CSV export file with PHP. I have access to the File Path Variable called $file_path.
How would I sort the CSV export file by a specific column and then sort it again by a second column? and then save the CSV file to the same file name and file path.
UPDATE:
I got it to read the CSV, then sort it and also save it to the CSV. However, it's also sorting the headers. I am trying to use array_shift and array_unshift but when I use array_shift with a multi-layer array, I am getting an error. (unshift works fine though).
function wp_all_export_after_export($export_id, $exportObj)
{
// Check whether "Secure Mode" is enabled in All Export -> Settings
$is_secure_export = PMXE_Plugin::getInstance()->getOption('secure');
if (!$is_secure_export) {
$filepath = get_attached_file($exportObj->attch_id);
} else {
$filepath = wp_all_export_get_absolute_path($exportObj->options['filepath']);
}
$handle = fopen($filepath, 'r') or die('cannot read file');
$binNumber = array();
$category = array();
$rows = array();
$header = array();
//build array of binNumbers, Categories, and array of rows
while (false != ( $row = fgetcsv($handle, 0, ',') )) {
$binNumber[] = $row[3];
$category[] = $row[1];
$rows[] = $row;
}
fclose($handle);
$header = $rows[0];
array_shift($rows);
//sort array of rows by BinNumber & then Category using our arrays
array_multisort($binNumber,SORT_ASC, $category, SORT_ASC, $rows);
array_unshift($rows,$header);
$file = fopen($filepath,"w");
foreach ($rows as $line) {
fputcsv($file, $line);
}
fclose($file);
}
add_action('pmxe_after_export', 'wp_all_export_after_export', 10, 2);
Is there a way I can change specific key values into boolean or string. The conversion changes all the Data into string. For example the Key value "Date" should be an integer instead of a string.
<?php
function csvToJson($fname) {
if (!($fp = fopen($fname, 'r') )) {
die("Can't open file");
}
$key = fgetcsv($fp, "1024", ",");
$json = array();
while ($row = fgetcsv($fp, "1024", ",")) {
$json[] = array_combine($key, $row);
}
fclose($fp);
foreach ( $json as $k=>$v ) {
$json[$k]['dateRequested'] = $json[$k]['DATE'];
$json[$k]['assignedAgent'] = $json[$k]['AGENT'];
$json[$k]['finalCompanyName'] = $json[$k]['COMPANY NAME'];
unset($json[$k]['DATE']);
unset($json[$k]['AGENT']);
unset($json[$k]['COMPANY NAME']);
}
return json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
?>
<?php
$json_data = csvToJson("lms.csv");
?>
Try this:
while ($row = fgetcsv($fp, "1024", ",")) {
// here $row contains all the columns in it in a numeric array
// Means 0 => first column of csv, 2 => second column of csv and so on
// you can convert any specific column value like
$json[] = array($row[0], setype($row[0], "string"), and so on);
}
You can do like this:
$json[$k]['dateRequested'] = (int)($json[$k]['DATE']);
$json[$k]['assignedAgent'] = $json[$k]['AGENT'];
$json[$k]['finalCompanyName'] = $json[$k]['COMPANY NAME'];
Sample usage :
$int = (int)(123);
$bool = (bool)(1);
$string = (string)(1234);
var_dump($int);
var_dump($bool);
var_dump($string);
Ive the following Code , a function take a list of usernames and put in them in array then execute function called function get_all_friends , Code works fine and no error , my question here how to adjust the code if ive bulk of usernames lets say like 10k ?
Like reading from file include all usernames name and put them in array using
$file_handle = fopen("users.txt")
please advise !
<?PHP
$user1 = "usernamehere";
$user2 = "usernamehere";
$user3 = "usernamehere";
$u[] = $user1;
$u[] = $user2;
$u[] = $user3;
function get_all_friends($users)
{
$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, TOKEN_KEY, TOKEN_SECRET);
$list = array();
foreach($users as $user)
{
$result = $connection->get( 'friends/ids', array(
"screen_name"=> $user)
);
foreach($result->ids as $friend)
{
$list[] = $friend;
}
}
return $list;
}
//call the function
$result = get_all_friends($u);
foreach($result as $res)
{
$query = "INSERT INTO friends (userid, name, grade, flag) VALUES ($res, 'name', 100, 0 ) ";
mysql_query($query);
}
//to print the databse result
echo "row<br />";
$res = mysql_query("SELECT * FROM friends");
while ($row = mysql_fetch_assoc($res))
{
print_r($row);
}
?>
Something like the following should work (untested):
$filename = "users.txt";
$file_handle = fopen($filename, "r");
$contents = fread($file_handle, filesize($filename));
$usernames = preg_split("/ (,|\\n) /", $contents);
fclose($file_handle);
The usernames must be separated by a comma or a new line.
Although, if you are positive that the usernames will only be separated by a new line OR a comma, this code will be faster:
$filename = "users.txt";
$file_handle = fopen($filename, "r");
$contents = fread($file_handle, filesize($filename));
// new line:
$usernames = explode("\n", $contents);
// or comma:
$usernames = explode(",", $contents);
fclose($handle);
Please choose only one of the $usernames definitions.
Specifically to answer the question, check file(..) - "Reads entire file into an array"
http://php.net/manual/en/function.file.php
Although you probably don't want to be doing it this way, if the file is large you'll be much better off reading sequentially or doing some sort of direct import.
I am new to PHP and would like to be able to read in a csv file which has two columns, one is the number (kind of like a ID) then the other holds a integer value. I have looked up the fgetcsv function but I have not been able to find a way to read a specific column from the csv file.
I would like to get all the values from the second column only, without the heading.
Any way of doing this?
This is what I have so far:
$file = fopen('data.csv', 'r');
$line = fgetcsv($file);
And this is some sample data from the csv file:
ID,Value
1,243.00
2,243.00
3,243.00
4,243.00
5,123.11
6,243.00
7,180.00
8,55.00
9,243.00
Any help would be appreciated.
Thanks.
fgetcsv() only reads a single line of the file at a time. You'll have to read the file in a loop to get it all:
$data = array();
while($row = fgetcsv($file)) {
$data[] = $row;
}
The heading you can skip by doing an fgetcsv once outside the loop, to read/trash the header values. And if you only want the second column, you can do:
$data[] = $row[1];
However, since you've got data in there, maybe it might be useful to keep it, plus key your new array with the ID values in the csv, so you could also have:
$data[$row[0]] = $row[1];
and then your nice shiny new array will pretty much exactly match what's in the csv, but as an array keyed by the ID field.
$csv = array_map("str_getcsv", file("data.csv", "r"));
$header = array_shift($csv);
// Seperate the header from data
$col = array_search("Value", $header);
foreach ($csv as $row) {
$array[] = $row[$col];
}
// Iterate through data set, creating array from Value column
$header = fgetcsv($h);
$rows = array();
while ($row = fgetcsv($h)) {
$rows []= array_combine($header, $row);
}
$fp = fopen($filePath, "r+");
$header = fgetcsv($fp);
while ($members = fgetcsv($fp)) {
$i = 0;
foreach ($members as $mem) {
$membersArray[ $i ][ ] = $mem;
$i++;
}
}
$newArray = array_combine($header, array_map("array_filter",$membersArray));
You can also use this class http://code.google.com/p/php-csv-parser/
<?php
require_once 'File/CSV/DataSource.php';
$csv = new File_CSV_DataSource;
$csv->load('data.csv');
var_export($csv->connect());
?>
My goal here is to open temp.php, explode by ### (line terminator), then by %% (field terminator). Change a specific field, on a specific line, then implode everything back together and save it.
There are a couple variables at play here:
row = the target row number
target = the target field/column number
nfv = the info that i want to place into the target field
Im using the counter $i to count until i get to the desired row. Then counter $j to count til i get to my desired field/target. So far this gives me an error for invalid implode arguments, or doesn't save any data at all. Im sure there are a couple things wrong, but i am frustrated and lost.
<?
$row = $_GET['row'];
$nfv = $_GET['nfv'];
$target = $_GET['target'];
$data = file_get_contents("temp.php");
$csvpre = explode("###", $data);
$i = 0;
$j = 0;
foreach ( $csvpre AS $key => $value){
$i++;
if($i == $row){
$info = explode("%%", $value);
foreach ( $info as $key => $value ){
$j++;
if($j == "$target"){
$value = $nfv;
}
}
$csvpre[$key] = implode("%%", $info);
}
}
$save = implode("###", $csvpre);
$fh = fopen("temp.php", 'w') or die("can't open file");
fwrite($fh, $save);
fclose($fh);
header("Location: data.php");
?>
If someone can tell what is wrong with this, please be detailed so i can learn why its not working.
Here is some sample csv data for testing
1%%4%%Team%%40%%75###2%%4%%Individual%%15%%35###3%%4%%Stunt Group%%50%%150###4%%4%%Coed Partner Stunt%%50%%150###5%%4%%Mascot%%15%%35###6%%8%%Team%%40%%75###7%%8%%Stunt Group%%50%%150###8%%8%%Coed Partner Stunt%%50%%150###9%%3%%Team%%40%%75###10%%1%%Team%%40%%75###11%%1%%Solo%%15%%35###12%%1%%Duet%%50%%150###13%%2%%Team%%50%%50###14%%2%%Solo%%15%%35###15%%2%%Duet%%50%%150###16%%8%%Individual%%15%%35###
The following should work. This also eliminates a lot of unnecessary looping
<?php
$row = $_GET['row'];
$nfv = $_GET['nfv'];
$target = $_GET['target'];
$data = file_get_contents("temp.php");
$csvpre = explode("###", $data);
//removed i and j. unnecessary.
//checks if the row exists. simple precaution
if (isset($csvpre[$row]))
{
//temporary variable, $target_row. just for readability.
$target_row = $csvpre[$row];
$info = explode("%%", $target_row);
//check if the target field exists. just another precaution.
if (isset($info[$target]))
{
$info[$target] = $nfv;
}
//same as yours. just pack it back together.
$csvpre[$row] = implode("%%", $info);
}
$save = implode("###", $csvpre);
$fh = fopen("temp.php", 'w') or die("can't open file");
fwrite($fh, $save);
fclose($fh);
header("Location: data.php");
?>
The looping you were doing was removed as the row were numerically indexed already anyways. Accessing the array element directly is much faster than looping through the elements until you find what you want.