Given:
A set of texts from the WYSIWYG editor. Stored in a database. All sorts of different tags there, among which there are such type:

<username class='username' uid='12345'>MyNick</username> 

Task:
When displaying, replace all these tags with the link in the user's personal account, instead of the nickname specified inside <username> </ username>, insert the nickname from the database corresponding to the uid (and suddenly changed, the record was made long ago) whether the user has uploaded a mini-avatar, and if so, then insert it in front of the nickname.
My decision:
1) for each text we are looking for all the tags, pull uid out of them

 $user_pattern = "/<username class=.* uid=\"(.*)\">.*<\/username>/"; preg_match_all($user_pattern, $text, $matches, PREG_SET_ORDER); foreach($matches as $value){ if(!in_array($value[1],$uids)){$uids[]=$value[1];} } 

2) Make a request to the database, compile an array of ready-made links (for all texts at once):

 $query=$dbh->query(" SELECT id, username FROM users WHERE users.id IN (".implode(',',$uids).")"); $query->setFetchMode(PDO::FETCH_ASSOC); while($row=$query->fetch()){ $uid=$row['id']; if(file_exists($_SERVER['DOCUMENT_ROOT']."/images/user_icons/$uid.png")){ $icon="<img src='/images/user_icons/$uid.png' class='icon_in_text'>"; }else{ $icon=""; } $users[$uid]="$icon <a href='/user/$uid/' class='username'>".$row['username']."</a>"; } 

3) Replace <username> with what we need (this is all in a loop for each text):

 preg_match_all($user_pattern, text, $matches, PREG_SET_ORDER); foreach($matches as $value){ $text=str_replace($value[0],$users[$value[1]],text); } 

Everything, everything works. Question to you, hashcoders: Am I too wise in the third step? I get the preg_match_all function 2 times (in points 1 and 3). And it will not be possible to replace immediately, otherwise a query to the database will be executed several times, with different sets of id for each text. Maybe remember the results of paragraph 1 in the array, and in paragraph 3, refer to the array, and not search again?
And it uses str_replace, in which I am not sure if it will not fail when working with Cyrillic.

    1 answer 1

    Am I too wise in the third step?

    If this is done by crown / one time, then by rewriting the code you will lose more resources than you win.

    But, in general, after the first regular season you have in $ matches, you should already have the complete occurrences of the string ($ matches [0..i] [0]), which you can use for search and replace. An array as keys can have not only uid, but also full strings, if the length scares you - you can take some short hash from them. In a good way, you can arrange each coincidence with a class / array so that they can be easily managed by specifying all the attributes that you may later need in your work.

    And it uses str_replace, in which I am not sure if it will not fail when working with Cyrillic.

    I did not come across this closely, but the stack flow suggested that this function works directly with bytes and not with characters, so it should be replaced as is, as long as the same encoding is used everywhere.