Обработка нескольких строк данных из текстовой области; более эффективный способ? - PullRequest
0 голосов
/ 25 ноября 2011

В моем приложении есть текстовое поле, которое мои пользователи должны вводить в формате:

Forename, Surname, YYYY-MM-DD, Company
Forename, Surname, YYYY-MM-DD, Company

на каждой строке. Мое намерение состоит в том, чтобы затем циклически проходить через каждый ряд, взрываясь через запятую и обрезая все пробелы.

Затем мне нужно передать разобранный массив в ассоциативный массив. Сейчас я делаю это вручную, исходя из предположения, что пользователь ввел данные в правильном порядке и формате; который работает, но полагается, что пользователь не портит.

Что бы вы предложили как лучший способ сделать это? Я думаю, что способ проверки каждого индекса, чтобы увидеть, пустой он или нет, кажется довольно неуклюжим, а также подверженным ошибкам.

Любые предложения или вещи для рассмотрения?

/************************************
* sample data from textarea:
* Name, Surname, 1980-02-22, Company
* Foo, Bar, 1970-05-12, Baz
************************************/
$data = preg_split('/\r\n|\n/', $_POST['data'], 
                                     -1,  PREG_SPLIT_NO_EMPTY);

$item = array();                
// loop through the data            
foreach($data as $row) :
    //  trim and explode each line in to an array
     $item[] = array_map('trim', explode(',', $row));
endforeach;

$k=0;
foreach($item as $user) :

    $processed_data[$k]['first_name'] = !empty($user[0]) ? $user[0] : NULL;
    $processed_data[$k]['last_name'] = !empty($user[1]) ? $user[1] : NULL;

    if(!empty($user[2])) :
        $dob = strtotime($user[2]);
        if($dob) {
            $processed_data[$k]['dob'] = $user[2];
        } else {
            $processed_data[$k]['dob'] = NULL;  
        }
    else:
        $processed_data[$k]['dob'] = NULL;  
    endif;

    $processed_data[$k]['company'] = !empty($user[3]) ? $user[3] : NULL;
    $k++;

endforeach;

// print_r($processed_data);

Ответы [ 2 ]

0 голосов
/ 07 декабря 2011

Вы можете инкапсулировать анализ и проверку в свои собственные классы.Кроме того, вы можете сделать то же самое для структуры данных, содержащей табличные данные.

class TableParser
{
    private $string;
    public function __construct($string)
    {
        $this->string = (string) $string;
    }
    public function parse()
    {
        $buffer = $this->string;
        $rows = explode("\n", $buffer);
        $rows = array_map('trim', $rows);
        return $this->parseRows($rows);
    }
    private function parseRows(array $rows)
    {
        foreach($rows as &$row)
        {
            $row = $this->parseRow($row);   
        }
        return $rows;
    }
    private function parseRow($row)
    {
        $keys = array('forename', 'surname', 'date', 'company');
        $keyCount = count($keys)
        $row = explode(',', $row, $keyCount);
        if (count($row) != $keyCount)
        {
            throw new InvalidArgumentException('A row must have 4 columns.');
        }
        $row = array_map('trim', $row);
        $row = array_combine($keys, $row);
        return $row;
    }
}

Этот синтаксический анализатор все еще довольно грубый.Вы можете улучшить его с течением времени, например, предоставляя лучшую обработку ошибок, учитывая информацию, какая строка неисправна и тому подобное.Такой компонент может быть легче интегрирован в ваш обычный поток приложений, так как вы можете вернуть эту информацию обратно пользователю, чтобы позволить ему вносить изменения во входные данные.

Кроме того, вы можете выделить проверку в секундуclass и выполняет только разбор / обрезку в синтаксическом анализаторе, но проверку по счетчику, указание ключей массива, а также проверку формата / значения даты во втором классе, чтобы держать вещи в стороне.

0 голосов
/ 26 ноября 2011

ты из старой школы :) Ну, как вы говорите выше, вы ожидаете, что пользователь правильно введет данные в текстовой области. Хорошо, если ваше приложение работает в настоящее время в надежной системе, не трогайте его, но в противном случае вам следует рассмотреть возможность добавления различных параметров в ваш пост-запрос (по одному для каждого поля, которое вы хотите взорвать) ...

Вы можете сделать это, чтобы решить проблему, которая у вас сейчас есть:

// The algorithm below believe user send data correctly
// Forename, Surname, YYYY-MM-DD, Company
$names = array('first_name', 'last_name', 'dob', 'company_name');

$lines = explode("\n", $_POST['data']);

$result = array();
foreach ($lines as $ line)
{
   $exploded_line = explode(",", $line);
   $row = array();
   foreach ($exploded_line as $key=>$item) { $row[$names[$key]]= trim($item); }
   $result[]=$row;
}

// Now in result there is an array like this
// result[0][first_name]
// result[0][last_name]
// result[0][dob]
// result[0][company_name]
// result[1][first_name]
// [ ... ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...