1 /**
2 * 文件读写类
3 * 读取时,支持跳过N个/行字符然后再读取M个/行字符
4 * 支持每次读取时使用回调函数
5 *
6 * 示例:
7 * $file = new File('a.txt', 'r');
8 *
9 * $data = $file->limit(0, 10)->getLine(function($line){
10 * return $line . ' <br/>';
11 * });
12 * print_r($data);
13 * $file->close();
14 *
15 */
16
17 class File {
18
19 protected $fp = null;
20 protected $file = null;
21 protected $limit = [0, 0];
22
23 public function __construct($file, $mode = 'r'){
24
25 $this->file = $file;
26 $this->fp = fopen($file, $mode);
27
28 }
29
30 public function limit($start, $line = 0){
31
32 if(func_num_args() == 1){
33 $line = $start; $start = 0;
34 }
35 $this->limit = [$start, $line];
36 return $this;
37 }
38
39 /**
40 * 增加对文件函数的直接调用
41 * @param string $method
42 * @param mixed $args
43 * @return mixed
44 */
45 public function __call($method, $args){
46
47 array_unshift($args, $this->fp);
48 return call_user_func_array($method, $args);
49 }
50
51
52
53 /**
54 * 读取文件按行
55 * @param function $func
56 * @param $read 读取方式
57 * @param $args 参数列表
58 * @return mixed
59 */
60 public function readLine($func = null, $read = null, $args = []){
61
62 $data = array();
63 $opt = array('char'=>'fgetc', 'line'=>'fgets', 'csv'=>'fgetcsv');
64 $read = (isset($opt[$read]))? $opt[$read] : 'fgets';
65 array_unshift($args, $this->fp);
66
67 //跳过字符数或行数
68 if($this->limit[0] !== 0){
69 for($i = 0; $i < $this->limit[0]; $i++){
70 if(call_user_func_array($read, $args) === false){
71 return $data;
72 }
73 }
74 }
75
76 if($this->limit[1] > 0){
77 //读取有效行数
78 for($i = 0; $i < $this->limit[1]; $i++){
79
80 if(($buffer = call_user_func_array($read, $args)) === false){
81 return $data;
82 }
83 if(is_callable($func)){
84 $buffer = $func($buffer);
85 if($buffer !== null) $data[] = $buffer;
86 }else{
87 $data[] = $buffer;
88 }
89 }
90
91 }else{
92 //读取所有行数
93 while(($buffer = call_user_func_array($read, $args)) !== false){
94 if(is_callable($func)){
95 $buffer = $func($buffer);
96 if($buffer !== null) $data[] = $buffer;
97 }
98 }
99 }
100 $this->setHome();
101 return $data;
102
103 }
104
105 /**
106 * 读取文件按字符
107 * @param function $func
108 * @return mixed
109 */
110 public function getChar($func = null){
111 return implode('', $this->readLine($func, 'char'));
112
113 }
114
115 /**
116 * 读取文件按行
117 * @param int $length
118 * @param function $func
119 * @return mixed
120 */
121 public function getLine($func = null, $length = 1024){
122
123 if(is_numeric($func)){
124 $length = $func; $func = null;
125 }
126 return $this->readLine($func, 'line', [$length]);
127 }
128
129 /**
130 * 读按行取csv文件
131 * @param unknown $func
132 * @param number $length
133 * @param string $delimiter
134 */
135 public function getCsv($length = 0, $delimiter = ','){
136 return $this->readLine($func, 'csv', [$length, $delimiter]);
137 }
138
139 /**
140 * 读取文件按字节
141 * @param number $length
142 * @return string
143 */
144 public function read($length = 0){
145
146 if(empty($length)) $length = filesize($this->file);
147 return fread($this->fp, $length);
148 }
149
150 /**
151 * 写入文件
152 * @param unknown $string
153 * @param unknown $length
154 * @return number
155 */
156 public function write($string, $length = null){
157 return fwrite($this->fp, $string, $length);
158 }
159
160 /**
161 * 写入csv文件
162 * @param unknown $data
163 * @param string $delimiter
164 * @return boolean
165 */
166 public function putCsv($data, $delimiter = ','){
167
168 foreach($data as $row) {
169 fputcsv($fp, $row);
170 }
171 }
172
173 /**
174 * 获取文件资源指针
175 * @return resource
176 */
177 public function getfp(){
178 return $this->fp;
179 }
180
181 /**
182 * 获取当前头文件指针位置
183 * @return number
184 */
185 public function getSeek(){
186 return ftell($this->fp);
187 }
188
189 /**
190 * 文件指针定位到开头
191 * @return boolean
192 */
193 public function setHome(){
194 return rewind($this->fp);
195 }
196
197 /**
198 * 文件指针定位到结尾
199 * @return number
200 */
201 public function setEnd(){
202 return fseek($this->fp, 0, SEEK_END);
203 }
204
205 /**
206 * 设置文件指针位置
207 * @param unknown $offset
208 * @param string $whence
209 * @return number
210 */
211 public function setSeek($offset, $whence = SEEK_SET){
212 return fseek($this->fp, $offset, $whence);
213 }
214
215 /**
216 * 关闭文件指针
217 * @return boolean
218 */
219 public function close(){
220 return fclose($this->fp);
221 }
222
223 public static function getSql($file, $isarray = false){
224
225 $content = preg_replace(['/[\r|\n]+\s?(((--\s+|#).*)|\/\*(.|\n)*\*\/)/', '/[\r|\n]+/'], '', file_get_contents($file));
226 if($isarray) $content = array_filter(explode(';', $content));
227 return $content;
228 }
229
230 }