php 对象的操作符,平滑升级你的PHP到5.6.0,及更新代码示例说明

本文介绍了如何平滑升级PHP至5.6.0,强调了升级过程无需宕机或关闭网站,并详细解释了升级过程中遇到的PHP扩展与新内核不兼容的问题及其解决方案。通过重新编译扩展和调整php.ini配置解决了问题。此外,还提到了PHP5.6.0引入的新特性如常量标量表达式、可变参数函数等。
摘要由CSDN通过智能技术生成

这里说下,一开始发表的是编译升级到php5.5.0,可是后来我发现了config.nice之后,就补充了一篇更简单的升级办法,就是后来的PHP5.4的升级

那为什么今天要补充一篇平滑升级到5.6.0呢,因为今天我升级的时候碰到了几个小问题,具体细节,下面会详细说明

在这之前我想说下,这次的升级是平滑升级。群里以及在网上看到不少朋友有类似这样的顾虑

[success]为什么PHP更新这么频繁?更新是不是要重启服务?我是不是要关闭网站?[/success]

这里我稍微总结几点:

既然是平滑升级,是不需要宕机,也不需要停止服务,是不存在关闭网站的说法

而升级最后的重启,重启的是PHP加载的配置文件,不影响你当前运行的网站

php-fpm是属于FastCgi,一旦启动是在内存中跑的,和你编译升级的过程没有任何关系

[success]

你可以从这篇文章了解什么是FastCgi

什么是CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI?

http://levi.yii.so/archives/1068

[/success]

但是不是说平滑升级了,就没有问题了,他最大的一个问题在于:升级PHP后,和你当前项目存在不兼容的部分。

一般而言PHP每次升级,不会和上一个版本出现较明显的不兼容,如果你的项目也一直在更新,可以不用当心。

然而如果你的项目非常老旧,我建议可以在每个大项目做一次更新,比如PHP5.4-PHP5.5、PHP5.5-PHP5.6,一般这样的版本更新至少也要间隔1年左右的时间了

[success]

我不建议长期守着较旧的版本,或者来个飞跃比较大的更新,往往这样才会出现大问题。当然,你可以根据自己习惯来决定何时更新。

[/success]

平滑升级PHP

OK,聊到这里说回正题,之前的文章有提到,平滑升级PHP非常简单,只要如下操作即可,并且我这次的升级也是如此照做

wget http://am1.php.net/get/php-5.6.0.tar.gz/from/this/mirror

tar -zvxf mirror

cp php-5.5.16/config.nice php-5.6.0/

cd php-5.6.0/

./config.nice

make ZEND_EXTRA_LIBS='-liconv'

make install

# 更新后会看到提示几个建议的操作

/root/php-5.6.0/build/shtool install -c ext/phar/phar.phar /usr/local/webserver/php-d/php-5.5.0/bin

ln -s -f /usr/local/webserver/php-d/php-5.5.0/bin/phar.phar /usr/local/webserver/php-d/php-5.5.0/bin/phar

/usr/local/webserver/php-d/php-5.5.0/bin/pecl php-ini /usr/local/webserver/php-d/php-5.5.0/etc/php.ini

一切顺利,拷贝一个PHP执行文件到启动目录,查看下当前版本

ln -f /usr/local/webservice/php-d/php/php-5.5.0/bin/php /etc/init.d/

service php -v

[success]我之前安装PHP的时候,由于安装目录位置在php-5.5.0,所以现在平滑升级也是在这个目录,大家下面看到这个目录嫑觉得奇怪[/success]

问题出现了,如下

Zend OPcache requires Zend Engine API version 220121212.

The Zend Engine API version 220131226 which is installed, is newer.

Contact Zend Technologies at http://www.zend.com/ for a later version of Zend OPcache.

PHP Warning: PHP Startup: imagick: Unable to initialize module

Module compiled with module API=20121212

PHP compiled with module API=20131226

These options need to match

in Unknown on line 0

PHP Warning: PHP Startup: memcache: Unable to initialize module

Module compiled with module API=20121212

PHP compiled with module API=20131226

These options need to match

in Unknown on line 0

PHP Warning: PHP Startup: pdo_mysql: Unable to initialize module

Module compiled with module API=20121212

PHP compiled with module API=20131226

These options need to match

in Unknown on line 0

PHP Warning: PHP Startup: redis: Unable to initialize module

Module compiled with module API=20121212

PHP compiled with module API=20131226

These options need to match

in Unknown on line 0

PHP 5.6.0 (cli) (built: Aug 30 2014 11:03:17)

Copyright (c) 1997-2014 The PHP Group

Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies

从提示上去理解很容易,PHP编译的扩展的内核和当前PHP内核不一致,那就说重新编译下扩展即可。

[success]处于好奇,我在网上搜了下,见到不少朋友的奇葩方法,比如把PHP重装回去,这里就不推荐了。[/success]

重新编译扩展

具体方法之前已提到过了,大家可以[点击这里查看查看详细文档],这里我就只用imagick来举例,代码如下:

wget http://pecl.php.net/get/imagick-3.1.2.tgz

tar -xvzf imagick-3.1.2.tgz

cd imagick-3.1.2

/usr/local/webserver/php-d/php-5.5.0/bin/phpize

export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/

./configure --with-php-config=/usr/local/webserver/php-d/php-5.5.0/bin/php-config

make

make install

当然你也可以直接使用pecl安装扩展,更简单

/usr/local/webserver/php-d/php-5.5.0/bin/pecl uninstall imagick

/usr/local/webserver/php-d/php-5.5.0/bin/pecl install imagick

OK,到这里算完事了吗?没有哦,执行下PHP文件,还是会有上面内核不对的错误,这是为什么呢?而在网上搜了一大圈,大致就两种回答:

重新安装旧版本,使其对应内核

重新编译扩展

第一条我是肯定不会去做的,否则我升级的意义呢?重新编译扩展我是做了,难道有什么不对的吗?无意间,我想到这么一个问题。

我的PHP是正常升级了,扩展也更新了

那说明一切正常,但是执行PHP后,还是说我内核不对

说明php.ini可能配置不正常

打开php.ini,排查后,我发现是内核加载目录路径错了,需要重新修改为当前内核路径,如下:

# 修改扩展目录位置

extension_dir = "/usr/local/webserver/php-d/php-5.5.0/lib/php/extensions/no-debug-non-zts-20131226/"

# 修改opcache目录位置

zend_extension=/usr/local/webserver/php-d/php-5.5.0/lib/php/extensions/no-debug-non-zts-20131226/opcache.so

再执行下PHP试试,一切正常,重启PHP-FPM

service php -v

Zend OPcache requires Zend Engine API version 220121212.

The Zend Engine API version 220131226 which is installed, is newer.

Contact Zend Technologies at http://www.zend.com/ for a later version of Zend OPcache.

PHP 5.6.0 (cli) (built: Aug 30 2014 11:03:17)

Copyright (c) 1997-2014 The PHP Group

Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies

service php-fpm restart

[success]注意,直到这一步,我才重启PHP-FPM哦![/success]

关于如何配置opcache,以及配置php-fpm,请参考这篇文章,这里不再赘述

http://levi.yii.so/archives/2987

PHP 5.6.0 有哪些更新

在网上搜过,只言片语比较少,我这里结合PHP官网给出的实例,做个简单说明

常量标量表达式

const ONE = 1;

const TWO = ONE * 2;

class C {

const THREE = TWO + 1;

const ONE_THIRD = ONE / self::THREE;

const SENTENCE = 'The value of THREE is '.self::THREE;

public function f($a = ONE + self::THREE) {

return $a;

}

}

echo (new C)->f()."n";

echo C::SENTENCE;

?>

以上例程会输出:

4

The value of THREE is 3

操作符实现可变参数函数

function f($req, $opt = null, ...$params) {

// $params is an array containing the remaining arguments.

printf('$req: %d; $opt: %d; number of params: %d'."n",

$req, $opt, count($params));

}

f(1);

f(1, 2);

f(1, 2, 3);

f(1, 2, 3, 4);

f(1, 2, 3, 4, 5);

?>

以上例程会输出:

$req: 1; $opt: 0; number of params: 0

$req: 1; $opt: 2; number of params: 0

$req: 1; $opt: 2; number of params: 1

$req: 1; $opt: 2; number of params: 2

$req: 1; $opt: 2; number of params: 3

参数解包功能

function add($a, $b, $c) {

return $a + $b + $c;

}

$operators = [2, 3];

echo add(1, ...$operators);

?>

以上例程会输出:

6

使用**操作符计算乘方

printf("2 ** 3 == %dn", 2 ** 3);

printf("2 ** 3 ** 2 == %dn", 2 ** 3 ** 2);

$a = 2;

$a **= 3;

printf("a == %dn", $a);

?>

以上例程会输出:

2 ** 3 == 8

2 ** 3 ** 2 == 512

a == 8

使用use关键字导入函数和常量

namespace NameSpace {

const FOO = 42;

function f() { echo __FUNCTION__."n"; }

}

namespace {

use const NameSpaceFOO;

use function NameSpacef;

echo FOO."n";

f();

}

?>

以上例程会输出:

42

NameSpacef

交互式的PHP调试器phpdbg

这里不做详细说明,点击查看官方文档 >

默认字符编码

在 php.ini 中通过 default_charset 设置默认编码

GMP对象支持操作符重载

$a = gmp_init(42);

$b = gmp_init(17);

// Pre-5.6 code:

var_dump(gmp_add($a, $b));

var_dump(gmp_add($a, 17));

var_dump(gmp_add(42, $b));

// New code:

var_dump($a + $b);

var_dump($a + 17);

var_dump(42 + $b);

?>

字符串安全比较

$expected = crypt('12345', '$2a$07$usesomesillystringforsalt$');

$correct = crypt('12345', '$2a$07$usesomesillystringforsalt$');

$incorrect = crypt('1234', '$2a$07$usesomesillystringforsalt$');

var_dump(hash_equals($expected, $correct));

var_dump(hash_equals($expected, $incorrect));

?>

以上例程会输出:

bool(true)

bool(false)

新增魔术方法__debugInfo(),便于调试

class C {

private $prop;

public function __construct($val) {

$this->prop = $val;

}

public function __debugInfo() {

return [

'propSquared' => $this->prop ** 2,

];

}

}

var_dump(new C(42));

?>

以上例程会输出:

object(C)#1 (1) {

["propSquared"]=>

int(1764)

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值