安全学习DAY23_Cookie&Session&Token

本文详细比较了Cookie和Session在存储位置、安全性、容量、生命周期和访问方式上的差异,以及Token在Web应用中的作用,强调了它们在身份验证和安全性的不同。同时讨论了学习网络安全的不同途径,包括专业学习、自学和培训。
文章目录
  • Cookie和Session的区别
  • Token的作用

Cookie和Session的区别

Cookie和Session都是用来在Web应用程序中跟踪用户状态的机制

1、存储位置不同:

Cookie是存储在客户端(浏览器)上的,而Session是存储在服务器端的。

2、安全性不同:

Cookie存储在客户端上,可能会被黑客利用窃取信息,而Session存储在服务器上,更加安全。

3、存储容量不同:

Cookie的存储容量有限,一般为4KB,而Session的存储容量理论上没有限制,取决于服务器的硬件和配置。

4、生命周期不同:

Cookie可以设置过期时间,即便关闭浏览器或者重新打开电脑,Cookie仍然存在,直到过期或者被删除。而Session一般默认在浏览器关闭后就会过期。

5、访问方式不同:

Cookie可以通过JavaScript访问,而Session只能在服务器端进行访问。

6、使用场景不同:

Cookie一般用于存储小型的数据,如用户的用户名和密码等信息。而Session一般用于存储大型的数据,如购物车、登录状态等信息。

总之,Cookie和Session都有各自的优缺点,选择使用哪一种方式,取决于具体的应用场景和需求。一般来说,如果需要存储敏感信息或者数据较大,建议使用Session;如果只需要存储少量的数据,并且需要在客户端进行访问,可以选择使用Cookie。

Token的作用

在Web应用程序中,使用token和不使用token的主要差异在于身份验证和安全性。

1.身份验证:采用token机制的Web应用程序,用户在登录成功后会收到一个token,这个token可以在每次请求时发送给服务器进行身份验证。而不采用token机制的Web应用程序,一般会使用session机制来保存用户登录状态,服务器会在用户登录成功后创建一个session,之后的每个请求都需要在HTTP头中附带这个session
ID,以便服务器能够验证用户身份。

2、安全性:采用token机制的Web应用程序,在服务器上不会存储用户的登录状态,只需要存储token即可。因此,即使token被盗取,黑客也无法获得用户的密码或者其他敏感信息。而不采用token机制的Web应用程序,一般会在服务器上存储用户的登录状态,因此如果服务器被黑客攻击,黑客可能会获得用户的敏感信息。

3、跨域访问:采用token机制的Web应用程序,在跨域访问时,可以使用HTTP头中的Authorization字段来传递token信息,方便实现跨域访问。而不采用token机制的Web应用程序,在跨域访问时,需使用cookie或session来传递用户身份信息,比较麻烦。

总之,采用token机制可以提高Web应用程序的安全性,并且方便实现跨域访问。不过,使用token机制也需要开发者自己来实现身份验证和token的生成和验证,相对来说比较复杂。而不采用token机制,使用session机制则相对简单,但是安全性相对较低。因此,具体采用哪种机制,需要根据实际情况进行权衡和选择。

学习网络安全技术的方法无非三种:

第一种是报网络安全专业,现在叫网络空间安全专业,主要专业课程:程序设计、计算机组成原理原理、数据结构、操作系统原理、数据库系统、 计算机网络、人工智能、自然语言处理、社会计算、网络安全法律法规、网络安全、内容安全、数字取证、机器学习,多媒体技术,信息检索、舆情分析等。

第二种是自学,就是在网上找资源、找教程,或者是想办法认识一-些大佬,抱紧大腿,不过这种方法很耗时间,而且学习没有规划,可能很长一段时间感觉自己没有进步,容易劝退。

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

第三种就是去找培训。

image.png

接下来,我会教你零基础入门快速入门上手网络安全。

网络安全入门到底是先学编程还是先学计算机基础?这是一个争议比较大的问题,有的人会建议先学编程,而有的人会建议先学计算机基础,其实这都是要学的。而且这些对学习网络安全来说非常重要。但是对于完全零基础的人来说又或者急于转行的人来说,学习编程或者计算机基础对他们来说都有一定的难度,并且花费时间太长。

第一阶段:基础准备 4周~6周

这个阶段是所有准备进入安全行业必学的部分,俗话说:基础不劳,地动山摇
image.png

第二阶段:web渗透

学习基础 时间:1周 ~ 2周:

① 了解基本概念:(SQL注入、XSS、上传、CSRF、一句话木马、等)为之后的WEB渗透测试打下基础。
② 查看一些论坛的一些Web渗透,学一学案例的思路,每一个站点都不一样,所以思路是主要的。
③ 学会提问的艺术,如果遇到不懂得要善于提问。
image.png

配置渗透环境 时间:3周 ~ 4周:

① 了解渗透测试常用的工具,例如(AWVS、SQLMAP、NMAP、BURP、中国菜刀等)。
② 下载这些工具无后门版本并且安装到计算机上。
③ 了解这些工具的使用场景,懂得基本的使用,推荐在Google上查找。

渗透实战操作 时间:约6周:

① 在网上搜索渗透实战案例,深入了解SQL注入、文件上传、解析漏洞等在实战中的使用。
② 自己搭建漏洞环境测试,推荐DWVA,SQLi-labs,Upload-labs,bWAPP。
③ 懂得渗透测试的阶段,每一个阶段需要做那些动作:例如PTES渗透测试执行标准。
④ 深入研究手工SQL注入,寻找绕过waf的方法,制作自己的脚本。
⑤ 研究文件上传的原理,如何进行截断、双重后缀欺骗(IIS、PHP)、解析漏洞利用(IIS、Nignix、Apache)等,参照:上传攻击框架。
⑥ 了解XSS形成原理和种类,在DWVA中进行实践,使用一个含有XSS漏洞的cms,安装安全狗等进行测试。
⑦ 了解一句话木马,并尝试编写过狗一句话。
⑧ 研究在Windows和Linux下的提升权限,Google关键词:提权
image.png
以上就是入门阶段

第三阶段:进阶

已经入门并且找到工作之后又该怎么进阶?详情看下图
image.png

给新手小白的入门建议:
新手入门学习最好还是从视频入手进行学习,视频的浅显易懂相比起晦涩的文字而言更容易吸收,这里我给大家准备了一套网络安全从入门到精通的视频学习资料包免费领取哦!

如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!

<?php defined('ABSPATH') || exit; /** * Robust partial checkout to regular /checkout/ with durable cart snapshot * - Snapshot full cart before virtualizing selection for checkout * - Do not remove anything until order is created * - On success (thank-you), rebuild cart as (snapshot - purchased) * - On cancel/back (visit cart), restore snapshot * - Guest resilience: localStorage + rehydrate AJAX */ /* ------------------------------------------------- * Helpers * ------------------------------------------------- */ /** * 新增:购物车数量AJAX端点 */ add_action('wp_ajax_get_cart_count', 'pc_get_cart_count'); add_action('wp_ajax_nopriv_get_cart_count', 'pc_get_cart_count'); function pc_get_cart_count() { check_ajax_referer('woocommerce-cart', 'security'); $count = WC()->cart->get_cart_contents_count(); wp_send_json_success(array('count' => $count)); } function pc_get_cart_uid() { if (is_user_logged_in()) { return 'user_' . get_current_user_id(); } if (empty($_COOKIE['pc_cart_uid'])) { $token = wp_generate_uuid4(); setcookie('pc_cart_uid', $token, time() + YEAR_IN_SECONDS, COOKIEPATH ?: '/', '', is_ssl(), false); $_COOKIE['pc_cart_uid'] = $token; } return 'guest_' . sanitize_text_field(wp_unslash($_COOKIE['pc_cart_uid'])); } function pc_build_item_key($product_id, $variation_id = 0) { return (int)$product_id . '|' . (int)$variation_id; } function pc_snapshot_current_cart() { if (!WC()->cart) wc_load_cart(); $items = array(); foreach (WC()->cart->get_cart() as $ci_key => $ci) { $pid = isset($ci['product_id']) ? (int)$ci['product_id'] : 0; $vid = isset($ci['variation_id']) ? (int)$ci['variation_id'] : 0; $qty = isset($ci['quantity']) ? wc_stock_amount($ci['quantity']) : 0; $var = isset($ci['variation']) && is_array($ci['variation']) ? $ci['variation'] : array(); if ($pid && $qty > 0) { $items[] = array( 'product_id' => $pid, 'variation_id' => $vid, 'variation' => array_map('wc_clean', $var), 'quantity' => $qty, ); } } return $items; } function pc_restore_cart_from_items($items) { if (!WC()->cart) wc_load_cart(); WC()->cart->empty_cart(); foreach ((array)$items as $it) { $pid = isset($it['product_id']) ? (int)$it['product_id'] : 0; $vid = isset($it['variation_id']) ? (int)$it['variation_id'] : 0; $qty = isset($it['quantity']) ? wc_stock_amount($it['quantity']) : 0; $var = isset($it['variation']) && is_array($it['variation']) ? array_map('wc_clean', $it['variation']) : array(); if ($pid && $qty > 0) { WC()->cart->add_to_cart($pid, $qty, $vid, $var); } } WC()->cart->calculate_totals(); } // Fixed: Check WC() and session existence before method_exists add_action('wp_loaded', function() { if (!function_exists('WC') || !WC() || !property_exists(WC(), 'session')) { return; } if (!method_exists(WC()->session, 'get')) return; $token = WC()->session->get('pc_partial_token'); if ($token && WC()->cart->is_empty()) { $payload = get_transient(pc_transient_key($token)); if (!empty($payload['snapshot'])) { pc_restore_cart_from_items($payload['snapshot']); WC()->cart->calculate_totals(); } } }, 20); function pc_transient_key($token) { return 'pc_partial_payload_' . sanitize_key($token); } /* ------------------------------------------------- * AJAX: Local rehydrate when Woo cart is empty * ------------------------------------------------- */ add_action('wp_ajax_pc_rehydrate_cart', 'pc_rehydrate_cart'); add_action('wp_ajax_nopriv_pc_rehydrate_cart', 'pc_rehydrate_cart'); function pc_rehydrate_cart() { check_ajax_referer('woocommerce-cart', 'security'); $raw = isset($_POST['items']) ? wp_unslash($_POST['items']) : ''; $items = is_string($raw) ? json_decode($raw, true) : (array)$raw; if (!is_array($items)) { wp_send_json_error(array('message' => 'Invalid items.'), 400); } if (!WC()->cart) wc_load_cart(); if (!WC()->cart->is_empty()) { wp_send_json_success(array('message' => 'Cart not empty.')); } foreach ($items as $it) { $pid = isset($it['product_id']) ? (int)$it['product_id'] : 0; $vid = isset($it['variation_id']) ? (int)$it['variation_id'] : 0; $qty = isset($it['quantity']) ? wc_stock_amount($it['quantity']) : 0; $var = isset($it['variation']) && is_array($it['variation']) ? array_map('wc_clean', $it['variation']) : array(); if ($pid && $qty > 0) { WC()->cart->add_to_cart($pid, $qty, $vid, $var); } } WC()->cart->calculate_totals(); wp_send_json_success(array('rehydrated' => true)); } /* ------------------------------------------------- * AJAX: Update qty (per-row; no page reload) * ------------------------------------------------- */ add_action('wp_ajax_update_cart_item_qty', 'pc_update_cart_item_qty'); add_action('wp_ajax_nopriv_update_cart_item_qty', 'pc_update_cart_item_qty'); function pc_update_cart_item_qty() { check_ajax_referer('woocommerce-cart', 'security'); $key = isset($_POST['cart_item_key']) ? wc_clean(wp_unslash($_POST['cart_item_key'])) : ''; $qty = isset($_POST['qty']) ? wc_stock_amount($_POST['qty']) : null; if (!$key || $qty === null) { wp_send_json_error(array('message' => 'Missing params.'), 400); } if (!WC()->cart) wc_load_cart(); if ($qty <= 0) { $removed = WC()->cart->remove_cart_item($key); WC()->cart->calculate_totals(); wp_send_json_success(array('removed' => (bool)$removed)); } else { $set = WC()->cart->set_quantity($key, $qty, true); WC()->cart->calculate_totals(); $cart_item = WC()->cart->get_cart_item($key); if (!$cart_item) { wp_send_json_error(array('message' => 'Cart item not found after update.'), 404); } $_product = $cart_item['data']; $subtotal_html = apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal($_product, $cart_item['quantity']), $cart_item, $key ); // Use line_total + line_tax (after totals) for checkbox data-price $line_total_incl_tax = (float)($cart_item['line_total'] + $cart_item['line_tax']); wp_send_json_success(array( 'subtotal_html' => $subtotal_html, 'line_total_incl_tax' => $line_total_incl_tax, 'removed' => false, )); } } /* ------------------------------------------------- * AJAX: Remove selected * ------------------------------------------------- */ add_action('wp_ajax_remove_selected_cart_items', 'pc_remove_selected_cart_items'); add_action('wp_ajax_nopriv_remove_selected_cart_items', 'pc_remove_selected_cart_items'); function pc_remove_selected_cart_items() { check_ajax_referer('woocommerce-cart', 'security'); $keys = isset($_POST['selected_items']) ? (array) $_POST['selected_items'] : array(); if (!WC()->cart) wc_load_cart(); foreach ($keys as $k) { $k = wc_clean(wp_unslash($k)); WC()->cart->remove_cart_item($k); } WC()->cart->calculate_totals(); wp_send_json_success(true); } /* ------------------------------------------------- * AJAX: Empty cart * ------------------------------------------------- */ add_action('wp_ajax_empty_cart', 'pc_empty_cart'); add_action('wp_ajax_nopriv_empty_cart', 'pc_empty_cart'); function pc_empty_cart() { check_ajax_referer('woocommerce-cart', 'security'); if (!WC()->cart) wc_load_cart(); WC()->cart->empty_cart(); wp_send_json_success(true); } /* ------------------------------------------------- * AJAX: Apply coupon * ------------------------------------------------- */ add_action('wp_ajax_apply_coupon', 'pc_apply_coupon'); add_action('wp_ajax_nopriv_apply_coupon', 'pc_apply_coupon'); function pc_apply_coupon() { check_ajax_referer('woocommerce-cart', 'security'); $code = isset($_POST['coupon_code']) ? wc_format_coupon_code(wp_unslash($_POST['coupon_code'])) : ''; if (!$code) { wp_send_json_error(array('message' => __('请输入优惠券代码', 'woocommerce')), 400); } if (!WC()->cart) wc_load_cart(); $applied = WC()->cart->apply_coupon($code); WC()->cart->calculate_totals(); if (is_wp_error($applied)) { wp_send_json_error(array('message' => $applied->get_error_message()), 400); } if (!$applied) { wp_send_json_error(array('message' => __('优惠券应用失败', 'woocommerce')), 400); } wp_send_json_success(true); } /* ------------------------------------------------- * AJAX: Start partial checkout to regular checkout page * ------------------------------------------------- */ add_action('wp_ajax_create_direct_order', 'pc_create_direct_order'); add_action('wp_ajax_nopriv_create_direct_order', 'pc_create_direct_order'); function pc_create_direct_order() { check_ajax_referer('woocommerce-cart', 'security'); $selected_keys = isset($_POST['selected_items']) ? (array) $_POST['selected_items'] : array(); if (empty($selected_keys)) { wp_send_json_error(array('message' => __('请选择要结算的商品', 'woocommerce')), 400); } if (!WC()->cart) wc_load_cart(); // Snapshot full cart $snapshot = pc_snapshot_current_cart(); // Build selected items from current cart based on cart_item_key list $selected = array(); foreach (WC()->cart->get_cart() as $ci_key => $ci) { if (!in_array($ci_key, $selected_keys, true)) { continue; } $pid = (int)$ci['product_id']; $vid = (int)$ci['variation_id']; $qty = wc_stock_amount($ci['quantity']); $var = isset($ci['variation']) && is_array($ci['variation']) ? array_map('wc_clean', $ci['variation']) : array(); if ($pid && $qty > 0) { $selected[] = array( 'product_id' => $pid, 'variation_id' => $vid, 'variation' => $var, 'quantity' => $qty, ); } } if (empty($selected)) { wp_send_json_error(array('message' => __('没有可结算的商品', 'woocommerce')), 400); } $token = wp_generate_uuid4(); $payload = array( 'uid' => pc_get_cart_uid(), 'snapshot' => $snapshot, 'selected' => $selected, 'created' => time(), ); set_transient(pc_transient_key($token), $payload, 2 * DAY_IN_SECONDS); // Put token in session (used across checkout AJAX calls) if (method_exists(WC()->session, 'set')) { WC()->session->set('pc_partial_token', $token); } $checkout_url = add_query_arg('pc_token', rawurlencode($token), wc_get_checkout_url()); wp_send_json_success(array('checkout_url' => $checkout_url)); } /* ------------------------------------------------- * Virtualize cart on checkout for token and rebuild after purchase * ------------------------------------------------- */ // Entering checkout with token: virtualize cart to selected items add_action('woocommerce_before_checkout_form', function() { if (!isset($_GET['pc_token'])) return; $token = sanitize_text_field(wp_unslash($_GET['pc_token'])); $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload['selected'])) return; if (!WC()->cart) wc_load_cart(); // Virtualize to selected items only pc_restore_cart_from_items($payload['selected']); // Persist token in session for all subsequent checkout AJAX calls if (method_exists(WC()->session, 'set')) { WC()->session->set('pc_partial_token', $token); } }, 1); // Safety: just-in-time re-virtualization before order processing add_action('woocommerce_before_checkout_process', function() { if (!method_exists(WC()->session, 'get')) return; $token = WC()->session->get('pc_partial_token'); if (!$token) return; $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload['selected'])) return; // Ensure cart still equals selected set pc_restore_cart_from_items($payload['selected']); }, 1); // Tag order with token add_action('woocommerce_checkout_create_order', function($order) { $token = null; if (isset($_GET['pc_token'])) { $token = sanitize_text_field(wp_unslash($_GET['pc_token'])); } elseif (method_exists(WC()->session, 'get')) { $token = WC()->session->get('pc_partial_token'); } if ($token) { $order->update_meta_data('_pc_partial_token', $token); $order->update_meta_data('_pc_cart_snapshot', $token); } }, 10, 1); // Fixed: Only remove purchased items from cart add_action('woocommerce_thankyou', function($order_id) { $order = wc_get_order($order_id); if (!$order) return; $token = $order->get_meta('_pc_partial_token'); if (!$token) return; $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload['snapshot'])) { if (method_exists(WC()->session, 'set')) { WC()->session->set('pc_partial_token', null); } delete_transient(pc_transient_key($token)); return; } // 1. Restore FULL snapshot (all items) pc_restore_cart_from_items($payload['snapshot']); WC()->cart->calculate_totals(); // 2. Remove only the purchased (selected) items foreach ($payload['selected'] as $selected_item) { $cart_item_key = pc_find_cart_item($selected_item['product_id'], $selected_item['variation_id']); if ($cart_item_key) { WC()->cart->remove_cart_item($cart_item_key); } } // 3. Update cart totals WC()->cart->calculate_totals(); // Cleanup token if (method_exists(WC()->session, 'set')) { WC()->session->set('pc_partial_token', null); } delete_transient(pc_transient_key($token)); }, 20); // Helper: Find cart item by product and variation ID function pc_find_cart_item($product_id, $variation_id = 0) { if (!WC()->cart) wc_load_cart(); foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) { $cart_pid = isset($cart_item['product_id']) ? (int)$cart_item['product_id'] : 0; $cart_vid = isset($cart_item['variation_id']) ? (int)$cart_item['variation_id'] : 0; if ($cart_pid == $product_id && $cart_vid == $variation_id) { return $cart_item_key; } } return false; } // Visiting cart with active token: restore full snapshot (cancel/back) add_action('woocommerce_before_cart', function() { if (!method_exists(WC()->session, 'get')) return; $token = WC()->session->get('pc_partial_token'); if (!$token) return; $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload['snapshot'])) return; // Restore full snapshot so cart page always shows everything pc_restore_cart_from_items($payload['snapshot']); }, 1); /* ------------------------------------------------- * Keep cart count accurate during checkout process * ------------------------------------------------- */ add_filter('woocommerce_cart_contents_count', function($count) { // Check if partial token exists if (!method_exists(WC()->session, 'get')) return $count; $token = WC()->session->get('pc_partial_token'); if ($token) { $payload = get_transient(pc_transient_key($token)); // Always show full cart count even during checkout if (!empty($payload['snapshot'])) { $snapshot_count = 0; foreach ($payload['snapshot'] as $item) { $snapshot_count += (int)$item['quantity']; } return $snapshot_count; } } return $count; }); // Ensure cart item totals are accurate in header add_action('woocommerce_before_cart', function() { pc_maintain_cart_consistency(); }); add_action('woocommerce_before_checkout_form', function() { pc_maintain_cart_consistency(); }); function pc_maintain_cart_consistency() { if (!method_exists(WC()->session, 'get')) return; $token = WC()->session->get('pc_partial_token'); if (!$token) return; $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload['snapshot'])) return; // Immediately restore full cart for consistent UI pc_restore_cart_from_items($payload['snapshot']); WC()->cart->calculate_totals(); } it says Your PHP code changes were not applied due to an error on line 86 of file wp-content/themes/woodmart-child/functions.php. Please fix and try saving again. Uncaught TypeError: method_exists(): Argument #1 ($object_or_class) must be of type object|string, null given in wp-content/themes/woodmart-child/functions.php:86 Stack trace: #0 wp-content/themes/woodmart-child/functions.php(86): method_exists() #1 wp-includes/class-wp-hook.php(324): {closure}() #2 wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters() #3 wp-includes/plugin.php(517): WP_Hook->do_action() #4 wp-settings.php(749): do_action() #5 wp-config.php(105): require_once('/home/u18285596...') #6 wp-load.php(50): require_once('/home/u18285596...') #7 wp-admin/admin.php(35): require_once('/home/u18285596...') #8 wp-admin/theme-editor.php(10): require_once('/home/u18285596...') #9 {main} thrown Please regenerate the FULL CODE for me to be replaced with the current one in functions.php
09-06
cart)) { WC()->cart = new WC_Cart(); } } } /** * 获取当前购物车的快照 */ function pc_snapshot_current_cart() { if (!WC()->cart) wc_load_cart(); $items = array(); foreach (WC()->cart->get_cart() as $ci_key => $ci) { $pid = isset($ci['product_id']) ? (int)$ci['product_id'] : 0; $vid = isset($ci['variation_id']) ? (int)$ci['variation_id'] : 0; $qty = isset($ci['quantity']) ? wc_stock_amount($ci['quantity']) : 0; $var = isset($ci['variation']) && is_array($ci['variation']) ? $ci['variation'] : array(); if ($pid && $qty > 0) { $items[] = array( 'product_id' => $pid, 'variation_id' => $vid, 'variation' => array_map('wc_clean', $var), 'quantity' => $qty, ); } } return $items; } /** * 从快照恢复购物车 */ function pc_restore_cart_from_items($items) { if (!WC()->cart) wc_load_cart(); WC()->cart->empty_cart(); foreach ((array)$items as $it) { $pid = isset($it['product_id']) ? (int)$it['product_id'] : 0; $vid = isset($it['variation_id']) ? (int)$it['variation_id'] : 0; $qty = isset($it['quantity']) ? wc_stock_amount($it['quantity']) : 0; $var = isset($it['variation']) && is_array($it['variation']) ? array_map('wc_clean', $it['variation']) : array(); if ($pid && $qty > 0) { WC()->cart->add_to_cart($pid, $qty, $vid, $var); } } WC()->cart->calculate_totals(); } /** * 生成瞬态键名 */ function pc_transient_key($token) { return 'pc_partial_payload_' . sanitize_key($token); } /** * 构建商品项唯一键 */ function pc_build_item_key($product_id, $variation_id = 0) { return $product_id . '_' . $variation_id; } /** * 获取购物车用户标识 */ function pc_get_cart_uid() { if (is_user_logged_in()) { return 'user_' . get_current_user_id(); } else { if (empty($_COOKIE['pc_cart_uid'])) { $token = wp_generate_uuid4(); setcookie('pc_cart_uid', $token, time() + YEAR_IN_SECONDS, COOKIEPATH ?: '/', '', is_ssl(), false); $_COOKIE['pc_cart_uid'] = $token; } return 'guest_' . sanitize_text_field(wp_unslash($_COOKIE['pc_cart_uid'])); } } /* ------------------------------------------------- * AJAX: 当购物车为空时恢复购物车 * ------------------------------------------------- */ add_action('wp_ajax_pc_rehydrate_cart', 'pc_rehydrate_cart'); add_action('wp_ajax_nopriv_pc_rehydrate_cart', 'pc_rehydrate_cart'); function pc_rehydrate_cart() { check_ajax_referer('woocommerce-cart', 'security'); $raw = isset($_POST['items']) ? wp_unslash($_POST['items']) : ''; $items = is_string($raw) ? json_decode($raw, true) : (array)$raw; if (!is_array($items)) { wp_send_json_error(array('message' => '无效的商品数据'), 400); } if (!WC()->cart) wc_load_cart(); if (!WC()->cart->is_empty()) { wp_send_json_success(array('message' => '购物车非空')); } foreach ($items as $it) { $pid = isset($it['product_id']) ? (int)$it['product_id'] : 0; $vid = isset($it['variation_id']) ? (int)$it['variation_id'] : 0; $qty = isset($it['quantity']) ? wc_stock_amount($it['quantity']) : 0; $var = isset($it['variation']) && is_array($it['variation']) ? array_map('wc_clean', $it['variation']) : array(); if ($pid && $qty > 0) { WC()->cart->add_to_cart($pid, $qty, $vid, $var); } } WC()->cart->calculate_totals(); wp_send_json_success(array('rehydrated' => true)); } /* ------------------------------------------------- * AJAX: 更新商品数量 (无需刷新页面) * ------------------------------------------------- */ add_action('wp_ajax_update_cart_item_qty', 'pc_update_cart_item_qty'); add_action('wp_ajax_nopriv_update_cart_item_qty', 'pc_update_cart_item_qty'); function pc_update_cart_item_qty() { check_ajax_referer('woocommerce-cart', 'security'); $key = isset($_POST['cart_item_key']) ? wc_clean(wp_unslash($_POST['cart_item_key'])) : ''; $qty = isset($_POST['qty']) ? wc_stock_amount($_POST['qty']) : null; if (!$key || $qty === null) { wp_send_json_error(array('message' => '缺少参数'), 400); } if (!WC()->cart) wc_load_cart(); if ($qty <= 0) { $removed = WC()->cart->remove_cart_item($key); WC()->cart->calculate_totals(); wp_send_json_success(array('removed' => (bool)$removed)); } else { $set = WC()->cart->set_quantity($key, $qty, true); WC()->cart->calculate_totals(); $cart_item = WC()->cart->get_cart_item($key); if (!$cart_item) { wp_send_json_error(array('message' => '更新后找不到商品'), 404); } $_product = $cart_item['data']; $subtotal_html = apply_filters('woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal($_product, $cart_item['quantity']), $cart_item, $key); $line_total_incl_tax = (float)($cart_item['line_total'] + $cart_item['line_tax']); wp_send_json_success(array( 'subtotal_html' => $subtotal_html, 'line_total_incl_tax' => $line_total_incl_tax, 'removed' => false )); } } /* ------------------------------------------------- * AJAX: 删除选中商品 * ------------------------------------------------- */ add_action('wp_ajax_remove_selected_cart_items', 'pc_remove_selected_cart_items'); add_action('wp_ajax_nopriv_remove_selected_cart_items', 'pc_remove_selected_cart_items'); function pc_remove_selected_cart_items() { check_ajax_referer('woocommerce-cart', 'security'); $keys = isset($_POST['selected_items']) ? (array) $_POST['selected_items'] : array(); if (!WC()->cart) wc_load_cart(); foreach ($keys as $k) { $k = wc_clean(wp_unslash($k)); WC()->cart->remove_cart_item($k); } WC()->cart->calculate_totals(); wp_send_json_success(true); } /* ------------------------------------------------- * AJAX: 清空购物车 * ------------------------------------------------- */ add_action('wp_ajax_empty_cart', 'pc_empty_cart'); add_action('wp_ajax_nopriv_empty_cart', 'pc_empty_cart'); function pc_empty_cart() { check_ajax_referer('woocommerce-cart', 'security'); if (!WC()->cart) wc_load_cart(); WC()->cart->empty_cart(); wp_send_json_success(true); } /* ------------------------------------------------- * AJAX: 应用优惠券 * ------------------------------------------------- */ add_action('wp_ajax_apply_coupon', 'pc_apply_coupon'); add_action('wp_ajax_nopriv_apply_coupon', 'pc_apply_coupon'); function pc_apply_coupon() { check_ajax_referer('woocommerce-cart', 'security'); $code = isset($_POST['coupon_code']) ? wc_format_coupon_code(wp_unslash($_POST['coupon_code'])) : ''; if (!$code) { wp_send_json_error(array('message' => __('请输入优惠券代码', 'woocommerce')), 400); } if (!WC()->cart) wc_load_cart(); $applied = WC()->cart->apply_coupon($code); WC()->cart->calculate_totals(); if (is_wp_error($applied)) { wp_send_json_error(array('message' => $applied->get_error_message()), 400); } if (!$applied) { wp_send_json_error(array('message' => __('优惠券应用失败', 'woocommerce')), 400); } wp_send_json_success(true); } /* ------------------------------------------------- * AJAX: 创建部分结算订单 * - 将快照和选中商品存储在瞬态中 * - 将会话中的token标记 * - 返回结账URL * ------------------------------------------------- */ add_action('wp_ajax_create_direct_order', 'pc_create_direct_order'); add_action('wp_ajax_nopriv_create_direct_order', 'pc_create_direct_order'); function pc_create_direct_order() { check_ajax_referer('woocommerce-cart', 'security'); // 初始化会话 if (!WC()->session) { WC()->session = new WC_Session_Handler(); WC()->session->init(); } $selected_keys = isset($_POST['selected_items']) ? (array) $_POST['selected_items'] : array(); if (empty($selected_keys)) { wp_send_json_error(array('message' => __('请选择要结算的商品', 'woocommerce')), 400); } if (!WC()->cart) wc_load_cart(); // 创建完整购物车快照 $snapshot = pc_snapshot_current_cart(); // 提取选中商品 $selected = array(); foreach (WC()->cart->get_cart() as $ci_key => $ci) { if (!in_array($ci_key, $selected_keys, true)) { continue; } $pid = isset($ci['product_id']) ? (int)$ci['product_id'] : 0; $vid = isset($ci['variation_id']) ? (int)$ci['variation_id'] : 0; $qty = isset($ci['quantity']) ? wc_stock_amount($ci['quantity']) : 0; $var = isset($ci['variation']) && is_array($ci['variation']) ? array_map('wc_clean', $ci['variation']) : array(); if ($pid && $qty > 0) { $selected[] = array( 'product_id' => $pid, 'variation_id' => $vid, 'variation' => $var, 'quantity' => $qty, ); } } if (empty($selected)) { wp_send_json_error(array('message' => __('没有可结算的商品', 'woocommerce')), 400); } $token = wp_generate_uuid4(); $payload = array( 'uid' => pc_get_cart_uid(), 'snapshot' => $snapshot, 'selected' => $selected, 'created' => time(), ); set_transient(pc_transient_key($token), $payload, 2 * DAY_IN_SECONDS); // 将token存入会话 if (method_exists(WC()->session, 'set')) { WC()->session->set('pc_partial_token', $token); } $checkout_url = add_query_arg('pc_token', rawurlencode($token), wc_get_checkout_url()); wp_send_json_success(array('checkout_url' => $checkout_url)); } /* ------------------------------------------------- * 结账流程处理 * - 根据token虚拟化购物车 * - 处理前确保重新虚拟化 * - 订单标记token * - 感谢页重建购物车 * - 返回购物车时恢复快照 * ------------------------------------------------- */ // 进入结账页时虚拟化购物车 add_action('woocommerce_before_checkout_form', 'pc_virtualize_cart_on_checkout', 1); function pc_virtualize_cart_on_checkout() { if (!isset($_GET['pc_token'])) return; $token = sanitize_text_field(wp_unslash($_GET['pc_token'])); $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload['selected'])) return; if (!WC()->cart) wc_load_cart(); // 仅加载选中商品 pc_restore_cart_from_items($payload['selected']); // 持久化token用于后续AJAX调用 if (method_exists(WC()->session, 'set')) { WC()->session->set('pc_partial_token', $token); } } // 订单处理前再次确保虚拟化 add_action('woocommerce_before_checkout_process', 'pc_revirtualize_before_processing', 1); function pc_revirtualize_before_processing() { if (!method_exists(WC()->session, 'get')) return; $token = WC()->session->get('pc_partial_token'); if (!$token) return; $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload['selected'])) return; pc_restore_cart_from_items($payload['selected']); } // 订单标记token add_action('woocommerce_checkout_create_order', 'pc_tag_order_with_token', 10, 1); function pc_tag_order_with_token($order) { $token = null; if (isset($_GET['pc_token'])) { $token = sanitize_text_field(wp_unslash($_GET['pc_token'])); } elseif (method_exists(WC()->session, 'get')) { $token = WC()->session->get('pc_partial_token'); } if ($token) { $order->update_meta_data('_pc_partial_token', $token); } } // 感谢页重建购物车 add_action('woocommerce_thankyou', 'pc_rebuild_cart_on_thankyou', 20); function pc_rebuild_cart_on_thankyou($order_id) { $order = wc_get_order($order_id); if (!$order) return; $token = $order->get_meta('_pc_partial_token'); if (!$token) return; $payload = get_transient(pc_transient_key($token)); if (empty($payload) || empty($payload['snapshot'])) { // 清理会话token if (method_exists(WC()->session, 'set')) { WC()->session->set('pc_part极 token', null); } delete_transient(pc_transient_key($token)); return; } // 创建已购商品映射表 $purchased = array(); foreach ($order->get_items() as $item) { $pid = (int)$item->get_product_id(); $vid = (int)$item->get_variation_id(); $qty = (int)$item->get_quantity(); $k = pc_build_item_key($pid, $vid); if (!isset($purchased[$k])) $purchased[$极] = 0; $purchased[$k] += $qty; } // 剩余商品 = 快照 - 已购 $remainder = array(); foreach ($payload['snapshot'] as $it) { $pid = isset($it['product_id']) ? (int)$it['product_id'] : 0; $vid = isset($it['variation_id']) ? (int)$it['variation_id'] : 0; $qty = isset($it['quantity']) ? wc_stock_amount($it['quantity']) : 0; $var = isset($it['variation']) ? $it['variation'] : array(); $k = pc_build_item_key($pid, $vid); $take = isset($purchased[$k]) ? (int)$purchased[$k] : 0; $left = max(0, $qty - $take); if ($left > 0) { $remainder[] = array( 'product_id' => $pid, 'variation_id' => $vid, 'variation' => $var, 'quantity' => $left, ); $purchased[$k] = max(0, $take - $qty); } } // 重建剩余商品的购物车 pc_restore_cart_from_items($remainder); // 清理会话token if (method_exists(WC()->session, 'set')) { WC()->session->set('pc_partial_token', null); } delete_transient(pc_transient_key($token)); } /* ------------------------------------------------- * 支付取消处理 * - 当订单 你修复到functions.php的这里而已,麻烦从这里开始,继续下去 /* ------------------------------------------------- * 支付取消处理 * - 当订单
09-03
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值