Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't this code simply print letters A to Z?

Tags:

php

<?php
for ($i = 'a'; $i <= 'z'; $i++)
    echo "$i\n";

This snippet gives the following output (newlines are replaced by spaces):

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

like image 303
Milan Babuškov Avatar asked Nov 04 '10 15:11

Milan Babuškov


4 Answers

From the docs:

PHP follows Perl's convention when dealing with arithmetic operations on character variables and not C's.

For example, in Perl 'Z'+1 turns into 'AA', while in C 'Z'+1 turns into '[' ( ord('Z') == 90, ord('[') == 91 ).

Note that character variables can be incremented but not decremented and even so only plain ASCII characters (a-z and A-Z) are supported.

From Comments:-
It should also be noted that <= is a lexicographical comparison, so 'z'+1 ≤ 'z'. (Since 'z'+1 = 'aa' ≤ 'z'. But 'za' ≤ 'z' is the first time the comparison is false.) Breaking when $i == 'z' would work, for instance.

Example here.

like image 143
Christian C. Salvadó Avatar answered Oct 23 '22 15:10

Christian C. Salvadó


Because once 'z' is reached (and this is a valid result within your range, the $i++ increments it to the next value in sequence), the next value will be 'aa'; and alphabetically, 'aa' is < 'z', so the comparison is never met

for ($i = 'a'; $i != 'aa'; $i++) 
    echo "$i\n"; 
like image 28
Mark Baker Avatar answered Oct 23 '22 16:10

Mark Baker


Others answers explain the observed behavior of the posted code. Here is one way to do what you want (and it's cleaner code, IMO):

foreach (range('a', 'z') as $i)
    echo "$i\n";

In response to ShreevatsaR's comment/question about the range function: Yes, it produces the "right endpoint", i.e. the values passed to the function are in the range. To illustrate, the output from the above code was:

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
like image 97
GreenMatt Avatar answered Oct 23 '22 15:10

GreenMatt


Others already said why PHP doesn't show what you expect. Here's how you get the result you might want:

<?php
for ($i = ord('a'); $i <= ord('z'); $i++)
    echo chr($i);
?>
like image 35
Filip Ekberg Avatar answered Oct 23 '22 15:10

Filip Ekberg