PHP mention script
I'm working on a mention script that gets an users pr开发者_Python百科ofile link when it is being mentioned in a news article or something. I've done the mention script, but it splits the users name after it finds a space. When an user wants to mention somebody they will start their name with a @ symbol.
So my script stops after it finds a space. That means if I wanted to mention an username such as @This is. It would only pick up This.
Could anyone tell me how I can pick up usernames with spaces in? Here is my script.
<?php
$string = "I'm wanting to speak to the user @This is please.";
$explosion = explode("@", $string);
$count = count($explosion);
for($i = 0; $i < $count; $i++){
$explosion2 = explode(" ", $explosion[$i]);
$explosion2 = $explosion2[0];
$string = str_replace("@{$explosion2}", "{$explosion2} yeah", $string);
}
echo $string;
?>
Thank you.
What if there are two users named "This" and "This is" and you have a text: "@This is, do you think @This is being serious?"
My advice would be to disallow spaces in usernames. It can cause more trouble than it's worth in many other situations anyway (URL creation, for instance).
There's no way to figure out if a username is just one word or multiple words from your example because the username has the exact same formatting as the rest of the string. There are a few ways you can fix this.
You explode on @ then read up until you reach some indicator of the end of the username. So strings would then need to be altered to have special indicators at the beginning AND END of usernames:
$string = "I'm wanting to speak to the user @This is@ please.";
This would be very convenient for you because you would only have to call explode once since the whole username would be in the array's second element.
Do you have a way to look up names? What I mean is, you need to be able to exclude This is
(and even This is please
) in order to find the user This
(if that was the intended user).
The naïve implementation would extract the string between the @
character and the first character not valid in a username (e.g., .
). This would give the string This is please
. You could then chop off one word at a time and see if a username matches.
This strategy, however, does not allow me to mention the user This
in the string "@This is not me."
if the user This is
exists.
To overcome this, the mention should be explicit with regard to the username. This can be achieved via delimiters (character that can themselves not be part of the username), e.g.:
I'm wanting to speak to the user [This is] please.
See @Jons' answer, too.
You have to edit this line:
$explosion2 = explode(" ", $explosion[$i]);
Other wise it will get only the first word. If you want take all the name up until a dot for example do this:
$explosion2 = explode(".", $explosion[$i]);
You cannot do that. Usually username doesn't contain spaces.
You definitely need to use a callback and need some means to determine if a username exists. You cannot guess from the words alone. And for simplicity I would prefer a regex callback here:
$str= preg_replace_callback('/@(\w+)( \w+)?( \w+)?/', 'rx_users', $str);
function rx_users($match) {
list($asis, $one, $two, $three) = $match;
if (user_exists($user=$one)
or user_exists($user="$one$two")
or user_exists($user="$one$two$three"))
{
return "<a href=user/$user>$user</a>";
}
else return $asis;
}
So it doesn't work without a user_exists()
test. But you can of course always fallback to assuming the username is just @$one
word per default.
I believe the solution to this problem would be to assign a unique numerical identifier to each registered user on sign up. Each user could then be referenced by username and/or their real name - with or without spaces between first and second names.
Strings beginning with @ would initiate a search of all users in a list which could then be selected from a drop down much like facebook or twitter.
精彩评论