PHP PECL 使用

不论你访问pecl.php.net的网速如何,都来看看吧

introduce lite

PHP Extension Community Library php 的 C 扩展仓库,即 php 的 so 格式的扩展

需要安装C编译器

yum groupinstall "Development tools"
yum -y install gcc gcc-c++  make cmake automake autoconf

安装redis扩展

pecl info redis
pecl install redis
pecl unisntall redis

也可以使用安装包

wget http://pecl.php.net/get/redis-3.0.0.tgz
pecl install redis-3.0.0.tgz

就会生成redis.so文件,加入到php.ini中即可

执行命令

/usr/local/php/bin/pecl install redis-2.2.8

可以看到,pecl会自动帮我们下载redis扩展的源码包,然后自动编译安装,安装好之后,扩展也是放在/usr/local/php/lib/php/extensions/no-debug-zts-20131226/下,我们只要在php.ini中添加extension=redis.so就可以了.pecl安装php扩展的简单语法如下 :
pecl install 扩展名-版本号

PECL 安装介绍

» PECL 是通过 » PEAR 打包系统来的 PHP 扩展库仓库,本章内容示范了怎样取得并安装 PECL 扩展。

以下指南中假定 /your/phpsrcdir/ 是 PHP 源程序的路径,extname 是 PECL 扩展库的名字。自己根据实际情况调整。此外还假定用户熟悉 » pear 命令。 PEAR 手册里 pear 命令的信息同样适用于 pecl。

要使用共享扩展库,必须经过编译,安装,然后加载。以下说明的方法提供了怎样编译和安装扩展库的各种指导,但并不会自动加载它们。可以通过将其包括在 php.ini 中用 extension PHP 指令加载,或者 用 dl() 函数。

当编译 PHP 模块时,拥有各种工具(autoconf,automake,libtool 等)的已知好使的版本很重要。所需工具和所需版本的详情见» 匿名 Git 说明。

下载 PECL 扩展库

pecl install extname 命令会自动下载扩展代码, 所以在这种情况下不需要再次下载。
» http://pecl.php.net/ PECL 网站包括有 PHP 开发组提供的不同扩展库的信息。这里的信息包括:更新记录,版本说明,需求,以及其它信息。
pecl download extname PECL 网站中列出的 PECL 扩展库的发行版本可以用 » pear 命令来下载和安装。也可以指明具体的修正版。
SVN 大多数 PECL 扩展库也在 SVN 中。其 web 页面见 be seen at » http://svn.php.net/viewvc/pecl/。要直接从 SVN 中下载,用以下命令:

$ svn checkout http://svn.php.net/repository/pecl/extname/trunk extname

在 Windows 上安装 PHP 扩展

在 Windows 上有两种加载 PHP 扩展的方式:把扩展编译进 PHP,或者加载 DLL。加载预编译的扩展是更简单更被推荐的方式。

要加载某扩展,需要在系统中有其相对应的“.dll”文件。所有扩展都会由 PHP 小组定期自动编译(如何下载见下节)。

要将一扩展编译入 PHP,请参考从源程序编译一章。

要编译一个独立的扩展(即 DLL 文件),请参考从源程序编译一章。如果在 PHP 发行包和 PCEL 中都没有某 DLL 文件,那可能需要自己编译之后才能使用该扩展。

去哪里找扩展库?

PHP 扩展库通常称为“php_*.dll”(其中星号代表具体某扩展的名字),位于“PHP\ext”目录下(在 PHP 4 中位于“PHP\extensions”目录下)。

PHP 发行包中包括了大多数开发者最常用到的扩展库。这些被称为“核心”扩展库。

不过呢,如果用户所需要的功能并没有被任何核心扩展提供,那还是有可能在 PECL 中找到。PHP Extension Community Library(PECL,PHP 扩展社区库)是个 PHP 扩展的储存室,提供了对于所有已知扩展的下载及开发途径的指南。

如果用户开发了一个自己使用的扩展,可以考虑将其发布到 PECL 中以便于其他有相同需求的用户使用。一个很好的副作用是可以得到其他用户的反馈,感谢,错误报告甚至修正/更新。不过在向 PECL 发布扩展之前,请先阅读 http://pecl.php.net/package-new.php。

下载哪个扩展?

用户常常会发现每个 DLL 都有好几个版本:

不同的版本号(至少前两个数字要一致)
不同的线程安全性设定
不同的处理器体系(x86,x64,…)
不同的排错设定
其它
请记住用户的扩展设定应该与所使用的 PHP 可执行文件的设定都保持一致。以下脚本可以显示所有 PHP 设定:

Example #1 phpinfo() call


或者在命令行运行:

drive:\\path\to\php\executable\php.exe -i

载入一个扩展

最常见的方式是在 php.ini 配置文件里包含一个 PHP 扩展。请注意很多扩展已经在 php.ini 里了,仅需要移除分号来激活它们。

;extension=php_extname.dll
extension=php_extname.dll

不过呢,有些 web 服务器会搞混,因为其并不一定使用和 PHP 可执行文件处于同一目录下的 php.ini 文件。要搞清楚具体使用了哪一个 php.ini 文件,在 phpinfo() 的输出中查看:

Configuration File (php.ini) Path  C:\WINDOWS

Loaded Configuration File   C:\Program Files\PHP\5.2\php.ini

激活一个扩展后,保存 php.ini 文件并重启动 web 服务器,然后用 phpinfo() 再次查看确定。新的扩展应该有其自己的一节。

解决问题

如果某扩展并未在 phpinfo() 中显示,应该查看日志以确定问题出在哪里。

如果是在命令行使用 PHP(CLI),扩展加载出错信息会直接在屏幕显示。

如果在 web 服务器中使用 PHP,则日志文件的位置与格式各不相同。请阅读所使用的 web 服务器之文档以确定日志文件的位置,这与 PHP 本身并无关系。

最常见的问题是 DLL 文件的位置,php.ini 中“extension_dir”设定的值,以及编译时的设置不匹配。

如果问题出在编译时设置不匹配,那可能所下载的 DLL 文件不对。可以尝试重新下载一个设置匹配的扩展。此外,phpinfo() 可以起到很大帮助。

用 PEAR 编译共享 PECL 扩展库

PECL 使建立共享 PHP 扩展库更容易。用 » pecl 命令这样做:

$ pecl install extname

这将下载extname 的源代码,编译之,并将extname.so 安装到extension_dir中。然后 extname.so就可以通过php.ini加载了。

默认情况下,pecl 命令不会安装标记为 alpha 或 beta 状态的包。如果没有 stable 包可用,也可以用以下命令安装一个 beta 包:

$ pecl install extname-beta

也可以用此命令安装一个指定的版本:

$ pecl install extname-0.1

Note:
在 php.ini 中激活扩展之后,需要重新启动 web 服务以使更改生效。
用 phpize 编译共享 PECL 扩展库 ¶

有时候不能用 pecl 安装命令。这可能是因为在防火墙后面,或者是因为想要安装的扩展库还没有 PECL 兼容的包,例如 SVN 中尚未发布的扩展库。如果要编译这种扩展库,可以用更底层的编译工具来手工进行编译。

phpize 命令是用来准备 PHP 扩展库的编译环境的。下面例子中,扩展库的源程序位于 extname 目录中:

$ cd extname
$ phpize
$ ./configure
$ make
# make install

成功的安装将创建extname.so并放置于 PHP的扩展库目录中。需要调整php.ini,加入extension=extname.so 这一行之后才能使用此扩展库。

如果系统中没有phpize 命令并且使用了预编译的包(例如 RPM),那要安装PHP 包相应的开发版本,此版本通常包含了phpize命令以及相应的用于编译 PHP 及其扩展库的头文件。

使用phpize --help 命令可以显示此命令用法。

将 PECL 扩展库静态编译入 PHP

有时可能需要将扩展库静态编译到PHP 中。这需要将扩展库源程序放入php-src/ext/目录中去并告诉PHP 编译系统来生成其配置脚本。

$ cd /your/phpsrcdir/ext
$ pecl download extname
$ gzip -d < extname.tgz | tar -xvf -
$ mv extname-x.x.x extname

这将产生以下目录:
/your/phpsrcdir/ext/extname

此时强制PHP 重新生成配置脚本,然后正常编译PHP

$ cd /your/phpsrcdir 
$ rm configure
$ ./buildconf --force
$ ./configure --help
$ ./configure --with-extname --enable-someotherext --with-foobar
$ make
$ make install

Note: 要运行“buildconf”脚本,需要autoconf 2.13automake 1.4+(更新版本的autoconf 也许能工作,但不被支持)。
是否用--enable-extname--with-extname 取决于扩展库。通常不需要外部库文件的扩展库使用--enable。要确认的话,在buildconf之后运行:

$ ./configure --help | grep extname

PHPUnit 内 打印输出

单元测试,echo输出没东西?

问题

在PHPunit断点调试时,发现其中的 echo,print 语句时,不会立即输出,而是在测试脚本完成时才有全部输出。为了能够立马输出,在调试时,执行一行就输出一行,需要使用如下代码。

输出代码

<?php
        fwrite(STDERR, print_r("\n" . memory_get_usage(), TRUE));
        echo "\n" . memory_get_usage();

PHP 匿名函数 闭包语法 function use

匿名函数

匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。当然,也有其它应用的情况。

匿名函数目前是通过 Closure 类来实现的。

Example #1 匿名函数示例

<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
    return strtoupper($match[1]);
}, 'hello-world');
// 输出 helloWorld
?>

闭包函数也可以作为变量的值来使用。PHP 会自动把此种表达式转换成内置类 Closure 的对象实例。把一个 closure 对象赋值给一个变量的方式与普通变量赋值的语法是一样的,最后也要加上分号:

Example #2 匿名函数变量赋值示例

<?php
$greet = function($name)
{
    printf("Hello %s\r\n", $name);
};

$greet('World');
$greet('PHP');
?>

闭包可以从父作用域中继承变量。 任何此类变量都应该用 use 语言结构传递进去。 PHP 7.1 起,不能传入此类变量: superglobals、 $this 或者和参数重名。

Example #3 从父作用域继承变量

<?php
$message = 'hello';

// 没有 "use"
$example = function () {
    var_dump($message);
};
echo $example();

// 继承 $message
$example = function () use ($message) {
    var_dump($message);
};
echo $example();

// Inherited variable's value is from when the function
// is defined, not when called
$message = 'world';
echo $example();

// Reset message
$message = 'hello';

// Inherit by-reference
$example = function () use (&$message) {
    var_dump($message);
};
echo $example();

// The changed value in the parent scope
// is reflected inside the function call
$message = 'world';
echo $example();

// Closures can also accept regular arguments
$example = function ($arg) use ($message) {
    var_dump($arg . ' ' . $message);
};
$example("hello");
?>

完善的例子

<?php  
/** 
 * author: selfimpr 
 * mail: lgg860911@yahoo.com.cn 
 * blog: http://blog.csdn.NET/lgg201 
 * 下面提到的代码在PHP5.3以上版本运行通过. 
 */  
function callback($callback) {  
    $callback();  
}  
//输出: This is a anonymous function.<br />/n  
//这里是直接定义一个匿名函数进行传递, 在以往的版本中, 这是不可用的.  
//现在, 这种语法非常舒服, 和JavaScript语法基本一致, 之所以说基本呢, 需要继续向下看  
//结论: 一个舒服的语法必然会受欢迎的.  
callback(function() {  
    print "This is a anonymous function.<br />/n";  
});  
//输出: This is a closure use string value, msg is: Hello, everyone.<br />/n  
//这里首先定义了一个闭包, 这次户口本上有名字了...  
//use, 一个新鲜的家伙...  
//众所周知, 闭包: 内部函数使用了外部函数中定义的变量.  
//在PHP新开放的闭包语法中, 我们就是用use来使用闭包外部定义的变量的.  
//这里我们使用了外部变量$msg, 定义完之后, 又对其值进行了改变, 闭包被执行后输出的是原始值  
//结论: 以传值方式传递的基础类型参数, 闭包use的值在闭包创建是就确定了.  
$msg = "Hello, everyone";  
$callback = function () use ($msg) {  
    print "This is a closure use string value, msg is: $msg. <br />/n";  
};  
$msg = "Hello, everybody";  
callback($callback);  
//输出: This is a closure use string value lazy bind, msg is: Hello, everybody.<br />/n  
//换一种引用方式, 我们使用引用的方式来use  
//可以发现这次输出是闭包定义后的值...  
//这个其实不难理解, 我们以引用方式use, 那闭包use的是$msg这个变量的地址  
//当后面对$msg这个地址上的值进行了改变之后, 闭包内再输出这个地址的值时, 自然改变了.  
$msg = "Hello, everyone";  
$callback = function () use (&$msg) {  
    print "This is a closure use string value lazy bind, msg is: $msg. <br />/n";  
};  
$msg = "Hello, everybody";  
callback($callback);  
//输出: This is a closure use object, msg is: Hello, everyone.<br />/n  
//闭包中输出的是之前被拷贝的值为Hello, everyone的对象, 后面是对$obj这个名字的一个重新赋值.  
//可以这样考虑  
//1. obj是对象Hello, everyone的名字  
//2. 对象Hello, everyone被闭包use, 闭包产生了一个对Hello, everyone对象的引用  
//3. obj被修改为Hello, everybody这个对象的名字  
//4. 注意, 是名字obj代表的实体变了, 而不是Hello, everyone对象, 那自然闭包的输出还是前面的Hello, everyone  
$obj = (object) "Hello, everyone";  
$callback = function () use ($obj) {  
    print "This is a closure use object, msg is: {$obj->scalar}. <br />/n";  
};  
$obj = (object) "Hello, everybody";  
callback($callback);  
//输出: This is a closure use object, msg is: Hello, everybody.<br />/n  
//还是按照上面的步骤, 按部就班的来吧:  
//1. obj名字指向Hello, everyone对象  
//2. 闭包产生一个引用指向Hello, everyone对象  
//3. 修改obj名字指向的对象(即Hello, everyone对象)的scalar值  
//4. 执行闭包, 输出的自然是Hello, everybody, 因为其实只有一个真正的对象  
$obj = (object) "Hello, everyone";  
$callback = function () use ($obj) {  
    print "This is a closure use object, msg is: {$obj->scalar}. <br />/n";  
};  
$obj->scalar = "Hello, everybody";  
callback($callback);  
//输出: This is a closure use object lazy bind, msg is: Hello, everybody.<br />/n  
//闭包引用的是什么呢? &$obj, 闭包产生的引用指向$obj这个名字所指向的地址.  
//因此, 无论obj怎么变化, 都是逃不脱的....  
//所以, 输出的就是改变后的值  
$obj = (object) "Hello, everyone";  
$callback = function () use (&$obj) {  
    print "This is a closure use object lazy bind, msg is: {$obj->scalar}. <br />/n";  
};  
$obj = (object) "Hello, everybody";  
callback($callback);  
/** 
 * 一个利用闭包的计数器产生器 
 * 这里其实借鉴的是Python中介绍闭包时的例子... 
 * 我们可以这样考虑: 
 *      1. counter函数每次调用, 创建一个局部变量$counter, 初始化为1. 
 *      2. 然后创建一个闭包, 闭包产生了对局部变量$counter的引用. 
 *      3. 函数counter返回创建的闭包, 并销毁局部变量, 但此时有闭包对$counter的引用,  
 *          它并不会被回收, 因此, 我们可以这样理解, 被函数counter返回的闭包, 携带了一个游离态的 
 *          变量. 
 *      4. 由于每次调用counter都会创建独立的$counter和闭包, 因此返回的闭包相互之间是独立的. 
 *      5. 执行被返回的闭包, 对其携带的游离态变量自增并返回, 得到的就是一个计数器. 
 * 结论: 此函数可以用来生成相互独立的计数器. 
 */  
function counter() {  
    $counter = 1;  
    return function() use(&$counter) {return $counter ++;};  
}  
$counter1 = counter();  
$counter2 = counter();  
echo "counter1: " . $counter1() . "<br />/n";  
echo "counter1: " . $counter1() . "<br />/n";  
echo "counter1: " . $counter1() . "<br />/n";  
echo "counter1: " . $counter1() . "<br />/n";  
echo "counter2: " . $counter2() . "<br />/n";  
echo "counter2: " . $counter2() . "<br />/n";  
echo "counter2: " . $counter2() . "<br />/n";  
echo "counter2: " . $counter2() . "<br />/n";  
?>  

PHP 反射 reflection

PHP 反射 reflection

反射一个类

//反射一个类
$obj = new \App\DataProviders\RightScale(['cloud'=>3,'deployment'=>'']);
$observer = new \ReflectionClass($obj);

//反射一个属性
$property = $observer->getProperty('_instance');
$property->setAccessible(true);
$property->setValue($obj,'DHP9CG78PUVFA');

//反射一个方法
$method = $observer->getMethod('getCpuUsage');
$method->setAccessible(true);
$re = $method->invoke($obj, []);

PHPStorm Xdebug 断点调试 Docker 环境下 PHP教程

最详细的保姆级别的Dcoker环境想配置PHPStorm Xdebug 断点调试教程,图文并茂

为什么

PHP程序报错,肉眼review了多少遍都觉得自己的写得没问题;有个switch代码分支判断,为什么进不了我想要的case; 调试PHP代码还在用 var_dump($re); die();。试试Xdebug断点调试吧。

他能做什么

开启Debug监听,一步步顺着代码走进程序的最深处。你会了解到真实的代码运行步骤,以及调用关系。你还能知道每个变量在程序运行时,值的多少,以及变化。同时避免了 var_dump 代码植入,(如果忘了删除,提交到线上,那这个耻辱柱会狠狠地钉在你身上)

好的来介绍下我们的这期主角 Xdebug

Xdebug 是

Xdebug是一个PHP扩展,提供了调试和性能分析功能。[1]它使用DBGp调试协议。

Xdebug可以提供的调试信息包括以下内容:

  • 错误消息[2]中的堆栈和函数跟踪具有:

  • 用户定义功能的全参数显示

  • 函数名称,文件名和行指示
  • 支持成员功能

  • 内存分配

  • 保护无限递归

Xdebug还提供:

  • PHP脚本的概要分析信息[3]
  • 代码覆盖率分析
  • 调试器前端交互地调试脚本的功能。[4]

以上摘自wiki

开始动手

环境介绍

这篇文章主要围绕Docker环境下PHP的Xdebug调试展开。

先说下笔者演示环境:Mac环境,安装Virtual Box,跑了一个Ubuntu虚拟机,再装了Docker ce软件。看到这,大伙儿先别急着关网页啊,我的环境估计有些奇葩,但大致流程是差不多的。

这套PHP Docker环境这篇文章有详细介绍: [Docker快速搭建一套PHP、Nginx、MySQL、Redis、Xdebug、Memcached 开发环境

安装软件

为 PHP 安装 Xdebug

Xdebug 官方文档已介绍。

  • Linux 或 Mac 环境通过命令行:
$ pecl install xdebug
  • Windows 用户通过 Xdebug Download 页面,根据自己的PHP版本可直接下载 *.dll 放入到拓展目录即可。
$ php -v    // 查看 PHP 版本
  • 手动编译安装

对于网络不那么畅通,pecl不能用时。

## 获取源码
$ git clone https://github.com/xdebug/xdebug.git
## 进入目录
$ cd xdebug
## php检查
$ phpize
## 编译前配置,一般来说 phpize 已经准备好了大部分工作,以及配置
$ ./configure
## 编译
$ make
## 测试并安装
$ make test && make install
  • Docker 环境为PHP安装PHP拓展

Docker 环境下提供了两种方式,第一种是通过pecl在线下载安装,受限于网络状况,大概了下会失败。

那么可以尝试通过其他途径下载好pecl-Xdebug的压缩包,Add到docker容器中安装。

FROM php:7.3-fpm-buster

...

# 方法1 pecl 安装
RUN yes | pecl install xdebug \
    && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \
    && echo "xdebug.remote_enable=on" >> /usr/local/etc/php/conf.d/xdebug.ini \
    && echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini

## ------------------------------------------------
# 方法2 下载安装 xdebug
ADD ./xdebug-2.6.1.tgz /tmp/php7-xdebug
RUN cd /tmp/php7-xdebug/xdebug-2.6.1/ && phpize && ./configure && \
    make && make install

配置 xdebug

找到我们的配置文件.

## 文件: /etc/php/conf.d/xdebug.ini

zend_extension=xdebug.so            // 启用xdebug拓展!

xdebug.remote_connect_back=1
xdebug.remote_enable = 1            // 启用远程调试
xdebug.remote_mode = "req"
xdebug.remote_handler = "dbgp"
xdebug.remote_host = "10.0.2.2"     // 这是你PHPStorm运行环境的IP地址
xdebug.remote_port = 9000           // 默认9000,最好别动
xdebug.idekey="PHPSTORM"            // PHPStormIDE用的默认值
xdebug.remote_autostart = 1

关于这个 xdebug.remote_host 这个ip,不是想当然就填个 127.0.0.1, 你要看看你PHPStorm所运行的环境,和PHP运行环境是否在一个环境,如果是,你填 127.0.0.1 是没问题。是Docker那么就肯定不在一个环境了,怎么看我们IDE所处环境的IP呢,先编辑下入口文件 index.php, 获取SERVER变量的 REMOTE_ADDR 属性。

## 文件: ~/public/index.php
<?php
print_r($_SERVER['REMOTE_ADDR']);die();

打开浏览器访问下php-fpm服务。这里是多少,xdebug.remote_host 就填多少。

配置 Docker

Docker环境下,要用IDE去debug代码,IDE还需要和Docker打交道。就是在PHPStorm配置好Dcoker的API入口。

这个大家可以参考这片文章 Docker开启Remote API 访问 2375端口 来配置下Docker环境。

转载注明出处

配置 phpstorm

以上准备好了后,就开始我们的重头戏,配置PHPStorm.

1.将Docker Remote API配置在PHPStorm上.

由于我的环境装了Vbox,用了NAT,所以端口是42376,你要自己的环境配置为准。

下面的 Connection Successful 就表示配置成功了。这里的 Name: 名字要记下来,后面要用。

2.新增PHP Cli Interpreter.

搜索: php language,点击最右侧 ··· 按钮

选择 From Dcoker...

这里的 Server: 名字选择 第 1 步 的 Dcoker Server 的名字。 Image name: 选择你的php容器。

点击确认后,PHPStorm会检查 PHP容器的版本,Xdebug拓展是否启用。有如下提示,没有报错,则表示环境无误,可进行下一步。

留意下红框里面的 PHP version:

这里就是配置好之后的展示效果,PHP language level: 最好和 PHP 容器内一致.

3.配置 Deployment

这个配置是用来让IDE知道PHP代码运行环境,以及本地PHP代码之间的目录映射关系。

这里选择 Local or mounted flolder,首先会让你输入 New server name:

我输入的是 bs。你也可以输入别的,但都要记录下来,后面会用到这个名字。

这里Folder:配置PHPStorm运行环境的文件路径。(也就是Mac下文件路径。)

这里我们查看下 PHP 容器内代码路径.

切到 Deployemnt 配置的 Mapping Tab,在 Deploment path: 填上容器内代码路径, Local path: 选择本地环境代码路径。

4.配置PHP > Server, 这里点击圆圈内的 导入 按钮。在弹框中选择刚刚新增的 Deployment 配置。(就是刚刚输入的 New server name

File/Direcotry 你检查下,一般都没问题。Absolute path on the server 是你代码运行的Docker容器内的根目录。调整好之后,点击 OK.

先别急,关闭弹框后,再确认下 Absolute path on the server

这里估计是 PHPStorm 的一个Bug 还是产品的需求,弹框里外都要配置一次才好。

好PHPStorm的配置就完成了。

Docker runtime 配置

别急

Docker 运行时容器内,还需配置两个环境变量 PHP_IDE_CONFIG, XDEBUG_CONFIG.

  1. serverNameDeployment 配置的名字。

  2. remote_host 填PHPStorm环境的IP,也就是PHP中 $_SERVER['REMOTE_ADDR'] 的值。

  3. remote_port 默认 900.

  • 需要对 docker-compose.yaml 配置文件中的 php 容器新增环境变量:
## 文件: ~/docker-compose.yaml

version: "2"
services:
    php:
        image: paulxu/php:5.6-fpm-jessis-pdo-xdebug-mysqli-gd-mb-zip-2
        volumes:
            ...
        ports:
            ...
        environment: 
            PHP_IDE_CONFIG: "serverName=bs"
            XDEBUG_CONFIG: "remote_host=10.0.2.2 remote_port=9000"
  • 如果你用的 docker run 拉起的容器,加上如下参数
$ docker run ... --env PHP_IDE_CONFIG="serverName=dealman" --env PHP_IDE_CONFIG="serverName=bs" ... php /bin/bash

开始Debug

1.启用Xdebug listening,点击以下红色电话。

现在就是开始侦听状态。

2.找到入口文件 ~/index.php,选择第一行代码,打一个断点,(不知道点哪,按Commond+F8)

3.开始访问Web站点。

这里第一个断点是红色箭头处,通过点击绿色按钮 Step over,代码一步步执行到了蓝色箭头处,这行代码也被IDE蓝色高亮标底,此时还能从 Variables 看到 已定义变量 $conf 的值。

结语

以前的大佬还在炫耀用notepad手撕代码,一遍过。在越来越快的开发节奏中,使用高级的工具,以及详尽的仪表盘来开发调试代码。希望大家看了,都能配置成功。

有问题欢迎提问。

参考

vscode用xdebug调试php多进程程序
Mac下基于Docker在PhpStorm中配置Xdebug
使用 Xdebug 在 PHPStorm 中调试 PHP 程序(框架/原生均适用)