PHP 本地開發終極解決方案

1. requirements

  1. git
  2. docker app
  3. docker-compose
  4. docker login
  5. 可能須要科-學-上-網
  6. root 帳號權限

2. 基礎

基於 https://github.com/yeszao/dnmp,參考 https://github.com/guanguans/dnmp-plusphp

2.1 DNMP

DNMP(Docker + Nginx + MySQL + PHP7/5 + Redis)是一款全功能的 LNMP 一鍵安裝程序html

DNMP 項目特色:mysql

  1. 100% 開源
  2. 100% 遵循 Docker 標準
  3. 支持 多版本 PHP 共存,可任意切換(PHP5.四、PHP5.六、PHP7.一、PHP7.二、PHP7.3)
  4. 支持綁定 任意多個域名
  5. 支持 HTTPS 和 HTTP/2
  6. PHP 源代碼、MySQL 數據、配置文件、日誌文件均可在 Host 中直接修改查看
  7. 內置 完整 PHP 擴展安裝命令
  8. 默認支持 pdo_mysqlmysqlimbstringgdcurlopcache 等經常使用熱門擴展,根據環境靈活配置
  9. 可一鍵選配經常使用服務:
    • 多 PHP 版本:PHP5.四、PHP5.六、PHP7.1-7.3
    • Web 服務:Nginx、Openresty
    • 數據庫:MySQL五、MySQL八、Redis、memcached、MongoDB、ElasticSearch
    • 消息隊列:RabbitMQ
    • 輔助工具:Kibana、Logstash、phpMyAdmin、phpRedisAdmin、AdminMongo
  10. 實際項目中應用,確保 100% 可用
  11. 全部鏡像源於 Docker 官方倉庫,安全可靠
  12. 一次配置, Windows、Linux、MacOs 皆可用
  13. 支持快速安裝擴展命令 install-php-extensions apcu

2.2 dnmp-plus

plus = xhgui + xhprof + tidewaysnginx

dnmp-plus = PHPer 的一鍵安裝開發環境 + PHP 非侵入式監控平臺(優化系統性能、定位 Bug 的神器)laravel

dnmp-plusyeszaoDNMP 基礎上新增:git

  • PHP xhprof 擴展 - Facebook 開發的 PHP 性能追蹤及分析工具
  • PHP tideways 擴展 - xhprof 的分支,支持 PHP7
  • PHP mongodb 擴展
  • MongoDB 服務
  • Mongo Express - MongoDB 服務管理系統
  • xhgui - xhprof 分析數據數據的 GUI 系統

3. 步驟

3.1. clone project

git clone https://gitee.com/zouzhipeng/my-dnmp.git dnmp
複製代碼

3.2. install

cd dnmp && docker-compose up -d
複製代碼

視網絡狀況,可能須要等待十幾分鍾。若是沒法下載,考慮使用代理。github

3.3. Go to your browser and type http://localhost, you will see:

image-20200618221524024
image-20200618221524024

PHP7.4 已能夠知足大部分需求,PHP5.x 相關已刪除。web

3.4 安裝 PHP 擴展

PHP 的不少功能都是經過擴展實現,而安裝擴展是一個略費時間的過程, 因此,除 PHP 內置擴展外,在 env.sample 文件中咱們僅默認安裝少許擴展, 若是要安裝更多擴展,請打開你的.env 文件修改以下的 PHP 配置, 增長鬚要的 PHP 擴展:redis

PHP_EXTENSIONS=pdo_mysql,opcache,redis       # PHP 要安裝的擴展列表,英文逗號隔開
複製代碼

須要先修改 docker-compose.yml 的 php 部分,註釋掉 image,並開啓 build,以下sql

php:
 # image: zzpwestlife/dnmp_php_xhgui:v1.0  build:  context: ./services/php  args:  PHP_VERSION: php:${PHP_VERSION}-fpm-alpine  CONTAINER_PACKAGE_URL: ${CONTAINER_PACKAGE_URL}  PHP_EXTENSIONS: ${PHP_EXTENSIONS}  TZ: "$TZ" 複製代碼

而後從新 build PHP 鏡像。

docker-compose build php
複製代碼

可用的擴展請看同文件的 env.sample 註釋塊說明。

3.5 快速安裝 php 擴展

  1. 進入容器:
docker exec -it php /bin/sh
install-php-extensions extension-name 複製代碼

很是方便。可用擴展列表見 https://github.com/mlocati/docker-php-extension-installer

4. 使用

4.1. Host 中使用 php 命令行 (php-cli)

如在 mac 中,就不須要再單獨安裝 php,直接使用 docker 中的 php 便可。

  1. 參考 bash.alias.sample 示例文件,將對應 php cli 函數拷貝到主機的 ~/.bashrc 文件。 (或者 ~/.zshrc,視具體狀況而定)

    # php7 cli
    php () {  tty=  tty -s && tty=--tty  docker run \  $tty \  --interactive \  --rm \  --volume $PWD:/www:rw \  --workdir /www \  zzpwestlife/dnmp_php_xhgui:v1.0 php "$@" } 複製代碼

    若是從新 build 過鏡像,zzpwestlife/dnmp_php_xhgui:v1.0 須要改成 dnmp-php

  2. 讓文件起效:

    source ~/.bashrc
    # source ~/.zshrc 複製代碼
  3. 而後就能夠在主機中執行 php 命令了:

    ~ php -v
    PHP 7.4.1 (cli) (built: Jan 18 2020 03:27:33) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies  with Zend OPcache v7.4.1, Copyright (c), by Zend Technologies  with Xdebug v2.9.2, Copyright (c) 2002-2020, by Derick Rethans 複製代碼

4.2. 使用 composer

方法 1:主機中使用 composer 命令

  1. 肯定 composer 緩存的路徑。好比,個人 dnmp 下載在 /Users/zouzhipeng/www/work/dnmp 目錄,那 composer 的緩存路徑就是 /Users/zouzhipeng/www/work/dnmp/data/composer

  2. 參考 bash.alias.sample 示例文件,將對應 php composer 函數拷貝到主機的 ~/.bashrc (~/.zshrc)

    # php7 composer
    composer () {  tty=  tty -s && tty=--tty  docker run \  $tty \  --interactive \  --rm \  --user www-data:www-data \  --volume ~//Users/zouzhipeng/www/work/dnmp/data/composer:/tmp/composer \  --volume $(pwd):/app \  --workdir /app \  zzpwestlife/dnmp_php_xhgui:v1.0 composer "$@" } 複製代碼

    一樣,若是從新 build 過鏡像,zzpwestlife/dnmp_php_xhgui:v1.0 須要改成 dnmp-php

  3. 讓文件生效:

    source ~/.bashrc
    複製代碼
  4. 在主機的任何目錄下就能用 composer 了:

    cd ~/dnmp/www/
    ~ composer -V Composer version 1.10.7 2020-06-03 10:03:56 複製代碼

方法二:容器內使用 composer 命令

還有另一種方式,就是進入容器,再執行 composer 命令,以 PHP7 容器爲例:

docker exec -it php /bin/sh
cd /www/localhost composer -V 複製代碼

5. 使用 Log

Log 文件生成的位置依賴於 conf 下各 log 配置的值。

5.1 nginx 日誌

Nginx 日誌是咱們用得最多的日誌,因此咱們單獨放在根目錄 log 下。

log 會目錄映射 nginx 容器的 /var/log/nginx 目錄,因此在 Nginx 配置文件中,須要輸出 log 的位置,咱們須要配置到 /var/log/nginx 目錄,如:

error_log  /var/log/nginx/nginx.localhost.error.log  warn;
複製代碼

5.2 PHP-FPM 日誌

大部分狀況下,PHP-FPM 的日誌都會輸出到 nginx 的日誌中,因此不須要額外配置。

另外,建議直接在 PHP 中打開錯誤日誌:

error_reporting(E_ALL);
ini_set('error_reporting', 'on'); ini_set('display_errors', 'on'); 複製代碼

若是確實須要,可按一下步驟開啓(在容器中)。

  1. 進入容器,建立日誌文件並修改權限:

    $ docker exec -it php /bin/sh
    $ mkdir /var/log/php $ cd /var/log/php $ touch php-fpm.error.log $ chmod a+w php-fpm.error.log 複製代碼
  2. 主機上打開並修改 PHP-FPM 的配置文件

    conf/php-fpm.conf
    複製代碼

    ,找到以下一行,刪除註釋,並改值爲:

    php_admin_value[error_log] = /var/log/php/php-fpm.error.log
    複製代碼
  3. 重啓 PHP-FPM 容器。

5.3 MySQL 日誌

由於 MySQL 容器中的 MySQL 使用的是 mysql 用戶啓動,它沒法自行在 /var/log 下的增長日誌文件。因此,咱們把 MySQL 的日誌放在與 data 同樣的目錄,即項目的 mysql 目錄下,對應容器中的 /var/lib/mysql/ 目錄。

slow-query-log-file     = /var/lib/mysql/mysql.slow.log
log-error = /var/lib/mysql/mysql.error.log 複製代碼

以上是 mysql.conf 中的日誌文件的配置。

6. 數據庫管理

本項目默認在 docker-compose.yml 中開啓了用於 MySQL 在線管理的 phpMyAdmin,以及用於 redis 在線管理的 phpRedisAdmin,能夠根據須要修改或刪除。

6.1 phpMyAdmin

phpMyAdmin 容器映射到主機的端口地址是:8080,因此主機上訪問 phpMyAdmin 的地址是:

http://localhost:8080
複製代碼

MySQL 鏈接信息:

  • host:(本項目的 MySQL 容器網絡)
  • port: 3306
  • username:(手動在 phpmyadmin 界面輸入)
  • password:(手動在 phpmyadmin 界面輸入)
image-20200618223738403
image-20200618223738403
image-20200618223807184
image-20200618223807184

Mac 上建議使用 Sequel Pro 管理 MySQL。

6.2 phpRedisAdmin

phpRedisAdmin 容器映射到主機的端口地址是:8081,因此主機上訪問 phpMyAdmin 的地址是:

http://localhost:8081
複製代碼

Redis 鏈接信息以下:

  • host: (本項目的 Redis 容器網絡)
  • port: 6379
image-20200618223843852
image-20200618223843852

Mac 上可使用 AnotherRedisDesktopManager 管理 redis

image-20200618224945285
image-20200618224945285

7. 在正式環境中安全使用

要在正式環境中使用,請:

  1. 在 php.ini 中關閉 XDebug 調試
  2. 加強 MySQL 數據庫訪問的安全策略
  3. 加強 redis 訪問的安全策略

8 常見問題

8.1 如何在 PHP 代碼中使用 curl?

參考這個 issue:https://github.com/yeszao/dnmp/issues/91

8.2 Docker 使用 cron 定時任務

Docker 使用 cron 定時任務

8.3 Docker 容器時間

容器時間在.env 文件中配置 TZ 變量,全部支持的時區請看時區列表・維基百科或者 PHP 所支持的時區列表・PHP 官網

8.4 如何鏈接 MySQL 和 Redis 服務器

這要分兩種狀況,

第一種狀況,在 PHP 代碼中

// 鏈接MySQL
$dbh = new PDO('mysql:host=mysql;dbname=mysql', 'root', '123456');  // 鏈接Redis $redis = new Redis(); $redis->connect('redis', 6379); 複製代碼

由於容器與容器是 expose 端口聯通的,並且在同一個 networks 下,因此鏈接的 host 參數直接用容器名稱,port 參數就是容器內部的端口。更多請參考《docker-compose ports 和 expose 的區別》

第二種狀況,在主機中經過命令行或者 Navicat 等工具鏈接。主機要鏈接 mysql 和 redis 的話,要求容器必須通過 ports 把端口映射到主機了。以 mysql 爲例,docker-compose.yml 文件中有這樣的 ports 配置:3306:3306,就是主機的 3306 和容器的 3306 端口造成了映射,因此咱們能夠這樣鏈接:

$ mysql -h127.0.0.1 -uroot -p123456 -P3306
$ redis-cli -h127.0.0.1 複製代碼

這裏 host 參數不能用 localhost 是由於它默認是經過 sock 文件與 mysql 通訊,而容器與主機文件系統已經隔離,因此須要經過 TCP 方式鏈接,因此須要指定 IP。

8.5 容器內的 php 如何鏈接宿主機 MySQL

  1. 宿主機執行 ifconfig docker0 獲得 inet 就是要鏈接的 ip 地址 (沒法驗證)
$ ifconfig docker0
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500  inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255  ... 複製代碼
  1. 運行宿主機 Mysql 命令行
mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
 mysql>flush privileges; // 其中各字符的含義: // *.* 對任意數據庫任意表有效 // "root" "123456" 是數據庫用戶名和密碼 // '%' 容許訪問數據庫的IP地址,%意思是任意IP,也能夠指定IP // flush privileges 刷新權限信息 複製代碼
  1. 接着直接 php 容器使用 172.0.17.1:3306 鏈接便可

9. xhgui

9.1 安裝

cd www/xhgui-branch
composer install 複製代碼

修改 xhgui-branch 配置文件 www/xhgui-branch/config/config.default.php

<?php
return [  ...  'debug' => true, // 改成true,便於調試  'mode' => 'development',  ...  'extension' => 'tideways', // 改成支持 PHP7 的 tideways  ...  'save.handler' => 'mongodb',  'db.host' => 'mongodb://mongo:27017', // 127.0.0.1 改成 mongo  'db.options' => [ // .env 中配置的 mongodb 帳號密碼  'username' => 'root',  'password' => '123456',  ],  ... ]; 複製代碼

hosts 文件中增長

127.0.0.1             xhgui.test
複製代碼

瀏覽器訪問 xhgui.test

image-20200618225249811
image-20200618225249811

10. 如何添加項目

cd www
mkdir -p laravel/public vim laravel/public/index.php 複製代碼

services/nginx/conf.d 添加一個配置文件

server {
    listen       80;
    server_name  laravel.test;
    root   /www/laravel/public;
    index  index.php;

    location / {
    try_files $uri $uri/ /index.php$is_args$args;
    }
    
    access_log /dev/null;
    #access_log /var/log/nginx/nginx.laravel.access.log main;
    error_log  /var/log/nginx/nginx.laravel.error.log  warn;

    location ~ \.php$ {
        fastcgi_pass   php:9000;
        fastcgi_index  index.php;
        include        fastcgi_params;
        fastcgi_param  PATH_INFO $fastcgi_path_info;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        # Run our specified PHP script before executing the main program
        fastcgi_param  PHP_VALUE "auto_prepend_file=/www/xhgui-branch/external/header.php";
    }
}
複製代碼

重啓 nginx

$ docker-compose restart nginx
複製代碼

瀏覽器訪問 http://laravel.test,再訪問 xhgui.test,此時已經有了內容,愉快的查看項目的性能追蹤及分析吧

11. xdebug 斷點調試

使用 PHPstorm 打開項目。Preferences->Languages & Frameworks ->PHPCLI Interpreter ,點擊右側的三個點,點擊彈出的窗口中左上角加號,選擇第一個

Jietu20200618-230202
Jietu20200618-230202

下一步要選擇 docker,而不是 docker compose。 選擇所需的 php 容器。點擊 OK

image-20200618230354250
image-20200618230354250

回到上一步的窗口。這裏能夠顯示 php 及擴展相關信息。

Jietu20200618-230740
Jietu20200618-230740

保存。回到上一步對話窗口。

設置目錄映射。先設置 Docker container。

Jietu20200618-230945
Jietu20200618-230945

而後設置 path mapping,與 docker container 一致便可。保存。

打開 Run -> Edit configuration 對話窗口。如圖,按順序配置。

左上角,添加一個 PHP Web Page.

點擊 Server 後面的三個點。配置一個 server,並設置好 Host 和 Path mapping

Jietu20200618-231421
Jietu20200618-231421

保存,回到上一級會話窗口。

點擊 validate,能夠看到一排對勾。

Jietu20200618-231625
Jietu20200618-231625

配置完成,在代碼中打斷點,打開小電話,請求頁面或接口,就能夠開始調試了。

image-20200618231802311
image-20200618231802311
相關文章
相關標籤/搜索