PHP 7.2 참조
PHP 7.1 참조
PHP 7은 2015년 12월 3일에 출시되었습니다. 아래에 설명된 다양한 새로운 기능, 변경 사항 및 이전 버전과의 호환성 중단이 함께 제공됩니다.
성능
특징
결합 비교 연산자
Null 병합 연산자
스칼라 유형 선언
반환 유형 선언
익명 클래스
유니코드 코드 포인트 이스케이프 구문
클로저 call()
메서드
필터링된 unserialize()
IntlChar
클래스
기대
그룹 use
선언
생성기 반환 표현식
발전기 위임
intdiv()
사용한 정수 나누기
session_start()
옵션
preg_replace_callback_array()
함수
CSPRNG 기능
define()
에서 배열 상수 지원
반사 추가
변경 사항
예약어 제한 완화
균일 변수 구문
엔진의 예외
던질 수 있는 인터페이스
정수 의미론
JSON 확장이 JSOND로 대체됨
오버플로 시 ZPP 오류
foreach()
의 동작 수정
list()
의 동작 변경
0으로 나누기 의미론에 대한 변경 사항
사용자 정의 세션 핸들러 반환 값 수정
PHP 4 스타일 생성자 지원 중단
date.timezone 경고 제거
대체 PHP 태그 제거
Switch 문에서 여러 기본 블록 제거
중복된 이름이 있는 매개변수 재정의 제거
데드 서버 API 제거
숫자 문자열에서 16진수 지원 제거
더 이상 사용되지 않는 기능 제거
E_STRICT 통지의 재분류 및 제거
password_hash()
에 대한 솔트 옵션 지원 중단
잘못된 8진수 리터럴 오류
substr()
반환 값 변경
FAQ
PHP 6은 어떻게 되었나요?
의심의 여지 없이 PHP 7의 가장 큰 부분은 애플리케이션에 제공되는 놀라운 성능 향상입니다. 이는 보다 컴팩트한 데이터 구조와 더 적은 힙 할당/할당 해제를 사용하도록 Zend 엔진을 리팩터링한 결과입니다.
실제 응용 프로그램의 성능 향상은 다양하지만 많은 응용 프로그램은 메모리 소비도 줄어들면서 ~100% 성능 향상을 얻는 것처럼 보입니다.
리팩터링된 코드베이스는 향후 최적화(예: JIT 컴파일)를 위한 추가 기회도 제공합니다. 따라서 향후 PHP 버전에서도 성능이 계속 향상될 것으로 보입니다.
PHP 7 성능 차트 비교:
PHP 7로 웹 속도 향상
Rasmus의 시드니 토크 벤치마크
결합 비교 연산자(또는 우주선 연산자)는 두 피연산자로부터 3방향 비교를 수행하기 위한 약칭 표기법입니다. 다음 중 하나일 수 있는 정수 반환 값이 있습니다.
양의 정수(왼쪽 피연산자가 오른쪽 피연산자보다 큰 경우)
0(두 피연산자가 모두 동일한 경우)
음의 정수(오른쪽 피연산자가 왼쪽 피연산자보다 큰 경우)
이 연산자는 항등 연산자( ==
, !=
, ===
, !==
)와 우선순위가 동일하며 다른 느슨한 비교 연산자( <
, >=
등)와 동작도 동일합니다. 또한 마찬가지로 비연관적이므로 피연산자 연결(예: 1 <=> 2 <=> 3
)은 허용되지 않습니다.
// 문자열을 비교합니다. lexicallyvar_dump('PHP' <=> 'Node'); // int(1)// 숫자를 크기별로 비교합니다.var_dump(123 <=> 456); // int(-1)// 해당 배열 요소를 서로 비교합니다.var_dump(['a', 'b'] <=> ['a', 'b']); // 정수(0)
객체는 비교할 수 없으므로 이 연산자와 함께 피연산자로 사용하면 정의되지 않은 동작이 발생합니다.
RFC: 결합 비교 연산자
널 병합 연산자(또는 isset 삼항 연산자)는 삼항 연산자에서 isset()
검사를 수행하기 위한 약식 표기법입니다. 이는 애플리케이션에서 흔히 수행되는 작업이므로 정확한 목적을 위해 새로운 구문이 도입되었습니다.
// PHP 7 이전 code$route = isset($_GET['route']) ? $_GET['route'] : 'index';// PHP 7+ 코드$route = $_GET['route'] ?? '색인';
RFC: Null 병합 연산자
스칼라 유형 선언은 coercive (기본값)와 strict 의 두 가지 유형으로 제공됩니다. 이제 문자열( string
), 정수( int
), 부동 소수점 숫자( float
) 및 부울( bool
)과 같은 매개 변수 유형을 (강제적으로 또는 엄격하게) 적용할 수 있습니다. 이는 PHP 5.x 버전에 도입된 다른 유형(클래스 이름, 인터페이스, array
및 callable
)을 확장합니다.
// 강제 모드 함수 sumOfInts(int ...$ints) { return array_sum($ints); }var_dump(sumOfInts(2, '3', 4.1)); // 정수(9)
엄격 모드를 활성화하려면 단일 declare()
지시문을 파일 상단에 배치해야 합니다. 이는 스칼라 입력의 엄격함이 파일별로 구성됨을 의미합니다. 이 지시문은 매개변수의 유형 선언뿐만 아니라 함수의 반환 유형(반환 유형 선언 참조), 내장 PHP 함수 및 로드된 확장의 함수에도 영향을 미칩니다.
유형 검사가 실패하면 TypeError
예외(엔진의 예외 참조)가 발생합니다. 엄격한 유형 지정에 존재하는 유일한 관대함은 정수가 부동 소수점 컨텍스트에 제공될 때 정수를 부동 소수점으로 자동 변환하는 것입니다(그 반대는 아님).
선언(strict_types=1);함수 곱셈(float $x, float $y) { $x * $y를 반환합니다. }함수 추가(int $x, int $y) { $x + $y를 반환합니다. }var_dump(곱하기(2, 3.5)); // float(7)var_dump(add('2', 3)); // 치명적인 오류: Uncaught TypeError: add()에 전달된 인수 1은 정수 유형이어야 하며 주어진 문자열...
유형 검사가 수행될 때는 호출 컨텍스트 만 적용됩니다. 즉, 엄격한 유형 지정은 함수/메서드 호출에만 적용되고 함수/메서드 정의에는 적용되지 않습니다. 위의 예에서 두 함수는 엄격한 파일이나 강제 파일에서 선언되었을 수 있지만 엄격한 파일에서 호출되는 한 엄격한 입력 규칙이 적용됩니다.
BC 브레이크
int
, string
, float
및 bool
이름을 가진 클래스는 이제 금지됩니다.
RFC: 스칼라 유형 선언
반환 유형 선언을 사용하면 함수, 메서드 또는 클로저의 반환 유형을 지정할 수 있습니다. 지원되는 반환 유형은 string
, int
, float
, bool
, array
, callable
, self
(메서드만), parent
(메서드만), Closure
, 클래스 이름, 인터페이스 이름입니다.
함수 arraysSum(array ...$arrays): array{ return array_map(function(array $array): int { return array_sum($array); }, $배열); }print_r(arraysSum([1,2,3], [4,5,6], [7,8,9]));/* OutputArray( [0] => 6 [1] => 15 [2] => 24)*/
하위 유형 지정과 관련하여 반환 유형에 대해 불변성이 선택되었습니다. 이는 단순히 메서드가 하위 유형 클래스에서 재정의되거나 계약에 정의된 대로 구현될 때 해당 반환 유형이 (재)구현하는 메서드와 정확히 일치해야 함을 의미합니다.
클래스 A {}클래스 B는 A를 확장합니다. {}클래스 C { 공개 함수 테스트() : A { 새로운 A를 반환; } }클래스 D는 C를 확장합니다. { // 메서드 재정의 C::test() : 공개 함수 test() : B // 분산 불일치로 인한 치명적인 오류 { 새로운 B를 반환; } }
재정의 메서드 D::test() : B
공분산이 허용되지 않기 때문에 E_COMPILE_ERROR
를 발생시킵니다. 이것이 작동하려면 D::test()
메서드의 반환 유형이 A
여야 합니다.
클래스 A {}인터페이스 SomeInterface { 공개 함수 테스트() : A; }클래스 B는 SomeInterface를 구현합니다. { public function test() : A // 모두 좋습니다! { null을 반환; // 치명적인 오류: 잡히지 않은 TypeError: B::test()의 반환 값은 A의 인스턴스여야 하며 null이 반환되었습니다... } }
이번에는 구현된 메서드가 실행될 때 TypeError
예외(엔진의 예외 참조)가 발생하도록 합니다. 이는 null
이 유효한 반환 유형이 아니기 때문입니다. 즉, 클래스 A
의 인스턴스만 반환될 수 있습니다.
RFC: 반환 유형 선언
익명 클래스는 간단한 일회용 개체를 만들어야 할 때 유용합니다.
// PHP 7 이전 코드클래스 로거 { 공개 함수 로그($msg) { 에코 $msg; } }$util->setLogger(new Logger());// PHP 7+ code$util->setLogger(new class { public function log($msg) { 에코 $msg; } });
생성자에 인수를 전달하고, 다른 클래스를 확장하고, 인터페이스를 구현하고, 일반 클래스와 마찬가지로 특성을 사용할 수 있습니다.
class SomeClass {}인터페이스 SomeInterface {}trait SomeTrait {}var_dump(new class(10) Extensions SomeClass Implements SomeInterface { private $num; public function __construct($num) { $this->num = $num; } SomeTrait를 사용합니다. });/** 출력:object(class@anonymous)#1 (1) { ["명령줄 code0x104c5b612":"class@anonymous":private]=> int(10)}*/
익명 클래스를 다른 클래스 내에 중첩해도 해당 외부 클래스의 비공개 또는 보호 메서드나 속성에 대한 액세스 권한이 부여되지 않습니다. 외부 클래스의 보호된 속성이나 메서드를 사용하기 위해 익명 클래스는 외부 클래스를 확장할 수 있습니다. 익명 클래스에서 외부 클래스의 전용 또는 보호 속성을 사용하려면 생성자를 통해 전달되어야 합니다.
<?phpclass 외부 { 개인 $prop = 1; 보호된 $prop2 = 2; 보호된 함수 func1() { 3을 반환; } 공개 함수 func2() { return new class($this->prop)는 외부 { private $prop3;을 확장합니다. 공개 함수 __construct($prop) { $this->prop3 = $prop; } 공개 함수 func3() { return $this->prop2 + $this->prop3 + $this->func1(); } }; } }echo (새 외부)->func2()->func3(); // 6
RFC: 익명 클래스
이를 통해 UTF-8로 인코딩된 유니코드 코드 포인트를 큰따옴표로 묶은 문자열이나 heredoc로 출력할 수 있습니다. 유효한 코드포인트는 모두 허용되며 앞에 0
이 선택사항입니다.
에코 "u{aa}"; // ªecho "u{0000aa}"; // ª (이전과 동일하지만 선택적으로 앞에 0이 붙음)echo "u{9999}"; // 향
RFC: 유니코드 코드 포인트 이스케이프 구문
클로저에 대한 새로운 call()
메소드는 객체 범위를 바인딩하는 동안 클로저를 호출하는 간단한 방법으로 사용됩니다. 이렇게 하면 호출하기 전에 중간 클로저를 생성할 필요가 없어져 더욱 성능이 좋고 컴팩트한 코드가 생성됩니다.
클래스 A {private $x = 1;}// PHP 7 이전 code$getXCB = function() {return $this->x;};$getX = $getXCB->bindTo(new A, 'A'); // 중간 폐쇄echo $getX(); // 1// PHP 7+ code$getX = function() {return $this->x;};echo $getX->call(new A); // 1
RFC: 클로저::호출
unserialize()
이 기능은 신뢰할 수 없는 데이터의 개체를 직렬화 해제할 때 더 나은 보안을 제공하기 위해 노력합니다. 개발자가 직렬화 취소할 수 있는 클래스를 화이트리스트에 추가할 수 있도록 하여 가능한 코드 삽입을 방지합니다.
// 모든 객체를 __PHP_Incomplete_Class로 변환 object$data = unserialize($foo, ["allowed_classes" => false]);// MyClass 및 MyClass2를 제외한 모든 객체를 __PHP_Incomplete_Class 객체로 변환$data = unserialize($foo, [" allowed_classes" => ["MyClass", "MyClass2"]]);// 기본 동작(생략과 동일) 모든 클래스를 허용하는 두 번째 인수)$data = unserialize($foo, ["allowed_classes" => true]);
RFC: 필터링된 unserialize()
IntlChar
클래스 새로운 IntlChar
클래스는 추가 ICU 기능을 노출하려고 합니다. 클래스 자체는 유니코드 문자를 조작하는 데 사용할 수 있는 여러 가지 정적 메서드와 상수를 정의합니다.
printf('%x', IntlChar::CODEPOINT_MAX); // 10ffffecho IntlChar::charName('@'); // 상업용 ATvar_dump(IntlChar::ispunct('!')); // 부울(참)
이 클래스를 사용하려면 Intl
확장이 설치되어 있어야 합니다.
BC 브레이크
전역 네임스페이스의 클래스는 IntlChar
로 호출하면 안 됩니다.
RFC: IntlChar 클래스
기대되는 것은 이전 assert()
함수에 대한 이전 버전과의 호환성 향상입니다. 프로덕션 코드에서 비용이 전혀 들지 않는 어설션을 활성화하고 오류 시 사용자 지정 예외를 발생시키는 기능을 제공합니다.
assert()
함수의 프로토타입은 다음과 같습니다.
void assert (mixed $expression [, mixed $message]);
이전 API와 마찬가지로 $expression
이 문자열이면 평가됩니다. 첫 번째 인수가 거짓이면 어설션이 실패합니다. 두 번째 인수는 일반 문자열(AssertionError가 트리거되도록 함)이거나 오류 메시지가 포함된 사용자 정의 예외 개체일 수 있습니다.
ini_set('assert.Exception', 1);class CustomError는 AssertionError를 확장합니다. {}assert(false, new CustomError('일부 오류 메시지'));
이 기능에는 두 가지 PHP.ini 설정(기본값 포함)이 제공됩니다.
zend.assertions = 1
주장.예외 = 0
zend.assertions 에는 세 가지 값이 있습니다.
1 = 코드 생성 및 실행(개발 모드)
0 = 코드를 생성하고 런타임에 코드 주위로 이동합니다.
-1 = 코드를 생성하지 않음(비용 없음, 생산 모드)
Assert.Exception은 어설션이 실패할 때 예외가 발생함을 의미합니다. 이전 assert()
함수와의 호환성을 유지하기 위해 기본적으로 꺼져 있습니다.
RFC: 기대사항
use
선언 이는 상위 네임스페이스에 따라 다중 use
선언을 그룹화하는 기능을 제공합니다. 이는 동일한 네임스페이스에 속하는 여러 클래스, 함수 또는 상수를 가져올 때 코드의 장황함을 제거하려고 합니다.
// PHP 7 이전 코드에서는 somenamespaceClassA 사용; somenamespaceClassB 사용; somenamespaceClassC를 C로 사용; 함수 somenamespacefn_a 사용; 함수 somenamespacefn_b 사용; 함수 somenamespace 사용 fn_c;사용 const somenamespaceConstA;사용 const somenamespaceConstB;사용 const somenamespaceConstC;// PHP 7+ 코드 사용 somenamespace{ClassA, ClassB, ClassC를 C로 사용}; 함수 somenamespace{fn_a, fn_b, fn_c} 사용; const somenamespace{ConstA, ConstB, ConstC} 사용;
RFC: 그룹 사용 선언
이 기능은 PHP 5.5에 도입된 생성기 기능을 기반으로 구축되었습니다. 최종 표현식 이 반환될 수 있도록 생성기 내에서 return
문을 사용할 수 있습니다(참조에 의한 반환은 허용되지 않음). 이 값은 새로운 Generator::getReturn()
메소드를 사용하여 가져올 수 있습니다. 이 메소드는 생성기가 값 생성을 완료한 후에만 사용할 수 있습니다.
// 이제 IIFE 구문이 가능합니다. 변경 사항 섹션의 균일 변수 구문 하위 섹션을 참조하세요.$gen = (function() { Yield 1; Yield 2; return 3; })();foreach ($gen을 $val로) { echo $val, PHP_EOL; }echo $gen->getReturn(), PHP_EOL;// 출력:// 1// 2// 3
생성기에서 최종 값을 명시적으로 반환할 수 있다는 것은 편리한 기능입니다. 이는 생성기를 실행하는 클라이언트 코드에서 구체적으로 처리할 수 있는 생성기(코루틴 계산의 일부 형태)에서 최종 값을 반환할 수 있기 때문입니다. 이는 클라이언트 코드가 먼저 최종 값이 생성되었는지 여부를 확인한 다음, 그렇다면 해당 값을 구체적으로 처리하도록 하는 것보다 훨씬 간단합니다.
RFC: 생성기 반환 표현식
생성기 위임은 생성기에서 표현식을 반환할 수 있는 기능을 기반으로 구축됩니다. Traversable
객체나 배열이 될 수 있는 yield from <expr>
구문을 사용하여 이를 수행합니다. 이는 더 이상 유효하지 않을 때까지 진행된 다음 호출 생성기에서 실행이 계속됩니다. 이 기능을 사용하면 yield
문을 더 작은 작업으로 분할하여 재사용성이 더 높은 깔끔한 코드를 만들 수 있습니다.
함수 생성() { 수율 1; 수율 2; gen2()에서 수익률을 반환합니다. }함수 gen2() { 산출량 3; 4를 반환합니다. }$gen = gen();foreach ($gen을 $val로) { 에코 $val, PHP_EOL; }echo $gen->getReturn();// 출력// 1// 2// 3// 4
RFC: 생성기 위임
intdiv()
사용한 정수 나누기 정수가 반환되는 나누기를 처리하기 위해 intdiv()
함수가 도입되었습니다.
var_dump(intdiv(10, 3)); // 정수(3)
BC 브레이크
전역 네임스페이스의 함수는 intdiv
로 호출하면 안 됩니다.
RFC: intdiv()
session_start()
옵션 이 기능은 session_start()
함수에 옵션 배열을 전달하는 기능을 제공합니다. 이는 세션 기반 php.ini 옵션을 설정하는 데 사용됩니다:
session_start(['cache_limiter' => '비공개']); // session.cache_limiter 옵션을 비공개로 설정합니다.
또한 이 기능에는 새로운 php.ini 설정( session.lazy_write
)이 도입되었습니다. 이 설정은 기본적으로 true로 설정되어 있으며 세션 데이터가 변경되는 경우에만 다시 작성된다는 의미입니다.
RFC: session_start() 옵션 소개
preg_replace_callback_array()
함수 이 새로운 함수를 사용하면 preg_replace_callback()
함수를 사용할 때 코드를 더욱 깔끔하게 작성할 수 있습니다. PHP 7 이전에는 정규식별로 실행해야 하는 콜백을 수행하려면 콜백 함수( preg_replace_callback()
의 두 번째 매개변수)가 많은 분기(기껏해야 해키 방식)로 오염되어야 했습니다.
이제 연관 배열을 사용하여 각 정규식에 콜백을 등록할 수 있습니다. 여기서 키는 정규식이고 값은 콜백입니다.
기능 서명:
string preg_replace_callback_array(array $regexesAndCallbacks, string $input);
$tokenStream = []; // [tokenName, lexeme] pair$input = <<<'end'$a = 3; // 변수 초기화end;// PHP 7 이전 codepreg_replace_callback( [ '~$[a-z_][azd_]*~i', '~=~', '~[d]+~', '~;~', '~//.*~' ], 함수 ($match) 사용 (&$tokenStream) { if (strpos($match[0], '$') === 0) { $tokenStream[] = ['T_VARIABLE', $match[0]] ; } elseif (strpos($match[0], '=') === 0) { $tokenStream[] = ['T_ASSIGN', $match[0]]; } elseif (ctype_digit($match[0])) { $tokenStream[] = ['T_NUM', $match[0]]; } elseif (strpos($match[0], ';') === 0) { $tokenStream[] = ['T_TERMINATE_STMT', $match[0]]; } elseif (strpos($match[0], '//') === 0) { $tokenStream[] = ['T_COMMENT', $match[0]]; } }, $input);// PHP 7+ codepreg_replace_callback_array( [ '~$[a-z_][azd_]*~i' => 함수 ($match) 사용 (&$tokenStream) { $tokenStream[] = ['T_VARIABLE', $match[0]]; }, '~=~' => 함수 ($match) 사용 (&$tokenStream) { $tokenStream[] = ['T_ASSIGN', $match[0]]; }, '~[d]+~' => 함수 ($match) 사용 (&$tokenStream) { $tokenStream[] = ['T_NUM', $match[0]]; }, '~;~' => 함수 ($match) 사용 (&$tokenStream) { $tokenStream[] = ['T_TERMINATE_STMT', $match[0]]; }, '~//.*~' => 함수 ($match) 사용 (&$tokenStream) { $tokenStream[] = ['T_COMMENT', $match[0]]; } ], $입력);
BC 브레이크
전역 네임스페이스의 함수는 preg_replace_callback_array
로 호출하면 안 됩니다.
RFC: preg_replace_callback_array 함수 추가
이 기능에는 암호화된 보안 정수 및 문자열을 생성하기 위한 두 가지 새로운 기능이 도입되었습니다. 이는 간단한 API를 노출하고 플랫폼 독립적입니다.
기능 서명:
string random_bytes(int length); int random_int(int min, int max);
충분한 임의성의 소스를 찾을 수 없는 경우 두 함수 모두 Error
예외를 발생시킵니다.
BC 브레이크
전역 네임스페이스의 함수는 random_int
또는 random_bytes
라고 호출하면 안 됩니다.
RFC: 쉬운 사용자 영역 CSPRNG
define()
에서 배열 상수 지원 배열 상수를 정의하는 기능은 PHP 5.6에서 const
키워드를 사용하여 도입되었습니다. 이 기능은 이제 define()
함수에도 적용되었습니다:
정의('ALLOWED_IMAGE_EXTENSIONS', ['jpg', 'jpeg', 'gif', 'png']);
RFC: 사용 가능한 RFC가 없습니다.
PHP 7에는 두 개의 새로운 리플렉션 클래스가 도입되었습니다. 첫 번째는 생성기 내부 검사에 사용되는 ReflectionGenerator
입니다.
클래스 ReflectionGenerator { 공개 __construct($gen 생성기) 공개 배열 getTrace($options = DEBUG_BACKTRACE_PROVIDE_OBJECT) 공개 int getExecutingLine(void) 공개 문자열 getExecutingFile(void) 공개 ReflectionFunctionAbstract getFunction(void) 공개 객체 getThis(void) 공용 생성기 getExecutingGenerator(void) }
두 번째는 스칼라 및 반환 유형 선언 기능을 더 잘 지원하는 ReflectionType
입니다.
클래스 반사 유형 { public bool allowedNull(void) public bool isBuiltin(void) 공개 문자열 __toString(void) }
또한 ReflectionParameter
에 두 가지 새로운 메서드가 도입되었습니다.
클래스 ReflectionParameter { // ... public bool hasType(void) public ReflectionType getType(void) }
ReflectionFunctionAbstract
의 두 가지 새로운 메서드는 다음과 같습니다.
클래스 ReflectionFunctionAbstract { // ... public bool hasReturnType(void) public ReflectionType getReturnType(void) }
BC 브레이크
전역 네임스페이스의 클래스는 ReflectionGenerator
또는 ReflectionType
으로 호출하면 안 됩니다.
RFC: 사용 가능한 RFC가 없습니다.
이제 클래스, 인터페이스 및 특성 내의 속성, 상수 및 메서드 이름으로 전역적으로 예약된 단어가 허용됩니다. 이렇게 하면 새 키워드가 도입될 때 BC 중단의 표면이 줄어들고 API에 대한 이름 지정 제한이 방지됩니다.
이는 유창한 인터페이스로 내부 DSL을 생성할 때 특히 유용합니다.
// 'new', 'private' 및 'for'는 이전에는 사용할 수 없었습니다.Project::new('프로젝트 이름')->private()->for('목적은 여기에')->with('사용자 이름은 여기에');
유일한 제한 사항은 class
키워드를 여전히 상수 이름으로 사용할 수 없다는 것입니다. 그렇지 않으면 클래스 이름 확인 구문( ClassName::class
)과 충돌할 수 있습니다.
RFC: 상황에 맞는 어휘 분석기
이 변화는 PHP의 변수 연산자에 훨씬 더 큰 직교성을 가져옵니다. 이는 이전에 허용되지 않았던 다양한 새로운 연산자 조합을 가능하게 하여 더 간결한 코드로 기존 작업을 수행하는 새로운 방법을 도입합니다.
// 중첩 ::$foo::$bar::$baz // $foo::$bar 속성의 $baz 속성에 액세스합니다.// 중첩 ()foo()() // foo()의 반환을 호출합니다. // ()(function () {})()로 묶인 표현식에 대한 연산자 // JS의 IIFE 구문
변수 연산자를 임의로 결합하는 기능은 간접 변수, 속성 및 메서드 참조의 평가 의미를 뒤집는 데서 비롯되었습니다. 새로운 동작은 더욱 직관적이며 항상 왼쪽에서 오른쪽으로 평가 순서를 따릅니다.
// 예전 의미 // 새로운 의미$$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']()
BC 브레이크
이전 평가 순서에 의존하는 코드는 중괄호와 함께 해당 평가 순서를 명시적으로 사용하도록 다시 작성해야 합니다(위의 중간 열 참조). 이렇게 하면 코드가 PHP 7.x와 호환되고 PHP 5.x와 역호환됩니다.
RFC: 균일 변수 구문
엔진의 예외는 많은 치명적이고 복구 가능한 치명적인 오류를 예외로 변환합니다. 이를 통해 사용자 정의 오류 처리 절차를 통해 애플리케이션의 점진적인 성능 저하가 가능해집니다. 이는 또한 finally
절 및 개체 소멸자와 같은 정리 기반 기능이 이제 실행된다는 의미이기도 합니다. 또한 애플리케이션 오류에 대한 예외를 사용하면 추가 디버깅 정보에 대한 스택 추적이 생성됩니다.
function sum(float ...$numbers) : float{ return array_sum($numbers); }try { $total = sum(3, 4, null); } catch (TypeError $typeErr) { // 여기서 유형 오류를 처리합니다.}
새로운 예외 계층 구조는 다음과 같습니다.
interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error |- ArithmeticError extends Error |- DivisionByZeroError extends ArithmeticError
이 새로운 예외 계층에 대한 자세한 내용은 변경 섹션의 Throwable 인터페이스 하위 섹션을 참조하세요.
BC 브레이크
복구 가능한 치명적인 오류를 처리(일반적으로 무시)하는 데 사용되는 사용자 정의 오류 처리기는 이제 예외가 발생하므로 더 이상 작동하지 않습니다.
eval()
ed 코드에서 발생하는 구문 분석 오류는 이제 예외가 되어 try...catch
블록에 래핑되어야 합니다.
RFC: 엔진의 예외
이 변경 사항은 엔진의 예외 도입으로 인해 PHP의 예외 계층 구조에 영향을 미칩니다. 기존 Exception
클래스 계층 구조 아래에 치명적이고 복구 가능한 치명적인 오류를 배치하는 대신, PHP 5.x 코드가 catch-all( catch (Exception $e)
) 조항.
새로운 예외 계층 구조는 다음과 같습니다.
interface Throwable |- Exception implements Throwable |- ... |- Error implements Throwable |- TypeError extends Error |- ParseError extends Error |- AssertionError extends Error |- ArithmeticError extends Error |- DivisionByZeroError extends ArithmeticError
Throwable
인터페이스는 Exception
및 Error
기본 클래스 계층 모두에 의해 구현되며 다음 계약을 정의합니다.
interface Throwable { final public string getMessage ( void ) final public mixed getCode ( void ) final public string getFile ( void ) final public int getLine ( void ) final public array getTrace ( void ) final public string getTraceAsString ( void ) public string __toString ( void ) }
Throwable
사용자 정의 클래스로 구현할 수 없습니다. 대신 사용자 정의 예외 클래스는 PHP의 기존 예외 클래스 중 하나를 확장해야 합니다.
RFC: 던질 수 있는 인터페이스
일부 정수 기반 동작의 의미 체계는 보다 직관적이고 플랫폼 독립적이 되도록 변경되었습니다. 변경 사항 목록은 다음과 같습니다.
NAN
및 INF
정수로 변환하면 항상 0이 됩니다.
이제 음수 비트만큼 비트 단위 이동이 허용되지 않습니다(bool(false) 반환을 유발하고 E_WARNING을 발생시킵니다).
정수의 비트 너비를 초과하는 비트 수만큼 왼쪽으로 비트 이동하면 항상 0이 됩니다.
정수의 비트 너비를 초과하는 비트 수만큼 오른쪽으로 비트 단위 이동하면 항상 0 또는 -1이 됩니다(부호에 따라 다름).
BC 브레이크
위의 내용에 대한 이전 의미론에 대한 의존은 더 이상 작동하지 않습니다.
RFC: 정수 의미론
이전 JSON 확장의 라이선스는 무료가 아닌 것으로 간주되어 많은 Linux 기반 배포판에서 문제를 일으켰습니다. 이후 확장 기능은 JSOND로 대체되었으며 일부 성능이 향상되고 이전 버전과의 호환성이 손상되었습니다.
BC 브레이크
숫자는 소수점으로 끝나서 는 안 됩니다 (예: 34.
는 34.0
또는 34
로 변경해야 함).
e
지수는 소수점 바로 뒤에 오면 안 됩니다 (예: 3.e3
3.0e3
또는 3e3
으로 변경되어야 함).
RFC: 현재 json 확장자를 jsond로 교체
부동 소수점에서 정수로의 강제 변환은 부동 소수점이 정수를 기대하는 내부 함수에 전달될 때 발생할 수 있습니다. float가 너무 커서 정수로 표시할 수 없으면 값이 자동으로 잘립니다(이로 인해 크기와 부호가 손실될 수 있음). 이로 인해 찾기 어려운 버그가 발생할 수 있습니다. 따라서 이 변경에서는 부동 소수점에서 정수로의 암시적 변환이 발생하고 null
반환하고 E_WARNING을 내보내 실패할 때 개발자에게 알리려고 합니다.
BC 브레이크
한때 자동으로 작동했던 코드는 이제 E_WARNING을 내보내고 함수 호출 결과가 다른 함수에 직접 전달되면 실패할 수 있습니다(이제 null
이 전달되므로).
RFC: 오버플로 시 ZPP 오류
foreach()
의 동작 수정 PHP의 foreach()
루프에는 이상한 경우가 많이 있었습니다. 이것들은 모두 구현 중심이었고 배열의 복사본과 참조 사이를 반복할 때, current()
및 reset()
과 같은 반복기 조작자를 사용할 때, 현재 반복 중인 배열을 수정할 때 등 정의되지 않고 일관되지 않은 동작을 많이 발생시켰습니다.
이러한 변화는 이러한 극단적인 경우의 정의되지 않은 동작을 제거하고 의미 체계를 더욱 예측 가능하고 직관적으로 만듭니다.
배열의 값으로 foreach()
$array = [1,2,3];$array2 = &$array;foreach($array as $val) { unset($array[1]); // 반복되는 배열을 수정합니다. echo "{$val} - ", current($array), PHP_EOL; }// PHP 7 이전 결과1 - 33 -// PHP 7 이상 결과1 - 12 - 13 - 1
값별 의미 체계가 사용되는 경우 반복되는 배열은 이제 내부에서 수정되지 않습니다. current()
에는 이제 항상 배열의 시작 부분에서 시작되는 동작이 정의되었습니다.
foreach()
배열과 개체에 대한 참조로, 개체의 값으로 사용됩니다.
$array = [1,2,3];foreach($array as &$val) { echo "{$val} - ", current($array), PHP_EOL; }// PHP 7 이전 결과1 - 22 - 33 -// PHP 7 이상 결과1 - 12 - 13 - 1
current()
함수는 더 이상 foreach()
의 배열 반복에 의해 영향을 받지 않습니다. 또한 참조별 의미 체계를 사용하는 중첩된 foreach()
는 이제 서로 독립적으로 작동합니다.
$array = [1,2,3];foreach($array as &$val) { echo $val, PHP_EOL; foreach($array를 &$val2로) { unset($array[1]); 에코 $val, PHP_EOL; } }// PHP 7 이전 결과111// PHP 7 이상 결과111333
BC 브레이크
오래된(기발하고 문서화되지 않은) 의미론에 대한 의존은 더 이상 작동하지 않습니다.
RFC: "foreach" 동작 수정
list()
의 동작 변경 list()
함수는 문자열을 지원하지 않는 것으로 문서화되어 있지만 문자열을 사용할 수 있는 경우는 거의 없습니다.
// 배열 역참조$str[0] = 'ab';list($a, $b) = $str[0];echo $a; // 에코 $b; // b// 객체 역참조$obj = new StdClass();$obj->prop = 'ab';list($a, $b) = $obj->prop;echo $a; // 에코 $b; // b// 함수 returnfunction func() { 'ab'를 반환; }list($a, $b) = func();var_dump($a, $b);echo $a; // 에코 $b; //b
이제 모든 경우에 list()
사용한 문자열 사용이 금지되도록 변경되었습니다.
또한 빈 list()
는 이제 치명적인 오류이며 변수 할당 순서가 왼쪽에서 오른쪽으로 변경되었습니다.
$a = [1, 2];list($a, $b) = $a;// 기존: $a = 1, $b = 2// 신규: $a = 1, $b = null + "정의되지 않음 인덱스 1"$b = [1, 2];list($a, $b) = $b;// OLD: $a = null + "정의되지 않은 인덱스 0", $b = 2// 신규: $a = 1, $b = 2
BC 브레이크
list()
직접적이지 않은 문자열 값과 동일하게 만드는 것은 더 이상 불가능합니다. 이제 null
위 예에서 변수 $a
및 $b
의 값이 됩니다.
변수 없이 list()
호출하면 치명적인 오류가 발생합니다.
기존의 오른쪽에서 왼쪽 할당 순서에 의존하는 것은 더 이상 작동하지 않습니다.
RFC: list() 동작 불일치 수정
RFC: 추상 구문 트리
PHP 7 이전에는 나누기(/) 또는 모듈러스(%) 연산자의 제수가 0인 경우 E_WARNING이 발생하고 false
반환되었습니다. 어떤 경우에는 부울 값을 반환하는 산술 연산이 의미가 없으므로 PHP 7에서는 해당 동작이 수정되었습니다.
새로운 동작으로 인해 나누기 연산자는 부동 소수점을 +INF, -INF 또는 NAN으로 반환합니다. 모듈러스 연산자 E_WARNING이 제거되었으며 (새로운 intdiv()
함수와 함께) DivisionByZeroError
예외가 발생합니다. 또한 intdiv()
함수는 유효한 정수 인수가 제공되어 잘못된 결과를 초래하는 경우(정수 오버플로로 인해) ArithmeticError
발생시킬 수도 있습니다.
var_dump(3/0); // float(INF) + E_WARNINGvar_dump(0/0); // float(NAN) + E_WARNINGvar_dump(0%0); // DivisionByZeroErrorintdiv(PHP_INT_MIN, -1); // 산술 오류
BC 브레이크
나누기 연산자는 더 이상 false
반환하지 않습니다(산술 연산에서 자동으로 0으로 강제될 수 있음).
모듈러스 연산자는 이제 false
반환하는 대신 0 제수를 사용하여 예외를 발생시킵니다.
RFC: 사용 가능한 RFC가 없습니다.
사용자 정의 세션 핸들러를 구현할 때 true
또는 false
반환 값을 기대하는 SessionHandlerInterface
의 조건자 함수가 예상대로 작동하지 않았습니다. 이전 구현의 오류로 인해 -1
반환 값만 false로 간주되었습니다. 즉, 실패를 표시하기 위해 부울 false
사용하더라도 성공으로 간주되었습니다.
<?phpclass FileSessionHandler는 SessionHandlerInterface를 구현합니다. { 개인 $savePath; 함수 열기($savePath, $sessionName) { 거짓을 반환; //항상 실패 } 함수 close(){return true;} 함수 read($id){} 함수 write($id, $data){} 함수 destroy($id){} 함수 gc($maxlifetime){} }session_set_save_handler(new FileSessionHandler());session_start(); // PHP 7 이전 코드에서는 오류가 발생하지 않습니다.
이제 위의 작업은 치명적인 오류로 인해 실패합니다. 반환 값이 -1
이면 계속 실패하고, 0
과 true
이면 계속 성공을 의미합니다. 반환된 다른 값은 이제 오류를 일으키고 E_WARNING을 발생시킵니다.
BC 브레이크
부울 false
반환되면 이제 실제로 실패합니다.
부울, 0
또는 -1
이외의 값이 반환되면 실패하고 경고가 발생합니다.
RFC: 사용자 정의 세션 핸들러 반환 값 처리 수정
PHP 4 생성자는 새로운 __construct()
와 함께 PHP 5에서 유지되었습니다. 이제 객체 생성 시 단일 메서드( __construct()
)만 호출하도록 하기 위해 PHP 4 스타일 생성자는 더 이상 사용되지 않습니다. 이는 PHP 4 스타일 생성자가 호출되었는지 여부에 대한 조건으로 인해 경험이 없는 개발자에게도 혼란을 줄 수 있는 추가 인지 오버헤드가 발생했기 때문입니다.
예를 들어, 클래스가 네임 스페이스 내에서 정의되거나 __construct()
메소드가 존재하는 경우 PHP 4 스타일 생성자가 일반 방법으로 인식되었습니다. __construct()
메소드 위에 정의 된 경우 e_strict 통지가 방출되지만 여전히 일반 방법으로 인식됩니다.
이제 PHP 7에서 클래스가 네임 스페이스에없고 __construct()
메소드가없는 경우 PHP 4 스타일 생성자는 생성자로 사용되지만 E_DEPRECATED가 방출됩니다. PHP 8에서 PHP 4 스타일 생성자는 항상 일반 방법으로 인식되며 E_DEPRECATED 통지는 사라집니다.
BC가 끊어집니다
사용자 지정 오류 처리기는 E_DEPRECATED 경고를 높이면 영향을받을 수 있습니다. 이 문제를 해결하려면 클래스 생성자 이름을 __construct
로 업데이트하십시오.
RFC : PHP 4 생성자를 제거하십시오
날짜 또는 시간 기반 기능이 호출되고 기본 시간대가 설정되지 않은 경우 경고가 방출되었습니다. 수정 사항은 단순히 날짜. date.timezone
INI 설정을 유효한 시간대로 설정하는 것이었지만, 이로 인해 사용자는 php.ini 파일을 가지고 미리 구성해야했습니다. 이것이 경고가 첨부 된 유일한 설정이었고 어쨌든 UTC로 기본값이되었으므로 이제 경고가 제거되었습니다.
RFC : 날짜를 제거하십시오. 타임 존 경고
대체 PHP 태그 <%
(및 <%=
), %>
, <script language="php">
및 </script>
가 제거되었습니다.
BC가 끊어집니다
이러한 대체 태그에 의존하는 코드는 일반 또는 짧은 개방 및 닫는 태그로 업데이트되어야합니다. 이 포트 스크립트로 수동으로 수행하거나 자동화 할 수 있습니다.
RFC : 대체 PHP 태그를 제거하십시오
이전에는 스위치 문 (마지막 default
블록이 실행 된 경우) 내에서 여러 default
블록 문을 지정할 수있었습니다. 이 (쓸모없는) 능력이 이제 제거되어 치명적인 오류가 발생합니다.
BC가 끊어집니다
여러 default
블록이있는 스위치 문을 생성 한 모든 코드 (또는 생성 가능성이 높아짐)는 이제 치명적인 오류가됩니다.
RFC : 스위치에서 여러 기본 케이스를 구문 오류로 정의합니다.
이전에는 함수 정의 내에서 중복 이름을 가진 매개 변수를 지정할 수있었습니다. 이 능력은 이제 제거되어 치명적인 오류가 발생합니다.
function foo ($ 버전, $ 버전) {return $ 버전; } echo foo (5, 7); // pre pr pr 7 result7 // php 7+ 결과 사전 오류 : parameters.php에서 매개 변수 $ 버전의 재정의
BC가 끊어집니다
중복 이름이있는 함수 매개 변수는 이제 치명적인 오류가됩니다.
다음 SAPI가 코어에서 제거되었습니다 (대부분은 PECL로 옮겨졌습니다).
Sapi/Aolserver
사피/아파치
sapi/apache_hooks
SAPI/APACHE2FILTER
사피/카우듐
SAPI/연속성
Sapi/Isapi
SAPI/MILTER
SAPI/NSAPI
SAPI/PHTTPD
SAPI/PI3WEB
Sapi/Roxen
SAPI/THTTPD
사피/턱시도
Sapi/WebJames
ext/mssql
ext/mysql
ext/sybase_ct
Ext/Ereg
RFC : 사망 여부 또는 아직 없음 PHP7 포트 포트 SAPI 및 확장
끈적 끈적한 16 진수는 더 이상 수치로 인식되지 않습니다.
var_dump (is_numeric ( '0x123')); var_dump ( '0x123'== '291'); echo '0x123' + '0x123'; // prp 7 resultbool (true) bool (true) 582 // php 7+ resultbool (false) bool (false) 0
이 변화의 이유는 언어 전체의 끈적 끈적한 16 진수의 처리 사이에 더 나은 일관성을 높이기 때문입니다. 예를 들어, 명시 적 캐스트는 STRINGY HEX 번호를 인식하지 못합니다.
var_dump ((int) '0x123'); // int (0)
대신, filter_var()
함수를 사용하여 STRINGY HEX 번호를 검증하고 변환해야합니다.
var_dump (filter_var ( '0x123', filter_validate_int, filter_flag_allow_hex)); // int (291)
BC가 끊어집니다
이 변경 사항은 is_numeric()
함수 및 ==
, +
, -
, *
, /
, %
, **
, ++
및 --
를 포함한 다양한 연산자에게 영향을 미칩니다.
RFC : 숫자 문자열에서 16 진지를 제거하십시오
모든 감가 상각 된 기능이 제거되었습니다.
원래 MySQL 확장 (Ext/MySQL)
Ereg Extension (Ext/Ereg)
참조별로 new
할당
호환되지 않는 $this
컨텍스트 (예 Foo::bar()
bar()
BC가 끊어집니다
PHP 5에서 감가 상각 경고로 실행되는 모든 코드는 더 이상 작동하지 않습니다 (경고를 받았습니다!)
RFC : PHP 7에서 더 이상 사용되지 않은 기능을 제거하십시오
E_strict 통지는 항상 그 의미에서 약간의 회색 영역이었습니다. 이 변경 사항은이 오류 범주를 완전히 제거하고 다음과 같습니다. E_Strict 통지를 제거하거나 기능이 미래에 제거되면 E_DEPRECATED로 변경하거나 E_NOTICE로 변경하거나 E_WARNING으로 홍보합니다.
BC가 끊어집니다
E_Strict가 심각도 오류 범주에 가장 낮기 때문에 E_Warning에 대한 오류 프로모션은 사용자 정의 오류 처리기를 깨뜨릴 수 있습니다.
RFC : e_strict 통지를 다시 분류하십시오
password_hash()
에 대한 소금 옵션 감가 상각PHP 5.5에 새로운 암호 해싱 API가 도입되면서 많은 사람들이이를 구현하고 자체 소금을 생성하기 시작했습니다. 불행히도,이 소금 중 다수는 mt_rand ()와 같은 암호적으로 불안한 기능에서 생성되어 소금이 기본적으로 생성 된 것보다 훨씬 약합니다. (예, 소금은이 새로운 API로 암호를 해싱 할 때 항상 소금이 사용됩니다!) 따라서 소금을 생성하는 옵션은 개발자가 불안한 소금을 생성하지 못하도록 감가 상각되었습니다.
RFC : RFC를 사용할 수 없습니다
잘못된 옥탈 리터럴은 이제 잘라 내고 조용히 무시되지 않고 구문 분석 오류를 일으 킵니다.
에코 0678; // 구문 분석 오류 : 유효하지 않은 숫자 문자 ...
BC가 끊어집니다
코드의 유효하지 않은 옥탈 리터럴은 이제 구문 분석 오류가 발생합니다.
RFC : RFC를 사용할 수 없습니다
substr()
반환 값 변경 절단의 시작 위치가 문자열 길이와 같을 때 substr()
이제 false
대신 빈 문자열을 반환합니다.
var_dump (substr ( 'a', 1)); // pre pr pr pr pr pr pr pr php 7 resultbool (false) // php 7+ resultstring (0) "" "
그러나 다른 경우에는 substr()
여전히 false
반환 할 수 있습니다.
BC가 끊어집니다
bool(false)
반환 값을 엄격히 확인한 코드는 이제 의미 적으로 유효하지 않을 수 있습니다.
RFC : RFC를 사용할 수 없습니다
PHP 6은 결코 밝혀지지 않은 주요 PHP 버전이었습니다. 그것은 핵심에서 유니 코드에 대한 완전한 지원을 특징으로했지만,이 노력은 너무 많은 합병증으로 인해 너무 야심적이었습니다. 이 새로운 주요 버전을 위해 버전 6을 건너 뛰는 주요 이유는 다음과 같습니다.
혼란을 방지하기 위해 . PHP 6에 대해 많은 자원이 작성되었으며 많은 지역 사회가 그 안에 등장한 내용을 알고있었습니다. PHP 7은 완전히 다른 초점 (특히 성능에 대한)과 완전히 다른 기능 세트를 갖는 완전히 다른 짐승입니다. 따라서 PHP 7이 무엇인지를 둘러싼 혼란이나 오해를 방지하기 위해 버전이 건너 뜁니다.
잠자는 개가 거짓말을하게됩니다 . PHP 6은 실패로 여겨졌으며 많은 양의 PHP 6 코드가 여전히 PHP 저장소에 남아 있습니다. 따라서 버전 6을 지나서 다음 주요 버전에서 새로 시작하는 것이 가장 좋은 것으로 보입니다.
RFC : PHP의 다음 릴리스 이름