Coding Standards

μ½”λ”© κ·œμΉ™

일반

PHP, HTML, XML, CSS, JS λ“± λͺ¨λ“  ν…μŠ€νŠΈ 파일의 λ¬Έμžμ…‹μ€ BOM이 μ—†λŠ” UTF-8μž…λ‹ˆλ‹€.

μ€„λ°”κΏˆ λ¬ΈμžλŠ” μœ λ‹‰μŠ€ 방식(LF)을 λ”°λ¦…λ‹ˆλ‹€.

μœˆλ„μš° λ©”λͺ¨μž₯μ—μ„œ νŽΈμ§‘ν•œ νŒŒμΌμ€ μœ„μ˜ 두 κ°€μ§€ κ·œμΉ™μ— μ–΄κΈ‹λ‚©λ‹ˆλ‹€.
μœˆλ„μš° μ‚¬μš©μžλŠ” Notepad++ λ“±μ˜ 개발자용 에디터λ₯Ό μ‚¬μš©ν•˜μ—¬ νŽΈμ§‘ν•˜μ‹œκΈ° λ°”λžλ‹ˆλ‹€.

λ“€μ—¬μ“°κΈ°λŠ” 1개의 νƒ­μœΌλ‘œ ν•©λ‹ˆλ‹€.
단, νƒ­ λŒ€μ‹  슀페이슀λ₯Ό μ‚¬μš©ν•˜λŠ” νŒŒμΌμ—μ„œλŠ” 일관성 μœ μ§€λ₯Ό μœ„ν•΄ 2~4칸의 슀페이슀λ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
λŒ€ν‘œμ μœΌλ‘œ Markdown, YAML λ“±μ˜ νŒŒμΌμ—μ„œλŠ” 슀페이슀둜 λ“€μ—¬μ“°κΈ°ν•©λ‹ˆλ‹€.

μ£Όμ„μ΄λ‚˜ κΈ΄ λͺ©λ‘ λ“±μ—μ„œ 쀄을 λ§žμΆ”κΈ° μœ„ν•΄ ν•œλ‘ 개의 슀페이슀λ₯Ό μΆ”κ°€ν•˜λŠ” 경우λ₯Ό μ œμ™Έν•˜λ©΄,
λ“€μ—¬μ“°κΈ° λͺ©μ μœΌλ‘œ νƒ­κ³Ό 슀페이슀λ₯Ό μ„žμ–΄μ„œ μ‚¬μš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μ€„λ°”κΏˆ, λ“€μ—¬μ“°κΈ° λ“±μ˜ κ·œμΉ™μ€ .editorconfig에 μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.
μ‚¬μš©ν•˜μ‹œλŠ” 에디터에 EditorConfig ν”ŒλŸ¬κ·ΈμΈμ„ μ„€μΉ˜ν•˜λ©΄ 이 νŒŒμΌμ„ μžλ™μœΌλ‘œ μΈμ‹ν•˜μ—¬
λΌμ΄λ―ΉμŠ€μ— λ§žλŠ” κ·œμΉ™μ΄ μžλ™μœΌλ‘œ μ μš©λ˜λ‹ˆ 적극 ν™œμš©ν•˜μ‹œκΈ° λ°”λžλ‹ˆλ‹€.

PHP μ½”λ“œλ§ŒμœΌλ‘œ 이루어진 νŒŒμΌμ€ 맨 끝에 ?> νƒœκ·Έλ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

곡백 및 μ€„λ°”κΏˆ κ·œμΉ™

클래슀 및 ν•¨μˆ˜ μ„ μ–Έκ³Ό if, for, foreach, while λ“±μ˜ μ€‘κ΄„ν˜ΈλŠ” λ‹€μŒ 쀄에 μ”λ‹ˆλ‹€.

class Foo
{                              // RIGHT
    public function bar() {    // WRONG

    }
}

μ‘°κ±΄λ¬Έμ΄λ‚˜ μˆœν™˜λ¬Έ 내에 ν•˜λ‚˜μ˜ λͺ…λ Ήλ§Œ μžˆλŠ” κ²½μš°μ—λ„ λ°˜λ“œμ‹œ μ€‘κ΄„ν˜Έλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
κ·Έλž˜μ•Ό λ‚˜μ€‘μ— λͺ…령이 좔가될 경우 μˆ˜μ •ν•˜κΈ° νŽΈλ¦¬ν•©λ‹ˆλ‹€.

if (!$foo) return false;    // WRONG
if (!$bar)                  // RIGHT
{
    return true;
}

단, ν΄λ‘œμ ΈλŠ” 같은 쀄에 μ€‘κ΄„ν˜Έλ₯Ό μ“Έ 수 있으며,
이 경우 μ€‘κ΄„ν˜Έ μ•žλ’€μ— ν•œ μΉΈμ”© 곡백을 두어 ν΄λ‘œμ Έκ°€ μ‹œμž‘λ˜κ³  λλ‚˜λŠ” 지점을 μ°ΎκΈ° 쉽도둝 ν•©λ‹ˆλ‹€.
λ‹«λŠ” μ€‘κ΄„ν˜Έμ™€ κ·Έ λ’€μ˜ 기호 μ‚¬μ΄μ—λŠ” 곡백을 두지 μ•ŠμŠ΅λ‹ˆλ‹€.

$foo = function($bar) { return $bar + 1; };    // RIGHT
$foo = function($bar) {                        // RIGHT
    return $bar + 1;
};
$foo = function($bar){return $bar + 1;};       // WRONG

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” 거의 λͺ¨λ“  ν•¨μˆ˜κ°€ 클둜져이며, 잘λͺ» μ€„λ°”κΏˆν•  경우 μ„Έλ―Έμ½œλ‘ μ΄ μ‚½μž…λ˜λŠ” λ“± 뢈편이 λ°œμƒν•  수 μžˆμœΌλ―€λ‘œ
μ€‘κ΄„ν˜Έλ₯Ό λ‹€μŒ 쀄에 μ“°μ§€ μ•Šμ•„λ„ λ©λ‹ˆλ‹€.

$("#foo").on("click", function() {    // OK
    if ($(this).val() === "bar") {    // OK
        $(this).val("baz");
    }
});

ν•¨μˆ˜ ν˜ΈμΆœμ‹œ ν•¨μˆ˜λͺ…κ³Ό κ΄„ν˜Έ 사이, κ΄„ν˜Έμ™€ 인자 사이에 곡백을 두지 μ•ŠμŠ΅λ‹ˆλ‹€.
인자λ₯Ό κ΅¬λΆ„ν•˜λŠ” μ‰Όν‘œλŠ” λ’€μͺ½μ—λ§Œ ν•œ 칸의 곡백을 λ‘‘λ‹ˆλ‹€.

function foobar($baz, $param)        // RIGHT
function foobar ( $baz , $param )    // WRONG

λ°°μ—΄ λ‚΄μ˜ μš”μ†Œλ“€μ„ κ΅¬λΆ„ν•˜λŠ” μ‰Όν‘œλ„ λ’€μͺ½μ—λ§Œ ν•œ 칸의 곡백을 λ‘‘λ‹ˆλ‹€.

array(1, 2, 3)    // RIGHT
array(1,2,3)      // WRONG
array(1 ,2 ,3)    // WRONG

if, for, foreach, while λ“±μ˜ ν‚€μ›Œλ“œ λ’€μ—λŠ” ν•œ 칸의 곡백을 λ‘λŠ” 것이 μ›μΉ™μ΄λ‚˜,
XE μ‹œμ ˆμ— μž‘μ„±λœ μ½”λ“œλŠ” 곡백이 μ—†λŠ” 것이 λ§ŽμœΌλ―€λ‘œ 이런 μ½”λ“œ μ£Όλ³€μ—μ„œλŠ” 곡백 없이 μ“Έ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
==, !=, > λ“±μ˜ μ—°μ‚°μžλŠ” 항상 μ•žλ’€μ— ν•œ μΉΈμ”© 곡백을 λ‘‘λ‹ˆλ‹€.

if ($foo === $bar)    // RECOMMENDED
if($foo === $bar)     // OK for XE Compatibility
if($foo==$bar){       // WRONG

μ—¬λŸ¬ 쀄에 걸쳐 배열을 μ„ μ–Έν•  경우, λ§ˆμ§€λ§‰ κ΅¬μ„±μš”μ†Œ 뒀에 μ‰Όν‘œλ₯Ό λ‚¨κΉλ‹ˆλ‹€.
κ·Έλž˜μ•Ό λ‚˜μ€‘μ— κ΅¬μ„±μš”μ†Œλ₯Ό μΆ”κ°€ν•  λ•Œ νŽΈλ¦¬ν•©λ‹ˆλ‹€.

$animals = array(
    'bear',
    'cat',
    'dog',    // COMMA
);

단, μžλ°”μŠ€ν¬λ¦½νŠΈ 및 JSONμ—μ„œλŠ” λ§ˆμ§€λ§‰ μ‰Όν‘œλ₯Ό λ°˜λ“œμ‹œ μ‚­μ œν•΄μ•Ό ν•©λ‹ˆλ‹€.
μ‰Όν‘œλ₯Ό λ‚¨κ²¨λ‘˜ 경우 일뢀 λΈŒλΌμš°μ €μ—μ„œ 였λ₯˜κ°€ λ°œμƒν•  수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

var animals = [
    'bear',
    'cat',
    'dog'    // NO COMMA
];

주석

주석은 κ΄€λ ¨ μ½”λ“œ μœ—μ€„μ— 써야 ν•©λ‹ˆλ‹€.
μ‘°κ±΄λ¬Έμ΄λ‚˜ λ£¨ν”„μ˜ κ²½μš°μ—λŠ” ν•΄λ‹Ή ν‚€μ›Œλ“œμ˜ μœ—μ€„μ— 주석을 μ”λ‹ˆλ‹€.

// If foo is bar, do something.
if ($foo->isBar())
{
    // Note: this will do X, Y, and Z.
    $foo->doSomething();
}
// Otherwise, do something else.
else
{
    // TODO: Refactor this later.
    $foo->doSomethingElse();
}

이전 λΈ”λ‘μ˜ λ§ˆμ§€λ§‰ 뢀뢄에 주석을 μ§‘μ–΄λ„£μ–΄μ„œλŠ” μ•ˆ λ©λ‹ˆλ‹€.

// RIGHT
if ($condition)
{

}
// RIGHT
elseif ($foo)
{
    // WRONG
}
else
{

}

λͺ¨λ“  ν΄λž˜μŠ€μ™€ ν•¨μˆ˜μ—λŠ” /**으둜 μ‹œμž‘ν•˜λŠ” PHPDoc λ°©μ‹μ˜ 주석을 λΆ™μ—¬μ•Ό ν•©λ‹ˆλ‹€.
PHPDoc 주석 μž‘μ„±μ— 어렀움이 μžˆλŠ” 경우, λ‹€λ₯Έ ν΄λž˜μŠ€μ™€ ν•¨μˆ˜μ˜ 주석을 μ°Έκ³ ν•˜μ‹­μ‹œμ˜€.

/**
 * This is the Foo class.
 */
class Foo
{
    /**
     * Constructor.
     *
     * @param string $member_srl
     */
    public function __construct(int $member_srl)
    {
        // μƒλž΅
    }

    /**
     * Check if this Foo is bar.
     *
     * @return bool
     */
    public function isBar(): bool
    {
        return true;
    }
}

λΆˆκ°€ν”Όν•œ 경우λ₯Ό μ œμ™Έν•˜λ©΄ 주석은 영문으둜 μ“°λŠ” 것을 μ›μΉ™μœΌλ‘œ ν•˜λ©°,
λŒ€λ¬Έμžλ‘œ μ‹œμž‘ν•˜λŠ” μ™„μ „ν•œ λ¬Έμž₯으둜 이루어져야 ν•©λ‹ˆλ‹€.

ν•¨μˆ˜μ˜ κ°€μ‹œμ„± 및 νƒ€μž… μ„ μ–Έ

μ‹ κ·œ μΆ”κ°€ν•˜λŠ” 클래슀 λ©”μ†Œλ“œλΌλ©΄ κ°€μ‹œμ„±, 각 νŒŒλΌλ―Έν„°μ˜ νƒ€μž…, 그리고 λ°˜ν™˜ νƒ€μž…μ„ μ„ μ–Έν•΄μ•Ό ν•©λ‹ˆλ‹€.
public이 μ•„λ‹Œ λ©”μ†Œλ“œλ‚˜ μ†μ„±μ˜ 이름은 μ›μΉ™μ μœΌλ‘œ 언더바(_)둜 μ‹œμž‘ν•©λ‹ˆλ‹€.
단, ν•˜μœ„ ν˜Έν™˜μ„±μ„ μœ„ν•΄ κ°€μ‹œμ„±μ΄λ‚˜ λ°˜ν™˜ νƒ€μž… 등을 μ—„κ²©ν•˜κ²Œ μ œν•œν•  수 μ—†λŠ” κ²½μš°μ—λŠ” μ˜ˆμ™Έλ‘œ ν•©λ‹ˆλ‹€.

public function getFoobarList(string $foobar, int $count): array
{
    return [];
}

νŠΉμ • 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό λ°›κ±°λ‚˜ λ°˜ν™˜ν•˜λŠ” λ©”μ†Œλ“œμ˜ 경우, λ°˜λ“œμ‹œ νƒ€μž…μ„ μ„ μ–Έν•΄μ•Ό ν•©λ‹ˆλ‹€.

public function getFoobar(int $foobar_srl): FoobarItem
{
    return new FoobarItem($foobar_srl);
}

protected function _arrangeFoobar(FoobarItem $foobar): \BaseObject
{
    return new \BaseObject(0, 'success_inserted');
}

참고둜 쿼리 κ²°κ³ΌλŠ” Rhymix\Framework\Helpers\DBResultHelper 클래슀의 μΈμŠ€ν„΄μŠ€λ‘œ λ°˜ν™˜λ©λ‹ˆλ‹€.

use Rhymix\Framework\Helpers\DBResultHelper;

public function updateFoobar(object $args): DBResultHelper
{
    return executeQuery('module.updateFoobar', $args);
}

컀밋 λ©”μ‹œμ§€

컀밋 λ©”μ‹œμ§€λŠ” κ°€λŠ₯ν•˜λ©΄ 영문으둜 μž‘μ„±ν•˜λ©°, λ™μ‚¬μ›ν˜•μœΌλ‘œ μ‹œμž‘ν•˜λŠ” ν˜„μž¬ν˜•, λͺ…λ Ήν˜• λ¬Έμž₯ μ‚¬μš©μ„ μ›μΉ™μœΌλ‘œ ν•©λ‹ˆλ‹€.

Delete unnecessary condition     // RIGHT
Fix #1234                        // RIGHT
Deletes unnecessary condition    // WRONG (λΆˆν•„μš”ν•œ 3인칭 λ‹¨μˆ˜ 동사변화)
Fixed #1234                      // WRONG (λΆˆν•„μš”ν•œ κ³Όκ±°ν˜•)

이 κ·œμΉ™μ— λ§žμΆ”μ–΄ 영문으둜 컀밋 λ©”μ‹œμ§€λ₯Ό μž‘μ„±ν•˜κΈ° μ–΄λ €μš΄ 경우, ν•œκΈ€λ‘œ μž‘μ„±ν•΄λ„ λ¬΄λ°©ν•©λ‹ˆλ‹€.
ν•œκΈ€ 컀밋 λ©”μ‹œμ§€λŠ” μ–΄λ””μ„œ 무엇을 μ–΄λ–»κ²Œ ν–ˆλŠ”μ§€ κ°„κ²°ν•˜κ³  λͺ…ν™•ν•˜κ³  κ²©μ‹μžˆκ²Œ ν‘œν˜„ν•˜λ©°,
κ°€λŠ₯ν•˜λ©΄ ν˜„μž¬ν˜• λ™μ‚¬λ‘œ λ§ˆμΉ˜λ„λ‘ ν•©λ‹ˆλ‹€.

크둬 μ΅œμ‹  λ²„μ „μ—μ„œ 슀크립트 였λ₯˜ ν•΄κ²°    // RIGHT
Foo ν΄λž˜μŠ€μ— bar() λ©”μ†Œλ“œ μΆ”κ°€           // RIGHT
νŒŒμΌμ²¨λΆ€ μ—λŸ¬λ‚˜λŠ”κ±° κ³ μ³€μ©Œμ—Ό~^^          // WRONG (κ²©μ‹μ—†λŠ” ν‘œν˜„)
ν•¨μˆ˜ κ°œμ„                                 // WRONG (λ‘λ¦¬λ­‰μ‹€ν•œ ν‘œν˜„)

기타

라이믹슀의 κΈ°λ³Έ error_reporting μ„€μ • ν•˜μ—μ„œ μ–΄λ–€ μ—λŸ¬λ„ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ ν•˜λŠ” 것을 λͺ©ν‘œλ‘œ ν•©λ‹ˆλ‹€.
E_NOTICE, E_DEPRECATED λ“± κ³Όκ±°μ—λŠ” μ‚¬μ†Œν•˜κ²Œ μ—¬κ²Όλ˜ 였λ₯˜λΌλ„ λ§ˆμ°¬κ°€μ§€μž…λ‹ˆλ‹€.
ν˜„μž¬ λ²„μ „μ—μ„œ μ‚¬μ†Œν•œ 였λ₯˜μ˜€λ˜ λ¬Έμ œκ°€ λ‹€μŒ λ²„μ „μ—μ„œλŠ” 치λͺ…적인 였λ₯˜λ‘œ λ°”λ€” 수 μžˆμŠ΅λ‹ˆλ‹€.

λΌμ΄λ―ΉμŠ€κ°€ μ§€μ›ν•˜λŠ” λͺ¨λ“  PHP λ²„μ „μ—μ„œ 정상 μž‘λ™ν•˜λŠ” μ½”λ“œλ₯Ό μž‘μ„±ν•΄μ•Ό ν•©λ‹ˆλ‹€.
예λ₯Ό λ“€μ–΄ arrow function은 PHP 7.4 μ΄μƒμ—μ„œλ§Œ μ§€μ›λ˜λ―€λ‘œ μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€.
λΆ€λ“μ΄ν•˜κ²Œ νŠΉμ • λ²„μ „μ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆλŠ” κΈ°λŠ₯을 μΆ”κ°€ν•  경우,
μ§€μ›ν•˜μ§€ μ•ŠλŠ” λ²„μ „μ—μ„œλ„ 단지 κ·Έ κΈ°λŠ₯을 μ‚¬μš©ν•  수 없을 뿐 κ·Έ λ°–μ˜ 였λ₯˜κ°€ λ°œμƒν•΄μ„œλŠ” μ•ˆ λ©λ‹ˆλ‹€.

λ¬Έμžμ—΄κ³Ό λ¬Έμžμ—΄, μ •μˆ˜μ™€ μ •μˆ˜λ₯Ό 비ꡐ할 λ•ŒλŠ” κ°€λŠ₯ν•˜λ©΄ == λŒ€μ‹  ===을 μ‚¬μš©ν•©λ‹ˆλ‹€.
μ‹€μ œ μžλ£Œν˜•μ΄ λ‹€λ₯Ό κ°€λŠ₯성이 μžˆλŠ” 경우 intval(), strval() λ“±μ˜ ν•¨μˆ˜ λ˜λŠ” (int)와 같은 type castλ₯Ό ν™œμš©ν•©λ‹ˆλ‹€.
μ •μˆ˜λŠ” 항상 64λΉ„νŠΈ λ²”μœ„λ₯Ό κ°€μ§€λŠ” κ²ƒμœΌλ‘œ κ°€μ •ν•©λ‹ˆλ‹€.

μ „μ—­ μƒμˆ˜λ₯Ό μ°Έμ‘°ν•  λ•ŒλŠ” \RX_CLIENT_IP와 같이 \λ₯Ό μ•žμ— λΆ™μ—¬μ„œ,
μΆ”ν›„ λ‹€λ₯Έ λ„€μž„μŠ€νŽ˜μ΄μŠ€λ‘œ μ½”λ“œλ₯Ό 이동 λ˜λŠ” λ³΅μ‚¬ν•˜λ”λΌλ„ λ¬Έμ œκ°€ 생기지 μ•Šλ„λ‘ ν•©λ‹ˆλ‹€.

μ—¬κΈ°μ—μ„œ κ·œμ •ν•˜μ§€ μ•Šμ€ λ‚΄μš©μ€ PSR-1κ³Ό
PSR-12λ₯Ό λ”°λ¦…λ‹ˆλ‹€.

CSS, JS λ“± ν”„λ‘ νŠΈμ—”λ“œμ—μ„œ μ‹€ν–‰ν•˜λŠ” μ½”λ“œλŠ” μ••μΆ•μ΄λ‚˜ μ•”ν˜Έν™”(λ‚œλ…ν™”) λ“± μˆ˜μ •μ΄ μ–΄λ €μš΄ μƒνƒœκ°€ μ•„λ‹Œ 원본 μ†ŒμŠ€ κ·ΈλŒ€λ‘œ μ œκ³΅λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.
μ‚¬μš©μžκ°€ μ†ŒμŠ€λ₯Ό μˆ˜μ •ν•˜λ”λΌλ„ λ³„λ„μ˜ ν”„λ‘œκ·Έλž¨μ΄λ‚˜ 개발 ν™˜κ²½μ„ μ΄μš©ν•œ μ••μΆ•, 컴파일, λΉŒλ“œ λ“±μ˜ 과정을 κ±°μΉ˜μ§€ μ•Šκ³  μƒˆλ‘œκ³ μΉ¨ ν›„ κ³§λ°”λ‘œ μ‚¬μš©ν•  수 μžˆμ–΄μ•Ό ν•œλ‹€λŠ” λœ»μž…λ‹ˆλ‹€.
단, 원본 μ†ŒμŠ€κ°€ κ³΅κ°œλ˜μ–΄ μžˆλŠ” μ™ΈλΆ€ 라이브러리λ₯Ό λŒμ–΄λ‹€ μ‚¬μš©ν•˜λŠ” κ²½μš°μ—λŠ” μ••μΆ•λœ μƒνƒœλ‘œ μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

composer 라이브러리λ₯Ό μ—…λ°μ΄νŠΈν•  λ•ŒλŠ” λΌμ΄λ―ΉμŠ€μ—μ„œ κ³΅μ‹μ μœΌλ‘œ μ§€μ›ν•˜λŠ” ν™˜κ²½(PHP 7.2 이상)μ—μ„œ 정상 μž‘λ™ν•˜λŠ” λ²„μ „μœΌλ‘œ κ³ μ •μ‹œμΌœμ•Ό ν•©λ‹ˆλ‹€.
라이믹슀 지원 ν™˜κ²½κ³Ό λ§žμ§€ μ•ŠλŠ” 라이브러리λ₯Ό κ°€μ Έμ˜€λŠ” 것은 μ›μΉ™μ μœΌλ‘œ κΈˆμ§€λ˜λ©°, λΆˆκ°€ν”Όν•œ 경우 ν•΄λ‹Ή 라이브러리λ₯Ό ν˜ΈμΆœν•˜λŠ” λͺ¨λ“  λΆ€λΆ„μ—μ„œ 미리 버전을 μ²΄ν¬ν•˜μ—¬
μΈν΄λ£¨λ“œλ˜λŠ” μ‹œμ μ— 였λ₯˜κ°€ λ°œμƒν•˜λŠ” 것을 막아야 ν•©λ‹ˆλ‹€.
λ˜ν•œ λΆˆν•„μš”ν•œ λΌμ΄λΈŒλŸ¬λ¦¬κ°€ λ“€μ–΄μ˜€μ§€ μ•Šλ„λ‘ λ°˜λ“œμ‹œ μ•„λž˜μ˜ λͺ…λ ΉμœΌλ‘œ μ—…λ°μ΄νŠΈν•©λ‹ˆλ‹€.

composer update --no-dev --ignore-platform-reqs --optimize-autoloader