PHP实用工具函数库:安全过滤、字符串处理与IP获取
本文整理并分享了多个实用的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代码优化的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













