현재 위치: > 최신 기사 목록> 객체 또는 리소스를 배열 키로 사용하여 발생하는 문제

객체 또는 리소스를 배열 키로 사용하여 발생하는 문제

M66 2025-06-06

PHP에서 배열은 문자열, 정수, 객체, 리소스 등을 포함한 다양한 유형의 요소를 저장할 수있는 매우 강력한 데이터 구조입니다. 대부분의 경우 배열 키는 문자열 또는 정수 일 수 있으며 일반적으로 사용하는 주요 유형입니다. 그러나 객체 나 리소스를 배열의 열쇠로 사용하면 기대치를 충족시키지 못하는 어렵 기 오류 나 동작이 발생할 수 있습니다. 이 기사는 PHP의 배열 키로 객체 또는 리소스를 사용하여 발생할 수있는 문제를 탐색하고 솔루션을 제공합니다.

1. 배열 키로 개체

객체를 배열 키로 직접 사용할 수없는 이유는 무엇입니까?

PHP에서 배열의 키는 해싱 (HASH)에 의해 관리됩니다. 정수 또는 문자열을 키로 사용하면 PHP는 내부 해싱 메커니즘을 통해 키를 직접 관리 할 수 ​​있습니다. 그러나 객체가 배열 키 인 경우, PHP는 객체가 __toString () 메소드 또는 특수 비교 방법을 구현하지 않는 한 해시 계산에 객체의 값을 직접 사용할 수 없습니다. 이러한 방법이 없으면 PHP는 객체의 해시 값을 배열 키로 사용 하며이 해시 값이 항상 객체의 독창성을 정확하게 나타내는 것은 아닙니다.

 <?php
class Person {
    public $name;
    
    public function __construct($name) {
        $this->name = $name;
    }
}

$obj1 = new Person("John");
$obj2 = new Person("Doe");

$array = [];
$array[$obj1] = "First object";
$array[$obj2] = "Second object";

// 가능한 출력:Array ( [Person Object] => Second object )
var_dump($array);
?>

위의 예에서, 우리는 $ obj1$ obj2 에 대해 다른 객체를 생성하지만 PHP는 여전히 해시 값을 배열의 키로 사용할 수 있으므로 예기치 않은 동작이 발생할 수 있습니다.

해결책

이 문제를 해결하려면 객체의 고유 식별자 ( SPL_OBJECT_HASH () )를 사용하거나 객체의 속성을 문자열 유형 (예 : __toString () 메소드를 통한)으로 변환하여 각 객체의 키가 어레이에서 고유한지 확인하는 것이 좋습니다.

 <?php
class Person {
    public $name;
    
    public function __construct($name) {
        $this->name = $name;
    }
    
    public function __toString() {
        return $this->name;
    }
}

$obj1 = new Person("John");
$obj2 = new Person("Doe");

$array = [];
$array[(string)$obj1] = "First object";
$array[(string)$obj2] = "Second object";

// 산출:Array ( [John] => First object [Doe] => Second object )
var_dump($array);
?>

__toString () 메소드를 구현함으로써 각 객체에 고유하고 인식 가능한 문자열 표현이 있는지 확인할 수 있으므로 위의 문제를 피할 수 있습니다.

2. 배열 키로 자원

자원을 배열 키로 사용할 수없는 이유는 무엇입니까?

PHP에서 자원은 일반적으로 외부 리소스 (예 : 데이터베이스 연결, 파일 핸들 등)에 대한 참조를 나타냅니다. 리소스 유형은 PHP의 특수 데이터 유형으로 직접 해시 표현이 없으며 배열 키로 리소스를 사용하면 문제가 발생할 수 있습니다.

리소스를 배열 키로 사용하는 경우 PHP에는 자원 컨텐츠가 직접 키로 자원이 없습니다. 대신 PHP는 해싱에 리소스 유형 및 식별자 조합을 사용합니다. 그러나 자원의 식별자는 다른 PHP 인스턴스마다 다를 수 있으므로 두 자원 유형의 데이터를 효과적으로 비교할 수 없습니다.

 <?php
$resource1 = fopen("file1.txt", "r");
$resource2 = fopen("file2.txt", "r");

$array = [];
$array[$resource1] = "First resource";
$array[$resource2] = "Second resource";

// 이것은 문제를 일으킬 수 있습니다,리소스 식별자는 환경에 따라 다를 수 있기 때문입니다
var_dump($array);
?>

해결책

특히 리소스 식별자 변경이 명확하지 않은 경우 리소스를 배열의 키로 사용하지 않는 것이 좋습니다. 리소스 데이터를 사용해야하는 경우 객체에서 리소스를 캡슐화 한 다음 객체를 배열 키로 사용하거나 리소스 (예 : 리소스 ID 또는 기타 문자열 식별자)를 배열 키로 식별 할 수있는 다른 데이터 유형을 사용하는 것을 고려하십시오.

 <?php
$resource1 = fopen("file1.txt", "r");
$resource2 = fopen("file2.txt", "r");

$array = [];
$array[(string)$resource1] = "First resource";
$array[(string)$resource2] = "Second resource";

var_dump($array);
?>

이러한 방식으로 리소스의 문자열 식별자는 배열 키의 고유성을 보장합니다.

3. 요약

PHP는 객체와 리소스를 배열의 키로 사용할 수있게하지만이 관행은 해싱 메커니즘의 한계로 인해 예상치 못한 문제를 일으킬 수 있습니다. 코드의 유지 관리 및 안정성을 보장하려면 다음과 같이 권장됩니다.

  • 문자열 또는 정수를 어레이의 키로 사용하십시오.

  • 객체를 사용해야하는 경우 __toString () 메소드를 구현하거나 spl_object_hash ()를 사용하여 객체의 고유 한 표현을 생성하는 것을 고려할 수 있습니다.

  • 리소스를 배열 키로 사용하지 마십시오. 사용하려면 리소스를 개체에 캡슐화하거나 리소스의 식별자를 배열 키로 사용하는 것이 좋습니다.

이 기사가 PHP의 배열 키로 객체 또는 리소스를 사용하여 발생할 수있는 문제와 솔루션을 이해하는 데 도움이되기를 바랍니다. 더 많은 질문이 있거나 추가 토론이 필요한 경우 메시지를 남겨두고 의사 소통하십시오!