programing

배열 키에 문자열을 사용하도록 PHP를 강제하려면 어떻게 해야 합니까?

yellowcard 2023. 9. 7. 21:38
반응형

배열 키에 문자열을 사용하도록 PHP를 강제하려면 어떻게 해야 합니까?

ID를 사용해서 이름을 지정하는 오래된 앱을 발견했어요 예를 들면...

array(1) {
  [280]=>
  string(3) "abc"
}

이제 이것들을 다시 주문해야 하고, 그리고.var_dump()키가 정수인 동안에는 그런 일이 일어나지 않을 것처럼 보일 수 있습니다.

을 .a지수에 ,든에서서에var_dump()열쇠 주변에 큰 따옴표를 보여줄 겁니다 지금은 끈으로 보여줄 겁니다

array(1) {
  ["280a"]=>
  string(3) "abc"
}

이렇게 하면 코드를 더 만질 필요 없이 쉽게 다시 주문할 수 있습니다.

이거 안 돼요.

$newArray = array();
foreach($array as $key => $value) {
   $newArray[(string) $key] = $value;
}

A var_dump()여전히 정수 배열 인덱스로 표시됩니다.

배열을 망치지 않고 키를 다시 정렬할 수 있도록 강제로 문자열로 만드는 방법이 있습니까?

안돼요!!

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

편집:

실제로 할 수 있습니다!! 순차 배열을 연관 배열에 캐스팅

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

대부분의 경우 다음 인용구가 참입니다.

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

PHP Documents의 예

 <?php
    $array = array(
        1    => "a",
        "1"  => "b",
        1.5  => "c",
        true => "d",
    );
    var_dump($array);
?>

위의 예제는 다음을 출력합니다.

array(1) {
  [1]=> string(1) "d"
}

따라서 번호가 매겨진 키로 배열을 생성하더라도 정수로 다시 캐스트됩니다.

불행하게도 저는 최근까지도 이 사실을 몰랐지만 저의 실패한 시도를 공유하려고 생각했습니다.

실패한 시도

$arr = array_​change_​key_​case($arr); // worth a try. 

배열의 모든 키가 소문자 또는 대문자인 배열을 반환합니다.번호가 매겨진 인덱스는 그대로 남아 있습니다.

다음 시도는 새로운 배열을 만드는 것이었습니다.array_combine이전 값을 입력하고 새( 문자열) 키를 입력합니다.

저는 몇가지 방법을 시도했습니다.$keys배열에는 유형 문자열의 숫자 값이 들어 있습니다.

range("A", "Z" )알파벳이 잘 어울려서 숫자 줄로 해보려고요.

$keys = range("0", (string) count($arr) ); // integers

이렇게 하면 배열이 키로 가득 찼지만 모두 int 형식이었습니다.

다음은 문자열 유형 값을 사용하여 배열을 만드는 몇 가지 성공적인 시도입니다.

$keys = explode(',', implode(",", array_keys($arr))); // values strings

$keys = array_map('strval', array_keys($arr)); // values strings

이제 그 둘을 합치기 위해서입니다.

$arr = array_combine( $keys, $arr); 

이것은 숫자열이 정수로 주조된 것을 발견한 때입니다.

$arr = array_combine( $keys, $arr); // int strings
//assert($arr === array_values($arr)) // true. 

키에 소수점 로 의 을 하는 한 입니다 은 를 에 입니다 를 를 에 은 "00","01","02"아니면"0.","1.","2.".

이렇게 할 수 있습니다.

$keys = explode(',', implode(".,", array_keys($arr)) . '.'); // added decimal point 
$arr = array_combine($keys, $arr);

물론 이와 같은 어레이 요소를 대상으로 해야 하기 때문에 이상적이지 못합니다.

$arr["280."]   

새로운 문자열을 입력하지 않고 정수만 입력해도 정확한 배열 요소를 대상으로 하는 작은 함수를 만들었습니다.

function array_value($array, $key){

    if(array_key_exists($key, $array)){
        return $array[ $key ];
    }
    if(is_numeric($key) && array_key_exists('.' . $key, $array)){
        return $array[ '.' . $key ];
    } 
    return null;
}

사용.

echo array_value($array, "208"); // "abc"

편집:

실제로 할 수 있습니다!! 순차 배열을 연관 배열에 캐스팅

그 모든 것들이 다 공짜로.

문자 null 를 할 를 할 수 ."\0"배열 키의 끝까지.따라서 PHP는 문자열을 정수로 해석할 수 없습니다. 함수:든열수예(:array_merge()작업합니다.또한 그렇지 않습니다.var_dump()정수 문자열 뒤에 추가로 표시됩니다.

예:

$numbers1 = array();
$numbers2 = array();
$numbers = array();

$pool1 = array(111, 222, 333, 444);
$pool2 = array(555, 666, 777, 888);

foreach($pool1 as $p1)
{
    $numbers1[$p1 . "\0"] = $p1;
}
foreach($pool2 as $p2)
{
    $numbers2[$p2 . "\0"] = $p2;
}

$numbers = array_merge($numbers1, $numbers2);

var_dump($numbers);

결과 출력은 다음과 같습니다.

array(8) {
    ["111"] => string(3) "111"
    ["222"] => string(3) "222"
    ["333"] => string(3) "333"
    ["444"] => string(3) "444"
    ["555"] => string(3) "555"
    ["666"] => string(3) "666"
    ["777"] => string(3) "777"
    ["888"] => string(3) "888"
}

없이.. "\0"부품 결과 배열은 다음과 같습니다.

array(8) {
    [0] => string(3) "111"
    [1] => string(3) "222"
    [2] => string(3) "333"
    [3] => string(3) "444"
    [4] => string(3) "555"
    [5] => string(3) "666"
    [6] => string(3) "777"
    [7] => string(3) "888"
}

.ksort() null자도다다l을 의미하는 도 무시합니다.$numbers[111]그리고.$numbers["111\0"]둘 다 정렬 알고리즘에서 동일한 가중치를 가질 것입니다.

것입니다. 예를 들어 은 를 입니다 의 한 입니다 $numbers["444"]는 은 해야 입니다 을 입니다 해야 은 을 $numbers["444\0"]그리고 심지어는 그렇지 않았으므로var_dump()끝에 null 문자가 있다는 것을 보여줄 것입니다. 왜 "Undefined offset"을 얻는지에 대한 단서가 없습니다.그래서 이 해킹은 A를 통해 반복하는 경우에만 사용합니다.foreach()코드를 유지하는 사람이 당신을 싫어할 겁니다

대신 $object = (object)$array;

편집:

정수인 경우 키를 변경하지 않고는 순서를 변경할 수 없다고 가정했습니다(이 예에서는 중요합니다).그러나 문자열이면 색인이 특별한 의미를 가지는 것으로 해석되어서는 안 되기 때문에 원하는 대로 순서를 변경할 수 있습니다.어쨌든, 내가 어떻게 했는지에 대한 질문 업데이트를 확인하세요 (다른 경로로 내려갔습니다).

사실 그들이 숫자 순서일 필요는 없습니다.

array(208=>'a', 0=> 'b', 99=>'c');

수동으로 할당하는 경우 완벽하게 유효합니다.정수 키가 숫자가 아닌 순서로 되어 있으면 분명하다고 생각할 수 있지만 누군가가 정수 키를 순차적으로 의미하는 것으로 잘못 해석할 수 있다는 것에는 동의합니다.그렇기는 하지만 업데이트를 하면서 코드를 변경할 수 있는 여유가 있었기 때문에 그게 더 나은 방법이라고 생각합니다.


아마도 가장 효율적인 방법은 아니지만 파이처럼 쉬운 방법일 것입니다.

$keys = array_keys($data);

$values = array_values($data);
$stringKeys = array_map('strval', $keys);

$data = array_combine($stringKeys, $values);

//sort your data

각 키 끝에 '.0'을 추가하면 다음과 같이 작동할 수 있습니다.

$options = [];
for ($i = 1; $i <= 4; $i++) {
    $options[$i.'.0'] = $i;
}

반환 예정:

array("1.0" => 1, "2.0" => 2, "3.0" => 3, "4.0" => 4)

완전히 최적은 아닐 수도 있지만 아무것도 자를 필요 없이 배열을 정렬하고 원래 키를 추출(동등치)

편집: 작동할 것입니다.

foreach($array as $key => $value) { 
    $newkey = sprintf('%s',$key);
    $newArray["'$newkey'"] = $value; 
} 

안녕하세요 우리는 아래 방법으로 배열의 인덱스를 문자열로 만들 수 있습니다.배열을 xml로 변환하면 다음과 같은 인덱스가 됩니다.[0]문제가 생길 수도 있으니 다음과 같은 문자열로 변환해 주세요.[sample_0]

$newArray = array();
foreach($array as $key => $value) {
   $newArray["sample_".$key] = $value;
}

지금까지 나온 다른 모든 해결책은 주요 PHP 버전 사이에서 깨질 수 있는 취약한 해결책을 사용하거나, 일부러 키를 손상시켜 불필요한 오류를 발생시키거나, 아무 이득 없이 코드 속도를 낮추는 해킹입니다.배열을 정렬하면서도 중요한 키 연결을 유지하는 다양한 기능은 PHP 4부터 존재해 왔습니다.

PHP가 정수 키를 사용하는 것을 막는 것은 무의미합니다. 정수 표현이 문자열과 완전히 같을 때만 그렇게 하기 때문에 배열에서 읽을 때 정수 키를 문자열로 다시 캐스팅하여 원래 데이터를 반환하는 것이 보장됩니다.정수 키를 다시 쓰는 함수를 피하는 한 데이터에 대한 PHP의 내부 표현은 전혀 무관합니다.문서에는 어떤 배열 기능을 사용할 것인지 명확히 나와 있습니다.

해킹 없이 데이터가 손상되지 않은 상태로 유지되는 방법을 보여주는 정렬 예제:

<?php

# use string keys to define as populating from a db, etc. would,
# even though PHP will convert the keys to integers
$in = array(
  '347' => 'ghi',
  '176' => 'def',
  '280' => 'abc',
);

# sort by key
ksort($in);
echo "K:\n";
$i = 1;
foreach ($in as $k => $v) {
    echo $i++, "\n";
    $k = (string) $k; # convert back to original
    var_dump($k, $v);
}

# sort by value
asort($in, SORT_STRING);
echo "\nV:\n";
$i = 1;
foreach ($in as $k => $v) {
    echo $i++, "\n";
    $k = (string) $k;
    var_dump($k, $v);
}

# unnecessary to cast as object unless keys could be sequential, gapless, and start with 0
if (function_exists('json_encode')) {
    echo "\nJSON:\n", json_encode($in);
}

생성되는 출력은 v5.2 이후로 변경되지 않았습니다(그 전에는 JSON만 누락됨).

K:
1
string(3) "176"
string(3) "def"
2
string(3) "280"
string(3) "abc"
3
string(3) "347"
string(3) "ghi"

V:
1
string(3) "280"
string(3) "abc"
2
string(3) "176"
string(3) "def"
3
string(3) "347"
string(3) "ghi"

JSON:
{"280":"abc","176":"def","347":"ghi"}

언급URL : https://stackoverflow.com/questions/3445953/how-can-i-force-php-to-use-strings-for-array-keys

반응형