PHP特性整合(PHP5.X到PHP7.1.x)


JavaScript 是支持闭包和 lambda 函数的最常见语言之一。 
在PHP中,我们也可以通过create_function()在代码运行时创建函数。但有一个问题:创建的函数仅在运行时才被编译,而不与其它代码同时被编译成执行码,因此我们无法使用类似APC这样的执行码缓存来提高代码执行效率。 
在PHP5.3中,我们可以使用Lambda/匿名函数来定义一些临时使用(即用即弃型)的函数,以作为array_map()/array_walk()等函数的回调函数。

echo preg_replace_callback('~-([a-z])~', function ($match) {    
    return strtoupper($match[1]);    
}, 'hello-world');    
// 输出 helloWorld    
$greet = function($name)    
{    
    printf("Hello %s\r\n", $name);    
};    
$greet('World');    
$greet('PHP');    
//...在某个类中    
$callback =      function ($quantity, $product) use ($tax, &$total)         {    
   $pricePerItem = constant(__CLASS__ . "::PRICE_" .  strtoupper($product));    
   $total += ($pricePerItem * $quantity) * ($tax + 1.0);    
 };    

Java中的finally一样,经典的try … catch … finally 三段式异常处理。

测试的boolean。

ini_set('assert.exception', 1);
class CustomError extends AssertionError {}
assert(false, new CustomError('Some error message'));

以上例程会输出: 
Fatal error: Uncaught CustomError: Some error message

http://www.laruence.com/2011/10/10/2217.html

http://www.laruence.com/2011/10/10/2204.html

算法。这就需要加密算法,也可以用于对密码哈希。更广泛的说明和用法示例

array_column

//从数据库获取一列,但返回是数组。  
$userNames = [];  
foreach ($users as $user) {  
    $userNames[] = $user['name'];  
}  
//以前获取数组某列值,现在如下  
$userNames = array_column($users, 'name');  

一个简单的密码散列API

$password = "foo";    
// creating the hash    
$hash = password_hash($password, PASSWORD_BCRYPT);    
// verifying a password    
if (password_verify($password, $hash)) {    
    // password correct!    
} else {    
    // password wrong!    
}   

异步信号处理 Asynchronous signal handling

A new function called pcntl_async_signals() has been introduced to enable asynchronous signal handling without using ticks (which introduce a lot of overhead). 
增加了一个新函数 pcntl_async_signals()来处理异步信号,不需要再使用ticks(它会增加占用资源)

pcntl_async_signals(true); // turn on async signals
pcntl_signal(SIGHUP,  function($sig) {
    echo "SIGHUP\n";
});
posix_kill(posix_getpid(), SIGHUP);

以上例程会输出:

SIGHUP

HTTP/2 服务器推送支持 ext/curl

Support for server push has been added to the CURL extension (requires version 7.46 and above). This can be leveraged through the curl_multi_setopt() function with the new CURLMOPT_PUSHFUNCTION constant. The constants CURL_PUST_OK and CURL_PUSH_DENY have also been added so that the execution of the server push callback can either be approved or denied. 
蹩脚英语: 
对于服务器推送支持添加到curl扩展(需要7.46及以上版本)。 
可以通过用新的CURLMOPT_PUSHFUNCTION常量 让curl_multi_setopt()函数使用。 
也增加了常量CURL_PUST_OK和CURL_PUSH_DENY,可以批准或拒绝 服务器推送回调的执行

php.ini中可使用变量

PHP default_charset 默认字符集 为UTF-8

ext/phar、ext/intl、ext/fileinfo、ext/sqlite3和ext/enchant等扩展默认随PHP绑定发布。其中Phar可用于打包PHP程序,类似于Java中的jar机制

PHP7.1不兼容性

1.当传递参数过少时将抛出错误

在过去如果我们调用一个用户定义的函数时,提供的参数不足,那么将会产生一个警告(warning)。 现在,这个警告被提升为一个错误异常(Error exception)。这个变更仅对用户定义的函数生效, 并不包含内置函数。例如:

function test($param){}
test();

输出:

Uncaught Error: Too few arguments to function test(), 0 passed in %s on line %d and exactly 1 expected in %s:%d

2.禁止动态调用函数

禁止动态调用函数如下 
assert() - with a string as the first argument 
compact() 
extract() 
func_get_args() 
func_get_arg() 
func_num_args() 
get_defined_vars() 
mb_parse_str() - with one arg 
parse_str() - with one arg

(function () {
    'func_num_args'();
})();

输出

Warning: Cannot call func_num_args() dynamically in %s on line %d

3.无效的类,接口,trait名称命名

以下名称不能用于 类,接口或trait 名称命名: 
void 
iterable

4.Numerical string conversions now respect scientific notation

Integer operations and conversions on numerical strings now respect scientific notation. This also includes the (int) cast operation, and the following functions: intval() (where the base is 10), settype(), decbin(), decoct(), and dechex().

5.mt_rand 算法修复

mt_rand() will now default to using the fixed version of the Mersenne Twister algorithm. If deterministic output from mt_srand() was relied upon, then the MT_RAND_PHP with the ability to preserve the old (incorrect) implementation via an additional optional second parameter to mt_srand().

6.rand() 别名 mt_rand() 和 srand() 别名 mt_srand()

rand() and srand() have now been made aliases to mt_rand() and mt_srand(), respectively. This means that the output for the following functions have changes: rand(), shuffle(), str_shuffle(), and array_rand().

7.Disallow the ASCII delete control character in identifiers

The ASCII delete control character (0x7F) can no longer be used in identifiers that are not quoted.

8.error_log changes with syslog value

If the error_log ini setting is set to syslog, the PHP error levels are mapped to the syslog error levels. This brings finer differentiation in the error logs in contrary to the previous approach where all the errors are logged with the notice level only.

9.在不完整的对象上不再调用析构方法

析构方法在一个不完整的对象(例如在构造方法中抛出一个异常)上将不再会被调用

10.call_user_func()不再支持对传址的函数的调用

call_user_func() 现在在调用一个以引用作为参数的函数时将始终失败。

11.字符串不再支持空索引操作符 The empty index operator is not supported for strings anymore

对字符串使用一个空索引操作符(例如str[]=x)将会抛出一个致命错误, 而不是静默地将其转为一个数组

12.ini配置项移除

下列ini配置项已经被移除: 
session.entropy_file 
session.entropy_length 
session.hash_function 
session.hash_bits_per_character

PHP7.0 不兼容性

1、foreach不再改变内部数组指针

在PHP7之前,当数组通过 foreach 迭代时,数组指针会移动。现在开始,不再如此,见下面代码。

$array = [0, 1, 2];
foreach ($array as &$val) {
    var_dump(current($array));
}

PHP5输出: 
int(1) 
int(2) 
bool(false) 
PHP7输出: 
int(0) 
int(0) 
int(0)

2、foreach通过引用遍历时,有更好的迭代特性

当使用引用遍历数组时,现在 foreach 在迭代中能更好的跟踪变化。例如,在迭代中添加一个迭代值到数组中,参考下面的代码:

$array = [0];
foreach ($array as &$val) {
    var_dump($val);
    $array[1] = 1;
}

PHP5输出: 
int(0) 
PHP7输出: 
int(0) 
int(1)

3、十六进制字符串不再被认为是数字

含十六进制字符串不再被认为是数字

var_dump("0x123" == "291");
var_dump(is_numeric("0x123"));
var_dump("0xe" + "0x1");
var_dump(substr("foo", "0x1"));

PHP5输出: 
bool(true) 
bool(true) 
int(15) 
string(2) “oo” 
PHP7输出: 
bool(false) 
bool(false) 
int(0) 
Notice: A non well formed numeric value encountered in /tmp/test.php on line 5 
string(3) “foo”

4、PHP7中被移除的函数

被移除的函数列表如下: 
call_user_func() 和 call_user_func_array()从PHP 4.1.0开始被废弃。 
已废弃的 mcrypt_generic_end() 函数已被移除,请使用mcrypt_generic_deinit()代替。 
已废弃的 mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() 和 mcrypt_ofb() 函数已被移除。 
set_magic_quotes_runtime(), 和它的别名 magic_quotes_runtime()已被移除. 它们在PHP 5.3.0中已经被废弃,并且 在in PHP 5.4.0也由于魔术引号的废弃而失去功能。 
已废弃的 set_socket_blocking() 函数已被移除,请使用stream_set_blocking()代替。 
dl()在 PHP-FPM 不再可用,在 CLI 和 embed SAPIs 中仍可用。 
GD库中下列函数被移除:imagepsbbox()、imagepsencodefont()、imagepsextendfont()、imagepsfreefont()、imagepsloadfont()、imagepsslantfont()、imagepstext() 
在配置文件php.ini中,always_populate_raw_post_data、asp_tags、xsl.security_prefs被移除了。

5、new 操作符创建的对象不能以引用方式赋值给变量

new 操作符创建的对象不能以引用方式赋值给变量

class C {}
$c =& new C;

PHP5输出: 
Deprecated: Assigning the return value of new by reference is deprecated in /tmp/test.php on line 3 
PHP7输出: 
Parse error: syntax error, unexpected ‘new’ (T_NEW) in /tmp/test.php on line 3

6、移除了 ASP 和 script PHP 标签

使用类似 ASP 的标签,以及 script 标签来区分 PHP 代码的方式被移除。 受到影响的标签有:<% %>、<%= %>、

7、从不匹配的上下文发起调用

在不匹配的上下文中以静态方式调用非静态方法, 在 PHP 5.6 中已经废弃, 但是在 PHP 7.0 中, 会导致被调用方法中未定义 $this 变量,以及此行为已经废弃的警告。

class A {
    public function test() { var_dump($this); }
}
// 注意:并没有从类 A 继承
class B {
    public function callNonStaticMethodOfA() { A::test(); }
}
(new B)->callNonStaticMethodOfA();

PHP5输出: 
Deprecated: Non-static method A::test() should not be called statically, assuming $this from incompatible context in /tmp/test.php on line 8 
object(B)#1 (0) { 

PHP7输出: 
Deprecated: Non-static method A::test() should not be called statically in /tmp/test.php on line 8 
Notice: Undefined variable: this in /tmp/test.php on line 3 
NULL

8、在数值溢出的时候,内部函数将会失败

将浮点数转换为整数的时候,如果浮点数值太大,导致无法以整数表达的情况下, 在之前的版本中,内部函数会直接将整数截断,并不会引发错误。 在 PHP 7.0 中,如果发生这种情况,会引发 E_WARNING 错误,并且返回 NULL。

9、JSON 扩展已经被 JSOND 取代

JSON 扩展已经被 JSOND 扩展取代。 
对于数值的处理,有以下两点需要注意的: 
第一,数值不能以点号(.)结束 (例如,数值 34. 必须写作 34.0 或 34)。 
第二,如果使用科学计数法表示数值,e 前面必须不是点号(.) (例如,3.e3 必须写作 3.0e3 或 3e3)。

10、INI 文件中 # 注释格式被移除

在配置文件INI文件中,不再支持以 # 开始的注释行, 请使用 ;(分号)来表示注释。 此变更适用于 php.ini 以及用 parse_ini_file() 和 parse_ini_string() 函数来处理的文件。

11、$HTTP_RAW_POST_DATA 被移除

不再提供 $HTTP_RAW_POST_DATA 变量。 请使用 php://input 作为替代。

12、yield 变更为右联接运算符

在使用 yield 关键字的时候,不再需要括号, 并且它变更为右联接操作符,其运算符优先级介于 print 和 => 之间。 这可能导致现有代码的行为发生改变。可以通过使用括号来消除歧义。

echo yield -1;
// 在之前版本中会被解释为:
echo (yield) - 1;
// 现在,它将被解释为:
echo yield (-1);
yield $foo or die;
// 在之前版本中会被解释为:
yield ($foo or die);
// 现在,它将被解释为:
(yield $foo) or die;

PHP 7.1.x 中废弃的特性

1.ext/mcrypt

mcrypt 扩展已经过时了大约10年,并且用起来很复杂。因此它被废弃并且被 OpenSSL 所取代。 从PHP 7.2起它将被从核心代码中移除并且移到PECL中。

2.mb_ereg_replace()和mb_eregi_replace()的Eval选项

对于mb_ereg_replace()和mb_eregi_replace()的 e模式修饰符现在已被废弃

弃用或废除

下面是被弃用或废除的 INI 指令列表. 使用下面任何指令都将导致 错误. 
define_syslog_variables 
register_globals 
register_long_arrays 
safe_mode 
magic_quotes_gpc 
magic_quotes_runtime 
magic_quotes_sybase 
弃用 INI 文件中以 ‘#’ 开头的注释. 
弃用函数: 
call_user_method() (使用 call_user_func() 替代) 
call_user_method_array() (使用 call_user_func_array() 替代) 
define_syslog_variables() 
dl() 
ereg() (使用 preg_match() 替代) 
ereg_replace() (使用 preg_replace() 替代) 
eregi() (使用 preg_match() 配合 ‘i’ 修正符替代) 
eregi_replace() (使用 preg_replace() 配合 ‘i’ 修正符替代) 
set_magic_quotes_runtime() 以及它的别名函数 magic_quotes_runtime() 
session_register() (使用 SESSION)sessionunregister()(使_SESSION 超全部变量替代) 
session_is_registered() (使用 $_SESSION 超全部变量替代) 
set_socket_blocking() (使用 stream_set_blocking() 替代) 
split() (使用 preg_split() 替代) 
spliti() (使用 preg_split() 配合 ‘i’ 修正符替代) 
sql_regcase() 
mysql_db_query() (使用 mysql_select_db() 和 mysql_query() 替代) 
mysql_escape_string() (使用 mysql_real_escape_string() 替代) 
废弃以字符串传递区域设置名称. 使用 LC_* 系列常量替代. 
mktime() 的 is_dst 参数. 使用新的时区处理函数替代. 
弃用的功能: 
弃用通过引用分配 new 的返回值. 
调用时传递引用被弃用. 
已弃用的多个特性 allow_call_time_pass_reference、define_syslog_variables、highlight.bg、register_globals、register_long_arrays、magic_quotes、safe_mode、zend.ze1_compatibility_mode、session.bug_compat42、session.bug_compat_warn 以及 y2k_compliance。

相关