소개
PHP에서 함수는 인수(argument)를 통해 호출하는 환경이나 스크립트로부터 입력값을 받도록 정의할 수 있습니다. 인수는 함수 이름 뒤의 괄호 안에 쉼표로 구분하여 나열하며, 함수를 호출할 때는 정의된 형식 매개변수와 같은 개수의 인수를 전달해야 합니다.
PHP는 다음과 같은 다양한 방식의 인수 전달을 지원합니다.
- 값에 의한 전달(pass by value)
- 참조에 의한 전달(pass by reference)
- 기본값이 설정된 인수
- 가변 개수의 인수
인수를 받는 함수: 값에 의한 전달
다음 예제는 두 개의 형식 매개변수를 가지는 함수를 정의하고, 인수를 값으로 전달하며 호출합니다. 함수의 인수는 함수 내부에서 지역 변수처럼 취급됩니다. 따라서 함수 내부에서 인수의 값을 변경해도 그 변경 사항은 함수 외부에는 반영되지 않습니다.
아래 예제에서 $x의 값은 함수 내부에서 변경되지만, 함수 호출이 끝난 후 $x의 값을 확인해 보면 원래 값 그대로 유지되는 것을 볼 수 있습니다.
예제
<?php
function add($x, $y){
$x = $x + $y;
echo $x . "\n";
}
$x = 10;
$y = 20;
add($x, $y);
// 함수 외부의 $x는 기존 값을 유지합니다.
echo $x;
?>
실행 결과
30 10
배열을 함수에 전달하기
다음 예제에서는 배열을 인수로 받는 add() 함수를 정의합니다. 함수 내부에서는 foreach 반복문을 사용해 배열의 각 요소를 순회하며 합계를 계산합니다.
예제
<?php
function add($arr){
$sum = 0;
foreach ($arr as $i){
$sum += $i;
}
echo "sum = " . $sum;
}
add(array(1, 2, 3));
?>
실행 결과
sum = 6
참조로 인수 전달하기
기본적으로 함수의 인수에는 값이 전달됩니다. 따라서 함수 내부에서 인수의 값을 변경해도 그 결과는 함수 외부에 반영되지 않습니다. 반면 인수를 참조(by reference)로 전달하면, 함수 내부에서 발생한 변경 사항이 함수 외부의 원래 변수에도 그대로 적용됩니다.
참조로 값을 받으려면 매개변수 이름 앞에 &(앰퍼샌드) 기호를 붙여야 합니다.
예제
<?php
function swap(&$x, &$y){
$t = $x;
$x = $y;
$y = $t;
echo "inside function x=$x y=$y\n";
}
$x = 5;
$y = 7;
echo "before calling function x=$x y=$y\n";
swap($x, $y);
echo "after calling function x=$x y=$y\n";
?>
실행 결과
before calling function x=5 y=7 inside function x=7 y=5 after calling function x=7 y=5
swap() 함수 내부에서 $x와 $y의 값이 서로 맞바뀌었습니다. 변수가 참조로 전달되었기 때문에 함수 외부에서도 수정된 값이 그대로 유지되는 것을 확인할 수 있습니다.
타입 힌트(타입 선언)
PHP는 본질적으로 동적 타입(dynamic typing) 언어입니다. 따라서 C/C++나 Java처럼 변수를 선언할 때 타입을 명시할 필요가 없습니다. 하지만 함수의 매개변수에 타입을 선언하면 파서가 잘못된 데이터 타입이 전달되는 상황을 감지할 수 있어 코드의 안정성이 크게 향상됩니다.
문법
// 타입 힌트를 사용해 함수 정의하기
function myfunction(type $arg1, type $arg2){
..
..
}
스칼라 타입(int, float, string, bool)을 비롯해 array, 클래스/인터페이스 이름, iterable, object 등 PHP의 모든 표준 데이터 타입을 함수 선언 시 타입 힌트로 사용할 수 있습니다.
가변 길이 인수 목록
매개변수 이름 앞에 ...(스프레드 연산자)를 붙이면 호출 시 전달되는 인수의 개수에 제한 없이 임의의 개수만큼 값을 받을 수 있습니다. 전달된 인수들은 하나의 배열로 묶여 함수 내부에서 사용됩니다.
예제
<?php
function add(...$numbers){
$ttl = 0;
foreach ($numbers as $num){
$ttl = $ttl + $num;
}
return $ttl;
}
$total = add(10, 15, 20);
echo "total= $total\n";
echo "total=". add(1, 2, 3, 4, 5). "\n";
?>
실행 결과
total= 45 total=15
또한 func_get_args() 함수를 사용하면 함수에 전달된 인수들의 목록을 배열 형태로 얻을 수 있습니다. 이 경우 함수 정의에 형식 매개변수를 명시하지 않아도 되며, PHP 반복문으로 인수 목록의 각 값을 순회할 수 있습니다.
타입 강제 변환과 strict_types
다음 예제는 int 타입 힌트를 가진 add() 함수를 정의하고 호출합니다.
예제
<?php
function add(int $x, int $y){
$z = $x + $y;
echo "addition=$z\n";
}
add(10, 20);
add(5.55, 6.66);
?>
실행 결과
addition=30 addition=11
두 번째 호출에서는 실수(float)가 인수로 전달되었지만 오류나 경고가 표시되지 않습니다. 이는 PHP가 덧셈을 수행하기 위해 내부적으로 float를 int로 자동 변환(강제 변환, coercion)하기 때문입니다.
이러한 자동 타입 변환을 방지하려면 declare 구문과 함께 strict_types=1을 선언하면 됩니다.
예제
<?php
declare(strict_types=1);
function add(int $x, int $y){
$z = $x + $y;
echo "addition=$z\n";
}
add(10, 20);
add(5.55, 6.66);
?>
strict_types=1을 선언한 후에는 두 번째 add() 호출에서 TypeError 예외가 발생합니다.
실행 결과
addition=30 PHP Fatal error: Uncaught TypeError: Argument 1 passed to add() must be of the type integer, float given