
PHP 开发指引
安装
Rocky 9
# NOT RECOMMAND
dnf module switch-to php:remi-7.4
dnf module switch-to php:remi-8.2
dnf remove php-xml php-mbstring php-fpm php-common php-cli php-json
# Recommand to use alternatives for PHP version managing
alternatives --install /usr/bin/php php /usr/bin/php74 1
alternatives --install /usr/bin/php php /usr/bin/php82 2
## Selete effective PHP interpreter.
alternatives --config php
Enterprise Linux
# EL 7Remi's RPM repository
sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
sudo yum -y --enablerepo=epel,remi,remi-php7 install php-fpm php-cli php-gd php-mbstring php-mcrypt php-mysqlnd php-opcache php-pdo php-devel
# EL9
sudo yum install http://rpms.remirepo.net/enterprise/remi-release-9.rpm
sudo dnf install -y php74-php-fpm php74 php74-php-opcache php74-php-pecl-redis5 php74-php-mysqlnd php74-php-devel php74-php-mbstring php74-php-soap php74-php-pecl-zip php74-php-xml php74-php-pecl-mcrypt php74-php-pecl-yaml php74-php-pecl-apcu php74-php-pear php74-php-pgsql php74-php-gd
sudo alternatives --install /usr/bin/php php /usr/bin/php74 1
# wp 命令行
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
# PHP 7.0.x from IUS
sudo yum install mod_php70u php70u-mysqlnd php70u-pecl-redis php70u-xml php70u-gd php70u-devel php70u-mbstring php70u-opcache php70u-pdo php70u-pear php70u-soap
macOS
Brew 可以安装多个版本的 PHP 环境。
Brew 安装后的指示:
To enable PHP in Apache add the following to httpd.conf and restart Apache:
LoadModule php7_module /usr/local/opt/php@7.4/lib/httpd/modules/libphp7.so
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
Finally, check DirectoryIndex includes index.php
DirectoryIndex index.php index.html
The php.ini and php-fpm.ini file can be found in:
/usr/local/etc/php/7.4/
php@7.4 is keg-only, which means it was not symlinked into /usr/local,
because this is an alternate version of another formula.
If you need to have php@7.4 first in your PATH, run:
echo 'export PATH="/usr/local/opt/php@7.4/bin:$PATH"' >> ~/.zshrc
echo 'export PATH="/usr/local/opt/php@7.4/sbin:$PATH"' >> ~/.zshrc
For compilers to find php@7.4 you may need to set:
export LDFLAGS="-L/usr/local/opt/php@7.4/lib"
export CPPFLAGS="-I/usr/local/opt/php@7.4/include"
To restart php@7.4 after an upgrade:
brew services restart php@7.4
Or, if you don't want/need a background service you can just run:
/usr/local/opt/php@7.4/sbin/php-fpm --nodaemonize
Ubuntu
凭借第三方安装源 Ubuntu 可实现多版本 PHP 共存。
export LC_ALL=C.UTF-8
sudo add-apt-repository ppa:ondrej/php
sudo add-apt-repository ppa:ondrej/nginx # Stable
sudo add-apt-repository ppa:ondrej/nginx-mainline # New Features
sudo add-apt-repository ppa:ondrej/apache2
# https://launchpad.proxy.ustclug.org 国内代理
# PHP 7.0
sudo apt install php7.0 php7.0-mbstring php7.0-mysql php7.0-opcache php7.0-json php7.0-xmlrpc php7.0-readline php7.0-zip php7.0-gd php7.0-bcmath php7.0-gd php7.0-fpm php7.0-curl php7.0-cli php7.0-xml php7.0-mcrypt
# PHP 7.1
sudo apt install php7.1 php7.1-mbstring php7.1-mysql php7.1-opcache php7.1-json php7.1-xmlrpc php7.1-zip php7.1-bcmath php7.1-gd php7.1-fpm php7.1-curl php7.1-cli php7.1-xml php7.1-mcrypt php-redis
# PHP 7.2
sudo apt install php7.2 php7.2-mbstring php7.2-mysql php7.2-opcache php7.2-json php7.2-xmlrpc php7.2-zip php7.2-bcmath php7.2-gd php7.2-fpm php7.2-curl php7.2-cli php7.2-xml php-tokenizer php-redis
# PHP 7.3
sudo apt install php7.3 php7.3-mbstring php7.3-mysql php7.3-opcache php7.3-json php7.3-xmlrpc php7.3-zip php7.3-bcmath php7.3-gd php7.3-fpm php7.3-curl php7.3-cli php7.3-xml php-tokenizer php-redis
# PHP 7.4
sudo apt install php7.4 php7.4-mbstring php7.4-mysql php7.4-opcache php7.4-json php7.4-xmlrpc php7.4-zip php7.4-bcmath php7.4-gd php7.4-fpm php7.4-curl php7.4-cli php7.4-xml php-tokenizer php-redis
# 切换默认 PHP 版本
update-alternatives --config php
# Apache2 + PHP 默认版本 @ Ubuntu 16.04
sudo apt install libapache2-mod-php php7.0 php7.0-mbstring php7.0-mysql php7.0-xmlrpc php7.0-readline php7.0-zip php7.0-gd php7.0-bcmath php7.0-gd php7.0-curl php7.0-cli php7.0-xml php7.0-mcrypt php7.0-fpm php-redis
# Nginx 完整版
sudo apt install nginx-extras
MAMP
安装 pecl 扩展
MAMP 支持多个版本的 PHP 引擎,安装扩展时需要先用 export 调整 PATH 来调整默认的 PHP 版本:
export PATH=/Applications/MAMP/bin/php/php7.0.26/bin:$PATH
pecl install redis
装完扩展后在 MAMP 中编辑对应的 PHP 配置模版激活扩展:
extension=redis.so
常用命令
常用设置
路径缓存
缓存 PHP 文件的真实路径:
realpath_cache_size = 256k
OPcache
; 是否侦测文件改动:生产环境设为 0,开发环境设为 1
opcache.validate_timestamps = 0
; 每隔多少秒检查文件是否跟新,0 表示每次请求都检查文件是否改动
opcache.revalidate_freq = 0
; PHP 7.0+ 最高支持 100000 10 万
opcache.max_accelerated_files = 100000
opcache.memory_consumption = 64
opcache.interned_strings_buffer = 16
opcache.fast_shutdown = 1
常见错误
未找到 autocconf
$ pecl install redis
WARNING: channel "pecl.php.net" has updated its protocols, use "pecl channel-update pecl.php.net" to update
downloading redis-4.2.0.tgz ...
Starting to download redis-4.2.0.tgz (235,569 bytes)
.................................................done: 235,569 bytes
25 source files, building
running: phpize
Configuring for:
PHP Api Version: 20151012
Zend Module Api No: 20151012
Zend Extension Api No: 320151012
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.
解决方案
brew install autoconf
PHP 应用服务器
mod_php
使用 Apache 服务器,为每个请求生成嵌入 mod_php 解释器的子进程。
php-fpm
使用 nginx 服务器,转发 PHP 请求给一系列 php-fpm 进程。
php-fpm.conf
# 一分钟内出现 10 个僵尸子进程则重启主进程
emergency_restart_threshold = 10
emergency_restart_interval = 1m
# 超长相应日志路径
slowlog = LOG_PATH
request_slowlog_timeout = 10s
# Drupal@8G 内存
pm.max_children = 51
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
调试
php-fpm 运行后可以用 cgi-fcgi 进行调试:
# 可用 CGI 环境变量
# DOCUMENT_ROOT The root directory of your server
# HTTP_COOKIE The visitor's cookie, if one is set
# HTTP_HOST The hostname of the page being attempted
# HTTP_REFERER The URL of the page that called your program
# HTTP_USER_AGENT The browser type of the visitor
# HTTPS "on" if the program is being called through a secure server
# PATH The system path your server is running under
# QUERY_STRING The query string (see GET, below)
# REMOTE_ADDR The IP address of the visitor
# REMOTE_HOST The hostname of the visitor (if your server has reverse-name-lookups on; otherwise this is the IP address again)
# REMOTE_PORT The port the visitor is connected to on the web server
# REMOTE_USER The visitor's username (for .htaccess-protected pages)
# REQUEST_METHOD GET or POST
# REQUEST_URI The interpreted pathname of the requested document or CGI (relative to the document root)
# SCRIPT_FILENAME The full pathname of the current CGI
# SCRIPT_NAME The interpreted pathname of the current CGI (relative to the document root)
# SERVER_ADMIN The email address for your server's webmaster
# SERVER_NAME Your server's fully qualified domain name (e.g. www.cgi101.com)
# SERVER_PORT The port number your server is listening on
# SERVER_SOFTWARE The server software you're using (e.g. Apache 1.3)
SCRIPT_NAME=/ \
HTTP_HOST=www.moha.online \
SCRIPT_FILENAME=WEB_ROOT/index.php \
REQUEST_METHOD=GET \
cgi-fcgi -bind -connect /run/php/php7.0-fpm.sock
发布
Capistrano
安装及配置
# 在本地环境安装
gem install capistrano
# 项目目录下执行
cap install
常用命令
# 发布
cap production deploy
# 回滚
cap production deploy:rollback
测试
行为驱动开发(BDD)
PHPUnit
一个测试用例对应一个从 PHPUnit_Framework_TestCase 扩展的类;类中每个以 test 为前缀的方法为一个测试。测试中使用断言诊断是否通过测试,有些断言没有文档,需查源码。
# 安装 PHPUnit 到 vender/bin/phpunit
composer require --dev phpunit/phpunit
PHPUnit 用 phpunit.xml 预定义命令行参数:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap.php">
<testsuites>
<!-- 多个测试用例构成一个测试组件 -->
<testsuite name="whovian">
<directory suffix="Test.php">tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist>
<directory>src</directory>
</whitelist>
</filter>
</phpunit>
bootstrap.php 用来加载 composer 组件:
<?php
// Enable Composer autoloader
require dirname(__DIR__) . '/vendor/autoload.php';
项目根目录准备 .travis.yml 整合 Travis CI 自动测试服务:
# 要小写
language: php
php:
- 5.4
- 5.5
- 5.6
- hhvm
install:
- composer install --no-dev --quiet
script: phpunit -c phpunit.xml --coverage-text
性能分析
基准测试工具 Apache Bench 和 Siege 可被用来分析应用性能。Xdebug 可以在开发环境中做性能分析,分析结果需要用 KCacheGrind 或 WinCacheGrind 来查看。XHProf 可以用在开发或生产环境,收集的信息较少,结果用 XHGUI 来查看。
Xdebug
Xdebug 报告为格式为 CacheGrind,mac 中可通过 brew install qcachegrind
安装查看器。
; php.ini 中 Xdebug 的配置
; 避免 Xdebug 生成大量报告
xdebug.profiler_enable = 0
; 用 XDEBUG_PROFILE=1 URL 参数激活
xdebug.profiler_enable_trigger = 1
xdebug.profiler_output_dir = PATH_OF_REPORT
安装
pecl install xdebug-3.1.6 # PHP 7.4
3.x 配置
[xdebug]
xdebug.mode = debug
xdebug.client_host = 127.0.0.1
xdebug.client_port = 9003
xdebug.discover_client_host = true
xdebug.start_with_request = yes
XHProf
XHProf 通过 XHGui 应用管理和配置。
安装
# Ubuntu
sudo apt-get install build-essential;
# CentOS
sudo yum groupinstall 'Development Tools';
sudo pecl install mongo;
sudo pecl install xhprof;
配置
; php.ini 配置相关扩展
extension=xhprof.so
extension=mongo.so
# config/config.default.php 配置 XHProf 触发概率
# 开发环境每次触发
'profiler.enable' => function() {
return true; // <-- Run on every request
},”
# 生产环境 1% 概率触发
'profiler.enable' => function() {
return rand(0, 100) === 42;
},”
触发
PHP 应用引入 XHGui 触发 XHProf:
; php.ini 中引入
auto_prepend_file = /var/sites/xhgui/external/header.php
; nginx 配置中引入
fastcgi_param PHP_VALUE "auto_prepend_file=/var/sites/xhgui/external/header.php";
; Apache 配置中引入
php_admin_value auto_prepend_file "/var/sites/xhgui/external/header.php