PHP会话技术
第十六章-PHP会话技术
PHP会话技术是构建动态、个性化Web应用的核心机制之一,它通过跟踪用户在网站上的连续操作状态,实现了网页间的数据持久化交互。无论是电商平台的购物车信息保存、社交媒体的用户登录状态维持,还是表单数据的跨页面传递,会话技术都发挥着不可替代的作用。在PHP中,开发者主要通过Cookie和Session两种方式实现会话管理:前者通过客户端存储键值数据完成轻量级状态跟踪,后者则借助服务器端存储与唯一会话ID的配合,为敏感信息提供更安全的解决方案。理解PHP会话技术的工作原理,不仅能优化用户体验,更是保障Web应用安全性的重要基石。
一,初步认识会话技术
初步认识会话技术:让网页“记住”用户的关键
当我们浏览网页时,每一次点击链接、提交表单或登录账户,本质上都是通过HTTP协议向服务器发送请求并接收响应。然而,HTTP协议本身是无状态的——服务器不会自动记录用户之前的操作,就像服务员每次接待顾客都当作陌生人一样。这种机制虽然保证了高效性,却无法满足现代Web应用对连续性交互的需求。例如,用户登录后如何在所有页面保持身份?电商购物车如何跨页面保存商品?这些问题都需要通过会话技术来解决。
会话技术的核心目标
会话技术的本质是在无状态的HTTP协议上实现有状态的交互。它通过某种方式让服务器或客户端能够“记住”用户在一段时间内的操作轨迹,从而提供连贯的个性化体验。常见的应用场景包括:
- 用户身份保持:登录状态无需重复验证
- 数据跨页传递:如多步骤表单的分页填写
- 行为追踪:记录用户浏览路径或偏好设置
两种主流实现方式
PHP中主要依赖两种互补的会话技术,共同构建完整的用户跟踪体系:
- Cookie:客户端的记忆便签
- 服务器通过HTTP响应头向浏览器发送键值对数据(如
Set-Cookie: user=Alice;
) - 浏览器会将这些数据存储在本地,后续每次访问同一域时自动回传
- 典型应用:记住登录状态、保存用户主题偏好等
- 服务器通过HTTP响应头向浏览器发送键值对数据(如
- Session:服务器的保险箱
- 在服务器端创建存储空间(如文件或数据库),每个用户拥有唯一会话ID
- 通过Cookie或URL参数将会话ID与客户端绑定
- 敏感数据(如购物车详情、临时验证码)安全存储在服务端
- 典型应用:金融操作验证、多步骤流程数据暂存
技术选型的关键考量
- 安全性:Cookie易被篡改,适合非敏感数据;Session数据存于服务端更安全
- 存储限制:Cookie有4KB大小限制,Session理论上无上限
- 生命周期:Cookie可设置长期留存,Session通常随浏览器关闭失效
- 性能影响:高频访问的Session数据需考虑服务器存储压力
理解会话技术,就像掌握网站的“记忆魔法”——它让冷冰冰的协议具备了“人性化”的交互能力。无论是简单的页面偏好记忆,还是复杂的多步骤事务处理,会话管理都在背后默默支撑着现代Web的流畅体验。对于开发者而言,合理选择Cookie与Session的组合策略,既能保障功能实现,也是构建安全可靠系统的必修课。
二,Cookie技术使用
一、设置Cookie
使用setcookie()
函数向客户端发送Cookie,必须在输出HTML内容前调用:
// 基础设置(名称+值)
setcookie("username", "JohnDoe");// 完整参数设置(有效期7天,作用域全站,HTTPS传输,防JS访问)
setcookie("theme", // Cookie名称"dark", // 值time() + 604800, // 过期时间戳(当前时间+7天)"/", // 作用路径(全站)".example.com", // 作用域名(包括子域名)true, // 仅通过HTTPS传输true // 禁止JavaScript访问(HttpOnly)
);
二、读取Cookie
通过$_COOKIE
超全局数组获取已存储的值,务必先验证存在性:
if(isset($_COOKIE["username"])) {$username = htmlspecialchars($_COOKIE["username"]); // 防XSSecho "欢迎回来, $username!";
} else {echo "首次访问用户";
}
三、删除Cookie
通过设置过期时间为过去时间触发浏览器删除:
// 删除时必须匹配原始设置路径/域名
setcookie("theme", "", time() - 3600, "/", ".example.com");
关键参数解析
参数 | 说明 | 示例值 |
---|---|---|
过期时间 | UNIX时间戳格式,0 表示会话Cookie(关闭浏览器失效) | time() + 86400*30 |
作用路径 | 指定哪些URL路径可访问Cookie,/ 表示全站 | /admin |
作用域名 | 允许子域名共享需设为.example.com 形式 | .yourdomain.com |
Secure | true 时仅通过HTTPS传输 | 需SSL环境启用 |
HttpOnly | true 时禁止JavaScript读取,防范XSS攻击 | 建议敏感Cookie始终启用 |
安全使用准则
-
敏感数据避坑
避免存储密码、身份令牌等敏感信息,必要时加密存储(如password_hash()
) -
防御会话劫持
为重要Cookie添加SameSite=Strict
属性(PHP 7.3+):setcookie("session_id", $token, ['expires' => time() + 3600,'samesite' => 'Strict' ]);
-
容量限制
单个Cookie不超过4KB,同一域名下通常最多允许50个Cookie
典型应用场景
-
用户偏好记忆
保存语言选择、主题颜色等非敏感设置setcookie("lang", "zh-CN", time() + 31536000); // 保存一年
-
登录状态保持
配合Session实现"记住我"功能(存储加密后的用户ID)$token = bin2hex(random_bytes(32)); // 生成随机令牌 setcookie("remember_token", $token, time() + 2592000, "/", "", true, true);
-
行为追踪
记录用户首次访问时间、浏览历史(需符合隐私政策)if(!isset($_COOKIE["first_visit"])) {setcookie("first_visit", date("Y-m-d H:i:s"), time() + 31536000); }
调试技巧
-
浏览器检查
按F12打开开发者工具 → Application → Cookies,实时查看存储状态 -
PHP输出检测
使用headers_list()
函数检查是否成功发送Set-Cookie头print_r(headers_list()); // 查看所有响应头
-
过期时间转换
使用date()
函数验证时间戳是否正确:echo date("Y-m-d H:i:s", time() + 604800); // 显示7天后的日期
三,Cookie管理四要素
一、Cookie 生命周期管理
Cookie 的有效期由 expires
参数精确控制,时间管理是会话状态跟踪的核心。
-
临时会话 Cookie
不设置expires
或设为0
,浏览器关闭即失效:setcookie("session_temp", "data"); // 会话级 Cookie
-
持久化 Cookie
使用明确的时间戳设置过期时间,支持长期存储:$expire = time() + 86400 * 30; // 30天后过期 setcookie("remember_me", "user123", $expire);
-
时间计算技巧
时间段 计算公式 示例值 15分钟 time() + 900
适合短期验证码 7天 time() + 7*86400
用户偏好设置 1年 time() + 365*86400
长期登录令牌 -
强制过期删除
通过设置过去时间戳触发浏览器删除:setcookie("old_cookie", "", time() - 3600, "/");
二、作用范围精准控制
通过 path
和 domain
参数实现细粒度访问控制。
-
路径限制 (
path
)
控制哪些 URL 路径可访问 Cookie:// 仅允许 /admin 路径访问 setcookie("admin_token", "xyz", 0, "/admin/");
/
:全站可访问(默认值)/api/
:仅 API 接口可用
-
域名作用域 (
domain
)-
精确域名:仅限指定域名
setcookie("site_data", "val", 0, "/", "www.example.com");
-
跨子域共享:使用
.
前缀setcookie("global_id", "123", 0, "/", ".example.com"); // 支持 www.example.com、api.example.com 等子域
-
-
跨域限制
- 默认遵循 同源策略,不同顶级域名无法共享
- 需通过 CORS 或 JSONP 实现跨域传递(需服务端配合)
三、跨子域实战方案
以多子域系统(如 shop.example.com
和 user.example.com
)为例:
-
统一认证系统
// 认证服务器设置 setcookie("auth_token", $token, ['expires' => time() + 3600,'path' => '/','domain' => '.example.com', // 关键点'secure' => true,'httponly' => true ]);
-
子域间数据同步
// 在 user.example.com 读取 Cookie if(isset($_COOKIE["auth_token"])){// 所有子域均可获取该 Cookie }
-
安全注意事项
- 仅限信任子域使用
.example.com
- 敏感 Cookie 必须启用
Secure
+HttpOnly
- 仅限信任子域使用
四、数组/对象数据存储
Cookie 本身仅支持字符串存储,结构化数据需编码处理。
-
JSON 序列化方案
// 存储数组 $cart = ['product_id' => 1001, 'qty' => 3]; setcookie("cart_data", json_encode($cart), time() + 3600);// 读取时解码 $cart = json_decode($_COOKIE["cart_data"], true);
-
Base64 安全编码
防御特殊字符问题:$data = base64_encode(serialize($userPrefs)); setcookie("prefs", $data);// 解码 $userPrefs = unserialize(base64_decode($_COOKIE["prefs"]));
-
存储限制与优化
数据类型 推荐方案 优势 小型配置数据 JSON 序列化 易读易解析 敏感复杂数据 服务端存储 + Cookie ID 避免数据泄露 高频访问数据 客户端缓存 + Cookie 标记 减少服务端压力
五、浏览器行为差异
不同浏览器对 Cookie 的处理存在细微差别:
浏览器 | 最大Cookie数/域名 | 单Cookie大小限制 | SameSite 默认值 |
---|---|---|---|
Chrome | 180 | 4KB | Lax (2020+) |
Firefox | 150 | 4KB | Lax |
Safari | 无明确限制 | 4KB | Strict |
六、安全与性能平衡实践
-
敏感数据存储原则
- 绝不存储:密码、信用卡号
- 加密存储:用户 ID →
"user_id" => encrypt(123, $secretKey)
- 签名校验:存储值附带 HMAC 签名
-
性能优化技巧
- 合并多个小 Cookie 为单个 JSON 对象
- 静态资源域名禁用 Cookie(CDN 域名分离)
// 图片服务器不使用 Cookie <img src="https://static.example.com/logo.png">
总结:Cookie 管理四要素
要素 | 关键配置项 | 典型值示例 |
---|---|---|
生命周期 | expires | time() + 86400*30 |
作用路径 | path | /api |
跨域能力 | domain + samesite | .example.com + Lax |
数据安全 | secure + httponly | true + true |
四,PHP Cookie 高级特性
Cookie 不仅是简单的键值存储,其高级特性可解决复杂场景下的状态管理、安全防护与性能优化问题。以下深度解析 PHP 中 Cookie 的进阶用法,配合 安全策略 与 实战场景,助您构建更健壮的 Web 应用。
一、安全增强特性
1. SameSite 防御 CSRF
PHP 7.3+ 支持直接设置 SameSite
属性,控制跨站请求是否携带 Cookie:
setcookie('auth_token', $token, ['expires' => time() + 3600,'samesite' => 'Strict', // 严格模式:仅同站请求携带'secure' => true, // 强制 HTTPS'httponly' => true // 禁止 JS 访问
]);
Lax
(默认):导航类请求(如链接跳转)携带 CookieStrict
:仅同源请求携带,防御 CSRF 但可能破坏第三方登录None
:允许跨站携带(需同时设置Secure
)
2. 前缀加固机制
通过 Cookie 前缀
声明 Cookie 的安全属性(Chrome 51+ 支持):
// 设置 __Host- 前缀的 Cookie(强制 Secure/Path=/ 且禁止指定 Domain)
setcookie('__Host-secure_id', 'value', ['expires' => time() + 86400,'secure' => true,'path' => '/'
]);
__Host-
:全站强制安全 Cookie__Secure-
:需启用 Secure 标志的 Cookie
3. 签名防篡改
对 Cookie 值进行 HMAC 签名,防止客户端篡改:
$secret = 'your-secret-key';
$value = 'user123';
$signature = hash_hmac('sha256', $value, $secret);
setcookie('user', $value . '|' . $signature, ['httponly' => true]);// 验证时拆分并校验签名
list($storedValue, $storedSig) = explode('|', $_COOKIE['user'], 2);
if (hash_hmac('sha256', $storedValue, $secret) === $storedSig) {// 数据未被篡改
}
二、跨域与子域共享
1. 跨子域共享 Cookie
通过设置 Domain
参数实现多子域共享(如 shop.example.com
与 blog.example.com
):
setcookie('global_pref', 'dark', ['expires' => time() + 604800,'domain' => '.example.com', // 注意开头的点号'path' => '/'
]);
2. 跨域单点登录 (SSO)
结合 OAuth 2.0 与 CORS 实现跨域认证(需服务端协作):
// 认证服务器设置 Cookie 后,通过 iframe 或 JS 同步到其他域
header('Access-Control-Allow-Origin: https://client-app.com');
header('Access-Control-Allow-Credentials: true');
setcookie('sso_token', $token, ['domain' => '.sso-provider.net','secure' => true,'samesite' => 'None'
]);
三、性能优化策略
1. Cookie 压缩
对 JSON 等结构化数据进行编码压缩:
$data = ['theme' => 'dark', 'font' => '16px'];
$compressed = base64_encode(gzencode(json_encode($data)));
setcookie('user_prefs', $compressed);// 读取时解压
$data = json_decode(gzdecode(base64_decode($_COOKIE['user_prefs'])), true);
2. 分布式存储
大体积数据使用 Cookie 存储索引 ID,实际数据存于服务端:
// 存储到 Redis
$cartId = uniqid('cart_');
$redis->set($cartId, json_encode($cartData));
setcookie('cart_id', $cartId, ['httponly' => true]);// 读取时通过 ID 获取数据
$cartData = $redis->get($_COOKIE['cart_id']);
3. CDN 边缘 Cookie
与 CDN 服务协作缓存动态内容(需配置 Vary: Cookie 头):
header('Vary: Cookie'); // 告知 CDN 根据 Cookie 区分缓存版本
if (isset($_COOKIE['geo_region'])) {// 返回基于地区定制的内容
}
四、监控与调试
1. 浏览器端监控
通过 JavaScript 监听 Cookie 变化(需非 HttpOnly Cookie):
// 前端代码:监听指定 Cookie 变化
let lastCookie = document.cookie;
setInterval(() => {if (document.cookie !== lastCookie) {console.log('Cookie changed:', document.cookie);lastCookie = document.cookie;}
}, 1000);
2. 服务端日志分析
记录 Cookie 使用情况用于审计:
// 记录敏感 Cookie 的访问日志
if (isset($_COOKIE['auth_token'])) {error_log("Auth token used: " . $_SERVER['REMOTE_ADDR'] . ' at ' . date('Y-m-d H:i:s'));
}
五、前沿技术整合
1. Cookie 与 JWT 协同
混合使用 Cookie 存储 JWT 的刷新令牌:
// 生成 JWT 双令牌体系
$accessToken = generateJWT($user, '15m'); // 短期令牌存 Session
$refreshToken = generateJWT($user, '7d'); // 长期令牌存 Cookie
setcookie('refresh_token', $refreshToken, ['expires' => time() + 604800,'httponly' => true,'samesite' => 'Strict'
]);
2. WebAssembly 加密
使用 WASM 实现前端加密后再存储至 Cookie:
// 前端通过 WebAssembly 加密数据
// PHP 服务端解密
$encryptedData = $_COOKIE['secure_data'];
$iv = substr($encryptedData, 0, 16);
$cipherText = substr($encryptedData, 16);
$decrypted = openssl_decrypt($cipherText, 'aes-256-cbc', $key, 0, $iv);
六,PHP Session 技术
一、Session 核心原理
1. Session 的本质
Session 是服务器在内存或其他存储介质中为每个用户创建的一块存储空间,用于保存用户状态。
2. Session 标识:Session ID
- 每次用户访问服务器时,服务器会生成一个唯一的 Session ID(通常是一个随机字符串)。
- 这个 ID 会通过客户端浏览器返回并保存,通常放在 Cookie 中,也可以通过 URL 参数等方式传递。
3. 流程原理
[1] 客户端首次访问服务器↓
[2] 服务器生成 Session 对象(内存中保存一份)和唯一 Session ID↓
[3] Session ID 通过 Set-Cookie 返回给客户端↓
[4] 客户端下次请求时通过 Cookie 自动携带 Session ID↓
[5] 服务器接收 Session ID,查找对应的 Session 数据,恢复用户状态
4. Session 存储位置
- 默认:服务器内存中(如 Python Flask、PHP 原生等)
- 可扩展为:
- Redis(分布式高可用)
- 数据库(如 MySQL)
- 文件系统
5. Session 生命周期
- 默认是临时会话:浏览器关闭后 Cookie(及 Session ID)消失
- 可设置有效期(如 30 分钟、7 天)
- 服务端也会设置过期时间(
maxInactiveInterval
)
二、Session 配置详解
在 PHP 开发中,Session
是保持用户状态最常见的方法之一,PHP 提供了丰富的配置项用于控制 Session 行为。通过 php.ini
或 ini_set()
调整核心参数:
配置项 | 说明 | 常见值 / 建议 |
---|---|---|
session.save_handler | Session 存储方式 | files (默认),也可使用 redis 、memcached 等 |
session.save_path | 存储路径或连接信息(视 handler 而定) | /tmp 、tcp://127.0.0.1:6379 |
session.name | 存储在 Cookie 中的 Session ID 名称 | PHPSESSID (默认) |
session.gc_maxlifetime | Session 生命周期(秒) | 1440 (默认 24 分钟,可设为 1800+) |
session.cookie_lifetime | Cookie 有效期(秒),0 表示浏览器关闭即失效 | 0 或 3600 |
session.cookie_path | Cookie 有效路径 | / (默认) |
session.cookie_domain | Cookie 有效域 | .example.com |
session.cookie_secure | 是否仅在 HTTPS 中传输 Cookie | 1 (建议开启) |
session.cookie_httponly | 禁止 JS 读取 Session Cookie | 1 (强烈建议开启) |
session.use_cookies | 是否使用 Cookie 保存 Session ID | 1 (默认) |
session.use_only_cookies | 禁止通过 URL 传递 Session ID | 1 (默认,强烈建议保留) |
session.use_trans_sid | 是否自动通过 URL 传递 Session ID | 0 (建议关闭) |
session.sid_length | Session ID 长度(PHP 7.1+) | 26 (建议保持默认) |
session.sid_bits_per_character | Session ID 中每个字符的比特数 | 5 /6 |
安全配置建议
session 配置优化
session.use_strict_mode = 1
session.use_only_cookies = 1
session.cookie_httponly = 1
session.cookie_secure = 1
session.cookie_samesite = Lax
session.gc_maxlifetime = 1800
PHP 脚本中设置(ini_set)
ini_set('session.gc_maxlifetime', 1800);
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
ini_set('session.use_only_cookies', 1);
ini_set('session.cookie_samesite', 'Lax');
session_name('MYSESSIONID');
session_start();
使用 Redis 作为 Session 存储
-
安装
redis
扩展:pecl install redis
-
设置配置:
session.save_handler = redis session.save_path = "tcp://127.0.0.1:6379"
session_start() 使用注意
- 一定要在
echo
或 HTML 输出前调用 - 调用一次即可自动读取和创建 Session
- 修改 session 设置必须在
session_start()
之前完成
三、生命周期管理
Session 的有效期由 客户端 Cookie 与 服务端数据 双重控制:
-
客户端过期
通过session.cookie_lifetime
控制会话 ID 在浏览器的留存时间:// 保持登录状态 7 天 ini_set('session.cookie_lifetime', 86400 * 7); session_start();
-
服务端垃圾回收
session.gc_maxlifetime
:数据过期时间(默认 24 分钟)session.gc_probability
与session.gc_divisor
:垃圾回收触发概率(如 1/100)
// 设置数据保留 2 小时,每次请求有 5% 概率触发 GC ini_set('session.gc_maxlifetime', 7200); ini_set('session.gc_probability', 5); ini_set('session.gc_divisor', 100);
-
手动销毁会话
session_start(); $_SESSION = []; // 清空数据 session_destroy(); // 销毁会话 setcookie(session_name(), '', time()-3600, '/'); // 强制客户端删除 Cookie
四、数据存储与序列化
$_SESSION
支持存储复杂数据结构,PHP 自动处理序列化/反序列化:
-
存储对象与资源
// 存储对象(类必须已定义) class User { public $name; } $_SESSION['user'] = new User(); $_SESSION['user']->name = 'Alice';// 资源类型无法序列化,需显式释放 $file = fopen('log.txt', 'r'); $_SESSION['file_handler'] = $file; // 触发警告!
-
自定义序列化处理器
通过session.serialize_handler
选择序列化方式:php
:PHP 内置格式(默认)php_serialize
:更安全的序列化方式
ini_set('session.serialize_handler', 'php_serialize'); session_start(); $_SESSION['data'] = ['key' => 'value'];
五、安全防护策略
-
防御会话劫持
-
绑定用户特征:校验 IP/User-Agent
session_start(); if ($_SESSION['user_agent'] !== $_SERVER['HTTP_USER_AGENT']) {session_regenerate_id(true); // 强制更换会话 IDsession_destroy(); }
-
-
防止会话固定攻击
session_start(); if (!isset($_SESSION['initiated'])) {session_regenerate_id(true); // 登录成功后更换 ID$_SESSION['initiated'] = true; }
-
加密会话数据
使用session_set_save_handler
自定义存储加密:class EncryptedSessionHandler extends SessionHandler {private $key;public function __construct($key) {$this->key = $key;}public function read($id) {$data = parent::read($id);return openssl_decrypt($data, 'AES-256-CBC', $this->key);}public function write($id, $data) {$encrypted = openssl_encrypt($data, 'AES-256-CBC', $this->key);return parent::write($id, $encrypted);} }$handler = new EncryptedSessionHandler('your-secret-key'); session_set_save_handler($handler, true); session_start();
六、高级存储方案
-
数据库存储会话(MySQL 示例)
CREATE TABLE `sessions` (`id` varchar(128) NOT NULL,`data` text,`timestamp` int(11) NOT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB;
class DatabaseSessionHandler extends SessionHandler {private $pdo;public function open($savePath, $sessionName) {$this->pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');return true;}public function read($id) {$stmt = $this->pdo->prepare("SELECT data FROM sessions WHERE id = ?");$stmt->execute([$id]);return $stmt->fetchColumn() ?: '';}public function write($id, $data) {$stmt = $this->pdo->prepare("REPLACE INTO sessions VALUES (?, ?, ?)");return $stmt->execute([$id, $data, time()]);}public function gc($maxLifetime) {$stmt = $this->pdo->prepare("DELETE FROM sessions WHERE timestamp < ?");return $stmt->execute([time() - $maxLifetime]);} }$handler = new DatabaseSessionHandler(); session_set_save_handler($handler, true); session_start();
-
Redis 加速会话
ini_set('session.save_handler', 'redis'); ini_set('session.save_path', 'tcp://127.0.0.1:6379?auth=secret'); session_start(); // 自动连接 Redis
七、性能优化技巧
-
会话锁定机制
PHP 默认使用阻塞式文件锁,高并发时可通过自定义处理器优化:class NonBlockingSessionHandler extends SessionHandler {public function read($id) {return parent::read($id);}public function write($id, $data) {// 禁用自动加锁return file_put_contents($this->getSessionFile($id), $data, LOCK_EX);} }
-
分布式会话共享
使用 Redis 或 Memcached 实现多服务器共享:// Nginx 配置 location ~ \.php$ {fastcgi_param PHP_VALUE "session.save_handler=redis\nsession.save_path=tcp://redis-cluster"; }
八、最佳实践总结
场景 | 推荐方案 | 优势 |
---|---|---|
小型站点 | 默认文件存储 + HttpOnly Cookie | 简单易维护 |
高并发系统 | Redis 存储 + 非阻塞处理 | 高吞吐低延迟 |
金融级安全 | 数据库存储 + AES 加密 | 防数据泄露 |
跨域单点登录 | 共享 Session ID + 统一认证中心 | 无缝跨系统跳转 |
相关文章:
PHP会话技术
第十六章-PHP会话技术 PHP会话技术是构建动态、个性化Web应用的核心机制之一,它通过跟踪用户在网站上的连续操作状态,实现了网页间的数据持久化交互。无论是电商平台的购物车信息保存、社交媒体的用户登录状态维持,还是表单数据的跨页面传递…...
QT聊天项目DAY10
1.封装redis操作类 头文件 #ifndef REDISMANAGE_H #define REDISMANAGE_H#include "Singletion.h" #include "GlobalHead.h"class RedisManage : public Singletion<RedisManage> {friend class Singletion<RedisManage>; public:~RedisMana…...
5.0.5 变换(旋转、缩放、扭曲)
WPF变换可以产生特殊效果,如平移、旋转、扭曲。 变换类 描述TranslateTransform沿着X轴和Y轴平移ScaleTransform 沿着定义的中心点缩放RotateTransform沿着定义的中心点旋转SkewTransform 扭曲元素MatrixTransfrom提供3x3矩阵,用于定义一个自定义变换 1…...
matlab转python
1 matlab2python开源程序 https://blog.csdn.net/qq_43426078/article/details/123384265 2 网址 转换网址:https://app.codeconvert.ai/code-converter?inputLangMatlab&outputLangPython 文件比较网址:https://www.diffchecker.com/text-comp…...
什么是直播美颜SDK?跨平台安卓、iOS美颜SDK开发实战详解
时下,尤其在社交、娱乐、电商等应用场景中,一个流畅且效果自然的美颜功能往往能直接影响用户的留存率和平台的营收。要实现这些效果,美颜SDK是核心工具。那么,什么是直播美颜SDK?它的功能有哪些?如何进行跨…...
大尺寸PCB如何重塑通信与新能源产业格局
在5G通信基站与新能源电站的机房内,一块块面积超过600mm600mm的PCB板正悄然推动着技术革命。作为电子设备的核心载体,大尺寸PCB凭借其高密度集成与复杂工艺,成为通信、能源等领域的“隐形功臣”。以猎板PCB为代表的厂商,凭借宽幅曝…...
JavaSE核心知识点02面向对象编程02-04(包和导入)
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 JavaSE核心知识点02面向对象编程02-04&#…...
【漫话机器学习系列】249.Word2Vec自然语言训练模型
【自然语言处理】用 Word2Vec 将词语映射到向量空间详解 一、背景介绍 在自然语言处理(NLP)领域,我们常常需要将文本信息转化为机器能够理解和处理的形式。传统的方法,如 one-hot编码,虽然简单,但存在严重…...
CSS transition过渡属性
transition 是 CSS 中用于创建平滑动画效果的属性,它允许元素在两个状态之间平滑过渡,而不是立即改变。通过定义过渡的属性、持续时间和速度曲线,你可以实现丰富的交互体验,如悬停效果、状态切换动画等。 核心作用 平滑过渡&…...
U9C对接飞书审批流完整过程
U9C虽然很强大,但是移动办公和审批流功能并不好用,为了弥补U9C这种不足,很多的企业在使用U9C的同时再开通钉钉、飞书、企业微信这种OA管理系统,两套系统并行使用,就需要考虑U9C和OA系统数据同步的问题,最简…...
阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化
作者:裘文成(翊韬) 摘要 随着企业全球化业务的扩展,如何高效、经济且可靠地将分布在海外各地的应用与基础设施日志统一采集至阿里云日志服务 (SLS) 进行分析与监控,已成为关键挑战。 本文聚焦于阿里云高性能日志采集…...
从0开始学习大模型--Day04--大模型的框架以及基本元素
Agent框架与策略分析 计划与执行(planning-and-Execute) 该框架侧重于先规划一系列的行动,然后执行。这个框架可以使大模型能够先综合考虑任务的多个方面,然后按照计划进行行动,比较适合应用在较复杂的项目管理中或者…...
FPGA实战项目2———多协议通信控制器
1. 多协议通信控制器模块 (multi_protocol_controller) 简要介绍 这是整个设计的顶层模块,承担着整合各个子模块的重要任务,是整个系统的核心枢纽。它负责协调 UART、SPI、I2C 等不同通信协议模块以及 DMA 模块的工作,同时处理不同时钟域之间的信号交互,确保各个模块能够…...
strings.Builder 使用详解
目录 1. 官方包 2. 支持版本 3. 官方说明 官方示例 方法 func (b *Builder) Cap() int func (b *Builder) Grow(n int) func (b *Builder) Len() int func (b *Builder) Reset() func (b *Builder) String() string func (b *Builder) Write(p []byte) (int, error)…...
数巅智能携手北京昇腾创新中心深耕行业大模型应用
当前,AI技术正在加速向各行业深度渗透,成为驱动产业转型和社会经济发展的重要引擎。构建开放协作的AI应用生态体系、推动技术和应用深度融合,已成为行业发展的重要趋势。 近日,数巅智能与北京昇腾人工智能计算中心(北京昇腾创新中…...
【嵌入式系统设计师(软考中级)】第二章:嵌入式系统硬件基础知识——⑤电源及电路设计
文章目录 7. 嵌入式系统电源分类及管理7.1 嵌入式系统电源分类7.2 电源管理技术7.3 电源完整性设计 8. 电子电路设计8.1 电子电路设计基础知识8.1.1 电子电路设计原理8.1.2 电子电路设计方法及步骤8.1.3 电子电路可靠性设计 8.2 PCB设计基础知识8.2.1 PCB设计原理8.2.2 PCB设计…...
排序算法-希尔排序
希尔排序是插入排序的改进版,通过将原始数组分成多个子序列进行间隔插入排序,逐步缩小间隔直至为1,最终完成整体排序。它也被称为缩小增量排序。 希尔排序步骤 选择增量序列(Gap Sequence):确定一个递减的…...
JAVA继承中变量和方法的存储和方法中访问变量的顺序
一、变量归属与内存位置 static 变量:属于类,只存在一份,保存在方法区(或元空间)。 实例变量(非static):属于对象,每个对象单独一份,保存在堆内存中。 二、…...
【PhysUnits】3.3 SI 基础量纲单位(units/base.rs)
一、源码 这段代码定义了一系列基础物理量纲的类型别名,并使用标记 trait Canonical 来表示它们是国际单位制(SI)中的基本单位。 use crate::Dimension; use typenum::{P1, Z0};/// 标记特质,表示基础量纲单位 pub trait Canoni…...
stm32F103芯片 实现PID算法控制温度例程
目录 硬件需求 软件需求 步骤 1. 配置STM32CubeMX 2. 编写PID控制代码 3. 编译和烧录 4. 测试 注意事项 要在STM32F103芯片上实现PID算法控制温度,首先需要确保你有一套完整的硬件和软件开发环境。这里,我将给你一个简化的例程,展示如何使用PID控制算法来调节一个假…...
Java学习手册:微服务设计原则
一、单一职责原则 每个微服务应该专注于一个特定的业务功能,具有清晰的职责边界。这有助于保持服务的简洁性,降低服务之间的耦合度,提高服务的可维护性和可扩展性。例如,可以将用户管理、订单管理、支付管理等功能分别设计为独立…...
【挑战项目】 --- 微服务编程测评系统(在线OJ系统)(二)
三十二、Swagger介绍&使用 官网:https://swagger.io/ 什么是swagger Swagger是一个接口文档生成工具,它可以帮助开发者自动生成接口文档。当项目的接口发生变更时,Swagger可以实时更新文档,确保文档的准确性和时效性。Swagger还内置了测试功能,开发者可以直接在文档中…...
Unity背景随着文字变化而变化
组件结构: 背景(父)需要添加如下两个组件 根据具体情况选择第一个组件水平还是垂直,一般垂直用的比较多 效果展示: 此时在文本框中改变内容背景图都会随着变化,动态的...
Elasticsearch内存管理与JVM优化:原理剖析与最佳实践
#作者:孙德新 文章目录 一、Elasticsearch缓存分类1、Node Query Cache:2、Shard Request Cache:3、Fielddata Cache: 三、内存常见的问题案例一案例二案例三案例四 四、内参分配最佳实践1、jvm heap分配2、将机器上少于一半的内…...
快速开发-基于Gin框架搭建web应用
一、概述 Go 语言的 Gin 框架是一个用 Go (Golang) 编写的 Web 框架,它旨在提供一种快速、简洁且高效的方式来构建 Web 应用程序。Gin 框架以其高性能和易用性而闻名,非常适合构建 API 服务、Web 服务和其他需要高性能的 Web 应用。 二、Gin框架…...
【RAG】RAG系统——langchain 的用法(说人话版与专业版)
说人话版: RAG就是一句话:对数据设置索引,用问题去检索,用llm生成回答 首先,做本地知识库 注意: py 3.10以上 配置环境变量,安装库 load外部数据,存储到本地的一个index里(这是最…...
pycharm无法直接识别wsl
原因是我的2020 无法支持这个版本的wsl 我就换成2024版 添加中可以看到 on wsl 如果你想切到自己创建的虚拟环境 你在下面这个界面选择conda就好 这样就可以切换成你想要的环境了...
数据结构每日一题day17(链表)★★★★★
题目描述:假设有两个按元素值递增次排列的线性表,均以单链表形式存储。请编与算法将这两个单链表归并为一个按元素值依次递减排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表。 算法思想: 1.初始化: 创建一个新…...
遗传算法(GA)
基本原理 算法介绍 遗传算法(Genetic Algorithm,简称GA)是一种基于自然选择和遗传学原理的搜索和优化技术。它模拟了生物进化过程,通过选择、交叉(重组)和变异等操作,逐步优化问题的解。 遗传…...
EPS三维测图软件
EPS三维测图软件EPS2016...
设计模式-命令模式
写在前面 Hello,我是易元,这篇文章是我学习设计模式时的笔记和心得体会。如果其中有错误,欢迎大家留言指正! 一、什么是命令模式? 命令模式是行为模式中的一种,通过将请求封装成对象,使开发者可…...
深入理解主从数据库架构与主从复制
目录 前言1. 主从数据库概述1.1 什么是主从数据库?1.2 主从数据库的应用场景 2. 主从数据库的工作原理2.1 主从数据库的读写分离2.2 数据同步机制2.3 异步与同步复制模式 3. 主从复制的实现步骤3.1 配置主库3.2 配置从库 4. 主从数据库架构的优缺点4.1 优点4.2 缺点…...
【C】初阶数据结构15 -- 计数排序与稳定性分析
本文主要讲解七大排序算法之外的另一种排序算法 -- 计数排序 目录 1 计数排序 1) 算法思想 2) 代码 3) 时间复杂度与空间复杂度分析 (1) 时间复杂度 (2) 空间复杂度 4) 计…...
@PostConstruct @PreDestroy
PostConstruct 是 Java EE(现 Jakarta EE)中的一个注解,用于标记一个方法在对象初始化完成后立即执行。它在 Spring 框架、Java Web 应用等场景中广泛使用,主要用于资源初始化、依赖注入完成后的配置等操作。 1. 基本作用 执行时…...
2025数维杯数学建模A题完整限量论文:空中芭蕾——蹦床运动的力学行为分析
2025数维杯数学建模A题完整限量论文:空中芭蕾——蹦床运动的力学行为分析 ,先到先得 A题完整论文https://www.jdmm.cc/file/2712067/ 蹦床( Trampoline )是一项运动员利用蹦床的反弹,在空中展示技能 技巧的竞技运动&…...
Kubernetes Gateway API 部署详解:从入门到实战
引言 在 Kubernetes 中管理网络流量一直是一个复杂而关键的任务。传统的 Ingress API 虽然广泛使用,但其功能有限且扩展性不足。Kubernetes Gateway API 作为新一代标准,提供了更强大的路由控制能力,支持多协议、跨命名空间路由和细粒度的流量管理。本文将带你从零开始部署…...
移动设备常用电子屏幕类型对比
概述 LCD 家族 (TN、STN、TFT、IPS、VA)依赖背光,性能差异主要来自液晶排列和驱动方式。OLED 以自发光为核心优势,但成本与寿命限制其普及。E-Paper 专为低功耗静态显示设计,与传统屏幕技术差异显著。 参数LCD&#…...
HarmonyOS开发-组件市场
1. HarmonyOS开发-组件市场 HarmonyOS NEXT开源组件市场是一个独立的插件,需通过DevEco Studio进行安装,可以点击下载,无需解压,直接通过zip进行安装,具体安装和使用方法可参考HarmonyOsNEXT组件市场使用说明。Harmony…...
效果图云渲染:价格、优势与使用技巧
对于做3D设计来说,渲染效果图会占用设计电脑的资源,如果能免去这个环节就好了。用设计电脑渲不仅拖慢电脑速度,遇到紧急情况无法快速渲染出来还可能耽误进度。而云渲染的出现,正是针对这个点——渲的快,价格便宜&#…...
OptiStruct实例:声振耦合超单元应用
如图10-11所示,本例采用一个简化的整车模型,模型分为车身(含声腔)与底盘两部分。首先分别运用CMS与CDS方法对车身(含声腔)模型进行缩聚,生成.h3d格式的CMS超单元和cps超单元,然后进行…...
排序算法-插入排序
插入排序是一种简单直观的排序算法,其核心思想是将未排序部分的元素逐个插入到已排序部分的正确位置,类似于整理扑克牌。 插入排序步骤 初始化:将序列的第一个元素视为已排序部分,其余为未排序部分。 选择元素:从未排…...
Uniapp Android/IOS 获取手机通讯录
介绍 最近忙着开发支付宝小程序和app,下面给大家介绍一下 app 获取通讯录的全部过程吧,也是这也是我app开发中的一项需求吧。 效果图如下 勾选配置文件 使用uniapp开发的童鞋都知道有一个配置文件 manifest.json 简单的说一下,就是安卓/ios/…...
【RAG】index环节中 关于嵌入模型和 ColBERT
1. 什么是嵌入模型?是不是把数据源转换为向量表示的模型? 是的,嵌入模型(Embedding Model)的核心功能就是将各种类型的数据(例如,文本、图像、音频等)转换成低维、稠密的向量表示。…...
一文掌握 LVGL 9 的源码目录结构
文章目录 📂 一文掌握 LVGL 9 的源码目录结构🧭 顶层目录概览📁 1. src/ — LVGL 的核心源码(🔥重点)📁 2. examples/ — API 示例📁 3. demos/ — 综合演示项目📁 4. do…...
ROS1 和 ROS2 在同一个系统中使用
一、环境变量设置 echo "ros noetic(1) or ros2 foxy(2)?" read edition if [ "$edition" -eq "1" ]; thensource /opt/ros/noetic/setup.bash elsesource /opt/ros/foxy/setup.bash fi 二、针对不同的ROS版本创建不同的工作空间work space...
Redis 8.0携新功能,重新开源
01 引言 Redis从7.4版本起,将开源许可证改成 RSALv2(Redis 源代码可用许可证)与 SSPLv1(服务器端公共许可证)的双重授权策略。简单来说,就是不能随意商用。为了抵制Redis,Redis的替代品Valkey、…...
AD原理图复制较多元器件时报错:“InvalidParameter Exception Occurred In Copy”
一、问题描述 AD原理图复制较多元器件时报错:AD原理图复制较多元器件时报错:“InvalidParameter Exception Occurred In Copy”。如下图 二、问题分析 破解BUG。 三、解决方案 1、打开参数配置 2、打开原理图优先项中的通用配置,取消勾选G…...
【wpf】12 在WPF中实现HTTP通信:封装HttpClient的最佳实践
一、背景介绍 在现代桌面应用开发中,网络通信是不可或缺的能力。WPF作为.NET平台下的桌面开发框架,可通过HttpClient轻松实现与后端API的交互。本文将以一个实际的HttpsMessages工具类为例,讲解如何在WPF中安全高效地封装HTTP通信模块。 二、…...
从概念表达到安全验证:智能驾驶功能迎来系统性规范
随着辅助驾驶事故频发,监管机制正在迅速补位。面对能力表达、使用责任、功能部署等方面的新要求,行业开始重估技术边界与验证能力,数字样机正成为企业合规落地的重要抓手。 2025年以来,围绕智能驾驶功能的争议不断升级。多起因辅…...
金贝灯光儿童摄影3大布光方案,解锁专业级童趣写真
随着亲子消费的持续升温,儿童摄影行业对高效、专业、灵活的专业灯光需求日益迫切。为精准解决儿童拍摄中孩子好动难配合、氛围单调、出片效率低下等痛点,深耕影像光源行业三十年,拥有丰富的商业人像摄影灯光解决方案的金贝品牌,近…...