PHP — ошибочный алфавитный цикл

Может ли кто-нибудь объяснить мне, почему:

    <?php
    for ($i = 'a'; $i <= 'z'; $i++){
    echo "$i ";
    }
    ?>

Почему его выход:

a b c d e f g h i j k l m n o p q r s t u v w x y z aa ab ac ad ae af ag ah ai aj ak al am an ao ap aq ar as at au av aw ax ay az ba bb bc bd be bf bg bh bi bj bk bl bm bn bo bp bq br bs bt bu bv bw bx by bz ca cb cc cd ce cf cg ch ci cj ck cl cm cn co cp cq cr cs ct cu cv cw cx cy cz da db dc dd de df dg dh di dj dk dl dm dn do dp dq dr ds dt du dv dw dx dy dz ea eb ec ed ee ef eg eh ei ej ek el em en eo ep eq er es et eu ev ew ex... on to yz

Но он отлично работает с

    <?php
    for ($i = 'a'; $i != 'aa'; $i++){
    echo "$i ";
    }
    ?>

Кажется, что цикл повторяется снова и снова, пока не достигнет «zz».

Если я даю $i<"aa", он должен работать нормально, но вместо этого выводит только «a».


person maxxon15    schedule 02.12.2011    source источник
comment
Даже не знал, что это можно сделать с помощью алфавита! +1   -  person Drahcir    schedule 02.12.2011
comment
возможный дубликат странного поведения оператора ++ в PHP 5.3   -  person ajreal    schedule 02.12.2011
comment
Вы всегда можете использовать функцию range(): us3.php.net/manual/en/ function.range.php   -  person Mr. Llama    schedule 02.12.2011
comment
@RichardLivingston Даже я не знал! :D Один из моих друзей показал мне это!   -  person maxxon15    schedule 02.12.2011
comment
@ajreal Вау! Это большой пост!   -  person maxxon15    schedule 02.12.2011
comment
Гораздо лучше дублировать: Почему этот код просто не печатает буквы от А до Я?   -  person eldarerathis    schedule 02.12.2011


Ответы (2)


См. руководство по оператору приращения:

PHP следует соглашению Perl при работе с арифметическими операциями над символьными переменными, а не в C. Например, в PHP и Perl $a = 'Z'; $а++; превращает $a в 'AA', а в C a = 'Z'; а++; превращает a в '[' (значение ASCII 'Z' равно 90, значение ASCII '[' равно 91). Обратите внимание, что символьные переменные могут увеличиваться, но не уменьшаться, и даже в этом случае поддерживаются только простые символы ASCII (a-z и A-Z). Увеличение/уменьшение других символьных переменных не влияет, исходная строка остается неизменной.

person nickb    schedule 02.12.2011
comment
В ПОРЯДКЕ. Я это понимаю. Но даже в этом случае цикл должен остановиться, когда он достигнет $i < 'z'. Как это происходит? - person maxxon15; 02.12.2011
comment
Я не понимаю, что вы имеете в виду - Это останавливает - person nickb; 02.12.2011
comment
Упс! Моя вина! Должно быть $i <= 'z' Почему оно переходит в aa ab... и так далее?! Цикл должен остановиться, так как он достиг z и повторил его. Разве не должно? - person maxxon15; 02.12.2011
comment
@ maxxon15: Потому что это лексическое (то есть алфавитное) сравнение. aa меньше, чем z, потому что оно будет стоять первым, когда вы расположите их в алфавитном порядке. Причина, по которой он останавливается на yz, заключается в том, что следующей строкой будет za, которая идет после (больше) z по алфавиту. - person eldarerathis; 03.12.2011

Вы не можете использовать оператор меньше ($i < "aa") для строки.

Он будет преобразован в числовой тип, и результаты обычно непредсказуемы.

person Benjam    schedule 02.12.2011
comment
Зависит от того, что вы пытаетесь сделать. - person Benjam; 02.12.2011
comment
@maxxon15: потому что aa не является буквой алфавита... Является ли zaa? Если вы рассматриваете свою последовательность, да, если вы рассматриваете алфавитный порядок, нет, это не так. Так что сравнение не совсем корректное. Использование == или !=, конечно, совсем другая история, поскольку вы можете четко определить идентификатор для строк. - person nico; 02.12.2011
comment
@nico Хм ... Это многое проясняет. Это, вероятно, причина, по которой он дает только a, когда я даю $i<"aa", и даже не выполняет обычную последовательность от a до z O_o - person maxxon15; 02.12.2011
comment
Если это все, что вы пытаетесь сделать, вы можете просто echo 'a b c d ...'; или echo implode(' ', range('a', 'z')); - person Benjam; 02.12.2011
comment
@Benjam - Да ... теперь буду использовать функцию range() ... :) - person maxxon15; 02.12.2011
comment
@nico: это сравнение имеет смысл в PHP. z больше, чем aa, потому что оно выполняет лексическое сравнение. Не имеет значения, что одна из двух букв, а другая только одна, они все равно являются строками. - person eldarerathis; 03.12.2011
comment
@eldarerathis: извините, возможно, я произвел неправильное впечатление своим предыдущим комментарием. Я говорю, что нет смысла использовать ‹= так, как использует OP, а не то, что PHP дает непредсказуемые результаты. - person nico; 03.12.2011