PHP Migrating to 7.0 7.1

2023-08-23 18:51:38 浏览数 (1)

  • 实验环境:https://onlinephp.io/

  • Polyfill https://github.com/symfony/polyfill/tree/main/src

PHP7.0 to PHP7.1

https://www.php.net/manual/en/migration71.php

7.1 New Features

代码语言:javascript复制
// Nullable types 可为空类型
function test(?string $name): ?string
代码语言:javascript复制
// Void 函数
function swap(&$left, &$right) : void
// 获取一个 void 方法的返回值会得到 null,并且不会产生任何警告
代码语言:javascript复制
// 对称数组解构
$data = [
    [1, 'Tom'],
    [2, 'Fred'],
];
[$id, $name] = $data[0];
// 赋值部分
[, $name1] = $data[1];

foreach ($data as [$id, $name]) {
    // logic here with $id and $name
}

function swap(&$a, &$b): void
{
    [$a, $b] = [$b, $a];
}
代码语言:javascript复制
// list 支持键名
$data = [
    ["id" => 1, "name" => 'Tom'],
    ["id" => 2, "name" => 'Fred'],
];
foreach ($data as ["name" => $name, "id" => $id]) {
    // logic here with $id and $name
}
代码语言:javascript复制
// 类常量支持可见性
class ConstDemo
{
    public const PUBLIC_CONST_A = 1;
}
代码语言:javascript复制
// iterable 伪类(与 callable 类似)
interface Traversable extends iterable {
    // 这个接口没有任何方法,它的作用仅仅是作为所有可遍历类的基本接口
    // Traversable as part of either Iterator or IteratorAggregate,不能直接实现
}

function iterator(iterable $iter)
{
    foreach ($iter as $val) {
        // ...
    }
}
代码语言:javascript复制
// 多异常捕获处理,可以通过管道字符(|)来实现多个异常的捕获
try {
    // some code
} catch (FirstException | SecondException $e) {
    // handle first and second exceptions
}
代码语言:javascript复制
// 支持为负的字符串偏移量,一个负数的偏移量会被理解为一个从字符串结尾开始的偏移量
// 所有支持偏移量的字符串操作函数,都支持接受负数作为偏移量
// 中文操作要小心
var_dump("abcdef"[-2]); // e
var_dump(strpos("aabbcc", "b")); // 2
var_dump(strpos("aabbcc", "b", -3)); // 3
代码语言:javascript复制
// 新增 Closure::fromCallable(),将 callable 转为一个 Closure 对象
// public static Closure::fromCallable(callable $callback): Closure
class Test
{
    public function exposeFunction()
    {
        return Closure::fromCallable([$this, 'privateFunction']);
    }
    private function privateFunction($param)
    {
        var_dump($param);
    }
}

$privFunc = (new Test)->exposeFunction();
$privFunc('some value');
// string(10) "some value"

7.1 New Functions

代码语言:javascript复制
// 否为可迭代
is_iterable()

7.1 Backward Incompatible Changes

代码语言:javascript复制
// 当传递参数过少时将抛出错误
function test($param){}
test();
/*
PHP71
Fatal error: Uncaught ArgumentCountError: Too few arguments to function test()

PHP70
Warning: Missing argument 1 for test()
*/
代码语言:javascript复制
// 禁止动态调用作用域自检函数
// $func() or array_map('extract', ...)
// function array_map($callback, array $array, array ...$arrays): array
(function () {
    $func = 'func_num_args';
    $func();
})();
/*
PHP71
Warning: Cannot call func_num_args() dynamically
*/
代码语言:javascript复制
// 以下名称不能用于命名 class, interface, trait
// - void
// - iterable
代码语言:javascript复制
// 数字字符串转换 遵循科学记数法
var_dump(intval('1e5'));
var_dump(is_numeric('1e5'));
var_dump(is_numeric('e'));
/*
PHP71
int(100000)
bool(true)
bool(false)


PHP70
int(1)
bool(true)
bool(false)
*/
代码语言:javascript复制
// call_user_func() 不再支持对传址的函数的调用
error_reporting(E_ALL);
function increment(&$var)
{
    $var  ;
}

$a = 0;
call_user_func('increment', $a); // ...expected to be a reference, value given
call_user_func_array('increment', [&$a]); // 1
$increment = 'increment';
$increment($a); // 2
代码语言:javascript复制
// 字符串不再支持空索引运算符
$str = "";
$str[] = "abc";
var_dump($str);
/*
PHP71
Fatal error: Uncaught Error: [] operator not supported for strings

PHP70
array(1) {
  [0]=>
  string(3) "abc"
}
*/

$a = "";
$a[0] = "hello world";
var_dump($a);
/*
PHP71
string(1) "h"

PHP70
array(1) {
  [0]=>
  string(11) "hello world"
}
*/
代码语言:javascript复制
// 通过空字符串上的字符串索引访问赋值
$str = '';
$str[10] = 'foo';
var_dump($str);
/*
PHP71
string(11) "          f"

PHP70
array(1) {
  [10]=>
  string(3) "foo"
}
*/
代码语言:javascript复制
// 当通过引用赋值引用它们自动创建这些元素时,数组中元素的顺序已更改。
$array = [];
$array['a'] = &$array['b'];
$array['b'] = 1;
var_dump($array);
/*
PHP71
array(2) {
  ["b"]=>
  &int(1)
  ["a"]=>
  &int(1)
}

PHP70
array(2) {
  ["a"]=>
  &int(1)
  ["b"]=>
  &int(1)
}
*/
代码语言:javascript复制
// 词法绑定变量不能重用名称,以下都将 fatal error
$f = function () use ($_SERVER) {}; // any superglobals
$f = function () use ($this) {};
$f = function ($param) use ($param) {};
代码语言:javascript复制
// 禁止 "return;" 对于已经在编译时键入的返回值
function test(int $i): array
{
    $i  = 1;
    return;
}
// PHP Compile Error A function with return type must return a value
代码语言:javascript复制
var_dump('1b'   'something');
/*
PHP71
Notice: A non well formed numeric value encountered
Warning: A non-numeric value encountered
int(1)

PHP70
int(1)
*/

PHP5.6 to PHP7.0

https://www.php.net/manual/en/migration70.php

Backward incompatible changes

代码语言:javascript复制
// 错误和异常处理相关的变更
// set_exception_handler() 不再保证收到的一定是 Exception 对象
function handler(Exception $e) { ... }
set_exception_handler('handler');

// 兼容 PHP 5 和 7
function handler($e) { ... }

// 仅支持 PHP 7
function handler(Throwable $e) { ... }

// 当内部构造器失败的时候,总是抛出异常
代码语言:javascript复制
// 间接调用的表达式的新旧解析顺序
// 现在严格遵循从左到右的顺序来解析
// 表达式               PHP 5 的解析方式           PHP 7 的解析方式
$$foo['bar']['baz']    ${$foo['bar']['baz']}    ($$foo)['bar']['baz']
$foo->$bar['baz']      $foo->{$bar['baz']}      ($foo->$bar)['baz']
代码语言:javascript复制
// foreach 通过值遍历时,操作的值为数组的副本
$array = [0];
foreach ($array as $val) {
    var_dump($val);
    $array[1] = 1;
}
// int(0)

// foreach通过引用遍历时,有更好的迭代特性
$array = [0];
foreach ($array as &$val) {
    var_dump($val);
    $array[1] = 1;
}
// PHP 7.0
// int(0)
// int(1)

// PHP 5.6
// int(0)
代码语言:javascript复制
// call_user_method() and call_user_method_array() 被移除。
// 应该使用 call_user_func() 和 call_user_func_array()
代码语言:javascript复制
// 在函数中检视参数值会返回 当前 的值
function foo($x) {
    $x  ;
    var_dump(func_get_arg(0));
}
foo(1);
// int(2) PHP 7.0
// int(1) PHP 5.6

7.0 New Features

代码语言:javascript复制
// 标量类型声明
// 返回值类型声明
function arraysSum(array ...$arrays): array
{
    return array_map(function(array $array): int {
        return array_sum($array);
    }, $arrays);
}
代码语言:javascript复制
// null 合并运算符,对 isset() 的简化
$username = $_GET['user'] ?? 'nobody';

// 太空船操作符(组合比较符)
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
代码语言:javascript复制
// 通过 define() 定义 常量数组
define('ANIMALS', [
    'dog',
    'cat',
    'bird'
]);
代码语言:javascript复制
// 匿名类 用来替代一些“用后即焚”的完整类定义
$app = new Application;
$app->setLogger(new class implements Logger {
    public function log(string $msg) {
        echo $msg;
    }
});
代码语言:javascript复制
// Unicode codepoint 转译语法
// 这接受一个以 16 进制形式的 Unicode codepoint
echo "u{9999}"; // 香
代码语言:javascript复制
// Closure::call() 新方法,简化绑定一个方法到对象上闭包并调用它
// PHP 7 之前版本的代码
$getXCB = function() {return $this->x;};
// function bindTo($newThis, $newScope = 'static') { }
// $newScope 将闭包关联到的类作用域
$getX = $getXCB->bindTo(new A, A::class); // 中间层闭包
echo $getX();

// PHP 7  及更高版本的代码
$getX = function() {return $this->x;};
echo $getX->call(new A);
代码语言:javascript复制
// 生成器委托 yield from
function gen()
{
    yield 1;
    yield 2;

    yield from gen2();
}
function gen2()
{
    yield 3;
    yield 4;
}
foreach (gen() as $val)
{
    echo $val, PHP_EOL;
}
// 1
// 2
// 3
// 4
代码语言:javascript复制
// 柯里化
function add($a) {
  return function($b) use ($a) {
    return $a   $b;
  };
}
$result = add(10)(15);
var_dump($result); // int 25

Deprecated features in PHP 7.0.x

代码语言:javascript复制
// 构造函数(方法名和类名一样)将被弃用,并在将来移除
class Foo {
    function foo() {
        echo 'I am the constructor';
    }
}
// PHP 7.0: Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP
// PHP 5.6: OK

Other Changes

代码语言:javascript复制
// 放宽了保留词限制,以前不能用 'new'、'private' 和 'for'
Project::new('Project Name')->private()->for('purpose here')->with('username here');
// class 关键词不能用于常量名,否则会和类名解析语法冲突(ClassName::class)

New Global Constants

代码语言:javascript复制
PHP_INT_MIN

– EOF –

  • # php

0 人点赞