php消息路由

1.单文件模式

web刚开始发展的时候,没有专门的前端工程师, web开发人员经常是服务端,客户端开发一把梭。那时候,不管是业务逻辑,还是界面交互,都喜欢把某个业务的前后端代码放在同一个文件。例如,jsp,asp,php均是这种模式。

例如,下面的订单管理页面,主要负责订单的增删查改

<?php
// 连接数据库
try {$pdo = new PDO('mysql:host=localhost;dbname=php', 'root', '123456');$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {die("数据库连接失败:" . $e->getMessage());
}// 获取所有订单
function getAllOrders()
{global $pdo;$sql = "SELECT * FROM orders";$stmt = $pdo->query($sql);return $stmt->fetchAll(PDO::FETCH_ASSOC);
}// 添加订单
function addOrder($customerName, $productName, $quantity, $totalPrice)
{global $pdo;$sql = "INSERT INTO orders (customer_name, product_name, quantity, total_price) VALUES (:customer_name, :product_name, :quantity, :total_price)";$stmt = $pdo->prepare($sql);$stmt->bindParam(':customer_name', $customerName);$stmt->bindParam(':product_name', $productName);$stmt->bindParam(':quantity', $quantity);$stmt->bindParam(':total_price', $totalPrice);$stmt->execute();
}// 更新订单
function updateOrder($id, $customerName, $productName, $quantity, $totalPrice)
{global $pdo;$sql = "UPDATE orders SET customer_name = :customer_name, product_name = :product_name, quantity = :quantity, total_price = :total_price WHERE id = :id";$stmt = $pdo->prepare($sql);$stmt->bindParam(':id', $id);$stmt->bindParam(':customer_name', $customerName);$stmt->bindParam(':product_name', $productName);$stmt->bindParam(':quantity', $quantity);$stmt->bindParam(':total_price', $totalPrice);$stmt->execute();
}// 删除订单
function deleteOrder($id)
{global $pdo;$sql = "DELETE FROM orders WHERE id = :id";$stmt = $pdo->prepare($sql);$stmt->bindParam(':id', $id);$stmt->execute();
}// 根据请求类型进行处理
if ($_SERVER['REQUEST_METHOD'] === 'POST') {if (isset($_POST['action']) && $_POST['action'] === 'add') {addOrder($_POST['customer_name'], $_POST['product_name'], $_POST['quantity'], $_POST['total_price']);} elseif (isset($_POST['action']) && $_POST['action'] === 'update') {updateOrder($_POST['id'], $_POST['customer_name'], $_POST['product_name'], $_POST['quantity'], $_POST['total_price']);} elseif (isset($_POST['action']) && $_POST['action'] === 'delete') {deleteOrder($_POST['id']);}header('Location: index.php');exit;
}$orders = getAllOrders();
?>
<!DOCTYPE html>
<html><head><title>订单管理系统</title><style>body {font-family: Arial, sans-serif;}.container {max-width: 800px;margin: 0 auto;padding: 20px;}table {width: 100%;border-collapse: collapse;}th,td {padding: 8px;border: 1px solid #ddd;}th {background-color: #f2f2f2;}.btn {padding: 6px 12px;border: none;border-radius: 4px;cursor: pointer;}.btn-primary {background-color: #007bff;color: #fff;}.btn-danger {background-color: #dc3545;color: #fff;}.modal {display: none;position: fixed;z-index: 1000;top: 0;left: 0;width: 100%;height: 100%;overflow: auto;background-color: rgba(0, 0, 0, 0.4);}.modal-content {background-color: #fff;margin: 10% auto;padding: 20px;border: 1px solid #888;width: 80%;}.modal-header,.modal-footer {padding: 10px;}.modal-title {margin: 0;}.form-group {margin-bottom: 15px;}label {display: block;margin-bottom: 5px;}input[type="text"],input[type="number"] {width: 100%;padding: 8px;border: 1px solid #ddd;border-radius: 4px;}</style>
</head><body><div class="container"><h1>订单管理系统</h1><table><thead><tr><th>订单编号</th><th>客户名称</th><th>产品名称</th><th>数量</th><th>总价</th><th>操作</th></tr></thead><tbody><?php foreach ($orders as $order): ?><tr><td><?php echo $order['id']; ?></td><td><?php echo $order['customer_name']; ?></td><td><?php echo $order['product_name']; ?></td><td><?php echo $order['quantity']; ?></td><td><?php echo $order['total_price']; ?></td><td><button class="btn btn-primary btn-sm edit-btn" data-id="<?php echo $order['id']; ?>" data-customer_name="<?php echo $order['customer_name']; ?>" data-product_name="<?php echo $order['product_name']; ?>" data-quantity="<?php echo $order['quantity']; ?>" data-total_price="<?php echo $order['total_price']; ?>">编辑</button><button class="btn btn-danger btn-sm delete-btn" data-id="<?php echo $order['id']; ?>">删除</button></td></tr><?php endforeach; ?></tbody></table><button class="btn btn-success" onclick="showAddModal()">添加订单</button></div><!-- 添加订单模态框 --><div id="addModal" class="modal"><div class="modal-content"><div class="modal-header"><h5 id="addModalLabel">添加订单</h5><button type="button" class="close" onclick="hideModal('addModal')">×</button></div><div class="modal-body"><form id="addForm"><div class="form-group"><label for="customer_name">客户名称</label><input type="text" class="form-control" id="customer_name" required></div><div class="form-group"><label for="product_name">产品名称</label><input type="text" class="form-control" id="product_name" required></div><div class="form-group"><label for="quantity">数量</label><input type="number" class="form-control" id="quantity" required></div><div class="form-group"><label for="total_price">总价</label><input type="number" class="form-control" id="total_price" required></div></form></div><div class="modal-footer"><button type="button" class="btn btn-secondary" onclick="hideModal('addModal')">关闭</button><button type="button" class="btn btn-primary" onclick="addOrder()">添加</button></div></div></div><!-- 编辑订单模态框 --><div id="editModal" class="modal"><div class="modal-content"><div class="modal-header"><h5 id="editModalLabel">编辑订单</h5><button type="button" class="close" onclick="hideModal('editModal')">×</button></div><div class="modal-body"><form id="editForm"><input type="hidden" id="edit_id"><div class="form-group"><label for="edit_customer_name">客户名称</label><input type="text" class="form-control" id="edit_customer_name" required></div><div class="form-group"><label for="edit_product_name">产品名称</label><input type="text" class="form-control" id="edit_product_name" required></div><div class="form-group"><label for="edit_quantity">数量</label><input type="number" class="form-control" id="edit_quantity" required></div><div class="form-group"><label for="edit_total_price">总价</label><input type="number" class="form-control" id="edit_total_price" required></div></form></div><div class="modal-footer"><button type="button" class="btn btn-secondary" onclick="hideModal('editModal')">关闭</button><button type="button" class="btn btn-primary" onclick="updateOrder()">保存</button></div></div></div><script src="https://code.jquery.com/jquery-3.6.0.min.js"></script><script>function showAddModal() {document.getElementById('addModal').style.display = 'block';}function hideModal(modalId) {document.getElementById(modalId).style.display = 'none';}// 添加订单function addOrder() {const customerName = document.getElementById('customer_name').value;const productName = document.getElementById('product_name').value;const quantity = document.getElementById('quantity').value;const totalPrice = document.getElementById('total_price').value;$.ajax({type: 'POST',url: 'index.php',data: {action: 'add',customer_name: customerName,product_name: productName,quantity: quantity,total_price: totalPrice},success: function() {hideModal('addModal');location.reload();}});}// 编辑按钮点击事件document.addEventListener('click', function(event) {if (event.target.classList.contains('edit-btn')) {const id = event.target.dataset.id;const customerName = event.target.dataset.customer_name;const productName = event.target.dataset.product_name;const quantity = event.target.dataset.quantity;const totalPrice = event.target.dataset.total_price;document.getElementById('edit_id').value = id;document.getElementById('edit_customer_name').value = customerName;document.getElementById('edit_product_name').value = productName;document.getElementById('edit_quantity').value = quantity;document.getElementById('edit_total_price').value = totalPrice;document.getElementById('editModal').style.display = 'block';}});// 保存编辑function updateOrder() {const id = document.getElementById('edit_id').value;const customerName = document.getElementById('edit_customer_name').value;const productName = document.getElementById('edit_product_name').value;const quantity = document.getElementById('edit_quantity').value;const totalPrice = document.getElementById('edit_total_price').value;$.ajax({type: 'POST',url: 'index.php',data: {action: 'update',id: id,customer_name: customerName,product_name: productName,quantity: quantity,total_price: totalPrice},success: function() {hideModal('editModal');location.reload();}});}// 删除按钮点击事件document.addEventListener('click', function(event) {if (event.target.classList.contains('delete-btn')) {const id = event.target.dataset.id;if (confirm('确定要删除该订单吗?')) {$.ajax({type: 'POST',url: 'index.php',data: {action: 'delete',id: id},success: function() {location.reload();}});}}});</script>
</body></html>

这种模式,虽然界面写起来可能不是很漂亮(毕竟术业有专攻),但开发效率还是非常高的。因为服务端客户端都是同一个开发,接口联调如丝般柔顺,减少了沟通的成本

2.前后端分离模式

伴随javascript的强势发展,现在的web工程基本采用前后端分离的模式,服务端只负责数据的处理,由客户端专门做交互界面。

将下面的代码分成两个文件

2.1.前端界面

<!DOCTYPE html>
<html><head><title>订单管理系统</title><meta charset="UTF-8" /><style>body {font-family: Arial, sans-serif;}.container {max-width: 800px;margin: 0 auto;padding: 20px;}table {width: 100%;border-collapse: collapse;}th,td {padding: 8px;border: 1px solid #ddd;}th {background-color: #f2f2f2;}.btn {padding: 6px 12px;border: none;border-radius: 4px;cursor: pointer;}.btn-primary {background-color: #007bff;color: #fff;}.btn-danger {background-color: #dc3545;color: #fff;}.modal {display: none;position: fixed;z-index: 1000;top: 0;left: 0;width: 100%;height: 100%;overflow: auto;background-color: rgba(0, 0, 0, 0.4);}.modal-content {background-color: #fff;margin: 10% auto;padding: 20px;border: 1px solid #888;width: 80%;}.modal-header,.modal-footer {padding: 10px;}.modal-title {margin: 0;}.form-group {margin-bottom: 15px;}label {display: block;margin-bottom: 5px;}input[type="text"],input[type="number"] {width: 100%;padding: 8px;border: 1px solid #ddd;border-radius: 4px;}</style></head><body><div class="container"><h1>订单管理系统</h1><table><thead><tr><th>订单编号</th><th>客户名称</th><th>产品名称</th><th>数量</th><th>总价</th><th>操作</th></tr></thead><tbody id="orderTableBody"></tbody></table><button class="btn btn-success" onclick="showAddModal()">添加订单</button></div><!-- 添加订单模态框 --><div id="addModal" class="modal"><div class="modal-content"><div class="modal-header"><h5 id="addModalLabel">添加订单</h5><button type="button" class="close" onclick="hideModal('addModal')">×</button></div><div class="modal-body"><form id="addForm"><div class="form-group"><label for="customer_name">客户名称</label><inputtype="text"class="form-control"id="customer_name"required/></div><div class="form-group"><label for="product_name">产品名称</label><inputtype="text"class="form-control"id="product_name"required/></div><div class="form-group"><label for="quantity">数量</label><inputtype="number"class="form-control"id="quantity"required/></div><div class="form-group"><label for="total_price">总价</label><inputtype="number"class="form-control"id="total_price"required/></div></form></div><div class="modal-footer"><buttontype="button"class="btn btn-secondary"onclick="hideModal('addModal')">关闭</button><button type="button" class="btn btn-primary" onclick="addOrder()">添加</button></div></div></div><!-- 编辑订单模态框 --><div id="editModal" class="modal"><div class="modal-content"><div class="modal-header"><h5 id="editModalLabel">编辑订单</h5><button type="button" class="close" onclick="hideModal('editModal')">×</button></div><div class="modal-body"><form id="editForm"><input type="hidden" id="edit_id" /><div class="form-group"><label for="edit_customer_name">客户名称</label><inputtype="text"class="form-control"id="edit_customer_name"required/></div><div class="form-group"><label for="edit_product_name">产品名称</label><inputtype="text"class="form-control"id="edit_product_name"required/></div><div class="form-group"><label for="edit_quantity">数量</label><inputtype="number"class="form-control"id="edit_quantity"required/></div><div class="form-group"><label for="edit_total_price">总价</label><inputtype="number"class="form-control"id="edit_total_price"required/></div></form></div><div class="modal-footer"><buttontype="button"class="btn btn-secondary"onclick="hideModal('editModal')">关闭</button><button type="button" class="btn btn-primary" onclick="updateOrder()">保存</button></div></div></div><script src="https://code.jquery.com/jquery-3.6.0.min.js"></script><script>// 加载订单数据function loadOrders() {$.ajax({type: "GET",url: "http://localhost/demo/order_handler.php",success: function (data) {$("#orderTableBody").html("");JSON.parse(data).forEach(function (order) {$("#orderTableBody").append("<tr><td>" +order.id +"</td><td>" +order.customer_name +"</td><td>" +order.product_name +"</td><td>" +order.quantity +"</td><td>" +order.total_price +'</td><td><button class="btn btn-primary btn-sm edit-btn" data-id="' +order.id +'" data-customer_name="' +order.customer_name +'" data-product_name="' +order.product_name +'" data-quantity="' +order.quantity +'" data-total_price="' +order.total_price +'">编辑</button><button class="btn btn-danger btn-sm delete-btn" data-id="' +order.id +'">删除</button></td></tr>');});},});}loadOrders();function showAddModal() {document.getElementById("addModal").style.display = "block";}function hideModal(modalId) {document.getElementById(modalId).style.display = "none";}// 添加订单function addOrder() {const customerName = document.getElementById("customer_name").value;const productName = document.getElementById("product_name").value;const quantity = document.getElementById("quantity").value;const totalPrice = document.getElementById("total_price").value;$.ajax({type: "POST",url: "http://localhost/demo/order_handler.php",data: {action: "add",customer_name: customerName,product_name: productName,quantity: quantity,total_price: totalPrice,},success: function () {hideModal("addModal");loadOrders();},});}// 编辑按钮点击事件document.addEventListener("click", function (event) {if (event.target.classList.contains("edit-btn")) {const id = event.target.dataset.id;const customerName = event.target.dataset.customer_name;const productName = event.target.dataset.product_name;const quantity = event.target.dataset.quantity;const totalPrice = event.target.dataset.total_price;document.getElementById("edit_id").value = id;document.getElementById("edit_customer_name").value = customerName;document.getElementById("edit_product_name").value = productName;document.getElementById("edit_quantity").value = quantity;document.getElementById("edit_total_price").value = totalPrice;document.getElementById("editModal").style.display = "block";}});// 保存编辑function updateOrder() {const id = document.getElementById("edit_id").value;const customerName =document.getElementById("edit_customer_name").value;const product_name = document.getElementById("edit_product_name").value;const quantity = document.getElementById("edit_quantity").value;const totalPrice = document.getElementById("edit_total_price").value;$.ajax({type: "POST",url: "/orders/update",data: {action: "update",id: id,customer_name: customerName,product_name: product_name,quantity: quantity,total_price: totalPrice,},success: function () {hideModal("editModal");loadOrders();},});}// 删除按钮点击事件document.addEventListener("click", function (event) {if (event.target.classList.contains("delete-btn")) {const id = event.target.dataset.id;if (confirm("确定要删除该订单吗?")) {$.ajax({type: "POST",url: "http://localhost/demo/order_handler.php",data: {action: "delete",id: id,},success: function () {loadOrders();},});}}});</script></body>
</html>

可以看到,CRUD的路径都是http://localhost/demo/order_handler.php这个php文件,通过action定义子类型。

2.2.后端代码

<?php
require_once 'router.php';
// 连接数据库
try {$pdo = new PDO('mysql:host=localhost;dbname=php', 'root', '123456');$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {die("数据库连接失败:" . $e->getMessage());
}// 获取所有订单
function getAllOrders()
{global $pdo;$sql = "SELECT * FROM orders";$stmt = $pdo->query($sql);return $stmt->fetchAll(PDO::FETCH_ASSOC);
}// 添加订单
function addOrder($customerName, $productName, $quantity, $totalPrice)
{global $pdo;$sql = "INSERT INTO orders (customer_name, product_name, quantity, total_price) VALUES (:customer_name, :product_name, :quantity, :total_price)";$stmt = $pdo->prepare($sql);$stmt->bindParam(':customer_name', $customerName);$stmt->bindParam(':product_name', $productName);$stmt->bindParam(':quantity', $quantity);$stmt->bindParam(':total_price', $totalPrice);$stmt->execute();
}// 更新订单
function updateOrder($id, $customerName, $productName, $quantity, $totalPrice)
{global $pdo;$sql = "UPDATE orders SET customer_name = :customer_name, product_name = :product_name, quantity = :quantity, total_price = :total_price WHERE id = :id";$stmt = $pdo->prepare($sql);$stmt->bindParam(':id', $id);$stmt->bindParam(':customer_name', $customerName);$stmt->bindParam(':product_name', $productName);$stmt->bindParam(':quantity', $quantity);$stmt->bindParam(':total_price', $totalPrice);$stmt->execute();
}// 删除订单
function deleteOrder($id)
{global $pdo;$sql = "DELETE FROM orders WHERE id = :id";$stmt = $pdo->prepare($sql);$stmt->bindParam(':id', $id);$stmt->execute();
}// 根据请求类型进行处理
if ($_SERVER['REQUEST_METHOD'] === 'GET') {$orders = getAllOrders();echo json_encode($orders);
} else if ($_SERVER['REQUEST_METHOD'] === 'POST') {if (isset($_POST['action']) && $_POST['action'] === 'add') {addOrder($_POST['customer_name'], $_POST['product_name'], $_POST['quantity'], $_POST['total_price']);} elseif (isset($_POST['action']) && $_POST['action'] === 'update') {updateOrder($_POST['id'], $_POST['customer_name'], $_POST['product_name'], $_POST['quantity'], $_POST['total_price']);} elseif (isset($_POST['action']) && $_POST['action'] === 'delete') {deleteOrder($_POST['id']);}header('Location: index.php');exit;
}

这里有一段代码,根据不同的请求方法调用相应的函数,就是非常简单(丑陋)的消息路由逻辑了。

// 根据请求类型进行处理
if ($_SERVER['REQUEST_METHOD'] === 'GET') {$orders = getAllOrders();echo json_encode($orders);
} else if ($_SERVER['REQUEST_METHOD'] === 'POST') {if (isset($_POST['action']) && $_POST['action'] === 'add') {addOrder($_POST['customer_name'], $_POST['product_name'], $_POST['quantity'], $_POST['total_price']);} elseif (isset($_POST['action']) && $_POST['action'] === 'update') {updateOrder($_POST['id'], $_POST['customer_name'], $_POST['product_name'], $_POST['quantity'], $_POST['total_price']);} elseif (isset($_POST['action']) && $_POST['action'] === 'delete') {deleteOrder($_POST['id']);}header('Location: index.php');exit;
}

3.实现简单路由

3.1.springmvc基于注解的路由

了解过springmvc(或者其他编程语言的mvc框架)的同学,可能对这种代码嗤之以鼻,确实太丑了。springmvc通过类注解,方法注解,定义消息路由,非常漂亮!

@RestController
@RequestMapping("/player")
public class PlayerController {@GetMapping(value = "/getProgress")public Response getProgress(@RequestHeader Map<String, String> headers, @Valid ReqQueryProgress req) {return Response.success(userGameData.getProgress());}@PostMapping(value = "/saveProgress")public Response saveProgress(@RequestHeader Map<String, String> headers, @Valid @RequestBody ReqSaveProgress req) {return Response.success(userGameData.getProgress());}
}

由于php不支持注解,无法做到springmvc的模式,即使使用了消息路由,也只能手动注册url与对应的执行函数。

3.2.路由函数(router.php)

<?php
// 定义路由和相关函数等内容$routes = [];
function route($method, $path, $callback)
{global $routes;$routes[$method][$path] = $callback;
}function dispatch()
{global $routes;$method = $_SERVER['REQUEST_METHOD'];$path = $_SERVER['REQUEST_URI'];// 本项目放在htdocs目录下的子目录demo,所以将url前缀进行替换$path = str_replace("/demo", "", $path);if (isset($routes[$method][$path])) {$callback = $routes[$method][$path];return $callback();} else {// 404处理header('HTTP/1.0 404 Not Found');echo '404 - Page not found';}
}

3.3.注册业务路由

order_handler.php那段丑陋的代码,现在可以删掉了,改为下面的代码

// 获取订单的路由
route('GET', '/orders', function () {$orders = getAllOrders();echo json_encode($orders);
});
// 添加订单的路由
route('POST', '/orders/add', function () {if (isset($_POST['action']) && $_POST['action'] === 'add') {addOrder($_POST['customer_name'], $_POST['product_name'], $_POST['quantity'], $_POST['total_price']);}header('Location: index.php');exit;
});
// 更新订单的路由
route('POST', '/orders/update', function () {if (isset($_POST['action']) && $_POST['action'] === 'update') {updateOrder($_POST['id'], $_POST['customer_name'], $_POST['product_name'], $_POST['quantity'], $_POST['total_price']);}header('Location: index.php');exit;
});
// 删除订单的路由
route('POST', '/orders/delete', function () {if (isset($_POST['action']) && $_POST['action'] === 'delete') {deleteOrder($_POST['id']);}header('Location: index.php');exit;
});

3.4.统一请求入口(网关)

 我们希望对order的所有请求转发到order_handler.php这个文件来,这里可以利用.htaccess来定义路由规则,在php代码的同级目录下,新建.htaccess文件,编辑下面的内容。将所有请求转发到index.php。

RewriteEngine On
RewriteRule ^(.*)$ index.php [QSA,L]

在index.php文件,加载路由文件,订单业务处理文件,

<?php
// 引入包含路由定义和相关函数(如addOrder、updateOrder等)的文件
require_once 'router.php';
require_once 'order_handler.php';// 调用dispatch函数处理请求
dispatch();// 跨域设置
// 允许任何来源访问
header('Access-Control-Allow-Origin: *');
// 允许的请求方法
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
// 允许的请求头
header('Access-Control-Allow-Headers: Content-Type');

修改客户端请求的url,由统一路径改为具体的路径,如http://localhost/demo/orders/add, action字段也可以去掉了。

3.5.另外一种路由:一个url对应一个文件

对于业务是对各种数据库表作增删查改,则可以换一种方式作映射。对于一张表,增删查改代表四种动作,对应不同的http方法,每一个动作对应一个php文件,采用下面的映射文件。

{"/api/order/": {"get": "api/order/query.php","post": "api/order/create.php","put": "api/order/edit.php","delete": "api/order/delete.php",},"/api/user/": {"get": "api/user/query.php","post": "api/user/create.php","put": "api/user/edit.php","delete": "api/user/delete.php",},
}

通过解析这个文件,得到url与对应的php文件。每次请求,提取出url与method类型,找到对应的php文件,加载后得到计算结果。代码如下:

// 启动一个输出缓冲区
ob_start();
// 根据url,method获取对应的php文件路径
$apiPath = mapAPI($path, $method);
// 加载php文件
include $apiPath;
// 获取缓冲区的结果
$body = ob_get_clean();// 返回给客户端
return ['statusCode' => 200,'headers' => $headers,'body' => $body
];

这种模式有两个很不好的地方:

  • 如果接口很多,文件数据也相应非常多
  • 同一张表的增删查改逻辑可能很关联性,拆分成多个文件不利于代码的复用 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/474845.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[ 网络安全介绍 1 ] 什么是网络安全?

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

无插件H5播放器EasyPlayer.js视频流媒体播放器如何开启electron硬解码Hevc(H265)

在数字化时代&#xff0c;流媒体播放器技术正经历着前所未有的变革。随着人工智能、大数据、云计算等技术的融合&#xff0c;流媒体播放器的核心技术不断演进&#xff0c;为用户提供了更加丰富和个性化的观看体验。 EasyPlayer.js H5播放器&#xff0c;是一款能够同时支持HTTP、…

阿里数字人工作 Emote Portrait Alive (EMO):基于 Diffusion 直接生成视频的数字人方案

TL;DR 2024 年 ECCV 阿里智能计算研究所的数字人工作&#xff0c;基于 diffusion 方法来直接的从音频到视频合成数字人&#xff0c;避免了中间的三维模型或面部 landmark 的需求&#xff0c;效果很好。 Paper name EMO: Emote Portrait Alive - Generating Expressive Portra…

Unity脚本基础规则

Unity脚本基础规则 如何在Unity中创建一个脚本文件&#xff1f; 在Project窗口中的Assets目录下&#xff0c;选择合适的文件夹&#xff0c;右键&#xff0c;选择第一个Create&#xff0c;在新出现的一栏中选择C# Script&#xff0c;此时文件夹内会出现C#脚本图标&#xff0c;…

基于YOLOv8深度学习的无人机航拍小目标检测系统(PyQt5界面+数据集+训练代码)

本研究提出并实现了一种基于YOLOv8深度学习模型的无人机航拍小目标检测系统&#xff0c;旨在解决高空环境下汽车目标检测的技术难题。随着无人机技术的发展&#xff0c;航拍图像已广泛应用于交通监控、城市管理、灾害应急等多个领域。然而&#xff0c;由于无人机通常在较高的飞…

Excel如何把两列数据合并成一列,4种方法

Excel如何把两列数据合并成一列,4种方法 参考链接:https://baijiahao.baidu.com/s?id=1786337572531105925&wfr=spider&for=pc 在Excel中,有时候需要把两列或者多列数据合并到一列中,下面介绍4种常见方法,并且提示一些使用注意事项,总有一种方法符合你的要求:…

VSCode自定义插件创建教程

文章目录 一、前言二、插件维护三、调试插件四、使用 vsce 生成 vsix 插件五、问题&#xff1a;打开调试窗口后&#xff0c;输入helloworld并没有指令提示六、插件创建实战七、拓展阅读 一、前言 对于前端程序猿来讲&#xff0c;最常用的开发利器中VSCode首当其冲&#xff0c;…

HarmonyOS Next 关于页面渲染的性能优化方案

HarmonyOS Next 关于页面渲染的性能优化方案 HarmonyOS Next 应用开发中&#xff0c;用户的使用体验至关重要。其中用户启动APP到呈现页面主要包含三个步骤&#xff1a; 框架初始化页面加载布局渲染 从页面加载到布局渲染中&#xff0c;主要包含了6个环节&#xff1a; 执行页…

深度学习之目标检测的技巧汇总

1 Data Augmentation 介绍一篇发表在Big Data上的数据增强相关的文献综述。 Introduction 数据增强与过拟合 验证是否过拟合的方法&#xff1a;画出loss曲线&#xff0c;如果训练集loss持续减小但是验证集loss增大&#xff0c;就说明是过拟合了。 数据增强目的 通过数据增强…

记录下,用油猴Tampermonkey监听所有请求,绕过seesion

油猴Tampermonkey监听所有请求&#xff0c;绕过seesion 前因后果脚本编写 前因后果 原因是要白嫖一个网站的接口&#xff0c;这个接口的页面入口被隐藏掉了&#xff0c;不能通过页面调用&#xff0c;幸好之前有想过逆向破解通过账号密码模拟登录后拿到token&#xff0c;请求该…

百度遭初创企业指控抄袭,维权还是碰瓷?

“ 抄袭指控引发网友热议&#xff0c;有人支持其立场&#xff0c;也有人认为工具类产品在界面设计上相似度高是行业常态。 ” 转载|科技新知 原创 作者丨晓伊 编辑丨蕨影 一年一度的百度世界大会刚刚落幕&#xff0c;一家初创企业却站出来公开指责百度抄袭自家产品&#xff…

golang通用后台管理系统09(系统操作日志记录)

1.日志工具类 package log/**** 日志记录 wangwei 2024-11-18 15:30*/ import ("log""os""path/filepath""time" )// 获取以当前日期命名的日志文件路径 func getLogFilePath() string {currentDate : time.Now().Format("2006-…

迁移学习理论与应用

迁移学习&#xff08;Transfer Learning&#xff09;是一种机器学习技术&#xff0c;旨在将一个任务&#xff08;源任务&#xff09;上学到的知识迁移到另一个相关但不完全相同的任务&#xff08;目标任务&#xff09;上&#xff0c;从而提高目标任务的学习效果。这种方法的核心…

Azure Kubernetes Service (AKS)资源优化策略

针对Azure Kubernetes Service (AKS)的资源优化策略&#xff0c;可以从多个维度进行考虑和实施&#xff0c;以提升集群的性能、效率和资源利用率。以下是一些关键的优化策略&#xff1a; 一、 Pod资源请求和限制 设置Pod请求和限制&#xff1a;在YAML清单中为所有Pod设置CPU和…

Vue3 虚拟列表组件库 virtual-list-vue3 的使用

Vue3 虚拟列表组件库 virtual-list-vue3 的基本使用 分享个人写的一个基于 Vue3 的虚拟列表组件库&#xff0c;欢迎各位来进行使用与给予一些更好的建议&#x1f60a; 概述&#xff1a;该组件组件库用于提供虚拟化列表能力的组件&#xff0c;用于解决展示大量数据渲染时首屏渲…

qt之QFTP对文件夹(含嵌套文件夹和文件)、文件删除下载功能

一、前言 主要功能如下&#xff1a; 1.实现文件夹的下载和删除&#xff0c;网上很多资料都是单独对某个路径的文件操作的&#xff0c;并不能对文件夹操作 2.实现目标机中含中文名称自动转码&#xff0c;有些系统编码方式不同&#xff0c;下载出来的文件会乱码 3.实现ftp功能…

SpringBoot登录功能实现思路(验证码+拦截器+jwt)

总括 用户输入用户名和密码和验证码即可进行登录 验证码 VerifyCode&#xff1a;生成验证码的工具类 /*** 生成验证码的工具类*/ public class VerifyCode {private int w 70;//设置缓冲区的宽private int h 35;//设置缓冲区的宽private Random r new Random();//从字体…

小米路由器用外网域名访问管理界面

本文在Redmi AX3000 (RA81)设置&#xff0c;其他型号路由器的管理界面端口可能各不相同。 开始之前需要保证路由器SSH功能正常&#xff0c;如果没有SSH可以参考这里。 1. 给WAN口开放80端口 可以通过下载mixbox的firewall插件或者其他防火墙插件开放端口。 2. 把域名解析到路…

杰发科技AC7801——ADC定时器触发的简单使用

使用场景 在需要多次采样结果的情况下&#xff0c;比如1s需要10w次的采样结果&#xff0c;可以考虑使用定时器触发采样&#xff0c;定时器设置多少的时间就会多久采样转换一次。 再加上使用dma&#xff0c;采样的结果直接放在dma的数组里面。 实现了自动采样&#xff0c;自动…

pytest结合allure做接口自动化

这是一个采用pytest框架&#xff0c;结合allure完成接口自动化测试的项目&#xff0c;最后采用allure生成直观美观的测试报告&#xff0c;由于添加了allure的特性&#xff0c;使得测试报告覆盖的内容更全面和阅读起来更方便。 1. 使用pytest构建测试框架&#xff0c;首先配置好…