Это сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

Загадка про PHP

Загадка про PHP. Есть массив, описанный таким вот образом:

array (1, '4' => 1, 'a' => 1, 1);

Вопрос: сможете ли вы, не запуская PHP, сказать какой индекс будет у последнего элемента?

Дополнение: буква «a» в индексе — латинская

Ctrl →Лабрис
30 комментариев
Улитка 2003

Сдается мне, последний элемент в массиве будет с индексом ’b’. (Это если a — английская).

(Не проверял)

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Улитка:

У него будет индекс <span style=«background-color:black; color: black»>5</span>.

Baka 2003

Не смог. 42? или любой бред ;-)
Если верить документации:
<blockquote>
Syntax «index => values», separated by commas, define index and values. index may be of type string or numeric. When index is omitted, a integer index is automatically generated, starting at 0. If index is an integer, next generated index will be the biggest integer index + 1. Note that when two identical index are defined, the last overwrite the first.
</blockquote>
, то индексы:
0, ’4’ (СТРОКА!!!) ’a’(строка), max(0)+1

Но так как PHP сделан по «приципу наибольшего удивления»
(или «через миллениум (с одной н)»),
оказывается, что ’4’ — не строка…

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Baka:

Правда странно? :)

Baka 2003

Если вспомнить, как там реальзованы логические значения,
то не очень :-)

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Baka:

А что там не так с логическими значениями?

Улитка 2003

Про правильный ответ:

Эту версию я рассматривал первой.
Второй была версия что последний элемент будет с индексом ’a’. (Она совпадает с правильным ответом, разница лишь в том, как понять смысл вопроса).
Третью версию я написал после того, как прочел в справке о том, что ’a’+1 = ’b’.

Никак не предполагал что php будет вставлять индексы в середину массива.

А вообще, такие вещи решаются программой test.php :-)

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Улитка:

Конечно решаются. Но иногда важно знать, что PHP сделает в каком-то случае, так как не задумываясь можно допустить ошибку.

Улитка 2003

Беда в том, что я всё время задумываюсь. И файл test.php у меня постоянно запущен :-)

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Улитка:

Я тоже :) Но вот сегодня пропустил одну вещь, связанную с проверкой индекса массивов, но не связанную с задачами.

Кстати, можешь посмотреть вторую задачу.

Baka 2003

$one = 1;
  $b_one = (bool)1;
  
  $ten = 10;
  $b_ten = (bool)10; # === TRUE

  if ($one == $b_one) {print «1:$one == $b_one\n»;}
  if ($one === $b_one) {print «2:$one === $b_one\n»;}

  if ($ten == $b_ten) {print «3:$ten == $b_ten\n»;}
  if ($ten === $b_ten) {print «4:$ten === $b_ten\n»;}

  if ($one == $b_ten) {print «5:$one == $b_ten\n»;}
  if ($b_one == $ten) {print «6:$b_one == $ten\n»;} # !!!

  print «\n»;
  if ($b_one == $b_ten) {print «7:$b_one == $b_ten\n»;}
  if ($b_one === $b_ten) {print «8:$b_one === $b_ten\n»;}

  if ($b_one == TRUE) {print «9:$b_one == TRUE\n»;}
  if ($b_one === TRUE) {print «10:$b_one === TRUE\n»;}

  if ($one == TRUE) {print «11:$one == TRUE\n»;}
  if ($one === TRUE) {print «12:$one === TRUE\n»;}

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Baka:

Приведение типов :) Kukutz уже об этом говорил :)

Baka 2003

Многие говорили. :-) Я об этом когда-то читал у Котерова (который dklab.ru).
Проблема возникает если, например, в функции сравнивать 10 со значеним параметра, думая, что это число
(а получено TRUE или булевский 1 — то есть «булевскость» в функции не видна), то получается
равенство, что не всегда хорошо.
Можно, конечно, все параметры пропускать через явный (int), но это тоже не очень весело.

Евгений Степанищев (bolknote.ru) 2003

Комментарий для Baka:

Да, я один раз на этом обжёгся и не факт, что не обожгусь сново.

detail 2003

Спрашивается только, нахрена так объявлять массивы, и как часто это может понадобиться? Как часто это может понадобиться, если писать комментируемый + понятный другим людям код. Не применять, как говорил Расмус Лердорф, лэйтнайт хэкс. :)

Евгений Степанищев (bolknote.ru) 2003

Комментарий для detail:

Язык надо знать, тогда и код будет понятен. А определятся он может так, например, если этот код генерируется автоматически.

detail 2003

<i> А определятся он может так, например, если этот код генерируется автоматически.</i>

Лихо, лихо. …А ещё на модуль DOM XML бочку катят!

Евгений Степанищев (bolknote.ru) 2003

Комментарий для detail:

А причём здесь DOM XML? :) Я часто использую автосгенерированные массивы.

detail 2003

Да просто XML-щиков гнобят, мол «шашечки или ехать, будьте проще». То же самое могу сказать про автосгенерированные массивы. :)

Евгений Степанищев (bolknote.ru) 2003

Комментарий для detail:

Автосгенерированные массивы — необходимость. Они помогают кешировать данные.

mivlad 2003

А не быстрее ли автосгенерированные массивы хранить в сериализованном виде?

Евгений Степанищев (bolknote.ru) 2003

Комментарий для mivlad:

Не быстрее. Unserialize гораздо медленее, чем include.

detail 2003

<i>Автосгенерированные массивы — необходимость. Они помогают кешировать данные.</i>
Я не знаю твоей позиции по XML, поэтому не буду продолжать. :)

Евгений Степанищев (bolknote.ru) 2003

Комментарий для detail:

XML настолько прострая вещь, что.. какая уж там может быть позиция?

mivlad 2003

<blockquote>Не быстрее. Unserialize гораздо медленее, чем include. </blockquote>Точно? Только что проверил — десериализация раза в полтора быстрей полноценного парсинга. Тестовый (генерирующий) скрипт:

for($i=0; 10000>$i; $i++)$a[]=mt_rand()%2?mt_rand():md5(mt_rand());
echo microtime(),«\n»;
$fp=fopen(’s’,’w’);
fwrite($fp,serialize($a));
fclose($fp);
echo microtime(),«\n»;
$fp=fopen(’p’,’w’);
fwrite($fp,’? $a=’.var_export($a,1).’?’); // около вопросиков добавить угловые скобки
fclose($fp);
echo microtime(),«\n»;

Обратный, думаю, сам напишешь :)
Кстати, serialize действительно медленнее, чем var_export.

Евгений Степанищев (bolknote.ru) 2003

Комментарий для mivlad:

Сравни unserialize и include. Ты сделал наоборот.

mivlad 2003

<blockquote>Сравни unserialize и include. Ты сделал наоборот.</blockquote>О чём и сказал (согласен, недостаточно внятно). Как раз в этом обратном случае ты прав, но unserialize <i>быстрее</i>, чем include.

Евгений Степанищев (bolknote.ru) 2003

Комментарий для mivlad:

Действительно — медленее на треть. Массив из 10000 элементов (строк по 32 символа) в цикле из 100 операций выполнился для unserialize за 10 секунд, для include — за 16. Любопытно. Буду использовать serialize там, где читаемость результата не важна.

mivlad 2003

<blockquote>Действительно — медленее на треть.</blockquote>Собственно, ничего удивительного — сравни, какой парсер нужен для одного и для другого случая :)

Евгений Степанищев (bolknote.ru) 2003

Комментарий для mivlad:

Уже :)