woocommerce/.ai/skills/woocommerce-backend-dev/zh-cn/data-integrity.md
2026-04-15 10:18:01 +08:00

4.1 KiB
Raw Permalink Blame History

数据完整性指南

目录

防止意外数据丢失

在删除/修改前总是验证实体状态,以防止意外数据丢失。

删除前的验证

在删除或修改实体前,总是验证实体的状态。

例子:删除草稿订单

// 正确:删除前验证订单状态
public function delete_draft_order( int $order_id ) {
    $order = wc_get_order( $order_id );

    if ( ! $order ) {
        return false;
    }

    // 验证它确实是草稿或结账草稿
    if ( ! in_array( $order->get_status(), array( 'draft', 'checkout-draft' ), true ) ) {
        throw new \Exception( 'Cannot delete non-draft order' );
    }

    return $order->delete( true );
}

// 错误:没有验证
public function delete_draft_order( int $order_id ) {
    $order = wc_get_order( $order_id );
    return $order->delete( true );  // 可能会删除任何订单!
}

考虑竞争条件

思考是否可能出现影响错误数据的竞争条件。

示例:用户特定数据删除

// 良好:在删除前验证所有权
public function delete_user_cart_item( int $item_id, int $user_id ) {
    $item = $this->get_cart_item( $item_id );

    if ( ! $item ) {
        return false;
    }

    // 防止竞争条件:验证项目属于此用户
    if ( (int) $item->get_user_id() !== $user_id ) {
        throw new \Exception( '无法删除属于其他用户的项目' );
    }

    return $this->data_store->delete( $item_id );
}

// 不良:可能存在竞争条件
public function delete_user_cart_item( int $item_id, int $user_id ) {
    // 在此期间,其他用户可能已获取此项目
    return $this->data_store->delete( $item_id );
}

基于会话的操作

对于基于会话的操作(如购物车或结账),请验证会话所有权。

例子:清除结账数据

// 良好做法:验证会话所有权
public function clear_checkout_data( int $session_id ) {
    $current_session_id = WC()->session->get_customer_id();

    if ( $session_id !== $current_session_id ) {
        throw new \Exception( 'Cannot clear checkout data for another session' );
    }

    WC()->session->set( 'checkout_data', array() );
}

如有疑问,请询问

如果不确定数据操作,请澄清以下内容:

  • 必需的州/所有权验证
  • 软删除与硬删除的必需条件
  • 防止删除的受保护州

数据操作安全检查清单

在实现修改或删除数据的代码前:

  • 验证实体存在
  • 验证实体状态(状态、类型等)
  • 验证所有权user_id、session_id 等)
  • 检查竞态条件
  • 考虑使用软删除(回收站)而非硬删除
  • 添加适当的错误处理
  • 记录敏感操作以供审计追踪
  • 添加权限检查(current_user_can()

常见陷阱与规避方法

1. 盲目信任用户输入

// 错误示例
$order_id = $_POST['order_id'];
$order->delete( true );

// 正确示例
$order_id = absint( $_POST['order_id'] );
if ( ! current_user_can( 'delete_order', $order_id ) ) {
    wp_die( 'Unauthorized' );
}
// ... 执行其他验证 ...

2. 无需验证的批量操作

// 错误:未经验证删除全部
foreach ( $order_ids as $order_id ) {
    wc_delete_order( $order_id );
}

// 正确:验证每个项目
foreach ( $order_ids as $order_id ) {
    $order = wc_get_order( $order_id );
    if ( $order && $order->get_status() === 'draft' ) {
        wc_delete_order( $order_id );
    }
}

3. 忽略返回值

// 错误:未检查操作是否成功
$order->delete( true );
wp_send_json_success();

// 正确:检查结果
if ( $order->delete( true ) ) {
    wp_send_json_success();
} else {
    wp_send_json_error( '删除订单失败' );
}