Как превратить таблицу в массив (PHP)

Дано: Форма с полем типа 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] закидываю в первую ячейку следующей строки.

А ещё, я чищу содержимое ячеек от символов, указанных в переменной $forbiddenCharacters. В т.ч. от символов перевода строки.

Собственно, на этом пока всё.

Напишите комментарий