Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
 
4
/**
5
 * File
6
 *
7
 * PHP versions 4 and 5
8
 *
9
 * LICENSE: This source file is subject to version 3.0 of the PHP license
10
 * that is available through the world-wide-web at the following URI:
11
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
12
 * the PHP License and are unable to obtain it through the web, please
13
 * send a note to license@php.net so we can mail you a copy immediately.
14
 *
15
 * @category    File
16
 * @package     File
17
 * @author      Richard Heyes <richard@php.net>
18
 * @author      Tal Peer <tal@php.net>
19
 * @author      Michael Wallner <mike@php.net>
20
 * @copyright   2002-2005 The Authors
21
 * @license     http://www.php.net/license/3_0.txt  PHP License 3.0
22
 * @version     CVS: $Id: File.php,v 1.38 2007/03/24 16:38:56 dufuz Exp $
23
 * @link        http://pear.php.net/package/File
24
 */
25
 
26
/**
27
 * Requires PEAR
28
 */
29
require_once 'PEAR.php';
30
 
31
/**
32
 * The default number of bytes for reading
33
 */
34
if (!defined('FILE_DEFAULT_READSIZE')) {
35
    define('FILE_DEFAULT_READSIZE', 1024, true);
36
}
37
 
38
/**
39
 * The maximum number of bytes for reading lines
40
 */
41
if (!defined('FILE_MAX_LINE_READSIZE')) {
42
    define('FILE_MAX_LINE_READSIZE', 40960, true);
43
}
44
 
45
/**
46
 * Whether file locks should block
47
 */
48
if (!defined('FILE_LOCKS_BLOCK')) {
49
    define('FILE_LOCKS_BLOCK', true, true);
50
}
51
 
52
/**
53
 * Mode to use for reading from files
54
 */
55
define('FILE_MODE_READ', 'rb', true);
56
 
57
/**
58
 * Mode to use for truncating files, then writing
59
 */
60
define('FILE_MODE_WRITE', 'wb', true);
61
 
62
/**
63
 * Mode to use for appending to files
64
 */
65
define('FILE_MODE_APPEND', 'ab', true);
66
 
67
/**
68
 * Use this when a shared (read) lock is required
69
 */
70
define('FILE_LOCK_SHARED', LOCK_SH | (FILE_LOCKS_BLOCK ? 0 : LOCK_NB), true);
71
 
72
/**
73
 * Use this when an exclusive (write) lock is required
74
 */
75
define('FILE_LOCK_EXCLUSIVE', LOCK_EX | (FILE_LOCKS_BLOCK ? 0 : LOCK_NB), true);
76
 
77
/**
78
 * Class for handling files
79
 *
80
 * A class with common functions for writing,
81
 * reading and handling files and directories
82
 *
83
 * @author  Richard Heyes <richard@php.net>
84
 * @author  Tal Peer <tal@php.net>
85
 * @author  Michael Wallner <mike@php.net>
86
 * @access  public
87
 * @package File
88
 *
89
 * @static
90
 */
91
class File extends PEAR
92
{
93
    /**
94
     * Destructor
95
     *
96
     * Unlocks any locked file pointers and closes all filepointers
97
     *
98
     * @access private
99
     */
100
    function _File()
101
    {
102
        File::closeAll();
103
    }
104
 
105
    /**
106
     * Handles file pointers. If a file pointer needs to be opened,
107
     * it will be. If it already exists (based on filename and mode)
108
     * then the existing one will be returned.
109
     *
110
     * @access  private
111
     * @param   string  $filename Filename to be used
112
     * @param   string  $mode Mode to open the file in
113
     * @param   mixed   $lock Type of lock to use
114
     * @return  mixed   PEAR_Error on error or file pointer resource on success
115
     */
116
    function _getFilePointer($filename, $mode, $lock = false)
117
    {
118
        $filePointers = &PEAR::getStaticProperty('File', 'filePointers');
119
 
120
        // Win32 is case-insensitive
121
        if (OS_WINDOWS) {
122
            $filename = strtolower($filename);
123
        }
124
 
125
        // check if file pointer already exists
126
        if (!isset($filePointers[$filename][$mode]) ||
127
            !is_resource($filePointers[$filename][$mode])) {
128
 
129
            // check if we can open the file in the desired mode
130
            switch ($mode)
131
            {
132
                case FILE_MODE_READ:
133
                    if (!preg_match('/^.+(?<!file):\/\//i', $filename) &&
134
                        !file_exists($filename)) {
135
                        return PEAR::raiseError("File does not exist: $filename");
136
                    }
137
                break;
138
 
139
                case FILE_MODE_APPEND:
140
                case FILE_MODE_WRITE:
141
                    if (file_exists($filename)) {
142
                        if (!is_writable($filename)) {
143
                            return PEAR::raiseError("File is not writable: $filename");
144
                        }
145
                    } elseif (!is_writable($dir = dirname($filename))) {
146
                        return PEAR::raiseError("Cannot create file in directory: $dir");
147
                    }
148
                break;
149
 
150
                default:
151
                    return PEAR::raiseError("Invalid access mode: $mode");
152
            }
153
 
154
            // open file
155
            $filePointers[$filename][$mode] = @fopen($filename, $mode);
156
            if (!is_resource($filePointers[$filename][$mode])) {
157
                return PEAR::raiseError('Failed to open file: ' . $filename);
158
            }
159
        }
160
 
161
        // lock file
162
        if ($lock) {
163
            $lock = $mode == FILE_MODE_READ ? FILE_LOCK_SHARED : FILE_LOCK_EXCLUSIVE;
164
            $locks = &PEAR::getStaticProperty('File', 'locks');
165
            if (@flock($filePointers[$filename][$mode], $lock)) {
166
                $locks[] = &$filePointers[$filename][$mode];
167
            } elseif (FILE_LOCKS_BLOCK) {
168
                return PEAR::raiseError("File already locked: $filename");
169
            } else {
170
                return PEAR::raiseError("Could not lock file: $filename");
171
            }
172
        }
173
 
174
        return $filePointers[$filename][$mode];
175
    }
176
 
177
    /**
178
     * Reads an entire file and returns it.
179
     * Uses file_get_contents if available.
180
     *
181
     * @access  public
182
     * @param   string  $filename Name of file to read from
183
     * @param   mixed   $lock Type of lock to use
184
     * @return  mixed   PEAR_Error if an error has occured or a string with the contents of the the file
185
     */
186
    function readAll($filename, $lock = false)
187
    {
188
        if (false === $file = @file_get_contents($filename)) {
189
            return PEAR::raiseError("Cannot read file: $filename");
190
        }
191
        return $file;
192
    }
193
 
194
    /**
195
     * Returns a specified number of bytes of a file.
196
     * Defaults to FILE_DEFAULT_READSIZE.  If $size is 0, all file will be read.
197
     *
198
     * @access  public
199
     * @param   string  $filename Name of file to read from
200
     * @param   integer $size Bytes to read
201
     * @param   mixed   $lock Type of lock to use
202
     * @return  mixed   PEAR_Error on error or a string which contains the data read
203
     *                  Will also return false upon EOF
204
     */
205
    function read($filename, $size = FILE_DEFAULT_READSIZE, $lock = false)
206
    {
207
        static $filePointers;
208
 
209
        if ($size == 0) {
210
            return File::readAll($filename, $lock);
211
        }
212
 
213
        if (!isset($filePointers[$filename]) ||
214
            !is_resource($filePointers[$filename])) {
215
            $fp = File::_getFilePointer($filename, FILE_MODE_READ, $lock);
216
            if (PEAR::isError($fp)) {
217
                return $fp;
218
            }
219
 
220
            $filePointers[$filename] = $fp;
221
        } else {
222
            $fp = $filePointers[$filename];
223
        }
224
 
225
        return !feof($fp) ? fread($fp, $size) : false;
226
    }
227
 
228
    /**
229
     * Writes the given data to the given filename.
230
     * Defaults to no lock, append mode.
231
     *
232
     * @access  public
233
     * @param   string  $filename Name of file to write to
234
     * @param   string  $data Data to write to file
235
     * @param   string  $mode Mode to open file in
236
     * @param   mixed   $lock Type of lock to use
237
     * @return  mixed   PEAR_Error on error or number of bytes written to file.
238
     */
239
    function write($filename, $data, $mode = FILE_MODE_APPEND, $lock = false)
240
    {
241
        $fp = File::_getFilePointer($filename, $mode, $lock);
242
        if (PEAR::isError($fp)) {
243
            return $fp;
244
        }
245
 
246
        if (false === $bytes = @fwrite($fp, $data, strlen($data))) {
247
            return PEAR::raiseError("Cannot write data: '$data' to file: '$filename'");
248
        }
249
 
250
        return $bytes;
251
    }
252
 
253
    /**
254
     * Reads and returns a single character from given filename
255
     *
256
     * @access  public
257
     * @param   string  $filename Name of file to read from
258
     * @param   mixed   $lock Type of lock to use
259
     * @return  mixed   PEAR_Error on error or one character of the specified file
260
     */
261
    function readChar($filename, $lock = false)
262
    {
263
        return File::read($filename, 1, $lock);
264
    }
265
 
266
    /**
267
     * Writes a single character to a file
268
     *
269
     * @access  public
270
     * @param   string  $filename Name of file to write to
271
     * @param   string  $char Character to write
272
     * @param   string  $mode Mode to use when writing
273
     * @param   mixed   $lock Type of lock to use
274
     * @return  mixed   PEAR_Error on error, or 1 on success
275
     */
276
    function writeChar($filename, $char, $mode = FILE_MODE_APPEND, $lock = false)
277
    {
278
        $fp = File::_getFilePointer($filename, $mode, $lock);
279
        if (PEAR::isError($fp)) {
280
            return $fp;
281
        }
282
 
283
        if (false === @fwrite($fp, $char, 1)) {
284
            return PEAR::raiseError("Cannot write data: '$data' to file: '$filename'");
285
        }
286
 
287
        return 1;
288
    }
289
 
290
    /**
291
     * Returns a line of the file (without trailing CRLF).
292
     * Maximum read line length is FILE_MAX_LINE_READSIZE.
293
     *
294
     * @access  public
295
     * @param   string  $filename Name of file to read from
296
     * @param   boolean $lock Whether file should be locked
297
     * @return  mixed   PEAR_Error on error or a string containing the line read from file
298
     */
299
    function readLine($filename, $lock = false)
300
    {
301
        static $filePointers; // Used to prevent unnecessary calls to _getFilePointer()
302
 
303
        if (!isset($filePointers[$filename]) ||
304
            !is_resource($filePointers[$filename])) {
305
            $fp = File::_getFilePointer($filename, FILE_MODE_READ, $lock);
306
            if (PEAR::isError($fp)) {
307
                return $fp;
308
            }
309
 
310
            $filePointers[$filename] = $fp;
311
        } else {
312
            $fp = $filePointers[$filename];
313
        }
314
 
315
        if (feof($fp)) {
316
            return false;
317
        }
318
 
319
        return rtrim(fgets($fp, FILE_MAX_LINE_READSIZE), "\r\n");
320
    }
321
 
322
    /**
323
     * Writes a single line, appending a LF (by default)
324
     *
325
     * @access  public
326
     * @param   string  $filename Name of file to write to
327
     * @param   string  $line Line of data to be written to file
328
     * @param   string  $mode Write mode, can be either FILE_MODE_WRITE or FILE_MODE_APPEND
329
     * @param   string  $crlf The CRLF your system is using. UNIX = \n Windows = \r\n Mac = \r
330
     * @param   mixed   $lock Whether to lock the file
331
     * @return  mixed   PEAR_Error on error or number of bytes written to file (including appended crlf)
332
     */
333
    function writeLine($filename, $line, $mode = FILE_MODE_APPEND, $crlf = "\n", $lock = false)
334
    {
335
        $fp = File::_getFilePointer($filename, $mode, $lock);
336
        if (PEAR::isError($fp)) {
337
            return $fp;
338
        }
339
 
340
        if (false === $bytes = fwrite($fp, $line . $crlf)) {
341
            return PEAR::raiseError("Cannot write data: '$data' to file: '$file'");
342
        }
343
 
344
        return $bytes;
345
    }
346
 
347
    /**
348
     * This rewinds a filepointer to the start of a file
349
     *
350
     * @access  public
351
     * @param   string  $filename The filename
352
     * @param   string  $mode Mode the file was opened in
353
     * @return  mixed   PEAR Error on error, true on success
354
     */
355
    function rewind($filename, $mode)
356
    {
357
        $fp = File::_getFilePointer($filename, $mode);
358
        if (PEAR::isError($fp)) {
359
            return $fp;
360
        }
361
 
362
        if (!@rewind($fp)) {
363
            return PEAR::raiseError("Cannot rewind file: $filename");
364
        }
365
 
366
        return true;
367
    }
368
 
369
    /**
370
     * Closes all open file pointers
371
     *
372
     * @access  public
373
     * @return  void
374
     */
375
    function closeAll()
376
    {
377
        $locks = &PEAR::getStaticProperty('File', 'locks');
378
        $filePointers = &PEAR::getStaticProperty('File', 'filePointers');
379
 
380
        // unlock files
381
        for ($i = 0, $c = count($locks); $i < $c; $i++) {
382
            is_resource($locks[$i]) and @flock($locks[$i], LOCK_UN);
383
        }
384
 
385
        // close files
386
        if (!empty($filePointers)) {
387
            foreach ($filePointers as $fname => $modes) {
388
                foreach (array_keys($modes) as $mode) {
389
                    if (is_resource($filePointers[$fname][$mode])) {
390
                        @fclose($filePointers[$fname][$mode]);
391
                    }
392
                    unset($filePointers[$fname][$mode]);
393
                }
394
            }
395
        }
396
    }
397
 
398
    /**
399
     * This closes an open file pointer
400
     *
401
     * @access  public
402
     * @param   string  $filename The filename that was opened
403
     * @param   string  $mode Mode the file was opened in
404
     * @return  mixed   PEAR Error on error, true otherwise
405
     */
406
    function close($filename, $mode)
407
    {
408
        $filePointers = &PEAR::getStaticProperty('File', 'filePointers');
409
 
410
        if (OS_WINDOWS) {
411
            $filename = strToLower($filename);
412
        }
413
 
414
        if (!isset($filePointers[$filename][$mode])) {
415
            return true;
416
        }
417
 
418
        $fp = $filePointers[$filename][$mode];
419
        unset($filePointers[$filename][$mode]);
420
 
421
        if (is_resource($fp)) {
422
            // unlock file
423
            @flock($fp, LOCK_UN);
424
            // close file
425
            if (!@fclose($fp)) {
426
                return PEAR::raiseError("Cannot close file: $filename");
427
            }
428
        }
429
 
430
        return true;
431
    }
432
 
433
    /**
434
     * This unlocks a locked file pointer.
435
     *
436
     * @access  public
437
     * @param   string  $filename The filename that was opened
438
     * @param   string  $mode Mode the file was opened in
439
     * @return  mixed   PEAR Error on error, true otherwise
440
     */
441
    function unlock($filename, $mode)
442
    {
443
        $fp = File::_getFilePointer($filename, $mode);
444
        if (PEAR::isError($fp)) {
445
            return $fp;
446
        }
447
 
448
        if (!@flock($fp, LOCK_UN)) {
449
            return PEAR::raiseError("Cacnnot unlock file: $filename");
450
        }
451
 
452
        return true;
453
    }
454
 
455
    /**
456
     * @deprecated
457
     */
458
    function stripTrailingSeparators($path, $separator = DIRECTORY_SEPARATOR)
459
    {
460
        if ($path === $separator) {
461
            return $path;
462
        }
463
        return rtrim($path, $separator);
464
    }
465
 
466
    /**
467
     * @deprecated
468
     */
469
    function stripLeadingSeparators($path, $separator = DIRECTORY_SEPARATOR)
470
    {
471
        if ($path === $separator) {
472
            return $path;
473
        }
474
        return ltrim($path, $separator);
475
    }
476
 
477
    /**
478
     * @deprecated Use File_Util::buildPath() instead.
479
     */
480
    function buildPath($parts, $separator = DIRECTORY_SEPARATOR)
481
    {
482
        require_once 'File/Util.php';
483
        return File_Util::buildPath($parts, $separator);
484
    }
485
 
486
    /**
487
     * @deprecated Use File_Util::skipRoot() instead.
488
     */
489
    function skipRoot($path)
490
    {
491
        require_once 'File/Util.php';
492
        return File_Util::skipRoot($path);
493
    }
494
 
495
    /**
496
     * @deprecated Use File_Util::tmpDir() instead.
497
     */
498
    function getTempDir()
499
    {
500
        require_once 'File/Util.php';
501
        return File_Util::tmpDir();
502
    }
503
 
504
    /**
505
     * @deprecated Use File_Util::tmpFile() instead.
506
     */
507
    function getTempFile($dirname = null)
508
    {
509
        require_once 'File/Util.php';
510
        return File_Util::tmpFile($dirname);
511
    }
512
 
513
    /**
514
     * @deprecated Use File_Util::isAbsolute() instead.
515
     */
516
    function isAbsolute($path)
517
    {
518
        require_once 'File/Util.php';
519
        return File_Util::isAbsolute($path);
520
    }
521
 
522
    /**
523
     * @deprecated Use File_Util::relativePath() instead.
524
     */
525
    function relativePath($path, $root, $separator = DIRECTORY_SEPARATOR)
526
    {
527
        require_once 'File/Util.php';
528
        return File_Util::relativePath($path, $root, $separator);
529
    }
530
 
531
    /**
532
     * @deprecated Use File_Util::realpath() instead.
533
     */
534
    function realpath($path, $separator = DIRECTORY_SEPARATOR)
535
    {
536
        require_once 'File/Util.php';
537
        return File_Util::realpath($path, $separator);
538
    }
539
}
540
 
541
PEAR::registerShutdownFunc(array('File', '_File'));
542
 
543
?>