学习PHP7系并回忆起PHP(给自己的提醒)
简述
-
PHP7の新機能の確認
- PHP7の新機能の確認
-
- を今更しつつPHPのおさらい
- をして7系に移行できるようにする
请提供更多背景信息以便我更好地理解你的要求。PHP中级者的目标—掌握语言的书籍
PHP: 从PHP 5.6.x迁移到 PHP 7.0.x
PHP: 从PHP 7.0.x迁移到 PHP 7.1.x
PHP: 从PHP 7.1.x迁移到 PHP 7.2.x
选取PHP版本变化的要点(从5.4.x到7.3.x)
前提 tí)
PHP7.2
注意事项我个人经过重新审视后,把我记住的以PHP7系列新增的功能为重点的部分写了下来。
声明PHP7发布后,支持了字符串类型、整数类型以及其他多种标量类型。可以说,这有点像类型提示,但需要注意的是,这种类型声明仍不完全。
function sampleFunc(int $num) {
echo $num;
}
sampleFunc(1); // 1
sampleFunc(true); // 1
sampleFunc("1"); // 1
sampleFunc("hoge"); // Argument 1 passed to sampleIntFunc() must be of the type integer, string given
- PHP7.2
注意事项我个人经过重新审视后,把我记住的以PHP7系列新增的功能为重点的部分写了下来。
声明PHP7发布后,支持了字符串类型、整数类型以及其他多种标量类型。可以说,这有点像类型提示,但需要注意的是,这种类型声明仍不完全。
function sampleFunc(int $num) {
echo $num;
}
sampleFunc(1); // 1
sampleFunc(true); // 1
sampleFunc("1"); // 1
sampleFunc("hoge"); // Argument 1 passed to sampleIntFunc() must be of the type integer, string given
function sampleFunc(int $num) {
echo $num;
}
sampleFunc(1); // 1
sampleFunc(true); // 1
sampleFunc("1"); // 1
sampleFunc("hoge"); // Argument 1 passed to sampleIntFunc() must be of the type integer, string given
在这个例子中,虽然字符串已经破裂,但仍然自动进行了转换并接受了其它结果。这个类型声明有点弱。PHP7引入的类型声明可以将其变得更加强大。
declare(strict_types=1);
function sampleFunc(int $num) {
echo $num;
}
sampleFunc(1); // 1
sampleFunc(true); // Uncaught TypeError: Argument 1 passed to sampleFunc() must be of the type integer, boolean given
sampleFunc("1"); // Uncaught TypeError: Argument 1 passed to sampleFunc() must be of the type integer, string given
sampleFunc("hoge"); // Uncaught TypeError: Argument 1 passed to sampleFunc() must be of the type integer, string given
通过在文件的开头添加declare(strict_types=1);可以实现更严格的类型声明。
有关declare的更多信息,请参阅PHP: declare – Manual。
如果想要允许NULL,可以在型的前面添加?。
declare(strict_types=1);
function sampleFunc(?int $num) {
echo $num;
}
sampleFunc(1); // 1
sampleFunc(null); // エラーは発生しない
可以通过返回值的方式进行定义,并且可以按照以下方式进行描述。
declare(strict_types=1);
function sampleFunc(int $num) :int {
return $num * 2;
}
echo sampleFunc(1); // 2
当然,可以像变量一样允许NULL(传达返回值可能为NULL的信息)。
declare(strict_types=1);
function sampleFunc(int $num) :?int {
return $num * 2;
}
此外,若要明确确保没有返回值时,可以按照以下方式进行描述。
declare(strict_types=1);
function sampleFunc(int $num) :void {
echo $num;
}
sampleFunc(1); // 1
运算符
空合并运算符(??)当给未定义的变量赋予初始值时,请写上“用于此目的”,这样说不太清楚。
$hoge;
if(isset($piyo)) {
$hoge = $piyo;
} else {
$hoge = 'hoge';
}
echo $hoge;
$hoge = isset($piyo)? $piyo: 'hoge';
echo $hoge;
$hoge = $piyo ?? 'hoge';
echo $hoge;
$hoge;
if(isset($piyo)) {
$hoge = $piyo;
} else {
$hoge = 'hoge';
}
echo $hoge;
$hoge = isset($piyo)? $piyo: 'hoge';
echo $hoge;
$hoge = $piyo ?? 'hoge';
echo $hoge;
以上3段代码相等。虽然”NULL合并运算符”这个名字有点难记,但如果能读懂代码的话应该很方便。
冒号:展示了Elvis操作符:
对于Elvis,我觉得有点像。Elvis操作符是在PHP5.3中添加的一个操作符。我以前从未使用过它。
如果NULL联合操作符等于isset,那么Elvis操作符将等同于if($hoge)。
$hoge;
if($piyo) {
$hoge = $piyo;
} else {
$hoge = 'hoge';
}
echo $hoge;
$hoge = $piyo? $piyo: 'hoge';
echo $hoge;
$hoge = $piyo ?: 'hoge';
echo $hoge;
$hoge;
if($piyo) {
$hoge = $piyo;
} else {
$hoge = 'hoge';
}
echo $hoge;
$hoge = $piyo? $piyo: 'hoge';
echo $hoge;
$hoge = $piyo ?: 'hoge';
echo $hoge;
以上提到的三个代码是等价的。由于Elvis操作符的名字很有威力,所以很容易记住。需要注意的是,由于它在if语句中判断,所以在行为方面需要稍加注意。
太空船计算符这个…名字不太酷(个人观点)。NULL合并运算符更酷一些…
宇宙船运算符本身在编写compare函数时经常使用。关于宇宙船运算符的解释,PHP官方手册非常易懂。
宇宙船演算子是用来比较两个表达式的。 如果$a大于$b,则返回1;如果$a等于$b,则返回0;如果$a小于$b,则返回-1。 在比较过程中,使用PHP类型比较规则的比较表。
// 整数値
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
// 浮動小数点数値
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
// 文字列
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
这个常数可以使用数组
那个?我记得以前的5系不能做到吧。可能只是因为没用过而已。
define('HOGE', [
'foo' => 'bar',
'key' => 'value'
]);
echo HOGE['foo']; // bar
宇宙船演算子是用来比较两个表达式的。 如果$a大于$b,则返回1;如果$a等于$b,则返回0;如果$a小于$b,则返回-1。 在比较过程中,使用PHP类型比较规则的比较表。
// 整数値
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
// 浮動小数点数値
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
// 文字列
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
那个?我记得以前的5系不能做到吧。可能只是因为没用过而已。
define('HOGE', [
'foo' => 'bar',
'key' => 'value'
]);
echo HOGE['foo']; // bar
这是指这样的事情,对吗?
在类内部的常量访问权限现在可以定义访问课堂内定义的常量的访问权限。我觉得这个功能可能会有所用处。
class sampleClass {
public const HOGE = [
'foo' => 'bar',
'key' => 'value'
];
private const PIYO = [
'foo' => 'bar',
'key' => 'value'
];
}
echo sampleClass::HOGE['key']; // value
echo sampleClass::PIYO['foo']; // Fatal error: Uncaught Error: Cannot access private const sampleClass::PIYO
匿名类这不是匿名函数,而是匿名类。它可以像匿名函数一样使用。
function sampleFunc(iHoge $obj) {
echo $obj->pubFunc('hoge'); // foo
echo $obj::HOGE['foo']; // bar
}
interface iHoge {
public function pubFunc(string $param1);
}
sampleFunc(new class implements iHoge {
public const HOGE = [
'foo' => 'bar',
'key' => 'value'
];
public function pubFunc(string $param1) {
echo $param1;
}
});
class sampleClass {
public const HOGE = [
'foo' => 'bar',
'key' => 'value'
];
private const PIYO = [
'foo' => 'bar',
'key' => 'value'
];
}
echo sampleClass::HOGE['key']; // value
echo sampleClass::PIYO['foo']; // Fatal error: Uncaught Error: Cannot access private const sampleClass::PIYO
function sampleFunc(iHoge $obj) {
echo $obj->pubFunc('hoge'); // foo
echo $obj::HOGE['foo']; // bar
}
interface iHoge {
public function pubFunc(string $param1);
}
sampleFunc(new class implements iHoge {
public const HOGE = [
'foo' => 'bar',
'key' => 'value'
];
public function pubFunc(string $param1) {
echo $param1;
}
});
用简单明了的方式来写的话,可能是这样的吧。感觉在编写测试用例的时候会经常使用到这个印象呢。虽然不是很确定。
断言
我觉得这个结构从以前就存在了,但听说在7系中更容易处理,所以我想写一个简单的测试。
define('TAX', 1.08);
function tax($v1) {
return $v1 * TAX;
}
$price = -1000;
assert($price >= 0, "price値が0未満");
assert(tax(1000) == 1050, "tax計算が異常");
define('TAX', 1.08);
function tax($v1) {
return $v1 * TAX;
}
$price = -1000;
assert($price >= 0, "price値が0未満");
assert(tax(1000) == 1050, "tax計算が異常");
有点杂乱,但是应该是这个感觉吧。在上面的例子中,当“TAX”的值改变时,如果插入assert语句,就可以注意到“不应该是1080,因此发生了某种未预料的异常”。这种情况下只用于异常检测,所以在assert语句内不应该发生副作用。
当assertion(assert的第一个参数)为“false”时,description(assert的第二个参数)将被输出,所以对于不熟悉的人可能会感到困惑。考虑到检测异常,可以将正常情况写在assertion中,将“因为正常情况没有通过所以异常”写在description中,这样记住会更好。assert只是用于开发过程中尽早发现错误和退化的工具,并不能保证验证或值的合法性,也不能忘记这一点。
虽然assert很方便,但在生产环境中也可能影响性能。在这种情况下,可以使用assert指令(zend.assertions)来设置。
好像写一点就好。