vscode使用xdebug3调试PHP脚本

1、安装 xdebug 扩展

本地环境windows

php -i 

PHP Version => 7.2.31

System => Windows NT WINDOWS10-JACK 10.0 build 17134 (Windows 10) AMD64
Build Date => May 12 2020 10:22:06
Compiler => MSVC15 (Visual C++ 2017)
Architecture => x64
Configure Command => cscript /nologo configure.js  "--enable-snapshot-build" "--enable-debug-pack" "--disable-zts" "--with-pdo-oci=c:\p
hp-snap-build\deps_aux\oracle\x64\instantclient_12_1\sdk,shared" "--with-oci8-12c=c:\php-snap-build\deps_aux\oracle\x64\instantclient_1
2_1\sdk,shared" "--enable-object-out-dir=../obj/" "--enable-com-dotnet=shared" "--without-analyzer" "--with-pgo"
Server API => Command Line Interface
Virtual Directory Support => disabled
Configuration File (php.ini) Path => C:\WINDOWS
Loaded Configuration File => D:\phpStudy\PHPTutorial\php\php-7.2.31-nts-Win32-VC15-x64\php.ini
Scan this dir for additional .ini files => (none)
Additional .ini files parsed => (none)
PHP API => 20170718
PHP Extension => 20170718
Zend Extension => 320170718
Zend Extension Build => API320170718,NTS,VC15
PHP Extension Build => API20170718,NTS,VC15
Debug Build => no
Thread Safety => disabled
Zend Signal Handling => disabled
Zend Memory Manager => enabled
Zend Multibyte Support => provided by mbstring
IPv6 Support => enabled
DTrace Support => disabled

Registered PHP Streams => php, file, glob, data, http, ftp, zip, compress.zlib, compress.bzip2, https, ftps, phar
Registered Stream Socket Transports => tcp, udp, ssl, tls, tlsv1.0, tlsv1.1, tlsv1.2
Registered Stream Filters => convert.iconv.*, string.rot13, string.toupper, string.tolower, string.strip_tags, convert.*, consumed, dec
hunk, zlib.*, bzip2.*

This program makes use of the Zend Scripting Language Engine:
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies

将上面的内容粘贴到 xdebug wizard ,它会给出推荐的下载

在这里插入图片描述
下载之后将名字改成php_xdebug.dll,然后放到扩展目录下。

修改 php.ini 文件,此处为初始配置,文章后面有完整配置

[XDebug]
xdebug.output_dir="D:\phpStudy\PHPTutorial\tmp\xdebug"
zend_extension=xdebug
xdebug.mode = debug
xdebug.client_host = 127.0.0.1
xdebug.client_port = 9100

注意,xdebug3 和 xdebug2 的配置项发生了很大变化,尽量参考官方说明而不是网上copy。

文档:https://xdebug.org/docs/all_settings

php -m 

查看 xdebug 的全部配置及默认值
php --ri xdebug


xdebug

__   __   _      _
\ \ / /  | |    | |
 \ V / __| | ___| |__  _   _  __ _
  > < / _` |/ _ \ '_ \| | | |/ _` |
 / . \ (_| |  __/ |_) | |_| | (_| |
/_/ \_\__,_|\___|_.__/ \__,_|\__, |
                              __/ |
                             |___/

Version => 3.1.6
Support Xdebug on Patreon, GitHub, or as a business: https://xdebug.org/support

             Enabled Features (through 'xdebug.mode' setting)
Feature => Enabled/Disabled
Development Helpers => ✘ disabled
Coverage => ✘ disabled
GC Stats => ✘ disabled
Profiler => ✘ disabled
Step Debugger => ✔ enabled
Tracing => ✘ disabled

                            Optional Features
Compressed File Support => no
Clock Source => GetSystemTimePreciseAsFileTime

Debugger => enabled
IDE Key =>

Directive => Local Value => Master Value
xdebug.mode => debug => debug
xdebug.start_with_request => default => default
xdebug.start_upon_error => default => default
xdebug.output_dir => D:\phpStudy\PHPTutorial\tmp\xdebug => D:\phpStudy\PHPTutorial\tmp\xdebug
xdebug.use_compression => 0 => 0
xdebug.trigger_value => no value => no value
xdebug.file_link_format => no value => no value
xdebug.filename_format => no value => no value
xdebug.log => no value => no value
xdebug.log_level => 7 => 7
xdebug.var_display_max_children => 128 => 128
xdebug.var_display_max_data => 512 => 512
xdebug.var_display_max_depth => 3 => 3
xdebug.max_nesting_level => 256 => 256
xdebug.cli_color => 0 => 0
xdebug.force_display_errors => Off => Off
xdebug.force_error_reporting => 0 => 0
xdebug.halt_level => 0 => 0
xdebug.max_stack_frames => -1 => -1
xdebug.show_error_trace => Off => Off
xdebug.show_exception_trace => Off => Off
xdebug.show_local_vars => Off => Off
xdebug.dump.COOKIE => no value => no value
xdebug.dump.ENV => no value => no value
xdebug.dump.FILES => no value => no value
xdebug.dump.GET => no value => no value
xdebug.dump.POST => no value => no value
xdebug.dump.REQUEST => no value => no value
xdebug.dump.SERVER => no value => no value
xdebug.dump.SESSION => no value => no value
xdebug.dump_globals => On => On
xdebug.dump_once => On => On
xdebug.dump_undefined => Off => Off
xdebug.profiler_output_name => cachegrind.out.%p => cachegrind.out.%p
xdebug.profiler_append => Off => Off
xdebug.cloud_id => no value => no value
xdebug.client_host => 127.0.0.1 => 127.0.0.1
xdebug.client_port => 9100 => 9100
xdebug.discover_client_host => Off => Off
xdebug.client_discovery_header => no value => no value
xdebug.idekey => no value => no value
xdebug.connect_timeout_ms => 200 => 200
xdebug.scream => Off => Off
xdebug.gc_stats_output_name => gcstats.%p => gcstats.%p
xdebug.trace_output_name => trace.%c => trace.%c
xdebug.trace_format => 0 => 0
xdebug.trace_options => 0 => 0
xdebug.collect_assignments => Off => Off
xdebug.collect_return => Off => Off
xdebug.auto_trace => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.collect_includes => (setting removed in Xdebug 3) => (setting removed in Xdebug 3)
xdebug.collect_params => (setting removed in Xdebug 3) => (setting removed in Xdebug 3)
xdebug.collect_vars => (setting removed in Xdebug 3) => (setting removed in Xdebug 3)
xdebug.coverage_enable => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.default_enable => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.gc_stats_enable => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.gc_stats_output_dir => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.overload_var_dump => (setting removed in Xdebug 3) => (setting removed in Xdebug 3)
xdebug.profiler_enable => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.profiler_enable_trigger => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.profiler_enable_trigger_value => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.profiler_output_dir => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.remote_autostart => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.remote_connect_back => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.remote_enable => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.remote_host => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.remote_log => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.remote_log_level => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.remote_mode => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.remote_port => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.remote_timeout => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.show_mem_delta => (setting removed in Xdebug 3) => (setting removed in Xdebug 3)
xdebug.trace_output_dir => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.trace_enable_trigger => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)
xdebug.trace_enable_trigger_value => (setting renamed in Xdebug 3) => (setting renamed in Xdebug 3)

2、主要配置项说明

xdebug.mode

此设置控制启用哪些Xdebug功能。默认值为 develop

此设置只能在PHP进程启动时(直接或通过php-fpm)在php.ini或99-xdebug.ini读取的文件中进行设置,而不能在.htaccess和 .user.ini按请求读取的文件中进行设置。

接受以下值:

  • off
    没有启用任何功能。Xdebug除了检查功能是否已启用外不起作用。如果您想要接近零的开销,请使用此设置。
  • develop
    启用包括重载的var_dump()在内的开发帮助。
  • coverage
    使Code Coverage Analysis能够生成代码覆盖率报告,主要是与PHPUnit结合使用 。
  • debug
    启用步骤调试(Step Debugging)。这可用于在代码运行时逐步检查代码,并分析变量的值。
  • gcstats
    使垃圾收集统计信息能够收集有关PHP的垃圾收集机制的统计信息。
  • profile
    启用性能分析,您可以使用它通过KCacheGrind之类的工具分析性能瓶颈。
  • trace
    启用功能跟踪功能,该功能允许您记录每个函数调用,包括参数,变量赋值以及在对文件的请求期间进行的返回值。

您可以通过以逗号分隔xdebug.mode:的值作为标识符来同时启用多个模式xdebug.mode=develop,trace。
您还可以通过XDEBUG_MODE在命令行上设置环境变量来设置模式,这将优先于xdebug.mode 设置。

start_with_request

默认值为 default

我们直到在CLI模式下,PHP脚本可以被轻松的调试,但是在fastcgi模式下,xdebug在何种情况拦截请求并触发调试呢,实际上一套WEB API 只有极少有性能瓶颈的API才需要被debug,每个接口都去记录profile是没必要的。这就是此配置的意义:

  • yes
    该功能在PHP请求启动时以及运行任何PHP代码之前启动。例如,xdebug.mode = trace 和 xdebug.start_with_request = yes启动整个请求的功能跟踪。

  • no
    请求开始时,该功能未激活。你仍然可以调用函数xdebug_start_trace() 来启动 trace;调用xdebug_break()开始逐步调试;调用xdebug_start_gcstats()来做垃圾收集统计。

  • trigger
    仅当请求开始时存在特定触发条件时,才激活该功能。触发器的名称是(大写)XDEBUG_TRIGGER,而Xdebug会去检查一下变量中($_ENV,$_GET,$_POST,$_COOKIE)是否有这个字段。
    功能特定的触发器名称也有一个旧式的备用名称:(XDEBUG_PROFILE 对于 Profiling),(XDEBUG_TRACE 对于 Function Trace)和 (XDEBUG_SESSION 对于 Step Debugging)
    也可以通过进行步骤调试的调试会话管理XDEBUG_SESSION_START
    使用xdebug.trigger_value可以控制哪个特定的触发器值将激活该触发器。如果xdebug.trigger_value设置为空字符串,则将接受任何值。
    示例:http://localhost:8000/test.php?XDEBUG_TRIGGER

  • default
    该default值取决于xdebug.mode
    debug:trigger
    gcstats:no
    profile:yes
    trace:trigger

client_port

Xdebug’s default debugging port has changed from 9000 to 9003.

php 的 xdebug 扩展作为一个代理客户端,会去连接 xdebug.client_host : xdebug.client_port,此时服务端是编辑器,因此编辑器要先启动,比如,如果你设置xdebug.mode=debugxdebug.start_with_request=yes,那么每次运行php程序xdebug都会去连接服务端,如果你没有启动编辑器的调试服务,那么php就会抛出错误信息Xdebug: [Step Debug] Time-out connecting to debugging client, waited: 200 ms. Tried: 127.0.0.1:9100 (through xdebug.client_host/xdebug.client_port) :-(

根据以上说明,我们的主要两个配置的值如下,这是下文的前提

xdebug.mode = debug
xdebug.start_with_request = trigger

因此,无论是命令行下还是web下的调试都需要人为来触发,实际上,这是合理的,因为大部分时候我们是不需要调试的,一直开启xdebug没有必要,人为触发的方式参考 https://xdebug.org/docs/step_debug

关于如何来人为触发,我们先配置好编辑器再说。

3、vscode安装 PHP Debug 插件。

在这里插入图片描述

4、vscode配置调试

查看 -> 命令面板 -> 搜索 settings 打开 settings.json配置PHP执行程序:
"php.validate.executablePath": "D:/phpStudy/PHPTutorial/php/php-7.2.31-nts-Win32-VC15-x64/php.exe",
这个是全局配置,跟随用户走的。

在当前项目目录下,创建 launch.js 文件 ,注意,这个文件是保存在项目下的,而不是全局的,每个项目都要单独配置。
在这里插入图片描述
如果已经存在了就修改
在这里插入图片描述
点击创建 launch.json 文件之后,选择 PHP,那么 PHP Debug 插件就会在当前项目中创建好 launch.json 文件,只需要将 port 修改为 9100 即可。

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for Xdebug",
            "type": "php",
            "request": "launch",
            "port": 9100
        },
        {
            "name": "Launch currently open script",
            "type": "php",
            "request": "launch",
            "program": "${file}",
            "cwd": "${fileDirname}",
            "port": 9100,
            "runtimeArgs": [
                "-dxdebug.start_with_request=yes"
            ],
            "env": {
                "XDEBUG_MODE": "debug,develop",
                "XDEBUG_CONFIG": "client_port=${port}",
                "XDEBUG_SESSION": "1"
            }
        },
        {
            "name": "Launch Built-in web server",
            "type": "php",
            "request": "launch",
            "runtimeArgs": [
                "-dxdebug.mode=debug",
                "-dxdebug.start_with_request=yes",
                "-S",
                "localhost:0"
            ],
            "program": "",
            "cwd": "${workspaceRoot}",
            "port": 9100,
            "serverReadyAction": {
                "pattern": "Development Server \\(http://localhost:([0-9]+)\\) started",
                "uriFormat": "http://localhost:%s",
                "action": "openExternally"
            }
        }
    ]
}

新建测试文件 test.php

<?php
$str = md5('123456');

echo date('Y-m-d H:i:s', 1596211200);
echo PHP_EOL;
echo date('Y-m-d H:i:s', 1604160000);

launch.json 提供了三种调试模式,下面将分别演示和说明

Listen for Xdebug

编辑器只管启动监听,就等着 php xdebug 扩展过来连接并进行交互。然后你就可以在命令行执行 php xxx.php来开始调试,或者也可以用来调试http请求。

在 test.php 打断点,最后按 F5 或者点击上面的绿色箭头启动调试,最下面的横条会变成黄色,效果如下:
在这里插入图片描述
在这里插入图片描述
我们打开编辑器命令行,执行php test.php,发现并没有触发调试,因为我们是需要手动来触发的。还是在当前命令行,我们来设置一个临时的环境变量,因为上面说了xdebug会在$_ENV中查找特定标志。

在 windows 命令行中设置临时环境变量使用set XDEBUG_SESSION=1,而在 linux 下则是export XDEBUG_SESSION=1,注意,此种方式设置的环境变量是临时的,并且只在当前命令行可见。我们通过echo %XDEBUG_SESSION%来查看此临时环境变量。

> echo %XDEBUG_SESSION%
%XDEBUG_SESSION%

> set XDEBUG_SESSION=1

> echo %XDEBUG_SESSION%
1

再次执行php test.php就可以调试了,按 F5 下一步,将鼠标移到变量上面就可以看到变量的值,当然,左边也会列出变量的值。
在这里插入图片描述
程序执行完了,而调试服务依然在监听。

如果此时 set XDEBUG_SESSION=0,运行脚本,发现还是能够调试,说明 xdebug 只是检测有没有 XDEBUG_SESSION,而不关心其值。

如果闲麻烦可以直接 php -dxdebug.start_with_request=yes test.php

接下来,我们调试 http 请求。

在当前目录,启动php内置的web服务器 php -S localhost:8000

> php -S localhost:8000
PHP 7.2.31 Development Server started at Wed Aug 16 15:56:48 2023
Listening on http://localhost:8000
Document root is D:\dev\php\magook\trunk\server\test_debug
Press Ctrl-C to quit.

浏览器访问 http://localhost:8000/test.php,发现已经可以调试了,这是怎么做到的?还是因为我们是在当前命令行启动的php server,自带有 XDEBUG_SESSION环境变量。

我直接在编辑器中新起一个命令行就不会有 XDEBUG_SESSION
在这里插入图片描述
再次访问 http://localhost:8000/test.php,就没有调试了。想要有调试,可以在 $_GET, $_POST, $_COOKIE中带有XDEBUG_SESSION=xxx,这个值不做限制,除非你设置了 xdebug.trigger_value

访问 http://localhost:8000/test.php?XDEBUG_SESSION=xxx就可以调试了。

好,关闭调试监听。

Launch currently open script

这是针对当前脚本的快速调试,不用我们在命令行自己输入执行。我们来分析一下这个配置

{
    "name": "Launch currently open script",
    "type": "php",
    "request": "launch",
    "program": "${file}",
    "cwd": "${fileDirname}",
    "port": 9100,
    "runtimeArgs": [
        "-dxdebug.start_with_request=yes"
    ],
    "env": {
        "XDEBUG_MODE": "debug,develop",
        "XDEBUG_CONFIG": "client_port=${port}"
    }
}

它首先设置了两个环境变量(XDEBUG_MODE, XDEBUG_CONFIG),当然也是当前命令行的临时变量,xdebug会接收它们并临时修改配置。

然后在执行的时候修改了php的配置,最终的执行命令是:
php -dxdebug.start_with_request=yes test.php

因为它会使用新的命令行来执行这个命令,所以也不会带有XDEBUG_SESSION

我们定位到 test.php文件,选择Launch currently open script,点击开始调试。效果如下

在这里插入图片描述
嗯?为什么没看见输出呢,那是因为没有打开调试控制台
在这里插入图片描述

Launch Built-in web server

从配置上来看,它就是启动了 php 内置的 server 来提供服务,并开启调试。

修改 localhost:8000

{
    "name": "Launch Built-in web server",
    "type": "php",
    "request": "launch",
    "runtimeArgs": [
        "-dxdebug.mode=debug",
        "-dxdebug.start_with_request=yes",
        "-S",
        "localhost:8000"
    ],
    "program": "",
    "cwd": "${workspaceRoot}",
    "port": 9100,
    "serverReadyAction": {
        "pattern": "Development Server \\(http://localhost:([0-9]+)\\) started",
        "uriFormat": "http://localhost:%s",
        "action": "openExternally"
    }
}

最终内部执行的命令为
php -dxdebug.mode=debug -dxdebug.start_with_request=yes -S localhost:8000

从配置就能看出这是强制调试的,不需要任何触发。

访问 http://localhost:8000/test.php

5、trace & profile

xdebug.mode = debug 的使用场景是当你需要断点调试的时候,但是有时候程序没问题,你想看看性能和各个地方的耗时情况,此时你可以换成 trace 和 profile 模式。

记录 trace ,也就是函数调用链,修改 php.ini
xdebug.mode = trace

还是上面的脚本,去掉所有的断点(当然也可以不去掉但是你需要一直按 F5 直到程序跑完),此时按一下 F5 程序就跑完了,然后去到目录D:\phpStudy\PHPTutorial\tmp\xdebug也就是上面配置的目录,会看到多出了一个文件 trace.1480951438.xt,内容为:

TRACE START [2020-12-30 06:47:20.891508]
    0.0782     383264   -> {main}() D:\dev\php\my\test.php:0
    0.0784     383264     -> ini_set($varname = 'date.timezone', $newvalue = 'Asia/Shanghai') D:\dev\php\my\test.php:2
    1.3640     383536     -> getstr() D:\dev\php\my\test.php:15
    1.9238     383536       -> rand($min = 0, $max = 25) D:\dev\php\my\test.php:6
    2.2915     383536     -> date($format = 'Y-m-d H:i:s', $timestamp = 1596211200) D:\dev\php\my\test.php:17
    3.0697     384248     -> date($format = 'Y-m-d H:i:s', $timestamp = 1604160000) D:\dev\php\my\test.php:19
    3.0722     313408
TRACE END   [2020-12-30 06:47:23.885604]

另外你还可以记录 profile ,用以性能分析,修改 php.ini
xdebug.mode = profile

于是多出了一个文件 cachegrind.out.241668,内容为

version: 1
creator: xdebug 3.0.1 (PHP 7.2.21)
cmd: D:\dev\php\my\test.php
part: 1
positions: line

events: Time_(10ns) Memory_(bytes)

fl=(1) php:internal
fn=(1) php::ini_set
2 9970 272

fl=(1)
fn=(2) php::rand
6 1170 0

fl=(2) D:\dev\php\my\test.php
fn=(3) getstr
4 52017740 0
cfl=(1)
cfn=(2)
calls=1 0 0
6 1170 0

fl=(1)
fn=(4) php::date
17 7210 936

fl=(1)
fn=(4)
19 1200 256

fl=(2)
fn=(5) {main}
1 455536270 0
cfl=(1)
cfn=(1)
calls=1 0 0
2 9970 272
cfl=(2)
cfn=(3)
calls=1 0 0
15 52018910 0
cfl=(1)
cfn=(4)
calls=1 0 0
17 7210 936
cfl=(1)
cfn=(4)
calls=1 0 0
19 1200 256

summary: 507821490 418632

那么如何从这个文件分析出程序的性能呢?由于篇幅过长,我写到了另外一篇文章来讲这个 https://blog.csdn.net/raoxiaoya/article/details/111994696

在使用浏览器这种方式调试的过程中发现一个问题,只有第一次请求才会生成 cachegrind.out 文件,后面的请求并不会去更新此文件,即使我改了代码,暂时不知道什么原因。

关于在PHPStorm中使用xdebug可以参考 https://blog.csdn.net/qq_34087545/article/details/89490269

关于XDebug的运行原理

根据上面的两种调试情况,我画了一个简易流程图。
在这里插入图片描述

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
您好!要在 VS Code 中使用 Xdebug 进行调试,需要完成以下步骤: 1. 首先,确保您已经在 PHP 环境中安装了 Xdebug。您可以通过编辑您的 `php.ini` 文件来启用 Xdebug。在 `php.ini` 文件中,找到并取消注释以下行(如果没有则添加): ``` zend_extension = xdebug.so ``` 2. 在 VS Code 中安装 PHP Debug 扩展。打开扩展面板(通过侧边栏的方块图标或者快捷键 `Ctrl+Shift+X`),搜索并安装 "PHP Debug" 扩展。 3. 在 VS Code 中创建一个调试配置文件 `launch.json`。点击 VS Code 左侧的调试图标(虫子图标),然后点击配置齿轮图标以打开 `launch.json` 文件。 4. 在 `launch.json` 文件中,选择 "PHP" 作为环境,并添加一个配置参数,如下所示: ```json { "version": "0.2.0", "configurations": [ { "name": "Listen for Xdebug", "type": "php", "request": "launch", "port": 9000, "log": true, "pathMappings": { "/path/to/your/project": "${workspaceFolder}" } } ] } ``` 请将 `/path/to/your/project` 替换为您实际的项目路径。 5. 启动 Xdebug 会话。在 VS Code 中点击调试面板左上角的绿色播放按钮,选择 "Listen for Xdebug" 配置。这将启动 Xdebug 的监听模式。 6. 设置断点。在您的代码中选择要设置断点的行,然后运行您的应用程序。当代码执行到断点时,调试器将会暂停执行并允许您逐步调试。 希望以上步骤能帮助您成功下载并配置 Xdebug 进行调试。如有其他问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值