Computer >> 컴퓨터 >  >> 프로그래밍 >> PHP

PHP 함수 인수 완벽 가이드: 값 전달부터 참조, 타입 힌트까지


소개

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