Very interesting question... what I would probably do is first split the string into an array on the line breaks, so you'd have rows. Then, loop through each array piece and split that piece on a space, so that you'd have each column in that row, and store each part of the piece into a different array according to which column we're on.
Sounds fairly confusing in words, so here's what I came up with:
$test = " 123 456 891
nnn jjj kkk
lol jkl lol";
$test = explode("\n", $test); // *** see note below
$columns = array();
for($i=0; isset($test[$i]); $i++) {
if(empty($columns[$i]))
$columns[$i] = $test[$i];
else
$columns[$i] .= ', ' . $test[$i]; // columns separated by comma and space, change this here
}
NOTE: As you'll see, my code snippet uses [man]explode[/man to split the string on a new line character. Not all OS's are created equally, thus line endings suffer the same uncertain fate. In Unix, it's simply \n - in Windows, it's \r\n - in Mac, it's \r. You might have to adjust the value for the separator in this function for it to suit your needs.
NOTE: In addition, you talked about Column 1 being 123, nn, etc. though in terms of PHP (and just about any other scripting language), you are actually referring to Column 0. Column 1 would, in fact, be 456, jjj, jkl. If you don't want to work with Column #'s starting with 0, simply change every reference to $i inside the for() loop in my code to $i+1. That way, Column numbers will start with 1 and continue on. Though, I find it much easier to simply condition myself as a progammer to start with 0 when dealing with arrays.
EDIT: I also would like to say that since my main computer is offline at the moment, I didn't have a chance to test/debug this code, so make sure you do that on your own. Also, if it's not obvious, $columns is an array of comma-delimited strings, the indeces matching up with the column # (starting with 0 as noted above).