前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP Migrating to 7.4 8.0

PHP Migrating to 7.4 8.0

作者头像
Yifans_Z
发布2023-08-23 18:51:05
2090
发布2023-08-23 18:51:05
举报
文章被收录于专栏:与荔枝一起成长

PHP7.3 to PHP7.4

https://www.php.net/manual/en/migration74.php https://php.watch/versions/7.4 PHP 7.4, the final release in the PHP 7.x series. PHP 7.4 brings typed properties, underscore numeric separator, and other minor improvements to PHP.

New Features 7.4

代码语言:javascript
复制
// Typed properties
class User {
    public int $id; // 会强制要求 $user->id 只能为 int 类型,访问前必须进行处理化,?int 也要进行初始化
}
代码语言:javascript
复制
// 箭头函数 Arrow functions
$factor = 10;
$nums = array_map(fn($n) => $n * $factor, [1, 2, 3, 4]);
代码语言:javascript
复制
// 有限的 Limited 返回类型协变和参数类型逆变
class A {}
class B extends A {}
class Producer {
    public function method(): A {}
}
class ChildProducer extends Producer {
    public function method(): B {}
}
// PHP74
// ok
//
// PHP73
// Fatal error: Declaration of ChildProducer::method(): B must be compatible with Producer::method(): A
代码语言:javascript
复制
// 空合并赋值运算符
$array['key1'] ??= 1;
// is roughly equivalent to
if (!isset($array['key2'])) {
    $array['key2'] = 2;
}
var_dump($array);
// array(2) {
//   ["key1"]=>
//   int(1)
//   ["key2"]=>
//   int(2)
// }
代码语言:javascript
复制
// Unpacking inside arrays
// 可以平替 array_merge
$parts = ['apple', 'pear'];
$fruits = ['orange', ...$parts, 'watermelon'];
var_dump($fruits);
// array(4) {
//   [0]=>
//   string(6) "orange"
//   [1]=>
//   string(5) "apple"
//   [2]=>
//   string(4) "pear"
//   [3]=>
//   string(10) "watermelon"
// }
代码语言:javascript
复制
// 数字文字分隔符
6.674_083e-11; // float
299_792_458;   // decimal
0xCAFE_F00D;   // hexadecimal
0b0101_1111;   // binary

var_dump((int)"1_123");
// int(1)
代码语言:javascript
复制
// WeakReference 类
// https://www.php.net/manual/zh/class.weakreference.php
$obj = new stdClass;
$weakref = WeakReference::create($obj);
var_dump($weakref->get());
unset($obj);
var_dump($weakref->get());
// object(stdClass)#1 (0) {
// }
// NULL

Backward Incompatible Changes 7.4

代码语言:javascript
复制
// 以数组形式访问非数组,将会抛出 notic
// null, bool, int, float or resource
$i = 12;
$i["a"];
// PHP74
// Notice: Trying to access array offset on value of type int
//
// PHP80
// Warning: Trying to access array offset on value of type int
//
// PHP73 ok

Deprecated Features 7.4

代码语言:javascript
复制
// 嵌套的三元运算必须明确地使用括号来指示运算的顺序
var_dump(1 ? 2 : 3 ? 4 : 5);
// PHP74
// Deprecated: Unparenthesized `a ? b : c ? d : e` is deprecated. Use either `(a ? b : c) ? d : e` or `a ? b : (c ? d : e)`
// int(4)

PHP7.4 to PHP8.0

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

New Features 8.0

代码语言:javascript
复制
// 命名参数
// https://www.php.net/manual/zh/functions.arguments.php#functions.named-arguments
// array_fill(int $start_index, int $count, mixed $value): array
var_dump(array_fill(value: 50, count: 3, start_index: 0));
// PHP80
// array(3) {
//   [0]=>
//   int(50)
//   [1]=>
//   int(50)
//   [2]=>
//   int(50)
// }
代码语言:javascript
复制
// 注解(Attributes)
// https://www.php.net/manual/zh/language.attributes.php
// 定义注解 -> 使用注解 -> (通过反射)提取注释
// 注意以后用词:Attributes 注解,Properties 属性
#[\Attribute]
class JsonSerialize {
    public function __construct(public ?string $fieldName = null) {
        var_dump("JsonSerialize:$fieldName");
    }
}
class VersionedObject {
    #[JsonSerialize('json-foobar')]
    protected string $myValue = '';
}
$object = new VersionedObject();
$reflection = new ReflectionObject($object);
foreach ($reflection->getProperties() as $reflectionProp) {
    foreach ($reflectionProp->getAttributes(JsonSerialize::class) as $jsonSerializeAttr) {
        var_dump($jsonSerializeAttr->getName());
        var_dump($jsonSerializeAttr->getArguments());
        var_dump($jsonSerializeAttr->getTarget());
        var_dump($jsonSerializeAttr->isRepeated());
        var_dump($jsonSerializeAttr->newInstance());
    }
}
// string(13) "JsonSerialize"
//
// array(1) {
//   [0]=>
//   string(11) "json-foobar"
// }
//
// int(8) Attribute::TARGET_PROPERTY
//
// bool(false)
//
// string(25) "JsonSerialize:json-foobar"
// object(JsonSerialize)#5 (1) {
//   ["fieldName"]=>
//   string(11) "json-foobar"
// }
代码语言:javascript
复制
// 构造器属性提升
// 当构造器参数带访问控制(visibility modifier)时,PHP 会同时把它当作对象属性和构造器参数,并赋值到属性
class Point {
    public function __construct(protected int $x, protected int $y = 0) {
    }
}
var_dump(new Point(2,4));
// object(Point)#1 (2) {
//   ["x":protected]=>
//   int(2)
//   ["y":protected]=>
//   int(4)
// }
class Point {
    public function __construct(int $x, int $y = 0) {
        $this->x = $x;
        $this->y = $y;
    }
}
var_dump(new Point(2,4));
// object(Point)#1 (2) {
//   ["x"]=>
//   int(2)
//   ["y"]=>
//   int(4)
// }

class Point2 {
    protected int $x;
    protected int $y;
    public function __construct(protected int $x, protected int $y = 0) {}
}
// 此类中已经定义了具有相同名称的字段
// Fatal error: Cannot redeclare Point::$x
代码语言:javascript
复制
// Union types 联合类型
// ?T is same T|null
//
// - 类型只能出现一次 int|string|INT 否则报错
// - 使用 mixed 会报错
// - bool 与 false or true 不能混用
// - object 与 class 不能混用
// - iterable 与 array Traversable 不能混用
// - 使用 self、parent 或 static 都会导致错误
代码语言:javascript
复制
// match 表达式
// https://www.php.net/manual/en/control-structures.match.php
// match 表达式必须是详尽,则会抛出 UnhandledMatchError。
$food = 'cake';
$return_value = match ($food) {
    'apple' => 'This food is an apple',
    'bar' => 'This food is a bar',
    'cake' => 'This food is a cake',
};
var_dump($return_value);
// string(19) "This food is a cake"
代码语言:javascript
复制
// Nullsafe 方法和属性
// As of PHP 8.0.0, this line:
$result = $repository?->getUser(5)?->name;
// Is equivalent to the following code block:
if (is_null($repository)) {
    $result = null;
} else {
    $user = $repository->getUser(5);
    if (is_null($user)) {
        $result = null;
    } else {
        $result = $user->name;
    }
}
代码语言:javascript
复制
// The WeakMap class has been added, accepts objects as keys, similar SplObjectStorage
// https://www.php.net/manual/en/class.weakmap.php
// https://www.php.net/manual/en/class.splobjectstorage.php
// final class WeakMap implements ArrayAccess, Countable, IteratorAggregate
$wm = new WeakMap();
$o = new StdClass;
class A {
    public function __destruct() {
        echo "Dead!\n";
    }
}
$wm[$o] = new A;
var_dump(count($wm));
// int(1)
unset($o);
// Dead!
// 销毁
var_dump(count($wm));
// int(0)


// 对比 SplObjectStorage
$wm = new SplObjectStorage();
$o = new StdClass;
class A {
    public function __destruct() {
        echo "Dead!\n";
    }
}
$wm[$o] = new A;
var_dump(count($wm));
// int(1)
unset($o);
// 未销毁
var_dump(count($wm));
// int(1)
代码语言:javascript
复制
// 只要类型兼容,现在可以将任意数量的函数参数替换为可变参数 variadic argument
class A {
    public function method(int $many, string $parameters, $here) {}
}
class B extends A {
    public function method(...$everything) {}
}
// OK
class C extends A {
    public function method(int ...$everything) {}
}
// Fatal error: Declaration of C::method(int ...$everything)
代码语言:javascript
复制
// static 后期静态绑定,现在可以用作返回类型
class Test {
    public function create(): static {
        return new static();
    }
}
代码语言:javascript
复制
// get_class($obj) === $obj::class
class Test {}
$obj = new Test;
var_dump($obj::class);
var_dump(get_class($obj));
代码语言:javascript
复制
// new instanceof 可以与任意表达式一起使用
// new (expression)(...$args)
// $obj instanceof (expression)
class A{};
class B{};
new (1>2 ? "A" : "B")();
代码语言:javascript
复制
// 新增 Stringable 接口。如果 class 定义了 __toString(),则自动实现了此接口
代码语言:javascript
复制
// Traits can define abstract private methods
trait T {
    abstract private function a();
}
代码语言:javascript
复制
// throw 可以作为一个表达式 as an expression
$fn = fn() => throw new Exception('Exception in arrow function');
代码语言:javascript
复制
// 参数列表中现在允许使用可选的尾随逗号
function functionWithLongSignature(
    Type1 $parameter1,
    Type2 $parameter2, // <-- This comma is now allowed.
) {}
代码语言:javascript
复制
// 允许 catch (Exception) 无需存储到变量
try {}
catch (Exception) {}
代码语言:javascript
复制
// 在父类上声明的私有方法不再对子类的方法强制执行任何继承规则(私有构造函数除外)
class ParentClass {
    private function method1() {}
    private function method2() {}
    private static function method3() {}
}
abstract class ChildClass extends ParentClass {
    public abstract function method1();
    public static function method2() {}
    public function method3() {}
}
// OK

Backward Incompatible Changes 8.0

代码语言:javascript
复制
// 字符串与数字比较
// 0 == "not-a-number" is false
// 将数字转换为字符串,并使用字符串比较
var_dump(0 == "foo");
var_dump(42 == "42foo");
var_dump(0 == "");
// PHP80
// bool(false)
// bool(false)
// bool(false)
//
// PHP74
// bool(true)
// bool(true)
// bool(true)
var_dump("" < 0);
var_dump("" < -1);
var_dump("a" < 0);
var_dump("b" < -1);
var_dump("ab" > 0);
// PHP80
// bool(true)
// bool(true)
// bool(false)
// bool(false)
// bool(true)
//
// PHP74
// bool(false)
// bool(false)
// bool(false)
// bool(false)
// bool(false)
代码语言:javascript
复制
// match is 保留关键字
代码语言:javascript
复制
// is_callable() 在检查具有 classname 的 non-static 方法时将 false(必须检查对象实例)
class Test {
    public function method1() {}
}
var_dump(is_callable([Test::class, 'method1']));
var_dump(is_callable([new Test, 'method1']));
// PHP80
// bool(false)
// bool(true)
//
// PHP74
// bool(true)
// bool(true)
代码语言:javascript
复制
// __autoload() function has been removed
代码语言:javascript
复制
// 删除了对 object 使用 array_key_exists() 的能力。isset() or property_exists() may be used instead

– EOF –

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-12-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • PHP7.3 to PHP7.4
    • New Features 7.4
      • Backward Incompatible Changes 7.4
        • Deprecated Features 7.4
        • PHP7.4 to PHP8.0
          • New Features 8.0
            • Backward Incompatible Changes 8.0
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档