PHP的远程调试原理是:在浏览器中(或通过其他方式)访问远程服务器地址,远程服务器将debug信息发送至配置好的地址(标记为地址1),此地址为PHPStorm监听的地址,PHPStorm在收到数据后进行处理,并返回数据至远程服务器,依次往复,直到断点或结束。
地址1应为远程服务器可以访问到的地址,但是在公司没有独立的外网IP,也不舍得使用域名映射软件,因此决定使用PHP的socket来进行转发数据。
思路:
- 在远程服务器创建socket,监听9001端口,9000端口被占用
- 在本机创建socket1,连接远程服务器9001
- 在本机创建socket2,连接本机PHPstorm监听的9000
- socket收到DEBUG数据后,将数据转发至socket1,socket1将数据转发值socket2
- socket2收到PHPStorm数据后,将数据转发至socket1,socket1将数据转发至远程服务器
- .......
- .......
1.需求
一台远程服务器,我使用的是阿里云主机,域名是www.wanglovechu.com
XDEBUG扩展(远程服务器)
SOCKET扩展(远程服务器)
PHPStorm(本地)
项目文件(本地、远程服务器)
PHP运行环境(远程服务器)
2.在远程服务器开启远程调试
xdebug.remote_host=localhost
xdebug.remote_port=9000
此两行表示远程服务器将debug数据发送至localhost主机的9000端口,若本机有外网IP,可将xdebug.remote_host设置为本机的外网IP,同时应保证指定的端口(本例中为9000)可访问。
3.配置PHPStorm
3.1
在位置1 上写上远程服务器上项目地址,在位置2写上本地项目与远程项目地址,即配置项目映射。
3.2
在3(一个下拉列表)中选择3.1中创建好的server(wanglovechu)
在4中写入起始地址,若index.php已配置为DirectoryIndex(nginx中为index),则可直接写“/”
3.3
可以在5出写入自定义的名字,在6处选择3.2中配置好的server,也可点击7创建配置新的server
4.编写socket脚本
远程服务器端脚本server.php
<?php
/**
* Created by PhpStorm.
* User: wwzhenu
* Date: 2018/1/22
* Time: 14:33
*/
# 服务器将数据发送至此接口
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === FALSE)
die('socket_create fail');
$ip = '0.0.0.0';
$port = 9001;
if (socket_bind($socket, $ip, $port) === FALSE)
die('9001 socket_bind fail');
if (socket_listen($socket, 4) === FALSE)
die('9001 socket_listen fail');
$client=NULL;
$server=NULL;
$read[]=$socket;
do{
socket_select($read,$w,$e,NULL);
foreach ($read as $s){
if ($s==$socket){
echo 'a new connection'.PHP_EOL;
$get=socket_accept($s);
$data=socket_read($get,10000000);
# 收到客户端数据
if ($data=='wang'){
echo 'client connect'.PHP_EOL;
$client=$get;
}
# 收到chrome数据
else{
ECHO 'debug data'.PHP_EOL;
$server=$get;
if (isset($client))
socket_write($client,$data,strlen($data));
}
echo $data.PHP_EOL;
}else if($s==$client){
echo 'receive PHPstorm data'.PHP_EOL;
$data=socket_read($s,10000000);
echo $data.PHP_EOL;
socket_write($server,$data,strlen($data));
}else if ($s==$server){
echo 'receive debug data'.PHP_EOL;
$data=socket_read($s,10000000);
echo $data.PHP_EOL;
socket_write($client,$data,strlen($data));
}
}
$read=[$socket];
if (isset($client))
$read[]=$client;
if (isset($server))
$read[]=$server;
}while(1);
本机需要执行脚本client.php
<?php
/**
* Created by PhpStorm.
* User: wwzhenu
* Date: 2018/1/22
* Time: 14:44
*/
# 连接远程
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === FALSE)
die('socket_create fail');
$ip="www.wanglovechu.com";
$port=9001;
socket_connect($socket, $ip, $port);
socket_write($socket,'wang',4);
#连接PHPstorm
$phpstorm = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($phpstorm === FALSE)
die('socket_create fail');
$ip="127.0.0.1";
$port=9000;
socket_connect($phpstorm, $ip, $port);
$read[] = $socket;
$read[] = $phpstorm;
do{
socket_select($read,$w,$e,NULL);
foreach ($read as $s){
# 收到远程数据
if ($s==$socket){
echo 'receive debug data'.PHP_EOL;
$data=socket_read($s,10000000);
socket_write($phpstorm,$data,strlen($data));
}
# 收到PHPstorm数据
elseif ($s==$phpstorm){
echo 'PHPstorm data'.PHP_EOL;
$data=socket_read($s,10000000);
socket_write($socket,$data,strlen($data));
}
echo $data.PHP_EOL;
}
$read=[$phpstorm,$socket];
}while(1);
5.执行脚本
在服务器执行server.php
在本机执行client.php
6.打断点,开始调试
点击右上角的小虫子按钮,开始调试,此时会使用配置好的浏览器访问www.wanglovechu.com/socket/index.php.....
再查看PHPStorm,可以查看到调试信息
注:这两个脚本只能使用一次,如需再次调试,需重新执行脚本,因为每次DEBUG,PHPStorm会使用新的socket,有兴趣的可以完善一下。
若有不准确或错误的地方烦请留言告知,不胜感激。