用户密码加密存储与校验(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