Lance
Lance

Reputation: 43

PHP parse a .txt

I'm working on a website and want admins to be able upload a .txt file with employee ID's and names. I need the .txt file to be parsed and insert information into the database, but I keep getting errors while parsing.

I tried following the format of PHP - parsing a txt file but after my first $row explode() I start getting several illegal or undefined offset errors.

The .txt:

186298  "Cushing,Kathy N"
167876  "Roberts,Joseph Allen"
109876  "Smith,Sarah Quinn"
118679  "Hernandez,Juan"
187568  "Freeman,Colby Matthew"

The .php function:

function updateMemberList()
{
        global $db_handle;
        $tmpName = $_SESSION['filename'];
        //$include_once ($_SERVER['DOCUMENT_ROOT'] . "../../uploads/updates/'$tmpName'");
        $txt_file = file_get_contents("../../uploads/updates/$tmpName");
        $rows = explode("\n", $txt_file);

        foreach($rows as $row => $data)
        {
            //Splits data into employee ID and full name
            $row_data = explode(' ', $data);

            $info[$row]['empid'] = $row_data[0];
            $info[$row]['name'] = $row_data[1];     //AFTER this line is where I start having errors

            //Splits name into last name and first name
            $row_name = explode(',', $info[$row]['name']);
            $info[$row_name]['lname'] = $row_name[0];
            $info[$row_name]['fname'] = $row_name[1];

            //Cleans " off last name
            $row_lname = explode('"', $info[$row_name]['lname']);
            $info[$row_lname]['lname'] = $row_lname[1];

            //Cleans middle name and " off first name
            $row_fname1 = explode(' ', $info[$row]['fname']);
            $info[$row]['fname'] = $row_fname1[0];
            $row_fname2 = explode('"', $info[$row]['fname']);
            $info[$row]['fname'] = $row_fname2[0];

            //Declares variables
            $uname = $info[row]['fname'] + "." + $info[$row]['lname'];
            $fname = $info[row]['fname'];
            $lname = $info[$row]['lname'];
            $empid = $info[$row]['empid'];

            //Checks to see if user is already in db
            $query = ("SELECT * FROM user WHERE username = '$uname'");
            $check = mysqli_query($db_handle, $query);
            $num_rows = $check->num_rows;

            //If user isn't in db, generates a password and adds them
            if ($num_rows < 1)
            {
                //Generates random 8 character password
                $length = 8;
                $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
                $charactersLength = strlen($characters);
                for ($i = 0; $i < $length; $i++)
                {
        $randomString[$i] = $characters[rand(0, $charactersLength - 1)];
                }
                $temppass = implode($randomString);
                $pword = password_hash($temppass, PASSWORD_DEFAULT);
                $addto = "INSERT INTO `user`(`username`, `first_name`, `last_name`, `employee_id`, `password_hash`, `isActive`, `firstLogin`) VALUES ('$uname', '$fname', '$lname', '$empid', '$pword', 1, 1)";
                mysqli_query($db_handle, $addto);
            }
        }
    }

Is there any way to parse after the tab that would be more simple to grab the first and last name and doesn't yell at me?

EDIT: Solved issues by swapping to a .csv instead of .txt

Upvotes: 3

Views: 785

Answers (4)

Lance
Lance

Reputation: 43

Followed advice of https://stackoverflow.com/users/1552594/mike-miller and swapped from .txt to .csv file. This made everything much easier to run through and solved all errors.

Upvotes: 0

Robert
Robert

Reputation: 20286

Use regex it makes it much simpler also you don't need explode('\n') just file() function

  foreach($rows as $row => $data) { 
     $matches = array();
     preg_match('#([0-9]+).*? "([^""]+?)"#', $data, $matches);
     echo $matches[1]; //id
     echo $matches[2]; //name
  }

also you can change

    $txt_file = file_get_contents("../../uploads/updates/$tmpName");
    $rows = explode("\n", $txt_file);

to

    $rows = file("../../uploads/updates/$tmpName");

Morover, to generate random 8 length string use

$temppass = bin2hex(openssl_random_pseudo_bytes(4));

it's much more secure.

Upvotes: 3

Christian
Christian

Reputation: 1577

Try this. First line of while loop:

//Splits data into employee ID and full name
$row_data   = array_map("trim", array_filter(explode('"', $data)));
$names      = explode(",", $row_data[1]);
$result     = array(
    "id"        => $row_data[0],
    "forname"   => $names[1],
    "surname"   => $names[0],
);

And $result should look like this:

Array
(
    [id] => 186298
    [forname] => Kathy N
    [surname] => Cushing
)

Hope this is helpful.

Upvotes: 0

Daan
Daan

Reputation: 12236

You need to explode with 2 spaces:

$row_data = explode('  ', $data);

Upvotes: -1

Related Questions