Split text string into $first and $last name in php

The simplest way is, by using explode:

$parts = explode(" ", $name);

After you have the parts, pop the last one as $lastname:

$lastname = array_pop($parts);

Finally, implode back the rest of the array as your $firstname:

$firstname = implode(" ", $parts);

example:

$name = "aaa bbb ccc ddd";

$parts = explode(" ", $name);
if(count($parts) > 1) {
    $lastname = array_pop($parts);
    $firstname = implode(" ", $parts);
}
else
{
    $firstname = $name;
    $lastname = " ";
}

echo "Lastname: $lastname\n";
echo "Firstname: $firstname\n";

Would result:

tomatech:~ ariefbayu$ php ~/Documents/temp/test.php 
Lastname: ddd
Firstname: aaa bbb ccc

I like cballou's answer because there's an effort to check if there's only a first name. I thought I'd add my functions for anyone else who comes lookin'.

Simple Function, Using Regex (word char and hyphens)

  • It makes the assumption the last name will be a single word.
  • Makes no assumption about middle names, that all just gets grouped into first name.
  • You could use it again, on the "first name" result to get the first and middle though.

Here's the code:

// uses regex that accepts any word character or hyphen in last name
function split_name($name) {
    $name = trim($name);
    $last_name = (strpos($name, ' ') === false) ? '' : preg_replace('#.*\s([\w-]*)$#', '$1', $name);
    $first_name = trim( preg_replace('#'.preg_quote($last_name,'#').'#', '', $name ) );
    return array($first_name, $last_name);
}

Ex 1: split_name('Angeler') outputs:

array(
    0 => 'Angeler',
    1 => ''
);

Ex 2: split_name('Angeler Mcgee') outputs:

array(
    0 => 'Angeler',
    1 => 'Mcgee'
);

Ex 3: split_name('Angeler Sherlee Mcgee') outputs:

array(
    0 => 'Angeler Sherlee',
    1 => 'Mcgee'
);

To get the first and middle name split,

Ex 4: split_name('Angeler Sherlee') outputs:

array(
    0 => 'Angeler',
    1 => 'Sherlee'
);

Another Function - Detects Middle Names Too

Later I decided that it would be nice to have the middle name figured out automatically, if applicable, so I wrote this function.

function split_name($name) {
    $parts = array();

    while ( strlen( trim($name)) > 0 ) {
        $name = trim($name);
        $string = preg_replace('#.*\s([\w-]*)$#', '$1', $name);
        $parts[] = $string;
        $name = trim( preg_replace('#'.preg_quote($string,'#').'#', '', $name ) );
    }

    if (empty($parts)) {
        return false;
    }

    $parts = array_reverse($parts);
    $name = array();
    $name['first_name'] = $parts[0];
    $name['middle_name'] = (isset($parts[2])) ? $parts[1] : '';
    $name['last_name'] = (isset($parts[2])) ? $parts[2] : ( isset($parts[1]) ? $parts[1] : '');
    
    return $name;
}

Ex 1: split_name('Angeler Sherlee Mcgee') outputs:

array(
    'first_name' => 'Angeler',
    'middle_name' => 'Sherlee',
    'last_name' => 'Mcgee'
);

Ex 2: split_name('Angeler Mcgee') outputs:

array(
    'first_name' => 'Angeler',
    'middle_name' => '',
    'last_name' => 'Mcgee'
);

Another Way - Sans Regex

Decided to add another way that doesn't use regex.

It also has return false; for non-recognizable names (null, empty string, too many word groups to infer).

<?php

function split_name($string) {
    $arr = explode(' ', $string);
    $num = count($arr);
    $first_name = $middle_name = $last_name = null;
    
    if ($num == 2) {
        list($first_name, $last_name) = $arr;
    } else {
        list($first_name, $middle_name, $last_name) = $arr;
    }

    return (empty($first_name) || $num > 3) ? false : compact(
        'first_name', 'middle_name', 'last_name'
    );
}

var_dump(split_name('Angela Mcgee'));
var_dump(split_name('Angela Bob Mcgee'));
var_dump(split_name('Angela'));
var_dump(split_name(''));
var_dump(split_name(null));
var_dump(split_name('Too Many Names In Here'));

Outputs

Array
(
    [first_name] => Angela
    [middle_name] => NULL
    [last_name] => Mcgee
)

Array
(
    [first_name] => Angela
    [middle_name] => Bob
    [last_name] => Mcgee
)

Array
(
    [first_name] => Angela
    [middle_name] => NULL
    [last_name] => NULL
)

false

false

false

if you have exactly 2-word input you can use list()

list($firstname, $lastname) = explode(" ", $string);

anyway you can use explode()

$words = explode(" ", $string);

$firstname = $words[0];
$lastname = $words[1];
$third_word = $words[2];
// ..

In my situation, I just needed a simple way to get first and last, but account for basic middle names:

$parts = explode(' ', 'Billy Bobby Johnson'); // $meta->post_title
$name_first = array_shift($parts);
$name_last = array_pop($parts);
$name_middle = trim(implode(' ', $parts));

echo 'First: ' . $name_first . ', ';
echo 'Last: ' . $name_last . ', ';
echo 'Middle: ' . $name_middle . '.';

Output:

First: Billy, Last: Johnson, Middle: Bobby.


list($firstname, $lastname) = explode(' ', $fullname,2);