테스트 결과, AST를 사용한 후 프로그램의 전체 실행 시간이 약 10%~15% 향상되었지만 메모리 소비도 증가하는 것으로 나타났습니다. 대용량 파일을 한 번 컴파일할 때 그 증가는 명백하지만 그리 심각한 수준은 아닙니다. 전체 프로젝트 실행 과정에서 문제가 발생합니다.
또한 위의 결과는 모두 Opcache를 사용하지 않은 결과이므로 프로덕션 환경에서 Opcache를 켜면 메모리 소비 증가는 큰 문제가 되지 않습니다.
Semantic Changes
단순한 시간 최적화라면 AST를 사용하는 충분한 이유가 되지 않는 것 같습니다. 실제로 AST 구현은 시간 최적화 고려사항이 아니라 구문 문제를 해결하기 위한 것입니다. 의미론의 몇 가지 변화를 살펴보겠습니다.
yield에는 괄호가 필요하지 않습니다.
PHP5 구현에서 표현식 컨텍스트(예: 할당 표현식의 오른쪽)에서 Yield를 사용하는 경우 Yield 선언 주위에 괄호를 사용해야 합니다.
<?php
$result = yield fn(); // 不合法的
$result = (yield fn()); // 合法的
This 이 동작은 단순히 PHP5 구현의 제한 때문입니다. PHP7에서는 괄호가 더 이상 필요하지 않습니다. 따라서 다음 작성 방법도 적법합니다.
<?php
$result = yield;
$result = yield $v;
$result = yield $k => $v;
물론 Yield의 적용 시나리오를 따라야 합니다.
괄호는 동작에 영향을 주지 않습니다
PHP5에서 ($foo)['bar'] = 'baz'와 $foo['bar'] = 'baz'는 다른 의미를 갖습니다. 사실, 이전 작성 방법은 불법이며 다음과 같은 오류가 발생합니다:
<?php
($foo)['bar'] = 'baz';
# PHP Parse error: Syntax error, unexpected '[' on line 1
그러나 PHP7에서는 두 가지 작성 방법이 같은 의미입니다.
마찬가지로 함수의 매개변수가 괄호로 묶인 경우 유형 검사에 문제가 있습니다. 이 문제는 PHP7에서도 해결되었습니다.
<?php
function func() {
return [];
}
function byRef(array &$a) {
}
byRef((func()));
위 코드는 byRef(func()를 호출하지 않는 한 PHP5에서 경보를 울리지 않습니다. ) ) 이지만 PHP7에서는 func() 양쪽에 괄호 유무에 관계없이 다음 오류가 발생합니다.
PHP Strict standards: Only variables should be passed by reference ...
list() 변경
list 키워드 동작이 많이 변경되었습니다. 리스트가 변수에 값을 할당하는 순서(동시에 등호 주위의 순서)는 예전에는 오른쪽에서 왼쪽이었지만 지금은 왼쪽에서 오른쪽입니다:
<?php
list($array[], $array[], $array[]) = [1, 2, 3];
var_dump($array);
// PHP5: $array = [3, 2, 1]
// PHP7: $array = [1, 2, 3]
# 注意这里的左右的顺序指的是等号左右同时的顺序,
# list($a, $b) = [1, 2] 这种使用中 $a == 1, $b == 2 是没有疑问的。
위 변경 이유는 다음과 같습니다. 왜냐하면 PHP5의 할당 과정에서 3이 배열에 처음으로 채워지고 1이 마지막으로 채워지지만 이제 순서가 변경되었기 때문입니다.
동일한 변경 사항은 다음과 같습니다.
<?php
$a = [1, 2];
list($a, $b) = $a;
// PHP5: $a = 1, $b = 2
// PHP7: $a = 1, $b = null + "Undefined index 1"
이전 할당 프로세스에서 $b가 먼저 2를 얻은 다음 $a의 값이 1이 되었지만 이제 $a가 먼저 1이 되어 더 이상 배열이 아니기 때문입니다. . 따라서 $b는 null이 됩니다.
목록은 이제 오프셋당 한 번만 액세스됩니다.
<?php
list(list($a, $b)) = $array;
// PHP5:
$b = $array[0][1];
$a = $array[0][0];
// PHP7:
// 会产生一个中间变量,得到 $array[0] 的值
$_tmp = $array[0];
$a = $_tmp[0];
$b = $_tmp[1];
빈 목록 멤버는 이제 모두 금지됩니다. 이전에는 특정 경우에만 가능했습니다.
<?php
list() = $a; // 不合法
list($b, list()) = $a; // 不合法
foreach ($a as list()) // 不合法 (PHP5 中也不合法)
참조 할당 순서
참조 할당 순서 PHP5에서는 오른쪽부터입니다. to left, 현재 시제는 왼쪽에서 오른쪽으로:
<?php
$obj = new stdClass;
$obj->a = &$obj->b;
$obj->b = 1;
var_dump($obj);
// PHP5:
object(stdClass)#1 (2) {
["b"] => &int(1)
["a"] => &int(1)
}
// PHP7:
object(stdClass)#1 (2) {
["a"] => &int(1)
["b"] => &int(1)
}
__clone 메소드를 직접 호출할 수 있습니다
이제 $obj->__clone()을 사용하여 __clone 메소드를 직접 호출할 수 있습니다. __clone은 이전에 직접 호출이 금지된 유일한 매직 메소드였습니다. 이전에는 다음과 같은 오류가 발생했습니다.
Fatal error: Cannot call __clone() method on objects - use 'clone $obj' instead in ...
변수 구문 일관성
AST는 RFC에서 제안된 다른 제안에서 보고된 일부 구문 일관성 문제도 해결했습니다. https://wiki.php.net/rfc/uniform_variable_syntax.
새 구현에서는 이전 문법 표현의 의미가 현재와 다소 다릅니다. 자세한 내용은 다음 표를 참조하세요.
Expression |
PHP5 |
PHP7 |
$$foo['bar']['baz'] $$foo['bar']['baz']
|
${$foo['bar']['baz']} |
($$foo)['bar']['baz'] |
$foo->$bar['baz'] |
$foo->{$bar['baz']} |
($foo->$bar)['baz'] |
$foo->$bar['baz']() |
$foo->{$bar['baz']}() |
($foo->$bar)['baz']() |
Foo::$bar['baz']() |
Foo::{$bar['baz']}() |
(Foo::$bar)['baz']() |
${$foo[ 'bar ']['baz']}
($$foo)['bar']['baz']
$foo-> ['baz']
$foo->{$bar['baz']}
🎜($foo->$bar)[' baz' ]
🎜🎜🎜🎜$foo->$bar['baz']()
🎜🎜$foo->{$bar['baz'] }( )
🎜🎜($foo->$bar)['baz']()
🎜🎜🎜🎜Foo::$bar['baz']( )🎜🎜<code>Foo::{$bar['baz']}()
🎜🎜(Foo::$bar)['baz']()
🎜 🎜🎜🎜🎜전체적으로 이전 순서는 오른쪽에서 왼쪽이었지만 이제는 왼쪽에서 오른쪽이며 괄호가 동작에 영향을 주지 않는다는 원칙도 따릅니다. 이러한 복잡한 변수 작성 방식은 실제 개발 시 주의가 필요합니다. 🎜🎜추천 튜토리얼: "🎜PHP7🎜"🎜