스타일 가이드 General Style and Syntax
본 페이지는 CI 를 가지고 개발할때 유용한 코딩규칙을 보여줍니다.
목차 Table of Contents
- PHP를 닫는 태그 (PHP Closing Tag)
- 클래스 및 메소드 이름짓기 (Class and Method Naming)
- 변수명 (Variable Names)
- 주석달기 (Commenting)
- 상수 (Constants)
- TRUE, FALSE, and NULL
- 논리연산 (Logical Operators)
- 리턴값 비교 및 형 변환 (Comparing Return Values and Typecasting)
- 디버깅 (Debugging Code)
- 파일내의 공백부분 (Whitespace in Files)
- 호환성 (Compatibility)
- 일반적 단어를 사용한 클래스 및 파일이름(Class and File Names using Common Words)
- 데이터베이스 테이블 명 (Database Table Names)
- 한클래스에 한파일 (One File per Class)
- 공백부분 (Whitespace)
- 줄바꿈 (Line Breaks)
- 인던트 (Code Indenting)
- 괄호의 여백(Bracket and Parenthetic Spacing)
- 제어판에서의 로컬라이즈 텍스트 (Localized Text in Control Panel)
- 프라이빗 메소드와 변수 (Private Methods and Variables)
- PHP 에러 (PHP Errors)
- 짧은 여는태그 (Short Open Tags)
- 한줄에 한문장 (One Statement Per Line)
- 문자열 (Strings)
- 쿼리 (SQL Queries)
- 기본 함수 파라미터 (Default Function Arguments)
- 중복 태그 파라미터 (Overlapping Tag Parameters)
PHP를 닫는 태그 (PHP Closing Tag)
PHP 닫는태그(?>)는 붙이든 붙이지 않든 파싱하는데는 문제가 없습니다. 그렇지만, 닫는태그를 사용한다면, 태그뒤에 공백이 붙을 경우 예상하지않았던 문제가 생길 수 있습니다. 생각했던것과는 다른 결과를 보여준다든지, 에러페이지를 보여줄 수도 있습니다. 또한 에러메세지가 숨겨지는경우 빈 페이지를 출력할 수 도 있습니다. 이러한 공백은 개발자나 코드의 사용자 혹은 ftp 프로그램 등에서 추가될 수 있습니다. 그러므로 모든 PHP파일에서 닫는태그를 제거하시기 바랍니다. 대신 주석으로 파일의 끝을 표시하시고, 현재파일의 경로를 기록해 두시면 좋습니다. 그러면, 파일이 잘린게 아니라는걸 명확히 알 수 있으니까요.
틀린예: <?php echo "Here's my code!"; ?> 옳은예:
<?php echo "Here's my code!"; /* End of file myfile.php */ /* Location:
./system/modules/mymodule/myfile.php */
클래스 및 메소드 이름짓기 (Class and Method Naming)
클래스 이름의 첫글자는 반드시 대문자로 시작해야하며, 생성자의 이름은 클래스 명과 동일해야 합니다. 여러 단어를 사용할 경우 카멜케이스(CamelCase) 대신 밑줄(_)로 연결해야합니다. 생성자를 제외한 모든 클래스 메소드는 소문자 만을 사용해야 하며 메소드의 기능을 가장 잘 설명할 수 있어야 합니다. 또한, 동사를 포함하고 있는것이 좋으며, 너무 길거나 의미가 불명확한 이름은 피해야 합니다.
틀린예: class superclass class SuperClass 옳은예:
class Super_class
주의: 클래스 이름과 생성자 이름은 철자 뿐 아니라, 대소문자도 같아야 합니다:
class Super_class {
function Super_class()
{
}
}
메소드 이름 예제:
틀린예: function fileproperties() // not descriptive and
needs underscore separator function fileProperties() // not descriptive and
uses CamelCase function getfileproperties() // Better! But still missing underscore
separator function getFileProperties() // uses CamelCase function get_the_file_properties_from_the_file()
// wordy 옳은예: function get_file_properties() // descriptive,
underscore separator, and all lowercase letters
변수명 (Variable Names)
변수명은 메소드명과 유사한 방법으로 작성하세요. 소문자만을 사용하고 밑줄(_)로 단어들을 이어주고, 변수의 목적을 가장 잘 설명할 수 있게 이름지으세요. 너무 짧거나, 단어가 아닌 변수는 for 루프에서만 사용하세요.
틀린예: $j = 'foo'; // single letter variables should only
be used in for() loops $Str // contains uppercase letters $bufferedText //
uses CamelCasing, and could be shortened without losing semantic meaning $groupid
// multiple words, needs underscore separator $name_of_last_city_used // too
long 옳은예: for ($j = 0; $j < 10; $j++) $str $buffer $group_id
$last_city
주석달기 (Commenting)
코드는 일반적으로 많은 주석을 포함해야 합니다. 주석은 신참 개발자에게 로직을 설명해 주는것은 물론, 몇달 후 자기 소스를 다시보았을때 왜 그렇게 만들었는지 설명해 주는 귀중한 자원입니다. 정해진 주석의 형식은 없지만, 아래의 형식을 추천합니다.
DocBlock 스타일의 주석. IDE에서 인식할 수 있도록 클래스와 함수 앞에서 사용함:
/**
* Super Class
*
* @package Package Name
* @subpackage Subpackage
* @category Category
* @author Author Name
* @link http://example.com
*/
class Super_class {
/**
* Encodes string for use in XML
*
* @access public
* @param string
* @return string
*/
function xml_encode($str)
여러줄의 주석을 기록할 경우 소스코드와 한줄 간격을 두는것이 좋습니다.
// break up the string by newlines
$parts = explode("\n", $str);
// A longer comment that needs to give greater detail on what is
// occurring and why can use multiple single-line comments. Try to
// keep the width reasonable, around 70 characters is the easiest to
// read. Don't hesitate to link to permanent external resources
// that may provide greater detail:
//
// http://example.com/information_about_something/in_particular/
$parts = $this->foo($parts);
상수 (Constants)
상수는 변수와 같은 규칙을 사용합니다.단 상수는 모두 대문자여야 합니다.다음의 예와 같이, 가능한 부분에서는 ExpressionEngine 의 상수를 사용하세요, i.e. SLASH, LD, RD, PATH_CACHE, etc.
틀린예: myConstant // missing underscore separator and not
fully uppercase N // no single-letter constants S_C_VER // not descriptive
$str = str_replace('{foo}', 'bar', $str); // should use LD and RD constants
옳은예: MY_CONSTANT NEWLINE SUPER_CLASS_VERSION $str = str_replace(LD.'foo'.RD,
'bar', $str);
TRUE, FALSE, and NULL
TRUE, FALSE, NULL 키워드는 항상 대문자만을 사용해야합니다.
틀린예: if ($foo == true) $bar = false; function foo($bar
= null) 옳은예: if ($foo == TRUE) $bar = FALSE; function foo($bar
= NULL)
논리연산 (Logical Operators)
어떤 장비에서는 || 를 사용할 경우 혼란스러울 수 있기 때문에( 예를들어 숫자11 처럼 보일수 있음) 사용하지 않는것이 좋습니다.. && 이 AND 보다 많이 쓰이지만, 양쪽다 괜찮습니다. !의 경우 앞뒤로 공백이 와야 합니다.
틀린예: if ($foo || $bar) if ($foo AND $bar) // okay but not
recommended for common syntax highlighting applications if (!$foo) if (! is_array($foo))
옳은예: if ($foo OR $bar) if ($foo && $bar) // recommended
if ( ! $foo) if ( ! is_array($foo))
리턴값 비교 및 형 변환 (Comparing Return Values and Typecasting)
PHP 함수중에는 실패했을때 명시적으로 FALSE 를 리턴하는것도 있지만 "" 나 0과 같이 유효한 값을 리턴하는 경우도 있습니다. 느슨한 비교의 경우 ""나 0 을 FALSE와 같이 취급하죠. 가능하면 느슨한 비교에서 암시적으로 FALSE로 처리해 줄 것을 기대하지말고 명시적으로 만들어야 합니다.
=== 와 !== 을 이용하여 엄격하게 형을 검사하세요.
틀린예: // If 'foo' is at the beginning of the string,
strpos will return a 0, // resulting in this conditional evaluating as TRUE
if (strpos($str, 'foo') == FALSE) 맞는예: if (strpos($str,
'foo') === FALSE)
틀린예: function build_string($str
= "") { if ($str == "") // uh-oh! What if FALSE or the integer 0 is passed
as an argument? { } } 맞는예: function build_string($str =
"") { if ($str === "") { } }
(형변환)typecasting쪽에도 유용한 정보가 있으므로 참조하시기 바랍니다. 형변환은 원하는것과 약간 다른 결과를 보여줄 수도 있습니다.예를들어, NULL 이나 FALSE를 string으로 변환하면 빈문자열을 반환하며, 숫자 0 은 문자 0을, TRUE는 "1"을 반환합니다.:
$str = (string) $str; // cast $str as a string
디버깅 (Debugging Code)
어떤 디버깅 코드도 소스코드에 남겨두지마세요. 만약 남아있더라도 주석처리 되어있어야 합니다.
예:var_dump(), print_r(), die(), and exit()
// print_r($foo);
파일내의 공백부분 (Whitespace in Files)
PHP의 여는 태그 앞이나 닫는태그뒤에는 절대로 공백이 있어서는 안됩니다. ExpressionEngine의 출력(output)은 먼저 버퍼에 저장됩니다. 그러므로, 공백은 ExpressionEngine의 출력 보다 앞서 출력을 내보내게 됩니다. 이러한 경우 에러가 발생하고 ExpressionEngine은 헤더정보를 내보내는데 실패하게 됩니다. 아래의 예제에서 마우스로 텍스트를 선택하면, 문제의 공백을 확인 할수 있습니다.
틀린예:
<?php
// ...there is whitespace and a linebreak above the opening PHP tag
// as well as whitespace after the closing PHP tag
?>
옳은예:
<?php
// this sample has no whitespace before or after the opening and closing PHP tags
?>
호환성 (Compatibility)
특별히 명시된게 없다면, 모든 코드는 PHP 4.3이나 그 이상에 호환됩니다. 그리고, PHP 기본 라이브러리 외의 것을 사용할 경우 , 그 라이브러리가 기본라이브러리와 동일한 이름의 함수를 포함하고 있다면, 내부적으로 기본이 아니라 추가로 설치된 라이브러리의 함수를 사용할 수도 있습니다. 그러므로 라이브러리를 추가하실때 반드시 기본라이브러리와 중복되는 함수가 있는지 확인하세요.
일반적 단어를 사용한 클래스 및 파일이름(Class and File Names using Common Words)
add-on 으로 작성한 클래스명이나 파일명이 너무 일반적이라면, 다른 PHP스크립트와 충돌할 수 있으므로, 고유한 접두어를 붙이는것이 좋습니다.명심해야 할것은 당신이 작성한 소스코드를 사용하는 다른 개발자나 사용자는 그 코드를 다른코드와 동시에 사용할 가능성이 높다는 점입니다.개발자의 이름이나 회사의 이름을 접두어로 쓰면 좋습니다.
틀린예: class Email pi.email.php class Xml ext.xml.php class
Import mod.import.php 옳은예: class Pre_email pi.pre_email.php
class Pre_xml ext.pre_xml.php class Pre_import mod.pre_import.php
데이터베이스 테이블 명 (Database Table Names)
add-on 을 만들경우 모든 테이블명은 'exp_' 로 시작해야합니다.그 다음은 개발자의 이름이나 회사명 접두어를 추가한후 짧고 명확한 테이블명을 설정하시면 됩니다. ExpressionEngine의 database class 가 접두어를 실재 사용하는 테이블 명으로 자동변환하므로, 개발자가 신경쓸 필요는 없습니다.
틀린예: email_addresses // 두개의 접두어가 다 빠졌음 pre_email_addresses
// exp_ 접두어가 빠졌음exp_email_addresses // 고유접두어(개발자이름이나,회사이름)이빠졌음 옳은예:
exp_pre_email_addresses
주의: MySQL은 테이블 이름에 64 자의 제한이 있습니다. 이런 제한이 큰 이슈가 되진 않을걸로 보이네요. 아래처럼 64자보다 긴 이름은 대체로 쓸데없이 기니까요. 아닌가? exp_pre_email_addresses_of_registered_users_in_seattle_washington
한클래스에 한파일 (One File per Class)
add-on 작성시 사용하는 클래스는 한 클래스당 하나의 파일로 작성하세요. 그렇지않으면 클래스들끼리 너무 가깝게 결합할 수 있습니다. 예를 들어 ExpressionEngine 에서 여러 클래스를 가진 파일은 Database 클래스 파일인데, DB 클래스 와 DB_Cache 클래스 그리고 Magpie 클래스와Snoopy 클래스를 사용하는Magpie plugin을 모두 포함하고 있습니다.(설명이 부족한듯 ㅡ,.ㅡ)
공백부분 (Whitespace)
소스코드에서 공백부분을 나타낼때 스페이스대신 탭을 사용하세요. 이건 작은 습관이긴 하지만, 스페이스바를 이용하는것보다 탭을 이용하는것이 단계별 인던트(들여쓰기:indentation)를 확인하기에 더 좋고, 다른 개발자들이 당신의 코드를 사용할때 인던트(들여쓰기:indentation)를 자신이 원하는대로 바꿀 수 있게 해줍니다. 그리고 부가적으로 소스코드의 크기를 줄여줍니다.
줄바꿈 (Line Breaks)
줄바꿈은 반드시 Unix line break를 사용해야 합니다. 특히 윈도우 환경에서 작업하는 개발자가 주의해야할 사항인데, 반드시 텍스트에디터의 환경설정에서 Unix line break를 사용하도록 설정하세요.
인던트 (Code Indenting)
Allman 스타일의 인던트(들여쓰기)를 사용하세요.(참고: Allman 스타일이란 BSD의 Emacs 스타일이며 eric allman이 만들었나봄-자세한건 allman style 하면 위키가 잘 가르쳐줄것임).클래스 선언부를 제외하고, 대괄호는 한라인을 차지하도록 합니다. 또한 대괄호의 들여쓰기는 자기가 속한 개체(예를 들어 for(){ 에서의 {가 속한것은 for()가 된다)와 같은 레벨의 들여쓰기로 합니다.
틀린예: function foo($bar) { // ... } foreach ($arr as $key
=> $val) { // ... } if ($foo == $bar) { // ... } else { // ... } for ($i
= 0; $i < 10; $i++) { for ($j = 0; $j < 10; $j++) { // ... } } 옳은예:
function foo($bar) { // ... } foreach ($arr as $key => $val) { // ... }
if ($foo == $bar) { // ... } else { // ... } for ($i = 0; $i < 10; $i++)
{ for ($j = 0; $j < 10; $j++) { // ... } }
괄호의 여백(Bracket and Parenthetic Spacing)
통상 대괄호나 소괄호를 사용할때 여백을 줘서는 안됩니다. PHP의 제어구조에서 파라미터를 사용할경우 (declare, do-while, elseif, for, foreach, if, switch, while)에는 좀다 읽기 쉽게 하기위해서 여백을 사용합니다.
틀린예: $arr[ $foo ] = 'foo'; 맞는예: $arr[$foo] = 'foo'; // no spaces around
array keys 틀린예: function foo ( $bar ) { } 맞는예: function foo($bar) // no spaces
around parenthesis in function declarations { } 틀린예: foreach( $query->result()
as $row ) CORRECT: foreach ($query->result() as $row) // single space following
PHP control structures, but not in interior parenthesis
제어판에서의 로컬라이즈 텍스트 (Localized Text in Control Panel)
제어판에서 사용되는 모든 글자는 lang 파일에 변수로 선언되어야 합니다. 그렇게 함으로써 로컬라이즈(국가별로 손쉽게 언어를 바꾸는것)가 쉬워지겠죠.ㅎㅎ
틀린예: return "Invalid Selection"; 옳은예: return $LANG->line('invalid_selection');
Private 메소드와 변수 (Private Methods and Variables)
Public 메소드에서 사용하는 Private메소드 혹은 Private변수는 반드시 밑줄(_)로 시작해야합니다. 클래스내에서만 사용되는 변수나 메소드(예를 들어 utility 나helper 메소드들)따위가 되겠죠.
convert_text() // public method
_convert_text() // private method
PHP 에러 (PHP Errors)
코드는 에러가 없어야 하며, 경고등을 감춰서 에러가 없는것 처럼 보여서는 안됩니다. 예를 들어, 직접 설정한 변수가 아니라 $_POST 와 같이 다른곳에서 받아오는 변수를 사용할때는 사용전에 반드시 isset()으로 변수가 존재하는지를 먼저 검사해야 합니다.
add-on을 개발할때는 PHP 환경설정에서 display_errors를 enable로 설정하여 반드시 모든 사용자가 에러보고(error reporting)를 볼수 있도록 해야합니다. 아래와 같이 체크할 수 있습니다:
if (ini_get('display_errors') == 1)
{
exit "Enabled";
}
php.ini 를 수정할 권한이 없다면 아래 코드로 enable 할 수 있습니다:
ini_set('display_errors', 1);
주의: ini_set() 를 이용한 display_errors 는 php.ini에서 설정한것과 동일하지 않습니다.script가 Fatal error를 포함하고 있다면, 효과가 없습니다.(이건 테스트 해 봐야 할듯)
짧은 여는태그 (Short Open Tags)
항상 긴 PHP 여는태그를 사용하세요.어떤 서버는 short_open_tag 가 enable 되어있지 않을 수 있습니다.
틀린예: <? echo $foo; ?> <?=$foo?> 옳은예:
<?php echo $foo; ?>
한줄에 한문장 ( One Statement Per Line)
여러문장을 하나의 줄에 쓰지 마시길..
틀린예: $foo = 'this'; $bar = 'that'; $bat = str_replace($foo,
$bar, $bag); 옳은예: $foo = 'this'; $bar = 'that'; $bat = str_replace($foo,
$bar, $bag);
문자열 (Strings)
문자열안에 변수가 포함되어있지않다면, 기본적으로 작은 따옴표(')를 사용하세요. 그리고 문자열안에 변수가 포함되어있다면 {}로 변수를 감싸세요.만약 문자열내부에 작은따옴표가 포함되어있을경우는 큰따옴표(")로 문자열을 감싸서, 이스케이프시퀀스(\)를 사용하지 않도록 하세요.
틀린예: "My String" // 변수가 없으므로 큰따옴표를 쓸 필요가 없다"My string $foo"
// needs braces 'SELECT foo FROM bar WHERE baz = \'bag\'' // ugly 옳은예:
'My String' "My string {$foo}" "SELECT foo FROM bar WHERE baz = 'bag'"
쿼리 (SQL Queries)
MySQL 키워드는 항상 대문자로!: SELECT, INSERT, UPDATE, WHERE, AS, JOIN, ON, IN, etc.
긴 쿼리는 읽기쉽게 여러라인으로 작성하세요.
틀린예: // keywords are lowercase and query is too long for
// a single line (... indicates continuation of line) $query = $this->db->query("select
foo, bar, baz, foofoo, foobar as raboof, foobaz from exp_pre_email_addresses
...where foo != 'oof' and baz != 'zab' order by foobaz limit 5, 100"); 옳은예:
$query = $this->db->query("SELECT foo, bar, baz, foofoo, foobar AS raboof,
foobaz FROM exp_pre_email_addresses WHERE foo != 'oof' AND baz != 'zab' ORDER
BY foobaz LIMIT 5, 100");
기본 함수 파라미터 (Default Function Arguments)
가능하면 함수의 기본값을 설정해서, 잘못된 호출로 인한 에러를 방지하세요. 함수 기본값은 짧은 코드로 에러를 방지하는 수단입니다. 예:
function foo($bar = '', $baz = FALSE)
중복 태그 파라미터 (Overlapping Tag Parameters)
이부분은 정확히 뭘 말하는지 잘 모르겠습니다. 아시는분께서 해석해 주시면, 감사드리겠습니다.
Avoid multiple tag parameters that have effect on the same thing. For instance, instead of include= and exclude=, perhaps allow include= to handle the parameter alone, with the addition of "not", e.g. include="not bar". This will prevent problems of parameters overlapping or having to worry about which parameter has priority over another.