match表达式(PHP 8)
<?php
//1
// $request_method = "post";
// $status = match($request_method) {
// 'post' => "post",
// 'get', 'head' => "get_head",
// default => throw new \Exception('Unsupported'),
// };
// var_dump($status);
//2
// class test1{
// public function beepa(): string{
// return "beepa";
// }
// public function beepb(): string{
// return "beepb";
// }
// public function beepc(): string{
// return "beepc";
// }
// public function match_test(): void{
// $a = 'a';
// $b = 'b';
// $c = 'c';
// $result = match($b){
// 'a' => $this->beepa(),
// 'b' => $this->beepb(),
// 'c' => $this->beepc(),
// };
// var_dump($result);
// }
// }
// $test1 = new test1();
// $test1->match_test();
//3
//表达式
// $age = 23;
// $result = match (true) {
// $age >= 65 => 'senior',
// $age >= 25 => 'adult',
// $age >= 18 => 'young adult',
// default => 'kid',
// };
// var_dump($result);
// $text = 'Bienvenue chez nous';
// $result = match (true) {
// str_contains($text, 'Welcome') || str_contains($text, 'Hello') => 'en',
// str_contains($text, 'Bienvenue') || str_contains($text, 'Bonjour') => 'fr',
// };
// var_dump($result);
//4
// function fizzbuzz($num) {
// print match (0) {
// $num % 15 => "FizzBuzz" . PHP_EOL,
// $num % 3 => "Fizz" . PHP_EOL,
// $num % 5 => "Buzz" . PHP_EOL,
// default => $num . PHP_EOL,
// };
// }
// for ($i = 0; $i <=100; $i++){
// fizzbuzz($i);
// }
//5
// $error_code = (int) 400;
// $message = (string) match($error_code){
// 200=>"OK",
// 400=>"Bad Request",
// 401=>"Unauthorized",
// 403=>"Forbidden",
// 404=>"Not Found",
// default=>"Unknown Error"
// };
// var_dump($message);
trait
<?php
//trait 更多用多于继承 无法实例化,而是使用 use
trait Dog{
public $name = "dog";
public static $static = 'foo';
public function drive(){
echo "This is dog drive";
}
public function eat(){
echo "This is dog eat";
}
public static function body() :void {
echo "This is dog body";
}
abstract public function getName(); //抽象方法
}
class Cat{
use Dog;
public function drive(){
echo "This is cat drive";
}
public function getName(){
echo "This is Cat name";
}
}
$cat = new Cat();
//$cat->drive(); //访问方法 This is cat drive
//$cat->eat(); //访问方法 This is dog eat
//echo $cat->name; //访问属性 dog
//echo $cat::$static; //访问静态变量 foo
//$cat::body(); //访问静态方法 This is dog body
//$cat->getName(); //抽象方法 This is Cat name
预定义接口之 ArrayAccess
<?php
class Obj implements ArrayAccess {
private $container = array();
public function __construct() {
$this->container = array(
"one" => 1,
"two" => 2,
"three" => 3,
);
}
public function offsetSet($offset, $value): void {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetExists($offset): bool {
return isset($this->container[$offset]);
}
public function offsetUnset($offset): void {
unset($this->container[$offset]);
}
//mixed 多种不同类型
public function offsetGet($offset): mixed {
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
}
$obj = new Obj;
//var_dump($obj["two"]); //offsetGet
//unset($obj["two"]); //offsetUnset
//var_dump(isset($obj["two"])); //offsetExists
//$obj["two"] = "A value"; //offsetSet
//var_dump($obj["two"]);
//$obj[] = 'Append 1';
//$obj[] = 'Append 2';
//$obj[] = 'Append 3';
//print_r($obj);
//魔术方法
class Obj2{
public $data;
public function __construct() {
$this->data = array(
"one" => 1,
"two" => 2,
"three" => 3,
);
}
/**
* 以对象的方式访问数组中的数据
*
* @param $key
* @return mixed
*/
public function __get($key): mixed
{
return $this->data[$key];
}
/**
* 以对象方式添加一个数组元素
*
* @param $key
* @param $val
*/
public function __set($key, $val): void
{
$this->data[$key] = $val;
}
/**
* 以对象方式判断数组元素是否设置
*
* @param $key
* @return bool
*/
public function __isset($key): bool
{
return isset($this->data[$key]);
}
/**
* 以对象方式删除一个数组元素
*
* @param $key
*/
public function __unset($key): void
{
unset($this->data[$key]);
}
}
$obj2 = new Obj2;
$obj2->one = "A value"; //__set
//var_dump($obj2->one); //__get
//unset($obj["one"]); //__unset
//var_dump(isset($obj["two"])); //__isset
//__set
$obj2->Append1 = 'Append 1';
$obj2->Append2 = 'Append 2';
$obj2->Append3 = 'Append 3';
print_r($obj2);
枚举(PHP 8 >= 8.1.0)
Enum 定义
<?php
//Enum 定义 枚举可以定义零个或多个case,且没有最大数量限制
enum Suit{
case Hearts;
case Diamonds;
case Clubs;
case Spades;
}
/**
//枚举的形参传入
function pick_a_card(Suit $suit) {
var_dump($suit);
}
$val = Suit::Diamonds;
pick_a_card($val);
pick_a_card(Suit::Clubs);
pick_a_card('Spades'); //err
*/
/**
//每个case是该名称对象的单例
$a = Suit::Spades;
$b = Suit::Spades;
var_dump($a === $b); // true
//instanceof(1)判断一个对象是否是某个类的实例,(2)判断一个对象是否实现了某个接口。
var_dump($a instanceof Suit); // true
*/
//所有的 case 有个只读的属性 name。 它大小写敏感,是 case 自身的名称。
print Suit::Spades->name;
print Suit::Diamonds->name;
回退(Backed)枚举
<?php
//BackedEnum 回退(Backed)枚举
//注意枚举定义中的类型声明。它表示所有枚举值都是给定类型的。仅 int 和 String 被允许作为枚举值。
enum Suit: string
{
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
}
/**
//所有的 case 有个只读的属性 value。 它是定义时指定的值。
print Suit::Spades->value;
print Suit::Diamonds->value;
*/
/***
//只读性,不可修改
$suit = Suit::Clubs;
$ref = &$suit->value; // Error: Cannot acquire reference to property Suit::$value
*/
/**
$suit = Suit::from('X'); // || Suit::from('H'); Suit::Hearts
// 无效数据抛出 ValueError:"X" is not a valid scalar value for enum "Suit"
print $suit->value;
$suit = Suit::tryFrom('A') ?? Suit::Spades;
// 无效数据返回 null,因此会用 Suit::Spades 代替。
print $suit->value;
*/
?>
枚举方法
<?php
interface Colorful{
public function color(): string;
}
//trait
trait Rectangle
{
public function shape(): string {
return "trait Rectangle";
}
}
enum Suit implements Colorful{
use Rectangle;
case Hearts;
case Diamonds;
case Clubs;
case Spades;
// 满足 interface 契约。
public function color(): string{
return match($this){
Suit::Hearts, Suit::Diamonds => 'Red',
Suit::Clubs, Suit::Spades => 'Black',
};
}
// 不是 interface 的一部分;也没问题
public function SuitShape(): string{
return "SuitShape";
}
}
function paint(Colorful $c) {
echo $c->name;
}
function paint_color(Colorful $c) {
echo $c->color();
}
// paint_color(Suit::Clubs);
// paint(Suit::Clubs); // 正常
// print (Suit::Diamonds->color()); //Black
// print(Suit::Diamonds->SuitShape()); // 输出 "SuitShape"
// print(Suit::Diamonds->shape()); // 输出 "trait Rectangle"
// var_dump(Suit::cases()); //返回全部条目 [Suit::Hearts, Suit::Diamonds, Suit::Clubs, Suit:Spades]
// Suit::Hearts === unserialize(serialize(Suit::Hearts));
// Suit::Hearts === "1";
print serialize(Suit::Hearts); // E:11:"Suit:Hearts";
enum Foo {
case Bar;
}
enum Baz: int {
case Beep = 5;
}
// print_r(Foo::Bar);
// print_r(Baz::Beep);
/*
Foo Enum (
[name] => Bar
)
Baz Enum:int {
[name] => Beep
[value] => 5
}
*/
枚举静态方法
<?php
//枚举静态方法
enum Size{
case Small;
case Medium;
case Large;
public const Huge = self::Large; //枚举静态变量
public static function fromLength(int $cm): static{
return match(true){
$cm < 50 => static::Small,
$cm < 100 => static::Medium,
default => static::Large,
};
}
}
// var_dump(Size::fromLength(1));
var_dump(Size::Huge);
范例用法
<?php
enum UserStatus: string {
case Pending = 'P';
case Active = 'A';
case Suspended = 'S';
case CanceledByUser = 'C';
public function label(): string
{
return match($this) {
static::Pending => 'Pending',
static::Active => 'Active',
static::Suspended => 'Suspended',
static::CanceledByUser => 'Canceled by user',
};
}
}
foreach (UserStatus::cases() as $case) {
printf('<option value="%s">%s</option>\n', $case->value, $case->label());
}