过滤 SQL 注入字符
/**
* 过滤SQL注入高危字符(严格模式)
* @param string $input 用户输入
* @return string 过滤后的安全字符串
*/
function filterStr($input)
{
// 正则匹配高危字符(包括注释、引号、逻辑运算符等)
$pattern = '/(\/\*|\*\/|--|#|\'|"|;|\\\|\||\b(OR|AND|UNION|SELECT|INSERT|UPDATE|DELETE|DROP|ALTER|CREATE|EXEC|XP_)\b)/i';
$filtered = preg_replace($pattern, '', strip_tags(trim($input)));
$filtered = preg_replace('/0x[0-9a-f]+/i', '', $filtered);
return htmlspecialchars($filtered, ENT_QUOTES, 'UTF-8');
}
$userInput = "admin' (OR 1=1)-- /* DROP TABLE users */";
echo filterStr($userInput); // 输出:admin ( 1=1) TABLE users
获取 PDO 预编译语句实际执行的 SQL
/**
* 获取预编译SQL的执行SQL语句
* @param string $sql 预编译SQL
* @param array $params 参数
* @return string 执行SQL语句
*/
function getExecutedSQL(string $sql, array $params): string
{
$keys = array_map(function ($k) {
return is_string($k) ? '/:' . $k . '/' : '/[?]/';
}, array_keys($params));
return preg_replace($keys, $params, $sql, 1);
}
$sql = "INSERT into test(`name`,`age`) values (:name,:age) ";
$params = ['name' => 'aa', 'age' => 2];
var_dump(getExecutedSQL($sql, $params)); //INSERT into test(`name`,`age`) values (aa,2)
$sql = "INSERT into test(`name`,`age`) values (?,?) ";
$params = ['aa', 2];
var_dump(getExecutedSQL($sql, $params));//INSERT into test(`name`,`age`) values (aa,2)
生成 EXCEL 的列名
function generateExcelColumns(int $count): array
{
if ($count < 1) {
return [];
}
$columns = [];
for ($i = 1; $i <= $count; $i++) {
$columnName = '';
$number = $i;
while ($number > 0) {
$modulo = ($number - 1) % 26;
$columnName = chr(65 + $modulo) . $columnName;
$number = (int)(($number - $modulo) / 26);
}
$columns[] = $columnName;
}
return $columns;
}
print_r(json_encode(generateExcelColumns(30)));
// ["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","AA","AB","AC","AD"]
记录日志
function writeLog(array $params): void
{
$msg = array_pop($params);
array_unshift($params, date('Y-m-d H:i:s'));
$params = array_map(function ($val) {
return '[' . $val . ']';
}, $params);
array_push($params, $msg);
$msg = array_reduce($params, function ($carry, $val) use ($params) {
return $carry . $val;
}, '');
file_put_contents('sys.log', $msg . "\r\n", FILE_APPEND);
}
$params = ['INFO', 'new order'];
writeLog($params);
$params = ['USER', '123456', 'new'];
writeLog($params);
文件强制下载
function echoFile(string $filePath)
{
$finfo = finfo_open(FILEINFO_MIME_TYPE); // FILEINFO_MIME_TYPE 用于获取MIME类型
$mimeType = finfo_file($finfo, $filePath);
finfo_close($finfo);
if (file_exists($filePath)) {
header('Content-Description: File Transfer');
header('Content-Type: ' . $mimeType);
header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);
exit;
} else {
header('HTTP/1.0 404 Not Found');
}
}
将 PHP 数组优雅地写入文件
/**
* 将PHP数组优雅地写入文件,保持完美格式
*/
class ArrayWriter
{
const INDENT = ' '; // 4空格缩进
public static function writeToFile(string $filename, array $data): string
{
$content = "<?php\nreturn [\n";
$content .= self::formatArray($data, 1);
$content .= "\n];";
file_put_contents($filename, $content);
return "数组已写入 {$filename}";
}
private static function formatArray(array $array, int $depth): string
{
$indent = str_repeat(self::INDENT, $depth);
$lines = [];
foreach ($array as $key => $value) {
$line = $indent;
// 处理键名
if (!is_int($key)) {
$line .= is_string($key) ? "'{$key}' => " : "{$key} => ";
}
// 处理值
if (is_array($value)) {
$line .= "[\n" . self::formatArray($value, $depth + 1) . "\n{$indent}]";
} elseif (is_string($value)) {
$line .= "'" . str_replace("'", "\\'", $value) . "'";
} elseif (is_bool($value)) {
$line .= $value ? 'true' : 'false';
} elseif (is_null($value)) {
$line .= 'null';
} else {
$line .= $value;
}
$lines[] = $line;
}
return implode(",\n", $lines);
}
}