Convert delimited strings into an associative array - php

I have a file codes.txt with records like this
USA 0233
JPN 6789
TUN 8990
CDN 2345
I want to read these content of the file to an associative array like this.
$codes["USA"] = 0233;
$codes["JPN"] = 6789;
$codes["TUN"] = 8990;
$codes["CDN"] = 2345;
this is the code that opens the file for writing. I need help in the array part. thks
$myFile = "codes.txt";
$fh = fopen($myFile, 'r');
$theData = fread($fh, filesize($myFile));
fclose($fh)

It's pretty straight forward. First read the file line-by-line (e.g. see the file function which does this already). Then parse each line by splitting it at the first space (see explode), use the first part as key and the second part as value:
$array = array();
foreach (file($myFile) as $line)
{
list($key, $value) = explode(' ', $line, 2) + array(NULL, NULL);
if ($value !== NULL)
{
$array[$key] = $value;
}
}
If your parser needs to be more specific, change it according to your needs. There are a lot of string functions with PHP that can be used for more differentiated parsing, like sscanf or regular expressions.
Another common method is to extend from SplFileObject, it allows to encapsulate the data-aquisition inside an iterator so you can better differentiate between the place where the data is used and where it is taken from. You can find an example in another answer:
PHP - Process CSV Into Array With Column Headings For Key

$myFile = "codes.txt";
$fh = fopen($myFile, 'r');
$theData = fread($fh, filesize($myFile));
$assoc_array = array();
$my_array = explode("\n", $theData);
foreach($my_array as $line)
{
$tmp = explode(" ", $line);
$assoc_array[$tmp[0]] = $tmp[1];
}
fclose($fh);
// well the op wants the results to be in $codes
$codes = $assoc_array;

There is an optimal way of doing this than any of these answers. You can use file_get_contents and array_walk functions to cut the things very short.
$allCases = explode("\r\n", file_get_contents("myfile.txt"));
$myList = array();
array_walk($allCases, "step", $myList);
function step($val, $key, &$arr) {
$aCase = explode(" ", $val);
$arr[$aCase[0]] = $aCase[1];
}
This way you don't need a for loop or a file handler.
Beware of the delimiter "\r\n" since this could be platform dependent in this case.

Related

How to extract specific text from a text file in php?

i am having difficulties with extracting specific text from a text file. I have tried many different ways like using fopen or file to open the file but this wont allow me to use any of the string functions. So i have decided to use file_get_contents and extract the text i want with the string methods as follows:
<?php
$data = [];
$file =
file_get_contents("data.txt", 0, NULL, 148);
list($id, $data_names) = preg_split('[:]', $file);
array_push($names, $data_names);
echo $emails[0];
?>
I used preg_split to split the text i want at a specific character (:) and i put the data in an array. Which worked for the first line but i don't know how to go about doing it for the rest of the lines, i've tried a while loop but that just ends up in an infinite loop.
data.txt formatted like this:
1:hannah.Smith
2:Bob.jones
3:harry.white
....
Any suggestions on how to do this or a better approach would be greatly appreciated.
There is a function for that. This isn't CSV but change the delimiter. To just get the names:
$handle = fopen("data.txt", "r"));
while(($line = fgetcsv($handle, 0, ":")) !== FALSE) {
$names[] = $line[1];
}
To index the names by the ids:
while(($line = fgetcsv($handle, 0, ":")) !== FALSE) {
$names[$line[0]] = $line[1];
}
To get the ids and names in a multidimensional array, use:
while(($names[] = fgetcsv($handle, 0, ":")) !== FALSE) {}
Well you are not assigning the return value of file_get_contents to a variable. So the contents of the file are not being used.
You can use the file function. It reads the contents of a file to an array. Each element of the array is a line in the file. You can then loop over the array and parse each line. For example:
$names = array();
$file = file_get_contents("data.txt");
for ($count = 0; $count < count($file); $count++) {
list($id, $name) = $file[$count];
$names[] = $name;
}
/** print the contents of the names array */
print_R($names);

Extract column from csv data in PHP

I have csv data in PHP such as the following (note, it's text with new line characters in it, not a file):
$data = 'A,B,C,D,E,F,G,H
1,1,2014-12-10,5,1,2,0,2
2,7,2014-12-09,9,0,,7,2';
How can I extract a column as an array that excludes the headers? For example, if I wanted to extract the 4th column, it would include 5 and 9.
UPDATE: I have tried
$te = array_column($data,'D');
and I get the error: Warning: array_column() expects parameter 1 to be array,
You can use str_getcsv() to read each row as an array (discarding the first to skip headers). Then just keep the relevant column, e.g.:
$lines = preg_split("/(?:\r?\n|\r\n?)/", $data); // Split lines
array_shift($lines); // Discard header
$result = array();
foreach ($lines as $csv) {
$row = str_getcsv($csv);
$result[] = $row[3];
}
var_dump($result);
As per cHao suggestion in the comment below, if you need a more robust support of generic CSV data, you can dump the string to a virtual file and use fgetcsv() instead (which already handles parsing of multiple lines of input correctly):
$fp = fopen('php://temp', 'r+');
fputs($fp, $data);
fseek($fp, 0);
$result = array();
fgetcsv($fp);
while (false != ($row = fgetcsv($fp))) {
$result[] = $row[3];
}
fclose($fp);
var_dump($result);
If this a comma delimited string, you could use str_getcsv() in this case:
// load the string and explode, then apply str_getcsv
$data = array_map('str_getcsv', explode("\n", $request->getResponseBody()));
array_shift($data); // remove the header
$fourth_column = array();
foreach($data as $line) {
if(!empty($line[3])) {
$fourth_column[] = $line[3]; // indices start at zero
}
}

for loop looping to tlast item in text file

I been working trying everything to get this to work any help would be greatly apreciated.
i tried many couple of ways to get this work but i either get this error that the domain ame parameter is empty or I get the last domain in the txt file.
the txt file is just one domain per line.
$address="file.txt";
$shit=fopen($address,"r");
$contents2= fread($shit,filesize($address));
//also tried $domainlist=explode("\n\r",$contents2);
$domainlist=explode("\n",$contents2);
for($i=0 ; $i<=count($domainlist); ++$i){
$domainlist[$i]=$domain;
$contents = file_get_contents("http://www.whoisxmlapi.com/whoisserver/WhoisService?
domainName=$domain&username=$username&password=$password&outputFormat=JSON");
$results=json_decode($contents);
print_r($results);
unset($domain);
};
?>
Easier:
$lines = file("file.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach($lines as $domain) {
$contents = file_get_contents("http://www.whoisxmlapi.com/whoisserver /WhoisService?domainName=$domain&username=$username&password=$password&outputFormat=JSON");
$results = json_decode($contents);
print_r($results);
}
You may want to trim($domain) or make sure it's valid or other checks before doing file_get_contents().
$file = fopen("file.txt", "r");
while(!feof($file)){
$line = fgets($file);
$last_line = $line;
}
fclose($file);
echo $last_line;
A few ways to do this...
$file = file("file.txt");
foreach($file as $line) {
// do something with the $line
}
I prefer this method unless you're unsure of the file size. If unsure, you may want to consider using fopen.

Combining two text files with PHP - ForEach loops

I'm completely puzzled where to even start on this, but I need to provide a list of keywords in file A and then the same in list B.
With these too files I want to append the lines in A foreach line in file B
For example:
File A:
line1
line2
line3
File B:
test1
test2
test3
Output to a combined.txt file:
line1test1
line2test1
line3test1
line1test2 ... and so on
If you could provide me the portions of the script to research, a sample script, or even a working way to do it. I would greatly appreciate it.
Per request, here is my sample code:
<?php
$file1 = 'keywords.txt';
$file2 = 'topics.txt';
$combined = 'combined.txt';
$keywords = fopen("keywords.txt", "rb");
$topics = fopen("topics.txt", "rb");
$front = explode($topics);
$back = explode($topics);
while (!feof($keywords) ) {
file_put_contents($combined, . $front ."". $back . "\n");
fclose($keywords & $topics);
}
?>
Hope this helps. Comments are sprinkled throughout the code, which I hope is sufficient explanation as to what I'm doing.
<?php
// Open keywords file for reading
$keywords_file = 'keywords.txt';
$keywords_fh = fopen($keywords_file, 'r');
// Get line by line from keywords file, push into $keywords array
// Make sure to trim each line from fgets, to strip off \n at end.
$keywords = array();
while ($line = trim(fgets($keywords_fh))) {
array_push($keywords, $line);
}
fclose($keywords_fh);
// Open topics file for reading
$topics_file = 'topics.txt';
$topics_fh = fopen($topics_file, 'r');
// Get line by line from topics file, push into $topics array
// Make sure to trim each line from fgets, to strip off \n at end.
$topics = array();
while ($line = trim(fgets($topics_fh))) {
array_push($topics, $line);
}
fclose($topics_fh);
// Open combined file for writing
$combined_file = 'combined.txt';
$combined_fh = fopen($combined_file, 'w');
// Iterate through each keyword.
// For each iteration, iterate through each topic.
// Write the concatenation of keyword and topic to file.
foreach ($keywords as $keyword) {
foreach ($topics as $topic) {
fwrite($combined_fh, "$keyword$topic\n");
}
}
fclose($combined_fh);
Here are some links to PHP documentation for some of the key functions I used:
fopen
trim
fgets
fwrite
fclose
$f1 = explode("\n",file_get_contents("fileA.txt"));
$f2 = explode("\n",file_get_contents("fileB.txt"));
foreach ($f1 as $key => $value) {
$f3[] = $value.$f2[$key];
}
file_put_contents("fileC.txt", implode("\n",$f3));

PHP: Differences in parsing static file and php array file

I wanted to find best way to make translation framework (gettext have some imperfections).
So I make two tests - One, parsing file contains static text by code below
function parseLine($line) {
if($line[0] == '#' || !strlen($line))
return array();
$eq = strpos($line, '=');
$key = trim(substr($line, 0, $eq));
$value = trim(substr($line, $eq+1));
$value = trim($value, '"');
return array($key => $value);
}
$table = array();
$fp = fopen('lang.lng', 'r');
while(!feof($fp)) {
$table += parseLine(fgets($fp, 4096));
}
fclose($fp);
and secondly including array
$table = include('lang.php');
Of course each lang.lng and lang.php has same data (1000 records) but reperesented in diffrent way.
I was surpised when I saw results...
First method: ~0.01 s
Second: ~0.001 s
Before test I was sure that including array will take more memory and time then parsing file.
Could somebody explain me where is mistake?
I would have thought that was a no-brainer. Which is faster, reading in a file that contains an array, or reading in a file, processing it line-by-line, and for each line look for various tokens and components and piece them all together in a complex matter to result in the same array as the include method?

Categories