• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PHPOffice / PhpSpreadsheet / 22981566997

12 Mar 2026 12:49AM UTC coverage: 96.844% (-0.06%) from 96.904%
22981566997

Pull #4834

github

web-flow
Merge b0a7099d3 into a1dacfdf7
Pull Request #4834: Add parallel Xlsx writing via pcntl_fork

182 of 218 new or added lines in 6 files covered. (83.49%)

14 existing lines in 1 file now uncovered.

47874 of 49434 relevant lines covered (96.84%)

382.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.93
/src/PhpSpreadsheet/Parallel/CpuDetector.php
1
<?php
2

3
namespace PhpOffice\PhpSpreadsheet\Parallel;
4

5
class CpuDetector
6
{
7
    private static ?int $cachedCount = null;
8

9
    public static function detectCpuCount(): int
9✔
10
    {
11
        if (self::$cachedCount !== null) {
9✔
12
            return self::$cachedCount;
5✔
13
        }
14

15
        self::$cachedCount = static::detect();
5✔
16

17
        return self::$cachedCount;
5✔
18
    }
19

20
    /**
21
     * Reset cached value (for testing).
22
     */
23
    public static function reset(): void
11✔
24
    {
25
        self::$cachedCount = null;
11✔
26
    }
27

28
    protected static function detect(): int
5✔
29
    {
30
        return static::fromPcntl()
5✔
31
            ?? static::fromEnv()
5✔
32
            ?? static::fromProcCpuinfo()
5✔
33
            ?? static::fromSysctl()
5✔
34
            ?? static::fromNproc()
5✔
35
            ?? 2;
5✔
36
    }
37

38
    protected static function fromPcntl(): ?int
5✔
39
    {
40
        if (!function_exists('pcntl_cpu_count')) {
5✔
41
            return null;
5✔
42
        }
43

44
        /** @phpstan-ignore argument.type */
NEW
45
        $result = call_user_func('pcntl_cpu_count');
×
NEW
46
        $count = is_int($result) ? $result : 0;
×
47

NEW
48
        return $count > 0 ? $count : null;
×
49
    }
50

51
    protected static function fromEnv(): ?int
7✔
52
    {
53
        $env = getenv('NUMBER_OF_PROCESSORS');
7✔
54
        if ($env === false) {
7✔
55
            return null;
5✔
56
        }
57

58
        $count = (int) $env;
2✔
59

60
        return $count > 0 ? $count : null;
2✔
61
    }
62

63
    protected static function fromProcCpuinfo(): ?int
5✔
64
    {
65
        if (!is_readable('/proc/cpuinfo')) {
5✔
NEW
66
            return null;
×
67
        }
68

69
        $cpuinfo = @file_get_contents('/proc/cpuinfo');
5✔
70
        if ($cpuinfo === false) {
5✔
NEW
71
            return null;
×
72
        }
73

74
        $count = substr_count($cpuinfo, 'processor');
5✔
75

76
        return $count > 0 ? $count : null;
5✔
77
    }
78

79
    protected static function fromSysctl(): ?int
1✔
80
    {
81
        if (PHP_OS_FAMILY !== 'Darwin') {
1✔
82
            return null;
1✔
83
        }
84

NEW
85
        $result = static::shellExec('sysctl -n hw.logicalcpu 2>/dev/null');
×
NEW
86
        if ($result === null) {
×
NEW
87
            return null;
×
88
        }
89

NEW
90
        $count = (int) trim($result);
×
91

NEW
92
        return $count > 0 ? $count : null;
×
93
    }
94

95
    protected static function fromNproc(): ?int
1✔
96
    {
97
        if (PHP_OS_FAMILY === 'Windows') {
1✔
NEW
98
            return null;
×
99
        }
100

101
        $result = static::shellExec('nproc 2>/dev/null');
1✔
102
        if ($result === null) {
1✔
NEW
103
            return null;
×
104
        }
105

106
        $count = (int) trim($result);
1✔
107

108
        return $count > 0 ? $count : null;
1✔
109
    }
110

111
    protected static function shellExec(string $command): ?string
1✔
112
    {
113
        if (!function_exists('shell_exec')) {
1✔
NEW
114
            return null;
×
115
        }
116

117
        return @shell_exec($command); // @phpstan-ignore return.type
1✔
118
    }
119
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc