关于CGI 和 PHP-FPM的对比分析

 更新时间:2016年11月25日 14:55  点击:1573
关于CGI 和 PHP-FPM我相信大家用会用但它们到底怎么区别及哪里不一样可能不知道了,这里为各位整理一篇关于CGI 和 PHP-FPM的对比分析文章。

首先我们引入一些概念,搞清楚 CGI 和 FastCGI

CGI

通用网关接口(Common Gateway Interface/CGI)是一种重要的互联网技术,可以让一个客户端,从网页浏览器向执行在网络服务器上的程序请求数据。CGI描述了服务器和请求处理程序之间传输数据的一种标准。
FastCGI

快速通用网关接口(Fast Common Gateway Interface/FastCGI)是一种让交互程序与Web服务器通信的协议。FastCGI是早期通用网关接口(CGI)的增强版本。

FastCGI致力于减少网页服务器与CGI程序之间互动的开销,从而使服务器可以同时处理更多的网页请求。
好现在明白了

CGI 和 FastCGI 是一种通信协议规范,不是一个实体
我们平常需要用词规范,是CGI 还是 CGI程序

CGI 程序和FastCGI程序,是指实现这两个协议的程序,可以是任何语言实现这个协议的。(PHP-CGI 和 PHP-FPM就是实现FastCGI的程序)


为什么推荐使用FastCGI程序

除了上面对两个协议的描述外,这里再补充下他们实现的程序的区别。

关于CGI程序

CGI使外部程序与Web服务器之间交互成为可能。CGI程序运行在独立的进程中,并对每个Web请求建立一个进程,这种方法非常容易实现,但效率很差,难以扩展。面对大量请求,进程的大量建立和消亡使操作系统性能大大下降。此外,由于地址空间无法共享,也限制了资源重用。
关于FastCGI程序

与为每个请求创建一个新的进程不同,FastCGI使用持续的进程来处理一连串的请求。这些进程由FastCGI服务器管理,而不是web服务器。 当进来一个请求时,web服务器把环境变量和这个页面请求通过一个socket比如FastCGI进程与web服务器(都位于本地)或者一个TCP connection(FastCGI进程在远端的server farm)传递给FastCGI进程。
FastCGI为了提高CGI的效率而存在的。

PHP-CGI 和 PHP-FPM的区别


PHP-CGI是PHP自带的FastCGI管理器。启动PHP-CGI,使用如下命令:

php-cgi -b 127.0.0.1:9000

php-cgi与php-fpm一样,也是一个fastcgi进程管理器,php-cgi的问题在于 1、php-cgi变更php.ini配置后需重启php-cgi才能让新的php-ini生效,不可以平滑重启 2、直接杀死php-cgi进程,php就不能运行了。(PHP-FPM和Spawn-FCGI就没有这个问题,守护进程会平滑从新生成新的子进程。) 针对php-cgi的不足,php-fpm应运而生。

PHP-FPM 的管理对象是php-cgi。使用PHP-FPM来控制PHP-CGI的FastCGI进程

Nginx 如何调用PHP

web server(比如说nginx)只是内容的分发者。比如,如果请求/index.html,那么web server会去文件系统中找到这个文件,发送给浏览器,这里分发的是静态数据。好了,如果现在请求的是/index.php,根据配置文件,nginx知道这个不是静态文件,需要去找PHP解析器来处理,那么他会把这个请求简单处理后交给PHP解析器。Nginx会传哪些数据给PHP解析器呢?url要有吧,查询字符串也得有吧,POST数据也要有,HTTP header不能少吧,好的,CGI就是规定要传哪些数据、以什么样的格式传递给后方处理这个请求的协议。仔细想想,你在PHP代码中使用的用户从哪里来的。

当web server收到/index.php这个请求后,会启动对应的CGI程序,这里就是PHP的解析器。接下来PHP解析器会解析php.ini文件,初始化执行环境,然后处理请求,再以规定CGI规定的格式返回处理后的结果,退出进程。web server再把结果返回给浏览器。

Apache如何调用PHP

Apache 有个mod_php 扩展。php是apache的一个外挂程序,必须依靠web服务器才可以运行。当客户端浏览器触发事件--->url 提交到apache服务器---->apache服务器根据php程序的特点判断是php程序,提交给php引擎程序--->php引擎程序解析并读取数据库生成相应的页面

FastCGI运行模式分析:

FastCGI的工作原理是:

(1)、Web Server 启动时载入FastCGI进程管理器【PHP的FastCGI进程管理器是PHP-FPM(php-FastCGI Process Manager)】(IIS ISAPI或Apache Module);
(2)、FastCGI进程管理器自身初始化,启动多个CGI解释器进程 (在任务管理器中可见多个php-cgi.exe)并等待来自Web Server的连接。
(3)、当客户端请求到达Web Server时,FastCGI进程管理器选择并连接到一个CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程php-cgi.exe。
(4)、FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在 WebServer中)的下一个连接。 在正常的CGI模式中,php-cgi.exe在此便退出了。

在上述情况中,你可以想象 CGI通常有多慢。每一个Web请求PHP都必须重新解析php.ini、重新载入全部dll扩展并重初始化全部数据结构。使用FastCGI,所有这些 都只在进程启动时发生一次。一个额外的好处是,持续数据库连接(Persistent database connection)可以工作。

 为什么要使用FastCGI,而不是多线程CGI解释器?
这可能出于多方面的考虑,例如:

(1)、你无论如何也不能在windows平台上稳定的使用多线程CGI解释器,无论是IIS ISAPI方式还是APACHE Module方式,它们总是运行一段时间就崩溃了。奇怪么?但是确实存在这样的情况!
当然,也有很多时候你能够稳定的使用多线程CGI解释器,但是,你有可能发现网页有时候会出现错误,无论如何也找不到原因,而换用FastCGI方式 时这种错误的概率会大大的降低。我也不清楚这是为什么,我想独立地址空间的CGI解释器可能终究比共享地址空间的形式来得稳定一点点。
(2)、性能!性能?可能么,难道FastCGI比多线程CGI解释器更快?但有时候确实是这样,只有测试一下你的网站,才能最后下结论。原因嘛,我觉得 很难讲,但有资料说在Zend WinEnabler的时代,Zend原来也是建议在Windows平台下使用FastCGI而不是IIS ISAPI或Apache Module,不过现在Zend已经不做这个产品了。

 FastCGI 模式运行PHP 的优点:

以 FastCGI 模式运行 PHP 有几个主要的好处。首先就是 PHP 出错的时候不会搞垮 Apache,只是 PHP 自己的进程当掉(但 FastCGI 会立即重新启动一个新 PHP 进程来代替当掉的进程)。其次 FastCGI 模式运行 PHP 比 ISAPI 模式性能更好(我本来用 ApacheBench 进行了测试,但忘了保存结果,大家有兴趣可以自己测试)。

在php中对于变量命名有什么规则呢,我相信各位都知道简单的但要精细估计不知道,下面我们来看看PHP变量的声明及变量的命名规则的介绍。

以下三种写法中,哪种是正确的?

在php程序中,变量的命名规则是怎样的,以下三种写法中,哪种是正确的?

第1种:
<?php
  $myname='aa';
?>

第2种:
<?php
  $myName='aa';
?>

第3种:
<?php
  $MyName='aa';
?>


经验分享

姓名,年龄:

<?php
/*
*变量名字以$开头
*变量的名称声明时一定要有意义
*变量不能以数字开头命名,可以用下划线开头,$和变量名不能有空格
*变量名中不能出现运算符号:加减乘除
*别的编程语言变量可能不能出现系统关键字,不过php可以,因为php有一个$
*/
$name = "毕恩竹";
$age = 20;
$php = 40;

echo $age;
变量名称区只有部分大小写

<?php
/*
$int和$INT区分大小写,echo不区分大小写
*/
$int = 10;
$INT = 20;

echo $int,"<br>";
eCho $INT;

驼峰式命名方式:one two three
<?php
$oneTwoThree = 10;
变量是用于临时存储值得容器。这些值可以是数字、文本、或者复杂得多的排列组合。是用于跟踪几乎所有类型信息的简单工具。
PHP是一种非常弱的类型语言。在大多数编程语言中,变量只能保持一种类型的数据,而且这个类型必须在使用变量前声明,例如C语言中。而在PHP中,变量的类型必须在使用变量前声明,例如C语言中。而在PHP中,变量的类型通常不是由程序员设定的,确切地说,是根据该变量使用的上下文在运行时(即变量的值)决定的。PHP不要求在使用变量之前声明变量,当第一次给第一个变量赋值时,你才创建了这个变量。
PHP的变量声明是以$符开始的,后面跟大小写字母,数字和下划线,但不能以数字开头。
<?php
$a=100;                            //声明一个变量a,赋予整数100
$b=”string”;                      //声明一个变量b,赋予字符串string
$c=true                            //声明一个变量c,赋予布尔值true
$d=99.99;                        //声明一个变量d,赋予浮尔点99.99
$key=$a;                         //声明一个key变量,并将a变量的值赋予
$a=$b=$c=$d=”value”      //同时声明多个变量,并赋予相同的值
可以使用函数()释放指定的变量,isset()函数检测变量是否设置,empty()数数检查一个变量是否为空
同时声明多个变量

<?php
$a = $b = $c =$d =10;

echo $a;
echo "<br>";
echo $b;
echo "<br>";
echo $c;
echo "<br>";
echo $d;
echo "<br>";
var_dump();可以打印输出变量类型和内容

<?php
var_dump(10);
$a=100;
var_dump($a);
isset()函数检测变量是否设置

<?php
$bool = isset($a);
var_dump($bool);

$a = 20;
$bool = isset($a);
var_dump($bool);
unset();删除一个变量

<?php
$a = 20;
unset($a);
$bool = isset($a);
var_dump($bool);
empty()数数检查一个变量是否为空,空的话返回true

<?php
$a = 20;
$b = '';
$c = 0;
$d = null;
$e = ' ';

var_dump(empty($a));
var_dump(empty($b));
var_dump(empty($c));
var_dump(empty($d));
var_dump(empty($e));
var_dump(empty($f));

回到文章开头,我们来看看如何解答

总结

1、各人喜好没有一定之规

2、目前的php对变量是不区分大小写的(据说php6将区分大小写)所以$myName='aa';被写成$myname='aa';时效果不便但可读性较差不如 $my_name='aa';清爽

3、对于区分大小写的语言,一般推荐使用“匈牙利表示法”

变量名由变量类型和若干以大写字母开头的表示变量含义的单词组成
比如
$myname='aa';
就写做
$sMyName='aa';

$myname=1;
就写做
$iMyName=1;

4、对于不区分大小写的语言,一般建议变量名由若干由下划连接的表示变量含义的单词组成

比如
$myname='aa';
就写做
$my_name='aa';

网易式评论箱的实现是许多站长非常想做到的一个东西了,今天我们来看看网易式评论箱的实现原理吧,具体的如下所示。
预览
QQ20160416-0.png
实现
基础
  1. 表的设计
  2. 前端的实现

由于每个回复的展示都需要完整的引用路径,我们需要一个字段来记录本条回复所回复的回复quote_id,在一个列表中如果每次都递归获取引用的评论,性能上会有很大的瓶颈,所以我们冗余一个字段,记录本条回复的引用路径 quote_path

CREATE TABLE `pre_comments` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `article_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `quote_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `quote_path` varchar(255) NOT NULL DEFAULT '',
  `user_id` bigint(20) unsigned NOT NULL DEFAULT '0',
  `username` char(15) NOT NULL DEFAULT '',
  `content` varchar(1024) NOT NULL,
  `up` bigint(20) NOT NULL DEFAULT '0',
  `down` bigint(20) NOT NULL DEFAULT '0',
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  `deleted_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_article_id` (`article_id`),
  KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

数据展示流程:


获取最新的10条评论
获取与最新的10条评论相关被引用的评论
组装数据,返回json
Reactjs渲染数据

Untitled.png

用伪代码可以表示为如下结构

<CommentBox>
  <CommentList>
    <CommentItem>
      <CommentQuote>
        <CommentQuote>
          <CommentToolBar>
            <CommentForm></CommentForm>
          </CommentToolBar>
        </CommentQuote>
        <CommentToolBar>
          <CommentForm></CommentForm>
        </CommentToolBar>
      </CommentQuote>
      <CommentToolBar>
        <CommentForm></CommentForm>
      </CommentToolBar>
    </CommentItem>
  </CommentList>
  <CommentForm></CommentForm>
</CommentBox>

优化

分库分表
通用计数组件
缓存
静态化
通过查询场景来决定分库分表的策略

根据articleId查询最新的评论
根据articleId 和 commentId更新计数
根据articleId 和 quoteId写入新的评论
展示某个用户(userId)所有的评论
其中有两个分表的路由key articleId 和 userId

页面跳转可以使用header函数来实现了当然如果多种办法我们看看还会有哪几种呢,下面我们一起来看小编整理的PHP页面跳转的三种方法例子。

Web系统中,从一个网页跳转到另一个网页,是项目中最常用的技术之一。

页面跳转可能是由于用户单击链接、按钮等引发的,也可能是系统自动产生的。

此处介绍PHP中常用的实现页面自动跳转的方法。

PHP页面跳转一、header()函数

header()函数是PHP中进行页面跳转的一种十分简单的方法。
header()函数的主要功能是将HTTP协议标头(header)输出到浏览器。
header()函数的定义如下:

void header (string string [,bool replace [,int http_response_code]])

可选参数replace指明是替换前一条类似标头还是添加一条相同类型的标头,默认为替换。

第二个可选参数http_response_code强制将HTTP相应代码设为指定值。
header函数中Location类型的标头是一种特殊的header调用,常用来实现页面跳转。
注意:

1.location和“:”号间不能有空格,否则不会跳转。
2.在用header前不能有任何的输出。
3.header后的PHP代码还会被执行。


< ?php
//重定向浏览器
header("Location: http://www.111cn.net/");
//确保重定向后,后续代码不会被执行
exit;
?>

PHP页面跳转二、Meta标签

Meta标签是HTML中负责提供文档元信息的标签,在PHP程序中使用该标签,也可以实现页面跳转。
若定义http-equiv为refresh,则打开该页面时将根据content规定的值在一定时间内跳转到相应页面。
若设置content=”秒数;url=网址”,则定义了经过多长时间后页面跳转到指定的网址。


< meta http-equiv="refresh"
content="1;url=http://www.111cn.net/">
< ?php  
$url = "http://www.111cn.net/"; ?>
< html>  
< head>  
< meta http-equiv="refresh" content="1; 
url=< ?php echo $url; ?>">  
< /head>  
< body> 
页面只停留一秒……  
< /body>
< /html>

PHP页面跳转三、JavaScript

例如,此代码可以放在程序中的任何合法位置。


< ?php 
$url = "http://www.111cn.net/"; 
echo "< script language='javascript'
type='text/javascript'>"; 
echo "window.location.href='$url'"; 
echo "< /script>"; 
?>
以上就是我们向大家介绍的三种PHP页面跳转实现方法。

下面我们来看一篇关于 PHP实现抓取HTTPS内容的方法和错误处理的教程希望这篇教程能够帮助到各位朋友。

最近在研究Hacker News API时遇到一个HTTPS问题。因为所有的Hacker News API都是通过加密的HTTPS协议访问的,跟普通的HTTP协议不同,当使用PHP里的函数 file_get_contents() 来获取API里提供的数据时,出现错误,使用的代码是这样的:

<?php
$data = file_get_contents("https://www.liqingbo.cn/son?print=pretty");
......
当运行上面的代码是遇到下面的错误提示:


PHP Warning:  file_get_contents(): Unable to find the wrapper "https" - did you forget to enable it when you configured PHP?


为什么会出现这样的错误?

在网上经过一番搜索,发现遇到这样错误的人还不少,问题很直接,是因为在PHP的配置文件里没有开启一个参数,在我本机上是 /apache/bin/php.ini 里的 ;extension=php_openssl.dll 这一项,需要将前面的分号去掉。你可以用下面的脚本来检查你的PHP环境的配置:


$w = stream_get_wrappers();
echo 'openssl: ',  extension_loaded  ('openssl') ? 'yes':'no', "\n";
echo 'http wrapper: ', in_array('http', $w) ? 'yes':'no', "\n";
echo 'https wrapper: ', in_array('https', $w) ? 'yes':'no', "\n";
echo 'wrappers: ', var_dump($w);

运行上面的这个脚本片段,在我的机器上得到的结果是:


openssl: no
http wrapper: yes
https wrapper: no
wrappers: array(10) {
  [0]=>
  string(3) "php"
  [1]=>
  string(4) "file"
  [2]=>
  string(4) "glob"
  [3]=>
  string(4) "data"
  [4]=>
  string(4) "http"
  [5]=>
  string(3) "ftp"
  [6]=>
  string(3) "zip"
  [7]=>
  string(13) "compress.zlib"
  [8]=>
  string(14) "compress.bzip2"
  [9]=>
  string(4) "phar"
}

替代方案

发现错误,改正错误,这很简单,困难的是,发现错误后无法改正错误。我原本是想将这个脚本方法远程主机上,但我无法修改远程主机的PHP配置,结果是,我无法使用这一方案,但我们不能在一棵树上吊死,这条路走不通,看看有没有其它路。

另外一个我经常用的PHP里抓取内容的函数是 curl ,它比 file_get_contents() 更强大,提供了很多的可选参数。对于访问 HTTPS 内容的问题,我们需要使用的 CURL 配置参数是:

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);

你可以从语义上看出,它是忽略/跳过了SSL安全验证。也许这不是一个很好的做法,但对于普通的场景中,这几经足够了。

下面是利用 Curl 封装的一个能访问HTTPS内容的函数:


function getHTTPS($url) {
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  curl_setopt($ch, CURLOPT_HEADER, false);
  curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_REFERER, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  $result = curl_exec($ch);
  curl_close($ch);
  return $result;
}

[!--infotagslink--]

相关文章

  • 源码分析系列之json_encode()如何转化一个对象

    这篇文章主要介绍了源码分析系列之json_encode()如何转化一个对象,对json_encode()感兴趣的同学,可以参考下...2021-04-22
  • php中去除文字内容中所有html代码

    PHP去除html、css样式、js格式的方法很多,但发现,它们基本都有一个弊端:空格往往清除不了 经过不断的研究,最终找到了一个理想的去除html包括空格css样式、js 的PHP函数。...2013-08-02
  • PHP编译安装后PHP-FPM使用笔记

    PHP-FPM我们相信各位用高版本的php经常使用到了,下面整理了一些关于PHP-FPM的笔记,有兴趣的可进来看看。 今天赶上了123System OPenVZ VPS全场半价的机会,购入了一...2016-11-25
  • index.php怎么打开?如何打开index.php?

    index.php怎么打开?初学者可能不知道如何打开index.php,不会的同学可以参考一下本篇教程 打开编辑:右键->打开方式->经文本方式打开打开运行:首先你要有个支持运行PH...2017-07-06
  • php-fpm 启动报please specify user and group other than root, pool ‘default’

    本文章来给大家介绍关于php-fpm 启动报please specify user and group other than root, pool ‘default’的解决办法。 安装PHP ,配置fpm 成功后启动发现报错: St...2016-11-25
  • MYSQL事务回滚的2个问题分析

    因此,正确的原子操作是真正被执行过的。是物理执行。在当前事务中确实能看到插入的记录。最后只不过删除了。但是AUTO_INCREMENT不会应删除而改变值。1、为什么auto_increament没有回滚?因为innodb的auto_increament的...2014-05-31
  • PHP中func_get_args(),func_get_arg(),func_num_args()的区别

    复制代码 代码如下:<?php function jb51(){ print_r(func_get_args()); echo "<br>"; echo func_get_arg(1); echo "<br>"; echo func_num_args(); } jb51("www","j...2013-10-04
  • PHP编程 SSO详细介绍及简单实例

    这篇文章主要介绍了PHP编程 SSO详细介绍及简单实例的相关资料,这里介绍了三种模式跨子域单点登陆、完全跨单点域登陆、站群共享身份认证,需要的朋友可以参考下...2017-01-25
  • PHP实现创建以太坊钱包转账等功能

    这篇文章主要介绍了PHP实现创建以太坊钱包转账等功能,对以太坊感兴趣的同学,可以参考下...2021-04-20
  • Mysql索引会失效的几种情况分析

    索引并不是时时都会生效的,比如以下几种情况,将导致索引失效: 1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)  注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引 ...2014-06-07
  • php微信公众账号开发之五个坑(二)

    这篇文章主要为大家详细介绍了php微信公众账号开发之五个坑,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2016-10-02
  • ThinkPHP使用心得分享-ThinkPHP + Ajax 实现2级联动下拉菜单

    首先是数据库的设计。分类表叫cate.我做的是分类数据的二级联动,数据需要的字段有:id,name(中文名),pid(父id). 父id的设置: 若数据没有上一级,则父id为0,若有上级,则父id为上一级的id。数据库有内容后,就可以开始写代码,进...2014-05-31
  • PHP如何通过date() 函数格式化显示时间

    这篇文章主要介绍了PHP如何通过date() 函数格式化显示时间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-11-13
  • PHP+jQuery+Ajax实现多图片上传效果

    今天我给大家分享的是在不刷新页面的前提下,使用PHP+jQuery+Ajax实现多图片上传的效果。用户只需要点击选择要上传的图片,然后图片自动上传到服务器上并展示在页面上。...2015-03-15
  • python 爬取京东指定商品评论并进行情感分析

    本文主要讲述了利用Python网络爬虫对指定京东商城中指定商品下的用户评论进行爬取,对数据预处理操作后进行文本情感分析,感兴趣的朋友可以了解下...2021-05-28
  • Underscore源码分析

    Underscore 是一个 JavaScript 工具库,它提供了一整套函数式编程的实用功能,但是没有扩展任何 JavaScript 内置对象。这篇文章主要介绍了underscore源码分析相关知识,感兴趣的朋友一起学习吧...2016-01-02
  • golang与php实现计算两个经纬度之间距离的方法

    这篇文章主要介绍了golang与php实现计算两个经纬度之间距离的方法,结合实例形式对比分析了Go语言与php进行经纬度计算的相关数学运算技巧,需要的朋友可以参考下...2016-07-29
  • PHP如何使用cURL实现Get和Post请求

    这篇文章主要介绍了PHP如何使用cURL实现Get和Post请求,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-07-11
  • 谈谈PHP中相对路径的问题与绝对路径的使用

    经常看到有人踩在了PHP路径的坑上面了,感觉有必要来说说PHP中相对路径的一些坑,以及PHP中绝对路径的使用,下面一起来看看。 ...2016-08-24
  • thinkPHP中多维数组的遍历方法

    这篇文章主要介绍了thinkPHP中多维数组的遍历方法,以简单实例形式分析了thinkPHP中foreach语句的使用技巧,需要的朋友可以参考下...2016-01-12