【干货合集】PHP技巧收集

用户密码加密存储与校验(bcrypt)

PHP原生提供了密码校验套件,password_hash、password_hash 函数。

查看当前支持那些password hash算法。

<?php
print_r( password_algos());//打印password_hash()支持的算法
/*Array
(
    [0] => 2y //常量: PASSWORD_BCRYPT,PASSWORD_DEFAULT(当前)
    [1] => argon2i //常量: PASSWORD_ARGON2I
    [2] => argon2id //常量: PASSWORD_ARGON2ID
)*/
?>

默认算法(目前是 bcrypt),PASSWORD_DEFAULT(=”2y”)

<?php
$password="123";
$hash_bcrypt= password_hash($password, PASSWORD_DEFAULT);
echo $hash_bcrypt;
//$2y$10$lqIW4KIBR6ZBF2wHYzDY7ez9dL4DemosVLH6ZcY/RYWzINJaq3rli
//默认时,工作因子cost会默认取10。
var_dump(password_verify('123',$hash_bcrypt));
//bool(true)
?>

bcrypt 算法,PASSWORD_BCRYPT(=”2y”)。

<?php
$password="123";
$hash_bcrypt=password_hash($password,PASSWORD_BCRYPT,['cost'=>rand(4,31)]);//默认cost=10
echo $hash_bcrypt;
//$2y$12$A0fTxKgT14PZM4m391bM8.UoYxdzk0H2AiA8uqyo3FxtIWAk32fzu
/*
$2y$ 表示哈希算法,他是一种bcrypt实现版本。
12$ 表示工作因子(cost factor),表示 2 的幂次,值越大计算时间越长。这里表示 2^12 次迭代。
A0fTxKgT14PZM4m391bM8.,这是 22 个字符的 Base64 编码的盐值(salt)。
UoYxdzk0H2AiA8uqyo3FxtIWAk32fzu,这是实际的哈希值部分,也是 31 个字符的 Base64 编码。
*/
var_dump(password_verify('123',$hash_bcrypt));
//bool(true)

大文件下载(不加载到php内存的)

readfile 函数,可以直接读取文件并将其输出到浏览器,而不会将整个文件加载到内存中。它非常适合用于下载大文件。

<?php
// 文件路径
$file_path = '/path/to/large-file.zip';

// 检查文件是否存在
if (!file_exists($file_path)) {
    die('文件不存在');
}

// 设置适当的 HTTP 头信息
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file_path) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_path));

// 禁用输出缓冲,确保数据立即发送到客户端
ob_end_clean();

// 使用 readfile 直接读取并输出文件
readfile($file_path);

// 确保脚本在此处终止
exit;
?>

fpassthru 函数可以从文件指针中读取数据并直接输出到浏览器,类似于 readfile,但它允许你更灵活地控制文件的读取过程。

<?php
// 文件路径
$file_path = '/path/to/large-file.zip';

// 检查文件是否存在
if (!file_exists($file_path)) {
    die('文件不存在');
}

// 设置适当的 HTTP 头信息
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($file_path) . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file_path));

// 打开文件
$file = fopen($file_path, 'rb');

// 禁用输出缓冲,确保数据立即发送到客户端
ob_end_clean();

// 使用 fpassthru 从文件指针中读取并输出数据
fpassthru($file);

// 关闭文件
fclose($file);

// 确保脚本在此处终止
exit;
?>
获取每次请求都不会重复的超短字符串

时间戳 + Base36 编码

Base36 编码可以将数字转换为更短的字符串,同时保持唯一性。因此可以将时间戳和一个随机数组合后进行 Base36 编码。

<?php
function generateUniqueKeyBase36() {
    // 获取当前时间戳(毫秒)
    $timestamp = round(microtime(true) * 1000);
    // 生成一个4位随机数(0-9999)
    $randomNumber = random_int(0, 9999);
    // 组合成一个较大的数字
    $combined = $timestamp * 10000 + $randomNumber;
    // 将其转换为 Base36 编码
    return base_convert($combined, 10, 36);
}

// 示例输出:一个较短的唯一字符串
echo generateUniqueKeyBase36();
//h2v6rayd7o

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注