7

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)
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
karto
  • 3,538
  • 8
  • 43
  • 68

3 Answers3

11

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:

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836
  • Very nice but I needed FILE_IGNORE_NEW_LINES. A Windows thing probably? – M T Sep 15 '22 at 21:31
  • @MT Not necessarily, I also use that with `files` on Linux, normally when I'm not interested in line terminators themselves, but just the string of each line. You might want to share more about what you're trying to accomplish that that I can actually see what you're concerned about. – hakre Sep 16 '22 at 11:20
  • thanks for asking but I'm not exactly sure what the question is. I needed to do exactly what the orginal question asked for. Your answer works for me but only if I add the ignore new lines option. I assume it's because of the difference between how unix and windows handles eol. DOS "\r\n" Unix just "\n" as discussed here: https://www.cs.toronto.edu/~krueger/csc209h/tut/line-endings.html#:~:text=Text%20files%20created%20on%20DOS,(%22%5Cn%22). – M T Sep 18 '22 at 20:23
  • @MT Yes, that can certainly be. Use that option then, its fine. For the answer we're not concerned about line endings any, I totally see no problem to use that option so use what works for you. The flag is exactly for such cases. – hakre Sep 19 '22 at 05:58
  • thanks. I made the comment simply to help other Windows users if they had similar trouble. In the end, since I was using it to keep "secrets" out of my git repo and then asked for a review, I was advised the best way for "secrets" is to add them as variables to a separate (.gitignored) php file and then include it. But your file reading method for associative arrays still looks very clean to me so I'll probably use it for other things. – M T Sep 20 '22 at 03:41
4
$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;
mrid
  • 5,782
  • 5
  • 28
  • 71
1

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.

Charlie
  • 22,886
  • 11
  • 59
  • 90