cgi ,fastcgi,php-fpm 区别
cgi
CGI 的英文是(COMMON GATEWAY INTERFACE)公共网关接口,它的作用就是帮助服务器与语言通信,这里就是 nginx 和 php 进行通信,因为 nginx 和 php 的语言不通,因此需要一个沟通转换的过程,而 CGI 就是这个沟通的协议。
nginx 服务器在接受到浏览器传递过来的数据后,如果请求的是静态的页面或者图片等无需动态处理的则会直接根据请求的 url 找到其位置然后返回给浏览器,这里无需 php 参与,但是如果是一个动态的页面请求,这个时候 nginx 就必须与 php 通信,这个时候就会需要用到 cgi 协议,将请求数据转换成 php 能理解的信息,然后 php 根据这些信息返回的信息也要通过 cgi 协议转换成 nginx 可以理解的信息,最后 nginx 接到这些信息再返回给浏览器。
fast-cgi
传统的 cgi 协议在每次连接请求时,会开启一个进程进行处理,处理完毕会关闭该进程,因此下次连接,又要再次开启一个进程进行处理,因此有多少个连接就有多少个 cgi 进程,这也就是为什么传统的 cgi 会显得缓慢的原因,因此过多的进程会消耗资源和内存。
而 fast-cgi 每次处理完请求后,不会 kill 掉这个进程,而是保留这个进程,使这个进程可以一次处理多个请求。这样每次就不用重新 fork 一个进程了,大大提高效率。
php-cgi
php-cgi 是 php 提供给 web serve 也就是 http 前端服务器的 cgi 协议接口程序,当每次接到 http 前端服务器的请求都会开启一个 php-cgi 进程进行处理,而且开启的 php-cgi 的过程中会先要重载配置,数据结构以及初始化运行环境,如果更新了 php 配置,那么就需要重启 php-cgi 才能生效,例如 phpstudy 就是这种情况。
php-fpm
php-fpm 是 php 提供给 web serve 也就是 http 前端服务器的 fastcgi 协议接口程序,它不会像 php-cgi 一样每次连接都会重新开启一个进程,处理完请求又关闭这个进程,而是允许一个进程对多个连接进行处理,而不会立即关闭这个进程,而是会接着处理下一个连接。它可以说是 php-cgi 的一个管理程序,是对 php-cgi 的改进。
php-fpm 会开启多个 php-cgi 程序,并且 php-fpm 常驻内存,每次 web serve 服务器发送连接过来的时候,php-fpm 将连接信息分配给下面其中的一个子程序 php-cgi 进行处理,处理完毕这个 php-cgi 并不会关闭,而是继续等待下一个连接,这也是 fast-cgi 加速的原理,但是由于 php-fpm 是多进程的,而一个 php-cgi 基本消耗 7-25M 内存,因此如果连接过多就会导致内存消耗过大,引发一些问题,例如 nginx 里的 502 错误。
同时 php-fpm 还附带一些其他的功能:
例如平滑过渡配置更改,普通的 php-cgi 在每次更改配置后,需要重新启动才能初始化新的配置,而 php-fpm 是不需要,php-fpm 分将新的连接发送给新的子程序 php-cgi,这个时候加载的是新的配置,而原先正在运行的 php-cgi 还是使用的原先的配置,等到这个连接后下一次连接的时候会使用新的配置初始化,这就是平滑过渡。
PHP5 跟 php7 的区别
PHP7.0 号称是性能提升上革命性的一个版本。面对 Facebook 家的 HHVM 引擎带来的压力,开发团队重写了底层的 Zend Engine,名为 Zend Engine 2。
底层内核解析
PHP7 中最重要的改变就是 zval 不再单独从堆上分配内存并且不自己存储引用计数。需要使用 zval 指针的复杂类型(比如字符串、数组和对象)会自己存储引用计数。这样就可以有更少的内存分配操作、更少的间接指针使用以及更少的内存分配。在 PHP7 中的 zval, 已经变成了一个值指针,它要么保存着原始值,要么保存着指向一个保存原始值的指针。也就是说现在的 zval 相当于 PHP5 的时候的 zval * . 只不过相比于 zval * , 直接存储 zval, 我们可以省掉一次指针解引用,从而提高缓存友好性.
HP7 为什么比 PHP5 性能提升了
1、变量存储字节减小,减少内存占用,提升变量操作速度
2、改善数组结构,数组元素和 hash 映射表被分配在同一块内存里,降低了内存占用、提升了 cpu 缓存命中率
3、改进了函数的调用机制,通过优化参数传递的环节,减少了一些指令,提高执行效率
总体
性能提升:PHP7 比 PHP5.0 性能提升了两倍。
全面一致的 64 位支持。
以前的许多致命错误,现在改成 [抛出异常]。
PHP 7.0 比 PHP5.0 移除了一些老的不在支持的 SAPI([服务器端] 应用编程端口)和扩展。
.PHP 7.0 比 PHP5.0 新增了空接合操作符。
PHP 7.0 比 PHP5.0 新增加了结合比较运算符。
PHP 7.0 比 PHP5.0 新增加了函数的返回类型声明。
PHP 7.0 比 PHP5.0 新增加了标量类型声明。
PHP 7.0 比 PHP5.0 新增加匿名类。
多进程同时读写一个文件
PHP 是支持进程的而不支持多线程(这个先搞清楚了),如果是对于文件操作,其实你只需要给文件加锁就能解决,不需要其它操作,PHP 的 flock 已经帮你搞定了。
用 flock 在写文件前先锁上,等写完后解锁,这样就实现了多线程同时读写一个文件避免冲突。
tp 框架
优点
TP 框架是我们中国人自己开发的框架,各种资料比较齐全,国内用的比较多,比较简单
和方便,而且是免费开源的
特性
多表查询非常方便,在 model 中几句代码就可以完成对多表的关联操作
融合了 smarty 模板,使前后台分离
支持多种缓存技术,尤其对 memcache 技术支持非常好
命名规范,模型,视图,控制器严格遵循命名规则,通过命名一一对应
支持多种 url 模式
内置 ajax 返回方法,包括 xml,json,html 等
支持应用扩展,类库扩展,驱动扩展
大写字母
U: 对 url 的组装 A: 内部实例化控制器 S: 缓存处理 R: 调用某个控制器的操作方法 D: 实例化
保存配置
laravel 框架
简介
laravel 框架的设计思想比较先进,非常适合应用各种开发模式,作为一个框架,它为你
准备好了一切,composer 是 php 的未来,没有 composer,php 肯定要走向没落
laravel 框架最大的特点和优秀之处就是集合了 php 比较新的特点,以及各种各样的设计
模式,Ioc 模式,依赖注入等.
特点
1. 强大的 rest router: 用简单的回调函数就可以调用,快速绑定 controller 和 router
2.artisan: 命令行工具,很多手动的工作都自动化
3. 可继承的模板,简化 view 的开发和管理
4.blade 模板:渲染速度更快
5.ORM 操作数据库
6.migration: 管理数据库和版本控制
7. 测试功能也很强大
8.composer 也是亮点
laravel 框架引入了门面,依赖注入,Ioc 模式,以及各种各样的设计模式等
composer
简介
compo及 “packages” 和 “libraries”,但它在每个项目的基础上进行管理,在你项目的某个目录中(例如 vendor)进行安装。默认情况下它不会在全局安装任何东西。因此,这仅仅是一个依赖管理。
命令
composer install 依据当前目录下的 composer.lock(锁文件) 或 composer.json 文件,所定义的依赖关系,安装依赖包。
composer update 更新依赖版本,如果你修改了 composer.json 中的依赖关系,想让 composer 按照 composer.json 文件中的定义执行更新操作,就用 update 命令。
composer require require 命令一般用来安装新的依赖包,并将依赖写入当前目录的 composer.json 文件中。如果 composer.json 文件中,添加或改变了依赖,修改后的依赖关系将被安装或者更新。
create-project 你可以使用 create-project 从现有的包中创建一个新的项目。它相当于执行了 git clone 命令后,将这个包的依赖安装到它自己的 vendor 目录。
设计模式
创建型
在软件工程中,创建型设计模式是处理对象创建机制的设计模式,试图以适当的方式来创建对象。对象创建的基本形式可能会带来设计问题,亦或增加了设计的复杂度。创建型设计模式通过控制这个对象的创建方式来解决此问题。
抽象工厂模式
在不指定具体类的情况下创建一系列相关或依赖对象。 通常创建的类都实现相同的接口。 抽象工厂的客户并不关心这些对象是如何创建的,它只是知道它们是如何一起运行的。
建造者模式
建造者是创建一个复杂对象的一部分接口。
有时候,如果建造者对他所创建的东西拥有较好的知识储备,这个接口就可能成为一个有默认方法的抽象类(又称为适配器)。
如果对象有复杂的继承树,那么对于建造者来说,有一个复杂继承树也是符合逻辑的。
注意:建造者通常有一个「流式接口」,例如 PHPUnit 模拟生成器。
工厂方法模式
对比简单工厂模式的优点是,您可以将其子类用不同的方法来创建一个对象。
举一个简单的例子,这个抽象类可能只是一个接口。
这种模式是「真正」的设计模式, 因为他实现了 S.O.L.I.D 原则中「D」的 「依赖倒置」。
这意味着工厂方法模式取决于抽象类,而不是具体的类。 这是与简单工厂模式和静态工厂模式相比的优势。
多例模式
多例模式被公认为是 反面模式,获得更好的可测试性和可维护性,使用『依赖注入模式』。
多例模式是指存在一个类有多个相同实例,而且该实例都是该类本身。这个类叫做多例类。 多例模式的特点是:
多例类可以有多个实例。
多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。
多例模式实际上就是单例模式的推广。
对象池模式
对象池模式是一种提前准备了一组已经初始化了的对象『池』而不是按需创建或者销毁的创建型设计模式。对象池的客户端会向对象池中请求一个对象,然后使用这个返回的对象执行相关操作。当客户端使用完毕,它将把这个特定类型的工厂对象返回给对象池,而不是销毁掉这个对象。
在初始化实例成本高,实例化率高,可用实例不足的情况下,对象池可以极大地提升性能。在创建对象(尤其是通过网络)时间花销不确定的情况下,通过对象池在可期时间内就可以获得所需的对象。
无论如何,对象池模式在需要耗时创建对象方面,例如创建数据库连接,套接字连接,线程和大型图形对象(比方字体或位图等),使用起来都是大有裨益的。在某些情况下,简单的对象池(无外部资源,只占内存)可能效率不高,甚至会有损性能。
原型模式
相比正常创建一个对象 (new Foo () ),首先创建一个原型,然后克隆它会更节省开销。
简单工厂模式
简单工厂模式是一个精简版的工厂模式。
它与静态工厂模式最大的区别是它不是『静态』的。因为非静态,所以你可以拥有多个不同参数的工厂,你可以为其创建子类。甚至可以模拟(Mock)他,这对编写可测试的代码来讲至关重要。
单例模式
单例模式被公认为是 反面模式,为了获得更好的可测试性和可维护性,请使用『依赖注入模式』。主要为了在应用程序调用的时候,只能获得一个对象实例。主要包括:数据库的连接,日志的使用等。
静态工厂模式
与抽象工厂模式类似,此模式用于创建一系列相关或相互依赖的对象。 『静态工厂模式』与『抽象工厂模式』的区别在于,只使用一个静态方法来创建所有类型对象, 此方法通常被命名为 factory 或 build。
结构型
在软件工程中,结构型设计模式是通过识别实体之间关系来简化设计的设计模式。
行为型
在软件工程中,行为设计模式是识别对象之间的通用通信模式并实现这些模式的设计模式。 通过这样做,这些模式增加了执行此通信的灵活性。
生命周期
php 的生命周期
模块初始化阶段 (Module init):即调用每个拓展源码中的的 PHP_MINIT_FUNCTION 中的方法初始化模块,进行一些模块所需变量的申请,内存分配等。
请求初始化阶段 (Request init):即接受到客户端的请求后调用每个拓展的 PHP_RINIT_FUNCTION 中的方法,初始化 PHP 脚本的执行环境。
执行该 PHP 脚本。
请求结束 (Request Shutdown):这时候调用每个拓展的 PHP_RSHUTDOWN_FUNCTION 方法清理请求现场,并且 ZE 开始回收变量和内存
关闭模块 (Module shutdown):Web 服务器退出或者命令行脚本执行完毕退出会调用拓展源码中的 PHP_MSHUTDOWN_FUNCTION 方法
laravel 的生命周期
加载项目依赖,注册加载 composer 自动生成的 class loader,也就是加载初始化第三方依赖。
创建应用实例,生成容器 Container,并向容Console 内核。
接收请求并响应,请求被发送到 HTTP 内核或 Console 内核,这取决于进入应用的请求类型。HTTP 内核继承自 Illuminate\Foundation\Http\Kernel 类,该类定义了一个 bootstrappers 数组,这个数组中的类在请求被执行前运行,这些 bootstrappers 配置了错误处理、日志、检测应用环境以及其它在请求被处理前需要执行的任务。HTTP 内核还定义了一系列所有请求在处理前需要经过的 HTTP 中间件,这些中间件处理 HTTP 会话的读写、判断应用是否处于维护模式、验证 CSRF 令牌等等。
发送请求,在 Laravel 基础的服务启动之后,把请求传递给路由了。路由器将会分发请求到路由或控制器,同时运行所有路由指定的中间件。传递给路由是通过 Pipeline(管道)来传递的,在传递给路由之前所有请求都要经过 app\Http\Kernel.php 中的 $middleware 数组,也就是中间件,默认只有一个全局中间件,用来检测你的网站是否暂时关闭。所有请求都要经过,你也可以添加自己的全局中间件。然后遍历所有注册的路由,找到最先符合的第一个路由,经过它的路由中间件,进入到控制器或者闭包函数,执行你的具体逻辑代码,把那些不符合或者恶意的的请求已被 Laravel 隔离在外。
基础组件 – 日志
Laravel 提供了强大的日志服务来记录日志信息到文件、系统错误日志、甚至是 Slack 以便通知整个团队。在日志引擎之下,Laravel 集成了 Monolog 日志库以便提供各种功能强大的日志处理器,从而允许你通过它们来定制自己应用的日志处理。
应用日志系统的所有配置都存放在配置文件 config/logging.php 中,该文件允许你配置应用的日志通道,因此需要查看每个可用通道及其配置项,默认情况下,Laravel 使用 stack 通道来记录日志信息,stack 通道被用于聚合多个日志通道到单个通道
配置通道名称
默认情况下,Monolog 通过与当前环境匹配的「通道名称」实例化,例如 production 或 local,要改变这个值,添加 name 项到通道配置
有效通道驱动列表
stack 用于创建「多通道」通道的聚合器
single 基于单文件 / 路径的日志通道(StreamHandler)
daily 基于 RotatingFileHandler 的 Monolog 驱动,以天为维度对日志进行分隔
slack 基于 SlackWebhookHandler 的 Monolog 驱动
syslog 基于 SyslogHandler 的 Monolog 驱动
errorlog 基于 ErrorLogHandler 的 Monolog 驱动
monolog Monolog 改成驱动,可以使用所有支持的 Monolog 处理器
custom 调用指定改成创建通道的驱动
配置 Single 和 Daily 通道
single 和 daily 通道有三个可选配置项:bubble、permission 和 locking。
bubble 表示消息在被处理后是否冒泡到其它通道 ,默认为 true
permission 日志文件权限,默认为 644
locking 在日志文件写入前尝试锁定它,默认为 false
配置 Slack 通道
slack 通道需要一个 url 配置项,这个 URL 需要和你配置的 Slack 团队 [请求 URL] 相匹配。
构建日志堆栈
stack 驱动允许你将多个通道合并到单个日志通道,stack 通道通过 channels 项将聚合了其他两个通道:syslog 和 slack。因此,记录日志信息时,这两个通道都有机会记录信息。
面向对象 oop
是什么
oop 是面向对象编程,面向对象编程是一种计算机编程架构,OOP 的一条基本原则是
计算机程序是由单个能够起到子程序作用的单元或对象组合而成。
* 三大特点 *
1、封装性:也称为信息隐藏,就是将一个类的使用和实现分开,只保留部分接口和方
法与外部联系,或者说只公开了一些供开发人员使用的方法。于是开发人员只 需要关
注这个类如何使用,而不用去关心其具体的实现过程,这样就能实现 MVC 分工合作,
也能有效避免程序间相互依赖,实现代码模块间松藕合。
2、继承性:就是子类自动继承其父级类中的属性和方法,并可以添加新的属性和方法
或者对部分属性和方法进行重写。继承增加了代码的可重用性。PHP 只支持单继承,也
就是说一个子类只能有一个父类。
3、多态性:子类继承了来自父级类中的属性和方法,并对其中部分方法进行重写。于
是多个子类中虽然都具有同一个方法,但是这些子类实例化的对象调用这些相同的方法
后却可以获得完全不同的结果,这种技术就是多态性。多态性增强了软件的灵活性。
设计模式的五大原则
单一职责原则 单一职责原则可以看做是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因
开发封闭原则 开放 – 封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护,可扩展,可复用,灵活性好。
接口隔离原则 通俗点说,不要强迫客户使用它们不用的方法,如果强迫用户使用它们不使用的方法,那么这些客户就会面临由于这些不使用的方法的改变所带来的改变。
依赖倒置原则 依赖倒置原则其实可以说是面向对象设计的标志,用哪种语言来编写程序不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象的设计,反之那就是过程化的设计了。
里氏替换原则 任何基类可以出现的地方,子类一定可以出现。 LSP 是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对 “开 – 闭” 原则的补充。实现 “开 – 闭” 原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
好处
1、易维护 采用面向对象思想设计的结构,可读性高,由于继承的存在,即使改变需求,那么维护
也只是在局部模块,所以维护起来是非常方便和较低成本的。
2、质量高 在设计时,可重用现有的,在以前的项目的领域中已被测试过的类使系统满足业务需求
并具有较高的质量。
3、效率高 在软件开发时,根据设计的需要对现实世界的事物进行抽象,产生类。使用这样的方法
解决问题,接近于日常生活和自然的思考方式,势必提高软件开发的效率和质量。
4、易扩展 由于继承、封装、多态的特性,自然设计出高内聚、低耦合的系统结构,使得系统更灵
活、更容易扩展,而且成本较低。
smarty
smarty 是用 php 写出来的模板引擎,也是目前业界最著名的 php 模板引擎之一,它分离了逻辑代码和外在的显示,提供了一种易于管理和使用的方法,用来将混杂的 php
逻辑代码与 html 代码进行分离,smarty 是 php 中最著名的引擎框架之一,我们公司使用的是 TP 框架,已经封装好了 smarty 模板,所以没有单独使用过
smarty 是个模板引擎,最显著的地方就是有可以把模板缓存起来。一般模板来说,都是做一个静态页面,然后在里面把一些动态的部分用一切分隔符切开,然后在 PHP 里打开这个模板文件,把分隔符里面的值替换掉,然后输出来,你可以看下 PHPLib 里面的 template 部分。
而 smarty 设定了缓存参数以后,第一次运行时候会把模板打开,在 php 替换里面值的
时候把读取的 html 和 php 部分重新生成一个临时的 php 文件,这样就省去了每次打
开都重新读取 html 了。如果修改了模板,只要重新刷下就行了。
参考资料
php的运行原理、cgi对比fastcgi以及php-cgi和php-fpm之间的联系区别_贝伦酱-CSDN博客
https://learnku.com/articles/28772#b271e4
https://laravelacademy.org/post/19467.html
