PHP의 언어적 능력이 강화되고 사용자가 늘면서 CI(Code Igniter), 심포니(Symfony), CakePHP, Slim 그리고 이 책에서 다루는 라라벨등 다양한 PHP 프레임워크가 개발되었습니다.


하지만 PHP 는 커뮤니티 차원에서 표준화 작업이 부재하다 보니 프레임워크나 라이브러리마다 설치와 사용법이 상이했고 서로 호환성이 떨어지는 문제가 있었습니다.


이로 인해 프레임워크나 라이브러리를 사용하면 종속되어 버리는 문제를 해결하고 각 프레임워크이나 애플리케이션간의 상호 운용성을 확보하기 위한 요구가 커뮤니티를 통해서 증대되었습니다.


PHP 프레임워크 상호 운영성 그룹((PHP-FIG; PHP Framework Interop Group - http://www.php-fig.org)은 Drupal, Laravel, Symfony, CakePHP, Composer 등을 만든 권위있는 PHP 개발자들이 모인 커뮤니티 그룹으로서 PHP 언어와 프레임워크를 더욱 유연하고 상호 운용 가능하게 만들수 있도록 사실상의 표준을 제정하는 그룹입니다.


Java 의 자바 커뮤니티 프로세스에서 제정되는 자바 스펙 요구서(JSR; Java Specification Request) 처럼 PHP 표준 권고(PSR; PHP Standard Recommendation) 이라는 규약을 제정하고 있으며 현재 총 5개의 규약이 통과되었습니다.


이로써 이를 지킨 프레임워크과 애플리케이션은 서로 호환성을 제공하여 PHP의 생태계는 더욱 발전하였고 개발자는 손쉽게 코드를 다른 프레임워크으로 이식하거나 여러 프레임워크의 장점을 손쉽게 사용할 수 있게 되었습니다.

실제로 라라벨은 모든 기능을 전부 구현하지 않고 심포니 프레임워크의 일부 기능을 그대로 차용(http://symfony.com/projects/laravel)하여 내부에 사용하고 있을 정도로 PSR 을 지키면 상호 운용성이 매우 높아지게 됩니다.


PSR 각 규약의 대략적인 내용을 정리하면 다음과 같습니다.


PSR-0 Autoloading Standard

autoloader 를 통해 클래스를 손쉽게 로딩할 수 있도록 하는 표준입니다. PSR-4 가 제정되면서 무효화 되었습니다. PSR-4 는 PHP-5.4 이상에서 사용 가능하므로 5.3 을 사용할 경우 PSR-0 을 따라야 합니다.


PSR-1 Basic Coding Standard

표준 코딩 스타일을 제시하는 표준으로 주요 내용은 다음과 같습니다. 

  • PHP 파일은 BOM(Byte Order Mark) 없는 UTF-8 인코딩을 사용할 것.
  • 네임스페이스와 클래스는 오토로딩 표준(PSR-0, PSR-4)을 따를 것.

    <?php
    namespace Vendor\Model;
    
    class Foo
    {
    }
    CODE
  • 클래스 이름은 반드시 StudlyCaps 와 같이 첫 글자를 대문자로 할 것 

  • 클래스내 상수는 반드시 모두 대문자로 작성하고 구분자로 _ 를 사용할 것

    <?php
    namespace Vendor\Model;
     
    class Foo
    {
        const VERSION = '1.0';
        const DATE_APPROVED = '2012-06-01';
    }
    CODE
  • 클래스내 메소드의 이름은 반드시 camelCase() 처럼 카멜케이스(camelCase) 를 사용할 것. 


PSR-2 Coding Style Guide

PSR-1 표준의 연장선인 코딩 스타일에 대한 표준으로서 공통된 스타일을 사용하여 가독성이 좋도록 더욱 구체적인 코딩 스타일을 가이드하고 있습니다.  주요 내용은 다음과 같습니다.

  • 들여 쓰기는 tab 대신 4칸의 공백 사용
  • 닫는 태그(?>) 는 사용하지 않음
  • namespace  선언뒤에는 한 줄의 공백을 사용하고 여러 개의 use는 줄 공백없이 사용후에 마지막 블록뒤에 한 줄의 공백을 사용할 것 

  • 클래스 구문의 여는 괄호는 다음 줄에 사용하고 닫는 괄호는 본문 다음 줄에 사용할 것
  • 메소드 구문의 여는 괄호는 다음 줄에 사용하고 닫는 괄호는 본문 다음 줄에 사용할 것
  • 가시성과 관련된 키워드인 abstract 과 final 은 모든 메소드와 프로퍼티에 명시적으로 사용하고 제일 먼저 와야 하며 static 구문은 그 후에 위치시킬 것
  • if 나 elseif 같은 제어 관련 구문은 제어문 뒤에 한 개의 공백을 두고 그 후에 괄호를 사용하고 조건문을 기술할 것. 함수 호출이나 메소드 호출은 메소드명 뒤에 공백이 있으면 안 됨,
  • if 나 elseif 같은 제어 관련 구문의 여는 괄호는 제어문과 같은 줄에 위치해야 함. 닫는 괄호는 본문의 다음 줄에 위치

다음은 PSR-2 를 준수한 코딩 스타일 예제입니다.
<?php
namespace Vendor\Package;
 
use FooInterface;
use BarClass as Bar;
 
class Foo extends Bar implements FooInterface
{
    public function sampleFunction($a, $b = null)
    {
		if ($a === $b) {
            bar();
        } elseif ($a > $b) {
            $foo->bar($arg1);
        }
	}
}
CODE


PSR-3 Logger Interface

로깅 장치(파일, 소켓, 데이타베이스등)에 상관없이 애플리케이션 로그를 남기기 위한 표준입니다. 다른 로깅 프레임워크를 사용해도 애플리케이션 수정이 없도록 

Psr\Log\LoggerInterface 인터페이스를 정의하고 이를 구현하도록 하고 있습니다. debug, info, notice, warning, error, critical, alert, emergency, log 총 아홉 개의 메소드를 지정하고 있으며 9번째 메소드인 log 를 제외하고 레벨에 따라 해당 메소드를 호출하면 됩니다.

log 메소드는 파라미터로 레벨을 지정할 수 있도록 정의되어 있습니다. PSR-3 를 구현한 가장 유명한 PHP 라이브러리는 MonoLog(https://github.com/Seldaek/monolog) 로 다음과 같이 로그 객체를 만들고 로그를 기록할 수 있습니다.

<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

// create a log channel
$log = new Logger('name');
$log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));

// add records to the log
$log->addWarning('Foo');
$log->addError('Bar');
CODE

라라벨은 모노로그를 지원하며 간편한 레이어를 제공하므로 다음과 같이 간단하게 사용할 수 있습니다.

Log::warning('Foo');
Log::error('Bar');
CODE


PSR-4 Autoloader

PHP 5 에 오토로딩 기능이 추가되었지만 라이브러리를 오토로딩하려면 직접 spl_autoload_register 메소드를 호출하여 일일이 등록해야 합니다. 외부 라이브러리를 사용할 경우 일일이 이를 등록하는 것은 만만한 작업이 아닙니다.

PSR-4 는 PSR-0 을 대체하는 새로운 오토로딩 표준으로 다음과 같이 정규화된 클래스 이름(FQCN; Fully Qualified Class Name) 을 규정하고 있으며 이를 준수하여 패키지를 개발할 경우 패캐지 관리자인 컴포저를 통해 손쉽게 의존성 있는 모든 패키지를 로딩할 수 있습니다.

\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
CODE

컴포저는 vendor/autoload.php 파일을 생성하므로 개발자는 다음과 같이 한 줄만 추가하면 include나 require를 사용하지 않고도 편리하게 개발할 수 있습니다.

<?php
require 'vendor/autoload.php';
CODE


여기에서 NamespaceName 은 최상위 네임스페이스(일반적으로 회사명이나 개인의 id 를 사용합니다)를 설정하고 SubNamespaceNames 은 하위 네임스페이스를 ClassName 은 클래스 이름을 입력합니다.


로깅 프레임워크인 MonoLog 의 경우 다음과 같이 네임스페이스를 사용하고 있습니다. 

<?php
namespace Monolog\Handler;
 
class FilterHandler extends AbstractHandler
{
CODE

네임스페이스는 실제 디렉터리에 일치하며 최종 php 소스 파일은 클래스명.php 로 존재하게 됩니다.

예로 FilterHandler를 구현한 파일은 src/Monolog/Handler/FilterHandler.php 에 위치하게 됩니다.


PSR-7 HTTP Message Interface

가장 최근에 통과되었으며 PHP에서 HTTP 에서 데이타를 주고 받기 위한 클래스와 메소드, 인터페이스등을 정의한 규약입니다.


사용하는 HTTP 라이브러리가 PSR-7 을 준수한다면 소스 변경없이 다른 PSR-7 구현물로 교체할수 있습니다.

PSR-7 을 구현한 라이브러리중 유명한 제품으로는 아마존이 후원하는 guzzle(https://github.com/guzzle/guzzle) 이 있으며 AWS(Amazon Web Service) 의 PHP SDK 는 guzzle 을 사용하여 HTTP 를 처리하고 있습니다.


같이 보기