PHP 5.x vs PHP 7 syntax

PHP 7에서는 PHP를 완전히 다시 설계했을 정도로 큰 속도 향상을 가져왔습니다.  기존 PHP 5에서 사라지거나 새로운 기능을 정리해보도록 하겠습니다. 

 

POSIX 정규 표현식 함수의 폐지
5.3에서 deprecated 였는데 함수가 제거되었습니다. 영향을 받는 것은 다음 함수입니다.

ereg (), eregi (), ereg_replace () eregi_replace, split () spliti () sql_regcase ()

ereg와 관련된 대부분의 기능이 제거되고 preg_match와 preg_replace 등의 PCRE 계열 함수를 사용할 수 있습니다.

ext/mysql 확장 폐지

5.5에서 deprecated 였는데 mysql_ 함수들이 제거되고 PDO와 mysqli로 대체 되었습니다. "mysql_"로 시작하는 함수는 사용할 수 없습니다. 

가변 변수의 새로운 기술 방법
다차원 배열을 가변 변수로 사용시 ${$var[ 'foo'][ 'bar']}처럼 {}를 사용하였습니다만 PHP7에서는 ($$var)['foo']['bar']로 표현할 수 있습니다. 
클래스 메소드나 속성의 경우는 다음과 같이합니다

// PHP 5.x;
$var->{$prop['key']};
$var->{$prop['key']}();
  
// PHP 7;
($var->$prop)['key'];
($var->$prop)['key']();

::(콜론) 클래스의 상수와 메소드 접근
클래스의 상수와 static 메소드에 관해 ":"를 중첩해 사용할 수 있습니다.

$var::$class::$constant

함수가 반환하는 값에 직접 액세스하기
함수가 돌려 준 callable(콜백)과 callable을 가지는 변수에서 직접 호출할 수 있습니다.

foo()();
$foo()();
$foo()['bar']();

무명 클래스 지원
"class"를 사용하여 일회성 무명 클래스(Anonymous Class)를 만들 수 있습니다.

$object = new class("Hello") {
    public $var;
    public function __construct($arg) {
        $this->var = $arg;
    }
};

use 그룹화
use를 이용할 때 네임 스페이스를 그룹화해 여러 클래스를 일괄 지정할 수 있게 되었습니다.

// 5.x
use Vendor\ComponentA\ClassA;
use Vendor\ComponentA\ClassB;
use Vendor\ComponentA\ClassC as Foo;
  
use Vendor\ComponentB\ClassD;
use Vendor\ComponentC\ClassE;
  
// 7.0
use Vendor\ComponentA\{
    ClassA,
    ClassB,
    ClassC as Foo
};
  
use Vendor\{
    ComponentB\ClassD,
    ComponentC\ClassE
};

 

Null Coalesce 연산자 추가

지금까지는 null이 될 수 있는 값을 아래처럼 삼항 연산자로 비교하곤 했습니다.

$ foo = isset ($ bar)? $ bar : $ baz;

PHP7에서는 새로운 연산자 ?? 를 사용하여 좀 더 쉽게 쓸 수 있게 되었습니다.

$ foo = $ bar ?? $ baz;

우주선 연산자 (<=>)의 추가

우주선 연산자 (Spaceship-Operator)라고 자주 불리는 "<=>"비교 연산자가 추가되었습니다. 

두 값이 같으면 0을, 왼쪽의 값이 작으면 -1, 크면 +1 반환합니다.

배열을 이용한 상수

define()를 사용해서 상수 선언할 때 배열을 지정할 수 있게 되었습니다.

preg_replace_callback_array() 함수의 추가

preg_replace_callback_array() 정규식 패턴과 대체 처리를 배열의 형태로 부여해 각각의 처리를 동시에 할 수 있습니다.

dirname() 함수의 강화

경로 문자열에서 디렉토리 이름을 반환하는 dirname()에 제 2 인수를 지정할 수 있게 되어, 몇 번째 디렉토리 이름을 취득할 것인지 지정할 수 있게 되었습니다.

$path = '/dir1/dir2/dir3/example.txt';
dirname($path, 2); // "/dir1/dir2"

password_hash ()의 salt 옵션 폐지

password_hash ()에 수동으로 salt를 설정하는 옵션이 있었지만 폐지되었습니다. 사용시에는 E_DEPRECATED가 발생합니다.

assert () 언어 구조화

디버깅에 사용해온 assert ()가 함수에서 언어 문법에 포함되어 식을 직접 지정할 수 있어 프로덕션 환경에서 오버헤드가 없어졌습니다.

try~catch에서 다루는 오류 종류의 확대

5.x에서는 불가능했던 PHP의 일반적 오류가 "\Error"로 잡을 수 있게 되었습니다. 그 외에도 "\ParseError" 이나 "\TypeError" 등의 오류도 다룰 수 있습니다.

Unicode 확장 영역에 대응

Unicode 문자 관한 많은 기능을 가진 IntlChar가 도입되 이모티콘 등의 명칭을 산출하거나 영숫자 여부 판정 할 수 있는 기능이 추가되었습니다.

타입 힌팅 강화

변수가 배열 또는 콜백인지 명시하는 기능은 PHP 5.x에도 있었습니다만 사용할 수 있는 유형이 늘어나 다음과 같은 형식도 지정할 수 있게되었습니다.
· bool 
· float 
· int 
· string

함수 function( int $foo )라고 했을때, "100 "등의 문자열을 넘겨 주면 int 형의 100로 변환됩니다. 
declare() 함수에서 "strict_types = 1"로 지정하면 자동 변환을 무효화하고 적절한 형태의 값이 주어지지 않은 경우 "\TypeError"을 발생시킬 수 있습니다.

반환 값도 타입 힌팅을 사용할 수 있으며 다음과 같이 지정합니다.
function example(string $str): int
{
    //
}

namespace 활용하기

네임스페이스를 쓰기 전까지는 include_once()를 남발하여 어디에서 온 라이브러리인지 확인하기 어렵고 충돌이 발생할 우려가 컷습니다. 

<?php
// lib/haruair/function.php
function HelloWorld() {
  return "HelloWorld";
}
?>
<?php
// lib/wordpress/function.php
function HelloWorld() {
  return "HelloWorld. I'm wordpress btw.";
}
?>
<?php
// app.php
include_once('./lib/haruair/helloWorld.php');
include_once('./lib/wordpress/helloWorld.php');
// PHP Fatal error:  Cannot redeclare HelloWorld()
?>

네임스페이스를 다음과 같이 선언하는 것으로 클래스를 네임스페이스 아래로 배정할 수 있습니다. 

<?php // lib/haruair/helloWorld.php
namespace Haruair;
class HelloWorld {
  function say() {
    return "HelloWorld";
  }
}
?>
<?php // lib/wordpress/helloWorld.php
namespace WordPress;
class HelloWorld {
  function say() {
    return "HelloWorld. I'm wordpress btw.";
  }
}
?>

이러면 다음 코드와 같이 한 파일에서 사용하는데 전혀 문제가 없습니다. 

<?php // app.php
include_once('./lib/haruair/helloWorld.php');
include_once('./lib/wordpress/helloWorld.php');
$haruair = new Haruair\HelloWorld();
$wordpress = new WordPress\HelloWorld();
echo $haruair->say(); // HelloWorld
echo $wordpress->say(); // HelloWorld. I'm wordpress btw.
?>

 

autoloader 활용하기

php에서 미리 선언한 함수나 클래스를 사용하려면 당연하게 include나 require 같은 내장 함수를 활용했어야 합니다. 하지만 spl_autoload_register 함수를 선언하면 파일을 필요로 할 때 불러오는 방식으로 구현할 수 있습니다.

다음 코드를 봅시다.

<?php
include_once('./src/haruair/event/ticket.php');
include_once('./src/haruair/event/attendee.php');
include_once('./src/haruair/event/coupon.php');
$ticket = new Haruair\Event\Ticket;
$attendee = new Haruair\Event\Attendee;
$coupon = new Haruair\Event\Coupon;
?>

이제 직접 include 하는 것이 아니라 autoloader를 활용해서 불러오도록 해 봅시다.

<?php
spl_autoload_register(function ($class) {
    // 프로젝트에 따른 네임스페이스 프리픽스
    $prefix = '';
    // 네임스페이스 프리픽스를 위한 기본 디렉토리 경로
    $base_dir = __DIR__ . '/src/';
    // 네임스페이스 프리픽스에 해당하는지 검사
    $len = strlen($prefix);
    if (strncmp($prefix, $class, $len) !== 0) {
        // 찾지 못했으므로 반환. 만약 다른 오토로드 함수가 등록되어 있다면 순차적으로 실행함.
        return;
    }
    // 네임스페이스를 제외한 상대 클래스명 찾기
    $relative_class = substr($class, $len);
    // 네임스페이스 프리픽스를 기본 디렉토리 경로로 치환, 네임스페이스 구분자를 디렉토리 구분자로
    // 전환하고 .php를 끝에 추가함
    $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
    // 파일이 존재하면 불러옴
    if (file_exists($file)) {
        require $file;
    }
});
$ticket = new Haruair\Event\Ticket;
$attendee = new Haruair\Event\Attendee;
$coupon = new Haruair\Event\Coupon;
// autoloader를 호출한다.
?>

 

함수의 타입 지정

기본적인 함수의 정의는 다음과 같이 선언 합니다.

function sum($x, $y) // 함수의 이름은 sum()이며, 변수 x, y를 매개변수로 가지는 함수를 정의함.
{
    return $x + $y;  // 매개변수 x, y를 더한 값을 반환함.
}
echo sum(1, 2);      // sum() 함수에 숫자 1와 2을 인수로 전달하여 호출함.

PHP 7부터는 함수의 반환값을 원하는 타입으로 반환받을 수 있도록, 반환값의 타입을 직접 지정할 수 있습니다.

또한, 반환값의 타입을 지정할 때 그 강도도 설정할 수 있습니다. 기본값인 약한 강도에서는 타입이 일치하지 않으면, 자동 타입 변환을 통해 명시된 타입으로 변환된 반환값을 반환합니다.

하지만 강한 강도에서는 반환값의 타입이 일치하지 않으면, 오류를 발생시킵니다.

function sum($x, $y) : float // 반환값의 타입을 float 타입으로 설정함.
{
    return $x + $y;
}
...
var_dump(sum(3 + 4)); // float  약한 감도이기 때문에 에러 없음

 반환 타입이 float 타입으로 설정되어 있으므로, 덧셈 연산의 결과가 int 타입에서 float 타입으로 자동 변환되어 반환됩니다.

만일 강한 강도록 함수의 반환 타입을 설정하면 에러가 됩니다. 

declare(strict_types = 1);   // strict 모드로 설정함.
 
function sum($x, $y) : float // 반환값의 타입을 float 타입으로 설정함.
{
    return $x + $y;
}
...
① var_dump(sum(3 + 4));   // 오류가 발생함.
② var_dump(sum(3 + 4.5)); // float

PHP 7부터 제공되는 strict 모드는 지금까지의 자동 변환으로 느슨하게 처리되던 타입 검사를 엄격하게 수행하도록 변경합니다.

strict 모드에서는 해당 위치에 나올 수 있는 적절한 타입 이외의 값이 나올 경우 타입 변환을 하지 않고 오류를 발생시킵니다.

 

문자열 관련 함수

 

문자열의 길이

strlen() 함수는 전달받은 문자열의 길이를 반환합니다.

이때 문자열의 길이란 문자열에 포함된 문자의 개수를 의미합니다.

$str = "12345678";
echo strlen($str); // 8

 한글이 포함된 문자열의 정확한 문자열 길이를 반환받기 위해서는 mb_strlen() 함수를 사용해야 합니다.

mb_strlen() 함수는 문자열뿐만 아니라 두 번째 인수로 인코딩 방식까지 전달받을 수 있습니다. 이렇게 전달받은 인코딩 방식으로 해당 문자열을 해석하여 정확한 문자열의 길이를 반환해 줍니다.

만약 두 번째 인수를 전달받지 못하면, 현재 시스템의 내부 인코딩 방식을 사용할 것입니다.

$str = "한글로된문자열";
 
echo strlen($str);             // 7 * 3 = 21
echo mb_strlen($str);          // 7 * 3 = 21
echo mb_strlen($str, "UTF-8"); // 7
 

Note:UTF-8 인코딩 방식에서는 영문자는 한 문자당 1바이트, 한글은 한 문자당 3바이트로 표현됩니다.

 

문자열 비교하기

strcmp() 함수는 전달받은 두 개의 문자열을 서로 비교합니다. 첫 번째 인수의 문자열이 두 번째 인수의 문자열보다 크면 양수를, 작으면 음수를 반환합니다.

이때 strcmp() 함수는 비교할 때 대소문자를 구분합니다. 하지만 strncasecmp()함수를 사용하면 대소문자를 구분하지 않고 두 개의 문자열을 비교할 수 있습니다.

strnatcmp() 함수는 strcmp() 함수와 비슷하며, strnatcasecmp() 함수는 strcasecmp() 함수와 비슷합니다. 차이점으로는 strnatcmp() 함수와 strnatcasecmp() 함수는 영숫자 순(natural ordering)으로 문자열을 비교한다는 점입니다.

echo strcmp("abc", "ABC");     // 양수
echo strcasecmp("abc", "ABC"); // 0
echo strcmp("2", "10");        // 양수
echo strnatcmp("2", "10");     // 음수

 

 

 

 

youngdeok의 이미지

Language

Get in touch with us

"어떤 것을 완전히 알려거든 그것을 다른 이에게 가르쳐라."
- Tryon Edwards -