PHP简介
安装
PHP及主要模块安装
- windows安装php:http://php.net/downloads.php
- 可下载
xampp
或lnmp
集成包(包含apache/mysql/php等服务)
- 可下载
- mac安装参考mac.md#php
- linux下安装分为(可同时安装php和php-fpm等模块)
- yum-config-manager
- dnf
- yum install -y php74-* (remi镜像)
- yum install php71w-* (webtatic镜像)
- yum-config-manager镜像方式
1 | # 参考 https://www.cnblogs.com/laterzh2022/p/16272581.html |
- dfn镜像方式
1 | # 对于 CentOS 8.4 |
- (弃用)
yum install php74-*
1 | # CentOS 8.4 |
- (弃用)
yum install php71w-*
1 | # 需要安装epel-release |
composer包管理工具安装
- Windows安装: https://getcomposer.org/download/
- Linux安装
1 | ## mac下安装(此处php为本地php命令,会安装到当前php版本对应目录;如果是x86模式的php版本,可指定php全路径) |
- 使用
1 | # 在项目 composer.json 所在目录运行,进行依赖包安装;一般依赖包会安装到项目根目录的vendor目录 |
php模块安装
php -m
查看安装的扩展- PEAR和PECL
- PEAR 是“PHP Extension and Application Repository”的缩写,即PHP扩展和应用仓库
- PECL 是“PHP Extension Community Library”的缩写,即PHP 扩展库
- PECL 可以看作PEAR 的一个组成部分,不同的是PEAR的所有扩展都是用纯粹的PHP代码编写的,而PECL是使用C 语言开发的,通常用于补充一些用PHP难以完成的底层功能
- PECL包下载
- windows可下载DLL文件直接安装
- linux等平台需要下载tgz自行编译安装
php-zip模块
- mac php73 安装 php-zip 失败; mac x86 php80 也安装失败
1 | # 如下载到 /opt/php-lib 目录 |
php-redis模块
1 | ## 基于windows 访问包地址下载DLL |
PHP环境组合
- 一般包含LAMP(Linux Apache Mysql PHP)和LNMP(Linux Nginx Mysql PHP)
- 相关文件
.htaccess
是lamp文件,是伪静态环境配置文件.user.ini
是lnmp文件,里面放的是网站的文件夹路径地址,目的是防止跨目录访问和文件跨目录读取。一般内容为open_basedir=/项目路径/:/tmp/:/proc/
项目调试
安装php Xdebug模块并设置
php.exe -m
查看是否安装Xdebug([Zend Modules]
中含有Xdebug
)- 无对应配置则需进行安装
安装成功后,修改
php.ini
,启用模块1
2
3[xdebug]
zend_extension=D:\software\xampp\php\ext\php_xdebug.dll
xdebug.remote_enable=1
还需安装Chrome插件
Xdebug Helper for Chrome
用于调试- 激活Xdebug的调试器:安装好后,在打开网页时,点击插件中的Debug按钮启动
- 启动项目参考PhpStorm进行开发
配合nginx使用
- nginx配置
1 | server { |
- linux + nginx + fastcgi运行php程序
- nginx配置同上
- nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端。nginx一般是把请求发fastcgi管理进程处理,fascgi管理进程选择cgi子进程处理结果并返回被nginx。而使用php-fpm则可以使nginx支持PHP
- 需要安装
php-fpm
来实现fastcgi,按照参考上文 systemctl start php-fpm
默认监听9000
端口- 编辑
/etc/php-fpm.d/www.conf
中的listen = 127.0.0.1:9000
可修改监听端口;也可将此listen改为listen = unix:/var/run/php-fpm/php-fpm.sock
,从而nginx配置改为fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
来进行转发
- 编辑
windows + nginx + fastcgi运行php程序(php5.3版本之后已经有了
php-cgi.exe
的可执行程序,经测试本地开发就很容易挂)快捷操作脚本(需提前启动,监听在19000端口上)
1
2
3
4
5
6
7
8
9:: 启动脚本 start_php_cgi.bat(直接执行php-cgi.exe默认监听端口是9000)。此处使用`RunHiddenConsole.exe`需要加入到PATH,下载地址`http://redmine.lighttpd.net/attachments/download/660/RunHiddenConsole.zip`
@echo off
echo Starting PHP FastCGI...
RunHiddenConsole.exe d:\software\xampp\php\php-cgi.exe -b 127.0.0.1:19000 -c d:\software\xampp\php\php.ini
:: 停止脚本 stop_php_cgi.bat
@echo off
echo Stopping nginx...
taskkill /F /IM nginx.exe > nul
常见问题
- nginx 502,日志显示Permission denied,权限问题
- 参考下文
File not found.
- 如果项目目录为
/project/test/public
则需要/project
/project/test
//project/test/public
均有执行权限(目录一般有执行权限,但是如果把文件放在/root目录则不行,root目录默认无执行权限,因此建议放到如/wwwroot/www等目录)。参考: https://serverfault.com/questions/170192/nginx-php-fpm-permission-denied-error-13-in-nginx-log-configuration-mista - 此时访问php文件仍然有问题,必须设置php-fpm的sock文件所属
chown www:www www.sock
- 但是每次重启php-fmp又需要重新设置
- 参考下文
- 浏览器访问返回
File not found.
此为php-fpm返回的错误,一般为nginx,php-fpm用户读取文件权限问题,具体如下- nginx.conf中一般设置
user www www;
(此时www用户必须要有权限读取到对应项目目录,项目父目录无所谓) - /etc/php-fpm.d/www.conf中一般设置`user = www
和
group = www`(此处www用户同nginx需要有权限访问到对应项目目录,一般设置成和nginx一样的用户);默认为apache(且不能设置为root)
- nginx.conf中一般设置
- 浏览器返回
Access denied.
此为php-fpm返回的错误- 首先需要确保上述权限设置正确
- 然后检查项目目录下
.user.ini
,里面放的是网站的文件夹路径地址,目的是防止跨目录访问和文件跨目录读取。一般配置为open_basedir=/项目路径/:/tmp/:/proc/
有时候迁移项目时路径变化了则需要修改此项目路径
- nginx报错
"/var/lib/nginx/tmp/fastcgi/xxx failed" (13: Permission denied)
- 执行
chown -R www /var/lib/nginx
(一般和nginx启动用户一致)
- 执行
- php报错
open(/var/lib/php/session/sess_...) failed: Permission denied (13)
- 一般php项目需要写文件的目录及其子目录设置成1733即可(如日志目录)
- 执行
sudo chmod 1733 /var/lib/php/session
参考: https://blog.csdn.net/wm9028/article/details/86571527
- nginx 502,日志显示Permission denied,权限问题
PHP基本语法
未特殊说明,都是基于 php7
基本及关键字
1 | # 是调用类中的静态方法或者常量,属性的符号 |
interface/abstract/trait
trait ^2
- use关键字在一个类中引入Trait类(类似抽象类,但是可以被多继承)后,相当于require或include了一段代码进来,不同之处在于use的Trait类与当前类是可以看做同一个类的,即当前类可以用$this关键字调用Trait类的方法。(此处的”当前类”指引入trait类的类)
- 当前类可以
use
多个trait类,trait类允许有实现代码,但是本身不能实例化 - 同名方法调用优先级:当前使用类 > Trait类 > 继承的基类
- trait类定义一个属性后,当前类就不能定义同样名称的属性,否则会产生 fatal error。可通过在trait类中定义属性和属性的get方法,并在当前类中进行覆盖
- 继承的方式,如果基类是private修饰控制的,则子类是无法调用的。但是Trait不一样,因为它类似于Require到当前类中了,所以不管是public、protected或private都是可以直接使用的
多个Trait类的冲突控制
1
2
3
4
5
6
7
8
9
10
11// 法一:insteadof关键字
use A, B {
B::a insteadof A; // a方法冲突时使用B类的a方法而不使用A类的a方法
A::b insteadof B; // b方法冲突时使用A类的b方法而不使用B类的b方法
}
// 法二:as关键字
use A, B {
B::a as c; // 声明B类的a方法为c,作用于该类
A::b as d; // 声明A类的b方法为d,作用于该类
}
示例
1 | // 抽象类(需要`extends`) |
反射相关
1 | $ref = new \ReflectionClass($classname); |
全局变量
$_GET
包含GET参数,下同。如$_GET['name']
获取name参数值$_POST
包含POST参数$_REQUEST
包含GET/POST参数,相对较慢$_SESSION
$_SERVER
- 包含Header参数。注意:header的key会自动转为大写,且key只能包含字母、数字、中划线(-)。且中划线(-)被自动转为下划线(_)。设置一个header的key为
user-name
,通过$_SERVER['HTTP_USER_NAME']
来获取 $_SERVER['REQUEST_URI']
获取请求路径
- 包含Header参数。注意:header的key会自动转为大写,且key只能包含字母、数字、中划线(-)。且中划线(-)被自动转为下划线(_)。设置一个header的key为
数据类型
字符串
1 | // 分割字符串 |
array/map
- 在php中map类型可以认为是array类型互通
1 | ## 创建/编辑/删除 array/map |
json
1 | // 数组转json字符串 => 默认将索引数组转成js数组,将关联数组转成js对象 |
数据类型转换
1 | // 拷贝对象 |
空值判断
1 | // 判断stdClass是否有某个属性,具体参考数组 |
流程控制
- for循环
- 支持break 和 continue,包括 while、do while、for 和 foreach 循环
1 | for ($i=0; $i < 10; $i++) { |
面向对象
1 | // 判断对象类型 |
文件
1 | // 移动文件 |
php.ini配置
- 查看php配置
1 | <!-- index.php --> |
- 配置
1 | [PHP] |
框架
易错点
$_POST
接受数据 ^1- Coentent-Type仅在取值为
application/x-www-data-urlencoded
和multipart/form-data
两种情况下,PHP才会将http请求数据包中相应的数据填入全局变量$_POST
。(jquery会默认转换请求头) - Coentent-Type为
application/json
时,可以使用$input = file_get_contents('php://input')
接受数据,再通过json_decode($input, TRUE)
转换成json对象 - 微信小程序wx.request的header设置成
application/x-www-data-urlencoded
时$_POST
也接受失败(基础库版本1.5.0,仅供个人参考),使用file_get_contents(‘php://input’)可以获取成功
- Coentent-Type仅在取值为
案例
POST接口
1 | function requestPost($url = '', $post_data = array()) { |
微信公众号开发
1 |
|
PhpStorm进行开发
- PhpStorm配置。参考http://blog.aezo.cn/2016/09/17/extend/idea/
- 参考项目调试
- PHP Build-in Web Server 进行调试(无需外部apahce,无需启动xampp)
- 保证xdebug和chrome插件配置成功
- 项目配置 - 新建PHP Build-in Web Server
- Host填内网地址/localhost,端口随便填,如果需要通过花生壳映射则端口建议443(否则部分重定向会带上原始端口)
- Document Root填项目web目录(如Thinkphp的public,Wordpress的项目根目录,其实就是nginx的root目录)
- 配置好后直接启动即可
- PHP Web Page 进行调试(需配合外部apahce,如xampp)
- 使用前需配置php可执行程序路径(Languages - PHP). 如果使用xampp,则可使用xampp中配置的xdebug
- 进行debug时,创建一个
PHP Web Page
启动配置,此时host和port需要填Apache服务器的host和port(PhpStorm中的启动配置并不会启动服务器,因此需要另外启动Apache等服务器)- Run Debug - PHP Web Page - 新建Server(localhost:8110, Xdebug) - Start Url(/test/index.php) - 启动Debug - 访问 http://localhost:8110/test/index.php
- PHPStorm使用Xdebug进行调试时,没打断点也一直进入到代码第一行:去掉勾选Run - Break at first line in PHP Scripts
- PHPStorm需要启动Debug监听:
Run - Start Listening for PHP Debug Connection
xampp
- 支持Windows、Linux、Mac,类似软件如
WampServer
、lamp
、lnmp
- xampp是将 Apache + MariaDB + PHP + Perl、tomcat、FileZila等软件打包打一起
- 安装xampp
- 修改 xampp Apache 端口(此时访问
http://localhost:8110/
访问的是目录D:\software\xampp\htdocs
)- 修改apache配置的
httpd.conf
文件中80
端口为8110
- 修改apache配置的
extra/httpd-ssl.conf
文件中443
为8443
- 配置端口(Config - Services and Port Settings)为
8110
- 修改apache配置的
设置xampp Apache虚拟机(此时访问
http://localhost:8111/
访问的是目录D:\phpwork
,且同时可访问8110)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18## httpd.conf
Listen 8110
Listen 0.0.0.0:8111 # 增加虚拟机监听端口
<Directory />
#AllowOverride none
#Require all denied # 拒绝所有请求
AllowOverride all # 所有都重定向
Allow from all
</Directory>
## extra/httpd-vhosts.conf 增加虚拟机
<VirtualHost *:8111>
ServerName localhost
DocumentRoot D:/phpwork
</VirtualHost>
## 重启apache
lnmp
- 类似xampp,专注于linux环境
- https://lnmp.org/
其他
php测试
- 使用
apache
自带的bin/ab.exe
工具ab.exe-n 10000 -c 100 http://localhost/index.php
表示100个人访问该地址10000次- 如果并发调到500,则会提示
apr_socket_connect()
原因是因为apache在windows下默认的最大并发访问量为150。我们可以设置conf\extra下的httpd-mpm.conf文件来修改它的最大并发数
- 如果并发调到500,则会提示
参考文章