Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
53 / 53
100.00% covered (success)
100.00%
13 / 13
CRAP
100.00% covered (success)
100.00%
1 / 1
MemoryHandler
100.00% covered (success)
100.00%
53 / 53
100.00% covered (success)
100.00%
13 / 13
26
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getLimit
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 updateMemoryUsage
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 hasUsages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUsages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 updatePeakMemoryUsage
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 hasPeakUsages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPeakUsages
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 prepare
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
3
 prepareHeaderAsString
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 prepareAsString
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
3
 formatMemoryToString
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
6
 formatMemoryToInt
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Debug\Handler;
15
16/**
17 * Debug memory handler class
18 *
19 * @category   Pop
20 * @package    Pop\Debug
21 * @author     Nick Sagona, III <dev@nolainteractive.com>
22 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
23 * @license    http://www.popphp.org/license     New BSD License
24 * @version    2.0.0
25 */
26class MemoryHandler extends AbstractHandler
27{
28
29    /**
30     * Memory limit
31     * @var int
32     */
33    protected int $limit = 0;
34
35    /**
36     * Memory usage snapshots
37     * @var array
38     */
39    protected array $usages = [];
40
41    /**
42     * Peak memory usage snapshots
43     * @var array
44     */
45    protected array $peaks = [];
46
47    /**
48     * Constructor
49     *
50     * Instantiate a memory handler object
51     *
52     * @param  ?string $name
53     */
54    public function __construct(?string $name = null)
55    {
56        parent::__construct($name);
57        $this->limit = $this->formatMemoryToInt(ini_get('memory_limit'));
58    }
59
60    /**
61     * Get memory limit
62     *
63     * @return int
64     */
65    public function getLimit(): int
66    {
67        return $this->limit;
68    }
69
70    /**
71     * Take a memory usage snapshot
72     *
73     * @param  bool $real
74     * @return MemoryHandler
75     */
76    public function updateMemoryUsage(bool $real = false): MemoryHandler
77    {
78        $this->usages[(string)microtime(true)] = memory_get_usage($real);
79        return $this;
80    }
81
82    /**
83     * Determine if the handler has memory usages snapshots
84     *
85     * @return bool
86     */
87    public function hasUsages(): bool
88    {
89        return (count($this->usages) > 0);
90    }
91
92    /**
93     * Get memory usages snapshots
94     *
95     * @return array
96     */
97    public function getUsages(): array
98    {
99        return $this->usages;
100    }
101
102    /**
103     * Take a peak memory usage snapshot
104     *
105     * @param  bool $real
106     * @return MemoryHandler
107     */
108    public function updatePeakMemoryUsage(bool $real = false): MemoryHandler
109    {
110        $this->peaks[(string)microtime(true)] = memory_get_peak_usage($real);
111        return $this;
112    }
113
114    /**
115     * Determine if the handler has peak memory usages snapshots
116     *
117     * @return bool
118     */
119    public function hasPeakUsages(): bool
120    {
121        return (count($this->peaks) > 0);
122    }
123
124    /**
125     * Get peak memory usages snapshots
126     *
127     * @return array
128     */
129    public function getPeakUsages(): array
130    {
131        return $this->peaks;
132    }
133
134    /**
135     * Prepare handler data for storage
136     *
137     * @return array
138     */
139    public function prepare(): array
140    {
141        $data = [
142            'limit'  => $this->formatMemoryToString($this->limit),
143            'usages' => [],
144            'peaks'  => []
145        ];
146
147        foreach ($this->usages as $time => $usage) {
148            $data['usages'][number_format($time, 5, '.', '')] = $this->formatMemoryToString($usage);
149        }
150
151        foreach ($this->peaks as $time => $peak) {
152            $data['peaks'][number_format($time, 5, '.', '')] = $this->formatMemoryToString($peak);
153        }
154
155        return $data;
156    }
157
158    /**
159     * Prepare header string
160     *
161     * @return string
162     */
163    public function prepareHeaderAsString(): string
164    {
165        $string  = ((!empty($this->name)) ? $this->name . ' ' : '') . 'Memory Handler';
166        $string .= PHP_EOL . str_repeat('=', strlen($string)) . PHP_EOL;
167
168        return $string;
169    }
170
171    /**
172     * Prepare handler data as string
173     *
174     * @return string
175     */
176    public function prepareAsString(): string
177    {
178        $string  = "Limit:\t\t\t" . $this->formatMemoryToString($this->limit) . PHP_EOL . PHP_EOL;
179
180        $string .= "Usages:" . PHP_EOL;
181        $string .= "-------" . PHP_EOL;
182        foreach ($this->usages as $time => $usage) {
183            $string .= number_format($time, 5, '.', '') . "\t" . $this->formatMemoryToString($usage) . PHP_EOL;
184        }
185        $string .= PHP_EOL;
186
187        $string .= "Peaks:" . PHP_EOL;
188        $string .= "------" . PHP_EOL;
189        foreach ($this->peaks as $time => $peak) {
190            $string .= number_format($time, 5, '.', '') . "\t" . $this->formatMemoryToString($peak) . PHP_EOL;
191        }
192        $string .= PHP_EOL;
193
194        return $string;
195    }
196
197    /**
198     * Format memory amount into readable string
199     *
200     * @param  int|string $memory
201     * @param  int $bytes
202     * @return string
203     */
204    public function formatMemoryToString(int|string $memory, int $bytes = 1024): string
205    {
206        if ($memory >= pow($bytes, 3)) {
207            $memory = round(($memory / pow($bytes, 3)), 2) . 'GB';
208        } else if ($memory >= pow($bytes, 2)) {
209            $memory = round(($memory / pow($bytes, 2)), 2) . 'MB';
210        } else if (($memory < pow($bytes, 2)) && ($memory >= $bytes)) {
211            $memory = round(($memory / $bytes), 2) . 'KB';
212        } else if ($memory < $bytes) {
213            $memory = $memory . 'B';
214        }
215
216        return $memory;
217    }
218
219    /**
220     * Format memory amount into integer
221     *
222     * @param  int|string $memory
223     * @param  int $bytes
224     * @return int
225     */
226    public function formatMemoryToInt(int|string $memory, int $bytes = 1024): int
227    {
228        $factor = 1;
229
230        if (stripos($memory, 'G') !== false) {
231            $factor = pow($bytes, 3);
232        } else if (stripos($memory, 'M') !== false) {
233            $factor = pow($bytes, 2);
234        } else if (stripos($memory, 'K') !== false) {
235            $factor = $bytes;
236        }
237
238        return (int)$memory * $factor;
239    }
240
241}