안녕하세요!
2016년도에 작성한 문서입니다.
기존에 PHP5에 익숙하신 분들이 새로이 PHP7이 나오면서,
간략하게 나마 무엇이 바뀌었는지,
그리고 PHP 프레임워크를 시작하기 전에 표준적인 코딩은 어떤 것인지 알아보기 위해 문서를 작성하였습니다.
많은 분들에게 도움이 되길 바라며!! ^^
* 참고 : PHP 5.5.9 이상 버전에서도 위 예제코드가 됩니다! >.<
3. 세부
1. PHP 표준 권고 (PSR)
2. 네임스페이스
3. 간결한 배열 문법
4. 트레이트
5. 클래스 오토로딩
6. 익명 함수
7. 동적 프로퍼티/메소드 생성
8. ::class 키워드로 클래스 이름 결정
9. 타입 힌팅
4. 1. PHP 표준 권고 (PSR)
• PHP 프레임워크 상호 운영성 그룹((PHP-FIG; PHP Framework Interop
Group - http://www.php-fig.org)은 Drupal, Laravel, Symfony, CakePHP,
Composer 등을 만든 권위있는 PHP 개발자들이 모인 커뮤니티 그룹
• 프레임워크나 라이브러리를 사용하면 종속되어 버리는 문제를 해결하
고 각 프레임워크이나 애플리케이션간의 상호 운용성을 확보하기 위
한 PHP 표준 권고(PSR; PHP Standard Recommendation) 이라는 규약을
제정
• Coding Style : PSR-1(Basic), PSR-2
• AutoLoading : PSR-4
• Interfaces : PSR-3(Logger), PSR-6(Caching), PSR-7(HTTP Message)
5. 1-1. PSR-1 Basic Coding Standard
• Files MUST use only <?php and <?= tags.
• Files MUST use only UTF-8 without BOM for PHP code.
• Namespaces and classes MUST follow an "autoloading" PSR: [PSR-0,
PSR-4].
• 클래스 이름은 반드시 StudlyCaps 와 같이 첫 글자를 대문자로 할
것
• 클래스내 상수는 반드시 모두 대문자로 작성하고 구분자로 _ 를
사용할 것
• 클래스내 메소드의 이름은 반드시 camelCase() 처럼 카멜케이스
(camelCase) 를 사용할 것.
1
2
3
4
5
6
7
8
9
10
11
<?php
namespace VendorModel;
class Foo
{
const VERSION = '1.0';
const DATE_APPROVED = '2012-06-01';
function camelCase(){
}
}
6. 1-2. PSR-2 Coding Style Guide
• 들여 쓰기는 tab 대신 4칸의 공백 사용
• 닫는 태그(?>) 는 사용하지 않음
• namespace 선언뒤에는 한 줄의 공백을 사용하고 여러 개의 use는 줄 공백없이
사용후에 마지막 블록뒤에 한 줄의 공백을 사용할 것
• 클래스 구문의 여는 괄호는 다음 줄에 사용하고 닫는 괄호는 본문 다음 줄에 사용할 것
• 메소드 구문의 여는 괄호는 다음 줄에 사용하고 닫는 괄호는 본문 다음 줄에 사용할 것
• 가시성과 관련된 키워드인 abstract 과 final 은 모든 메소드와 프로퍼티에 명시적으로 사용하고 제일 먼
저 와야 하며 static 구문은 그 후에 위치시킬 것
• if 나 elseif 같은 제어 관련 구문은 제어문 뒤에 한 개의 공백을 두고 그 후에 괄호를 사용하고 조건문을
기술할 것. 함수 호출이나 메소드 호출은 메소드명 뒤에 공백이 있으면 안 됨,
• if 나 elseif 같은 제어 관련 구문의 여는 괄호는 제어문과 같은 줄에 위치해야 함. 닫는 괄호는 본문의 다
음 줄에 위치
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
namespace VendorPackage;
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);
}
}
}
7. 1-3. PSR-4 : AutoLoader
• PHP 5 에 오토로딩 기능이 추가되었지만 라이브러리를 오토로딩하려면 직접 spl_autoload_register 메소드를 호출하여 일일이 등록해야 합니
다. 외부 라이브러리를 사용할 경우 일일이 이를 등록하는 것은 만만한 작업이 아닙니다.
• PSR-4 는 PSR-0 을 대체하는 새로운 오토로딩 표준으로 다음과 같이 정규화된 클래스 이름(FQCN; Fully Qualified Class Name) 을 규정하고 있으
며 이를 준수하여 패키지를 개발할 경우 패캐지 관리자인 컴포저를 통해 손쉽게 의존성 있는 모든 패키지를 로딩할 수 있습니다.
<NamespaceName>(<SubNamespaceNames>)*<ClassName>
• 컴포저는 vendor/autoload.php 파일을 생성하므로 개발자는 다음과 같이 한 줄만 추가하면 include나 require를 사용하지 않고도 편리하게 개발
할 수 있습니다.
<?php
require 'vendor/autoload.php';
• 여기에서 NamespaceName 은 최상위 네임스페이스(일반적으로 회사명이나 개인의 id 를 사용합니다)를 설정하고 SubNamespaceNames 은 하
위 네임스페이스를 ClassName 은 클래스 이름을 입력합니다.
8. 2. 네임스페이스
선언 Defining [Wiki2.php] 사용 Using
<?php
namespace Wiki2Sub;
Class Book{
public function show(){
echo "test2";
}
}
<?php
include "Wiki2.php";
use Wiki2SubBook as wiki2;
$c = new wiki2();
$c->show();
• http://php.net/manual/kr/language.namespaces.rationale.php
9. 3. 간결한 배열 문법
변경 전 변경 후
<?php
$arr = array(
"name1" => "test1",
"name2" => "test2",
);
<?php
$arr = [
"name1" => "test1",
"name2" => [
"name_sub1"=>"test_sub1",
"name_sub2"=>"test_sub2",
],
];
• array() 문법대신 간단하게 [ ] 로 배열을 기술
10. 4. 트레이트 (trait)
• http://php.net/language.oop5.traits
• 코드 재사용 기법
• class 대신 trait이라는 키워드를 사용
• 우선순위 : trait, class
<?
trait HelloWorld {
public function sayHello() {
echo 'Hello World!';
}
}
class TheWorldIsNotEnough {
use HelloWorld;
public function sayHello() {
echo 'Hello Universe!';
}
}
$o = new TheWorldIsNotEnough();
$o->sayHello();
>> Hello World!
11. 5. 클래스 오토로딩 Class Autoloading
• http://php.net/manual/kr/languag
e.oop5.autoload.php
• http://php.net/manual/kr/function
.spl-autoload-register.php
• 1-3 PSR-4 AutoLoader 참조
<?php
spl_autoload_register('MyClassLoader::LibraryLoader');
spl_autoload_register('MyClassLoader::DatabaseLoader');
class MyClassLoader
{
public static function LibraryLoader($class)
{
include 'libraries/' . $class. '.php';
}
public static function DatabaseLoader ($class)
{
include 'databases/' . $class. '.php';
}
}
12. 6. 익명함수 (annoymous function)
• http://php.net/manual/kr/languag
e.oop5.anonymous.php
• http://modernpug.github.io/php-
the-right-way/pages/Functional-
Programming.html
• 클로져 또는 콜백이라고도 함
?php
$input = array(1, 2, 3, 4, 5, 6);
// 익명 함수를 하나 만들어서 변수에 대입
$filter_even = function($item) {
return ($item % 2) == 0;
};
// array_filter 내장 함수는 배열과 함수를 인자로 받는다.
$output = array_filter($input, $filter_even);
// 익명 함수를 변수에 할당해서 전달할 필요없이 이렇게 하는 것도 가능
하다.
$output = array_filter($input, function($item) {
return ($item % 2) == 0;
});
print_r($output);
13. 7. 동적 프로퍼티/메소드 생성
• http://php.net/manual/kr/languag
e.oop5.overloading.php
• __set, __get [프로퍼티] ,
• __call, __callStatic [메서드] 등으
로 동적으로 변수, 메서드를 생성
<?php
class MethodTest
{
public function __call($name, $arguments)
{
// 주의: $name 의 값은 대소를 구분합니다.
echo "Calling object method '$name' "
. implode(', ', $arguments). "n";
}
/** PHP 5.3.0 이후 */
public static function __callStatic($name, $arguments)
{
// 주의: $name 의 값은 대소를 구분합니다.
echo "Calling static method '$name' "
. implode(', ', $arguments). "n";
}
}
$obj = new MethodTest;
$obj->runTest('in object context');
MethodTest::runTest('in static context'); // As of PHP 5.3.0
14. 8. 스코프 해결 연산자 (::)
• http://php.net/manual/kr/languag
e.oop5.paamayim-
nekudotayim.php
• className::Method/Property
<?php
class MyClass {
const CONST_VALUE = 'A constant value';
}
$classname = 'MyClass';
echo $classname::CONST_VALUE; // As of PHP 5.3.0
echo MyClass::CONST_VALUE;
15. 9. 타입 힌팅
• http://php.net/manual/kr/language.oop5.paamayim-nekudotayim.php
• 함수는 이제 파라미터를 객체(함수 프로토 타입에 클래스의 이름을 명시하는것으로), 인터페이스, 배
열(PHP 5.1 이후) 또는 callable(PHP 5.4 이후) 로 강제할수 있게 되었습니다. 하지만, NULL을 디폴트 값으
로 지정하게 되면, 이후 호출시 NULL을 인자로 넘기는것도 가능합니다.
<?php
use IlluminateContractsContainerContainer as ContainerContract;
class Dispatcher implements DispatcherContract
{
public function __construct(ContainerContract $container = null) // $container 타입을 클래스명으로!
{
$this->container = $container ?: new Container;
}
}