安木生 - PHP
type: channel
link: https://www.anmusheng.com/index.php/category/php/
items: SAPI运行生命周期
items: PHP优秀资源汇集
items: PHP使用键值对格式化字符串
items: Composer版本依赖
items: Cookie和Session详解
items: linux下php拓展安装方法

SAPI运行生命周期
type: item
date: 2020-07-27T18:30:00+00:00
description: SAPISAPI指的是Server Application Programming Interface服务端应用编程端口，它是PHP与其他应用交互的接口。PHP脚本要执行有许多方式，直接在命令行下运行，或通过Web服务器，也可以嵌入其他程序中。SAPI提供了一个和外部通信的接口，常见的SAPI有：Cli， CGI，FastCGI。CliPHP的命令行运行模式。CGICGI即通用网关接口（common gatewag interface)，它是一段程序，通俗的讲CGI就象是一座桥，把网页和Web服务器中的执行程序连接起来，它把客户端请求传递给服务器的执行程序（PHP-CGI），再把服务器执行程序的结果返还给客户端。CGI方式在遇到客户端连接请求时先要创建CGI的子进程，激活一个CGI进程，然后处理请求，处理完后结束这个子进程。这就是fork-and-execute模式。所以用CGI方式的服务器有多少连接请求就会有多少CGI子进程，子进程反复加载是CGI性能低下的主要原因。当用户请求数量非常多时，会大量挤占系统的资源如内存和CPU等，造成效能低下。FastCGIFastCGI是CGI的升级版本，FastCGI像是一个常驻(long-live)型的CGI，它可以一直执行着，只要激活后，不会每次都要花费时间去fork一次。PHP使用PHP-FPM(FastCGI Process Manager)，全称PHP FastCGI进程管理器进行管理。Web服务器启动时载入FastCGI进程管理器，FastCGI进程管理器自身初始化，启动多个CGI解释器进程并等待来自Web服务器的连接。当客户端请求到达Web服务器时，FastCGI进程管理器选择并连接到一个CGI解释器。Web服务器将CGI环境变量和标准输入发送到FastCGI子进程PHP-CGI。FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web服务器。当FastCGI子进程关闭连接时，请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在Web Server中)的下一个连接。在CGI模式中，PHP-CGI在此便退出了。在上述情况中，你可以想象CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部扩展并重初始化全部数据结构。使用FastCGI，所有这些都只在进程启动时发生一次。一个额外的好处是，持续数据库连接(Persistent database connection)可以工作。SAPI运行PHP生命周期不管何种SAPI，都会经过下面几个阶段（ 可重复某几个环节）：模块初始化(Module init)：调用每个拓展中的的PHP_MINIT_FUNCTION中的方法初始化模块，进行一些模块所需变量的申请，内存分配等。请求初始化(Request init)：接受到客户端的请求后调用每个拓展的PHP_RINIT_FUNCTION中的方法，初始化PHP脚本的执行环境，如Session模块的RINIT会初始化$_SESSION变量。执行PHP脚本请求结束(Request Shutdown)：调用每个拓展的PHP_RSHUTDOWN_FUNCTION方法清理请求现场，并且Zend Engine开始回收变量和内存。关闭模块(Module shutdown)：Web服务器退出或者命令行脚本执行完毕退出会调用拓展源码中的PHP_MSHUTDOWN_FUNCTION 方法。对于FastCGI，每个CGI子进程都会经过模块初始化和请求结束环节，不过每个子进程的模块初始化只在进程fork出来以来后进行，整个子进程的生命周期内可能会处理多个请求。只有在Web服务器退出或者子进程被结束之后才会进行关闭模块阶段，在这两个阶段之间会随着每个请求重复请求初始化-请求结束的环节。

PHP优秀资源汇集
type: item
date: 2020-07-14T11:44:00+00:00
description: PHP PSR 代码标准PHP 资源列表PHP 设计模式用 PHP 的方式实现的各类算法合集建站系统Magento - 电商系统Flarum - 基于 PHP 和 Mithril.js 开发的轻社区Koel - 音乐社区禅道 - 项目管理软件Jitamin - 项目管理系统Kanboard - 项目管理工具Phproject - 项目管理系统Matomo - 开源 Web 统计软件，原 PiwikBookStack - 类 wiki 和在线书籍写作平台SmartWiki - 支持 Markdown 的文档工具Codiad - Web 在线 IDEMeEdu - 基于 Laravel 开发的在线点播系统PHP Server Monitor - 服务器监控工具基础框架Slim - 非常优秀的轻量级框架，适合开发小型 API 应用Symfony - 组件式框架，提供了众多优秀的 PHP 类库Laravel - 号称最优雅的 PHP 框架CodeIgniter4 - CodeIgniter 全新现代版本Yii 2ThinkPHP 5Zend FrameworkFlight - RESTful 框架Bullet - RESTful 框架Aura - 包含许多组件Kohana - HMVC框架Workerman - PHP Socket服务器框架Ohsce - 高可靠性 PHP 通信 控制框架 SOCKETPPM - PHP Process ManagerZPHP - SOA 服务框架appserver.io - 多线程的 PHP 应用服务器MeepoPS - 多进程 SocketServicephpDaemon - PHP 异步框架QPM - Quick PHP 进程管理框架Zan PHP Framework - 有赞团队开源的基于 PHP 协程的网络服务框架Swoole - PHP 语言的高性能网络通信框架Phalcon - 扩展型框架React - 异步框架(PHP 版 node.js)Zephir - 可以用近似 PHP 的一种中间代码写程序，然后自动转为 C++，并作为扩展来运行Yaf - 鸟哥写的扩展型框架APIxGo! - PHP AOP 框架Fat-Free FrameworkCakePHP - 老牌框架One - 基于 swoole 常驻内存框架框架laravel-admin - 快速构建后台管理的开发工具Voyager - Laravel 后台管理框架FastAdmin - 基于 ThinkPHP5 + Bootstrap 的极速后台开发框架ThinkCMF - 后台内容管理框架，基于 ThinkPHP5RhaPHP - 微信开发、小程序开发、微信公众号管理系统未归类MonologHoa - An extensible set of PHP librariesBelt - 工具函数库PHP Sitemap Generator - 网站地图生成类Array2XMLXML2ArraypChart - 图表生成库PHP QR Code - 二维码生成hashids - 根据整数生成唯一、不连续的短 IDParticle - 唯一 ID 生成器Pinyin - 中文转拼音工具Ratchet - 创建实时、双向客户端服务器 WebSockets 应用JsonMapper - 将内嵌 JSON 结构映射为 PHP 类的库Pimple - 依赖注入容器PHP-DI - 依赖注入容器Mobile Detect - 浏览器环境检测类DeviceDetector - 浏览器环境检测类poliander/cron - Crontab 格式解析dragonmantank/cron-expression - Crontab 格式解析Box - Phar 构建工具phpMyFAQ - F.A.Q. 应用hook - BaaS 软件KodExplorer - 基于Web的在线文件管理、代码编辑器ICEcoder - Web IDE(基于 Web 的代码编辑器)PHPSandbox - 将运行 PHP 作为独立进程的一种方式PHPCPD - 在代码中寻找类似模式的工具Ubench - 代码执行效率评测工具Text_Diff - 代码文件比较工具PHP Analyzer - 执行和编译器相同的流动分析apache2nginx - 在线转换 apache 配置为 nginx 配置php-mirroring - Packagist and Github mirroringSocketLog - 微信调试、API 调试和 AJAX 的调试的工具，能将日志通过 WebSocket 输出到 Chrome 浏览器的 console 中ApnsPHP - iOS 推…

PHP使用键值对格式化字符串
type: item
date: 2020-07-14T10:44:00+00:00
description: Python基于字典的字符串格式化如下：person = {'name':'bruce', 'number':'56778'} print("%(name)'s phone number is %(number)" % person)使用PHP实现类似功能：function sprintf_array($string, $array) { $keys = array_keys($array); $keysmap = array_flip($keys); $values = array_values($array); while (preg_match('/%\(([a-zA-Z0-9_-]+)\)/', $string, $m)) { if (!isset($keysmap[$m[1]])) { echo "No key $m[1]\n"; return false; } $string = str_replace($m[0], '%' . ($keysmap[$m[1]] + 1) . '$', $string); } array_unshift($values, $string); var_dump($values); return call_user_func_array('sprintf', $values); } echo sprintf_array("%(name)s's phone number is %(number)08d", array('name' => 'bruce', 'number' => '56778'));

Composer版本依赖
type: item
date: 2020-03-10T06:42:00+00:00
description: 基本约束精确版本可以指定具体的版本，告诉Composer只能安装这个版本。但是如果其他的依赖需要用到其他的版本，则包的安装或者更新最后会失败并终止。{ "require": { "ezimuel/ringphp": "1.1.2", } }范围使用比较操作符可以指定包的范围。这些操作符包括：>，>=，<，<=，!=。 可以定义多个范围，使用空格或者逗号表示逻辑上的与，使用双竖线表示逻辑上的或。其中与的优先级会大于或。也可用连字符定义范围。需要注意的是，使用没有边界的范围有可能会导致安装不可预知的版本，并破坏向下的兼容性。建议使用折音号操作符。{ "require": { "ezimuel/ringphp": ">=1.1.2", "ezimuel/ringphp": ">=1.1.2 <2.0 || >2.3.0", "ezimuel/ringphp": "1.0.0 - 2.1.0", } }通配符可使用通配符去定义版本。{ "require": { "ezimuel/ringphp": "1.1.*", } }下一个重要版本操作符波浪号~波浪号\~定义了最小的版本，并且允许按版本的最后一位版本号进行升级。如\~1.2相当于>=1.2 <2.0.0，而\~1.2.3相当于>=1.2.3 <1.3.0折音号^^操作符允许升级版本到安全的版本。{ "require": { "ezimuel/ringphp": "^1.1.2", } }版本稳定性如果没有显式的指定版本的稳定性，Composer会默认在内部指定为-dev或者-stable。如果想指定稳定版本，可以在版本后面添加后缀-stable。 Composer的minimum-stability配置项定义了包在选择版本时对稳定性的选择的默认行为。默认是stable。它的值如下（按照稳定性排序）：dev，alpha，beta，RC和stable。除了修改这个配置去修改这个默认行为，还可以通过稳定性标识（例如@stable和@dev）来安装一个相比于默认配置不同稳定性的版本。例如：{ "require": { "monolog/monolog": "1.0.*@beta", "acme/foo": "@stable" } }

Cookie和Session详解
type: item
date: 2020-03-05T02:32:00+00:00
description: 会话跟踪是Web程序中常用的技术，用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份，Session通过在服务器端记录信息确定用户身份。Cookie机制在程序中，会话跟踪是很重要的事情。理论上，一个用户的所有请求操作都应该属于同一个会话，而另一个用户的所有请求操作则应该属于另一个会话，二者不能混淆。例如，用户A在超市购买的任何商品都应该放在A的购物车内，不论是用户A什么时间购买的，这都是属于同一个会话的，不能放入用户B或用户C的购物车内，这不属于同一个会话。 而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕，客户端与服务器端的连接就会关闭，再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内，当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话，必须引入一种机制。 Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前，基本上所有的网站都采用Cookie来跟踪会话。什么是CookieCookie是由W3C组织提出，最早由Netscape社区发展的一种机制。目前Cookie已经成为标准，所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。 由于HTTP是一种无状态的协议，服务器单从网络连接上无从知道客户身份。怎么办呢？就给客户端们颁发一个通行证吧，每人一个，无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。 Cookie实际上是一小段的文本信息。客户端请求服务器，如果服务器需要记录该用户状态，就向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时，浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie，以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。 注意：Cookie功能需要浏览器的支持，如果浏览器不支持Cookie或者把Cookie禁用了，Cookie功能就会失效。Cookie的不可跨域名性很多网站都会使用Cookie。例如，Google会向客户端颁发Cookie，Baidu也会向客户端颁发Cookie。那浏览器访问Google会不会也携带上Baidu颁发的Cookie呢？或者Google能不能修改Baidu颁发的Cookie呢？ 答案是否定的。Cookie具有不可跨域名性。根据Cookie规范，浏览器访问Google只会携带Google的Cookie，而不会携带Baidu的Cookie。Google也只能操作Google的Cookie，而不能操作Baidu的Cookie。 Cookie在客户端是由浏览器来管理的。浏览器能够保证Google只会操作Google的Cookie而不会操作Baidu的Cookie，从而保证用户的隐私安全。浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。Google与Baidu的域名不一样，因此Google不能操作Baidu的Cookie。 需要注意的是，虽然网站images.google.com与网站www.google.com同属于Google，但是域名不一样，二者同样不能互相操作彼此的Cookie。 注意：用户登录网站www.google.com之后会发现访问images.google.com时登录信息仍然有效，而普通的Cookie是做不到的。这是因为Google做了特殊处理。Cookie的安全属性HTTP协议不仅是无状态的，而且是不安全的。使用HTTP协议的数据不经过任何加密就直接在网络上传播，有被截获的可能。使用HTTP协议传输很机密的内容是一种隐患。如果不希望Cookie在HTTP等非安全协议中传输，可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。 提示：secure属性并不能对Cookie内容加密，因而不能保证绝对的安全性。如果需要高安全性，需要在程序中对Cookie内容加密、解密，以防泄密。JavaScript操作CookieCookie是保存在浏览器端的，因此浏览器具有操作Cookie的先决条件。浏览器可以使用脚本程序如JavaScript等操作Cookie。由于JavaScript能够任意地读写Cookie，有些好事者便想使用JavaScript程序去窥探用户在其他网站的Cookie。不过这是徒劳的，W3C组织早就意识到JavaScript对Cookie的读写所带来的安全隐患并加以防备了，W3…

linux下php拓展安装方法
type: item
date: 2020-01-22T01:22:00+00:00
description: linux下php有多种方式来安装拓展， 主要有包管理式的安装、pecl 安装和源码编译安装。 包管理式的安装卸载尤为方便，而源码编译式的安装则方便参数调优。一般搭建本机开发环境推荐包管理式的安装，节约时间。而线上部署环境则推荐编译安装， 方便调优。本文以CentOS下\`MongoDB 扩展安装举例。yum安装yum方式安装能自动安装拓展的.so动态库，并配置好php.ini 注： 1. 请确保自己yum源里面有对应扩展 2. 安装完成后重启服务器 Nginx 或者 Apacheyum search mongodb | grep php # 搜索yum 源里面MongoDB拓展 yum -y install php72u-pecl-mongo # 安装 PHP 对应版本的MongoDB扩展 systemctl restart nginx # 重新启动 Nginxpecl安装pecl install mongodb安装完成后在PHP配置文件php.ini里面加载 MongoDB扩展，然后重启服务器源码编译安装wget http://pecl.php.net/get/mongodb-1.2.8.tgz #下载源码包 tar zxf mongodb-1.2.8.tgz #解压 cd mongodb-1.2.8 /usr/bin/phpize ./configure --with-php-config=/usr/bin/php-configphpize命令用于准备php扩展安装的编译环境，php-config用于获取所安装的PHP配置的信息。