Passed
Push — master ( 51ac1b...cef3f3 )
by Thomas
09:07
created

src/Helpers/FileHelper.php (1 issue)

Severity
1
<?php
2
3
namespace LeKoala\DevToolkit\Helpers;
4
5
use RecursiveIteratorIterator;
6
use RecursiveDirectoryIterator;
7
8
class FileHelper
9
{
10
    /**
11
     * Slightly modified version of http://www.geekality.net/2011/05/28/php-tail-tackling-large-files/
12
     * @author Torleif Berger, Lorenzo Stanco
13
     * @link http://stackoverflow.com/a/15025877/995958
14
     * @license http://creativecommons.org/licenses/by/3.0/
15
     */
16
    public static function tail($filepath, $lines = 1, $adaptive = true)
17
    {
18
        // Open file
19
        $f = @fopen($filepath, "rb");
20
        if ($f === false) {
21
            return false;
22
        }
23
24
        // Sets buffer size, according to the number of lines to retrieve.
25
        // This gives a performance boost when reading a few lines from the file.
26
        if (!$adaptive) {
27
            $buffer = 4096;
28
        } else {
29
            $buffer = ($lines < 2 ? 64 : ($lines < 10 ? 512 : 4096));
30
        }
31
        // Jump to last character
32
        fseek($f, -1, SEEK_END);
33
        // Read it and adjust line number if necessary
34
        // (Otherwise the result would be wrong if file doesn't end with a blank line)
35
        if (fread($f, 1) != "\n") {
36
            $lines -= 1;
37
        }
38
39
        // Start reading
40
        $output = '';
41
        $chunk = '';
0 ignored issues
show
The assignment to $chunk is dead and can be removed.
Loading history...
42
        // While we would like more
43
        while (ftell($f) > 0 && $lines >= 0) {
44
            // Figure out how far back we should jump
45
            $seek = min(ftell($f), $buffer);
46
            // Do the jump (backwards, relative to where we are)
47
            fseek($f, -$seek, SEEK_CUR);
48
            // Read a chunk and prepend it to our output
49
            $output = ($chunk = fread($f, $seek)) . $output;
50
            // Jump back to where we started reading
51
            fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR);
52
            // Decrease our line counter
53
            $lines -= substr_count($chunk, "\n");
54
        }
55
        // While we have too many lines
56
        // (Because of buffer size we might have read too many)
57
        while ($lines++ < 0) {
58
            // Find first newline and remove all text before that
59
            $output = substr($output, strpos($output, "\n") + 1);
60
        }
61
        // Close file and return
62
        fclose($f);
63
        return trim($output);
64
    }
65
66
    /**
67
     * Recursively remove a dir
68
     *
69
     * @param string $dir
70
     * @return bool
71
     */
72
    public static function rmDir($dir)
73
    {
74
        if (!is_dir($dir)) {
75
            return false;
76
        }
77
        $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
78
        $files = new RecursiveIteratorIterator($it, RecursiveIteratorIterator::CHILD_FIRST);
79
        foreach ($files as $file) {
80
            if ($file->isDir()) {
81
                rmdir($file->getRealPath());
82
            } else {
83
                unlink($file->getRealPath());
84
            }
85
        }
86
        return rmdir($dir);
87
    }
88
89
    /**
90
     * Check if a directory contains children
91
     *
92
     * @link https://stackoverflow.com/questions/6786014/php-fastest-way-to-find-if-directory-has-children
93
     * @param string $dir
94
     * @return bool
95
     */
96
    public static function dirContainsChildren($dir)
97
    {
98
        $result = false;
99
        if ($dh = opendir($dir)) {
100
            while (!$result && ($file = readdir($dh)) !== false) {
101
                $result = $file !== "." && $file !== "..";
102
            }
103
            closedir($dh);
104
        }
105
        return $result;
106
    }
107
108
    /**
109
     * @link https://www.digitalocean.com/community/questions/proper-permissions-for-web-server-s-directory
110
     * @param string $dir
111
     * @return bool
112
     */
113
    public static function ensureDir($dir)
114
    {
115
        if (!is_dir($dir)) {
116
            return mkdir($dir, 0755, true);
117
        }
118
        return true;
119
    }
120
121
    /**
122
     * @param int $bytes
123
     * @param integer $decimals
124
     * @return string
125
     */
126
    public static function humanFilesize($bytes, $decimals = 2)
127
    {
128
        if ($bytes < 1024) {
129
            return $bytes . ' B';
130
        }
131
        $factor = floor(log($bytes, 1024));
132
        return sprintf("%.{$decimals}f ", $bytes / pow(1024, $factor)) . ['B', 'KB', 'MB', 'GB', 'TB', 'PB'][$factor];
133
    }
134
}
135