program tip

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

radiobox 2020. 8. 27. 07:38
반응형

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


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

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

인쇄물

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

내가 원하는

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

아니; 아니요 :

에서 수동 :

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

추가

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

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

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

예, 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

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

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

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

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

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

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

55는 int로 표시됩니다.


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

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

PHP 매뉴얼에서 :

A key may be either an integer or a string . If a key is the standard representation of an integer , it will be interpreted as such (i.e. "8" will be interpreted as 8, while "08" will be interpreted as "08"). Floats in key are truncated to integer . The indexed and associative array types are the same type in PHP, which can both contain integer and string indices.


I had this problem trying to merge arrays which had both string and integer keys. It was important that the integers would also be handled as string since these were names for input fields (as in shoe sizes etc,..)

When I used $data = array_merge($data, $extra); PHP would 're-order' the keys. In an attempt doing the ordering, the integer keys (I tried with 6 - '6'- "6" even (string)"6" as keys) got renamed from 0 to n ... If you think about it, in most cases this would be the desired behaviour.

You can work around this by using $data = $data + $extra; instead. Pretty straight forward, but I didn't think of it at first ^^.


Strings containing valid integers will be cast to the integer type. E.g. the key "8" will actually be stored under 8. On the other hand "08" will not be cast, as it isn't a valid decimal integer.

WRONG

I have a casting function which handles sequential to associative array casting,

$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
}

As workaround, you can encode PHP array into json object, with JSON_FORCE_OBJECT option.

i.e., This example:

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

will result in:

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

I ran into this problem on an array with both '0' and '' as keys. It meant that I couldn't check my array keys with either == or ===.

$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";
    }
}

The workaround is to cast the array keys back to strings before use.

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";
    }
}

Regarding @david solution, please note that when you try to access the string values in the associative array, the numbers will not work. My guess is that they are casted to integers behind the scenes (when accessing the array) and no value is found. Accessing the values as integers won't work either. But you can use array_shift() to get the values or iterate the array.

$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)

I had this problem while trying to sort an array where I needed the sort key to be a hex sha1. When a resulting sha1 value has no letters, PHP turns the key into an integer. But I needed to sort the array on the relative order of the strings. So I needed to find a way to force the key to be a string without changing the sorting order.

Looking at the ASCII chart (https://en.wikipedia.org/wiki/ASCII) the exclamation point sorts just about the same as space and certainly lower than all numbers and letters.

So I appended an exclamation point at the end of the key string.

for(...) {

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

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

참고URL : https://stackoverflow.com/questions/4100488/a-numeric-string-as-array-key-in-php

반응형