CodeIgniter 4构造函数参数实战详解(高级用法大揭秘)

第一章:CodeIgniter 4构造函数参数概述

在 CodeIgniter 4 中,控制器的构造函数(constructor)是初始化操作的核心入口。与早期版本不同,CodeIgniter 4 不再推荐在构造函数中直接调用父类构造函数 parent::__construct() 来加载核心服务,而是通过依赖注入机制自动处理。框架利用 PHP 的类型提示功能,在构造函数中注入所需的服务类实例,从而实现更灵活、可测试性更强的代码结构。

构造函数中的依赖注入

CodeIgniter 4 支持通过构造函数参数自动解析并注入服务容器中注册的类。常见注入对象包括请求、响应、会话等核心组件。
namespace App\Controllers;

use CodeIgniter\Controller;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;

class Home extends Controller
{
    protected $request;

    public function __construct(RequestInterface $request)
    {
        // 自动注入请求对象
        $this->request = $request;
    }

    public function index()
    {
        // 使用注入的请求对象获取输入数据
        $name = $this->request->getGet('name');
        return $this->response->setJSON(['hello' => $name]);
    }
}
上述代码中,RequestInterface 被自动解析为当前请求实例,无需手动初始化。

支持的可注入服务

以下为常用可注入接口及其用途:
接口名用途说明
RequestInterface获取客户端请求数据,如 GET/POST 参数
ResponseInterface构建并发送 HTTP 响应
SessionInterface管理用户会话状态
  • 构造函数注入提升了代码解耦性
  • 避免了在方法内频繁使用 service() 函数获取实例
  • 便于单元测试时模拟依赖对象

第二章:构造函数参数的基础与依赖注入机制

2.1 构造函数参数在MVC架构中的作用解析

在MVC(Model-View-Controller)架构中,构造函数参数承担着依赖注入和组件解耦的关键职责。通过构造函数传入模型、服务或配置对象,控制器能够以声明式方式获取所需资源,提升可测试性与模块化程度。
依赖注入的实现方式
使用构造函数参数可明确指定控制器所依赖的服务实例,避免硬编码和全局状态。
type UserController struct {
    userService *UserService
}

func NewUserController(service *UserService) *UserController {
    return &UserController{
        userService: service,
    }
}
上述代码中,*UserService 通过构造函数注入,使 UserController 无需关心服务的创建过程,仅专注处理HTTP请求与视图逻辑。
优势与应用场景
  • 提升代码可维护性:依赖关系清晰可见
  • 便于单元测试:可传入模拟对象(mock)进行隔离测试
  • 支持运行时动态替换实现,增强扩展能力

2.2 CodeIgniter 4依赖注入容器工作原理解读

CodeIgniter 4 的依赖注入(DI)容器通过自动解析类及其依赖关系,实现松耦合设计。核心机制基于反射(Reflection),在实例化类时自动识别构造函数参数类型,并递归注入所需服务。
依赖解析流程
容器首先检查类是否已注册为单例,若未注册则通过 PHP 的 `ReflectionClass` 分析构造函数参数类型,逐层构建依赖树。
// 示例:服务注册与解析
$container = \Config\Services::getContainer();
$container->set('UserService', function() {
    return new UserService(new UserRepository());
});
$userService = $container->get('UserService');
上述代码中,`set()` 注册服务,`get()` 触发自动解析与实例化。闭包确保对象生命周期可控。
关键特性支持
  • 自动类型提示注入:根据参数类型自动实例化依赖
  • 单例管理:确保全局唯一实例
  • 别名支持:简化复杂类名引用

2.3 如何通过构造函数实现服务自动注入

在现代依赖注入(DI)框架中,构造函数注入是实现服务解耦的核心方式。它通过在类的构造函数中声明依赖项,由容器自动解析并注入实例。
构造函数注入的基本模式
public class OrderService
{
    private readonly IPaymentGateway _payment;
    private readonly ILogger _logger;

    public OrderService(IPaymentGateway payment, ILogger logger)
    {
        _payment = payment;
        _logger = logger;
    }
}
上述代码中,IPaymentGateway 和 ILogger<T> 通过构造函数参数传入,DI 容器会根据注册的服务类型自动匹配并注入具体实例。
优势与推荐实践
  • 明确依赖关系,提升可测试性
  • 避免运行时空引用异常
  • 支持递归注入复杂对象图
构造函数注入确保对象创建时即完成依赖初始化,是构建高内聚、低耦合系统的关键手段。

2.4 使用构造函数传递配置与依赖的典型场景

在面向对象设计中,构造函数注入是实现依赖反转和配置解耦的核心手段之一。通过在实例化时传入依赖项与配置参数,对象能够保持高内聚与低耦合。
服务组件初始化
典型场景如数据库客户端的构建。以下示例展示通过构造函数注入配置:

type Database struct {
    connString string
    timeout    time.Duration
}

func NewDatabase(connString string, timeout time.Duration) *Database {
    return &Database{
        connString: connString,
        timeout:    timeout,
    }
}
该模式将连接字符串与超时策略作为参数传入,使 Database 实例具备明确的初始化契约,便于测试与多环境适配。
依赖注入框架中的应用
  • 第三方服务客户端(如 Redis、MQ)通过构造注入凭证与端点
  • 日志记录器接收输出级别与目标位置
  • HTTP 客户端封装基础 URL 与认证令牌
这种设计提升了可配置性,同时支持运行时动态替换实现。

2.5 参数类型约束与实例化异常排查实践

在泛型编程中,参数类型约束是确保类型安全的核心机制。若约束定义不当或实例化时传入非法类型,将触发运行时异常。
常见类型约束错误示例

type Container[T any] struct {
    value T
}

func NewContainer[T any](v T) *Container[T] {
    if v == nil { // 错误:nil 不能用于 any 类型的比较
        panic("value cannot be nil")
    }
    return &Container[T]{value: v}
}
上述代码试图对泛型参数 T 进行 nil 判断,但当 T 为基本类型(如 int)时,v == nil 将引发编译错误。正确做法是通过类型约束限制为指针或接口类型。
推荐的约束设计模式
  • 使用 ~interface{} 明确允许 nil 值的类型
  • 通过自定义约束接口提升类型安全性
  • 在构造函数中增加类型断言或反射校验

第三章:高级依赖管理与服务注册技巧

3.1 自定义类中构造函数参数的依赖绑定方法

在面向对象设计中,依赖注入是解耦组件的关键手段。通过构造函数参数实现依赖绑定,可提升类的可测试性与灵活性。
构造函数注入示例
type UserService struct {
    repo UserRepository
}

func NewUserService(r UserRepository) *UserService {
    return &UserService{repo: r}
}
上述代码中,NewUserService 构造函数接收一个 UserRepository 接口实例作为参数,并将其赋值给结构体字段。这种方式将数据访问逻辑抽象为依赖项,避免在服务内部硬编码具体实现。
依赖绑定流程
  • 定义接口规范数据访问行为
  • 构造函数接收接口实例作为参数
  • 容器或调用方负责传递具体实现
该模式支持运行时动态替换依赖,便于单元测试中使用模拟对象。

3.2 利用Service Provider管理复杂依赖关系

在现代应用架构中,Service Provider 成为解耦组件依赖的核心机制。通过定义统一的接口注册与发现方式,开发者可将服务实例的创建与使用分离。
服务注册示例

type ServiceProvider interface {
    Register() error
    Resolve(name string) (interface{}, error)
}

func (p *DatabaseProvider) Register() error {
    db, err := sql.Open("mysql", p.DSN)
    if err != nil {
        return err
    }
    p.instance = db
    return nil
}
上述代码定义了一个数据库服务提供者,其 Register 方法封装了连接初始化逻辑,实现延迟加载与错误隔离。
依赖注入流程
  • 启动阶段:容器扫描所有 ServiceProvider 并调用 Register
  • 运行时:通过 Resolve 按需获取服务实例
  • 生命周期管理:支持单例、瞬态等不同作用域策略
该机制显著提升了模块间的可测试性与可替换性。

3.3 接口与实现解耦:基于构造函数的多态注入

在现代软件设计中,依赖倒置原则要求高层模块不依赖于低层模块的具体实现,而是依赖于抽象。通过构造函数注入具体实现,可实现接口与实现的彻底解耦。
构造函数注入示例

type Notifier interface {
    Send(message string) error
}

type EmailService struct{}

func (e *EmailService) Send(message string) error {
    // 发送邮件逻辑
    return nil
}

type UserService struct {
    notifier Notifier
}

// 通过构造函数注入具体实现
func NewUserService(n Notifier) *UserService {
    return &UserService{notifier: n}
}
上述代码中,UserService 不直接实例化 EmailService,而是在构造时接收符合 Notifier 接口的任意实现,提升可测试性与扩展性。

优势对比

方式耦合度可测试性
直接实例化高低
构造函数注入低高

第四章:实战中的构造函数参数应用模式

4.1 在控制器中优雅地注入模型与服务类

在现代Web框架中,依赖注入是实现解耦和提升可测试性的核心手段。通过构造函数或属性注入,控制器可以清晰地声明所需的服务与模型。
构造函数注入示例
type UserController struct {
    userService *UserService
    userModel   *UserModel
}

func NewUserController(userService *UserService, userModel *UserModel) *UserController {
    return &UserController{
        userService: userService,
        userModel:   userModel,
    }
}
上述代码通过构造函数将*UserService和*UserModel注入到控制器中,确保依赖明确且不可变。
优势分析
  • 提升代码可读性:依赖关系一目了然
  • 增强可测试性:便于在单元测试中替换模拟对象
  • 降低耦合度:控制器不负责创建依赖实例

4.2 中间件中使用构造函数实现权限服务依赖

在构建可扩展的中间件系统时,依赖注入是关键设计模式之一。通过构造函数注入权限服务,能够有效解耦业务逻辑与认证授权细节。
构造函数注入示例
type AuthMiddleware struct {
    authService *AuthService
}

func NewAuthMiddleware(service *AuthService) *AuthMiddleware {
    return &AuthMiddleware{authService: service}
}
上述代码通过构造函数 NewAuthMiddleware 将 AuthService 实例注入中间件,确保其职责单一且便于测试。
优势分析
  • 提升可测试性:可在单元测试中传入模拟服务实例
  • 增强灵活性:运行时可动态替换不同实现
  • 符合依赖倒置原则:高层模块不直接创建底层服务

4.3 自定义库类的参数化初始化与配置传递

在构建可复用的库类时,参数化初始化是提升灵活性的关键。通过构造函数注入配置项,能够实现运行时动态调整行为。
配置结构体设计
采用结构体集中管理配置参数,便于扩展与维护:
type Config struct {
    Timeout  time.Duration
    Retries  int
    Endpoint string
}

type Client struct {
    config Config
}
该设计将配置封装在Config中,避免散列的参数传递,增强可读性。
初始化与默认值处理
使用选项模式设置默认值并允许覆盖:
  • 通过WithTimeout()等函数设置可选参数
  • 构造函数合并默认配置与用户输入
func NewClient(opts ...func(*Config)) *Client {
    cfg := Config{Timeout: 5 * time.Second, Retries: 3}
    for _, opt := range opts {
        opt(&cfg)
    }
    return &Client{config: cfg}
}
此方式实现安全的参数化初始化,确保配置一致性。

4.4 测试环境下构造函数参数的模拟与替换

在单元测试中,常需隔离外部依赖。通过模拟构造函数参数,可实现对对象初始化过程的精确控制。
依赖注入与模拟
将服务实例作为参数传入构造函数,便于在测试时替换为模拟对象(Mock),从而避免真实调用。
  • 降低耦合:解耦对象创建与使用
  • 提升可测性:便于注入预设行为的模拟实例
代码示例:Go 中的接口注入

type Service struct {
    repo Repository
}

func NewService(r Repository) *Service {
    return &Service{repo: r}
}
上述代码中,Repository 接口通过构造函数注入。测试时可用模拟实现替代真实数据访问层,控制其返回值以覆盖不同分支逻辑。

第五章:总结与最佳实践建议

性能监控与调优策略
在高并发系统中,持续的性能监控是保障稳定性的关键。使用 Prometheus 与 Grafana 搭建可观测性平台,可实时追踪服务延迟、CPU 使用率和内存泄漏情况。

// Go 中通过 expvar 暴露自定义指标
var requestCount = expvar.NewInt("http_requests_total")

func handler(w http.ResponseWriter, r *http.Request) {
    requestCount.Add(1)
    fmt.Fprintf(w, "Hello, World!")
}
微服务通信的最佳实践
建议采用 gRPC 替代 RESTful API 进行内部服务通信,以获得更低的延迟和更高的吞吐量。务必启用 TLS 加密,并结合 Protocol Buffers 实现强类型接口契约。
  1. 定义清晰的 service 接口并版本化管理
  2. 使用拦截器实现日志、认证与限流
  3. 配置连接池与超时策略避免级联故障
数据库访问优化案例
某电商平台在订单查询接口中引入缓存层后,P99 延迟从 850ms 降至 98ms。采用 Redis 作为二级缓存,配合 PostgreSQL 的连接池(pgBouncer),显著提升响应能力。
优化项优化前优化后
平均响应时间620ms85ms
QPS1,2009,500
安全加固建议
生产环境必须禁用调试接口与远程 shell 访问。所有容器镜像应基于最小化基础镜像构建,并通过 Trivy 扫描漏洞。
构建 → 镜像扫描 → 单元测试 → 集成测试 → 准生产部署 → 监控告警
常见消息队列:ActiveMQ、RabbitMQ、RocketMQ、Kafka的区别总结 常见消息队列:ActiveMQ、RabbitMQ、RocketMQ、Kafka的区别。 阅读详情

相关推荐

解决/usr/lib64/libstdc++.so.6和/lib64/libc.so.6版本过低问题

在CentOS7.0中编译好MySQL5.7.14之后,然后在CentOS6.5中初始化MySQL,执行:/usr/local/mysql/bin/mysqld --version出现如下问题:./bin/mysqld: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by ./bin/mysqld)

poxiaonie的博客 2万+

揭秘CodeIgniter 4依赖注入机制:构造函数参数使用全指南

掌握CodeIgniter 4依赖注入核心技巧,轻松管理类间依赖。本文深入解析构造函数参数自动注入机制,涵盖服务容器绑定、类型提示用法及常见应用场景,提升代码可维护性与测试性,是PHP开发者优化架构的实用指南,值得收藏。

VarLens的博客 814

告别复杂配置!用GuidosToolbox 3.0做MSPA景观格局分析,从安装到出图全记录

本文详细介绍了如何使用GuidosToolbox 3.0进行MSPA景观格局分析,从安装配置到出图全流程。涵盖环境准备、数据预处理、参数设置、结果解读及可视化技巧,帮助用户快速掌握这一生态安全评估工具。特别针对安装教程中的常见问题提供解决方案,提升分析效率。

weixin_29248313的博客 489

CodeIgniter 4构造函数参数详解(高级开发必知的5大陷阱)

掌握CodeIgniter 4的构造函数参数使用技巧,避免常见错误。详解依赖注入、父类调用等5大陷阱及解决方案,提升框架开发稳定性与性能,适用模块化项目开发,值得收藏。

AlgoChat的博客 688

ArchLinux下用Wine运行钉钉全攻略:从字体配置到中文输入法避坑

本文详细介绍了在ArchLinux系统上使用Wine运行钉钉的完整配置流程。从最新的WoW64架构环境准备、中文字体配置与DPI优化,到钉钉安装、关键系统库替换,再到解决中文输入法失效等核心难题,提供了实战避坑指南。旨在帮助Linux用户在企业办公场景下,获得接近原生的稳定使用体验。

alice7model的博客 588

PCIe 物理层(Physical Layer)详解

PCIe物理层关键技术解析 PCIe物理层作为协议栈底层核心,承担着比特流传输、链路训练与电气特性管理等关键功能。该层采用分层架构,包含逻辑物理层(负责编解码/加扰)和电气物理层(处理信号收发)。关键技术亮点包括: 智能链路管理:通过LTSSM状态机实现11种状态转换,涵盖链路检测(Detect)、协商(Polling/Configuration)、功耗管理(L0s/L1)等全生命周期控制 高效编码方案:Gen1/Gen2采用8b/10b编码(20%开销),Gen3+升级为128b/130b(仅1.5%开销

珂珂可爱多 726

揭秘CodeIgniter 4依赖注入机制:构造函数参数使用全攻略

掌握CodeIgniter 4依赖注入核心技巧,本文深入解析构造函数参数的使用方法与场景,涵盖服务容器绑定、自动注入原理及实际开发应用。帮你提升代码可维护性与测试性,构建高效应用,值得收藏。

FastDebug的博客 942

vit的cam和注意力图: VIT模型的可解释性

VIT的热力图怎么画

YI_SHU_JIA的博客 1万+

揭秘CodeIgniter 4控制器构造函数:你必须知道的3个陷阱与最佳写法

掌握CodeIgniter 4控制器构造函数的正确用法,避开常见陷阱。详解自动加载服务、父类调用规则与依赖注入实践,提升应用性能与可维护性。适用于API开发与模块化项目架构,值得收藏。

LogicPlex的博客 943

Pytorch transformers tokenizer 分词器词汇表添加新的词语和embedding

NLP添加新词汇

7322

Python 安装 PyTorch(GPU)详细教程

本章教程,介绍如何安装PyTorch GPU版本的具体教程。

猿小白的博客 1620

避免应用崩溃!CodeIgniter 4构造函数参数验证的4个关键步骤

避免应用崩溃!掌握CodeIgniter 4的构造函数参数验证四步法,适用于控制器与服务类初始化场景,通过类型声明、依赖注入校验、默认值设置和异常处理保障稳定性。有效提升代码健壮性,值得收藏

CodePulse的博客 513

基于YOLOv10的机器人抓取引导系统:从物体检测到精准抓取

python# 数据标注工具简化版import os"""启动标注工具""""""标注单张图像"""print(f"标注图像: {os.path.basename(img_path)}")print("请在图像上绘制抓取矩形框...")# 这里应该实现交互式标注界面# 简化版本直接返回示例标注# 示例标注数据"""保存标注结果"""# 保存为YOLO格式# 转换为YOLO格式。

YOLO 377

【CodeIgniter 4构造函数参数深度解析】:掌握核心注入技巧,提升开发效率

掌握CodeIgniter 4构造函数参数的正确用法,解决依赖注入难题,提升应用灵活性与可测试性。详解服务容器自动注入、parent::__construct调用时机及常见误区,适用于控制器与库类开发。核心技巧一文读懂,值得收藏。

CompiShoal的博客 923

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

【紧急避坑】CodeIgniter 4升级后构造函数参数失效?解决方案速看

解决CodeIgniter 4升级后构造函数异常问题,详解CodeIgniter 4 的构造函数参数正确用法,适用于控制器与服务类初始化场景,通过parent::__construct()调用父类构造确保兼容性,避免报错。升级迁移必看,值得收藏

FuncTide的博客 748

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

【PHP框架进阶指南】:CodeIgniter 4构造函数参数传递的3种最佳实践

掌握CodeIgniter 4 的构造函数参数传递技巧,提升应用初始化效率。本文详解依赖注入、父类构造调用和参数过滤3种最佳实践,适用于控制器与服务类开发,保障代码健壮性与可维护性,值得收藏

VarFun的博客 974

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

你真的懂CodeIgniter 4的构造函数吗?参数注入失败的7个原因曝光

掌握CodeIgniter 4 的构造函数参数,解决依赖注入失败问题。本文剖析7大常见原因,涵盖服务容器、自动加载与类型提示等关键机制,提升应用稳定性。开发者必读,值得收藏。

PixelShoal的博客 813

【PHP框架进阶必看】:CodeIgniter 4构造函数参数传递的5种方式及最佳实践

掌握CodeIgniter 4构造函数参数传递的5种实用方式,解决类初始化依赖注入难题。涵盖控制器、服务类等应用场景,详解父类调用、依赖注入容器等核心方法,提升代码可维护性与灵活性,PHP开发者进阶必读,值得收藏。

PoliSeed的博客 941

构造函数参数配置难题,一文搞定CodeIgniter 4服务容器集成

轻松解决CodeIgniter 4 的构造函数参数注入难题,详解服务容器集成方法。涵盖依赖注入配置、控制器与类库应用场景,提升代码可维护性与测试性。配置清晰、操作简单,一文掌握核心技巧,值得收藏。

CodeTrick的博客 739

CodeIgniter 4依赖注入实战:构造函数参数处理技巧(资深架构师私藏笔记)

掌握CodeIgniter 4的构造函数参数处理技巧,提升应用解耦与可测试性。详解依赖注入原理、服务容器调用及实际应用场景,解析自动解析与手动绑定的核心方法。架构清晰,维护更高效,值得收藏。

AlgoInk的博客 1043

揭秘CodeIgniter 4构造函数注入:如何正确传递参数并避免常见错误

掌握CodeIgniter 4构造函数参数注入技巧,解决依赖传递难题。详解控制器与服务类中如何正确使用构造函数注入,避免循环依赖与实例化错误,提升应用可测试性与模块化程度。实用场景+代码示例,值得收藏。

VarChat的博客 440

你真的会用CodeIgniter 4的构造函数吗?:5个必须掌握的参数处理技巧

掌握CodeIgniter 4构造函数参数的正确用法,提升开发效率与代码可维护性。本文详解依赖注入、父类调用等5大核心技巧,适用于控制器与服务类场景,避免常见错误。合理使用构造函数参数,让应用结构更清晰,值得收藏。

VarLens的博客 392

CodeIgniter 4控制器构造函数使用全攻略(构造函数权威指南)

掌握CodeIgniter 4控制器构造函数的正确用法,解决初始化逻辑与依赖注入难题。涵盖自动加载服务、属性赋值、调用父类构造方法等核心技巧,提升代码组织效率与可维护性。适用于全局配置、权限验证等场景,值得收藏。

ProceNest的博客 871

CodeIgniter 4服务注册与构造函数参数绑定(专家级配置方案曝光)

掌握CodeIgniter 4构造函数参数绑定技巧,解决服务注册依赖注入难题。适用于自定义服务、第三方库集成等场景,通过容器实现自动解析与参数注入,提升应用解耦度和可测试性。专家级配置方案曝光,值得收藏。

LiteCode的博客 999

CodeIgniter 4构造函数不执行?,90%开发者忽略的加载顺序问题详解

解决CodeIgniter 4控制器构造函数不执行问题,揭秘加载顺序陷阱。适用于自定义初始化逻辑场景,通过正确使用__construct与parent::__construct确保执行,避免常见错误。掌握关键加载流程,提升项目稳定性,值得收藏。

PoliVein的博客 939

CodeIgniter 4 实例教程系列,用 CodeIgniter4开发一个自己的web管理系统或是cms系统

我之前也是从事PHP开发的程序员,奈何中途转行做了搜索引擎优化。现在工作中越来越感觉到离不开编程了。 比如说,在上一家公司,我提报做一个网站改版,十五天我和设计人员将设计图搞出来了,但是等待研发人员编写代码,我足足等了10个月。最后也只是将html文件给我,我自己对接的后台系统。 公司越大,流程越多,办起事情来,感觉身心俱疲啊!(研发一直多定制的项目,总是在赶期...) 我也就是在这个时间段内,逐步又拾起我阔别已久的php编程。(年龄大了,时间总是不够用。上有老下有小,生活真难!) 十年前我是Cod

枫叶cms 2279
上一篇: 【邮件开发必知】:深入解析mail函数额外参数的5大核心用途
下一篇: 解决PHP中文字符长度计算异常:mb_strlen编码参数设置的5个关键点
PixelStream
博客等级 码龄1年 177粉丝 2182原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值