将文本中的@mentions 替换为可点击的文本,包括从数据库中获取的相关 ID table
Replace @mentions in text with clickable text including related ids fetched from a database table
我希望能够点击每个@.... 并转到他们的特定页面,这样我就可以从数据库中获取文本中每个匹配项的 ID,以便 link比赛的页面。我确实从 foreach 循环中获取了一个 id 数组,但是当我在 foreach 循环中使用 preg_replace 时,我为多个值插入了相同的 id。我被卡住了,尝试了很多不同的变体,但还没有成功。
$text = "I went to the dog park yesterday and saw @dog4 playing with @dog8 and @dog3 drinking water.";
public function getLinks($text) {
preg_match_all("/@([\w]+)/", $text, $matches);
if ($matches) {
$result = array_values($matches[1]);
}
$sql = "SELECT dogId FROM dogs WHERE dogName = :dogName";
foreach ($result as $dogName) {
$stmt = $this->con->prepare($sql);
$stmt->execute(array(":dogName" => $dogName));
$data = $stmt->fetch(PDO::FETCH_ASSOC);
$i = 0;
if (!empty($data)) {
foreach ($data as $dogId) {
$i++;
// It's working here. I'm getting an array of dogIds
echo '<pre>'; print_r($data); echo '</pre>';
Array
(
[dogId] => 4
)
Array
(
[dogId] => 8
)
Array
(
[dogId] => 3
)
if ($i == count($data)) {
$pattern = "/@([\w]+)/";
$dogPage = "<span onclick='openPage(\"dogs.php?id=$dogId\")' role='link' tabindex='0'>[=11=]</span>";
$dogLink = preg_replace($pattern, $dogPage, $text);
// It's not working here. I only get the last array value(3) inserted in $dogId for every match.
echo '<pre>'; print_r($dogPage); echo '</pre>';
"<span onclick='openPage(\"dogs.php?id=3\")' role='link' tabindex='0'>@dog4</span>"
"<span onclick='openPage(\"dogs.php?id=3\")' role='link' tabindex='0'>@dog8</span>"
"<span onclick='openPage(\"dogs.php?id=3\")' role='link' tabindex='0'>@dog3</span>"
}
}
}
} return $dogLink
}
我得到的结果文本是
I went to the dog park yesterday and saw @dog4(id=3) playing with @dog8(id=3) and @dog3(id=3) drinking water.
但我想要实现的是
I went to the dog park yesterday and saw @dog4(id=4) playing with @dog8(id=8) and @dog3(id=3) drinking water.
提前致谢!
首先扫描您的输入文本以查找所有@mentions 并构建一个没有前导“@”的平面值数组(\K
意味着忘记任何先前匹配的字符——在本例中为 @
).从生成列表中的 dogs
table 中提取所有行,并将它们转换为查找数组,其中 dogName
作为键,dogId
作为值。
$count = preg_match_all('/@\K\w+/', $text, $mentions);
if ($count) {
$in = str_repeat('?,', $count - 1) . '?';
$stmt = $db->prepare("SELECT dogName, dogId FROM dogs WHERE dogName IN ($in)");
$stmt->execute($mentions[0]);
$lookup = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
}
生成$mentions
的演示:https://3v4l.org/O9v37
PDO 引用: & https://phpdelusions.net/pdo/fetch_modes#FETCH_KEY_PAIR
然后您可以使用 /@(\w+)/
作为 preg_replace_callback()
的第一个参数再次读取 @mentions 的输入文本。在回调的自定义函数范围内,使用 isset()
快速检查匹配的提及项是否作为查找中的键存在——如果是,则替换,如果不是,则不要更改文本。
$text = "I went to the dog park yesterday and saw @dog4 playing with @dog8 and @dog3 drinking water -- poor @dog33.";
$lookup = [
'dog4' => 4,
'dog8' => 8,
'dog3' => 3,
];
echo preg_replace_callback(
'/@(\w+)/',
function ($m) use($lookup) {
return isset($lookup[$m[1]])
? "<span onclick='openPage(\"dogs.php?id={$lookup[$m[1]]}\")' role='link' tabindex='0'>{$m[0]}</span>"
: $m[0];
},
$text
);
输出:
I went to the dog park yesterday and saw <span onclick='openPage("dogs.php?id=4")' role='link' tabindex='0'>@dog4</span> playing with <span onclick='openPage("dogs.php?id=8")' role='link' tabindex='0'>@dog8</span> and <span onclick='openPage("dogs.php?id=3")' role='link' tabindex='0'>@dog3</span> drinking water -- poor @dog33.
我希望能够点击每个@.... 并转到他们的特定页面,这样我就可以从数据库中获取文本中每个匹配项的 ID,以便 link比赛的页面。我确实从 foreach 循环中获取了一个 id 数组,但是当我在 foreach 循环中使用 preg_replace 时,我为多个值插入了相同的 id。我被卡住了,尝试了很多不同的变体,但还没有成功。
$text = "I went to the dog park yesterday and saw @dog4 playing with @dog8 and @dog3 drinking water.";
public function getLinks($text) {
preg_match_all("/@([\w]+)/", $text, $matches);
if ($matches) {
$result = array_values($matches[1]);
}
$sql = "SELECT dogId FROM dogs WHERE dogName = :dogName";
foreach ($result as $dogName) {
$stmt = $this->con->prepare($sql);
$stmt->execute(array(":dogName" => $dogName));
$data = $stmt->fetch(PDO::FETCH_ASSOC);
$i = 0;
if (!empty($data)) {
foreach ($data as $dogId) {
$i++;
// It's working here. I'm getting an array of dogIds
echo '<pre>'; print_r($data); echo '</pre>';
Array
(
[dogId] => 4
)
Array
(
[dogId] => 8
)
Array
(
[dogId] => 3
)
if ($i == count($data)) {
$pattern = "/@([\w]+)/";
$dogPage = "<span onclick='openPage(\"dogs.php?id=$dogId\")' role='link' tabindex='0'>[=11=]</span>";
$dogLink = preg_replace($pattern, $dogPage, $text);
// It's not working here. I only get the last array value(3) inserted in $dogId for every match.
echo '<pre>'; print_r($dogPage); echo '</pre>';
"<span onclick='openPage(\"dogs.php?id=3\")' role='link' tabindex='0'>@dog4</span>"
"<span onclick='openPage(\"dogs.php?id=3\")' role='link' tabindex='0'>@dog8</span>"
"<span onclick='openPage(\"dogs.php?id=3\")' role='link' tabindex='0'>@dog3</span>"
}
}
}
} return $dogLink
}
我得到的结果文本是
I went to the dog park yesterday and saw @dog4(id=3) playing with @dog8(id=3) and @dog3(id=3) drinking water.
但我想要实现的是
I went to the dog park yesterday and saw @dog4(id=4) playing with @dog8(id=8) and @dog3(id=3) drinking water.
提前致谢!
首先扫描您的输入文本以查找所有@mentions 并构建一个没有前导“@”的平面值数组(\K
意味着忘记任何先前匹配的字符——在本例中为 @
).从生成列表中的 dogs
table 中提取所有行,并将它们转换为查找数组,其中 dogName
作为键,dogId
作为值。
$count = preg_match_all('/@\K\w+/', $text, $mentions);
if ($count) {
$in = str_repeat('?,', $count - 1) . '?';
$stmt = $db->prepare("SELECT dogName, dogId FROM dogs WHERE dogName IN ($in)");
$stmt->execute($mentions[0]);
$lookup = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
}
生成$mentions
的演示:https://3v4l.org/O9v37
PDO 引用: & https://phpdelusions.net/pdo/fetch_modes#FETCH_KEY_PAIR
然后您可以使用 /@(\w+)/
作为 preg_replace_callback()
的第一个参数再次读取 @mentions 的输入文本。在回调的自定义函数范围内,使用 isset()
快速检查匹配的提及项是否作为查找中的键存在——如果是,则替换,如果不是,则不要更改文本。
$text = "I went to the dog park yesterday and saw @dog4 playing with @dog8 and @dog3 drinking water -- poor @dog33.";
$lookup = [
'dog4' => 4,
'dog8' => 8,
'dog3' => 3,
];
echo preg_replace_callback(
'/@(\w+)/',
function ($m) use($lookup) {
return isset($lookup[$m[1]])
? "<span onclick='openPage(\"dogs.php?id={$lookup[$m[1]]}\")' role='link' tabindex='0'>{$m[0]}</span>"
: $m[0];
},
$text
);
输出:
I went to the dog park yesterday and saw <span onclick='openPage("dogs.php?id=4")' role='link' tabindex='0'>@dog4</span> playing with <span onclick='openPage("dogs.php?id=8")' role='link' tabindex='0'>@dog8</span> and <span onclick='openPage("dogs.php?id=3")' role='link' tabindex='0'>@dog3</span> drinking water -- poor @dog33.