Windows 10 下使用 PHPStorm 開(kāi)發(fā)/調(diào)試 Docker +deockerfile+Swoole + XDebug + Hyperf

前言

Xdebug 應(yīng)該有很多人并不會(huì)陌生,調(diào)試安裝雖然有些繁瑣,但是使用起來(lái)還是很順手。

Docker 和 Swoole ,近年來(lái)也是很火,就是不便于調(diào)試,很多人看到標(biāo)題的第一反應(yīng)「Swoole 不是和 Xdebug 不兼容嗎?」,
是的,在 Swoole 的官方文檔中就明確指出了 Swoole 和 Xdebug 不兼容。

image

但是,強(qiáng)大的社區(qū)還是給了我們答案:SDEBUG

Sdebug 是 fork 自 Xdebug 2.7 ,可用于 Swoole 環(huán)境進(jìn)行斷點(diǎn)、調(diào)試的一個(gè)工具。

運(yùn)行環(huán)境

| 軟件 | 版本 |
| Windows 10 專(zhuān)業(yè)版 | 1909 |
| PHPStorm | 2020.1 |
| Docker Desktop | 2.2.0.5(43884) |
| Docker | 19.03.8 |
| Hyper-V | latest |
| Hyperf (PHP Framework) | 1.1.25 (hyperf-skeleton create) |
| Sdebug | 2.7 |
| PHP | 7.3.12 |

開(kāi)始安裝

Docker && Docker Desktop

Docker 在 Windows 下可以通過(guò) 官網(wǎng)下載 ,但是需要注意有以下限制。

  • 64 位操作系統(tǒng)
  • 4G 以上的 RAM
  • BIOS 中開(kāi)啟虛擬化
  • Windows 專(zhuān)業(yè)版及以上
  • 開(kāi)啟 Hyper-V

這里我并不打算展開(kāi)介紹,因?yàn)轭?lèi)似的文章實(shí)在太多了,確保 Docker 安裝完成。

當(dāng)安裝完成后,在你的桌面任務(wù)欄會(huì)出現(xiàn)一個(gè) 靜態(tài) Docker 的小圖標(biāo),注意,這里強(qiáng)調(diào)一下 靜態(tài) 靜態(tài)圖標(biāo)表示 Docker 在運(yùn)行中,動(dòng)態(tài)則表示處于啟動(dòng)中等非運(yùn)行狀態(tài),然后右鍵點(diǎn)擊,選擇 Settings ,我們需要打開(kāi)兩個(gè)選項(xiàng)。

  • 1、啟用 TCP 連接
image
  • 2、設(shè)置國(guó)內(nèi)的 Docker Hub 鏡像
image
{
  "registry-mirrors": [
    "http://hub-mirror.c.163.com"
  ],
  "insecure-registries": [],
  "debug": true,
  "experimental": false
}

現(xiàn)在,選擇右下角的 Apply & Restart 等待 Docker 重啟,如果 Docker 沒(méi)有重啟,可以手動(dòng)點(diǎn)擊任務(wù)欄 Docker 圖標(biāo)的 Restart ,重啟完成后,執(zhí)行命令檢查。

$ docker info
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Registry Mirrors:
 http://hub-mirror.c.163.com/
Live Restore Enabled: false
Product License: Community Engine

現(xiàn)在你應(yīng)該可以看到網(wǎng)易的鏡像地址。

開(kāi)始吧

檢查連接

能否進(jìn)行調(diào)試的重要因素就是 Docker 容器能否和宿主機(jī)進(jìn)行通信,否則,以下都是白扯。

使用 PowersShell 或者 Cmder

就是去改window系統(tǒng) C:/Windows/System32/drivers/etc/hosts文件加一行

$ cat C:/Windows/System32/drivers/etc/hosts|findstr host.docker.internal
192.168.3.22 host.docker.internal

執(zhí)行后你應(yīng)該可以看到輸出了一個(gè) 192.168.x.x 的 IP ,映射到了 host.docker.internal,請(qǐng)記住這個(gè) IP。
現(xiàn)在執(zhí)行如下命令,運(yùn)行一個(gè) alpine linux 容器,并執(zhí)行一個(gè) ping 命令,但是你在這里是看不到輸出的。

  • 擴(kuò)展閱讀

Networking features in Docker Desktop for Windows | Docker Documentation

$ docker run -di alpine:latest
a8369f4e057e161c2079281e4bfbc31dc509f802e3ce0c2f09708cd8613459ae

接著執(zhí)行以下命令獲取到容器的 ID ,其實(shí)在上一條執(zhí)行完畢我們就已經(jīng)得到了容器 ID。

$ docker ps
CONTAINER ID        IMAGE               COMMAND               CREATED              STATUS              PORTS               NAMES
a8369f4e057e        alpine:latest       "/bin/sh"   About a minute ago   Up About a minute                       pensive_lehmann

使用 docker exec 打開(kāi)可以可以和容器交互的命令行。

$ docker exec -it a8369f4e057e sh

一般我們看到的命令都是 docker exec -it <CONTAINER ID> /bin/bash ,但是 alpine 沒(méi)有 /bin/bash 這個(gè)位置,所以這里我們直接用 sh 即可。
在進(jìn)去終端后,我們從新執(zhí)行一下 ping 命令。

/ # ping 192.168.3.22
PING 192.168.3.22 (192.168.3.22): 56 data bytes
64 bytes from 192.168.3.22: seq=0 ttl=37 time=1.003 ms
64 bytes from 192.168.3.22: seq=1 ttl=37 time=0.937 ms
64 bytes from 192.168.3.22: seq=2 ttl=37 time=1.026 ms
64 bytes from 192.168.3.22: seq=3 ttl=37 time=1.141 ms
^C
--- 192.168.3.22 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.937/1.026/1.141 ms

如果能輸出正常的 ping 信息,說(shuō)明我們的 docker 容器內(nèi)部可以和主機(jī)通信了。
如果不行,可以嘗試 ping 192.168.56.1。
如果這兩個(gè)命令都 ping 不通,我覺(jué)得你就沒(méi)必要看了,??因?yàn)樽罨镜木褪且龅?Docker 容器內(nèi)部和宿主機(jī)通信,才能
使用 Xdebug,如果你只是想搭建一個(gè)開(kāi)發(fā)環(huán)境,那么你還可以繼續(xù)看下去。

接下來(lái)的內(nèi)容,我會(huì)帶你使用 Dockerfile 構(gòu)建一個(gè)自己的 Docker PHP 開(kāi)發(fā)環(huán)境。

Docker

安裝 PHP

大多數(shù)情況下,我都會(huì)選用最新的 PHP 作為開(kāi)發(fā)使用,除非項(xiàng)目要求使用舊版,這里就屬于情況例外。因?yàn)?Sdebug 是基于 Xdebug 2.7 的,
而 Xdebug 2.7 是不支持最新的 PHP 7.4 的,所以我們只能到 Docker Hub PHP Library 選擇一個(gè)較新的 php:7.3.17-cli-alpine3.11 這個(gè) tag。
新建一個(gè) php.dockerfile 文件,并安裝一些必要的擴(kuò)展和 Composer。
步驟 先

#先不用急著安裝,請(qǐng)看完最后一個(gè)Dockerfile內(nèi)容 ,會(huì)把這些一起安裝
docker pull  php:7.3.17-cli-alpine3.11

然后去工作目錄創(chuàng)建一個(gè)項(xiàng)目文件夾。比如D盤(pán)://docker/php
然后在文件夾里新建一個(gè)文件Dockerfile
Dockerfile內(nèi)容如下

#先不用急著運(yùn)行,請(qǐng)看完最后一個(gè)Dockerfile內(nèi)容 ,會(huì)把這些一起運(yùn)行
FROM php:7.3.17-cli-alpine3.11
# 現(xiàn)在我們需要配置一些東西。
# 編譯參數(shù),用于指定 Swoole 版本
ARG swoole_ver
# 保存到環(huán)境變量,如果沒(méi)有傳遞就給默認(rèn)值
ENV SWOOLE_VER=${swoole_ver:-"v4.4.15"}

# apk 是 alpine 的一個(gè)包管理器
# set -ex 是為了在出錯(cuò)時(shí)及時(shí)停掉腳本
RUN set -ex \
    # 在臨時(shí)目錄進(jìn)行這一切
    && cd /tmp \
    # 把 apk 的默認(rèn)源改為aliyun鏡像
    && sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
    # 更新包列表
    && apk update \
    # 添加這么多擴(kuò)展是因?yàn)楹竺嫖覀兙幾g swoole 和 sdebug 需要用到 
    && apk add vim git autoconf openssl-dev build-base zlib-dev re2c libpng-dev oniguruma-dev

# install composer
RUN cd /tmp \
    # 從aliyun 下載composer 
    && wget https://mirrors.aliyun.com/composer/composer.phar \
    && chmod u+x composer.phar \
    && mv composer.phar /usr/local/bin/composer \
    # 給 composer 設(shè)置aliyun鏡像
    && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer \
    # 把 composer 全局命令加入 PATH ,以確保以后我們會(huì)用到
    && echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.bashrc

# php ext
RUN php -m \
    # docker-php-ext-install 是 php 為我們提供的指令,讓我們可以安裝一些 php 的預(yù)設(shè)擴(kuò)展
    # 可以在這里啟用必要的擴(kuò)展
    && docker-php-ext-install gd pdo_mysql mysqli sockets pcntl \
    # 現(xiàn)在可以檢查一下 php 已經(jīng)安裝的擴(kuò)展
    && php -m

在當(dāng)前目錄 打開(kāi)命令窗口 cmd 命令

#執(zhí)行Dockerfile  命令如下
#先不用急著打包,請(qǐng)看完最后一個(gè)Dockerfile內(nèi)容 ,會(huì)把這些一起執(zhí)行
docker build -t="php:7.3.17" .

這樣我們的鏡像就可以運(yùn)行 php 了,但是接下來(lái)我們還要安裝 swoole 。

安裝 Swoole

如果用過(guò) PECL 的朋友可能會(huì)知道,Swoole、PhpRedis 可以用 PECL 直接安裝,但是 PECL 安裝因?yàn)橄螺d比較慢,所以我們這里
采用 Swoole 官方在國(guó)內(nèi)的倉(cāng)庫(kù)

# install swoole
RUN cd /tmp \
    # from mirrors
    && git clone https://gitee.com/swoole/swoole swoole \
    && cd swoole \
    # 切換到指定版本的 tag
    && git checkout ${SWOOLE_VER} \
    && phpize \
    # 執(zhí)行configure命令
    && ./configure --enable-openssl --enable-sockets --enable-http2 --enable-mysqlnd \
    && make \
    && make install \
    # 通過(guò) docker-php-ext-enable 來(lái)啟用擴(kuò)展,這個(gè)命令也是 php 為我們提供的。
    && docker-php-ext-enable swoole \
    # 檢查 php 已經(jīng)安裝的模塊
    && php -m \
    # 檢查 swoole 是否正確安裝
    && php --ri swoole

安裝 Sdebug

Sdebug 源代碼托管在了 Github 上面,眾所周知,因?yàn)橐恍┰颍珿ithub 下載速度很慢,所以我們需要使用到國(guó)內(nèi)鏡像,
但是 Sdebug 在國(guó)內(nèi)貌似也沒(méi)有鏡像,所以就要我們自己動(dòng)手了,到 碼云 ,注冊(cè)一個(gè)帳號(hào),然后新建項(xiàng)目選擇從 Github 導(dǎo)入,
這樣我們就能創(chuàng)建一個(gè)倉(cāng)庫(kù)的鏡像了,我已經(jīng)創(chuàng)建好了一個(gè) Sdebug ,如果你介意的話(huà),可以自己創(chuàng)建一個(gè),方法就在上面。
安裝 Sdebug 的過(guò)程和 Swoole 幾乎完全一樣,但是也要注意一些點(diǎn),接下來(lái)在 Dockerfile 中我將會(huì)詳細(xì)注釋

# install sdebug
# 運(yùn)行克隆前,先把目錄切換到 /tmp ,避免之前的命令導(dǎo)致目錄錯(cuò)誤
RUN cd /tmp \
    # from mirrors
    && git clone https://gitee.com/vyi/sdebug sdebug \
    # 進(jìn)入克隆的目錄
    && cd sdebug \
    # 切換到 sdebug_2_7 分支,這里一定到切換分支,因?yàn)?master 分支是 Xdebug 的源碼
    && git checkout sdebug_2_7 \
    && phpize \
    && ./configure --enable-xdebug \
    && make \
    && make install \
    # 這里 安裝完成后執(zhí)行的值 xdebug
    && docker-php-ext-enable xdebug \
    && php -m \
    # 這里檢查也是喲,注意是 sdebug
    && php --ri sdebug

現(xiàn)在一切都安裝完成了,我們還需要對(duì) swoole 和 sdebug 進(jìn)行簡(jiǎn)單的配置,跟剛才一樣,這里還是使用 Dockerfile 指令
/usr/local/etc/php/conf.d 這個(gè)位置是 php 默認(rèn)會(huì)掃描的 ini 加載目錄,我們可以執(zhí)行php --ini命令檢查

/mnt/d/htdocs/tom # php --ini
Configuration File (php.ini) Path: /usr/local/etc/php
Loaded Configuration File:         (none)
Scan for additional .ini files in: /usr/local/etc/php/conf.d
Additional .ini files parsed:      /usr/local/etc/php/conf.d/99-xdebug-enable.ini,
/usr/local/etc/php/conf.d/docker-php-ext-gd.ini,
/usr/local/etc/php/conf.d/docker-php-ext-mysqli.ini,
/usr/local/etc/php/conf.d/docker-php-ext-pcntl.ini,
/usr/local/etc/php/conf.d/docker-php-ext-pdo_mysql.ini,
/usr/local/etc/php/conf.d/docker-php-ext-redis.ini,
/usr/local/etc/php/conf.d/docker-php-ext-sockets.ini,
/usr/local/etc/php/conf.d/docker-php-ext-sodium.ini,
/usr/local/etc/php/conf.d/docker-php-ext-swoole.ini,
/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

可以看到以下內(nèi)容,也就是說(shuō)他會(huì)在這里掃描配置文件

Scan for additional .ini files in: /usr/local/etc/php/conf.d

# config php
RUN cd /usr/local/etc/php/conf.d \
    # swoole config
    # 關(guān)閉 swoole 短名稱(chēng),使用 Hyperf 這個(gè)是必須要
    && echo "swoole.use_shortname = off" >> 99-off-swoole-shortname.ini \
    # config xdebug
    && { \
        # 添加一個(gè) Xdebug 節(jié)點(diǎn)
        echo "[Xdebug]"; \
        # 啟用遠(yuǎn)程連接
        echo "xdebug.remote_enable = 1"; \
        # 這個(gè)是多人調(diào)試,但是現(xiàn)在有些困難,就暫時(shí)不啟動(dòng)
        echo ";xdebug.remote_connect_back = On"; \
        # 自動(dòng)啟動(dòng)遠(yuǎn)程調(diào)試
        echo "xdebug.remote_autostart  = true"; \
        # 這里 host 可以填前面取到的 IP ,也可以填寫(xiě) host.docker.internal 。
        echo "xdebug.remote_host = host.docker.internal"; \
        # 這里端口固定填寫(xiě) 19000 ,當(dāng)然可以填寫(xiě)其他的,需要保證沒(méi)有被占用
        echo "xdebug.remote_port = 19000"; \
        # 這里固定即可
        echo "xdebug.idekey=PHPSTORM"; \
        # 把執(zhí)行結(jié)果保存到 99-xdebug-enable.ini 里面去
    } | tee 99-xdebug-enable.ini

host.docker.internal 和 19000 這兩個(gè)是必然關(guān)系,這 host 指向的是宿主機(jī),端口是 PHP Storm 監(jiān)聽(tīng)的端口,docker 需要把請(qǐng)求發(fā)送過(guò)去,所以這里需要確保沒(méi)有被占用。

  • 擴(kuò)展閱讀

Networking features in Docker Desktop for Windows | Docker Documentation

安裝 PhpRedis

因?yàn)轫?xiàng)目需要連接 Redis 所以使用這個(gè)擴(kuò)展,這個(gè)只是一個(gè)連接庫(kù),并不是 Redis。

# install phpredis
RUN cd /tmp \
    # from mirrors
    && git clone https://gitee.com/mirrors/phpredis phpredis \
    && cd phpredis \
    && phpize \
    && ./configure \
    && make \
    && make install \
    && docker-php-ext-enable redis \
    && php -m \
    && php --ri redis

雜項(xiàng)配置

# check
# 檢查一下 PHP 版本信息和 已安裝的模塊
RUN cd /tmp \
    # 檢查 PHP 版本
    && php -v \
    # 檢查已安裝的模塊
    && php -m \
    && echo -e "Build Completed!"

# 暴露 9501 端口
EXPOSE 9501
# 設(shè)置工作目錄,即默認(rèn)登錄目錄,這個(gè)目錄現(xiàn)在并不存在,
# 我們需要在 run 時(shí)把我們外部 windows 的文件目錄映射到 docker 容器中去
WORKDIR /mnt/d/htdocs

Dockerfile

現(xiàn)在我們的 Dockerfile 應(yīng)該已經(jīng)是下面的樣子

FROM php:7.3.17-cli-alpine3.11
# 現(xiàn)在我們需要配置一些東西。
# 編譯參數(shù),用于指定 Swoole 版本
ARG swoole_ver
# 保存到環(huán)境變量,如果沒(méi)有傳遞就給默認(rèn)值
ENV SWOOLE_VER=${swoole_ver:-"v4.4.15"}

# apk 是 alpine 的一個(gè)包管理器
# set -ex 是為了在出錯(cuò)時(shí)及時(shí)停掉腳本
RUN set -ex \
    # 在臨時(shí)目錄進(jìn)行這一切
    && cd /tmp \
    # 把 apk 的默認(rèn)源改為aliyun鏡像
    && sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
    # 更新包列表
    && apk update \
    # 添加這么多擴(kuò)展是因?yàn)楹竺嫖覀兙幾g swoole 和 sdebug 需要用到 
    && apk add vim git autoconf openssl-dev build-base zlib-dev re2c libpng-dev oniguruma-dev

# install composer
RUN cd /tmp \
    # 從aliyun 下載composer 
    && wget https://mirrors.aliyun.com/composer/composer.phar \
    && chmod u+x composer.phar \
    && mv composer.phar /usr/local/bin/composer \
    # 給 composer 設(shè)置aliyun鏡像
    && composer config -g repo.packagist composer https://mirrors.aliyun.com/composer \
    # 把 composer 全局命令加入 PATH ,以確保以后我們會(huì)用到
    && echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.bashrc

# php ext
RUN php -m \
    # docker-php-ext-install 是 php 為我們提供的指令,讓我們可以安裝一些 php 的預(yù)設(shè)擴(kuò)展
    # 可以在這里啟用必要的擴(kuò)展
    && docker-php-ext-install gd pdo_mysql mysqli sockets pcntl \
    # 現(xiàn)在可以檢查一下 php 已經(jīng)安裝的擴(kuò)展
    && php -m

# install swoole
RUN cd /tmp \
    # from mirrors
    && git clone https://gitee.com/swoole/swoole swoole \
    && cd swoole \
    # 切換到指定版本的 tag
    && git checkout ${SWOOLE_VER} \
    && phpize \
    # 執(zhí)行configure命令
    && ./configure --enable-openssl --enable-sockets --enable-http2 --enable-mysqlnd \
    && make \
    && make install \
    # 通過(guò) docker-php-ext-enable 來(lái)啟用擴(kuò)展,這個(gè)命令也是 php 為我們提供的。
    && docker-php-ext-enable swoole \
    # 檢查 php 已經(jīng)安裝的模塊
    && php -m \
    # 檢查 swoole 是否正確安裝
    && php --ri swoole

# install sdebug
# 運(yùn)行克隆前,先把目錄切換到 /tmp ,避免之前的命令導(dǎo)致目錄錯(cuò)誤
RUN cd /tmp \
    # from mirrors
    && git clone https://gitee.com/vyi/sdebug sdebug \
    # 進(jìn)入克隆的目錄
    && cd sdebug \
    # 切換到 sdebug_2_7 分支,這里一定到切換分支,因?yàn)?master 分支是 Xdebug 的源碼
    && git checkout sdebug_2_7 \
    && phpize \
    && ./configure --enable-xdebug \
    && make \
    && make install \
    # 這里 安裝完成后執(zhí)行的值 xdebug
    && docker-php-ext-enable xdebug \
    && php -m \
    # 這里檢查也是喲,注意是 sdebug
    && php --ri sdebug

# config php
RUN cd /usr/local/etc/php/conf.d \
    # swoole config
    # 關(guān)閉 swoole 短名稱(chēng),使用 Hyperf 這個(gè)是必須要
    && echo "swoole.use_shortname = off" >> 99-off-swoole-shortname.ini \
    # config xdebug
    && { \
        # 添加一個(gè) Xdebug 節(jié)點(diǎn)
        echo "[Xdebug]"; \
        # 啟用遠(yuǎn)程連接
        echo "xdebug.remote_enable = 1"; \
        # 這個(gè)是多人調(diào)試,但是現(xiàn)在有些困難,就暫時(shí)不啟動(dòng)
        echo ";xdebug.remote_connect_back = On"; \
        # 自動(dòng)啟動(dòng)遠(yuǎn)程調(diào)試
        echo "xdebug.remote_autostart  = true"; \
        # 這里 host 可以填前面取到的 IP ,也可以填寫(xiě) host.docker.internal 。
        echo "xdebug.remote_host = host.docker.internal"; \
        # 這里端口固定填寫(xiě) 19000 ,當(dāng)然可以填寫(xiě)其他的,需要保證沒(méi)有被占用
        echo "xdebug.remote_port = 19000"; \
        # 這里固定即可
        echo "xdebug.idekey=PHPSTORM"; \
        # 把執(zhí)行結(jié)果保存到 99-xdebug-enable.ini 里面去
    } | tee 99-xdebug-enable.ini

# install phpredis
RUN cd /tmp \
    # from mirrors
    && git clone https://gitee.com/mirrors/phpredis phpredis \
    && cd phpredis \
    && phpize \
    && ./configure \
    && make \
    && make install \
    && docker-php-ext-enable redis \
    && php -m \
    && php --ri redis

# check
# 檢查一下 PHP 版本信息和 已安裝的模塊
RUN cd /tmp \
    # 檢查 PHP 版本
    && php -v \
    # 檢查已安裝的模塊
    && php -m \
    && echo -e "Build Completed!"

# 暴露 9501 端口
EXPOSE 9501
# 設(shè)置工作目錄,即默認(rèn)登錄目錄,這個(gè)目錄現(xiàn)在并不存在,
# 我們需要在 run 時(shí)把我們外部 windows 的文件目錄映射到 docker 容器中去
WORKDIR /mnt/d/htdocs

以上就是我們完整的 Dockerfile,現(xiàn)在我們要來(lái)生成一下鏡像文件

docker build -f php.dockerfile -t faqqcn/php-swoole-sdebug:1.0 .
  • -f 表示我們要使用那個(gè) dockerfile 文件
  • -t 表示為我們的鏡像起一個(gè)名字格式 <domain>/<name>:<tag>
  • . 最后的 . 表示當(dāng)前目錄
Successfully built 9c5c20556cf2
Successfully tagged faqqcn/php-swoole-sdebug:1.0
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

輸出以上內(nèi)容說(shuō)明鏡像制作成功了,現(xiàn)在來(lái)看一下。

$ docker image ls                                                                                     
REPOSITORY                 TAG                         IMAGE ID            CREATED              SIZE  
faqqcn/php-swoole-sdebug   1.0                         9c5c20556cf2        About a minute ago   526MB 

現(xiàn)在來(lái)運(yùn)行一下

$ docker run -di -p 8080:9501 -v D:/2vy-cc/htdocs:/mnt/d/htdocs --name php-swoole-sdebug faqqcn/php-swoole-sdebug:1.0
19db6032c9fe9cd2228844e4c029c980f14172991a4f113480ee5facd1763c2e
  • 參數(shù)解釋

| 參數(shù) | 說(shuō)明 |
| -di | 這是兩個(gè)參數(shù) -d 和 -i 的簡(jiǎn)寫(xiě),d 表示后臺(tái)運(yùn)行,i 表示交互操作 |
| -p | 啟用一個(gè)端口映射,把宿主機(jī)的 8080 和 容器 內(nèi)的 9501 映射 |
| -v | 啟用一個(gè)目錄映射,把宿主機(jī)的 D:/2vy-cc/htdocs 目錄和 容器內(nèi)的 /mnt/d/htdocs 映射 |
| --name | 給容器起一個(gè)名字,方便下次啟動(dòng)、停用、刪除、日志 |

更多參數(shù)詳見(jiàn) Docker run 命令

最后面就跟上我們鏡像的名字,然后 docker 會(huì)輸出一個(gè)容器的 id

現(xiàn)在進(jìn)入容器。

docker exec -it php-swoole-sdebug sh

-it 表示創(chuàng)建一個(gè)交互操作和創(chuàng)建一個(gè)終端,后面跟剛剛上面的 name ,最后跟一個(gè)啟動(dòng)的 shell , alpine 默認(rèn)是 sh
進(jìn)入到終端內(nèi)后檢查一下 php 信息,并創(chuàng)建一下項(xiàng)目

# php -v                                                 
PHP 7.3.17 (cli) (built: Apr 24 2020 18:12:13) ( NTS )                 
Copyright (c) 1997-2018 The PHP Group                                  
Zend Engine v3.3.17, Copyright (c) 1998-2018 Zend Technologies         
    with Sdebug v2.7.3-dev, Copyright (c) 2002-2019, by Derick Rethans 

# php -m
[PHP Modules]      
Core               
ctype              
curl               
date               
dom                
fileinfo           
filter             
ftp                
gd                 
hash               
iconv              
json               
libxml             
mbstring           
mysqli             
mysqlnd            
openssl            
pcntl              
pcre               
PDO                
pdo_mysql          
pdo_sqlite         
Phar               
posix              
readline           
redis              
Reflection         
sdebug             
session            
SimpleXML          
sockets            
sodium             
SPL                
sqlite3            
standard           
swoole             
tokenizer          
xml                
xmlreader          
xmlwriter          
zlib               

[Zend Modules]     
Sdebug             

# composer                                      
   ______                                            
  / ____/___  ____ ___  ____  ____  ________  _____  
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/  
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /      
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/       
                    /_/                              
Composer version 1.10.5 2020-04-10 11:44:22          

可以看到已經(jīng)安裝 swoole、redis、Sdebug、composer ,接下來(lái)我們將創(chuàng)建一個(gè) Hyperf 項(xiàng)目

創(chuàng)建項(xiàng)目

# composer create-project hyperf/hyperf-skeleton

安裝過(guò)程中會(huì)有一個(gè)引導(dǎo),這里你可以全部敲回車(chē)默認(rèn),也可以根據(jù)需要選擇自己要用的組件。
現(xiàn)在進(jìn)入項(xiàng)目,并啟動(dòng)。

cd hyperf-skeleton
php bin/hyperf.php start

你將會(huì)看到一切錯(cuò)誤蹦了出來(lái),但是不要擔(dān)心,如果你細(xì)看,你會(huì)發(fā)現(xiàn)這是 Redis 的錯(cuò)誤,稍后我們來(lái)解決它。
為了我們愉快的開(kāi)發(fā),如果每次修改文件后我們都要來(lái)執(zhí)行一下上面的命令,豈不是很麻煩,
我們現(xiàn)在來(lái)安裝一個(gè)自動(dòng)文件修改后自動(dòng)重啟的工具 hyperf-watch

# curl -o watch https://gitee.com/liangguifeng/hyperf-watch/raw/master/watch

# ls -alF | grep watch
  -rwxr-xr-x    1 root     root          3921 May  4 07:40 watch*

如果這里的 watch 權(quán)限中沒(méi)有 x 我們就手動(dòng)給他加一下

chmod +x watch

現(xiàn)在我們執(zhí)行 php watch。然后在宿主機(jī)中打開(kāi) PHPStorm ,開(kāi)始在 PHPStorm 里面寫(xiě)代碼,并配置 Sdebug。

php watch

PHPStorm

打開(kāi)文件

  • config/autoload/async_queue.php

修改里面的 'processes' => 1,'processes' => 0, 注意,這里是指關(guān)掉異步隊(duì)列,從而來(lái)解決
控制臺(tái)中的 Redis 錯(cuò)誤,如果你需要使用到異步隊(duì)列,請(qǐng)把這里保持不變,并且到 config/autoload/redis.php 中正確配置 redis 鏈接信息。

保存后,看到控制臺(tái)會(huì)自動(dòng)重啟,現(xiàn)在頁(yè)面已經(jīng)不會(huì)報(bào)錯(cuò)了,在瀏覽器中訪問(wèn)試試,剛剛我們把宿主機(jī)的 8080 映射到了主機(jī)內(nèi)的 9501 端口,
所以我們直接訪問(wèn)本機(jī)的 8080 端口。

image

OK,現(xiàn)在我們已經(jīng)可以訪問(wèn)到 docker 中部署的項(xiàng)目了,接下來(lái)配置調(diào)試。
打開(kāi) PHPStorm 設(shè)置 進(jìn)入 Languages & Frameworks | PHP ,看起來(lái)是下面這樣。

image

點(diǎn)擊這里的 ...

image

選擇 + 并選擇 From Docker ...

image.png

如果這里沒(méi)有出現(xiàn) successful 這說(shuō)明你在第一步出錯(cuò)了,沒(méi)有啟用 TCP 連接,選擇上這里后重啟 docker

image

這里選擇鏡像。


image.png

檢查確認(rèn)后 ok

image

現(xiàn)在進(jìn)去這里從新選擇選擇一下容器和本機(jī)的映射關(guān)系,幫助我們?cè)谡{(diào)試是找到對(duì)應(yīng)的文件,否則會(huì)調(diào)試失敗。

image.png

先刪除已有的映射關(guān)系,選中默認(rèn)的映射

image

然后點(diǎn)擊上一行的 Mapping 進(jìn)去添加

image.png

現(xiàn)在添加一下目錄映射關(guān)系


image

現(xiàn)在,在打開(kāi)設(shè)置 Languages & Frameworks | PHP | Debug

image

創(chuàng)建一個(gè)服務(wù),并填寫(xiě)對(duì)應(yīng)的信息,并且請(qǐng)記住 Name XDEBUG_02 這個(gè)名字

image

新建一個(gè)調(diào)試

image

添加一個(gè)配置

image.png

現(xiàn)在點(diǎn)擊右上角的電話(huà),讓他變成這個(gè)狀態(tài)。


image.png

啟動(dòng)調(diào)試吧!

image

切換到容器窗口,結(jié)束掉先前的命令,現(xiàn)在我們執(zhí)行 php watch ,你會(huì)發(fā)現(xiàn)卡住了?。?!這特喵什么鬼呀?這就說(shuō)明 Xdebug 開(kāi)始工作了
切換到 PHPStorm ,你會(huì)發(fā)現(xiàn)左邊的跳過(guò)按鈕斷點(diǎn)按鈕綠了,現(xiàn)在我們從新點(diǎn)到 Debugger 欄目下,你會(huì)發(fā)現(xiàn)有一個(gè)錯(cuò)誤。而且 IDE 中沒(méi)效果。
因?yàn)檫@還么有真正完成。

image.png

現(xiàn)在我們來(lái)解決它 ,根據(jù)錯(cuò)誤錯(cuò)誤信息,我們簡(jiǎn)單了解到,是需要以環(huán)境變量,叫 PHP_IDE_CONFIG ,點(diǎn)擊 more info...,
進(jìn)去 PHPStorm 的文檔頁(yè)面,檢索一下 PHP_IDE_CONFIG ,發(fā)現(xiàn)要讓我們配置一個(gè)叫 serverName 的參數(shù),
就是前面創(chuàng)建的 Server ,用來(lái)映射本地文件。

image.png

因?yàn)槲覀冋{(diào)試的是容器內(nèi)的 cli ,所以我們切入到容器的終端,輸入以下內(nèi)容

export PHP_IDE_CONFIG=serverName=XDEBUG_02

然后在執(zhí)行 php watch 。
現(xiàn)在你就會(huì)看,我們?cè)?watch 的時(shí)候,斷點(diǎn)就開(kāi)始工作了。

image

現(xiàn)在你進(jìn)行調(diào)試的話(huà),你會(huì)發(fā)現(xiàn)下面的調(diào)試欄,有時(shí)候會(huì)有好幾個(gè) hyperf.php 來(lái)回切,很是干擾,
這是因?yàn)轫?xiàng)目默認(rèn)配置了使用多個(gè) worker ,你可以在這里把他改成 1。

image

業(yè)務(wù)調(diào)試

現(xiàn)在試試開(kāi)始調(diào)試業(yè)務(wù)代碼吧!
進(jìn)入默認(rèn)的控制器,下個(gè)斷點(diǎn)。

image

打開(kāi)瀏覽器刷新,你會(huì)發(fā)現(xiàn),并沒(méi)有發(fā)生變化,貌似沒(méi)有捕獲到斷點(diǎn)。

image

這時(shí)候只需要在URl加上參數(shù) XDEBUG_SESSION_START=PHPSTORM ,
URL 變成了 http://localhost:8080/?XDEBUG_SESSION_START=233
好了現(xiàn)在我們可以看到 PHPStorm 中成功加載到了斷點(diǎn)了。

image.png

如果你覺(jué)得這樣麻煩,可以安裝一個(gè) Chrome 擴(kuò)展 Xdebuge Helper
安裝以后在插件欄右鍵選擇 選項(xiàng) ,在 IDE Key 中選擇 PHPSTORM 然后 save,回到頁(yè)面,
左鍵點(diǎn)擊插件欄的蟲(chóng)子,選擇 Debug ,現(xiàn)在刷新頁(yè)面,PHPStorm 就能自動(dòng)捕獲到 Debug 了。

image

在 POSTMAN 中調(diào)試

一般的 GET 請(qǐng)求我們可以在瀏覽器直接調(diào)試,但是有時(shí)候需要發(fā)送 header 或者 post 的時(shí)候,
就會(huì)選擇 POSTMAN 這種工具進(jìn)行請(qǐng)求,這時(shí)候我們只需要在請(qǐng)求參數(shù)中加上 XDEBUG_SESSION_START=PHPSTORM 這個(gè)參數(shù)就行了
也可以 在 Cookie 中添加 XDEBUG_SESSION=PHPSTORM 也可以觸發(fā)調(diào)試。

完結(jié)。

整篇下來(lái),比之前那一篇文章還要復(fù)雜,但是我已經(jīng)盡量去用較少的內(nèi)容講清楚更多的東西,開(kāi)發(fā)時(shí)我們總是離不開(kāi)調(diào)試。

如果你有別的想法或者好的建議可以直接與我聯(lián)系,如您發(fā)現(xiàn)文章內(nèi)容有錯(cuò)誤歡迎指出。

如果你對(duì)遠(yuǎn)程調(diào)試還感興趣,可以看看我的另一篇文章,用來(lái)介紹 XDEBUG 遠(yuǎn)程調(diào)試。
Xdebug 遠(yuǎn)程調(diào)試,你會(huì)用嗎?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容