Дано: Форма с полем типа textarea, в которое методом копипаста (Ctrl-C Ctrl-V) вставляется содержимое таблице Excell.
Нужно, превратить эти данные в двухмерный массив типа $arr[номер_строки][номер_ячейки].
Собственно, делалось это вот так. Т.е. дробим полученную строку по символам перевода каретки (\n), а то что раздробилось — дробим по символу табуляции (\t) и получаем массив $arr.
function tableToArray($textarea) { $arrtr = explode("\n", $textarea); foreach ($arrtr as $k => $v) { $arr[$k] = explode("\t", $v); } return $arr; }
Ничто не предвещало беды, но, вмешался человеческий фактор. Кое-кто повадился ставить символы перевода каретки прямо в ячейках таблицы, и всё пошло по… лесу.
Пришлось усложнить алгоритм.
function tableToArray($textarea) { //Делаем проверку первой строки. По ней считаем количество колонок в таблице $prearrtr = explode("\n", $textarea); $tdcount = count(explode("\t", $prearrtr[0])) - 1; //Получаем номер последней ячейки для каждой строки $tabattr = explode("\t", $textarea); //Дробим данные по символу табуляции $forbiddenCharacters = "\/*?<>|+%!\n\r"; //Запрещённые символы $arr = []; $trnum = 0; $tdnum = 0; foreach ($tabattr as $v) { if ($tdnum < $tdcount) { //Если у нас не последняя ячейка $arr[$trnum][$tdnum] = preg_replace("/[${forbiddenCharacters}]/", '', $v); $tdnum++; }else{ //Если ячейка последняя, то она содержит и первую ячейку следующей строки //Кроме того, и в первой и в последней ячейке могут быть ненужные переводы строк //Поэтому, бьём на массив, удаляем пустые ячейки, перенумеровываем. $finalv = array_values(array_diff(explode("\n", $v), array(''))); //Пишем последнюю ячейку $arr[$trnum][$tdnum] = preg_replace("/[${forbiddenCharacters}]/", '', $finalv[0]); $trnum++; $tdnum = 0; $arr[$trnum][$tdnum] = preg_replace("/[${forbiddenCharacters}]/", '', $finalv[1]); $tdnum++; } } return $arr; }
Если смотреть в код, то в принципе алгоритм понятен. Есть пара моментов, которые поясню отдельно.
Первая строка таблицы (шапка) — эталонная и её никто не правит. Поэтому, в ней нет символов переходов строк. По ней считаем количество столбцов в таблице.
Дробим данные по табуляции и закидываем в массив $tabattr. Проблема в том, что последняя ячейка текущей строки сливается с первой ячейкой следующей и попадает в одну ячейку массива. Поэтому, дойдя до последней ячейки (по номеру $tdcount), я дроблю полученные данные по символу перевода каретки и получаю массив $finalv. Удаляю из $finalv пустые ячейки и перенумеровываю ключи.
Теперь, первую ячейку $finalv[0] загоняю в последнюю ячейку текущей строки массива таблицы, а вторую ячейку $finalv[1] закидываю в первую ячейку следующей строки.
Собственно, на этом пока всё.