PHP에서 배열 키로 사용되는 숫자 문자열


104

"123"정수로 변환하지 않고 PHP 배열의 키 와 같은 숫자 문자열을 사용할 수 있습니까?

$blah = array('123' => 1);
var_dump($blah);

인쇄물

array(1) {
  [123]=>
  int(1)
}

내가 원하는

array(1) {
  ["123"]=>
  int(1)
}

7
PHP는 형식이 느슨하기 때문에 "123"== 123거의 모든 용도에 사용됩니다. 특별히 문자열로 원하는 이유는 무엇입니까?
ircmaxell

17
내 마음에 떠오르는 이유는 array_merge "입력 배열에 동일한 문자열 키가있는 경우 해당 키의 이후 값이 이전 값을 덮어 쓰게됩니다. 그러나 배열에 숫자 키가 포함되어 있으면 이후 값은 그렇지 않습니다. 원래 값을 덮어 쓰지만 추가됩니다. "
ficuscr 2014

8
배열 키로서의 숫자 문자열이 문제가되는 또 다른 예 :asort
swenedo


4
또 다른 사용 사례 : 단위 테스트 JSON 데이터 전환. 이러한 배열을 JSON으로 변환하고 그 반대로 변환하면 원본과 결과가 정확히 동일하다고 주장 할 수 없습니다.
David

답변:


90

아니; 아니요 :

에서 수동 :

키는 정수 또는 문자열 일 수 있습니다. 키가 정수의 표준 표현이면 그대로 해석됩니다 (예 : "8"은 8로 해석되고 "08"은 "08"로 해석 됨).

추가

아래의 설명으로 인해 동작이 비슷 하지만 JavaScript 객체 키 동일 하지 않다는 점을 지적하는 것이 재미있을 것이라고 생각했습니다 .

foo = { '10' : 'bar' };

foo['10']; // "bar"
foo[10]; // "bar"
foo[012]; // "bar"
foo['012']; // undefined!

107
PHP, 서버 측 IE.
Marek Maurizio

5
실제로 방법이있는 것 같습니다! 이 답변에 동의하지 않습니까? stackoverflow.com/a/35180513/247696
Flimm

1
?! 어떻게 .. foo는 [012] 반환 "바"
Himanshu

2
@Himanshu : php는 0으로 시작하는 숫자를 8 진수로 해석하기 때문입니다. 그래서 012는 8 진수 10입니다.
Yeasir Arafat Majumder

49

예, stdClass객체를 배열 캐스팅하여 가능 합니다.

$data =  new stdClass;
$data->{"12"} = 37;
$data = (array) $data;
var_dump( $data );

그 결과 (PHP 버전 7.1까지) :

array(1) {
  ["12"]=>
  int(37)
}

(업데이트 : 내 원래 답변은 사용하여 더 복잡한 방식을 보 json_decode()였으며 json_encode()필요하지 않았습니다.)

주석 참고 : 안타깝게도 값을 직접 참조 할 수는 없습니다. $data['12']그러면 알림이 표시됩니다.

업데이트 :
PHP 7.2부터는 숫자 문자열을 키로 사용하여 값을 참조 할 수도 있습니다.

var_dump( $data['12'] ); // int 32

2
그러나 문자열 키를 사용하여 값에 직접 액세스하는 것은 작동하지 않습니다. 다음 행을 예제에 추가하십시오 echo $data['12'];.. "Notice : Undefined offset : 12 in-on line 5"라는 오류가 표시됩니다.
LS

1
U가 laravel의 DD ($ 데이터)를 사용하는 경우가 충돌합니다 : P
카밀 Kiełczewski

2
PHP 7.2.0RC2에서 동작은 이전과 동일합니다.
dev0

1
분명히 array_key_exists이전 버전에서도 찾을 수 없습니다.
당황하지 마십시오.

1
PHP 7.4에서 작동하지 않습니다
jasmines

12

PHP 데이터 구조에서 숫자 키를 사용해야하는 경우 개체가 작동합니다. 객체는 순서를 유지하므로 반복 할 수 있습니다.

$obj = new stdClass();
$key = '3';
$obj->$key = 'abc';

이것은 아주 좋은 제안입니다. 나는 프레임 워크 코드를 작성 중이고 누군가가 "우연한"인덱싱 : array ( 'this', 'that') 또는 "associative"인덱싱을 가질 수있는 배열을 전달하는 데 직면했습니다. array (123 => array ( 'this', 'that ')). 지금, 당신 덕분에, 난 그냥 typehint 수) +1
그냥 일반 고

그러나 "123"과 같은 숫자 문자열을 정수로 변환하지 않고 PHP 배열의 키로 사용할 수 있습니까?
Flimm

@Flimm 불가능한 것이 아니기 때문에 솔루션을 제공합니다.
steampowered

@Flimm 그 대답은 PHP 매뉴얼 과 모순되는 것 같습니다 : 유효한 정수를 포함하는 문자열은 정수 유형으로 캐스팅됩니다. 예를 들어 키 "8"은 실제로 8 아래에 저장됩니다. 반면에 "08"은 유효한 십진 정수가 아니기 때문에 캐스트되지 않습니다. , 나는 그의 대답을 테스트하지 않았지만.
steampowered

그 문장은 "Specifying with array(). 그래서 나는 그 문맥에서 유효한 정수를 지정하는 문자열이 정수 유형으로 캐스트 될 것이라고 가정하고 있습니다.하지만 배열을 만드는 다른 방법이 있음이 밝혀졌습니다. 내가 테스트 한 David의 답변과 같은
Flimm

10

내 해결 방법은 다음과 같습니다.

$id = 55;
$array = array(
  " $id" => $value
);

공백 문자 (앞에 추가)는 int 변환을 유지하기 때문에 좋은 솔루션입니다.

foreach( $array as $key => $value ) {
  echo $key;
}

55는 int로 표시됩니다.


4
또는 "0$id" => $value. 에 붙이는 0도 작동합니다.
nawfal 2015

그래서 "123"과 같은 숫자 문자열을 정수로 변환하지 않고 PHP 배열의 키로 사용할 수 없다는 말입니까?
Flimm

5

키를 문자열로 형변환 할 수 있지만 결국 PHP의 느슨한 입력으로 인해 정수로 변환됩니다. 직접 확인 :

$x=array((string)123=>'abc');
var_dump($x);
$x[123]='def';
var_dump($x);

PHP 매뉴얼에서 :

키는 정수 또는 문자열 일 수 있습니다. 키가 정수의 표준 표현이면 그대로 해석됩니다 (예 : "8"은 8로 해석되고 "08"은 "08"로 해석 됨). 키의 부동 소수점은 정수로 잘립니다. 인덱스 및 연관 배열 유형은 PHP에서 동일한 유형이며 정수 및 문자열 인덱스를 모두 포함 할 수 있습니다.


1
변환은 느슨한 타이핑 때문이 아닙니다. php는 문자열 숫자 인지 확인한 다음 변환합니다.

1
그래서 불가능하다는 말씀인가요? 이 답변 은 정수처럼 보이는 문자열을 배열의 키로 사용하는 방법이 있음을 보여줍니다.
Flimm

IMHO 문제는 PHP 인터프리터입니다. 문자열과 정수를 배열 키로 혼합하는 언어를 갖는 것은 상상조차 할 수 없습니다. 최선의 해결책은? Undolog stackoverflow.com/a/15413637/1977778 에서 제안한대로 가장 좋은 해결책은 후행 공백을 사용하는 것입니다 ... 슬프게도.
sentenza

@sentenza : 이는 PHP 배열의 키로서 문자열과 정수의 혼합을 허용 특히 이후 상상할 수있다 :[42 => 'answer', 'snafu' => 'fubar']
LS

@LS 예. PHP가 그렇게 할 수 있다는 것을 알고 있지만 가상의 제네릭 유형 시스템 내에서 키를 고려하면 문자열과 숫자를 동시에 포함 하는 혼합 유형 과 일치하지 않습니다 . 이른바 입력 결합 배열의 키에 적용된 단순히 오류가 쉽다.
sentenza

1

문자열과 정수 키를 모두 가진 배열을 병합하려고 시도하는 동안이 문제가 발생했습니다. 정수는 입력 필드의 이름이기 때문에 문자열로도 처리되는 것이 중요했습니다 (예 : 신발 크기 등).

$data = array_merge($data, $extra);PHP를 사용할 때 키를 '재주문'합니다. 주문을하고 시도에서, 정수 키 (I 함께 노력 6- '6'- "6"심지어 (string)"6"키로)에 0에서 이름이있어 n당신이 그것에 대해 생각한다면, 대부분의 경우이 원하는 동작 될 것이다 ....

$data = $data + $extra;대신 사용하여이 문제를 해결할 수 있습니다 . 꽤 솔직한데 처음 엔 생각도 못했어요 ^^.


똑같은 문제가 나를이 페이지로 이끌었지만 이것은 OP의 질문에 대한 대답이 아니라고 말해야합니다.
Flimm

@Flimm 사실. 하지만 답을 찾기 위해이 페이지로 이동했습니다. 내 솔루션이 다른 Google 직원에게 도움이 될 수 있다고 생각했습니다. :)
Brainfeeder

1

유효한 정수를 포함하는 문자열은 정수 유형으로 캐스트됩니다. 예를 들어 키 "8"은 실제로 8 아래에 저장됩니다. 반면에 "08"은 유효한 십진 정수가 아니기 때문에 캐스트되지 않습니다.

잘못된

연상 배열 캐스팅을 순차적으로 처리하는 캐스팅 기능이 있습니다.

$array_assoc = cast($arr,'array_assoc');

$array_sequential = cast($arr,'array_sequential');

$obj = cast($arr,'object');

$json = cast($arr,'json');



function cast($var, $type){

    $orig_type = gettype($var);

    if($orig_type == 'string'){

        if($type == 'object'){
            $temp = json_decode($var);
        } else if($type == 'array'){
            $temp = json_decode($var, true);
        }
        if(isset($temp) && json_last_error() == JSON_ERROR_NONE){
            return $temp;
        }
    }
    if(@settype($var, $type)){
        return $var;
    }
    switch( $orig_type ) {

        case 'array' :

            if($type == 'array_assoc'){

                $obj = new stdClass;
                foreach($var as $key => $value){
                    $obj->{$key} = $value;
                }
                return (array) $obj;

            } else if($type == 'array_sequential'){

                return array_values($var);

            } else if($type == 'json'){

                return json_encode($var);
            }
        break;
    }
    return null; // or trigger_error
}

PHP 7.4에서 작동하지 않습니다
jasmines

1

해결 방법으로 JSON_FORCE_OBJECT 옵션을 사용하여 PHP 배열을 json 객체로 인코딩 할 수 있습니다.

즉,이 예 :

     $a = array('foo','bar','baz');
     echo "RESULT: ", json_encode($a, JSON_FORCE_OBJECT);

결과 :

     RESULT: {"0" : "foo", "1": "bar", "2" : "baz"}

0

나는 키로 '0'과 ''를 모두 사용하는 배열 에서이 문제가 발생했습니다. == 또는 ===로 배열 키를 확인할 수 없음을 의미합니다.

$array=array(''=>'empty', '0'=>'zero', '1'=>'one');
echo "Test 1\n";
foreach ($array as $key=>$value) {
    if ($key == '') { // Error - wrongly finds '0' as well
        echo "$value\n";
    }
}
echo "Test 2\n";
foreach ($array as $key=>$value) {
    if ($key === '0') { // Error - doesn't find '0'
        echo "$value\n";
    }
}

해결 방법은 사용하기 전에 배열 키를 문자열로 다시 캐스팅하는 것입니다.

echo "Test 3\n";
foreach ($array as $key=>$value) {
    if ((string)$key == '') { // Cast back to string - fixes problem
        echo "$value\n";
    }
}
echo "Test 4\n";
foreach ($array as $key=>$value) {
    if ((string)$key === '0') { // Cast back to string - fixes problem
        echo "$value\n";
    }
}

1
이것은 실제로 질문에 대한 답이 아닙니다.
Flimm

0

@david 솔루션과 관련하여 연관 배열의 문자열 값에 액세스하려고하면 숫자가 작동하지 않습니다. 내 생각에 그들은 (배열에 액세스 할 때) 장면 뒤에서 정수로 캐스팅되고 값이 발견되지 않는다는 것입니다. 값에 정수로 액세스하는 것도 작동하지 않습니다. 그러나 array_shift ()를 사용하여 값을 가져 오거나 배열을 반복 할 수 있습니다.

$data = new stdClass;
$data->{"0"} = "Zero";
$data->{"1"} = "One";
$data->{"A"} = "A";
$data->{"B"} = "B";

$data = (array)$data;

var_dump($data);
/*
Note the key "0" is correctly saved as a string:
array(3) {
  ["0"]=>
  string(4) "Zero"
  ["A"]=>
  string(1) "A"
  ["B"]=>
  string(1) "B"
}
*/

//Now let's access the associative array via the values 
//given from var_dump() above:
var_dump($data["0"]); // NULL -> Expected string(1) "0"
var_dump($data[0]); // NULL (as expected)
var_dump($data["1"]); // NULL -> Expected string(1) "1"
var_dump($data[1]); // NULL (as expected)
var_dump($data["A"]); // string(1) "A" (as expected)
var_dump($data["B"]); // string(1) "B" (as expected)

어떤 PHP 버전? 나는 당신의 예를 정확히 시도했고 키 "0"0php가 7.2.10됩니다.
J.BizMai

-1

16 진수 sha1이되도록 정렬 키가 필요한 배열을 정렬하는 동안이 문제가 발생했습니다. 결과 sha1 값에 문자가 없으면 PHP는 키를 정수로 바꿉니다. 하지만 문자열의 상대적인 순서에 따라 배열을 정렬해야했습니다. 그래서 정렬 순서를 변경하지 않고 키를 문자열로 강제하는 방법을 찾아야했습니다.

ASCII 차트 ( https://en.wikipedia.org/wiki/ASCII )를 보면 느낌표는 공백과 거의 동일하며 모든 숫자와 문자보다 확실히 낮습니다.

그래서 키 문자열 끝에 느낌표를 추가했습니다.

for(...) {

    $database[$sha.'!'] = array($sha,$name,$age);
}

ksort($database);
$row = reset($database);
$topsha = $row[0];

"123"과 같은 숫자 문자열을 정수로 변환하지 않고는 PHP 배열의 키로 사용할 수 없다는 뜻입니까?
Flimm

아니오-ksort ()를 사용하여 배열을 정렬 할 때 모든 숫자 인 키를 정수로만 처리합니다. 정수로 변환되지 않습니다. 정렬 중 하나로 비교됩니다.
drchuck
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.