PHP 7 소개: 새로운 기능과 사라진 기능
게시 됨: 2022-03-112015년 PHP 세계에서 가장 흥미진진한 사건 중 하나는 PHP 7의 출시였습니다. PHP 7은 마지막 주요 버전인 PHP 5가 출시된 지 10년이 되었습니다. 한 걸음 더 나아가 PHP 7은 많은 새로운 기능과 성능 업그레이드를 도입했습니다. .
그러나 또한 사용되지 않는 이전 기능을 제거하여 일부 호환성 중단이 발생하여 이전 응용 프로그램이 새 버전으로 마이그레이션하기 더 어렵게 만듭니다. 이 가이드는 PHP 7을 기반으로 기존 애플리케이션을 옮기거나 새 애플리케이션을 구축하려는 경우 예상되는 사항에 대한 빠른 둘러보기 역할을 해야 합니다.
하지만 잠깐, PHP 6은 어디로 갔습니까?
최근에 PHP로 작업하지 않았다면 PHP 6에 무슨 일이 일어났는지 궁금할 것입니다. 왜 PHP 5에서 PHP 7로 건너뛰나요? 간단히 말해서 PHP 6은 실패했습니다. 버전 6의 주요 기능은 유니코드 문자에 대한 기본 지원이었습니다. PHP는 주로 웹 개발에 사용되고 웹은 유니코드를 필요로 하기 때문에 유니코드를 PHP로 가져오는 움직임은 의미가 있습니다.
그 아이디어는 유니코드에 대한 완전한 지원을 코어 자체에 가져오는 것이었습니다. 어리석은 이모티콘을 변수 및 함수 이름으로 사용하는 기능에서 강력한 국제 문자열 기능에 이르기까지 언어에 확장된 기능을 가져왔을 것입니다. 예를 들어, 다른 언어에서 영어와 다르게 대문자와 소문자를 사용하거나 한자의 이름을 영어로 변환해야 하는 경우입니다.
불행히도 이 야심찬 계획은 예상보다 더 큰 문제로 판명되었습니다. 코드베이스의 대부분은 핵심 확장과 중요한 확장 모두에 대해 유니코드를 지원하도록 이식되어야 했으며, 이는 지루하고 까다로웠습니다. 이로 인해 언어의 다른 기능 개발 속도가 느려져 이 과정에서 많은 PHP 개발자를 좌절시켰습니다. 추가적인 장애물이 나타났고, 그 결과 네이티브 유니코드 지원 개발에 대한 관심이 줄어들었고 결국 프로젝트가 중단되었습니다.
책과 기사와 같은 리소스는 PHP 6 및 유니코드 지원을 위해 작성되었기 때문에 혼동을 피하기 위해 새 버전의 이름은 PHP 7로 변경됩니다.
어쨌든, 슬픈 과거에 충분히 머물면서 PHP 7이 파티에 가져오는 것을 봅시다.
성능 대결, PHP 7 대 PHP 5
거의 모든 업데이트에서 사소한 성능 업그레이드가 예상됩니다. 그러나 이번에 PHP는 PHP 7의 가장 매력적인 기능 중 하나인 순수한 성능을 이전 버전에 비해 크게 개선했습니다. 이것은 Zend 엔진 자체의 내부를 다루는 "PHPNG" 프로젝트의 일부로 제공됩니다.
내부 데이터 구조를 리팩토링하고 AST(Abstract Syntax Tree) 형태의 코드 컴파일에 중간 단계를 추가함으로써 결과적으로 우수한 성능과 보다 효율적인 메모리 할당을 얻을 수 있습니다. 수치 자체는 매우 유망해 보입니다. 실제 앱에서 수행된 벤치마크에 따르면 PHP 7은 평균적으로 PHP 5.6보다 2배 빠르며 요청 시 메모리 소비가 50% 감소하므로 PHP 7은 Facebook의 HHVM JIT 컴파일러에 대한 강력한 경쟁자가 됩니다. 몇 가지 일반적인 CMS 및 프레임워크에 대한 성능을 보여주는 Zend의 이 인포그래픽을 살펴보세요.
메모리 소비의 감소는 또한 PHP를 중심으로 마이크로 서비스를 구축할 수 있는 기회와 함께 더 작은 시스템이 요청을 더 잘 처리할 수 있도록 합니다. 내부 변경, 특히 AST 구현은 성능을 더욱 향상시킬 수 있는 향후 최적화 가능성도 열어줍니다. JIT 컴파일러의 새로운 사내 구현은 향후 버전에 대해 고려되고 있습니다.
PHP 7 구문 설탕
PHP 7에는 새로운 구문 기능이 있습니다. 언어 자체의 기능을 확장하는 것은 아니지만 코드를 작성하는 것이 더 즐겁고 눈을 즐겁게 하는 더 나은 또는 더 쉬운 방법을 제공합니다.
그룹 수입 신고
이제 동일한 네임스페이스에서 시작된 클래스에 대한 가져오기 선언을 단일 use
줄로 그룹화할 수 있습니다. 이는 의미 있는 방식으로 선언을 정렬하는 데 도움이 되거나 단순히 파일에 일부 바이트를 저장하는 데 도움이 됩니다.
use Framework\Module\Foo; use Framework\Module\Bar; use Framework\Module\Baz;
PHP 7에서는 다음을 사용할 수 있습니다.
use Framework\Module\{Foo, Bar, Baz};
또는 여러 줄 스타일을 선호하는 경우:
use Framework\Module{ Foo, Bar, Baz };
Null 병합 연산자
이것은 PHP 프로그래밍의 일반적인 문제를 해결합니다. 다른 변수가 실제로 설정된 경우 다른 변수의 변수에 값을 할당하거나 그렇지 않으면 다른 값을 제공합니다. 사용자 제공 입력으로 작업할 때 일반적으로 사용됩니다.
PHP 7 이전:
if (isset($foo)) { $bar = $foo; } else { $bar = 'default'; // we would give $bar the value 'default' if $foo is NULL }
PHP 7 이후:
$bar = $foo ?? 'default';
이것은 또한 여러 변수와 연결될 수 있습니다.
$bar = $foo ?? $baz ?? 'default';
우주선 운영자
우주선 연산자 <=>
는 1,0 또는 -1을 반환하여 두 값이 같은지 여부 뿐만 아니라 불평등에 대해 더 큰 값을 나타내는 두 값 간의 3방향 비교를 허용합니다.
여기서 우리는 값이 어떻게 다른지에 따라 다른 조치를 취할 수 있습니다.
switch ($bar <=> $foo) { case 0: echo '$bar and $foo are equal'; case -1: echo '$foo is bigger'; case 1: echo '$bar is bigger'; }
비교되는 값은 정수, 부동 소수점, 문자열 또는 배열일 수 있습니다. 문서를 확인하여 서로 다른 값을 비교하는 방법에 대한 아이디어를 얻으십시오. [https://wiki.php.net/rfc/combined-comparison-operator]
PHP 7의 새로운 기능
그러나 물론 PHP 7에는 새롭고 흥미로운 기능도 포함되어 있습니다.
스칼라 매개변수 유형 및 반환 유형 힌트
PHP 7은 4가지 스칼라 유형을 추가하여 메소드(클래스, 인터페이스 및 배열)에서 매개변수의 이전 유형 선언을 확장합니다. 정수( int
), 부동 소수점( float
), 부울( bool
) 및 문자열( string
)이 가능한 매개변수 유형입니다.
또한 선택적으로 어떤 유형의 메서드와 함수가 반환되는지 지정할 수 있습니다. 지원되는 유형은 bool , int , float , string , array , callable , 클래스 또는 인터페이스 이름 , self 및 parent ( 클래스 메소드용 )
class Calculator { // We declare that the parameters provided are of type integer public function addTwoInts(int $x, int $y): int { return $x + $y; // We also explicitly say that this method will return an integer } }
유형 선언을 사용하면 보다 강력한 애플리케이션을 구축할 수 있으며 함수에서 잘못된 값을 전달하거나 반환하는 것을 방지할 수 있습니다. 다른 이점으로는 DocBlock이 누락된 경우 코드베이스에 대한 더 나은 통찰력을 제공하는 정적 코드 분석기 및 IDE가 있습니다.
PHP는 약한 유형의 언어이므로 매개변수 및 반환 유형에 대한 특정 값은 컨텍스트를 기반으로 캐스트됩니다. int
유형의 선언된 매개변수가 있는 함수에서 값 "3"을 전달하면 인터프리터는 이를 정수로 받아들이고 오류를 발생시키지 않습니다. 이것을 원하지 않으면 declare
지시문을 추가하여 strict mode
를 활성화할 수 있습니다.
declare(strict_types=1);
이것은 전역 옵션이 전역 엄격성으로 구축 된 것과 그렇지 않은 것으로 코드 리포지토리를 분할하여 둘의 코드를 결합할 때 예기치 않은 동작을 초래하기 때문에 파일별로 설정됩니다.
엔진 예외
엔진 예외를 추가하면 스크립트 종료를 초래할 수 있는 치명적인 오류를 쉽게 포착하고 처리할 수 있습니다.
존재하지 않는 메서드 호출과 같은 오류는 스크립트를 종료하지 않고 대신 try catch 블록에서 처리할 수 있는 예외를 throw하여 응용 프로그램의 오류 처리를 향상시킵니다. 치명적인 오류가 발생하면 다시 시작해야 하므로 특정 유형의 앱, 서버 및 데몬에 중요합니다. PHPUnit의 테스트는 치명적인 오류가 전체 테스트 스위트를 삭제하므로 더욱 유용해집니다. 오류가 아닌 예외는 테스트 사례별로 처리됩니다.
PHP 7은 발생할 수 있는 오류 유형에 따라 여러 가지 새로운 예외 클래스를 추가합니다. 버전 간의 호환성을 유지하기 위해 엔진 예외와 사용자 예외 모두에서 구현할 수 있는 새로운 Throwable
인터페이스가 추가되었습니다. 이것은 기본 예외 클래스를 확장하기 위해 엔진 예외를 피하기 위해 필요했으며 이전에는 없었던 오래된 코드 포착 예외가 발생했습니다.
PHP 7 이전에는 치명적인 오류와 함께 스크립트가 종료되었을 것입니다.
try { thisFunctionDoesNotEvenExist(); } catch (\EngineException $e) { // Clean things up and log error echo $e->getMessage(); }
익명의 클래스
익명 클래스는 간단한 단기 인스턴스에서 사용할 수 있는 익명 함수의 사촌입니다. 익명 클래스는 일반 객체처럼 쉽게 생성되고 사용됩니다. 다음은 문서의 예입니다.
PHP 7 이전
class MyLogger { public function log($msg) { print_r($msg . "\n"); } } $pusher->setLogger( new MyLogger() );
익명 클래스 사용:
$pusher->setLogger(new class { public function log($msg) { print_r($msg . "\n"); } });
익명 클래스는 단위 테스트, 특히 테스트 개체 및 서비스를 조롱할 때 유용합니다. 이것은 우리가 조롱하려는 인터페이스를 제공하는 간단한 객체를 생성함으로써 무거운 조롱 라이브러리와 프레임워크를 피하는 데 도움이 됩니다.

CSPRNG 함수
암호학적으로 안전한 문자열과 정수를 생성하기 위한 두 가지 새로운 기능이 추가되었습니다.
random_bytes(int $len);
길이가 $len
인 임의의 문자열을 반환합니다.
random_int(int $min, int $max);
$min
과 $max
사이의 숫자를 반환합니다.
유니코드 코드포인트 이스케이프 구문
다른 많은 언어와 달리 PHP 7 이전에는 PHP에는 문자열 리터럴, . 이 기능은 UTF-8 코드포인트를 사용하여 이러한 문자를 생성하기 위해 이스케이프 \u
시퀀스를 추가합니다. 이것은 문자를 직접 삽입하는 것보다 낫기 때문에 보이지 않는 문자와 그래픽 표현은 같지만 의미가 다른 문자를 더 잘 처리할 수 있습니다.
echo "\u{1F602}"; // outputs ‚
이것은 동작을 변경하기 때문에 \u
시퀀스가 있는 기존 코드를 중단합니다.
발전기 업그레이드
PHP의 생성기에는 몇 가지 멋진 추가 기능도 있습니다. 이제 제너레이터에는 반복 후 최종 값을 출력하는 데 사용할 수 있는 return 문이 있습니다. 이를 통해 제너레이터가 오류 없이 실행되었는지 확인하고 제너레이터를 호출한 코드가 다양한 시나리오를 적절하게 처리할 수 있습니다.
또한 제너레이터는 다른 제너레이터에서 표현식을 반환하고 산출할 수 있습니다. 이를 통해 복잡한 작업을 더 단순하고 모듈식 단위로 나눌 수 있습니다.
function genA() { yield 2; yield 3; yield 4; } function genB() { yield 1; yield from genA(); // 'genA' gets called here and iterated over yield 5; return 'success'; // This is a final result we can check later } foreach (genB() as $val) { echo "\n $val"; // This will output values 1 to 5 in order } $genB()->getReturn(); // This should return 'success' when there are no errors.
기대
이전 버전과의 호환성을 유지하면서 assert()
기능이 향상되었습니다. 프로덕션 코드에서 비용이 들지 않는 주장을 허용하고 주장이 실패할 때 사용자 지정 예외를 throw하는 기능을 제공하므로 개발 중에 유용할 수 있습니다.
assert()
는 PHP 7에서 언어 구조가 됩니다. 어설션은 개발 및 테스트 환경에서만 디버깅 목적으로 사용해야 합니다. 동작을 구성하기 위해 두 가지 새로운 지시문이 제공됩니다.
-
zend.assertions
-
1
: 코드 생성 및 실행(개발 모드)(기본값) -
0
: 코드를 생성하지만 런타임에 코드 주위를 점프합니다. -
-1
: 비용이 들지 않는 코드를 생성하지 않음(프로덕션 모드)
-
-
assert.exception
-
1
: 예외로 제공된 개체를 throw하거나 예외가 제공되지 않은 경우 새 AssertionError 개체를 throw하여 어설션이 실패하면 throw합니다. -
0
: 위에서 설명한 대로 Throwable 을 사용하거나 생성하지만 던지지 않고 해당 객체를 기반으로 경고만 생성합니다(PHP 5 동작과 호환).
-
PHP 5에서 PHP 7로의 전환 준비
주요 릴리스의 도입은 이전 기능을 변경/업데이트하거나 너무 오래되었다고 간주되거나 일정 기간 사용되지 않는 경우 제거할 수 있는 기회를 제공합니다. 이러한 변경으로 인해 이전 응용 프로그램의 호환성이 중단될 수 있습니다.
이러한 버전 도약으로 인해 발생하는 또 다른 문제는 의존하는 중요한 라이브러리와 프레임워크가 아직 최신 버전을 지원하도록 업데이트되지 않았을 수 있다는 것입니다. PHP 팀은 새 변경 사항을 가능한 한 이전 버전과 호환되도록 하고 새 버전으로의 마이그레이션이 가능한 한 고통스럽지 않도록 하려고 노력했습니다. 더 최신의 최신 앱은 새 버전으로 이동하는 것이 더 쉬워야 하는 반면, 이전 앱은 비용보다 이점이 더 큰지 여부를 결정해야 하며 업데이트를 선택하지 않을 수도 있습니다.
대부분의 휴식은 경미하고 쉽게 완화될 수 있지만 다른 휴식은 더 많은 노력과 시간이 필요할 수 있습니다. 기본적으로 PHP 7을 설치하기 전에 애플리케이션에 사용 중단 경고가 있는 경우 수정될 때까지 애플리케이션을 중단시키는 오류가 발생할 수 있습니다. 경고를 받았죠?
이전 SAPI 및 확장
가장 중요한 것은 mysql
확장처럼 오래되고 더 이상 사용되지 않는 SAPI가 제거되었다는 것입니다. 확장 및 제거된 기능의 전체 목록을 보려면 여기와 여기에서 이 RFC를 확인할 수 있습니다.
또한 다른 SAPI가 PHP 7로 이식되고 있습니다.
균일 변수 구문
이 업데이트는 가변 변수 구성에 대한 일관성을 위해 몇 가지를 변경했습니다. 이렇게 하면 변수를 사용하여 고급 표현식을 사용할 수 있지만 아래와 같이 일부 다른 경우에는 동작이 변경됩니다.
// old meaning // new meaning $$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']()
이렇게 하면 이와 같은 값에 액세스하는 응용 프로그램의 동작이 중단됩니다. 반면에 다음과 같이 깔끔한 작업을 수행할 수 있습니다.
// Nested () foo()(); // Calls the return of foo() $foo->bar()(); // IIFE syntax like JavaScript (function() { // Function body })(); // Nested :: $foo::$bar::$baz
이전 스타일 태그 제거됨
여는/닫는 태그 <% ... %>
, <%= ... %>
, <script language="php"> ... </script>
가 제거되어 더 이상 유효하지 않습니다. 유효한 것으로 교체하는 것은 쉬울 것입니다. 그러나 그것을 사용하여 무엇을하고 있습니까, Weirdo?
클래스, 인터페이스 및 특성에 대한 잘못된 이름
매개변수 및 반환 유형과 같은 추가로 인해 클래스, 인터페이스 및 특성은 더 이상 다음 이름을 가질 수 없습니다.
- 부울
- 정수
- 뜨다
- 끈
- 없는
- 진실
- 거짓
이로 인해 기존 애플리케이션과 이를 사용하는 라이브러리가 중단되지만 수정하기 쉬워야 합니다. 또한 오류를 일으키지 않고 유효하지만 다음은 향후 사용을 위해 예약되어 있으므로 사용해서는 안 됩니다.
- 자원
- 물체
- 혼합
- 숫자
그것들을 사용하지 않는 것은 미래에 그것들을 변경하는 작업을 절약해야 합니다.
호환성을 깨는 변경 사항의 전체 목록은 이 문서를 확인하십시오.
코드를 확인하고 PHP 7로 이동할 때 나타날 수 있는 잠재적인 문제를 감지할 수 있는 php7cc를 사용할 수도 있습니다. 그러나 물론 PHP 7을 설치하고 직접 확인하는 것보다 더 좋은 방법은 없습니다.
잠재적인 PHP 7 호환성 문제
PHP 7 인프라 호환성
많은 호스팅 서비스가 PHP 7에 대한 지원을 추가하기 시작했습니다. 이는 성능 향상으로 인해 하드웨어의 클라이언트 웹 사이트 수를 늘리고 운영 비용을 줄이며 마진을 높일 수 있기 때문에 공유 호스팅 제공자에게 희소식입니다. 클라이언트 자체에 관해서는 이러한 조건에서 너무 많은 향상을 기대해서는 안되지만 공평하게 공유 호스팅은 어쨌든 성능 지향적인 선택이 아닙니다.
반면에 가상 사설 서버 또는 전용 서버를 제공하는 서비스는 이러한 성능 향상의 모든 이점을 누릴 수 있습니다. Heroku와 같은 일부 PaaS 서비스는 초기에 PHP 7을 지원했지만 AWS Beanstalk 및 Oracle의 OpenShift와 같은 다른 서비스는 뒤쳐져 있습니다. PHP 7이 이미 지원되는지 또는 가까운 시일 내에 지원이 제공될지 확인하려면 PaaS 제공업체의 웹사이트를 확인하십시오.
물론 IaaS 제공업체를 통해 하드웨어를 제어하고 PHP 7을 설치할 수 있습니다(또는 원하는 경우 컴파일). PHP 7 패키지는 이미 주요 IaaS 환경에서 사용할 수 있습니다.
PHP 7 소프트웨어 호환성
인프라 호환성 외에도 잠재적인 소프트웨어 호환성 문제도 염두에 두어야 합니다. WordPress, Joomla 및 Drupal과 같은 인기 있는 콘텐츠 관리 시스템은 최신 릴리스에서 PHP 7에 대한 지원을 추가했습니다. Symfony 및 Laravel과 같은 주요 프레임워크도 전폭적인 지원을 받습니다.
그러나 주의가 필요한 시점입니다. 이 지원은 추가 기능, 플러그인, 패키지 또는 CMS나 프레임워크에서 호출하는 형식의 타사 코드로 확장되지 않습니다. 그들은 호환성 문제로 고통받을 수 있으며 모든 것이 PHP 7에 대해 준비되었는지 확인하는 것은 귀하의 책임입니다.
활성 상태로 유지 관리되는 리포지토리의 경우 이는 문제가 되지 않습니다. 그러나 PHP 7 지원이 부족한 오래되고 유지 관리되지 않는 리포지토리는 전체 앱을 사용할 수 없게 만들 수 있습니다.
PHP의 미래
PHP 7의 릴리스는 오래되고 사용되지 않는 코드를 제거하고 향후 새로운 기능과 성능 업그레이드를 위한 길을 열었습니다. 또한 PHP는 곧 추가 성능 최적화를 얻을 것으로 예상됩니다. 이전 릴리스와의 호환성 중단에도 불구하고 대부분의 문제는 쉽게 해결할 수 있습니다.
라이브러리와 프레임워크는 현재 코드를 PHP 7로 마이그레이션하여 최신 버전을 제공하고 있습니다. 직접 사용해보고 결과를 확인하는 것이 좋습니다. 아마도 귀하의 애플리케이션이 이미 호환되어 PHP 7을 사용하고 이점을 얻을 수 있을 것입니다.