GetPrintableType::getPrintableType()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright (c) 2016-present Ganbaro Digital Ltd
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 *   * Redistributions of source code must retain the above copyright
12
 *     notice, this list of conditions and the following disclaimer.
13
 *
14
 *   * Redistributions in binary form must reproduce the above copyright
15
 *     notice, this list of conditions and the following disclaimer in
16
 *     the documentation and/or other materials provided with the
17
 *     distribution.
18
 *
19
 *   * Neither the names of the copyright holders nor the names of his
20
 *     contributors may be used to endorse or promote products derived
21
 *     from this software without specific prior written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
 * POSSIBILITY OF SUCH DAMAGE.
35
 *
36
 * @category  Libraries
37
 * @package   MissingBits/Types
38
 * @author    Stuart Herbert <[email protected]>
39
 * @copyright 2015-present Ganbaro Digital Ltd www.ganbarodigital.com
40
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
41
 * @link      http://ganbarodigital.github.io/php-the-missing-bits
42
 */
43
44
namespace GanbaroDigital\MissingBits\TypeInspectors;
45
46
use Closure;
47
48
/**
49
 * GetPrintableType will tell you the PHP data type of any given input data.
50
 */
51
class GetPrintableType
52
{
53
    /**
54
     * use this flag for minimum output
55
     * @var int
56
     */
57
    const FLAG_NONE = 0;
58
59
    /**
60
     * use this flag to see classnames in the return value
61
     * @var int
62
     */
63
    const FLAG_CLASSNAME = 1;
64
65
    /**
66
     * use this flag to see what kind of callable `$item` is
67
     * @var int
68
     */
69
    const FLAG_CALLABLE_DETAILS = 2;
70
71
    /**
72
     * use this flag to see the value of `$item`
73
     * @var int
74
     */
75
    const FLAG_SCALAR_VALUE = 4;
76
77
    /**
78
     * current maximum possible value for `$flags`
79
     * @var int
80
     */
81
    const FLAG_MAX_VALUE = 7;
82
83
    /**
84
     * default value for `$flags` if you don't provide one
85
     * @var int
86
     */
87
    const FLAG_DEFAULTS = 7;
88
89
    /**
90
     * what PHP type is $item?
91
     *
92
     * @param  mixed $item
93
     *         the data to examine
94
     * @param  int $flags
95
     *         options to change what we put in the return value
96
     * @return string
97
     *         the data type of $item
98
     */
99
    public function getPrintableType($item, $flags = self::FLAG_DEFAULTS)
0 ignored issues
show
Coding Style Best Practice introduced by
Please use __construct() instead of a PHP4-style constructor that is named after the class.
Loading history...
100
    {
101
        return self::of($item, $flags);
102
    }
103
104
    /**
105
     * what PHP type is $item?
106
     *
107
     * @param  mixed $item
108
     *         the data to examine
109
     * @param  int $flags
110
     *         options to change what we put in the return value
111
     * @return string
112
     *         the data type of $item
113
     */
114
    public static function of($item, $flags = self::FLAG_DEFAULTS)
115
    {
116
        // make sure we have a usable set of flags
117
        if (!is_int($flags)) {
118
            $flags = self::FLAG_DEFAULTS;
119
        }
120
        if ($flags < 0 || $flags > self::FLAG_MAX_VALUE) {
121
            $flags = self::FLAG_DEFAULTS;
122
        }
123
124
        if (is_object($item)) {
125
            return self::returnObjectType($item, $flags);
126
        }
127
128
        if (is_callable($item)) {
129
            return self::returnCallableType($item, $flags);
130
        }
131
132
        if (is_scalar($item)) {
133
            return self::returnScalarType($item, $flags);
134
        }
135
136
        return gettype($item);
137
    }
138
139
    /**
140
     * extract the details about a PHP callable array
141
     *
142
     * @param  array|string $item
143
     *         the callable() to examine
144
     * @param  int $flags
145
     *         options to change what we put in the return value
146
     * @return string
147
     *         the data type of $item
148
     */
149
    private static function returnCallableType($item, $flags)
150
    {
151
        // user doesn't want the details
152
        if (!($flags & self::FLAG_CALLABLE_DETAILS)) {
153
            return "callable";
154
        }
155
156
        // $item may contain the name of a function
157
        if (!is_array($item)) {
158
            return "callable<" . $item . ">";
159
        }
160
161
        // $item may contain a <classname, method> pair
162
        if (is_string($item[0])) {
163
            return "callable<" . $item[0] . "::" . $item[1] . ">";
164
        }
165
166
        // $item contains an <object, method> pair
167
        return "callable<" . get_class($item[0]). "::" . $item[1] . ">";
168
    }
169
170
    /**
171
     * turn a PHP object into the underlying PHP data type
172
     *
173
     * @param  object $item
174
     *         the data to inspect
175
     * @param  int $flags
176
     *         options to change what we put in the return value
177
     * @return string
178
     *         the data type of $item
179
     */
180
    private static function returnObjectType($item, $flags)
181
    {
182
        // special case - PHP Closure objects
183
        if ($item instanceof Closure) {
184
            return 'callable';
185
        }
186
187
        // does the caller want to know what kind of object?
188
        if ($flags & self::FLAG_CLASSNAME) {
189
            return 'object<' . get_class($item) . '>';
190
        }
191
192
        // if we get here, then a plain 'object' will suffice
193
        return "object";
194
    }
195
196
    /**
197
     * extract the details about a PHP scalar value
198
     *
199
     * @param  bool|float|int|string $item
200
     *         the data to examine
201
     * @param  int $flags
202
     *         options to change what we put in the return value
203
     * @return string
204
     *         the data type of $item
205
     */
206
    private static function returnScalarType($item, $flags)
207
    {
208
        // what do we have?
209
        $prefix = gettype($item);
210
211
        // user doesn't want the details
212
        if (!($flags & self::FLAG_SCALAR_VALUE)) {
213
            return $prefix;
214
        }
215
216
        // special case - boolean values
217
        if (is_bool($item)) {
218
            if ($item) {
219
                return $prefix . "<true>";
220
            }
221
            return $prefix . "<false>";
222
        }
223
224
        // general case
225
        return $prefix . "<{$item}>";
226
    }
227
}
228