변수

변수 (Variables)

PHP에서 변수가 어떻게 생겼고, 어디까지 유효하며, 밖에서 들어온 값은 어떻게 다뤄지는지 한 번에 정리한 챕터예요. 이름 짓는 규칙부터 값/참조 대입, 스코프, 그리고 폼이나 쿠키로 들어오는 외부 변수까지, PHP 변수에 대한 거의 모든 걸 다뤄요.

출처: PHP 매뉴얼

본문

PHP에서 변수는 $(달러) 뒤에 변수 이름을 붙여서 표현해요. 변수 이름은 대소문자를 구분해요.

올바른 변수 이름은 글자(A-Z, a-z, 또는 128부터 255까지의 바이트)나 밑줄(_)로 시작하고, 그 뒤에 글자·숫자·밑줄을 아무렇게나 이어 붙일 수 있어요. 정규식으로는 이렇게 표현돼요.

^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$

⚠️ 참고: 변수 이름은 문자(characters)가 아니라 바이트(byte) 단위로 비교돼요. PHP는 128~255 범위 바이트의 인코딩을 해석하거나 검증하지 않아서, 바이트가 완전히 같아야 같은 변수로 취급돼요. 그래서 UTF-8로 쓰인 이름은 멀티바이트 시퀀스의 모든 바이트가 유효 범위 안에 들어와서 잘 동작하지만, Shift-JIS나 UTF-16처럼 멀티바이트 안에 128보다 작은 바이트가 들어가는 인코딩은 안 돼요. 또 렌더링 결과는 똑같아 보여도 서로 다른 변수일 수 있어요. 예를 들어 ä를 U+00E4로 쓴 경우와 a 뒤에 결합 다이어레시스 U+0308을 붙인 경우는 서로 다른 변수예요. (보통은 이 깊은 내용을 신경 쓸 일이 없어요.)

⚠️ 참고: $this는 대입할 수 없는 특별한 변수예요. PHP 7.1.0 이전에는 가변 변수 등으로 간접 대입이 가능했지만, 이후 버전에서는 불가능해요. 또 PHP 8.0.0부터는 정의되지 않은 변수에 접근하면 E_NOTICE가 아니라 E_WARNING이 발생해요.

예를 들어 다음 이름들은 모두 유효한 변수 이름이에요.

<?php
$var = 'Bob';
$Var = 'Joe';
echo "$var, $Var";      // outputs "Bob, Joe"

$_4site = 'not yet';    // valid; starts with an underscore
$täyte = 'mansikka';    // valid; 'ä' is (Extended) ASCII 228.

반면 숫자로 시작하는 이름은 유효하지 않아요.

<?php
$4site = 'not yet';     // invalid; starts with a number

PHP는 사실 이름 규칙을 벗어난 어떤 바이트 조합도 변수 이름으로 받아들여요. 다만 이런 이름은 문법상 직접 쓸 수 없으니, 런타임에만 동적으로 접근할 수 있어요. 접근 방법은 가변 변수 문단을 봐 주세요.

<?php
${'invalid-name'} = 'bar';
$name = 'invalid-name';
echo ${'invalid-name'}, " ", $$name;

위 예제를 실행하면 이렇게 출력돼요.


bar bar

값 대입과 참조 대입

기본적으로 변수는 항상 값(value)으로 대입돼요. 어떤 표현식을 변수에 대입하면 원래 표현식의 값 전체가 그대로 복사되는 거죠. 그래서 한 변수의 값을 다른 변수에 대입한 뒤, 둘 중 하나를 바꿔도 다른 쪽에는 아무 영향이 없어요.

PHP에는 또 다른 대입 방식이 있는데, 바로 참조(reference)로 대입하는 거예요. 이 경우 새 변수는 원래 변수를 그냥 가리키는 별명(alias)처럼 동작해요. 새 변수를 바꾸면 원래 변수에도 영향이 가고, 그 반대도 마찬가지예요.

참조로 대입하려면 대입되는(원본) 변수 앞에 앰퍼샌드(&)를 붙이면 돼요. 아래 코드는 My name is Bob을 두 번 출력해요.

<?php
$foo = 'Bob';              // Assign the value 'Bob' to $foo
$bar = &$foo;              // Reference $foo via $bar.
$bar = "My name is $bar";  // Alter $bar...
echo $bar . PHP_EOL;
echo $foo . PHP_EOL;       // $foo is altered too.

한 가지 중요한 점은 변수만 참조로 대입할 수 있다는 거예요.

<?php
$original = 25;
$ref1 = &$original;        // This is a valid assignment.
$ref2 = &(24 * 7);         // Invalid; references an unnamed expression.
<?php
// Note the lack of & indicating a returned reference in the function declaration.
// i.e. the function does not return a reference, so the result cannot be assigned by reference
function test()
{
   $original = 25;
   return $original;
}

// Note: A notice is issued, but the non-reference value is assigned
$result1 = &test();        // Invalid because test() doesn't return a variable by reference.
var_dump($result1);

// This function is defined as returning a reference, but does not return a variable
function &test2()
{
    return 26;             // Invalid because the returned value isn't a variable reference.
}

// Note: The non-reference value is assigned
$result2 = &test2();
var_dump($result2);

PHP에서는 변수를 미리 선언할 필요가 없지만, 그래도 선언해 두는 게 아주 좋은 습관이에요. 정의되지 않은 변수에 접근하면 E_WARNING이 발생하고(PHP 8.0.0 이전에는 E_NOTICE), 정의되지 않은 변수의 기본값은 null이에요. 변수가 이미 초기화됐는지 확인하려면 isset()을 쓰면 돼요.

<?php
// Unset AND unreferenced (no use context) variable.
var_dump($unset_var);

위 예제를 실행하면 이렇게 출력돼요.


Warning: Undefined variable $unset_var in ...
NULL

PHP는 또 정의되지 않은 변수에서 배열을 자동으로 만들어 주는 autovivification(자동 생성) 을 지원해요. 정의되지 않은 변수에 요소를 추가하면 경고 없이 새 배열이 생겨요.

<?php
$unset_array[] = 'value'; // Does not generate a warning.
var_dump($unset_array);

⚠️ 경고: 정의되지 않은 변수가 가진 기본값(null)에 의존하는 코드는 주의가 필요해요. 같은 이름의 변수를 쓰는 다른 파일을 한 파일 안에서 include 했을 때 문제가 될 수 있거든요.

변수는 unset() 언어 구조로 파괴할 수 있어요. 변수 관련 함수가 궁금하다면 변수 함수 레퍼런스를 참고하세요.

변수 스코프 (Variable scope)

변수의 스코프는 그 변수가 정의된 문맥(context)이에요. PHP에는 함수 스코프(function scope)전역 스코프(global scope) 가 있어요. 함수 밖에서 정의된 변수는 전역 스코프에 국한되고, 파일을 include 하면 그 파일 속 코드는 include가 일어난 줄의 변수 스코프를 그대로 물려받아요.

<?php
$a = 1;
include 'b.inc'; // Variable $a will be available within b.inc

이름 있는 함수나 익명(anonymous) 함수 안에서 만든 변수는 그 함수 본문 스코프에만 국한돼요. 다만 화살표 함수(arrow function)는 부모 스코프의 변수를 바인딩해서 본문 안에서 쓸 수 있게 해 줘요. 호출하는 파일 안의 함수 내부에서 include를 한 경우엔, 호출된 파일의 변수들이 마치 호출한 함수 안에서 정의된 것처럼 사용 가능해요.

<?php
$a = 1; // global scope

function test()
{ 
    var_dump($a); // Variable $a is undefined as it refers to a local version of $a
}

test();

이 예제는 정의되지 않은 변수 $a 때문에 E_WARNING(PHP 8.0.0 이전엔 E_NOTICE)을 발생시켜요. echo가 가리키는 $a는 함수 안의 지역 버전인데 이 스코프에서 값을 할당받지 못했기 때문이에요. 여기서 C 언어와의 차이를 짚어 볼게요. C에서는 전역 변수가 특별히 재정의되지 않는 한 함수 안에서 자동으로 사용 가능해요. 그런데 이렇게 하면 사람이 실수로 전역 변수를 바꿔버릴 위험이 있어요. PHP에서는 함수 안에서 전역 변수를 쓰려면 그 함수 안에서 그 변수를 global로 선언해야 해요.

global 키워드

global 키워드는 전역 스코프의 변수를 지역 스코프로 바인딩하는 데 쓰여요. 변수 하나나 변수 목록과 함께 쓸 수 있고, 같은 이름의 전역 변수를 참조하는 지역 변수가 생성돼요. 해당 전역 변수가 없으면 전역 스코프에 그 변수가 만들어진 뒤 null로 초기화돼요.

<?php
$a = 1;
$b = 2;

function Sum()
{
    global $a, $b;

    $b = $a + $b;
} 

Sum();
echo $b;

위 예제를 실행하면 이렇게 출력돼요.


3

함수 안에서 $a$b를 global로 선언하면, 이후 이 두 변수에 대한 모든 참조가 전역 버전으로 처리돼요. 함수가 조작할 수 있는 전역 변수의 개수에는 제한이 없어요.

전역 스코프의 변수에 접근하는 두 번째 방법은 PHP가 정의하는 특별한 $GLOBALS 배열을 쓰는 거예요. 앞의 예제를 이렇게 다시 쓸 수 있어요.

<?php
$a = 1;
$b = 2;

function Sum()
{
    $GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b'];
} 

Sum();
echo $b;

$GLOBALS는 전역 변수 이름이 키(key), 그 변수의 내용이 값(value)인 연관 배열이에요. $GLOBALS슈퍼글로벌(superglobal) 이라서 어떤 스코프에서든 존재해요. 그래서 함수 안에서도 이렇게 전역 데이터에 바로 접근할 수 있어요.

<?php
function test_superglobal()
{
    echo $_POST['name'];
}

⚠️ 참고: 함수 밖에서 global 키워드를 쓰는 건 오류가 아니에요. 그 파일이 함수 안에서 include된다면 유용하게 쓸 수 있어요.

static 변수

변수 스코프의 또 다른 중요한 기능은 static 변수예요. static 변수는 지역 함수 스코프에만 존재하지만, 프로그램 실행이 그 스코프를 떠나도 값을 잃지 않아요. 아래 예제를 볼게요.

<?php
function test()
{
    $a = 0;
    echo $a . PHP_EOL;
    $a++;
}

test();
test();
test();

이 함수는 호출할 때마다 $a0으로 설정하고 0을 출력하니 쓸모가 없어요. 함수를 빠져나가면 $a가 사라져서 $a++이 아무 일도 못 하거든요. 현재 카운트를 잃지 않는 유용한 카운팅 함수를 만들려면 $a를 static으로 선언하면 돼요.

<?php
function test()
{
    static $a = 0;
    echo $a . PHP_EOL;
    $a++;
}

test();
test();
test();

이제 $a는 함수의 첫 호출에서만 초기화되고, test()를 호출할 때마다 $a의 값을 출력한 뒤 증가시켜요.

static 변수는 또 재귀 함수를 다루는 한 가지 방법이기도 해요. 아래의 간단한 함수는 static 변수 $count로 언제 멈출지 판단하면서 재귀적으로 10까지 세요.

<?php
function test()
{
    static $count = 0;

    $count++;
    echo $count . PHP_EOL;
    if ($count < 10) {
        test();
    }
    $count--;
}

test();

PHP 8.3.0 이전에는 static 변수를 상수 표현식으로만 초기화할 수 있었어요. PHP 8.3.0부터는 함수 호출 같은 동적 표현식도 허용돼요.

<?php
function foo(){
    static $int = 0;          // correct 
    static $int = 1+2;        // correct
    static $int = sqrt(121);  // correct as of PHP 8.3.0

    $int++;
    echo $int;
}

익명 함수 안의 static 변수는 그 특정 함수 인스턴스 안에서만 유지돼요. 익명 함수가 호출마다 다시 만들어지면 static 변수도 다시 초기화돼요.

<?php
function exampleFunction($input) {
    $result = (static function () use ($input) {
        static $counter = 0;
        $counter++;
        return "Input: $input, Counter: $counter\n";
    });

    return $result();
}

// Calls to exampleFunction will recreate the anonymous function, so the static
// variable does not retain its value.
echo exampleFunction('A'); // Outputs: Input: A, Counter: 1
echo exampleFunction('B'); // Outputs: Input: B, Counter: 1

PHP 8.1.0부터 static 변수를 쓰는 메서드가 상속(오버라이드 없이)되면, 상속된 메서드는 부모 메서드와 static 변수를 공유해요. 즉 메서드의 static 변수가 static 프로퍼티처럼 동작하게 된 거죠. PHP 8.3.0부터는 static 변수를 임의 표현식으로 초기화할 수 있어요.

<?php
class Foo {
    public static function counter() {
        static $counter = 0;
        $counter++;
        return $counter;
    }
}
class Bar extends Foo {}
var_dump(Foo::counter()); // int(1)
var_dump(Foo::counter()); // int(2)
var_dump(Bar::counter()); // int(3), prior to PHP 8.1.0 int(1)
var_dump(Bar::counter()); // int(4), prior to PHP 8.1.0 int(2)

global·static 변수와 참조

PHP는 staticglobal 수정자를 참조(reference) 개념으로 구현해요. 예컨대 함수 스코프 안에서 global로 가져온 진짜 전역 변수는 실제로 그 전역 변수에 대한 참조를 만드는 거예요. 이 때문에 의외의 동작이 생길 수 있는데, 아래 예제를 보면 이해가 쉬워요.

<?php
function test_global_ref() {
    global $obj;
    $new = new stdClass;
    $obj = &$new;
}

function test_global_noref() {
    global $obj;
    $new = new stdClass;
    $obj = $new;
}

test_global_ref();
var_dump($obj);
test_global_noref();
var_dump($obj);

위 예제를 실행하면 이렇게 출력돼요.


NULL
object(stdClass)#1 (0) {
}

static 문장도 비슷하게 동작해요. 참조는 static으로 저장되지 않아요.

<?php
function &get_instance_ref() {
    static $obj;

    echo 'Static object: ';
    var_dump($obj);
    if (!isset($obj)) {
        $new = new stdClass;
        // Assign a reference to the static variable
        $obj = &$new;
    }
    if (!isset($obj->property)) {
        $obj->property = 1;
    } else {
        $obj->property++;
    }
    return $obj;
}

function &get_instance_noref() {
    static $obj;

    echo 'Static object: ';
    var_dump($obj);
    if (!isset($obj)) {
        $new = new stdClass;
        // Assign the object to the static variable
        $obj = $new;
    }
    if (!isset($obj->property)) {
        $obj->property = 1;
    } else {
        $obj->property++;
    }
    return $obj;
}

$obj1 = get_instance_ref();
$still_obj1 = get_instance_ref();
echo "\n";
$obj2 = get_instance_noref();
$still_obj2 = get_instance_noref();

위 예제를 실행하면 이렇게 출력돼요.


Static object: NULL
Static object: NULL

Static object: NULL
Static object: object(stdClass)#3 (1) {
  ["property"]=>
  int(1)
}

이 예제가 보여주는 건, static 변수에 참조를 대입하면 그 참조가 다음 호출 때 기억되지 않는다는 점이에요. (&get_instance_ref()를 두 번째 호출했을 때 static object가 다시 NULL인 걸 볼 수 있어요.)

가변 변수 (Variable variables)

때로는 변수 이름 자체를 동적으로 만들고 싶을 때가 있어요. 즉 그때그때 설정하고 사용할 수 있는 "변수 이름"을 쓰는 거죠. 보통 변수는 이런 식으로 설정해요.

<?php
$a = 'hello';
var_dump($a);

가변 변수(variable variable)는 어떤 변수의 값 하나를 가져와서, 그 값을 또 다른 변수의 이름으로 취급해요. 위 예제에서 hello를 변수 이름으로 쓰려면 달러 기호를 두 개 붙이면 돼요.

<?php
$a = 'hello';
$$a = 'world';
var_dump($hello);

이 시점에 PHP 기호 트리에는 $a(내용 "hello")와 $hello(내용 "world") 두 변수가 생겨 있어요. 그래서 이 문장은,

<?php
$a = 'hello';
$$a = 'world';
echo "$a {$$a}";

아래 문장과 완전히 같은 결과를 내요.

<?php
$a = 'hello';
$$a = 'world';
echo "$a $hello";

즉 둘 다 hello world를 출력해요.

가변 변수를 배열과 함께 쓰려면 모호함(ambiguity)을 정리해야 해요. $$a[1]을 파서가 보면, $a[1]을 변수로 쓰려는 건지, $$a를 변수로 쓰고 거기서 [1] 인덱스를 붙이려는 건지 알 수가 없어요. 이 모호함을 푸는 문법은 전자의 경우 ${$a[1]}, 후자의 경우 ${$a}[1]이에요.

클래스 프로퍼티도 가변 프로퍼티 이름으로 접근할 수 있어요. 가변 프로퍼티 이름은 호출이 일어난 스코프에서 해석돼요. 예를 들어 $foo->$bar 같은 표현식이 있으면, 지역 스코프에서 $bar를 찾아 그 값을 $foo의 프로퍼티 이름으로 써요. $bar가 배열 접근인 경우도 마찬가지예요.

중괄호는 프로퍼티 이름의 경계를 명확히 구분할 때도 써요. 프로퍼티가 배열을 담고 있거나, 이름이 여러 부분으로 이뤄져 있거나, json_decode()나 SimpleXML처럼 보통은 유효하지 않은 문자를 이름에 포함할 때 특히 유용해요.

<?php
class Foo {
    public $bar = 'I am bar.';
    public $arr = ['I am A.', 'I am B.', 'I am C.'];
    public $r   = 'I am r.';
}

$foo = new Foo();
$bar = 'bar';
$baz = ['foo', 'bar', 'baz', 'quux'];
echo $foo->$bar . "\n";
echo $foo->{$baz[1]} . "\n";

$start = 'b';
$end   = 'ar';
echo $foo->{$start . $end} . "\n";

$arr = 'arr';
echo $foo->{$arr[1]} . "\n";
echo $foo->{$arr}[1] . "\n";

위 예제를 실행하면 이렇게 출력돼요.


I am bar.
I am bar.
I am bar.
I am r.
I am B.

⚠️ 경고: 가변 변수는 함수나 클래스 메서드 안에서 PHP의 슈퍼글로벌 배열과 함께 쓸 수 없어요. $this 변수도 동적으로 참조할 수 없는 특별한 변수예요.

미리 정의된 변수 (Predefined Variables)

PHP는 여러 미리 정의된 변수를 제공해요. 여기에 더해 웹 서버(적용 가능한 경우), 환경, 사용자 입력에서 온 변수를 담은 추가적인 사전 정의 배열도 제공하는데, 이 배열들은 모든 스코프에서 자동으로 사용 가능해서 흔히 "슈퍼글로벌" 이라고 불러요. (PHP에는 사용자가 정의하는 슈퍼글로벌이라는 건 없어요.) 자세한 건 슈퍼글로벌 목록을 참고하세요.

⚠️ 참고: 슈퍼글로벌은 함수나 클래스 메서드 안에서 가변 변수로 사용할 수 없어요.

variables_order 설정에 따라 일부 변수가 설정되지 않으면, 그에 해당하는 PHP 사전 정의 배열도 비어 있게 돼요.

외부 소스에서 온 변수 (Variables From External Sources)

HTML 폼 (GET과 POST)

폼이 PHP 스크립트로 제출되면 그 폼의 정보가 자동으로 스크립트에서 사용 가능해져요. 이 정보에 접근하는 방법은 몇 가지가 있어요.

<form action="foo.php" method="post">
    Name:  <input type="text" name="username" /><br />
    Email: <input type="text" name="email" /><br />
    <input type="submit" name="submit" value="Submit me!" />
</form>

보통 HTML 폼의 데이터에 접근하는 방법은 두 가지예요. 아래에 지금 쓸 수 있는 방법을 정리했어요.

<?php
echo $_POST['username'];
echo $_REQUEST['username'];

GET 폼도 비슷한데, 적절한 GET 사전 정의 변수를 쓰면 돼요. GET은 또 URL에서 ? 뒤에 오는 QUERY_STRING에도 적용돼요. 예를 들어 http://www.example.com/test.php?id=3에는 $_GET['id']로 접근할 수 있는 GET 데이터가 들어 있어요. $_REQUEST도 함께 참고하세요.

⚠️ 참고: 변수 이름 속의 점(dot)과 공백(space)은 밑줄로 변환돼요. 예를 들어 ``는 $_REQUEST["a_b"]가 돼요.

PHP는 또 폼 변수 문맥에서 배열도 이해해요. 관련 변수들을 한데 묶을 수도 있고, 다중 선택 입력 값들을 꺼내는 데 쓸 수도 있어요. 아래 예제는 폼을 자기 자신에게 POST하고, 제출되면 데이터를 화면에 보여줘요.

<?php
if ($_POST) {
    echo '<pre>';
    echo htmlspecialchars(print_r($_POST, true));
    echo '</pre>';
}
?>
<form action="" method="post">
    Name:  <input type="text" name="personal[name]" /><br />
    Email: <input type="text" name="personal[email]" /><br />
    Beer: <br />
    <select multiple name="beer[]">
        <option value="warthog">Warthog</option>
        <option value="guinness">Guinness</option>
        <option value="stuttgarter">Stuttgarter Schwabenbräu</option>
    </select><br />
    <input type="submit" value="submit me!" />
</form>

⚠️ 참고: 외부 변수 이름이 유효한 배열 문법으로 시작하면 끝의 나머지 문자는 조용히 무시돼요. 예를 들어 ``는 $_REQUEST['foo']['bar']가 돼요.

IMAGE SUBMIT 변수 이름

표준 제출 버튼 대신 이미지를 제출 버튼으로 쓸 수도 있어요.

<input type="image" src="image.gif" name="sub" />

사용자가 이미지의 어딘가를 클릭하면, 폼이 sub_xsub_y라는 두 변수를 추가로 동반해서 서버로 전송돼요. 이 변수에는 이미지 안에서 사용자가 클릭한 좌표가 담겨요. 참고로 브라우저가 실제로 보내는 이름에는 밑줄이 아니라 점(period)이 들어 있는데, PHP가 그 점을 밑줄로 자동 변환해 줘요.

HTTP 쿠키

PHP는 RFC 6265에 정의된 HTTP 쿠키를 투명하게 지원해요. 쿠키는 원격 브라우저에 데이터를 저장해 재방문 사용자를 추적·식별하는 메커니즘이에요. 쿠키는 setcookie() 함수로 설정할 수 있어요. 쿠키는 HTTP 헤더의 일부이기 때문에, Set-Cookie 함수는 브라우저로 어떤 출력을 보내기 전에 호출해야 해요. 이건 header() 함수와 같은 제약이에요. 쿠키 데이터는 $_COOKIE 같은 적절한 쿠키 배열과 $_REQUEST에서 사용할 수 있어요. 더 자세한 내용과 예제는 setcookie() 매뉴얼 페이지를 참고하세요.

⚠️ 참고: PHP 7.2.34, 7.3.23, 7.4.11부터 보안상의 이유로 들어오는 쿠키의 이름을 더 이상 url-decode 하지 않아요.

하나의 쿠키 변수에 여러 값을 대입하고 싶다면 배열로 대입하면 돼요.

<?php
setcookie("MyCookie[foo]", 'Testing 1', time()+3600);
setcookie("MyCookie[bar]", 'Testing 2', time()+3600);

이러면 두 개의 별도 쿠키가 생기지만, 스크립트 안에서는 MyCookie가 하나의 배열로 보여요. 한 쿠키에 여러 값을 담고 싶다면 값을 serialize()하거나 explode()해서 쓰는 걸 고려해 보세요.

쿠키는 경로나 도메인이 다르지 않으면 브라우저에서 같은 이름의 이전 쿠키를 덮어써요. 그래서 쇼핑 카트 애플리케이션에서는 카운터를 유지하고 넘겨주는 식으로 쓸 수 있어요.

<?php
if (isset($_COOKIE['count'])) {
    $count = $_COOKIE['count'] + 1;
} else {
    $count = 1;
}
setcookie('count', $count, time()+3600);
setcookie("Cart[$count]", $item, time()+3600);

들어오는 변수 이름의 점(dot)

보통 PHP는 스크립트로 전달되는 변수의 이름을 바꾸지 않아요. 다만 점(period, full stop)은 PHP 변수 이름에서 유효하지 않은 문자라는 점을 알아 둘 필요가 있어요. 이유를 볼게요.

<?php
$varname.ext;  /* invalid variable name */

파서는 이걸 $varname이라는 변수 뒤에 문자열 결합 연산자, 그리고 알려진 키나 예약어에 해당하지 않는 barestring(따옴표 없는 문자열) 'ext'가 따라오는 것으로 봐요. 당연히 의도한 결과가 아니죠. 그래서 PHP는 들어오는 변수 이름의 모든 점을 밑줄로 자동 변환해요.

변수 타입 알아내기

PHP는 변수의 타입을 그때그때 결정하고 (보통) 필요에 따라 변환하기 때문에, 특정 변수의 타입이 어떤지 항상 명확하진 않아요. PHP는 gettype(), is_array(), is_float(), is_int(), is_object(), is_string()처럼 변수 타입을 알아내는 함수를 여럿 제공해요. 타입 챕터도 함께 참고하세요.

HTTP는 텍스트 프로토콜이라서, $_POST·$_GET 같은 슈퍼글로벌 배열에 들어오는 거의 모든 내용은 문자열로 남아요. PHP가 값을 특정 타입으로 바꾸려 시도하지 않아요. 아래 예제에서 $_GET["var1"]은 문자열 "null"을, $_GET["var2"]는 문자열 "123"을 담고 있어요.


/index.php?var1=null&var2=123

변경 이력 (Changelog)

버전 설명
7.2.34, 7.3.23, 7.4.11 보안상의 이유로 들어오는 쿠키의 이름을 더 이상 url-decode 하지 않아요.

더 알아보기