Blame view

vendor/yiisoft/multiparser/CsvParser.php 4.96 KB
1e991822   Mihail   csv parser with e...
1
2
  <?php
  /**
1e991822   Mihail   csv parser with e...
3
  
40ff24a1   Mihail   refactor CsvParse...
4
   */
036717a1   Mihail   add error excepti...
5
  namespace yii\multiparser;
dc10d651   Mihail   add value filter ...
6
  
1e991822   Mihail   csv parser with e...
7
  
37656b1f   Mihail   add parser interf...
8
  class CsvParser implements ParserInterface
999b9326   Mihail   add detectStartPo...
9
  {
1e991822   Mihail   csv parser with e...
10
  
1e991822   Mihail   csv parser with e...
11
  
40ff24a1   Mihail   refactor CsvParse...
12
13
      /** @var bool
      имеет ли файл заголовок который будет установлен ключами возвращемого массива*/
e55d56cc   Mihail   add draft version...
14
      public $hasHeaderRow = false;
40ff24a1   Mihail   refactor CsvParse...
15
16
17
      /** @var array - массив с заголовком,
       * если не указан и установлено свойство $hasHeaderRow - будет определен автоматически */
      public $keys;
1e991822   Mihail   csv parser with e...
18
  
40ff24a1   Mihail   refactor CsvParse...
19
      /** @var экземляр SplFileObject читаемого файла */
e55d56cc   Mihail   add draft version...
20
      public $file;
1e991822   Mihail   csv parser with e...
21
  
40ff24a1   Mihail   refactor CsvParse...
22
      /** @var int - первая строка с которой начинать парсить */
e55d56cc   Mihail   add draft version...
23
      public $first_line = 0;
1e991822   Mihail   csv parser with e...
24
  
40ff24a1   Mihail   refactor CsvParse...
25
26
27
28
29
      /** @var int - последняя строка до которой  парсить
       * если не указана, то парсинг происходит до конца файла*/
      public $last_line = 0;
  
      /** @var int - первая колонка файла с которой начнется парсинг */
e55d56cc   Mihail   add draft version...
30
      public $first_column = 0;
b13b1c83   Mihail   final version par...
31
  
40ff24a1   Mihail   refactor CsvParse...
32
      /** @var string - разделитель csv */
e55d56cc   Mihail   add draft version...
33
      public $delimiter = ';';
40ff24a1   Mihail   refactor CsvParse...
34
35
36
37
38
39
40
41
  
      /** @var bool
      нужно ли искать автоматически первоую значисмую строку (не пустая строка)
       * иначе первая строка будет взята из аттрибута $first_line */
      public $auto_detect_first_line = false;
  
      /** @var int - количество значимых колонок, что бы определить первую значимую строку
       * используется при автоопределении первой строки*/
e55d56cc   Mihail   add draft version...
42
      public $min_column_quantity = 5;
dc10d651   Mihail   add value filter ...
43
  
5c710262   Mihail   edit csv parser -...
44
  
40ff24a1   Mihail   refactor CsvParse...
45
46
47
      /**
     метод устанвливает нужные настройки объекта SplFileObject, для работы с csv
       */
e55d56cc   Mihail   add draft version...
48
49
      public function setup()
      {
999b9326   Mihail   add detectStartPo...
50
51
52
          $this->file->setCsvControl($this->delimiter);
          $this->file->setFlags(\SplFileObject::READ_CSV);
          $this->file->setFlags(\SplFileObject::SKIP_EMPTY);
40ff24a1   Mihail   refactor CsvParse...
53
54
          if ($this->auto_detect_first_line) {
              $this->shiftToFirstValuableLine();
e55d56cc   Mihail   add draft version...
55
          }
1e991822   Mihail   csv parser with e...
56
57
      }
  
40ff24a1   Mihail   refactor CsvParse...
58
59
60
61
62
63
64
      /**
       * определяет первую значимую строку,
       * считывается файл пока в нем не встретится строка с непустыми колонками
       * в количестве указанном в атрибуте min_column_quantity
       * в результате выполнения курсор ресурса будет находится на последней незначимой строке
       */
      protected function shiftToFirstValuableLine()
e55d56cc   Mihail   add draft version...
65
      {
e55d56cc   Mihail   add draft version...
66
  
40ff24a1   Mihail   refactor CsvParse...
67
68
69
          $finish = false;
  
          while (!$finish) {
999b9326   Mihail   add detectStartPo...
70
71
              $j = 0;
              $row = $this->readRow();
999b9326   Mihail   add detectStartPo...
72
73
              if ($row === false) {
                  continue;
e55d56cc   Mihail   add draft version...
74
              }
999b9326   Mihail   add detectStartPo...
75
  
999b9326   Mihail   add detectStartPo...
76
77
78
79
80
81
82
              for ($i = 1; $i <= count($row); $i++) {
  
                  if ($row[$i - 1] <> '') {
                      $j++;
                  }
  
                  if ($j >= $this->min_column_quantity) {
40ff24a1   Mihail   refactor CsvParse...
83
                      break 2;
999b9326   Mihail   add detectStartPo...
84
                  }
e55d56cc   Mihail   add draft version...
85
86
              }
          }
e55d56cc   Mihail   add draft version...
87
      }
1e991822   Mihail   csv parser with e...
88
89
  
      /**
40ff24a1   Mihail   refactor CsvParse...
90
91
       * @return array - итоговый двумерный массив с результатом парсинга
       * метод считывает с открытого файла данные построчно
1e991822   Mihail   csv parser with e...
92
93
94
       */
      public function read()
      {
1e991822   Mihail   csv parser with e...
95
          $return = [];
40ff24a1   Mihail   refactor CsvParse...
96
97
  
          $current_line = 0;
e774f057   Mihail   work with custome...
98
          //$this->keys = NULL;
40ff24a1   Mihail   refactor CsvParse...
99
  
1e991822   Mihail   csv parser with e...
100
          while (($row = $this->readRow()) !== FALSE) {
40ff24a1   Mihail   refactor CsvParse...
101
              $current_line++;
1e991822   Mihail   csv parser with e...
102
103
  
              if ($this->hasHeaderRow) {
dc10d651   Mihail   add value filter ...
104
105
                  if ($this->keys === NULL) {
                      $this->keys = array_values($row);
1e991822   Mihail   csv parser with e...
106
107
                  } else {
  
dc10d651   Mihail   add value filter ...
108
                      if (count($this->keys) !== count($row)) {
1e991822   Mihail   csv parser with e...
109
  //
036717a1   Mihail   add error excepti...
110
                          throw new \ErrorException( "Invalid columns detected on line # {$current_line}", 0, 1, $this->file->getBasename(), $current_line);
1e991822   Mihail   csv parser with e...
111
112
                      }
  
dc10d651   Mihail   add value filter ...
113
                      $return[] = array_combine($this->keys, $row);
1e991822   Mihail   csv parser with e...
114
                  }
40ff24a1   Mihail   refactor CsvParse...
115
116
117
              }
              else
              {
1e991822   Mihail   csv parser with e...
118
119
                  $return[] = $row;
              }
40ff24a1   Mihail   refactor CsvParse...
120
121
              // если у нас установлен лимит, при  его достижении прекращаем парсинг
              if (($this->last_line) && ($current_line > $this->last_line)) {
999b9326   Mihail   add detectStartPo...
122
123
124
                  break;
              }
  
1e991822   Mihail   csv parser with e...
125
126
127
          }
  
          $this->closeHandler();
1e991822   Mihail   csv parser with e...
128
129
130
          return $return;
      }
  
2957209c   Mihail   csv parser - add ...
131
  
dfeb2d10   Mihail   edit universal cs...
132
      protected function closeHandler()
1e991822   Mihail   csv parser with e...
133
      {
2957209c   Mihail   csv parser - add ...
134
          $this->file = NULL;
1e991822   Mihail   csv parser with e...
135
136
      }
  
40ff24a1   Mihail   refactor CsvParse...
137
138
139
      /**
       * @return array - одномерный массив результата парсинга строки
       */
dfeb2d10   Mihail   edit universal cs...
140
      protected function readRow()
1e991822   Mihail   csv parser with e...
141
      {
dfeb2d10   Mihail   edit universal cs...
142
  
999b9326   Mihail   add detectStartPo...
143
          $row = $this->file->fgetcsv();
40ff24a1   Mihail   refactor CsvParse...
144
145
146
147
          if (is_array($row) && $this->first_column) {
  
              $row = array_slice($row, $this->first_column);
  
dfeb2d10   Mihail   edit universal cs...
148
          }
999b9326   Mihail   add detectStartPo...
149
150
          if (is_null($row))
              $row = false;
dc10d651   Mihail   add value filter ...
151
  
dfeb2d10   Mihail   edit universal cs...
152
          return $row;
1e991822   Mihail   csv parser with e...
153
154
155
  
      }
  
1e991822   Mihail   csv parser with e...
156
157
  
  }