Passed
Pull Request — 1.x (#334)
by Akihito
02:26
created

XHProfResult::stop()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 4
eloc 11
c 1
b 0
f 1
nc 3
nop 1
dl 0
loc 19
rs 9.9
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Resource\SemanticLog\Profile;
6
7
use JsonSerializable;
8
use Override;
9
10
use function file_put_contents;
11
use function function_exists;
12
use function serialize;
13
use function sprintf;
14
use function str_replace;
15
use function sys_get_temp_dir;
16
use function uniqid;
17
use function xhprof_disable;
18
use function xhprof_enable;
19
20
use const XHPROF_FLAGS_CPU;
21
use const XHPROF_FLAGS_MEMORY;
22
use const XHPROF_FLAGS_NO_BUILTINS;
23
24
final class XHProfResult implements JsonSerializable
25
{
26
    private ?string $profileId = null;
27
28
    public function __construct(
29
        public readonly ?string $file = null,
30
    ) {
31
    }
32
33
    public static function start(): self
34
    {
35
        if (! function_exists('xhprof_enable')) {
36
            return new self(); // @codeCoverageIgnore
37
        }
38
39
        /** @psalm-suppress UndefinedConstant, MixedArgument */
40
        xhprof_enable(XHPROF_FLAGS_NO_BUILTINS | XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY);
41
42
        $instance = new self();
43
        $instance->profileId = uniqid('xhprof_', true);
44
45
        return $instance;
46
    }
47
48
    public function stop(string $uri): self
49
    {
50
        if ($this->profileId === null || ! function_exists('xhprof_disable')) {
51
            return new self(); // @codeCoverageIgnore
52
        }
53
54
        $xhprofData = xhprof_disable();
55
        $filename = sprintf(
56
            '%s/xhprof_%s_%s.xhprof',
57
            sys_get_temp_dir(),
58
            str_replace(['/', ':', '?'], '_', $uri),
59
            $this->profileId,
60
        );
61
62
        if (file_put_contents($filename, serialize($xhprofData)) === false) {
63
            return new self(); // @codeCoverageIgnore
64
        }
65
66
        return new self($filename);
67
    }
68
69
    /** @return array<string, mixed> */
70
    #[Override]
71
    public function jsonSerialize(): array
72
    {
73
        if ($this->file === null) {
74
            return [];
75
        }
76
77
        return ['file' => $this->file];
78
    }
79
}
80