Дозволені символи в ключах масиву 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-символьний набір і, отже, не пропонує вбудовану підтримку Unicode. Перегляньте детальну інформацію про тип рядка.

Отже, коротко, будь-який рядок може бути ключем. І рядок може містити будь-які двійкові дані (до 2 Гб). Отже, ключем можуть бути будь-які двійкові дані (оскільки рядок може бути будь-якими двійковими даними).

Деякі випадкові (допустимі) зловживання ключами масиву:

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

1
Щоб уточнити, це не означає, що ви не можете використовувати рядки Unicode як ключі масиву. Насправді будь-який двійковий рядок прекрасно працює. Мені здається, що відсутність підтримки Unicode, яку описав PHP, дратує, оскільки це насправді неправда. :)
обдурити

1
@deceze Unicode підпадає під категорію "будь-які двійкові дані" :) (хоча, мабуть, з формулюванням посібника, я вважаю, що необхідні роз'яснення). І твердження "не пропонує рідну підтримку Unicode" є досить вірним. Там ядро ​​PHP не включає версії Unicode strlen, substr тощо. Хоча "не пропонує власну обробку рядків Unicode", можливо, буде більш доречним.
Корбін,

3
Звичайно, ядро ​​не містить жодних засобів для маніпулювання рядками Unicode. Але поки ви не хочете маніпулювати рядками, PHP їх чудово підтримує. І реалістично кажучи, розширення MB доступне практично за кожним встановленням PHP за замовчуванням, тому різниця між "базовою підтримкою" чи ні є переважно академічною. :)
обдурити

1
@deceze, можливо, їх примітка повинна читати "не споконвічно (див. розширення mb)" або щось інше тоді. Ти правда прав. Будь-яка інсталяція PHP з 2005 року по суті підтримує Unicode, хоча я б стверджував, що підтримка Unicode в PHP (з розширеннями) все ще трохи неприємна.
Корбін,

@Corbin, чому ти називаєш це зловживання замість використання ?
Pacerier

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 () ідеально підходить для створення простого текстового ключа з будь-якого рядка. Проблема не в безпеці. Також добре, що це швидко. Єдине питання полягає в тому, чи вирішили вони знехтувати, а потім усунути це, оскільки це зараз не підходить для того, що було розроблено спочатку. Ми побачимо.
Патанджалі

2
Ви використовували стару версію PHP? Ваш перший приклад чудово працює в PHP 7.1.
Елліот Б.

6

Ключі масиву PHP можуть бути цілими чи рядками. Рядки PHP - це байтові масиви, що означає послідовності байтів. Інших типів рядків не існує, і PHP інакше не встановлює жодних спеціальних обмежень для рядків ключів масиву. Іншими словами: поки це рядок, все йде.


Я думаю, що неявний привід із рядка до цілочисельного ключа є важливою відмінністю, оскільки певні функції працюють по-різному, якщо ключ є цілим чи ні. наприклад, Ви можете використовувати довільні номери рядків лише для того, щоб виявити, що функція масиву згодом переіндексує їх з 0..n-1.
Матвій

1
Згоден, але я вважаю, що це на межі сфери дії цього питання. :)
обдурити

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

Я особисто не мав жодних проблем із незвичними символами в клавішах масиву. Те, що є і що не є законним, недостатньо добре задокументовано, окрім як сказати, що ключовим фактором повинен бути скаляр. Найкраще - просто спробувати і побачити.


Так, непослідовно, але це добре задокументовано.
Корбін,

0

На додаток до всіх відповідей, оскільки вони відповідають дійсності: Ви можете використовувати PSR, які є певними правилами між найкращими програмістами щодо гарного та стандартного стилю кодування.


0

У масиві php ви не можете використовувати ключ: 2.3 або десяткові числа


-1

Кодуйте php-сторінку в ANSI "é" зможе використовувати (Cinéma не відображатиметься як Cinéma). У Notepad ++ просто скористайтеся меню Encode => Convert ANSI і збережіть


2
(Здається, ця публікація не дає якісної відповіді на запитання. Будь ласка, відредагуйте свою відповідь або просто опублікуйте її як коментар до питання).
sɐunıɔ ןɐ qɐp

Ви можете пояснити це далі? Що робити, якщо éйого немає, що робити, якщо OP все-таки не використовує Notepad ++?
Ніко Хаасе
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.