I couldn't come up with a "good" algorithm, just a more-or-less brute force approach:
<?php
function spiral($n)
{
$n = abs((int)$n);
$result = array();
$count = 0;
for($i = 1; $i <= $n; $i++) {
if($i % 2) {
for($y = $i, $x = 1; $x <= $i; $x++) {
$result[$x][$y] = ++$count;
}
for($x = $i, $y = $i - 1; $y >= 1; $y--) {
$result[$x][$y] = ++$count;
}
}
else {
for($y = 1, $x = $i; $y <= $i; $y++) {
$result[$x][$y] = ++$count;
}
for($x = $i - 1, $y = $i; $x >= 1; $x--) {
$result[$x][$y] = ++$count;
}
}
}
return $result;
}
?>
<html><head><title>Test</title>
<style type='text/css'>
table {
border-collapse: collapse;
border: solid 2px black;
}
td {
text-align: center;
padding: 0.2em;
border: solid 1px black;
}
</style></head><body>
<?php
$test = range(1,6);
foreach($test as $num) {
echo "<h3>Test Value: $num</h3>\n";
$data = spiral($num);
echo "<table>\n";
for($y = 1; $y <= $num; $y++) {
echo "<tr>";
for($x = 1; $x <= $num; $x++) {
echo "<td>".$data[$x][$y]."</td>";
}
echo "</tr>\n";
}
echo "<table>\n";
}
?>
</body></html>