php
文章目录
语言
版本
PHP5
- PHP5.0 : 使用了Zend 2 引擎,增加了新关键字,包括this,try,catch,public,private,protected等
- PHP5.1:PDO扩展默认启动、性能优化、修复了超过400个bug
- PHP5.2:新增Zip、Filter 、JSON 扩展
- PHP5.3:弃用的功能,匿名函数(又叫闭包函数,1,2),新增魔术方法,命名空间,后期静态绑定,Heredoc 和 Nowdoc, const, 三元运算符,Phar
- PHP5.4:闭包 支持 $this,Short Open Tag, 数组简写形式,Traits, 内置用于开发的 CLI 模式的 web server ,SESSION 扩展能追踪文件的上传进度
- PHP5.5:yield(生成器用法、协程),list() 用于 foreach,finally关键字,opcache扩展
- PHP5.6:支持大于 2GB 的文件上传,常量增强,可变函数参数,命名空间增强,pgsql 扩展现在支持 异步方式连接数据库及执行查询
PHP6
旨在为 PHP提供完全内置的unicode的支持,由于困难,最终取消。
PHP7
- PHP7.0 使用了Zend Engine 3.0性能升级,匿名类,标量类型声明,返回值类型声明,太空船操作符, 单个 use 语句 一次性可以导入多个类、函数和常量 生成器可以返回表达式 JSON 扩展已经被 JSOND 取代 listen 端口现在同时监听 IPv4 和 IPv6 地址 更多参考资料 PHP7新特性总结 从 PHP 5.6.x 移植到 PHP 7.0.x
- PHP7.1 可为空(Nullable)类型 、新增 void 类型、类常量可见性、iterable 伪类 多异常捕获处理 list支持键名 字符串支持负向 curl支持推送http2
- PHP7.2 新的对象类型object 、允许重写抽象方法(Abstract method)、允许分组命名空间的尾部逗号
- PHP7.3 更灵活的Heredoc和Nowdoc、 数组析构支持引用赋值 list结构支持引用解析。 instanceof 运算符支持字面量语法 LDAP 全支持 性能提升 废弃大小写不敏感的常量
- PHP7.4 预加载 、FFI、类属性的类型支持
PHP8
- PHP8.0 JIT 注解的功能 构造器属性提升功能(在构造函数中声明类的属性) 联合类型 Match 表达式 Nullsafe 运算符(?->)
PHP7比PHP5性能高原因(2倍提升)
- 变量存储字节减小,减少内存占用,提升变量操作速度
- 改善数组结构,数组元素和hash映射表被分配在同一块内存里,降低了内存占用,提升cpu缓存命中率
- 改进了函数调用机制,通过优化参数传递的环节,减少了一些指令,提高执行效率
类与对象
- 简介
- 基本概念
- 属性
- 类常量
- 类的自动加载
- 构造函数和析构函数
- 访问控制(可见性)
- 对象继承
- 范围解析操作符 (::)
- 静态(static)关键字
- 抽象类
- 对象接口
- Trait
- 匿名类
- 重载
- 遍历对象
- 魔术方法
- Final 关键字
- 对象复制
- 对象比较
- 后期静态绑定
- 对象和引用
- 对象序列化
- 协变与逆变
- OOP 变更日志
PHP标准库(SPL)
数据结构
迭代器
接口
异常
SPL函数
文件处理
各种类及接口
框架
Laravel
生命周期
第一步
入口点 public/index.php
,加载 composer
生成的自动加载器定义,然后从 bootstrap/app.php
中检索 Laravel
应用程序实例。
HTTP / Console 内核
接下来,根据进入应用的请求类型,传入的请求将被发送到 HTTP
内核或者 Console
内核。
引导程序用来配置异常处理、配置日志、检测应用程序环境,并执行在实际处理请求之前需要完成的其他任务。
HTTP 内核还定义了一个 HTTP 中间件 列表,所有请求在被应用程序处理之前都必须通过该列表。
HTTP 内核的 handle
方法的签名非常简单:它接收 Request
接口并返回 Response
接口。
服务提供者
最重要的内核引导操作之一是为应用程序加载 服务提供者 。应用程序的所有服务提供程序都在 config/app.php
文件中的 providers
数组。
服务提供者是所有Laravel应用程序的引导中心,或理解为注册,比如注册服务容器绑定,事件监听器,中间件,甚至路由。是配置应用程序的中心。
Facades 充当服务容器中底层类的静态代理,提供简洁、富有表现力的好处,同时保持比传统静态方法更多的可测试性核灵活性。是一个提供从容器访问对象的类
路由
应用程序中最重要的服务提供者之一是 App\Providers\RouteServiceProvider
。此服务提供者加载应用程序的 routes
目录中包含的路由文件。
一旦应用程序被引导并且所有服务提供者都被注册,「请求」将被传递给路由器进行调度。路由器将请求发送到路由或控制器,并运行任何路由特定的中间件。
如果请求通过了所有匹配路由分配的中间件,则执行路由或控制器方法,并通过路由的中间件链路返回路由或控制器方法的响应。
最后
一旦路由或控制器方法返回一个响应,该响应将通过路由的中间件返回,从而使应用程序有机会修改或检查传出的响应
依赖注入(dependency injection)
- 谁依赖谁
- 注入什么,自动注入主要依赖反射功能,是控制反转的一种实现方式。
控制反转(Inversion Of Control, IOC)
面向对象编程中一种设计原则,减少代码之间的耦合(只依赖接口,不依赖具体实现),将控制权交给容器,在运行时容器将具体的实现动态的“注入”到调用类的对象中。
- 谁控制谁
- 反转什么
容器是什么
你把需要的类丢给容器处理,容器去反射寻找这个类的参数
Hyperf
框架生命周期
swoole生命周期
swoole_server中对象的4层生命周期
变量、对象、资源、require/include的文件等下面统称为对象
程序全局期
在 swoole_server->start
之前就创建好的对象,我们称之为程序全局生命周期。这些变量在程序启动后就会一直存在,直到整个程序结束运行才会销毁。
有一些服务器程序可能会连续运行数月甚至数年才会关闭/重启,那么程序全局期的对象在这段时间持续驻留在内存中的。程序全局对象所占用的内存是 Worker
进程间共享的,不会额外占用内存。
这部分内存会在写时分离(COW
),在 Worker
进程内对这些对象进行写操作时,会自动从共享内存中分离,变为进程全局对象。
程序全局期
include
/require
的代码,必须在整个程序shutdown
时才会释放,reload
无效
进程全局期
swoole拥有进程生命周期控制的机制,一个 Worker
子进程处理的请求数超过max_request配置后,就会自动销毁。Worker
进程启动后创建的对象(onWorkerStart中创建的对象),在这个子进程存活周期之内,是常驻内存的。onConnect/onReceive/onClose 中都可以去访问它。
进程全局对象所占用的内存是在当前子进程内存堆的,并非共享内存。对此对象的修改仅在当前
Worker
进程中有效 进程期include/require的文件,在reload
后就会重新加载
会话期
onConnect
到 onClose
是一次TCP的会话周期,http keep-alive时,一个连接可能会有多个request。 http是无状态的,一个用户可能也不止一个连接,可以通过创建一个session来关联同一个用户的不同请求。
请求期
请求期就是指一个完整的请求发来,也就是 onReceive
收到请求开始处理,直到返回结果发送 response
。这个周期所创建的对象,会在请求完成后销毁。
swoole中请求期对象与普通PHP程序中的对象就是一样的。请求到来时创建,请求结束后销毁。
请求与协程生命周期
Swoole 在处理每个连接时,会默认创建一个协程去处理,主要体现在 onRequest
、onReceive
、onConnect
事件,所以可以理解为每个请求都是一个协程,由于创建协程也是个常规操作,所以一个请求协程里面可能会包含很多个协程,同一个进程内协程之间是内存共享的,但调度顺序是非顺序的,且协程间本质上是相互独立的没有父子关系,所以对每个协程的状态处理都需要通过 协程上下文 来管理。
短生命周期对象
new 关键字创建的对象,可以使用make创建一个短生命周期对象又可以使用依赖注入功能。
容器仅管理长生命周期对象
换种方式理解就是容器内管理的对象 都是单例 ,这样的设计对于长生命周期的应用来说会更加的高效,减少了大量无意义的对象创建和销毁,这样的设计也就意味着所有需要交由 DI 容器管理的对象均不能包含 状态
值。
状态
可直接理解为会随着请求而变化的值,事实上在 协程 编程中,这些状态值也是应该存放于 协程上下文
中的,即 Hyperf\Context\Context
。
Yii2
待补充……
PHP-FPM配置与优化
进程管理模式使用
- 内存大 (4G以上)并对并发和可用性要求的话,建议使用
static
+pm.max_children(最大进程数)
- 小内存 (1G以上)建议使用
dynamic
或 (0.5G上下)建议使用ondemand
模式,降低pm.start_servers(启动时进程数)
和pm.max_spare_servers (最大空闲数)
进程数
backlog 大小问题
一个php-fpm子进程在同一时间只能处理一个进程,nginx发起的请求没有fpm进程进行accept,nginx就会断掉改连接,等fpm忙起来再去accept时,就会发现已断开,报错503
backlog设置过小,fpm紫禁城全部处于忙碌状态,backlog也塞满了,就会拒绝新的连接,nginx再去请求就会被拒。
backlog 一般设置2的幂,可参考内核 somaxconn
php-fpm进程数,每个php-fpm占用内存、平均内存占用
pm.max_requests
最大请求数
达到后释放,避免内存泄漏
request_terminate_timeout
最长执行时间优化
文章作者 小叨
上次更新 2023-04-20