FunctionAvailabilityCheck   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 0
dl 0
loc 113
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
B isFunctionEnabled() 0 8 5
A isFunctionDefined() 0 4 1
A isFunctionBlacklistedInSuhosin() 0 12 3
A isFunctionBlacklistedInPhpIni() 0 8 2
A isFunctionsMentionedInList() 0 8 2
A prepareList() 0 4 1
1
<?php
2
3
/**
4
 * This file is part of tenside/core.
5
 *
6
 * (c) Christian Schiffler <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * This project is provided in good faith and hope to be usable by anyone.
12
 *
13
 * @package    tenside/core
14
 * @author     Christian Schiffler <[email protected]>
15
 * @copyright  2015 Christian Schiffler <[email protected]>
16
 * @license    https://github.com/tenside/core/blob/master/LICENSE MIT
17
 * @link       https://github.com/tenside/core
18
 * @filesource
19
 */
20
21
namespace Tenside\Core\Util;
22
23
/**
24
 * This class provides methods to check if certain functions have been disabled in PHP or are callable.
25
 */
26
class FunctionAvailabilityCheck
27
{
28
    /**
29
     * Cache.
30
     *
31
     * @var string[]
32
     */
33
    private static $blackListSuhosin;
34
35
    /**
36
     * Cache.
37
     *
38
     * @var string[]
39
     */
40
    private static $blackListPhpIni;
41
42
43
    /**
44
     * Check if function is defined.
45
     *
46
     * @param string      $function  The function to test.
47
     *
48
     * @param string|null $extension The optional name of an php extension providing said function.
49
     *
50
     * @return bool
51
     */
52
    public static function isFunctionEnabled($function, $extension = null)
53
    {
54
        return
55
            (null === $extension || extension_loaded($extension))
56
            && !static::isFunctionBlacklistedInPhpIni($function)
57
            && !static::isFunctionBlacklistedInSuhosin($function)
58
            && static::isFunctionDefined($function);
59
    }
60
61
    /**
62
     * Check if function is defined.
63
     *
64
     * @param string $function The function to test.
65
     *
66
     * @return bool
67
     */
68
    public static function isFunctionDefined($function)
69
    {
70
        return function_exists($function);
71
    }
72
73
    /**
74
     * Check if function is blacklisted in Suhosin.
75
     *
76
     * @param string $function The function to test.
77
     *
78
     * @return bool
79
     */
80
    public static function isFunctionBlacklistedInSuhosin($function)
81
    {
82
        if (!extension_loaded('suhosin')) {
83
            return false;
84
        }
85
86
        if (!isset(self::$blackListSuhosin)) {
87
            self::$blackListSuhosin = static::prepareList(ini_get('suhosin.executor.func.blacklist'));
0 ignored issues
show
Bug introduced by
Since prepareList() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of prepareList() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
88
        }
89
90
        return static::isFunctionsMentionedInList($function, self::$blackListSuhosin);
91
    }
92
93
    /**
94
     * Check if method is blacklisted in Suhosin.
95
     *
96
     * @param string $function The function to test.
97
     *
98
     * @return bool
99
     */
100
    public static function isFunctionBlacklistedInPhpIni($function)
101
    {
102
        if (!isset(self::$blackListPhpIni)) {
103
            self::$blackListPhpIni = static::prepareList(ini_get('disable_functions'));
0 ignored issues
show
Bug introduced by
Since prepareList() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of prepareList() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
104
        }
105
106
        return static::isFunctionsMentionedInList($function, self::$blackListPhpIni);
107
    }
108
109
    /**
110
     * Check if a function is mentioned in the passed (comma separated) list.
111
     *
112
     * @param string   $function The function to test.
113
     *
114
     * @param string[] $list     The function list.
115
     *
116
     * @return bool
117
     */
118
    public static function isFunctionsMentionedInList($function, $list)
119
    {
120
        if (empty($list)) {
121
            return false;
122
        }
123
124
        return (false !== array_search($function, $list));
125
    }
126
127
    /**
128
     * Explode a list.
129
     *
130
     * @param string $list The list.
131
     *
132
     * @return string[]
133
     */
134
    private static function prepareList($list)
135
    {
136
        return array_map('strtolower', array_map('trim', explode(',', $list, -1)));
137
    }
138
}
139