Znaki dozwolone w kluczach tablicy php?


86

Mam kilka kluczy tablic php, które są wypełnione wieloma dziwnymi znakami.

Czy to jest dozwolone? Czy są jakieś ograniczenia co do tego, czego nie mogę użyć?


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

Odpowiedzi:


90

Zgodnie z instrukcją :

Klucz może być liczbą całkowitą lub łańcuchem. Wartość może być dowolnego typu.

Dodatkowo wystąpią następujące rzucane klucze:

  • Ciągi zawierające prawidłowe liczby całkowite będą rzutowane na typ całkowity. Np. Klucz „8” będzie faktycznie przechowywany pod 8. Z drugiej strony „08” nie będzie rzutowane, ponieważ nie jest prawidłową liczbą dziesiętną.
  • Liczba zmiennoprzecinkowa jest również rzutowana na liczby całkowite, co oznacza, że ​​część ułamkowa zostanie obcięta. Np. Klucz 8.7 będzie faktycznie przechowywany pod 8.
  • Wartości logiczne są również rzutowane na liczby całkowite, tj. Klucz prawda będzie faktycznie przechowywany pod 1, a klucz fałsz pod 0.
  • Null zostanie rzutowany na pusty łańcuch, tj. Klucz null będzie faktycznie przechowywany pod "".
  • Tablice i obiekty nie mogą być używane jako klucze. Spowoduje to wyświetlenie ostrzeżenia: Niedozwolony typ przesunięcia.

Podręcznik ponownie :

Łańcuch to seria znaków, gdzie znak jest tym samym, co bajt. Oznacza to, że PHP obsługuje tylko zestaw 256 znaków, a zatem nie oferuje natywnej obsługi Unicode. Zobacz szczegóły typu string.

Krótko mówiąc, kluczem może być dowolny ciąg. Ciąg może zawierać dowolne dane binarne (do 2 GB). Dlatego klucz może być dowolnymi danymi binarnymi (ponieważ ciąg może być dowolnymi danymi binarnymi).

Niektóre przypadkowe (prawidłowe) nadużycia kluczy tablicowych:

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

1
Aby wyjaśnić, nie oznacza to, że nie można używać łańcuchów Unicode jako kluczy tablicowych. W rzeczywistości każdy ciąg binarny działa dobrze. Uważam, że samozwańczy brak obsługi Unicode w PHP jest irytujący, ponieważ nie jest to prawdą. :)
deceze

1
@deceze Unicode należy do kategorii „dowolne dane binarne” :) (choć myślę, że po sformułowaniu podręcznika przypuszczam, że wyjaśnienie jest konieczne). A powiedzenie „nie oferuje natywnej obsługi Unicode” jest wystarczające. Rdzeń PHP nie zawiera wersji strlen, substr, itp. W standardzie Unicode. Chociaż „nie oferuje natywnego przetwarzania ciągów znaków Unicode”, może być bardziej odpowiednie.
Corbin

3
Jasne, jądro nie zawiera żadnych udogodnień do manipulowania ciągami znaków Unicode. Ale tak długo, jak nie chcesz manipulować napisami, PHP obsługuje je dobrze. I mówiąc realistycznie, rozszerzenie MB jest domyślnie dostępne w praktycznie każdej instalacji PHP, więc rozróżnienie między „obsługą rdzenia” a nie jest w większości akademickie. :)
deceze

1
@deceze może ich notatka powinna brzmieć „nie natywnie (patrz rozszerzenie mb)” lub coś w tym stylu. Ale masz rację. Każda instalacja PHP od 2005 roku zasadniczo obsługuje Unicode, chociaż uważam, że obsługa Unicode w PHP (z rozszerzeniami) jest nadal trochę nieprzyjemna.
Corbin

@Corbin, dlaczego nazywasz to nadużyciem zamiast używać ?
Pacerier,

12

Klucz musi być łańcuchem lub liczbą całkowitą. Odbywa się kilka rzutów, ale myślę, że podręcznik dobrze wyjaśnia:

Klucz może być liczbą całkowitą lub łańcuchem. Wartość może być dowolnego typu.

Dodatkowo wystąpią następujące rzucane klucze:

  • Ciągi zawierające prawidłowe liczby całkowite będą rzutowane na typ całkowity. Np. Klucz „8” będzie faktycznie przechowywany pod 8. Z drugiej strony „08” nie będzie rzutowane, ponieważ nie jest prawidłową liczbą dziesiętną.
  • Liczba zmiennoprzecinkowa jest również rzutowana na liczby całkowite, co oznacza, że ​​część ułamkowa zostanie obcięta. Np. Klucz 8.7 będzie faktycznie przechowywany pod 8.
  • Wartości logiczne są również rzutowane na liczby całkowite, tj. Klucz prawda będzie faktycznie przechowywany pod 1, a klucz fałsz pod 0.
  • Null zostanie rzutowany na pusty łańcuch, tj. Klucz null będzie faktycznie przechowywany pod "".
  • Tablice i obiekty nie mogą być używane jako klucze. Spowoduje to wyświetlenie ostrzeżenia: Niedozwolony typ przesunięcia.

Typy zasobów mogą być teraz rzutowane na liczby całkowite (nie jestem pewien, czy jest to nowa funkcja), więc możesz użyć np. Uchwytu pliku lub uchwytu curl jako klucza pośrednio, rzutując go na liczbę całkowitą i używając go jako klucza.
thomasrutter

10

Znalazłem tę odpowiedź, szukając więcej informacji na temat problemu, który miałem. Używałem ciągów znaków ze znakami UTF-8, które nie działałyby jako klucze do tablicy, którą miałem.

Coś jak

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

Dla mnie (niezbyt dużym ani sprytnym) rozwiązaniem było zrobienie tego ...

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

2
Lubię md5 () do generowania kluczy tablicowych. Nawet jeśli w tym momencie nie jest to całkowicie konieczne, nadal wydaje się bezpieczniejsze.
billynoah

1
md5 () jest idealna do generowania klucza zwykłego tekstu z dowolnego ciągu. Bezpieczeństwo nie jest problemem. Dobrze też, że jest szybki. Jedynym problemem jest to, czy zdecydują się je wycofać, a następnie wyeliminować, ponieważ teraz nie jest to dobre dla tego, co zostało pierwotnie zaprojektowane. Zobaczymy.
Patanjali,

2
Czy korzystałeś ze starszej wersji PHP? Twój pierwszy przykład działa dobrze w PHP 7.1.
Elliot B.

6

Klucze tablic PHP mogą być liczbami całkowitymi lub łańcuchami. Łańcuchy PHP to tablice bajtów, czyli sekwencje bajtów. Nie ma innych typów łańcuchów, a PHP w inny sposób nie nakłada żadnych specjalnych ograniczeń na ciągi kluczy tablicowych. Innymi słowy: tak długo, jak jest to ciąg, wszystko jest dozwolone.


Myślę, że niejawne rzutowanie z ciągu na klucz będący liczbą całkowitą jest ważnym rozróżnieniem, ponieważ niektóre funkcje działają inaczej, jeśli klucz jest liczbą całkowitą, czy nie. np. możesz użyć dowolnych liczb w łańcuchach tylko po to, aby stwierdzić, że funkcja tablicowa później reindeksuje je z 0..n-1.
Matthew

1
Zgoda, ale myślę, że jest to granica zakresu tego pytania. :)
deceze

5

Wszystko, co możesz włożyć do łańcucha PHP, może zostać użyte jako klucz tablicy. Nie ma ograniczeń co do liczby znaków.

$a = array();

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

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

1

Jeśli złożone klucze powodują błąd „nieokreślonego indeksu”, możesz po prostu mieć problem z „przycinaniem”.

Szalałem, ponieważ złożony klucz wypluł błąd „undefined index” i pomyślałem, że może to naruszenie składni. Klucz tablicy powodujący błąd został zbudowany na podstawie pola z zapytania bazy danych MySQL, które konwertowałem na klucz i używałem w nowej tablicy. Klucz wyglądał następująco: pl_1DNKoiJKwotCqAycickBVhTya oto jak został skonstruowany kod.

//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];

kiedy w rzeczywistości, $keyvali $dbquery['fieldname']wydawało się być idealnym dopasowaniem (weryfikowane wizualnie przez echo obu w przeglądarce). Tajemnica została rozwiązana poprzez proste użycie trimw drugim stwierdzeniu w następujący sposób: $keyval = trim($array_two['fieldname']);Po „przycięciu” php nie narzekał.

Mając nadzieję, że to uratuje innych przed frustrującymi momentami ...


0

Osobiście nie miałem żadnych problemów z nietypowymi znakami w kluczach tablicowych. To, co jest, a co nie jest legalne, nie jest dobrze udokumentowane, poza stwierdzeniem, że klucz musi być skalarem. Najlepiej po prostu spróbować i zobaczyć.


Trochę niespójne, tak, ale jest dobrze udokumentowane.
Corbin

0

Oprócz wszystkich odpowiedzi, które są prawdziwe: możesz użyć PSR , że są one pewnego rodzaju regułami między najlepszymi programistami, aby mieć ładny i standardowy styl kodowania.



-1

Zakoduj stronę php w ANSI "é", którego będzie można używać (Cinéma nie pojawi się jako Cinéma). W Notepad ++ po prostu użyj menu Encode => Convert ANSI i zapisz


2
(Wydaje się, że ten post nie zapewnia dobrej odpowiedzi na pytanie. Zmień odpowiedź lub po prostu opublikuj ją jako komentarz do pytania).
sɐunıɔ ןɐ qɐp

Czy możesz to dalej wyjaśnić? A co, jeśli go énie ma, a jeśli OP nie używa w końcu Notepad ++?
Nico Haase
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.