phpBMS

root/trunk/phpbms/include/parsecsv.lib.php

Revision 432, 20.9 KB (checked in by nate, 3 years ago)
  • Added support for escaping quotes in import csv files with a backslash (\) character.
Line 
1<?php
2
3class parseCSV {
4       
5/*
6
7        Class: parseCSV v0.3.2
8        http://code.google.com/p/parsecsv-for-php/
9       
10       
11        Fully conforms to the specifications lined out on wikipedia:
12         - http://en.wikipedia.org/wiki/Comma-separated_values
13       
14        Based on the concept of Ming Hong Ng's CsvFileParser class:
15         - http://minghong.blogspot.com/2006/07/csv-parser-for-php.html
16       
17       
18       
19        Copyright (c) 2007 Jim Myhrberg (jim@zydev.info).
20
21        Permission is hereby granted, free of charge, to any person obtaining a copy
22        of this software and associated documentation files (the "Software"), to deal
23        in the Software without restriction, including without limitation the rights
24        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25        copies of the Software, and to permit persons to whom the Software is
26        furnished to do so, subject to the following conditions:
27
28        The above copyright notice and this permission notice shall be included in
29        all copies or substantial portions of the Software.
30
31        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
37        THE SOFTWARE.
38       
39       
40       
41        Code Examples
42        ----------------
43        # general usage
44        $csv = new parseCSV('data.csv');
45        print_r($csv->data);
46        ----------------
47        # tab delimited, and encoding conversion
48        $csv = new parseCSV();
49        $csv->encoding('UTF-16', 'UTF-8');
50        $csv->delimiter = "\t";
51        $csv->parse('data.tsv');
52        print_r($csv->data);
53        ----------------
54        # auto-detect delimiter character
55        $csv = new parseCSV();
56        $csv->auto('data.csv');
57        print_r($csv->data);
58        ----------------
59        # modify data in a csv file
60        $csv = new parseCSV();
61        $csv->sort_by = 'id';
62        $csv->parse('data.csv');
63        # "4" is the value of the "id" column of the CSV row
64        $csv->data[4] = array('firstname' => 'John', 'lastname' => 'Doe', 'email' => 'john@doe.com');
65        $csv->save();
66        ----------------
67        # add row/entry to end of CSV file
68        #  - only recommended when you know the extact sctructure of the file
69        $csv = new parseCSV();
70        $csv->save('data.csv', array('1986', 'Home', 'Nowhere', ''), true);
71        ----------------
72        # convert 2D array to csv data and send headers
73        # to browser to treat output as a file and download it
74        $csv = new parseCSV();
75        $csv->output (true, 'movies.csv', $array);
76        ----------------
77       
78
79*/
80
81
82        /**
83         * Configuration
84         * - set these options with $object->var_name = 'value';
85         */
86       
87        # use first line/entry as field names
88        var $heading = true;
89       
90        # override field names
91        var $fields = array();
92       
93        # sort entries by this field
94        var $sort_by = null;
95        var $sort_reverse = false;
96       
97        # delimiter (comma) and enclosure (double quote)
98        var $delimiter = ',';
99        var $enclosure = '"';
100       
101        # basic SQL-like conditions for row matching
102        var $conditions = null;
103       
104        # number of rows to ignore from beginning of data
105        var $offset = null;
106       
107        # limits the number of returned rows to specified amount
108        var $limit = null;
109       
110        # number of rows to analyze when attempting to auto-detect delimiter
111        var $auto_depth = 15;
112       
113        # characters to ignore when attempting to auto-detect delimiter
114        var $auto_non_chars = "a-zA-Z0-9\n\r";
115       
116        # preferred delimiter characters, only used when all filtering method
117        # returns multiple possible delimiters (happens very rarely)
118        var $auto_preferred = ",;\t.:|";
119       
120        # character encoding options
121        var $convert_encoding = false;
122        var $input_encoding = 'ISO-8859-1';
123        var $output_encoding = 'ISO-8859-1';
124       
125        # used by unparse(), save(), and output() functions
126        var $linefeed = "\r\n";
127       
128        # only used by output() function
129        var $output_delimiter = ',';
130        var $output_filename = 'data.csv';
131       
132       
133        /**
134         * Internal variables
135         */
136       
137        # current file
138        var $file;
139       
140        # loaded file contents
141        var $file_data;
142       
143        # array of field values in data parsed
144        var $titles = array();
145       
146        # two dimentional array of CSV data
147        var $data = array();
148       
149       
150        /**
151         * Constructor
152         * @param   input   CSV file or string
153         * @return  nothing
154         */
155        function parseCSV ($input = null, $offset = null, $limit = null, $conditions = null) {
156                if ( $offset !== null ) $this->offset = $offset;
157                if ( $limit !== null ) $this->limit = $limit;
158                if ( count($conditions) > 0 ) $this->conditions = $conditions;
159                if ( !empty($input) ) $this->parse($input);
160        }
161       
162       
163        // ==============================================
164        // ----- [ Main Functions ] ---------------------
165        // ==============================================
166       
167        /**
168         * Parse CSV file or string
169         * @param   input   CSV file or string
170         * @return  nothing
171         */
172        function parse ($input = null, $offset = null, $limit = null, $conditions = null) {
173                if ( !empty($input) ) {
174                        if ( $offset !== null ) $this->offset = $offset;
175                        if ( $limit !== null ) $this->limit = $limit;
176                        if ( count($conditions) > 0 ) $this->conditions = $conditions;
177                        if ( is_readable($input) ) {
178                                $this->data = $this->parse_file($input);
179                        } else {
180                                $this->file_data = &$input;
181                                $this->data = $this->parse_string();
182                        }
183                        if ( $this->data === false ) return false;
184                }
185                return true;
186        }
187       
188        /**
189         * Save changes, or new file and/or data
190         * @param   file     file to save to
191         * @param   data     2D array with data
192         * @param   append   append current data to end of target CSV if exists
193         * @param   fields   field names
194         * @return  true or false
195         */
196        function save ($file = null, $data = array(), $append = false, $fields = array()) {
197                if ( empty($file) ) $file = &$this->file;
198                $mode = ( $append ) ? 'at' : 'wt' ;
199                $is_php = ( preg_match('/\.php$/i', $file) ) ? true : false ;
200                return $this->_wfile($file, $this->unparse($data, $fields, $append, $is_php), $mode);
201        }
202       
203        /**
204         * Generate CSV based string for output
205         * @param   output      if true, prints headers and strings to browser
206         * @param   filename    filename sent to browser in headers if output is true
207         * @param   data        2D array with data
208         * @param   fields      field names
209         * @param   delimiter   delimiter used to separate data
210         * @return  CSV data using delimiter of choice, or default
211         */
212        function output ($output = true, $filename = null, $data = array(), $fields = array(), $delimiter = null) {
213                if ( empty($filename) ) $filename = $this->output_filename;
214                if ( $delimiter === null ) $delimiter = $this->output_delimiter;
215                $data = $this->unparse($data, $fields, null, null, $delimiter);
216                if ( $output ) {
217                        header('Content-type: application/csv');
218                        header('Content-Disposition: inline; filename="'.$filename.'"');
219                        echo $data;
220                }
221                return $data;
222        }
223       
224        /**
225         * Convert character encoding
226         * @param   input    input character encoding, uses default if left blank
227         * @param   output   output character encoding, uses default if left blank
228         * @return  nothing
229         */
230        function encoding ($input = null, $output = null) {
231                $this->convert_encoding = true;
232                if ( $input !== null ) $this->input_encoding = $input;
233                if ( $output !== null ) $this->output_encoding = $output;
234        }
235       
236        /**
237         * Auto-Detect Delimiter: Find delimiter by analyzing a specific number of
238         * rows to determine most probable delimiter character
239         * @param   file           local CSV file
240         * @param   parse          true/false parse file directly
241         * @param   search_depth   number of rows to analyze
242         * @param   preferred      preferred delimiter characters
243         * @param   enclosure      enclosure character, default is double quote (").
244         * @return  delimiter character
245         */
246        function auto ($file = null, $parse = true, $search_depth = null, $preferred = null, $enclosure = null) {
247               
248                if ( $file === null ) $file = $this->file;
249                if ( empty($search_depth) ) $search_depth = $this->auto_depth;
250                if ( $enclosure === null ) $enclosure = $this->enclosure;
251               
252                if ( $preferred === null ) $preferred = $this->auto_preferred;
253               
254                if ( empty($this->file_data) ) {
255                        if ( $this->_check_data($file) ) {
256                                $data = &$this->file_data;
257                        } else return false;
258                } else {
259                        $data = &$this->file_data;
260                }
261               
262                $chars = array();
263                $strlen = strlen($data);
264                $enclosed = false;
265                $n = 1;
266                $to_end = true;
267               
268                // walk specific depth finding posssible delimiter characters
269                for ( $i=0; $i < $strlen; $i++ ) {
270                        $ch = $data{$i};
271                        $nch = ( isset($data{$i+1}) ) ? $data{$i+1} : false ;
272                        $pch = ( isset($data{$i-1}) ) ? $data{$i-1} : false ;
273                       
274                        // open and closing quotes
275                        if ( $ch == $enclosure && (!$enclosed || $nch != $enclosure) ) {
276                                $enclosed = ( $enclosed ) ? false : true ;
277                       
278                        // inline quotes       
279                        } elseif ( $ch == $enclosure && $enclosed ) {
280                                $i++;
281
282                        // end of row
283                        } elseif ( ($ch == "\n" && $pch != "\r" || $ch == "\r") && !$enclosed ) {
284                                if ( $n >= $search_depth ) {
285                                        $strlen = 0;
286                                        $to_end = false;
287                                } else {
288                                        $n++;
289                                }
290                               
291                        // count character
292                        } elseif (!$enclosed) {
293                                if ( !preg_match('/['.preg_quote($this->auto_non_chars, '/').']/i', $ch) ) {
294                                        if ( !isset($chars[$ch][$n]) ) {
295                                                $chars[$ch][$n] = 1;
296                                        } else {
297                                                $chars[$ch][$n]++;
298                                        }
299                                }
300                        }
301                }
302               
303                // filtering
304                $depth = ( $to_end ) ? $n-1 : $n ;
305                $filtered = array();
306                foreach( $chars as $char => $value ) {
307                        if ( $match = $this->_check_count($char, $value, $depth, $preferred) ) {
308                                $filtered[$match] = $char;
309                        }
310                }
311               
312                // capture most probable delimiter
313                ksort($filtered);
314                $delimiter = reset($filtered);
315                $this->delimiter = $delimiter;
316               
317                // parse data
318                if ( $parse ) $this->data = $this->parse_string();
319               
320                return $delimiter;
321               
322        }
323       
324       
325        // ==============================================
326        // ----- [ Core Functions ] ---------------------
327        // ==============================================
328       
329        /**
330         * Read file to string and call parse_string()
331         * @param   file   local CSV file
332         * @return  2D array with CSV data, or false on failure
333         */
334        function parse_file ($file = null) {
335                if ( $file === null ) $file = $this->file;
336                if ( empty($this->file_data) ) $this->load_data($file);
337                return ( !empty($this->file_data) ) ? $this->parse_string() : false ;
338        }
339       
340        /**
341         * Parse CSV strings to arrays
342         * @param   data   CSV string
343         * @return  2D array with CSV data, or false on failure
344         */
345        function parse_string ($data = null) {
346                if ( empty($data) ) {
347                        if ( $this->_check_data() ) {
348                                $data = &$this->file_data;
349                        } else return false;
350                }
351               
352                $rows = array();
353                $row = array();
354                $row_count = 0;
355                $current = '';
356                $head = ( !empty($this->fields) ) ? $this->fields : array() ;
357                $col = 0;
358                $enclosed = false;
359                $was_enclosed = false;
360                $strlen = strlen($data);
361               
362                // --nrieb-- Adding support for escaping quotes with a backslash (\) character
363                $data = str_replace('\"', '""', $data);
364               
365                // walk through each character
366                for ( $i=0; $i < $strlen; $i++ ) {
367                        $ch = $data{$i};
368                        $nch = ( isset($data{$i+1}) ) ? $data{$i+1} : false ;
369                        $pch = ( isset($data{$i-1}) ) ? $data{$i-1} : false ;
370                       
371                        // open and closing quotes
372                        if ( $ch == $this->enclosure && (!$enclosed || $nch != $this->enclosure) ) {
373                                $enclosed = ( $enclosed ) ? false : true ;
374                                if ( $enclosed ) $was_enclosed = true;
375                       
376                        // inline quotes       
377                        } elseif ( $ch == $this->enclosure && $enclosed ) {
378                                $current .= $ch;
379                                $i++;
380
381                        // end of field/row
382                        } elseif ( ($ch == $this->delimiter || ($ch == "\n" && $pch != "\r") || $ch == "\r") && !$enclosed ) {
383                                if ( !$was_enclosed ) $current = trim($current);
384                                $key = ( !empty($head[$col]) ) ? $head[$col] : $col ;
385                                $row[$key] = $current;
386                                $current = '';
387                                $col++;
388                       
389                                // end of row
390                                if ( $ch == "\n" || $ch == "\r" ) {
391                                        if ( $this->_validate_offset($row_count) && $this->_validate_row_conditions($row, $this->conditions) ) {
392                                                if ( $this->heading && empty($head) ) {
393                                                        $head = $row;
394                                                } elseif ( empty($this->fields) || (!empty($this->fields) && (($this->heading && $row_count > 0) || !$this->heading)) ) {
395                                                        if ( !empty($this->sort_by) && !empty($row[$this->sort_by]) ) {
396                                                                if ( isset($rows[$row[$this->sort_by]]) ) {
397                                                                        $rows[$row[$this->sort_by].'_0'] = &$rows[$row[$this->sort_by]];
398                                                                        unset($rows[$row[$this->sort_by]]);
399                                                                        for ( $sn=1; isset($rows[$row[$this->sort_by].'_'.$sn]); $sn++ ) {}
400                                                                        $rows[$row[$this->sort_by].'_'.$sn] = $row;
401                                                                } else $rows[$row[$this->sort_by]] = $row;
402                                                        } else $rows[] = $row;
403                                                }
404                                        }
405                                        $row = array();
406                                        $col = 0;
407                                        $row_count++;
408                                        if ( $this->sort_by === null && $this->limit !== null && count($rows) == $this->limit ) {
409                                                $i = $strlen;
410                                        }
411                                }
412                               
413                        // append character to current field
414                        } else {
415                                $current .= $ch;
416                        }
417                }
418                $this->titles = $head;
419                if ( !empty($this->sort_by) ) {
420                        ( $this->sort_reverse ) ? krsort($rows) : ksort($rows) ;
421                        if ( $this->offset !== null || $this->limit !== null ) {
422                                $rows = array_slice($rows, ($this->offset === null ? 0 : $this->offset) , $this->limit, true);
423                        }
424                }
425                return $rows;
426        }
427       
428        /**
429         * Create CSV data from array
430         * @param   data        2D array with data
431         * @param   fields      field names
432         * @param   append      if true, field names will not be output
433         * @param   is_php      if a php die() call should be put on the first
434         *                      line of the file, this is later ignored when read.
435         * @param   delimiter   field delimiter to use
436         * @return  CSV data (text string)
437         */
438        function unparse ( $data = array(), $fields = array(), $append = false , $is_php = false, $delimiter = null) {
439                if ( !is_array($data) || empty($data) ) $data = &$this->data;
440                if ( !is_array($fields) || empty($fields) ) $fields = &$this->titles;
441                if ( $delimiter === null ) $delimiter = $this->delimiter;
442               
443                $string = ( $is_php ) ? "<?php header('Status: 403'); die(' '); ?>".$this->linefeed : '' ;
444                $entry = array();
445               
446                // create heading
447                if ( $this->heading && !$append ) {
448                        foreach( $fields as $key => $value ) {
449                                $entry[] = $this->_enclose_value($value);
450                        }
451                        $string .= implode($delimiter, $entry).$this->linefeed;
452                        $entry = array();
453                }
454               
455                // create data
456                foreach( $data as $key => $row ) {
457                        foreach( $row as $field => $value ) {
458                                $entry[] = $this->_enclose_value($value);
459                        }
460                        $string .= implode($delimiter, $entry).$this->linefeed;
461                        $entry = array();
462                }
463               
464                return $string;
465        }
466       
467        /**
468         * Load local file or string
469         * @param   input   local CSV file
470         * @return  true or false
471         */
472        function load_data ($input = null) {
473                $data = null;
474                $file = null;
475                if ( $input === null ) {
476                        $file = $this->file;
477                } elseif ( file_exists($input) ) {
478                        $file = $input;
479                } else {
480                        $data = $input;
481                }
482                if ( !empty($data) || $data = $this->_rfile($file) ) {
483                        if ( $this->file != $file ) $this->file = $file;
484                        if ( preg_match('/\.php$/i', $file) && preg_match('/<\?.*?\?>(.*)/ims', $data, $strip) ) {
485                                $data = ltrim($strip[1]);
486                        }
487                        if ( $this->convert_encoding ) $data = iconv($this->input_encoding, $this->output_encoding, $data);
488                        if ( substr($data, -1) != "\n" ) $data .= "\n";
489                        $this->file_data = &$data;
490                        return true;
491                }
492                return false;
493        }
494       
495       
496        // ==============================================
497        // ----- [ Internal Functions ] -----------------
498        // ==============================================
499       
500        /**
501         * Validate a row against specified conditions
502         * @param   row          array with values from a row
503         * @param   conditions   specified conditions that the row must match
504         * @return  true of false
505         */
506        function _validate_row_conditions ($row = array(), $conditions = null) {
507                if ( !empty($row) ) {
508                        if ( !empty($conditions) ) {
509                                $conditions = (strpos($conditions, ' OR ') !== false) ? explode(' OR ', $conditions) : array($conditions) ;
510                                $or = '';
511                                foreach( $conditions as $key => $value ) {
512                                        if ( strpos($value, ' AND ') !== false ) {
513                                                $value = explode(' AND ', $value);
514                                                $and = '';
515                                                foreach( $value as $k => $v ) {
516                                                        $and .= $this->_validate_row_condition($row, $v);
517                                                }
518                                                $or .= (strpos($and, '0') !== false) ? '0' : '1' ;
519                                        } else {
520                                                $or .= $this->_validate_row_condition($row, $value);
521                                        }
522                                }
523                                return (strpos($or, '1') !== false) ? true : false ;
524                        }
525                        return true;
526                }
527                return false;
528        }
529       
530        /**
531         * Validate a row against a single condition
532         * @param   row          array with values from a row
533         * @param   condition   specified condition that the row must match
534         * @return  true of false
535         */
536        function _validate_row_condition ($row, $condition) {
537                $operators = array(
538                        '=', 'equals', 'is',
539                        '!=', 'is not',
540                        '<', 'is less than',
541                        '>', 'is greater than',
542                        '<=', 'is less than or equals',
543                        '>=', 'is greater than or equals',
544                        'contains',
545                        'does not contain',
546                );
547                $operators_regex = array();
548                foreach( $operators as $value ) {
549                        $operators_regex[] = preg_quote($value, '/');
550                }
551                $operators_regex = implode('|', $operators_regex);
552                if ( preg_match('/^(.+) ('.$operators_regex.') (.+)$/i', trim($condition), $capture) ) {
553                        $field = $capture[1];
554                        $op = $capture[2];
555                        $value = $capture[3];
556                        if ( preg_match('/^([\'\"]{1})(.*)([\'\"]{1})$/i', $value, $capture) ) {
557                                if ( $capture[1] == $capture[3] ) {
558                                        $value = $capture[2];
559                                        $value = str_replace("\\n", "\n", $value);
560                                        $value = str_replace("\\r", "\r", $value);
561                                        $value = str_replace("\\t", "\t", $value);
562                                        $value = stripslashes($value);
563                                }
564                        }
565                        if ( array_key_exists($field, $row) ) {
566                                if ( ($op == '=' || $op == 'equals' || $op == 'is') && $row[$field] == $value ) {
567                                        return '1';
568                                } elseif ( ($op == '!=' || $op == 'is not') && $row[$field] != $value ) {
569                                        return '1';
570                                } elseif ( ($op == '<' || $op == 'is less than' ) && $row[$field] < $value ) {
571                                        return '1';
572                                } elseif ( ($op == '>' || $op == 'is greater than') && $row[$field] > $value ) {
573                                        return '1';
574                                } elseif ( ($op == '<=' || $op == 'is less than or equals' ) && $row[$field] <= $value ) {
575                                        return '1';
576                                } elseif ( ($op == '>=' || $op == 'is greater than or equals') && $row[$field] >= $value ) {
577                                        return '1';
578                                } elseif ( $op == 'contains' && preg_match('/'.preg_quote($value, '/').'/i', $row[$field]) ) {
579                                        return '1';
580                                } elseif ( $op == 'does not contain' && !preg_match('/'.preg_quote($value, '/').'/i', $row[$field]) ) {
581                                        return '1';
582                                } else {
583                                        return '0';
584                                }
585                        }
586                }
587                return '1';
588        }
589       
590        /**
591         * Validates if the row is within the offset or not if sorting is disabled
592         * @param   current_row   the current row number being processed
593         * @return  true of false
594         */
595        function _validate_offset ($current_row) {
596                if ( $this->sort_by === null && $this->offset !== null && $current_row < $this->offset ) return false;
597                return true;
598        }
599       
600        /**
601         * Enclose values if needed
602         *  - only used by unparse()
603         * @param   value   string to process
604         * @return  Processed value
605         */
606        function _enclose_value ($value = null) {
607                if ( $value !== null && $value != '' ) {
608                        $delimiter = preg_quote($this->delimiter, '/');
609                        $enclosure = preg_quote($this->enclosure, '/');
610                        if ( preg_match("/".$delimiter."|".$enclosure."|\n|\r/i", $value) || ($value{0} == ' ' || substr($value, -1) == ' ') ) {
611                                $value = str_replace($this->enclosure, $this->enclosure.$this->enclosure, $value);
612                                $value = $this->enclosure.$value.$this->enclosure;
613                        }
614                }
615                return $value;
616        }
617       
618        /**
619         * Check file data
620         * @param   file   local filename
621         * @return  true or false
622         */
623        function _check_data ($file = null) {
624                if ( empty($this->file_data) ) {
625                        if ( $file === null ) $file = $this->file;
626                        return $this->load_data($file);
627                }
628                return true;
629        }
630       
631       
632        /**
633         * Check if passed info might be delimiter
634         *  - only used by find_delimiter()
635         * @return  special string used for delimiter selection, or false
636         */
637        function _check_count ($char, $array, $depth, $preferred) {
638                if ( $depth == count($array) ) {
639                        $first = null;
640                        $equal = null;
641                        $almost = false;
642                        foreach( $array as $key => $value ) {
643                                if ( $first == null ) {
644                                        $first = $value;
645                                } elseif ( $value == $first && $equal !== false) {
646                                        $equal = true;
647                                } elseif ( $value == $first+1 && $equal !== false ) {
648                                        $equal = true;
649                                        $almost = true;
650                                } else {
651                                        $equal = false;
652                                }
653                        }
654                        if ( $equal ) {
655                                $match = ( $almost ) ? 2 : 1 ;
656                                $pref = strpos($preferred, $char);
657                                $pref = ( $pref !== false ) ? str_pad($pref, 3, '0', STR_PAD_LEFT) : '999' ;
658                                return $pref.$match.'.'.(99999 - str_pad($first, 5, '0', STR_PAD_LEFT));
659                        } else return false;
660                }
661        }
662       
663        /**
664         * Read local file
665         * @param   file   local filename
666         * @return  Data from file, or false on failure
667         */
668        function _rfile ($file = null) {
669                if ( is_readable($file) ) {
670                        if ( !($fh = fopen($file, 'r')) ) return false;
671                        $data = fread($fh, filesize($file));
672                        fclose($fh);
673                        return $data;
674                }
675                return false;
676        }
677
678        /**
679         * Write to local file
680         * @param   file     local filename
681         * @param   string   data to write to file
682         * @param   mode     fopen() mode
683         * @param   lock     flock() mode
684         * @return  true or false
685         */
686        function _wfile ($file, $string = '', $mode = 'wb', $lock = 2) {
687                if ( $fp = fopen($file, $mode) ) {
688                        flock($fp, $lock);
689                        $re = fwrite($fp, $string);
690                        $re2 = fclose($fp);
691                        if ( $re != false && $re2 != false ) return true;
692                }
693                return false;
694        }
695       
696}
697
698?>
Note: See TracBrowser for help on using the browser.
Scanned by Orvant Copyright © 2010 Kreotek, LLC. All Rights reserved.