3v4l.org

run code in 200+ php & hhvm versions
Bugs & Features
<?php class KeywordParameters { public $post_name; public $cat_slug; public $base; public $medium; public function __construct($post_name, $cat_slug, $base, $medium) { $this->post_name = $post_name; $this->cat_slug = $cat_slug; $this->base = $base; $this->medium = $medium; } } class Replacements { public $replacements_list; public $keyword_parameters; public function __construct($replacements_list, $keyword_parameters) { $this->replacements_list = $replacements_list; $this->keyword_parameters = $keyword_parameters; } } class ReplacementTasks { const PATTERN_FORMAT = '~(?=[%s])(?=\b\w|(?<!\S)\W)(?:%s)(?<=\w\b|\W(?!\S))~ui'; protected $replacement_tasks = []; protected $formats = []; protected $pattern = false; protected $first_characters; protected $first_character_discrimination; protected $alternation; protected $keywords = []; public function add(Replacements $replacements) { $params = $replacements->keyword_parameters; $format = '<a href="' . $params->base . '%s?utm_source=blogpost&utm_medium=' . $params->medium . '&utm_content=' . $params->post_name . '&utm_campaign=' . $params->cat_slug . '" target="_blank">%s</a>'; $formats_last_index = array_push($this->formats, $format) - 1; foreach ($replacements->replacements_list as $keyword => $replacement) { $this->first_characters[] = mb_substr($keyword, 0, 1, 'UTF-8'); $this->replacement_tasks[$keyword] = [ 'replacement' => $replacement, 'format' => &$this->formats[$formats_last_index] ]; $this->keywords[] = preg_quote($keyword, '~'); } $this->pattern = false; } public function replace($str) { $this->build_pattern(); $that = &$this; return preg_replace_callback($this->pattern, function ($m) use (&$that) { return sprintf($that->replacement_tasks[$m[0]]['format'], $that->replacement_tasks[$m[0]]['replacement'], $m[0]); }, $str); } protected function build_pattern() { if ( $this->pattern ) return; $this->build_pattern_elements(); $this->pattern = sprintf(self::PATTERN_FORMAT, $this->first_character_discrimination, $this->alternation); } protected function build_pattern_elements() { rsort($this->keywords); $this->alternation = implode('|', $this->keywords); $this->first_character_discrimination = preg_quote(implode('', array_unique($this->first_characters)), '~'); } } $data = array( 'post_content' => 'làm game developer việc làm Game Developer việc làm Game Developer TPHCM việc làm Game Developer Hà Nội việc làm Senior Game Developer việc làm Senior Game Developer TPHCM', 'post_name' => 'Test post' ); $cat_slug = 'test'; $parameters_external = new KeywordParameters($data['post_name'], $cat_slug, 'https://itviec.com/', 'jobs'); $parameters_internal = new KeywordParameters($data['post_name'], $cat_slug, 'https://blog.itviec.com/', 'referral'); $keywords_internal = array( "làm game developer" => "game-developer-ban-co-muon-lam/", ); $keywords_external = array( "việc làm Game Developer TPHCM" => "viec-lam-it/game-developer/ho-chi-minh-hcm", "việc làm Game Developer Hà Nội" => "viec-lam-it/game-developer/ha-noi", "việc làm Game Developer" => "viec-lam-it/game-developer", ); $replacements_external = new Replacements($keywords_external, $parameters_external); $replacements_internal = new Replacements($keywords_internal, $parameters_internal); $replacement_tasks = new ReplacementTasks(); $replacement_tasks->add($replacements_external); $replacement_tasks->add($replacements_internal); echo $replacement_tasks->replace($data['post_content']);
based on qgW52
Output for 5.6.0 - 5.6.30, hhvm-3.15.4, 7.0.0 - 7.2.0
<a href="https://blog.itviec.com/game-developer-ban-co-muon-lam/?utm_source=blogpost&utm_medium=referral&utm_content=Test post&utm_campaign=test" target="_blank">làm game developer</a> <a href="https://itviec.com/viec-lam-it/game-developer?utm_source=blogpost&utm_medium=jobs&utm_content=Test post&utm_campaign=test" target="_blank">việc làm Game Developer</a> <a href="https://itviec.com/viec-lam-it/game-developer/ho-chi-minh-hcm?utm_source=blogpost&utm_medium=jobs&utm_content=Test post&utm_campaign=test" target="_blank">việc làm Game Developer TPHCM</a> <a href="https://itviec.com/viec-lam-it/game-developer/ha-noi?utm_source=blogpost&utm_medium=jobs&utm_content=Test post&utm_campaign=test" target="_blank">việc làm Game Developer Hà Nội</a> việc làm Senior Game Developer việc làm Senior Game Developer TPHCM