0%

零落成泥碾作尘,只有香如故。

创建工程

执行命令:

1
scrapy startproject xici

新建爬虫

进入到xici目录执行命令

1
scrapy genspider aixici www.xicidaili.com

编写items

1
2
3
4
5
6
7
8
9
10
11
import scrapy

class XiciItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
ip = scrapy.Field()
port = scrapy.Field()
possion = scrapy.Field()
type = scrapy.Field()
speed = scrapy.Field()
last_time = scrapy.Field()

编写爬虫

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# -*- coding: utf-8 -*-
import scrapy
from xici.items import XiciItem

class AixiciSpider(scrapy.Spider):
name = "aixici"
allowed_domains = ["www.xicidaili.com"]
start_urls = ['http://www.xicidaili.com/']

def start_requests(self):
reqs = []
for i in range(1,10):
req = scrapy.Request('http://www.xicidaili.com/nn/%s'%i)
reqs.append(req)

return reqs

def parse(self, response):
ip_list = response.xpath('//*[@id="ip_list"]')
trs = ip_list[0].xpath('tr')
items = []
for ip in trs[1:]:
pre_item = XiciItem()
pre_item['ip'] = ip.xpath('td[2]/text()')[0].extract()
pre_item['port'] = ip.xpath('td[3]/text()')[0].extract()
pre_item['possion'] = ip.xpath('td[4]')[0].extract().strip()
pre_item['type'] = ip.xpath('td[6]/text()')[0].extract()
pre_item['speed'] = ip.xpath('td[7]/div[@class="bar"]/@title').re('\d{0,2}\.\d{0,}')[0]
pre_item['last_time'] = ip.xpath('td[10]/text()')[0].extract()
items.append(pre_item)
return items

运行爬虫

1
scrapy crawl aixici -o item.json

一想到时光匆匆,竟经不起半点挥霍,我就会对时间吝啬起来,因为此刻已过,便永不复还。

实例一

使用foreach修改数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
protected static function packedData($data, $key, $type = 'delete')
{
// 删除data中的必要数据
if ($type == 'update') {
foreach ($data as &$order) {
unset($order['useragent']);
unset($order['ad_id']);
unset($order['ad_channel']);
unset($order['ad_url']);
unset($order['ad_referer']);
unset($order['ad_referer_host']);
unset($order['ad_url_param']);
unset($order['utm_source']);
unset($order['utm_medium']);
unset($order['utm_term']);
unset($order['utm_content']);
unset($order['utm_campaign']);
}
}
return [
'key' => $key,
'data' => $data
];
}

实例二

在没有返回值的情况下修改数组中的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Route::get('hehe', function () {
$datas = [1,2,3,4];
haha($datas);
dump($datas);
});

function haha(&$datas)
{
foreach ($datas as $data) {
$data = $data * 2;
}
return $datas;
}

山家除夕无他事,插了梅花便过年
http缓存一直有在用,也听前辈讲过,今天打算自己总结一下,把不同情况都试了一遍,发现网上有些内容并不全对。

首先,我们知道,浏览器缓存后,在浏览器的network中看到的状态码分两种情况,304和200 OK from cache

304

304是协商缓存,表示请求了服务器,但是内容没有变化,从浏览器本地缓存取数据

304 是通过按浏览器上的刷新按钮或者按F5刷新得到的状态码

从下图可以看到,headers中有etag属性,etag是资源的唯一标识,如果内容变了,etag会改变

Last-Modified 也是用于协商缓存的Last-Modified的值表示内容最后修改时间

浏览器请求已经缓存的资源时,会把etag和Last-Modified发送给服务器,服务器对比,如果浏览器发送来的和服务器的值相等,说明内容没有变化,服务器返回304给浏览器,浏览器从缓存读取数据

200 OK from cache

200 OK from cache 表示浏览器没有发出网络请求,直接取的本地缓存

200 OK from cache 是通过在地址栏回车得到的状态码

如下图,没有etag属性。etag是服务器计算出来的唯一值,因为没有请求服务器,所以也不会有etag标识

expires、Cache-Control

expires 表示过期日期,是绝对值。适用于http1.0协议

Cache-Control 表示缓存的时间,是相对值,比如3600,表示3600秒后失效。适用于http1.1及以上

如有expires和Cache-Control 同时存在,Cache-Control优先级更高

Cache-Control: no-cache:这个很容易让人产生误解,使人误以为是响应不被缓存。实际上Cache-Control: no-cache是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性。

Cache-Control: no-store:这个才是响应不被缓存的意思。

Pragma: no-cache:跟Cache-Control: no-cache相同,Pragma: no-cache兼容http 1.0 ,Cache-Control: no-cache是http 1.1提供的。

以大部分人努力程度之低,根本轮不到去拼天赋
MySQL的sql_mode合理设置 sql_mode是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入。在生产环境必须将这个值设置为严格模式,所以开发、测试环境的数据库也必须要设置,这样在开发测试阶段就可以发现问题

sql_mode常用值如下:
ONLY_FULL_GROUP_BY:
对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中

NO_AUTO_VALUE_ON_ZERO:
该值影响自增长列的插入。默认设置下,插入0或NULL代表生成下一个自增长值。如果用户 希望插入的值为0,而该列又是自增长的,那么这个选项就有用了。

STRICT_TRANS_TABLES:
在该模式下,如果一个值不能插入到一个事务表中,则中断当前的操作,对非事务表不做限制
NO_ZERO_IN_DATE:
在严格模式下,不允许日期和月份为零

NO_ZERO_DATE:
设置该值,mysql数据库不允许插入零日期,插入零日期会抛出错误而不是警告。

ERROR_FOR_DIVISION_BY_ZERO:
在INSERT或UPDATE过程中,如果数据被零除,则产生错误而非警告。如 果未给出该模式,那么数据被零除时MySQL返回NULL

NO_AUTO_CREATE_USER:
禁止GRANT创建密码为空的用户

NO_ENGINE_SUBSTITUTION:
如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常

PIPES_AS_CONCAT:
将”||”视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似

ANSI_QUOTES:
启用ANSI_QUOTES后,不能用双引号来引用字符串,因为它被解释为识别符

ORACLE的sql_mode设置等同:PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, NO_KEY_OPTIONS, NO_TABLE_OPTIONS, NO_FIELD_OPTIONS, NO_AUTO_CREATE_USER.

http://blog.csdn.net/wyzxg/article/details/8787878

虎豹只会独处,牛羊才会成群。
在使用MySQL 5.7版本时,因为SQL_MODE的改变而导致的问题,究其原因都是因为MySQL 5.7控制的更加严格了,所以在MySQL 5.6或MySQL 5.5有些SQL语句就无法在MySQL 5.7执行。

简介

查询当前SQL_MODE
v 5.5.3

1
2
select @@sql_mode;
// NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

v 5.7.21

1
2
select @@sql_mode;
// ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

参数意思

  • ONLY_FULL_GROUP_BY
    在严格模式下,不要让GROUP BY部分中的查询指向未选择的列,否则报错。

  • NO_ZERO_DATE
    在严格模式,不要将’0000-00-00’做为合法日期。你仍然可以用IGNORE选项插入零日期。在非严格模式,可以接受该日期,但会生成警告。

  • NO_ZERO_IN_DATE
    在严格模式,不接受月或日部分为0的日期,对年不限制。如果使用IGNORE选项,我们为类似的日期插入’0000-00-00’。在非严格模式,可以接受该日期,但会生成警告。

  • ERROR_FOR_DIVISION_BY_ZERO
    在严格模式,在INSERT或UPDATE过程中,如果被零除(或MOD(X,0)),则产生错误(否则为警告)。如果未给出该模式,被零除时MySQL返回NULL。如果用到INSERT IGNORE或UPDATE IGNORE中,MySQL生成被零除警告,但操作结果为NULL。

  • NO_AUTO_CREATE_USER
    在严格模式下,防止GRANT自动创建新用户,除非还指定了密码。

  • NO_ENGINE_SUBSTITUTION
    如果需要的存储引擎被禁用或未编译,可以防止自动替换存储引擎。

  • STRICT_TRANS_TABLES
    为事务存储引擎启用严格模式,也可能为非事务存储引擎启用严格模式,非法数据值被拒绝,下面有详细说明。
    严格模式控制MySQL如何处理非法或丢失的输入值。有几种原因可以使一个值为非法。例如,数据类型错误,不适合列,或超出范围。当新插入的行不包含某列的没有显示定义DEFAULT子句的值,则该值被丢失。
    对于事务表,当启用STRICT_ALL_TABLES或STRICT_TRANS_TABLES模式时,如果语句中有非法或丢失值,则会出现错误。语句被放弃并滚动。
    对于非事务表,如果插入或更新的第1行出现坏值,两种模式的行为相同。语句被放弃,表保持不变。如果语句插入或修改多行,并且坏值出现在第2或后面的行,结果取决于启用了哪个严格选项:
    对于STRICT_ALL_TABLES,MySQL返回错误并忽视剩余的行。但是,在这种情况下,前面的行已经被插入或更新。这说明你可以部分更新,这可能不是你想要的。要避免这点,最好使用单行语句,因为这样可以不更改表即可以放弃。
    对于STRICT_TRANS_TABLES,MySQL将非法值转换为最接近该列的合法值并插入调整后的值。如果值丢失,MySQL在列中插入隐式 默认值。在任何情况下,MySQL都会生成警告而不是给出错误并继续执行语句。
    严格模式不允许非法日期,例如’2004-04-31’。它不允许禁止日期使用“零”部分,例如’2004-04-00’或”零”日期。要想禁止,应在严格模式基础上,启用NO_ZERO_IN_DATE和NO_ZERO_DATE SQL模式。
    如果你不使用严格模式(即不启用STRICT_TRANS_TABLES或STRICT_ALL_TABLES模式),对于非法或丢失的值,MySQL将插入调整后的值并给出警告。在严格模式,你可以通过INSERT IGNORE或UPDATE IGNORE来实现。

常见问题

某些GROUP BY的SQL语句无法执行了

这是因为MySQL 5.7默认加入了ONLY_FULL_GROUP_BY参数。在MySQL的sql_mode是非ONLY_FULL_GROUP_BY语义时。一条select语句,MySQL允许target list中输出的表达式是除聚集函数或group by column以外的表达式,这个表达式的值可能在经过group by操作后变成undefined,例如:

1
select * from tt group by id;

而对于语义限制都比较严谨的多家数据库,如SQLServer、Oracle、PostgreSql都不支持select target list中出现语义不明确的列,这样的语句在这些数据库中是会被报错的,所以从MySQL 5.7版本开始修正了这个语义,就是我们所说的ONLY_FULL_GROUP_BY语义。而正确的写法如下:

1
2
select id from tt group by id;
select id,max(age) from tt group by id;

所以ONLY_FULL_GROUP_BY的语义就是确定select target list中的所有列的值都是明确语义,简单的说来,在ONLY_FULL_GROUP_BY模式下,target list中的值要么是来自于聚集函数的结果,要么是来自于group by list中的表达式的值。

创建表时使用日期数据类型指定的默认值为0000-00-00时报错

这是因为MySQL 5.7默认加入了NO_ZERO_DATE和NO_ZERO_IN_DATE参数。通过上面的介绍,这两个参数还是有些区别的,NO_ZERO_DATE是完全匹配默认值为0000-00-00时才限制,而NO_ZERO_IN_DATE是在匹配到月或日任意为00时限制(对年不限制)。

当数据类型为date或datetime时,并且使用了NO_ZERO_IN_DATE限制,那么会有如下几种情况:

1
2
3
4
5
6
7
8
9
10
11
# 不合法默认值;
CREATE TABLE `test` (`time` datetime NOT NULL DEFAULT '1111-00-01 00:00:00'
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

# 合法默认值;
CREATE TABLE `test` (`time` datetime NOT NULL DEFAULT '1111-01-01 00:00:00'
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

# 合法默认值;
CREATE TABLE `test` (`time` datetime NOT NULL DEFAULT '0000-01-01 00:00:00'
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

timestamp类型取值范围:1970-01-01 00:00:00到2037-12-31 23:59:59。也就是说默认值最少需要调整为1970-01-02 00:00:00。

1
2
3
4
5
6
7
CREATE TABLE `test` (
`mid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`start_time` timestamp NOT NULL DEFAULT '1970-01-02 00:00:00',
`end_time` timestamp NOT NULL DEFAULT '2037-12-31 23:59:59',
PRIMARY KEY (`mid`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

最大值或最小值在timestamp合法范围内才行。网上大概看了看,部分人碰到这个问题都是数据库升级的时候,老的表结构无法在MySQL 5.7应用了。如果想调整SQL模式,直接在配置文件写入sql_mode参数跟上对应的模式参数即可。

修改字段类型小于小于最长字段时报错

当启用严格模式时”STRICT_TRANS_TABLES或STRICT_ALL_TABLES”时,控制MySQL如何处理非法或丢失的输入值。有几种原因可以使一个值为非法。例如,数据类型错误,不适合列,或超出范围。当新插入的行不包含某列的没有显示定义DEFAULT子句的值,则该值被丢失。

1
2
3
4
5
6
7
mysql> select * from dd;
+--------------------------------+
| log |
+--------------------------------+
| 一二三四五六七八九十 |
+--------------------------------+
1 row in set (0.00 sec)
1
2
3
4
5
6
7
8
9
10
11
12
mysql> set sql_mode='STRICT_TRANS_TABLES';
Query OK, 0 rows affected (0.00 sec)

mysql> alter table dd change column log log varchar(9);
ERROR 1265 (01000): Data truncated for column 'log' at row 1

mysql> set sql_mode='';
Query OK, 0 rows affected (0.00 sec)

mysql> alter table dd change column log log varchar(9);
Query OK, 1 row affected, 1 warning (0.02 sec)
Records: 1 Duplicates: 0 Warnings: 1
1
2
3
4
5
6
7
MariaDB [dkey]> select * from dd;                               
+-----------------------------+
| log |
+-----------------------------+
| 一二三四五六七八九 |
+-----------------------------+
1 row in set (0.00 sec)

可以看到非严格模式,默认把多余数据给截断了。

http://www.ywnds.com/?p=8865

我在这里准备了一百口棺材,九十九口留给贪官,一口留给自己。

问题引出

看下面这个代码片段的结果

1
2
$res1 = 0.07 * 100 == 7;
dump($res1); // false

结果竟然是 false
这个和电脑中存储小数的原理有关。大家都知道计算机只能存储0和1,我们日常生活习惯使用的是10进制的数据,像0.07这个小数在计算机中存储时会有精度损失.

问题解决

1
2
$res2 = bcmul(0.07, 100) == 7;
dump($res2); // true

BC 数学 函数
● bcadd — 2个任意精度数字的加法计算
● bccomp — 比较两个任意精度的数字
● bcdiv — 2个任意精度的数字除法计算
● bcmod — 对一个任意精度数字取模
● bcmul — 2个任意精度数字乘法计算
● bcpow — 任意精度数字的乘方
● bcpowmod — Raise an arbitrary precision number to another, reduced by a specified modulus
● bcscale — 设置所有bc数学函数的默认小数点保留位数
● bcsqrt — 任意精度数字的二次方根
● bcsub — 2个任意精度数字的减法

实例

1
2
3
4
5
6
<?php
$re = intval(18.99*100)/100;
echo $re;
echo "<br>";
$gg = bcdiv(bcmul('18.99','100'), '100',2);
echo $gg;

http://php.net/manual/zh/book.bc.php

啊 这瞌睡 这瞌睡像十除以三

函数

1
2
3
4
5
6
7
8
9
10
11
function trace_sql($dump = false)
{
DB::listen(function ($event) use($dump) {
if ($dump) {
dump($event->sql);
dump($event->bindings);
}
Log::info($event->sql);
Log::info($event->bindings);
});
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
public function index()
{
trace_sql();
$query = Order::query();
//$query->whereBetween('updated_at',[Carbon::today(), Carbon::tomorrow()]);
$query->whereHas('incomeExpenditure', function ($query) {
$query->whereBetween('created_at',[Carbon::today(), Carbon::tomorrow()])->where('value', '>', 0);
});
$orders = $query->where('status', 'paid')->with('products')->orderBy('updated_at', 'desc')->paginate(1000);
$datas = $this->todayStatistics();
return view('home.index', ['orders' => $orders, 'datas' => $datas]);
}

有些人让你对明天充满期许,却再也没有出现在你的明天里。
### apache的配置 使用 Apache 模拟出两个站点,分别使用8081和8082端口 访问: http://121.42.176.99:8081/ http://121.42.176.99:8082/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Listen 8081
<VirtualHost *:8081>
ServerAdmin webmaster@dummy-host2.example.com
DocumentRoot "/usr/local/httpd/htdocs/test"
DirectoryIndex index.html index.php
ServerName 127.0.0.1
ErrorLog "logs/dummy-host2.example.com-error_log"
CustomLog "logs/dummy-host2.example.com-access_log" common
</VirtualHost>
<Directory "/usr/local/httpd/htdocs/test">
Options FollowSymLinks
AllowOverride all
allow from all
Require all granted
</Directory>
Listen 8082
<VirtualHost *:8082>
ServerAdmin webmaster@dummy-host2.example.com
DocumentRoot "/usr/local/httpd/htdocs/test1"
DirectoryIndex index.html index.php
ServerName 127.0.0.1
ErrorLog "logs/dummy-host2.example.com-error_log"
CustomLog "logs/dummy-host2.example.com-access_log" common
</VirtualHost>
<Directory "/usr/local/httpd/htdocs/test">
Options FollowSymLinks
AllowOverride all
allow from all
Require all granted
</Directory>
网站的内容index.php 打印出服务器变量: var_export($_SERVER);

反向代理nginx

nginx 默认使用80端口,http://121.42.176.99/
配置:

1
2
3
location / {
proxy_passs http://localhost:8081
}

之后重启nginx
这时候访问http://121.42.176.99/,就会访问的是apache的8081端口

问题

我们发现获取到的服务器信息不正确:
1、HTTP_HOST:localhost:8081
2、REMOTE_ADDR:127.0.0.1 (客户端的IP)
这会对我们的开发造成“迷茫”,因此要在nginx配置里加入
1、proxy_set_header Host $host;
2、proxy_set_header X-Real-IP $remote_addr;

其他的一些设置请google;

等一个不爱你的人,就像在机场等一艘船

安装环境

  • CentOS 6.8 64
  • MySQL 5.7.17

安装过程

  • CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)
    yum install cmake -y

  • 安装编译器
    yum install gcc gcc-c++ -y

  • 安装图像函数库
    yum install ncurses ncurses-devel -y

  • 解压并进入到目录,执行
    cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DSYSCONFDIR=/etc -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DMYSQL_DATADIR=/var/lib/mysql/data -DWITH_BOOST=boost

  • 开始编译
    make
    make install

编译完成

  • 增加一个mysql用户(useradd mysql -M -s /sbin/nologin)
  • 配置文件位置(/etc/my.cnf)
  • 初始化(mysqld –initialize –user=mysql –basedir=/var/lib/mysql –datadir=/var/lib/mysql/data)

问题

Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)
解决方案:
在mysql的配置文件中加入

1
2
[mysql]
socket=/var/lib/mysql/mysql.sock

多赚钱,离傻逼们远一点

Apache

  • 先从官方网站下载php7,并且解压

    1
    2
    wget http://am1.php.net/get/php-7.0.0.tar.gz/from/this/mirror
    tar zvxf php-7.0.0.tar.gz# cd php-7.0.0
  • 接下来要进行编译前的配置,需要提供apxs参数

    1
    /configure --prefix=/usr/local/php7 \--with-config-file-path=/usr/local/php7/etc \--with-config-file-scan-dir=/usr/local/php7/etc/php.d \--with-apxs2=/usr/local/apache/bin/apxs \--with-mcrypt=/usr/include \--enable-mysqlnd \--with-mysqli \--with-pdo-mysql \--with-gd \--with-iconv \--with-zlib \--enable-xml \--enable-shmop \--enable-sysvsem \--enable-inline-optimization \--enable-mbregex \--enable-mbstring \--enable-ftp \--enable-gd-native-ttf \--with-openssl \--enable-pcntl \--enable-sockets \--with-xmlrpc \--enable-zip \--enable-soap \--without-pear \--with-gettext \--enable-session \--with-curl \--with-jpeg-dir \--with-freetype-dir \--enable-opcache

    注意配置--prefix 安装文件位置, --with-config-file-path 配置文件位置, --with-apxs2整合apache,

  • 编译

    1
    2
    make
    make install
  • 配置apache
    如果上面的编译安装正常,由于我们配置了apxs选项,所以在编译的时候,make会对apache的apxs进行调用操作,结果就是在apache的安装目录下的modules目录下生成libphp7.so,并在apache的配置文件httpd.conf中增加一行

    1
    2
    3
    4
    5
    LoadModule php7_module        modules/libphp7.so
    ```一看就明白了,就是让apache去加载一个新的libphp7.so模块。但是我们仍然要对`httpd.conf`进行修改,重新配置apache。找到LoadModule php,你会发现,竟然出现了两行LoadModule,同时加载了php5和php7,如下:
    ```php
    LoadModule php5_module modules/libphp5.so
    LoadModule php7_module modules/libphp7.so

    我们把第一行给注释掉,而且还要增加一个PHPIniDir的配置项,即修改为如下:

    1
    2
    3
    #LoadModule php5_module        modules/libphp5.so
    LoadModule php7_module modules/libphp7.so
    PHPIniDir /usr/local/php7/etc

    重启apache,现在可以写一个phpinfo去试试看了。
    或者这样修改配置文件

    1
    2
    3
    Apache不认识xxx.php后缀
    打开Apache配置文件,增加
    AddType application/x-httpd-php .php

Nginx

  • 先从官方网站下载php7,并且解压

    1
    2
    wget http://am1.php.net/get/php-7.0.0.tar.gz/from/this/mirror
    tar zvxf php-7.0.0.tar.gz# cd php-7.0.0
  • 接下来要进行编译前的配置,我们不提供apxs参数,我们提供php-fpm相关参数

    1
    # ./configure --prefix=/usr/local/php7 \--with-config-file-path=/usr/local/php7/etc \--with-config-file-scan-dir=/usr/local/php7/etc/php.d \--with-mcrypt=/usr/include \--enable-mysqlnd \--with-mysqli \--with-pdo-mysql \--enable-fpm \--with-fpm-user=nginx \--with-fpm-group=nginx \--with-gd \--with-iconv \--with-zlib \--enable-xml \--enable-shmop \--enable-sysvsem \--enable-inline-optimization \--enable-mbregex \--enable-mbstring \--enable-ftp \--enable-gd-native-ttf \--with-openssl \--enable-pcntl \--enable-sockets \--with-xmlrpc \--enable-zip \--enable-soap \--without-pear \--with-gettext \--enable-session \--with-curl \--with-jpeg-dir \--with-freetype-dir \--enable-opcache
  • 配置无误后执行

    1
    2
    make
    make install
  • 调整php配置
    默认安装好之后,你会发现/usr/local/php7/etc下面没有php.ini文件,这个去哪里要呢?在php7的源码安装包都有。

    1
    2
    3
    4
     cd /usr/src/php-7.0.0/# ls
    ```可以看到有两个php.ini-xxx文件,我们可以分别vi打开来看下,一个是产品模式,一个是开发模式。
    ```php
    cp php.ini-production /usr/local/php7/etc/php.ini# vi /usr/local/php7/etc/php.ini
  • 启用php-fpm服务
    上面我们在编译php7的时候,已经将fpm模块编译了,那么接下来,我们要启用php-fpm。但是默认情况下它的配置文件和服务都没有启用,所以要我们自己来搞定。
    搞定配置文件:

    1
    2
    3
    cd /usr/local/php7/etc
    mv php-fpm.conf.default php-fpm.conf
    mv php-fpm.d/www.conf.defualt php-fpm.d/www.conf
  • php-fpm的服务载入
    我们希望使用service php-fpm start|stop|restart这些操作来实现服务的重启,但没有像nginx那么复杂,php编译好之后,给我们提供了一个php-fpm的程序,不需要我再编写分享了。这个文件放在php编译源码目录中:

    1
    2
    3
    4
    5
    6
    cd /usr/src/php-7.0.0/sapi/fpm
    ls
    cp init.d.php-fpm /etc/init.d/php-fpm
    chmod +x /etc/init.d/php-fpm
    chkconfig --add php-fpm#
    chkconfig php-fpm on

    通过上面这个操作,我们就可以使用

    1
    sevice php-fpm start

    来启用php-fpm了。用

    1
    ps -ef | grep php-fpm

    看看进程吧。

  • 查看php版本

    1
    2
    3
    ./bin/php -v


  • nginx代理php实现访问
    php-fpm走的是127.0.0.1:9000,外网是无法访问的,而且我们也不可能直接通过php-fpm给外网提供服务,我们用nginx去代理9000端口执行php。
    我们需要在nginx的配置文件中增加代理的规则,即可让用户在访问80端口,请求php的时候,交由后端的fpm去执行,并返回结果。

    1
    vi /usr/local/nginx/conf/nginx.conf

    那么怎么代理php-fpm呢?

    1
    2
    3
    4
    5
    6
    7
    location ~ \.php$ {
    root html;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /$document_root$fastcgi_script_name;
    include fastcgi_params;
    }

    这样就OK了,重新载入nginx配置即可

    1
    service nginx reload

https://www.tangshuang.net/1774.html