【问题标题】:Unable to get PHP script name using REGEX无法使用 REGEX 获取 PHP 脚本名称
【发布时间】:2020-06-04 06:23:03
【问题描述】:

我面临着很大的挑战。我有我的函数where(),它跟踪用户在网站上的访问位置,并获取脚本文件名并提供描述并插入数据库。

该脚本一直运行良好,直到最近,并且在最近从 MySQL 5.6.405.6.47

的小更新后没有意识到此功能失败

我不确定这是否与它有关,但几天后我发现它不再工作了。

我们的功能:

function where($scriptname = "index", $userid, $update=1){
    if (!is_valid_id($userid))
        die;

    if (preg_match("/details.php/i", $scriptname))
        $where = "Browsing File Details (ID $_GET[id])";
    elseif (preg_match("/files.php/i", $scriptname))
        $where = "Browsing Files";
    elseif (preg_match("/account-info.php/i", $scriptname))
        $where = "Browsing Account Info (ID $_GET[id])";
    elseif (preg_match("/upload.php/i", $scriptname))
        $where = "Uploading File";
    elseif (preg_match("/account.php/i", $scriptname))
        $where = "Browsing User Control Panel";
    elseif (preg_match("/search.php/i", $scriptname))
        $where = "Searching For Files";
    elseif (preg_match("/forums.php/i", $scriptname))
        $where = "Viewing Forums";
    elseif (preg_match("/index.php/i", $scriptname))
        $where = "Browsing Homepage";
    elseif (preg_match("/mailbox.php/i", $scriptname))
        $where = "Viewing Messages";
    elseif (preg_match("/comments.php/i", $scriptname))
        $where = "Viewing Comments";
    elseif (preg_match("/recover.php/i", $scriptname))
        $where = "Recovering Account";
    elseif (preg_match("/bookmarks.php/i", $scriptname))
        $where = "Viewing Bookmarks";
    elseif (preg_match("/getfile.php/i", $scriptname))
        $where = "Downloaded File (ID $_GET[id])";
    elseif (preg_match("/faq.php/i", $scriptname))
        $where = "Reading FAQ Page";
    elseif (preg_match("/friends.php/i", $scriptname))
        $where = "Viewing Friends";
    elseif (preg_match("/admin.php/i", $scriptname))
        $where = "Managing Admin Panel";
    else
        $where = "Unknown Location";

    if ($update) {
        // Worked until a few days ago. No site changes were made prior for quite some time. 
        //$query = sprintf("UPDATE users SET page=".sqlesc($where)." WHERE id ='%s'", mysql_real_escape_string($userid)); 
        // Now using line below, which does insert into row if I use my own variable. 
        $query = "UPDATE users SET last_access='" . get_date_time() . "', page=" . sqlesc($where) . " WHERE id=" . $userid;
        $result = SQL_Query_exec($query);
    }
        return $where;
}

现在,我已尝试使用以下代码将其范围缩小到导致它的原因。目前,上面的函数只插入

未知位置

到数据库,无论查看什么页面。

我明白了:

$stringtest = "This inserts into database!";
$query = "UPDATE users SET last_access='" . get_date_time() . "', page=" . sqlesc($stringtest) . " WHERE id=" . $userid;

这很好用,但是它没有通过任何$where 条件。

我尝试了各种正则表达式来匹配文件名,但无济于事。

知道我做错了什么吗?

提前致谢!

【问题讨论】:

  • 你应该学会使用准备好的语句,而不是将字符串连接到 SQL 中。
  • “未知位置”发生在任何 SQL 完成之前。调试 $scriptname 传递给此函数的内容。
  • var_dump($scriptname, $where)放在if/else之后。
  • @Barmar - 我已经使用了你的建议 var_dump 这就是产生的结果: string(55) "/usr/local/www/htdocs/details.php" string(33) "Browsing File Details (ID 193)" 不太确定如何处理这个问题。似乎在技术上可行,但不会更新行?
  • 我不知道为什么第一个 preg_match() 与那个名字不匹配。

标签: php mysql regex preg-match


【解决方案1】:

对于 SQL 部分,使用准备好的语句,如上所述。

假设,$scriptname 包含文件名,没有扩展名,而不是绝对路径,并且根据提供的代码,我认为那里不需要preg_match()。只需简单的switch ... case 即可。

更好的是,如果您想要一个带有描述的可管理位置列表(无论如何您每次都重复使用它们),您可以使用如下关联数组(可以由单独的函数返回)并执行以下操作:

$locations = array(
  'index' => 'Browsing Homepage', 
  'forums' => 'Browsing Homepage,
  //  and so on for all of your files
);

// And to get the description - assuming case matters, otherwise use strtolower()
$desc = isset($locations[$scriptname]) ? $locations[$scriptname] : 'Unknown Location';

【讨论】:

  • 谢谢,我现在重写函数并使用准备好的语句。我发布的功能效率不高,我认为可以通过用户ID将basename PHP_SELF返回到行来实现。更少的混乱,我可以使用文件名的案例
  • 不确定这里报告的要求是什么,但也许最好保存脚本的完整路径——根本不需要额外的处理。您拥有的访问者越多,您对 log 方法的调用就越多。快速保持日志操作至关重要。另一方面,报告偶尔会发生,因此您可以有更多的处理时间。另一个脚本可以解释您的日志。使脚本路径与任何类型的信息(单行文本或对象)相关联,然后在您的报告中显示此信息。就像上面的例子一样。
  • 我仍然没有运气。我可以用这个正确解析文件名: if (basename("details.php", $where)) $where = "Viewing Details";但它只会使用整个区块中的第一个匹配项,其他页面不报告,默认为该详细信息页面。我已经尝试了 5 种不同的功能,我希望我知道我在这里做错了什么......
  • 如何获取脚本名称?还, ”。”在正则表达式中具有特殊含义,您必须对其进行转义。并且 - 你真的必须简化事情 - 这里不需要正则表达式。
  • 我已经为此切换到数组解决方案,并进行了更好的检查,旧代码即将淘汰。
【解决方案2】:

我注意到您的 $scriptname 的默认值是“index”。我认为这引用了“index.php”?而您的匹配模式也在寻找文件扩展名。 (顺便说一句,未转义的. 并不意味着文字“。”。这是“任何一个字符”的正则表达式规则。所以是的,它会起作用,但有点偶然。)

你传递了什么样的价值观?在运行比较之前,尝试在该函数中删除/转储 $scriptname 的值,作为健全性检查,以验证是否收到了预期的输入类型。可能是您看到了合法的,即使只是意外的失败。

【讨论】:

  • 我传入 $userid ,它发送当前登录的用户 ID,注释行是工作行。我确实运行了 var_dump($scriptname, $where);在“else”之后,输出显示 string(55) "/usr/local/www/htdocs/details.php" string(33) "Browsing File Details (ID 193)
  • $scriptname = “index” 没有效果,它与 $scriptname 相同,我尝试在 var_dump 中将 basename() 附加到 $scriptname,并且只有一个文件名,但它没有在 elseif 块中做任何事情。在其他尝试使用 $where 的输出时,我看到在数据库中插入了指向错误 404 页面的直接路径
  • 酷!所以问题不在于您在此处发布的 sn-p。这是该功能所采取的措施是发送完整的文件路径而不是文件名。要么开始调试调用者,要么将$scriptname = basename($scriptname); 应用到函数的顶部。祝你好运!
  • 谢谢老兄,我很感激
猜你喜欢
  • 2010-11-22
  • 1970-01-01
  • 2019-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 2012-08-14
相关资源
最近更新 更多