PHP实用工具函数库:安全过滤、字符串处理与IP获取

清欢
清欢
发布时间:2026-10-13 | 4人浏览过
原创

本文整理并分享了多个实用的PHP自定义函数,涵盖输入提交过滤(防XSS)、数组 stripslashes 处理、带中文支持的字符串截取、客户端IP获取及匿名化、支持中文的字符串加解密、中文字符检测以及隐藏文件真实路径下载等核心功能。这些基础代码段可直接集成至项目中,提升开发效率与安全性。

准备条件

在使用以下代码前,请确保您的服务器环境运行着 PHP,并且具备基础的 PHP 编程常识。部分函数依赖于特定的 PHP 扩展(如 mbstring),建议在服务器开启相应功能以获得最佳兼容性。

核心操作顺序

第1步:实现输入提交的深度安全过滤

目的:防止恶意脚本注入和危险 HTML 属性泄露。

动作:使用 filter() 函数对用户提交的文本进行清洗。该函数通过正则表达式完全过滤掉 HTML 注释、JS 脚本标签,拦截包含 on事件、javascript: 协议等危险属性的标签,并移除多余的基础 HTML 结构标签。最后将特殊字符反解析以确保格式正确。

function filter($text)
{
 //完全过滤注释
 $text = preg_replace('/<!--?.*-->/', '', $text);
 //完全过滤js
 $text = preg_replace('/<script?.*\/script>/', '', $text);
 //过滤危险的属性,如:过滤on事件lang js
 while (preg_match('/(<[^><]+)( lang|action|background|codebase|dynsrc|lowsrc)[^><]+/i', $text, $mat)) {
 $text = str_replace($mat[0], $mat[1], $text);
 }
 while (preg_match('/(<[^><]+)(window\.|javascript:|js:|about:|file:|document\.|vbs:|cookie)([^><]*)/i', $text, $mat)) {
 $text = str_replace($mat[0], $mat[1] . $mat[3], $text);
 }
 //过滤多余html
 $text = preg_replace('/<\/?(html|head|meta|link|base|basefont|body|bgsound|script|form|iframe|frame|frameset|applet|id|ilayer|layer|name|script|xml)[^><]*>/i', '', $text);
 //反转换
 $text = str_replace('[', '<', $text);
 $text = str_replace(']', '>', $text);
 $text = str_replace('|', '"', $text);
 return $text;
}

第2步:递归处理数组以去除转义字符

目的:解决在开启 magic_quotes_gpc 或类似环境下,多维数组中嵌套的反斜杠问题。

动作:调用 stripslashes_array() 函数。该函数会遍历数组,跳过系统敏感变量名(如 argc, argv),对字符串类型的值执行 stripslashes 操作,若值为子数组则递归调用自身。

function stripslashes_array(&$array)
{
 while (list($key, $var) = each($array)) {
 if ($key != 'argc' && $key != 'argv' && (strtoupper($key) != $key || '' . intval($key) == "$key")) {
 if (is_string($var)) {
 $array[$key] = stripslashes($var);
 }
 if (is_array($var)) {
 $array[$key] = stripslashes_array($array[$key]);
 }
 }
 }
 return $array;
}

第3步:增强版中文兼容字符串截取

目的:防止因截断中文字符(通常占多字节)导致页面乱码。

动作:使用 subString() 函数。该函数首先尝试利用 mb_substr 进行多字节安全截取;若不满足条件,则进入底层逻辑,根据 ASCII 码判断是否为多字节字符,并通过长度补偿机制(+1 或 +2)精确截取指定长度的字符串,并在末尾自动追加省略号。

function subString($strings, $start, $length)
{
 if (function_exists('mb_substr') && function_exists('mb_strlen')) {
 $sub_str = mb_substr($strings, $start, $length, 'utf8');
 return mb_strlen($sub_str, 'utf8') < mb_strlen($strings, 'utf8') ? $sub_str . '...' : $sub_str;
 }
 $str = substr($strings, $start, $length);
 $char = 0;
 for ($i = 0; $i < strlen($str); $i++) {
 if (ord($str[$i]) >= 128)
 $char++;
 }
 $str2 = substr($strings, $start, $length + 1);
 $str3 = substr($strings, $start, $length + 2);
 if ($char % 3 == 1) {
 if ($length <= strlen($strings)) {
 $str3 = $str3 .= '...';
 }
 return $str3;
 }
 if ($char % 3 == 2) {
 if ($length <= strlen($strings)) {
 $str2 = $str2 .= '...';
 }
 return $str2;
 }
 if ($char % 3 == 0) {
 if ($length <= strlen($strings)) {
 $str = $str .= '...';
 }
 return $str;
 }
}

第4步:获取并隐藏客户端真实 IP 地址

目的:准确识别用户 IP,并对隐私数据进行脱敏处理。

动作:首先调用 GetIP() 按优先级读取 HTTP_X_FORWARDED_FOR、HTTP_CLIENT_IP 和 REMOTE_ADDR 获取原始 IP。随后在 AnonymousIP() 中将获取到的 IPv4 地址最后一位替换为星号,实现匿名化展示。

function GetIP()
{
 if (@$_SERVER["HTTP_X_FORWARDED_FOR"])
 $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
 else if (@$_SERVER["HTTP_CLIENT_IP"])
 $ip = $_SERVER["HTTP_CLIENT_IP"];
 else if (@$_SERVER["REMOTE_ADDR"])
 $ip = $_SERVER["REMOTE_ADDR"];
 else if (@getenv("HTTP_X_FORWARDED_FOR"))
 $ip = getenv("HTTP_X_FORWARDED_FOR");
 else if (@getenv("HTTP_CLIENT_IP"))
 $ip = getenv("HTTP_CLIENT_IP");
 else if (@getenv("REMOTE_ADDR"))
 $ip = getenv("REMOTE_ADDR");
 else
 $ip = "Unknown";
 return $ip;
}

function AnonymousIP() 
{
 $ip = GetIP();
 if ($ip == "Unknown") {
 $removed_ip = "未知用户";
 }
 if (strpos($ip, ":")) {
 $removed_ip = "IPv6用户";
 } else {
 $reg1 = '/(\\d+\\.){3}\\d+/';
 $reg2 = '~(\d+)\.(\d+)\.(\d+)\.(\d+)~';
 $removed_ip = preg_replace($reg1, "\\1*", $ip);
 }
 return $removed_ip;
}

第5步:实现支持中文的字符串加解密

目的:保护敏感数据,同时兼容 UTF-8 编码的中文字符。

动作:使用 dencrypt() 函数。该函数生成动态密钥与固定密钥混合的加密密钥,采用异或运算结合 base64 编码,并针对长文本支持 gzip 压缩存储,短文本直接存储,确保了密文的灵活性与紧凑性。

function dencrypt($string, $isEncrypt = true, $key = "youdian")
{
 if (!isset($string{0}) || !isset($key{0})) {
 return false;
 }
 
 $dynKey = $isEncrypt ? hash('sha1', microtime(true)) : substr($string, 0, 40);
 $fixedKey = hash('sha1', $key);
 
 $dynKeyPart1 = substr($dynKey, 0, 20);
 $dynKeyPart2 = substr($dynKey, 20);
 $fixedKeyPart1 = substr($fixedKey, 0, 20);
 $fixedKeyPart2 = substr($fixedKey, 20);
 $key = hash('sha1', $dynKeyPart1 . $fixedKeyPart1 . $dynKeyPart2 . $fixedKeyPart2);
 
 $string = $isEncrypt ? $fixedKeyPart1 . $string . $dynKeyPart2 : (isset($string{339}) ? gzuncompress(base64_decode(substr($string, 40))) : base64_decode(substr($string, 40)));
 
 $n = 0;
 $result = '';
 $len = strlen($string);
 
 for ($n = 0; $n < $len; $n++) {
 $result .= chr(ord($string{$n}) ^ ord($key{$n % 40}));
 }
 return $isEncrypt ? $dynKey . str_replace('=', '', base64_encode($n > 299 ? gzcompress($result) : $result)) : substr($result, 20, -20);
}

第6步:检测字符串是否包含非英文字符

目的:快速判断输入内容是否包含中文或其他双字节字符。

动作:调用 CheckChinese() 函数,利用正则表达式 [\x7f-\xff] 匹配超出 ASCII 范围的字符,匹配成功即返回 true。

function CheckChinese($string)
{
 if (preg_match("/[\x7f-\xff]/", $string)) {
 return true;
 } else {
 return false;
 }
}

第7步:实现隐藏文件真实路径的安全下载

目的:让用户通过浏览器触发下载,而不暴露服务器上的实际目录结构。

动作:使用 FileHeaderJump() 函数。设置 HTTP 响应头为附件类型,指定文件名,清空输出缓冲区并刷新,最后读取文件流结束进程。

function FileHeaderJump($file)
{
 header('Content-Description: File Transfer');
 header('Content-Type: application/octet-stream');
 header('Content-Disposition: attachment; filename=' . basename($file));
 header('Content-Transfer-Encoding: binary');
 header('Expires: 0');
 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
 header('Pragma: public');
 header('Content-Length: ' . filesize($file));
 ob_clean();
 flush();
 readfile($file);
 exit;
}

第8步:生成指定长度的随机字符串

目的:用于生成临时密码、验证码或 Token。

动作:定义由大小写字母和数字组成的字符集,使用循环和 mt_rand 随机抽取字符拼接,返回最终字符串。

function CreateRandomString($length)
{
 $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
 $password = "";
 for ($i = 0; $i < $length; $i++) {
 $password .= $chars[mt_rand(0, strlen($chars) - 1)];
 }
 return $password;
}

完成判断与排错

  • 测试验证:将上述代码块保存至独立的 .php 文件引入项目中,通过调用各函数传入测试数据,观察返回值是否符合预期。特别是 subString 和 CheckChinese,建议使用包含大量汉字的样本进行测试。
  • 性能考量:AnonymousIP 中的正则匹配需注意效率,若有高频需求建议优化正则表达式或使用内置函数组合。
  • 安全风险:提供的 filter 函数基于正则匹配,面对复杂的 XSS 攻击可能不够全面,生产环境中建议结合成熟的过滤库(如 HTMLPurifier)使用。

简要总结

以上就是PHP实用工具函数的详细内容,更多关于PHP代码优化的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表