비교 연산자는 PHP에서 간과하기 쉬운 측면 중에 하나입니다. 그럴 경우 예상치 못한 결과에 당황하는 일을 많이 겪게 될 것입니다. 그런 문제 중에서 하나는 strict한 비교(boolean 타입을 integer 타입과 비교하는 등 타입을 자동으로 맞춰서 비교하는 것)를 할 때 발생합니다.
<?php
$a = 5; // integer 타입의 숫자 5
var_dump($a == 5); // 값을 비교; true
var_dump($a == '5'); // 타입을 무시하고 값을 비교; true
var_dump($a === 5); // 타입과 값을 모두 비교 (integer 와 integer); true
var_dump($a === '5'); // 타입과 값을 (integer 와 string); false
// 타입을 무시한 비교
if (strpos('testing', 'test')) { // 'test'가 인덱스 0에서 발견되어 strpos 는 0을 리턴. 0은 false로 취급된다.
// code...
}
// strict 비교
if (strpos('testing', 'test') !== false) { // (0 !== false)의 비교 결과는 true 이다.
// code...
}
‘if/else’ 구문을 함수나 클래스 메소드 안에서 사용할 때 흔히 하는 오해는 혹시 발생할 수 있는 경우를 대비해 ‘else’를 꼭 써야 한다는 것입니다. 하지만 조건문의 결과가 return 값을 정의하는 것 뿐이라면 ‘else’가 필수적인 것은 아닙니다.
<?php
function test($a)
{
if ($a) {
return true;
} else {
return false;
}
}
// vs.
function test($a)
{
if ($a) {
return true;
}
return false; // else is not necessary
}
// or even shorter:
function test($a)
{
return (bool) $a;
}
switch 구문은 끝없이 if else if 를 타이핑하지 않아도 되게 해주는 편리한 구문입니다. 하지만 몇 가지 주의해야 할 점들이 있습니다.
<?php
$answer = test(2);
function test($a)
{
switch ($a) {
case 1:
// code...
break; // switch 구문을 벗어나기 위해서 break 를 사용.
case 2:
// code... // break 를 써주지 않았으므로 'case 3' 로 계속 진행됨.
case 3:
// code...
return $result; // 함수 내에서는 'return' 하면 함수 실행이 종료됨.
default:
// code...
return $error;
}
}
네임스페이스를 사용할 때, 여러분이 작성한 함수 때문에 내장 함수를 사용할 수 없게되는 경우를 만날 수 있습니다. 그럴 때에는 역슬래시를 사용하여 전역 함수를 호출하는 방법이 있습니다.
<?php
namespace phptherightway;
function fopen()
{
$file = \fopen(); // 함수 이름이 내장 함수와 같다.
// '\' 를 붙여서 전역 네임스페이스의 함수를 실행한다.
}
function array()
{
$iterator = new \ArrayIterator(); // ArrayIterator는 내장 클래스이다. 역슬래시 없이 사용하면
// phptherightway 라는 네임스페이스에서 ArrayIterator 를 찾으려고 할 것이다.
}
<?php
$a = 'Multi-line example'; // 연결 및 대입 연산자 (.=)
$a .= "\n";
$a .= 'of what not to do';
// vs
$a = 'Multi-line example' // 연결 연산자 (.)
. "\n" // 두 번째 라인부터는 들여써준다.
. 'of what to do';
문자열은 문자들의 나열입니다, 꽤 쉬워보입니다. 이 말은, 약간의 다른 방법(작은따옴표, 큰따옴표)으로 문자열 타입간에 미묘한 차이가 발생할 수 있고, 조금씩 다른문법을 제공합니다.
작은따옴표는 “리터럴 문자열”을 나타내기 위해 사용합니다. 리터럴 문자열은 특수 문자나 변수로 해석할 수 없습니다. 만약
작은따옴표를 사용한다면, 'some $thing'
처럼 변수명을 정하며, some $thing
로 출력을 받을 수 있습니다. 만약 큰
따옴표를 사용하는 경우, 즉, $thing
변수명을 찾아서 결과가 없으면 에러 메세지를 표시해야 합니다.
<?php
echo 'This is my string, look at how pretty it is.'; // 단순히 텍스트만 담고 있는 문자열을 PHP에게 분석시킬 필요가 없다.
/**
* 출력:
*
* This is my string, look at how pretty it is.
*/
큰따옴표는 문자열의 스위스 군용 나이프 입니다. 큰따옴표는 미리 언급한것 처럼 \n
개행, \t
탭, 기타등등 과 같은
특수문자는 해석하지만, 특수문자의 모든 종류를 해석하지는 않습니다.
<?php
echo 'phptherightway is ' . $adjective . '.' // 변수와 이스케이프 문자를 포함시키려고 작은따옴표 문자열을
. "\n" // 여러 줄에 걸쳐서 연결 연산자로 연결시키는 예제 코드
. 'I love learning' . $code . '!';
// vs
echo "phptherightway is $adjective.\n I love learning $code!" // 큰따옴표 문자열을 사용하면 연결 연산자를 여러번
// 쓰지 않고도 한 방에 해결할 수 있다.
큰따옴표는 변수를 포함할 수 있는데, 이것을 “Interpolation” 이라고 합니다.
<?php
$juice = 'plum';
echo "I like $juice juice"; // 출력: I like plum juice
Interpolation은 종종 변수가 다른 문자를 건드리는 경우에 씁니다. 하지만, 리터럴 문자와 변수명이 약간 혼란스러울 수 있다는 문제가 있습니다.
이 문제를 고치자면, 중괄호 안에 한쌍의 변수를 감싸면 됩니다.
<?php
$juice = 'plum';
echo "I drank some juice made of $juices"; // $juice 라는 변수를 읽을 수 없다.
// vs
$juice = 'plum';
echo "I drank some juice made of {$juice}s"; // $juice 가 제대로 분석된다.
/**
* 중괄호 안에 넣은 복잡한 형태의 변수 접근 방식도 잘 지원됩니다.
*/
$juice = array('apple', 'orange', 'plum');
echo "I drank some juice made of {$juice[1]}s"; // $juice[1] 이 잘 분석된다.
Nowdoc 문법은 5.3 에서 추가된 기능입니다. 작은따옴표와 동일한 특성을 가지고 있습니다.
<?php
$str = <<<'EOD' // <<< 기호로 nowdoc 문법 구문을 시작한다.
Example of string
spanning multiple lines
using nowdoc syntax.
$a does not parse.
EOD; // 끝을 나타내는 'EOD'는 반드시 줄의 가장 처음에 나와야 하고, 뒤에 다른 구문이 오면 안된다.
/**
* 출력:
*
* Example of string
* spanning multiple lines
* using nowdoc syntax.
* $a does not parse.
*/
Heredoc 문법은 큰따옴표와 동일하게 동작합니다.
<?php
$a = 'Variables';
$str = <<<EOD // <<< 기호로 heredoc 문법 구문을 시작한다.
Example of string
spanning multiple lines
using heredoc syntax.
$a are parsed.
EOD; // 끝을 나타내는 'EOD'는 반드시 줄의 가장 처음에 나와야 하고, 뒤에 다른 구문이 오면 안된다.
/**
* 출력:
*
* Example of string
* spanning multiple lines
* using heredoc syntax.
* Variables are parsed.
*/
It should be noted that multiline strings can also be formed by continuing them across multilines in a statement. e.g. 여러 줄에 걸쳐 계속 입력하는 방식으로 여러 줄을 작성할 수도 있다는 것에도 주목할 필요가 있습니다. 예를 들어
$str = "
Example of string
spanning multiple lines
using statement syntax.
$a are parsed.
";
/**
* Output:
*
* Example of string
* spanning multiple lines
* using statement syntax.
* Variables are parsed.
*/
작은따옴표는 보통 큰따옴표보다 빠르다는 속설이 있습니다. 하지만 사실이 아닙니다.
하나의 문자열을 정의하고 복잡한 일이나 값을 연결하려고 하지 않는 경우, 작은따옴표나 큰따옴표를 사용한 문장은 동일한 의미를 갖습니다. 어느것도 더 빠르지 않습니다.
만약 일반 문자열(큰따옴표 문자열 또는 작은따옴표 문자열 어느것이든지)이나 Interpolation된 변수를 포함한 큰따옴표
문자열을 여러개를 연결하고자 한다면, 그 결과는 다양할 수 있습니다. 그 연결하고자 하는 개수가 적다면 도트 연산자(.
)를
사용하는 편이 조금더 빠릅니다. 만약 엄청나게 많은 변수를 사용한다면 Interpolation을 사용하는 쪽이 더 빠릅니다.
당신이 문자열로 무엇을 하든, 눈에 띄는 효과는 발생하지 않습니다. 위에서 이야기한 두가지 중 어느 것을 사용해서 코드를 다시 작성하는 것은 굉장히 무의미한 일입니다. 그렇기 때문에 두 차이가 갖는 의미와 효과를 완전히 이해하지 않았다면 이러한 작은 최적화(micro-optimization)는 피해야 합니다.
삼항 연산자(ternary operator)는 코드를 간결하게 표현하는 좋은 방법이지만, 남용되는 경향이 있어 주의해야 합니다. 삼항 연산자를 중첩해서 사용할 수 있기는 하지만, 이해할 수 없는 코드가 되기 때문에 그렇게 사용하지 않는 것이 좋습니다.
<?php
$a = 5;
echo ($a == 5) ? 'yay' : 'nay';
코드 줄 수를 줄이기 위해서 모든 가독성을 포기한 코드를 한 번 비교해 봅시다.
<?php
$b = 10;
echo ($a) ? ($a == 5) ? 'yay' : 'nay' : ($b == 10) ? 'excessive' : ':('; // 삼항 연산자를 과도하게 중첩시켜서 코드를 알아볼 수 없다
‘return’ 구문과 삼항 연산자를 같이 쓰는 올바른 방법을 봅시다.
<?php
$a = 5;
echo ($a == 5) ? return true : return false; // 이렇게 하면 에러가 발생한다.
// vs
$a = 5;
return ($a == 5) ? 'yay' : 'nope'; // 'yay'를 리턴한다.
boolean 값을 리턴하기 위해 삼항연산자를 할 필요가 없습니다. 예를 들어보겠습니다.
<?php
$a = 3;
return ($a == 3) ? true : false; // $a == 3 인지에 따라 true나 false 를 리턴한다.
// vs
$a = 3;
return $a == 3; // $a == 3 인지에 따라 true나 false 를 리턴한다.
===, !==, !=, == 등의 모든 비교 연산자에 마찬가지로 적용되는 사실입니다.
삼항연산자를 사용하는 경우, 괄호는 코드의 가독성과, 블록 내부 결합을 향상시킵니다. 괄호를 사용할 필요가 없는 경우:
<?php
$a = 3;
return ($a == 3) ? "yay" : "nope"; // $a == 3 일 때에는 yay 를 리턴한다.
// vs
$a = 3;
return $a == 3 ? "yay" : "nope"; // $a == 3 일 때에는 yay 를 리턴한다.
구문 여러개를 묶어서 한 덩어리로 조건 판단이 되도록 하는데에 괄호를 사용하는 것이 일반적인 일입니다. ($a == 3 and $b == 4)이라는 조건과 $c == 5 이라는 조건이 모두 참일 때에 true 를 리턴하는 예제 코드입니다.
<?php
return ($a == 3 && $b == 4) && $c == 5;
아래 코드는 ($a != 3 AND $b != 4)이라는 조건이나 $c == 5 라는 조건 둘 중에 하나만 참이면 true 를 리턴하는 예제 코드입니다.
<?php
return ($a != 3 && $b != 4) || $c == 5;
PHP 5.3부터 삼항 연사자의 중간 부분을 생략 가능합니다. “expr1 ?: expre3” 표현식은 expr1이 TRUE로 평가되는 경우 expr1을 리턴하고, 아닌 경우에 expr3을 리턴합니다.