Your URL is index.php?/topic/7398-.../page__p__64307&forcePrint=1.... PHP treats everything up to the first & as a single query key, so none of the named parameters (p, showtopic, etc.) are set. The if / else if chain falls to the last branch, which reads:
php
else if (!preg_match('#(?P<content>p)(?P<id>\d+)#s', $_SERVER['REQUEST_URI'])) // posts
That branch only runs when the URL does not contain p<digits>. Your URL does contain __p__64307, so the branch is skipped, content_type is never set, and line 81 warns. The branch that should handle post URLs was never written, so these links have been 301ing to your forum index instead of the post. The same warning also fires for any URL that matches nothing at all.
I’m inferring the intent from the surrounding code, but the edit below makes it behave the way the rest of the script clearly expects.
Edit 1: replace the final else if block
Replace this block:
php
else if (!preg_match('#(?P<content>p)(?P<id>\d+)#s', $_SERVER['REQUEST_URI'])) // posts
{
preg_match('#/(?P<content_type>topic|forum|user|profile|gallery/image|gallery/album|gallery/category|gallery)/(?P<content_id>\d+)#s', $_SERVER['REQUEST_URI'], $match); // threads, forums, users, profile posts
$input += $match;
}
with:
php
else if (preg_match('#p(\d+)#', $_SERVER['REQUEST_URI'], $match)) // posts
{
$input['content_type'] = 'p';
$input['content_id'] = $match[1];
}
else if (preg_match('#/(?P<content_type>topic|forum|user|profile|gallery/image|gallery/album|gallery/category|gallery)/(?P<content_id>\d+)#s', $_SERVER['REQUEST_URI'], $match)) // threads, forums, users, profile posts
{
$input['content_type'] = $match['content_type'];
$input['content_id'] = $match['content_id'];
}
Edit 2: add a safety net right after that chain
Put this just before the $params = []; line:
php
$input += ['content_type' => '', 'content_id' => 0];
+= only fills in keys that are missing, so it never overrides a real match. Unmatched URLs now fall through to the existing if (!$target) fallback to the index with no warning.