Adrian Gheorghe
Adrian Gheorghe

Reputation: 677

PHP reading data input from a text file

I have a text file which I must read, and use the data from.

3
sam 99912222
tom 11122222
harry 12299933
sam
edward
harry

How can I create an array of these strings in the following form?

array(
    "name" => "number"
    ...
)

I tried this:

$handle = fopen("file.txt", "r");
fscanf($handle, "%d %d", $name, $number);

What then? No matter what I try, it only works for the first line.

sam 99912222

Upvotes: 1

Views: 1367

Answers (3)

Poiz
Poiz

Reputation: 7617

With the Algorithm below, you can simply parse each individual line of the Text-File Contents into an array with the 1st Word or Digit(s) on each line as the Key and the 2nd Word as the Value. When the 2nd word or group of words do not exist, a NULL is assigned to that Key. For re-usability, this algorithm has been encapsulated into a Function. Here you go:

<?php

    function parseTxtFile($txtFile){
        $arrTxtContent      = [];

        if(!file_exists($txtFile)){ return null;}
        $strFWriteTxtData   = file_get_contents($txtFile);

        if(empty($strFWriteTxtData)){return null;}

        $arrFWriteInfo      = explode("\n", $strFWriteTxtData);

        foreach($arrFWriteInfo as $iKey=>$lineData){
            $arrWriteData   = explode(", ", $lineData);
            foreach($arrWriteData as $intKey=>$strKeyInfo){
                preg_match("#(^[a-z0-9_A-Z]*)(\s)(.*$)#i", $strKeyInfo, $matches);
                preg_match("#(^[a-z0-9_A-Z]*)(\s*)?$#i", $strKeyInfo, $matches2);
                if($matches) {
                    list(, $key, $null, $val)   = $matches;
                    if (!array_key_exists($key, $arrTxtContent)) {
                        $arrTxtContent[$key]    = $val;
                    }else{
                        $iKey   = $intKey + 1;
                        $key    = $key . "_{$iKey}";
                        $arrTxtContent[$key]    = $val;
                    }
                }else if($matches2) {
                    list(, $key, $null)   = $matches2;
                    if (!array_key_exists($key, $arrTxtContent)) {
                        $arrTxtContent[$key]    = null;
                    }else{
                        $key = preg_match("#_\d+#", $key, $match)? $key . $match[0] : "{$key}_1";
                        $arrTxtContent[$key]    =  null;
                    }
                }
            }
        }
        return $arrTxtContent;
    }

    var_dump(parseTxtFile(__DIR__ . "/data.txt"));

Just call the function parseTxtFile($txtFile) passing it the path to your text File and it will return an Array that looks something like below:

    array (size=7)
      3         => null
      'sam'     => string '99912222' (length=8)
      'tom'     => string '11122222' (length=8)
      'harry'   => string '12299933' (length=8)
      'sam_1'   => null
      'edward'  => null
      'harry_1' => null

Hope this could help a bit....

Cheers & Good-Luck ;-)

Upvotes: 1

FirstOne
FirstOne

Reputation: 6215

Added codes to have both types of output - ignoring and including the lines that don't have name-value pairs. Check them out below


This code goes through each line and gets only the ones that have both name and value (something[space]something)):

//$lines = ... each line of the file in an array

$vals = array();
foreach($lines as $v){
    $tmp = explode(' ', $v);
    if(count($tmp) > 1){
        $vals[trim($tmp[0])] = trim($tmp[1]); // trim to prevent garbage
    }
}

print_r($vals);

It will output this:

Array
(
    [sam] => 99912222
    [tom] => 11122222
    [harry] => 12299933
)

See the code in action here.


If you need the values even if they didn't come in pairs, do it like this:

//$lines = ... each line of the file

$vals = array();
foreach($lines as $v){
    $tmp = explode(' ', $v);
    $name = '';
    $number = '';
    $tmp[0] = trim($tmp[0]);
    if(count($tmp) > 1){
        $name = $tmp[0];
        $number = trim($tmp[1]);
    }else{
        if(is_numeric($tmp[0])){
            $number = $tmp[0];
        }else{
            $name = $tmp[0];
        }

    }
    $vals[] = array(
        'name' => $name,
        'number' => $number
    );
}

print_r($vals);

And the output:

Array
(
    [0] => Array
        (
            [name] => 
            [number] => 3
        )

    [1] => Array
        (
            [name] => sam
            [number] => 99912222
        )

    [2] => Array
        (
            [name] => tom
            [number] => 11122222
        )

    [3] => Array
        (
            [name] => harry
            [number] => 12299933
        )

    [4] => Array
        (
            [name] => sam
            [number] => 
        )

    [5] => Array
        (
            [name] => edward
            [number] => 
        )

    [6] => Array
        (
            [name] => harry
            [number] => 
        )

See the code in action here.

Upvotes: 2

Kamil
Kamil

Reputation: 1030

Data in file are inconsistent, best of is to use regex to identify what data you've got from each line.

$lines = file('file.txt'); // this will open file and split them into lines
$items = array();
foreach($lines as $line){
   $name = null;
   $number = null;
   $nameFound = preg_match("|([A-Za-z]+)|", $line, $matches);
   if($nameFound){
      $name = $matches[0];
   }
   $numberFound = preg_match("|([0-9]+)|", $line, $matches);
   if($numberFound){
      $number = $matches[0];
   }

   $items[] = array('name' => $name, 'number' => $number);
}

Then in items you should find parsed data from file.

To make it just extract full format data just change lines with regex into one line like this:

$lines = file('file.txt'); // this will open file and split them into lines
$items = array();
foreach($lines as $line){
   $userFound = preg_match("/([A-Za-z]+) ([0-9]+)/", $line, $matches);
   if($userFound){
      $items[$matches[1]] = $matches[2];
   }

}

Upvotes: 1

Related Questions