How to extract name and surname from Full name

Hi I am trying to separate the first name and last name from a full name, currently using the following code, which however also returns the space before the last name, which I don’t want. How can I fix it?

	
$name = "John Smith";
	$firstname = strtok($name, ' ');
	echo $firstname;

	$lastname = strstr($name, ' ');
	echo $lastname;
$name = "John Smith";
	$firstname = strtok($name, ' ');
	echo trim($firstname);

	$lastname = strstr($name, ' ');
	echo trim($lastname);

Every subsequent call to strtok only needs the token, but even despite that there are certain reasons to avoid using strtok.

I’d code it up using explode:


$name = "John Smith";
$parts = explode(' ', $name);

$firstname = parts[0];
echo trim($firstname); 

$lastname = parts[1];
echo trim($lastname);

You could then neaten things up with the use of list:


$name = "John Smith";

list($firstname, $lastname) = explode(' ', $name);

echo trim($firstname); 
echo trim($lastname);

What if the name has middle name too?


function splitName($name){
    $names = explode(' ', $name);
    $lastname = $names[count($names) - 1];
    unset($names[count($names) - 1]);
    $firstname = join(' ', $names);
    return $firstname . ' = ' . $lastname;
}
echo splitName('firstname middlename surname');

And what if you’re dealing with foreign names, such as Portia de Rossi, or Armin van Buuren?

It can be a lot more convenient for the user to split up the first/middle/last names themself, since the user is more likely to get it right than where automated systems attempt to understand the whole lot.

If you need to convert a database of names, then with careful filtering you can weed out the obvious naming schemes, allowing you to create gradually more complex schemes to cater for the remainder.

and what if someone entered

john brown jnr

or

fred bloggs snr

for $name?

That needs some rule while entering the name. I am not saying that the function knows whatever is entered and returns first name and middle name. I wrote that function if the names are entered as ‘firstname middlename lastname’. Without any specific rules in the input, any functions don’t work.

yep, and so I agree with pmw57

[I]

[I]It can be a lot more convenient for the user to split up the first/middle/last names themself, since the user is more likely to get it right than where automated systems attempt to understand the whole lot.

If you need to convert a database of names, then with careful filtering you can weed out the obvious naming schemes, allowing you to create gradually more complex schemes to cater for the remainder.[/I]

[/I]

Well presuming that the input will always be in the same format, you can just use:


list($firstname, $middlename, $lastname) = explode(' ', $name);

That’s about the simplest you can get.

Yes no doubt on that. No debate :).

But my example was for optional middle name.

A simple if statement can help you out there. How are your PHP programming skills?


var $parts = explode(' ', $name);
if (count($parts) === 2) {
    list($firstname, $lastname) = $parts;
} else if (count($parts) === 3) {
    list($firstname, $middlename, $lastname) = $parts;
}

Or you could use other techniques that strip off the first word, then the last word, from which you can then decide based on what’s left what action to take from there. But that’s getting more complex than perhaps is needed.

Yes agreed on that there can be several different ways to achieve the goal. But in what aspect (performance?) the code I have written is not good? I have used three functions you have used two with two if conditions. Is there performance issue?

I didn’t see any handling for the middle name in your code.

It may be preferable to return an associative array, with all three parts filled in within the array. I’d also use functions like array_pop to help manage things more clearly.

For example:


function splitName($name) {
    $parts = explode(' ', $name);
    return array(
        'firstname' => array_shift($parts),
        'lastname' => array_pop($parts),
        'middlename' => join(' ', $parts)
    );
}