psr-12

Gunny Park·2024년 2월 23일
  1. 일반

2.1. 기본 코딩 표준
코드의 모든 규칙들은 psr-1에 나타나있다(outlined).

per-1의 StudlyCaps(첫글자 대문자) 용어는 파스칼케이스로서 해석되어진다. 각 단어의 첫 글자는 맨 앞 글자를 포함하여 대문자로 표시된다.

2.2. 파일
모든 php 파일은 Unix LF (linefeed) line으로 끝나는 것으로 사용해야한다.
모든 php 파일은 끝 줄에 빈줄이 없어야하고 single LF로 끝나야한다.
(All PHP files MUST end with a non-blank line, terminated with a single LF.)
php 코드로만 이루어진 파일은 반드시 끝 태그인 ?>를 제거해야한다.

2.3. 줄
줄 길이에 강력한 제한을 하지 않는다.
줄 길이의 가벼운 제한은 120개 문자가 되어야한다.
80개 문자보다 긴 줄은 각 80자 이내의 여러 후속 행으로 분할되어야 한다.
줄 끝에 여백(whitespace)이 있으면 안된다.
빈 줄은 명시적으로 금지된 경우를 제외하고 가독성을 향상과 관련 코드 블록을 나타내기 위해 추가될 수 있다.
한 줄에 한 개의 statement만 사용해야한다.

2.4. 들여쓰기
4개의 공백으로 되어있는 들여쓰기로 사용해야한다. (기본 tab으로 들여쓰기를 사용하면 안된다.)

2.5. 키워드와 타입
소문자로 키워드와 타입을 선언해야한다.
타입 키워드의 short form으로 사용되야한다.
Ex. boolean 대신에 bool 사용, integer 대신 int 사용

  1. statement, namespace, import statement 선언
    php 파일의 윗 부분은 아래 순서로 작성
  • <?php 태그로 시작
  • file-level 문서 블록
  • 선언 statement
  • 파일의 namespace 선언
  • use로 클래스 호출 (import statements)
  • use로 함수 호출 (import statements)
  • use로 상수 호출 (import statements)
  • php 코드 작성

파일에 HTML과 PHP가 혼합되어 있는 경우에도 위 섹션 중 하나를 계속 사용할 수 있습니다. 그렇다면 코드의 나머지 부분이 닫는 PHP 태그와 HTML 및 PHP의 혼합으로 구성되어 있더라도 파일 상단에 있어야 합니다.
(When a file contains a mix of HTML and PHP, any of the above sections may still be used. If so, they MUST be present at the top of the file, even if the remainder of the code consists of a closing PHP tag and then a mixture of HTML and PHP.)

파일이 <?php태그로 시작할때 다음줄부터 코드가 있어야한다.

import문은 반드시 백슬래시로 시작되면 안된다.

Ex.

<?php

/**
 * This file contains an example of coding styles.
 */

declare(strict_types=1);

namespace Vendor\Package;

use Vendor\Package\{ClassA as A, ClassB, ClassC as C};
use Vendor\Package\SomeNamespace\ClassD as D;
use Vendor\Package\AnotherNamespace\ClassE as E;

use function Vendor\Package\{functionA, functionB, functionC};
use function Another\Vendor\functionD;

use const Vendor\Package\{CONSTANT_A, CONSTANT_B, CONSTANT_C};
use const Another\Vendor\CONSTANT_D;

/**
 * FooBar is an example class.
 */
class FooBar
{
    // ... additional PHP code ...
}

3 depth 이상의 복합 네임스페이스는 사용하면 안된다. 최대 복합 네임스페이스의 depth는 아래와 같다.

<?php

use Vendor\Package\SomeNamespace\{
    SubnamespaceOne\ClassA,
    SubnamespaceOne\ClassB,
    SubnamespaceTwo\ClassY,
    ClassZ,
};

아래와 같이 사용해서는 안된다.

<?php

use Vendor\Package\SomeNamespace\{
    SubnamespaceOne\AnotherNamespace\ClassA,
    SubnamespaceOne\ClassB,
    ClassZ,
};

strict type을 선언하길 원한다면 파일의 첫 줄에 선언해야한다.
(When wishing to declare strict types in files containing markup outside PHP opening and closing tags, the declaration MUST be on the first line of the file and include an opening PHP tag, the strict types declaration and closing tag.)

Ex.

<?php declare(strict_types=1) ?>
<html>
<body>
    <?php
        // ... additional PHP code ...
    ?>
</body>
</html>

정확히 공백없이 declare(strict_types=1)로 선언한다. (끝에 세미콜론은 없어도 된다.)

declare 블록 선언문은 아래처럼 선언해야한다.

declare(ticks=1) {
    // some code
}
  1. 클래스, property, 함수
    닫는 중괄호와 같은 줄에 주석이나 statement를 사용해서는 안 된다.
    새 클래스를 인스턴스화할때는 인자가 없을때에도 소괄호는 반드시 존재해야한다.
new Foo();

4.1. extends와 implements
클래스 이름과 같은줄에 extends와 implements가 선언 되야 한다.
클래스 이름과 같은줄에 extends와 implements가 선언 되야 하고 다음줄에 중괄호가 있어야한다. 닫는 중괄호 윗줄에 빈줄이 있으면 안된다.

<?php

namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
    // constants, properties, methods
}

implements나 extends가 여러개인 경우 여러 줄로 나누어 작성해야한다.
(Lists of implements and, in the case of interfaces, extends MAY be split across multiple lines, where each subsequent line is indented once. When doing so, the first item in the list MUST be on the next line, and there MUST be only one interface per line.)

<?php

namespace Vendor\Package;

use FooClass;
use BarClass as Bar;
use OtherVendor\OtherPackage\BazClass;

class ClassName extends ParentClass implements
    \ArrayAccess,
    \Countable,
    \Serializable
{
    // constants, properties, methods
}

4.2. trait
클래스의 여는 중괄호 다음줄에 use를 사용하여 trait를 사용해야한다.
(The use keyword used inside the classes to implement traits MUST be declared on the next line after the opening brace.)

<?php

namespace Vendor\Package;

use Vendor\Package\FirstTrait;

class ClassName
{
    use FirstTrait;
}

한 줄당 한 개의 trait를 선언해야한다.
(Each individual trait that is imported into a class MUST be included one-per-line and each inclusion MUST have its own use import statement.)

<?php

namespace Vendor\Package;

use Vendor\Package\FirstTrait;
use Vendor\Package\SecondTrait;
use Vendor\Package\ThirdTrait;

class ClassName
{
    use FirstTrait;
    use SecondTrait;
    use ThirdTrait;
}

클래스 안에 use문 외에 아무것도 없을때 use문 다음줄에 닫는 중괄호가 있어야한다.

<?php

namespace Vendor\Package;

use Vendor\Package\FirstTrait;

class ClassName
{
    use FirstTrait;
}

클래스 안에 use문 외에 코드가 있을때 use문 다음줄에는 빈 줄이 있어야한다.

<?php

namespace Vendor\Package;

use Vendor\Package\FirstTrait;

class ClassName
{
    use FirstTrait;

    private $property;
}

insteadof와 as 연산자를 사용할때 들여쓰기, 공백, 새 줄을 사용되어야한다.
(When using the insteadof and as operators they must be used as follows taking note of indentation, spacing, and new lines.)

<?php

class Talker
{
    use A;
    use B {
        A::smallTalk insteadof B;
    }
    use C {
        B::bigTalk insteadof C;
        C::mediumTalk as FooBar;
    }
}

4.3. property와 상수
var은 property로 선언하면 안된다.
statement당 하나의 property만 선언해야한다.
property 이름은 첫글자를 _로 사용하면 안된다.
타입 선언과 property 이름 사이에는 공백이 있어야 한다.

<?php

namespace Vendor\Package;

class ClassName
{
    public $foo = null;
    public static int $bar = 0;
}

4.4. 메소드와 함수
함수명 첫글자는 반드시 _를 사용해서는 안 된다.
(Method names MUST NOT be prefixed with a single underscore to indicate protected or private visibility. That is, an underscore prefix explicitly has no meaning.)
함수명 다음에는 공백 없이 같은 줄에 여는 소괄호를 사용해야하며 다음줄에 중괄호를 사용해야하고 괄호 전에 공백이 있으면 안된다.
(Method and function names MUST NOT be declared with space after the method name. The opening brace MUST go on its own line, and the closing brace MUST go on the next line following the body. There MUST NOT be a space after the opening parenthesis, and there MUST NOT be a space before the closing parenthesis.)

메소드 예:

<?php

namespace Vendor\Package;

class ClassName
{
    public function fooBarBaz($arg1, &$arg2, $arg3 = [])
    {
        // method body
    }
}

함수 예:

<?php

function fooBarBaz($arg1, &$arg2, $arg3 = [])
{
    // function body
}

4.5. 메소드와 함수 인자
인자 리스트에는 , 전에 공백이 있어서는 안되고 ,뒤에 공백이 있어야한다.
메소드와 함수의 기본 값을 갖는 인자들은 인자 리스트의 끝에 위치해야한다.

<?php

namespace Vendor\Package;

class ClassName
{
    public function foo(int $arg1, &$arg2, $arg3 = [])
    {
        // method body
    }
}

인자 리스트는 인자가 많을 경우 첫 인자를 함수선언 다음줄에 작성하고 각 인자당 하나의 줄로 작성해야한다.
(Argument lists MAY be split across multiple lines, where each subsequent line is indented once. When doing so, the first item in the list MUST be on the next line, and there MUST be only one argument per line.)
이렇게 여러 줄에 인자를 작성할 경우 닫는 소괄호와 같은 줄에 소괄호 다음에 공백 후 여는 줄괄호를 사용해야한다.

<?php

namespace Vendor\Package;

class ClassName
{
    public function aVeryLongMethodName(
        ClassTypeHint $arg1,
        &$arg2,
        array $arg3 = []
    ) {
        // method body
    }
}

함수가 return 값이 있는 경우 함수와 같은 줄에 인자의 닫는 소괄호 다음에 :입력하고 공백 후 return 타입을 작성한다.

<?php

declare(strict_types=1);

namespace Vendor\Package;

class ReturnTypeVariations
{
    public function functionName(int $arg1, $arg2): string
    {
        return 'foo';
    }

    public function anotherFunction(
        string $foo,
        string $bar,
        int $baz
    ): string {
        return 'foo';
    }
}

null 타입이 선언된 경우 함수 선언 끝에 return 타입과 ? 사이에 공백이 있어서는 안된다.
(In nullable type declarations, there MUST NOT be a space between the question mark and the type.)

<?php

declare(strict_types=1);

namespace Vendor\Package;

class ReturnTypeVariations
{
    public function functionName(?string $arg1, ?int &$arg2): ?string
    {
        return 'foo';
    }
}

& 연산자 다음에 인자뒤에는 공백이 있어서는 안된다.
(When using the reference operator & before an argument, there MUST NOT be a space after it, like in the previous example.)

… 연산자와 인자 사이에는 공백이 있어서는 안된다.
(There MUST NOT be a space between the variadic three dot operator and the argument name:)

public function process(string $algorithm, ...$parts)
{
    // processing
}

& 연산자와 연산자와 인자 사이에는 공백이 있어서는 안된다.
(When combining both the reference operator and the variadic three dot operator, there MUST NOT be any space between the two of them:)

public function process(string $algorithm, &...$parts)
{
    // processing
}

4.6. abstract, final, static
static 선언 뒤에 abstract 선언을 해야 한다.
(When present, the abstract and final declarations MUST precede the visibility declaration.
When present, the static declaration MUST come after the visibility declaration.)

<?php

namespace Vendor\Package;

abstract class ClassName
{
    protected static $foo;

    abstract protected function zim();

    final public static function bar()
    {
        // method body
    }
}

4.7. 메소드와 함수 호출
메소드나 함수 호출을 할 때, 메소드나 함수 이름, 함수의 여는 소괄호 사이에 공백이 없어야 한다. 함수의 여는 소괄호 뒤, 닫는 소괄호 전에 공백이 없어야 한다.
인자 리스트에는 ,전에 공백이 없어야하고 ,뒤에는 공백이 있어야한다.

<?php

bar();
$foo->bar($arg1);
Foo::bar($arg2, $arg3);

인자가 많을 경우 인자당 한 줄로 구분해야하며 첫 인자는 함수의 다음줄에 작성해야한다.
하나의 인자가 여러 값이나 변수를 포함하는 경우 인자당 한줄이 아니다.
(Argument lists MAY be split across multiple lines, where each subsequent line is indented once. When doing so, the first item in the list MUST be on the next line, and there MUST be only one argument per line. A single argument being split across multiple lines (as might be the case with an anonymous function or array) does not constitute splitting the argument list itself.)

<?php

$foo->bar(
    $longArgument,
    $longerArgument,
    $muchLongerArgument
);
<?php

somefunction($foo, $bar, [
  // ...
], $baz);

$app->get('/hello/{name}', function ($name) use ($app) {
    return 'Hello ' . $app->escape($name);
});
  1. 제어 구조
    제어 구조를 위한 일반적인 스타일 규칙은 아래 내용을 따른다.
  • 제어 구조 키워드 다음은 하나의 공백을 사용해야 한다.
  • 여는 괄호 다음에는 하나의 공백을 사용하면 안된다.
  • 닫는 괄호 전에 하나의 공백을 사용하면 안된다.
  • 열고 닫는 중괄호 사이에는 하나의 공백을 사용해야 한다.
  • 구조 body는 들여쓰기를 한 번 사용해야 한다.
  • 여는 괄호 이후 다음줄에 코드를 작성해야 한다.
  • body 다음 줄에 닫는 괄호를 사용해야 한다.
    각 구조의 body는 중괄호로 묶어야한다.
    (The body of each structure MUST be enclosed by braces.)

5.1. if, else if, else
elseif문의 닫는 중괄호는 else문 선언과 같은 줄에 있어야 한다.

<?php

if ($expr1) {
    // if body
} elseif ($expr2) {
    // elseif body
} else {
    // else body;
}

elseif는 else if 대신에 사용해야 한다.

인자가 많을 경우 첫 인자는 조건문의 다음줄에 작성해야하고 각 인자당 한 줄로 작성해야한다.

<?php

if (
    $expr1
    && $expr2
) {
    // if body
} elseif (
    $expr3
    && $expr4
) {
    // elseif body
}

5.2. switch, case
case를 선언할때 들여쓰기를 사용해야하고 break는 같은 레벨에서 들여쓰기를 해야한다. break가 없을때는 주석으로 명시를 해야한다.
(The case statement MUST be indented once from switch, and the break keyword (or other terminating keywords) MUST be indented at the same level as the case body. There MUST be a comment such as // no break when fall-through is intentional in a non-empty case body.)

<?php

switch ($expr) {
    case 0:
        echo 'First case, with a break';
        break;
    case 1:
        echo 'Second case, which falls through';
        // no break
    case 2:
    case 3:
    case 4:
        echo 'Third case, return instead of break';
        return;
    default:
        echo 'Default case';
        break;
}

switch의 인자의 길이가 길 경우 switch 선언 다음줄부터 나눠서 작성할 수 있다.
(Expressions in parentheses MAY be split across multiple lines, where each subsequent line is indented at least once. When doing so, the first condition MUST be on the next line. The closing parenthesis and opening brace MUST be placed together on their own line with one space between them. Boolean operators between conditions MUST always be at the beginning or at the end of the line, not a mix of both.)

<?php

switch (
    $expr1
    && $expr2
) {
    // structure body
}

5.3. while, do while
while문의 기본 예시:

<?php

while ($expr) {
    // structure body
}

while문의 인자의 길이가 길 경우 여러 줄로 나누어 작성할 수 있다.
(Expressions in parentheses MAY be split across multiple lines, where each subsequent line is indented at least once. When doing so, the first condition MUST be on the next line. The closing parenthesis and opening brace MUST be placed together on their own line with one space between them. Boolean operators between conditions MUST always be at the beginning or at the end of the line, not a mix of both.)

<?php

while (
    $expr1
    && $expr2
) {
    // structure body
}

do while문의 기본 예시:

<?php

do {
    // structure body;
} while ($expr);

인자의 길이가 길 경우 인자를 여러 줄로 나누어 작성하는 예시:

<?php

do {
    // structure body;
} while (
    $expr1
    && $expr2
);

5.4. for
for문의 기본 예시:

<?php

for ($i = 0; $i < 10; $i++) {
    // for body
}

for문의 인자가 길 경우 여러 줄로 나누어 작성하는 예시:

<?php

for (
    $i = 0;
    $i < 10;
    $i++
) {
    // for body
}

5.5. foreach
foreach문의 기본 예시:

<?php

foreach ($iterable as $key => $value) {
    // foreach body
}

5.6. try, catch, finally
try, catch, finally문의 기본 예시:

<?php

try {
    // try body
} catch (FirstThrowableType $e) {
    // catch body
} catch (OtherThrowableType | AnotherThrowableType $e) {
    // catch body
} finally {
    // finally body
}
  1. 연산자

6.1. 단항 연산자
증감 연산자는 변수(피연산자)와 연산자 사이에 어떠한 공백도 있으면 안된다.

$i++;
++$j;

type casting 연산자는 괄호 안에 어떠한 공백도 있으면 안된다.

$intValue = (int) $input;

6.2. binary 연산자
모든 binary 유형의 연산자 앞, 뒤에 공백이 있어야 한다.

if ($a === $b) {
    $foo = $bar ?? $a ?? $b;
} elseif ($a > $b) {
    $foo = $a + $b * $c;
}

6.3. 삼항 연산자
?: 연산자의 앞, 뒤에 공백이 있어야 한다.

$variable = $foo ? 'foo' : 'bar';

?: 연산자의 앞, 뒤에 공백이 있어야한다.

$variable = $foo ?: 'bar';
  1. closure(클로저)
    클로저는 function 키워드 뒤의 공백과 use 키워드 앞뒤의 공백으로 선언되어야 합니다.
    클로저는의 여는 괄호는 선언과 같은 줄에 있어야하며 닫는 괄호는 body 다음 줄에 있어야한다.

여는 괄호와 첫 인수 사이에 공백이 있어서는 안 되며, 닫는 괄호와 마지막 변수 사이에 공백이 있어서는 안 됩니다.
(There MUST NOT be a space after the opening parenthesis of the argument list or variable list, and there MUST NOT be a space before the closing parenthesis of the argument list or variable list.)

인수 뒤에 ,는 공백이 있으면 안되고 , 뒤에 공백 추가 후 인수를 작성해야한다.
(In the argument list and variable list, there MUST NOT be a space before each comma, and there MUST be one space after each comma.)

클로저의 기본값이 있는 인자 순서중에 맨 끝에 위치해야한다.

반환 타입이 있는 경우 일반 함수 규칙과 동일하고 use를 사용하고 반환 타입이 있다면 use 닫는 태그 뒤에 공백 없이 :를 추가하고 공백 후 반환타입을 지정해야한다.

예시:

<?php

$closureWithArgs = function ($arg1, $arg2) {
    // body
};

$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {
    // body
};

$closureWithArgsVarsAndReturn = function ($arg1, $arg2) use ($var1, $var2): bool {
    // body
};

인자의 길이가 길 경우 여러 줄로 인자를 작성할 수 있다.
(Argument lists and variable lists MAY be split across multiple lines, where each subsequent line is indented once. When doing so, the first item in the list MUST be on the next line, and there MUST be only one argument or variable per line.
When the ending list (whether of arguments or variables) is split across multiple lines, the closing parenthesis and opening brace MUST be placed together on their own line with one space between them.)

예시:

<?php

$longArgs_noVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) {
   // body
};

$noArgs_longVars = function () use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
   // body
};

$longArgs_longVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
   // body
};

$longArgs_shortVars = function (
    $longArgument,
    $longerArgument,
    $muchLongerArgument
) use ($var1) {
   // body
};

$shortArgs_longVars = function ($arg) use (
    $longVar1,
    $longerVar2,
    $muchLongerVar3
) {
   // body
};

클로저가 함수나 메소드 호출에서 인수로 직접 사용되는 경우에도 formatting 규칙이 적용된다.

<?php

$foo->bar(
    $arg1,
    function ($arg2) use ($var1) {
        // body
    },
    $arg3
);
  1. 익명 클래스
    예시:
<?php

$instance = new class {};

implement의 인자 개수가 여러 개인 경우 각 인자당 한 줄로 나누어 작성한다.(첫 인자는 선언 다음 줄에 작성)

<?php

// Brace on the same line
$instance = new class extends \Foo implements \HandleableInterface {
    // Class content
};

// Brace on the next line
$instance = new class extends \Foo implements
    \ArrayAccess,
    \Countable,
    \Serializable
{
    // Class content
};
profile
ASD programmer

0개의 댓글