forked from ArtSkills/common
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathCsvWriter.php
132 lines (120 loc) · 3.54 KB
/
CsvWriter.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?php
declare(strict_types=1);
namespace ArtSkills\Lib;
use ArtSkills\Error\InternalException;
use Exception;
/**
* Запись в CSV файл. Работает в двух решимах:
* - Построчная запись (для больших объёмов данных)
* ```php
* $svFile = new CsvWriter('svFile.csv', ',', 'cp1251');
* while ($data = $query->fetchRow()) {
* $svFile->writeRow($data);
* }
* $svFile->close(); // также возможно сделать unset($svFile) - сохраняет данные при вызове деструктора
* ```
* - Запись ассоциативного массива целиком
* ```php
* $result = CsvWriter::writeCsv('svFile.csv', $lines, ',', 'cp1251');
* ```
* @SuppressWarnings(PHPMD.MethodMix)
*/
class CsvWriter
{
public const DEFAULT_ENCLOSURE = '"';
/**
* Указатель на файл
*
* @var ?resource
*/
private $_handle;
/**
* Разделитель колонок
*
* @var string
*/
private string $_delimiter = CsvReader::DEFAULT_DELIMITER;
/**
* CsvWriter constructor.
*
* @param string $filename
* @param string $delimiter
* @param string $encoding
* @throws InternalException
* @SuppressWarnings(PHPMD.ErrorControlOperator)
*/
public function __construct(
string $filename,
string $delimiter = CsvReader::DEFAULT_DELIMITER,
string $encoding = CsvReader::DEFAULT_ENCODING
) {
// phpcs:ignore
@$this->_handle = fopen($filename, 'w');
if (!$this->_handle) {
throw new InternalException('Ошибка создания файла ' . $filename);
}
stream_filter_append($this->_handle, 'convert.iconv.UTF-8/' . $encoding . '//TRANSLIT//IGNORE');
$this->_delimiter = $delimiter;
}
/**
* Запись строки
*
* @param array<string|int, string|int|bool|float|null> $row
* @return int
* @throws Exception
*/
public function writeRow(array $row): int
{
if (!$this->_handle) {
throw new Exception('Попытка записать в закрытый файл');
}
return fputcsv($this->_handle, $row, $this->_delimiter);
}
/**
* Закрывает файл
*
* @return void
*/
public function close()
{
fclose($this->_handle);
$this->_handle = null;
}
/**
* Деструктор и в Африке деструктор
*/
public function __destruct()
{
if ($this->_handle) {
$this->close();
}
}
/**
* Выгружает CSV файл из массива data
*
* @param string $filename
* @param array<string|int, array<string|int, string|int|bool|float|null>> $data
* @param string $delimiter
* @param string $encoding
* @param string $enclosure
* @return bool
*/
public static function writeCsv(
string $filename,
array $data,
string $delimiter = CsvReader::DEFAULT_DELIMITER,
string $encoding = CsvReader::DEFAULT_ENCODING,
string $enclosure = self::DEFAULT_ENCLOSURE
): bool {
$handle = fopen($filename, 'w');
stream_filter_append($handle, 'convert.iconv.UTF-8/' . $encoding);
if (!$handle) {
return false;
}
foreach ($data as $line) {
fputcsv($handle, $line, $delimiter, $enclosure);
}
fclose($handle);
return true;
}
}