ThinkPHP常用方法
对称加密
对称加密可以用来把登录用户的 id 和 name 等少数信息http_build_query成一个字符串加密后放入 cookie 中。
public function encryptString($content, $key)
{
return openssl_encrypt($content, 'AES-128-ECB', $key);
}
public function decryptString($content, $key)
{
return openssl_decrypt($content, 'AES-128-ECB', $key);
}
调用
//待加密字符串
$queryString = 'id=1&name=John+Doe&age=22&city=%E5%8D%8E%E7%9B%9B%E9%A1%BF';
//加密
$encStr = openssl_encrypt($queryString, 'AES-128-ECB', 'key123');
echo $encStr . PHP_EOL;
//解密
$deStr = openssl_decrypt($encStr, 'AES-128-ECB', 'key123');
echo $deStr . PHP_EOL;
http_build_query & parse_str
http_build_query 将该数组或对象转换成一个经过 URL 编码的查询字符串。
parse_str 将查询字符串转换成数组或对象。
$data = array(
'name' => 'John Doe',
'age' => 22,
'city' => 'New York'
);
//将数组转换为url的查询部分
$queryString = http_build_query($data);
echo $queryString . PHP_EOL;
//将 ur拼接字符串 转换成数组
parse_str($queryString, $res);
print_r($res);
执行后返回
Cookie对象
// 在 cookie 中设置 access_token 值
Cookie::set('access_token', $accessToken, Config::get('app.default_logout_time'));
// 从 cookie 中获取accessToken
$accessToken = Cookie::get('access_token');
DB 链式调用
Db 对象链式调用查询数据。
$whereMap = [];
if (!empty($name)) $whereMap[] = ['name', 'like', "%{$name}%"];
$list = Db::name('table1')
->alias("a")
->field("a.*,c.col2")
->where($where)
->join("table2 c", "a.col1 = c.id", "left")
->order(["create_time" => "desc"])
->paginate($param["limit"], false, [$param["page"]]);
-
table / name
table 方法用于指定要操作的数据库表全名(包括表前缀)。例如:Db::table('think_user')。
name 方法用于指定要操作的数据库表名,不包括表前缀。ThinkPHP 会自动添加前缀。例如:Db::name('user')。 -
where
用于构造查询条件,可以接受数组、字符串等多种参数形式。例如:
->where('id', 1):id 等于 1。
->where(['id' => 1, 'name' => 'Tom']):id 等于 1 且 name 等于 Tom。 -
field
用于指定需要查询的字段,可以是字符串或数组。例如:
->field('id, name'):只查询 id 和 name 字段。
->field(['id', 'name']):效果同上。 -
order
用于指定查询结果的排序方式。例如:
->order('id desc'):根据 id 降序排序。
->order(['id' => 'desc', 'name' => 'asc']):先按 id 降序,然后按 name 升序。 -
limit / page
limit 方法用于限制查询结果的数量。例如:->limit(10) 或 ->limit(10, 20)(从第 10 条开始的 20 条记录)。
page 方法用于分页查询,第一个参数是页数,第二个参数是每页的数量。例如:->page(2, 10)。 -
group
用于通过一个或多个列对结果集进行分组。例如:->group('user_id')。 -
having
用于配合 group 方法,对分组后的结果进行过滤。例如:->having('COUNT(user_id) > 1')。 -
join
用于执行 JOIN 操作。可以是字符串或数组,还可以指定 JOIN 类型。例如:
->join('think_profile p', 'p.user_id=user.id'):默认 INNER JOIN。
->join(['think_profile' => 'p'], 'p.user_id=user.id', 'LEFT'):LEFT JOIN。 -
alias
用于给当前表设置别名,便于在复杂查询中引用。例如:->alias('u')。 -
distinct
用于返回唯一不同的值。例如:->distinct(true)->field('user_id')。 -
count / max / min / avg / sum
这些方法用于执行聚合查询:
count:计算总记录数。例如:->where('status', 1)->count()。
max:计算最大值。例如:->max('price')。
min:计算最小值。例如:->min('price')。
avg:计算平均值。例如:->avg('score')。
sum:计算总和。例如:->sum('amount')。
PHP
将字符串分割成数组
//将$str字符串用,分割成数组
$arr = explode(',', $str);
通过引用访问数组元素
这是foreach循环的控制结构。$data是要遍历的数组或对象,而&$item表示数组或对象中的每个元素的引用。
&符号表示引用。这意味着$item变量将直接引用数组或对象中的元素,而不是复制其值。这样,如果在循环内部修改$item的值,那么原始数组或对象中对应的元素也会被修改。
foreach ($data as &$item)
将单个列表重构为树形结构
/**
* 递归将列表重构为树形结构
* @param array $elements 列表数组
* @param $parentId 父id,不传默认为 0
* @return array
*/
function buildTree(array $elements, $parentId = 0) {
$branch = array();
foreach ($elements as $element) {
//第一次循环找pid 为 0 的元素
if ($element['parent_id'] == $parentId) {
//如果找到了,则把当前元素的id作为父级id传下去.并返回子节点的树形结构
$children = buildTree($elements, $element['id']);
if ($children) { //如果查找的父级 id 有数据,则把子树形结构数据赋值给当前节点的children
$element['children'] = $children;
}
$branch[] = $element;
}
}
return $branch;
}
//测试列表结构重构为树形结构
$items = [
['id' => 1, 'parent_id' => 0, 'name' => 'Item 1'],
['id' => 2, 'parent_id' => 1, 'name' => 'Item 1.1'],
['id' => 3, 'parent_id' => 1, 'name' => 'Item 1.2'],
['id' => 4, 'parent_id' => 2, 'name' => 'Item 1.1.1'],
// 更多元素...
];
//首次不传$parentId默认为 0
$tree = buildTree($items);
print_r($tree);
将单个列表重构为树形结构-递归带深度
/**
* 递归将列表重构为树形结构
* @param array $elements 列表数组
* @param $parentId 父id,不传默认为 0
* @return array
*/
function buildTree(array $elements, $parentId = 0, $depth = 1) {
$branch = [];
foreach ($elements as $element) {
if ($element['parent_id'] == $parentId) {
if ($depth > 0) {
$children = buildTree($elements, $element['id'], $depth - 1);
if ($children) {
$element['children'] = $children;
}
}
$branch[] = $element;
}
}
return $branch;
}
//测试列表结构重构为树形结构
$items = [
['id' => 1, 'parent_id' => 0, 'name' => 'Item 1'],
['id' => 2, 'parent_id' => 1, 'name' => 'Item 1.1'],
['id' => 3, 'parent_id' => 1, 'name' => 'Item 1.2'],
['id' => 4, 'parent_id' => 2, 'name' => 'Item 1.1.1'],
// 更多元素...
];
//首次不传$parentId默认为 0
$tree = buildTree($items,0,1);
print_r($tree);
将多个列表重构为树形结构(ptype为父节点的type)
/**
* 构建多级树形结构
* @param $data 列表数据: id type pid ptype构成
* @param $parentId 父ID
* @param $parentType 父类型 加这个字段是因为树形结构的集合来源于多个表,id可能重复
* @return array
*/
public static function buildTreeForIbe(&$data, $parentId = 0, $parentType = null) {
$tree = [];
foreach ($data as $key => $item) {
if ($item['pid'] == $parentId && $item['ptype'] == $parentType) {
//这里可以优化,当item为叶子节点时可以不走递归函数
$item['children'] = TreeUtil::buildTreeForIbe($data, $item['id'], $item['type']);
$tree[] = $item;
unset($data[$key]); // 从数据中移除已经处理过的节点,提高效率,下次遍历时可以少一个
}
}
return $tree;
}
将多个列表重构为树形结构(只有type确定层级,无ptype字段组合关联)
/**
* 构建树形结构
* @param $items
* @return array
*/
function buildTree($items,$rootId) {
$indexedItems = [];
$tree = [];
// 预处理,将元素按 type 和 id 索引
foreach ($items as &$item) {
$item['children'] = [];
$indexedItems[$item['type']][$item['id']] = &$item;
}
// 建立父子关系
foreach ($items as &$item) {
if ($item['type'] != 'level0') { // 不是顶级元素时,type 为 level0 时表示顶级元素
// 根据 type 确定父级 type
switch ($item['type']) {
case 'level1':
$parentType = 'level0';
break;
case 'level2':
$parentType = 'level1';
break;
case 'level3':
$parentType = 'level2';
break;
default:
$parentType = null;
}
if ($parentType && isset($indexedItems[$parentType][$item['pid']])) {
$indexedItems[$parentType][$item['pid']]['children'][] = &$item;
}
} elseif ($item['type'] == 'level0' && $item['pid'] == $rootId) { // 顶级元素
$tree[] = &$item;
}
}
return $tree;
}
//将四个自增id的列表合并成一个,并且用type区分上下级
$allItems = array_merge($level0List, $level1List, $level2List, $level3List);
// 构建树形结构
$tree = $this->buildTree($allItems,$cityId);
树形结构去重
/**
* 树形结构去重
* @param $nodes 待去重的节点
* @param $processedNodes 已处理的节点集合,key为节点的id
* @return array
*/
public static function removeTreeDuplicates($nodes, &$processedNodes = [])
{
$uniqueNodes = [];
//遍历节点
foreach ($nodes as $node) {
//如果节点没被处理则处理,已经处理过,则跳过
if (!isset($processedNodes[$node['id']])) {
//设置节点为已处理
$processedNodes[$node['id']] = true;
//递归处理子节点
if (!empty($node['children'])) {
$node['children'] = self::removeTreeDuplicates($node['children'], $processedNodes);
}
$uniqueNodes[] = $node;
}
}
return $uniqueNodes;
}
发送URL请求工具类
class CurlUtil
{
// 发送GET请求
public static function get($url)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
$response = curl_exec($curl);
if ($response === false) {
$error = curl_error($curl);
curl_close($curl);
throw new Exception("cURL GET请求错误: {$error}");
}
curl_close($curl);
return $response;
}
// 发送POST请求
public static function post($url, $data, $isJson = false)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
if ($isJson) {
$data = json_encode($data);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
}
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($curl);
if ($response === false) {
$error = curl_error($curl);
curl_close($curl);
throw new Exception("cURL POST请求错误: {$error}");
}
curl_close($curl);
return $response;
}
}
/**请求实例*/
try {
/**Get请求*/
$response = CurlUtil::get('https://www.baidu.com');
echo $response;
/**Post请求*/
$postData = ['key' => 'value'];
$response = CurlUtil::post('http://example.com/post', $postData);
echo $response;
/**Json请求*/
$jsonPostData = ['key' => 'value'];
$response = CurlUtil::post('http://example.com/postjson', $jsonPostData, true);
echo $response;
} catch (Exception $e) {
echo $e->getMessage();
}
逗号分隔字符串
// 你的逗号分隔的字符串
$string = "苹果,香蕉,橙子,西瓜";
// 使用explode函数分割字符串
$array = explode(",", $string);
// 使用foreach遍历数组
foreach ($array as $item) {
echo $item . "\n"; // 打印每个元素
}
十六进制数据解析
class HexUtil
{
/**
* 十六进制字符串转int数组
* 这里使用int存储, 因为PHP中没有short类型, int可以存储0~255的范围
* @param string $hexStr 十六进制字符串, 例如: 010A0FFE
* @return array 返回的int数组, 例如[1, 10, 15, 254]
*/
public static function hexStrToByteArray(string $hexStr) {
// 存储转换后的整数数组
$byteArray = [];
// 计算数组长度, 每两位16进制为一个元素
$len = strlen($hexStr) / 2;
// 遍历16进制字符串
for ($i = 0; $i < $len; $i++) {
// 每次取两个16进制数据转换
$index = $i * 2;
$hexEle = substr($hexStr, $index, 2);
$b = hexdec($hexEle); // 将16进制字符串转换为整数
$byteArray[] = $b;
}
return $byteArray;
}
/**
* 将字节数组转换为十六进制字符串
*
* @param array $byteArr 字节数组,包含原始的二进制数据
* @param int $start 起始索引,表示从字节数组的哪个位置开始转换
* @param int $end 结束索引,表示字节数组转换到哪个位置结束
*
* @return string 转换后的十六进制字符串,每个字节用两个十六进制字符表示
*/
private function byteArrToHexStr($byteArr, $start, $end)
{
$result = '';
for ($i = $start; $i <= $end; $i++) {
$result .= sprintf("%02X", $byteArr[$i]);
}
return $result;
}
/**
* 将指定几个字节解析成一个数值
* @param array $bytes 字节数组
* @param int $start 起始位置(高位)
* @param int $end 结束位置(低位)
* @return int
* @throws InvalidArgumentException
*/
public static function mergeBytesToInt(array $bytes, int $start, int $end) {
if ($start < 0 || $end >= count($bytes) || $start > $end) {
throw new InvalidArgumentException("起始位置或结束位置不合法");
}
$mergedValue = 0;
for ($i = $start; $i <= $end; $i++) {
// 将字节转换为无符号整数并左移相应的位数,然后通过位或操作合并
$mergedValue |= ($bytes[$i] & 0xFF) << (8 * ($end - $i));
}
return $mergedValue;
}
}
Thinkphp6
m-n中间表操作
例如给用户分配角色时,先把该用户的所有角色关系记录删除,在insert新的记录
namespace app\model;
use think\Model;
class UserAreaModel extends Model
{
protected $name = 'user_area';
/**
* 给用户设置区域
* $userId: 用户
* $areaIds: 逗号分隔的区域
* @return void
*/
public static function setAreaIdForUser($userId,$areaIds){
// Step 1: 删除现有用户拥有的area记录
try {
UserAreaModel::where('userid', $userId)->delete();
// Step 2: 遍历并插入新记录
$areaIdList = explode(',', $areaIds); // 将逗号分隔的字符串转为数组
$data = array_map(function ($areaId) use ($userId) {
return ['userid' => $userId, 'areaid' => intval($areaId)]; // 确保areaid是整型
}, $areaIdList);
UserAreaModel::insertAll($data); // 批量插入user-area关联数据数据
} catch (\Exception $e) {
echo $e->getMessage();
return; // 出错则退出函数
}
}
}
PHP调试
dd()函数
dd通常代表 "dump and die"。这个函数的目的是打印出一个或多个变量的信息,并且终止脚本的执行。使用 dd() 函数时,它会展示变量的详细信息,如类型、值等,并且在展示完信息后,脚本会立即停止执行,这有助于调试过程中快速定位问题。
dd函数并不是ThinkPHP框架中的标准函数。dd(Dump and Die)函数通常在 Laravel 框架中使用,用于调试目的,它会输出变量的内容并终止脚本执行。如果你在 ThinkPHP 中需要类似 dd 的功能,你可能需要自定义一个函数或使用 halt、dump 加上 exit/die 的组合来实现类似的效果。
halt()函数
输出变量或错误信息,并终止程序执行.
调用 halt 函数时,它会立即停止程序的执行,并输出你指定的信息,这可以帮助你在开发过程中快速定位和理解代码执行的状态或遇到的错误。
var_export打印数组
打印数组可以使用print_r函数也可以使用var_export打印字典样式数组.
$jsonString = '{"id":"1","name":"autumn"}';
//将JSON字符串转换为PHP关联数组,true时,函数会将JSON对象转换为PHP的关联数组(即字典样式的数组)。false或省略,json_decode会将JSON对象转换为PHP对象。
$array = json_decode($jsonString, true);
//使用 var_export 打印数组,并确保第二个参数为 true,函数会返回字符串而不是直接输出
echo var_export($array, true).PHP_EOL;

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步