PHP 배열 키에 허용되는 문자?


86

이상한 문자가 많은 PHP 배열 키가 있습니다.

허용됩니까? 사용할 수없는 것에 제약이 있습니까?


제약 :$a = (object) ['@km³' => 123]; error_log($a->@km³);
Bitterblue

답변:


90

설명서 에 따르면 :

키는 정수 또는 문자열 일 수 있습니다. 값은 모든 유형이 될 수 있습니다.

또한 다음과 같은 키 캐스트가 발생합니다.

  • 유효한 정수를 포함하는 문자열은 정수 유형으로 캐스트됩니다. 예를 들어 키 "8"은 실제로 8 아래에 저장됩니다. 반면에 "08"은 유효한 십진 정수가 아니기 때문에 캐스트되지 않습니다.
  • 부동 소수점도 정수로 캐스트되므로 분수 부분이 잘립니다. 예를 들어 키 8.7은 실제로 8 아래에 저장됩니다.
  • 부울도 정수로 캐스트됩니다. 즉, true 키는 실제로 1 아래에 저장되고 false 키는 0 아래에 저장됩니다.
  • Null은 빈 문자열로 캐스트됩니다. 즉, null 키는 실제로 ""아래에 저장됩니다.
  • 배열과 객체는 키로 사용할 수 없습니다. 이렇게하면 경고가 발생합니다. 잘못된 오프셋 유형입니다.

다시 매뉴얼 :

문자열은 일련의 문자이며 문자는 바이트와 동일합니다. 즉, PHP는 256 자 세트 만 지원하므로 기본 유니 코드 지원을 제공하지 않습니다. 문자열 유형에 대한 세부 사항을 참조하십시오.

즉, 모든 문자열이 키가 될 수 있습니다. 그리고 문자열에는 모든 이진 데이터 (최대 2GB)가 포함될 수 있습니다. 따라서 키는 모든 이진 데이터가 될 수 있습니다 (문자열이 이진 데이터 일 수 있기 때문에).

배열 키의 임의의 (유효한) 남용 :

$w = array(chr(0) => 'null byte?', chr(rand(0, 255)) => 'random byte?');
var_dump($w);

1
명확히하기 위해 유니 코드 문자열을 배열 키로 사용할 수 없다는 의미는 아닙니다. 사실 모든 이진 문자열은 잘 작동합니다. 사실이 아니기 때문에 PHP의 자체 설명 유니 코드 지원 부족이 성가시다. :)
deceze

1
@deceze 유니 코드는 "모든 이진 데이터"범주에 속합니다. :) (매뉴얼의 표현으로 추측하지만 설명이 필요하다고 생각합니다). 그리고 "기본 유니 코드 지원을 제공하지 않는다"는 말은 사실입니다. PHP 코어에는 strlen, substr 등의 유니 코드 버전이 포함되어 있지 않습니다. "유니 코드 문자열의 기본 처리를 제공하지 않음"이 더 적절할 수 있습니다.
Corbin

3
물론 코어에는 유니 코드 문자열 을 조작 하는 기능이 없습니다 . 그러나 문자열을 조작하지 않는 한 PHP는 문자열을 잘 지원합니다. 사실적으로 말하면 MB 확장은 기본적으로 거의 모든 PHP 설치에서 사용할 수 있으므로 "핵심 지원"여부를 구분하는 것은 대부분 학문적입니다. :)
deceze

1
@deceze는 그들의 노트가 "원래 적으로 (mb 확장자 참조)가 아님"이라고 읽어야 할지도 모릅니다. 그래도 당신 말이 맞아요. 2005 년 이후의 모든 PHP 설치는 기본적으로 유니 코드를 지원하지만, PHP (확장 기능 포함)에서 유니 코드를 지원하는 것은 여전히 ​​약간 불쾌합니다.
Corbin

@Corbin, 왜 사용 대신 남용 이라고 부르 나요?
Pacerier 2013-08-07

12

키는 문자열 또는 정수 여야합니다. 발생하는 몇 가지 캐스트가 있지만 설명서가 잘 설명하고 있다고 생각합니다.

키는 정수 또는 문자열 일 수 있습니다. 값은 모든 유형이 될 수 있습니다.

또한 다음과 같은 키 캐스트가 발생합니다.

  • 유효한 정수를 포함하는 문자열은 정수 유형으로 캐스트됩니다. 예를 들어 키 "8"은 실제로 8 아래에 저장됩니다. 반면에 "08"은 유효한 십진 정수가 아니기 때문에 캐스트되지 않습니다.
  • 부동 소수점도 정수로 캐스트되므로 분수 부분이 잘립니다. 예를 들어 키 8.7은 실제로 8 아래에 저장됩니다.
  • 부울도 정수로 캐스트됩니다. 즉, true 키는 실제로 1 아래에 저장되고 false 키는 0 아래에 저장됩니다.
  • Null은 빈 문자열로 캐스트됩니다. 즉, null 키는 실제로 ""아래에 저장됩니다.
  • 배열과 객체는 키로 사용할 수 없습니다. 이렇게하면 경고가 발생합니다. 잘못된 오프셋 유형입니다.

리소스 유형은 이제 정수로 캐스트 될 수 있습니다 (새로운 기능인지 확실하지 않음). 예를 들어 파일 핸들 또는 컬 핸들을 정수로 캐스트하고 키로 사용하여 간접적으로 키로 사용할 수 있습니다.
thomasrutter

10

내가 가진 문제에 대한 자세한 정보를 찾고있는이 답변을 찾았습니다. 내가 가진 배열의 키로 작동하지 않는 UTF-8 문자가 포함 된 문자열을 사용하고있었습니다.

같은 것

$str = "R&D - Solution";
$arr = array( "R&D - Solution" => "Research" );
echo $arr[$str];  // did not work

저에게 (크거나 영리하지 않은) 해결책은 이것을하는 것이 었습니다 ..

$str = md5("R&D - Solution");
$arr = array( md5("R&D - Solution") => "Research" );
echo $arr[$str];  // works!

2
배열 키를 생성하는 데 md5 ()를 좋아합니다. 이 시점에서 완전히 필요하지 않더라도 여전히 더 안전하다고 느낍니다.
billynoah

1
md5 ()는 모든 문자열에서 일반 텍스트 키를 생성하는 데 적합합니다. 보안은 문제가 아닙니다. 빠른 것도 좋다. 유일한 문제는 그들이 원래 디자인 된 것에 적합하지 않기 때문에 그것을 폐기하기로 결정한 다음 제거할지 여부입니다. 우리는 보게 될 것이다.
Patanjali

2
이전 버전의 PHP를 사용하고 계셨습니까? 첫 번째 예제는 PHP 7.1에서 잘 작동합니다.
Elliot B.

6

PHP 배열 키는 정수 또는 문자열 일 수 있습니다. PHP 문자열은 바이트 배열로, 바이트 시퀀스를 의미합니다. 다른 유형의 문자열은 없으며 PHP는 배열 키 문자열에 특별한 제한을 부과하지 않습니다. 즉, 문자열이면 무엇이든 진행됩니다.


문자열에서 정수 키로의 암시 적 캐스트는 키가 정수인지 아닌지에 따라 특정 기능이 다르게 작동하기 때문에 중요한 구별이라고 생각합니다. 예를 들어, 임의의 문자열 번호를 사용하여 배열 함수가 나중에 0..n-1에서 다시 색인화 함을 찾을 수 있습니다.
Matthew

1
동의하지만이 질문의 범위의 경계에 있다고 생각합니다. :)
deceze

5

PHP 문자열에 넣을 수있는 것은 무엇이든 배열 키로 사용할 수 있습니다. 허용되는 문자에는 제한이 없습니다.

$a = array();

$x = 'long string of random garage';
echo $a[$x]; // this is ok

$x = array();
echo $a[$x]; // not ok

1

복잡한 키로 인해 "정의되지 않은 인덱스"오류가 발생하는 경우 단순히 "트림"문제가있을 수 있습니다.

복잡한 키가 "정의되지 않은 인덱스"오류를 뱉어 내고 구문 위반 일 수 있다고 생각했기 때문에 나는 미쳐 버렸다. 오류를 일으키는 배열 키는 내가 키로 변환하고 새 배열에서 사용하는 MySQL 데이터베이스 쿼리의 필드에서 빌드되었습니다. 키는 다음과 같았습니다. pl_1DNKoiJKwotCqAycickBVhTy여기에 코드가 생성 된 방법이 있습니다.

//new array created from database query
$new_array[$dbquery['fieldname']] = {some value};

//key value found in field of second array
$keyval = $array_two['fieldname'];

//this produced the "undefined index" error
echo $new_array[$keyval];

사실, 때 $keyval$dbquery['fieldname']완벽하게 일치하는 것으로 나타났다 (시각 브라우저에 모두 반향에 의해 확인). 수수께끼는 trim두 번째 문장에서 다음과 같이 간단히 해결되었습니다 : $keyval = trim($array_two['fieldname']);일단 '트리밍'되면, PHP는 더 이상 불평하지 않습니다.

이것이 실망스러운 순간에서 다른 사람들을 구하기를 바랍니다.


0

개인적으로 배열 키의 특이한 문자에 문제가 없었습니다. 무엇이 합법적이며 합법적이지 않은지는 잘 문서화되어 있지 않습니다. 키가 스칼라 여야한다는 것 외에는 말입니다. 가장 좋은 방법은 시도하고 보는 것입니다.


예, 약간 일관성이 없지만 잘 문서화되어 있습니다.
Corbin

0

모든 답변이 사실 인 것 외에도 : PSR 을 사용 하여 멋진 표준 코딩 스타일을 갖기 위해 최고의 프로그래머간에 일종의 규칙임을 알 수 있습니다 .


0

PHP 배열에서는 키 : 2.3 또는 십진수를 사용할 수 없습니다.


-1

ANSI "é"로 PHP 페이지를 인코딩하면 사용할 수 있습니다 (Cinéma는 Cinéma로 표시되지 않음). 메모장 ++에서 Encode => Convert ANSI 메뉴를 사용하고 저장하십시오.


2
(이 게시물은 질문에 대한 양질의 답변 을 제공하지 않는 것 같습니다 . 답변 을 수정하거나 질문에 대한 의견으로 게시하십시오).
sɐunıɔ ןɐ qɐp

더 설명해 주시겠습니까? 경우 어떻게 é존재하지 않는, 영업 이익은 결국 ++ 메모장을 무엇을 사용하지 않는 경우?
Nico Haase
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.