Passed
Push — master ( 28ea87...37d3cb )
by kill
02:19
created

function.php ➔ array_map_recursive()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 2
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
use puck\Container;
3
4
/**
5
 * 获取客户端IP地址
6
 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
7
 * @param boolean $adv 是否进行高级模式获取(有可能被伪装)
8
 * @return mixed
9
 */
10
function get_client_ip($type=0, $adv=true)
0 ignored issues
show
Coding Style introduced by
get_client_ip uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
11
{
12
    $type=$type ? 1 : 0;
13
    static $ip=null;
14
    if (null !== $ip) {
15
        return $ip[$type];
16
    }
17
    if ($adv) {
18
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
19
            $arr=explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
20
            $pos=array_search('unknown', $arr);
21
            if (false !== $pos) {
22
                unset($arr[$pos]);
23
            }
24
            $ip=trim($arr[0]);
25
        } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
26
            $ip=$_SERVER['HTTP_CLIENT_IP'];
27
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
28
            $ip=$_SERVER['REMOTE_ADDR'];
29
        }
30
    } elseif (isset($_SERVER['REMOTE_ADDR'])) {
31
        $ip=$_SERVER['REMOTE_ADDR'];
32
    }
33
    // IP地址合法验证
34
    $long=sprintf("%u", ip2long($ip));
35
    $ip=$long ? array($ip, $long) : array('0.0.0.0', 0);
36
    return $ip[$type];
37
}
38
//2为直接输出数组
39
function show_json(array $arr, $type=2)
40
{
41
42
    if (isset($arr['status']) && $type == 2) {
43
        $ret=$arr;
44
    }
45
    else {
46
        $ret['status']=$type;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$ret was never initialized. Although not strictly required by PHP, it is generally a good practice to add $ret = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
47
        $ret['data']=$arr;
48
    }
49
50
    $obj=json_encode($ret);
51
    header('Content-Type: application/json');
52
    echo $obj;
53
    exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The function show_json() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
54
}
55
56
function success($arr)
57
{
58
    show_json($arr, 1);
59
}
60
61
function error($arr)
62
{
63
    show_json($arr, 0);
64
}
65
function not_found($str='page not found,that is all we know!') {
66
    header('HTTP/1.1 404 Not Found');
67
    header("status: 404 Not Found");
68
    exit($str);
0 ignored issues
show
Coding Style Compatibility introduced by
The function not_found() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
69
}
70
71
72
/**
73
 * 数据签名认证
74
 * @param  array  $data 被认证的数据
75
 * @return string       签名
76
 * @author 麦当苗儿 <[email protected]>
77
 */
78
function data_auth_sign($data) {
79
    //数据类型检测
80
81
    if (!is_array($data)) {
82
83
        $data=(array) $data;
84
    }
85
    ksort($data); //排序
86
    $code=http_build_query($data); //url编码并生成query字符串
87
    $sign=sha1($code); //生成签名
88
    return $sign;
89
}
90
/**
91
 * session管理函数
92
 * @param string $name session名称 如果为数组则表示进行session设置
93
 * @param mixed $value session值
94
 * @return mixed
95
 */
96
function session($name='', $value='') {
0 ignored issues
show
Coding Style introduced by
session uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
97
    if (is_array($name)) {
98
99
        if (isset($name['id'])) {
100
            session_id($name['id']);
101
        }
102
103
        if (isset($name['name'])) {
104
            session_name($name['name']);
105
        }
106
107
        if (isset($name['path'])) {
108
            session_save_path($name['path']);
109
        }
110
111
        if (isset($name['domain'])) {
112
            ini_set('session.cookie_domain', $name['domain']);
113
        }
114
115
        if (isset($name['expire'])) {
116
            ini_set('session.gc_maxlifetime', $name['expire']);
117
            ini_set('session.cookie_lifetime', $name['expire']);
118
        }
119
        if (isset($name['use_trans_sid'])) {
120
            ini_set('session.use_trans_sid', $name['use_trans_sid'] ? 1 : 0);
121
        }
122
123
        if (isset($name['use_cookies'])) {
124
            ini_set('session.use_cookies', $name['use_cookies'] ? 1 : 0);
125
        }
126
127
        if (isset($name['cache_limiter'])) {
128
            session_cache_limiter($name['cache_limiter']);
129
        }
130
131
        if (isset($name['cache_expire'])) {
132
            session_cache_expire($name['cache_expire']);
133
        }
134
        session_start();
135
    } elseif ('' === $value) {
136
        if ('' === $name) {
137
            // 获取全部的session
138
            return $_SESSION;
139
        } elseif (0 === strpos($name, '[')) {
140
            // session 操作
141
            if ('[pause]' == $name) {// 暂停session
142
                session_write_close();
143
            } elseif ('[start]' == $name) {
144
                // 启动session
145
                session_start();
146
            } elseif ('[destroy]' == $name) {
147
                // 销毁session
148
                $_SESSION=array();
149
                session_unset();
150
                session_destroy();
151
            } elseif ('[regenerate]' == $name) {
152
                // 重新生成id
153
                session_regenerate_id();
154
            }
155
        } else {
156
            if (strpos($name, '.')) {
157
                list($name1, $name2)=explode('.', $name);
158
                return isset($_SESSION[$name1][$name2]) ? $_SESSION[$name1][$name2] : null;
159
            } else {
160
                return isset($_SESSION[$name]) ? $_SESSION[$name] : null;
161
            }
162
        }
163
    } elseif (is_null($value)) {
164
        // 删除session
165
        if (strpos($name, '.')) {
166
            list($name1, $name2)=explode('.', $name);
167
            unset($_SESSION[$name1][$name2]);
168
        } else {
169
            unset($_SESSION[$name]);
170
        }
171
    } else {
172
        // 设置session
173
        if (strpos($name, '.')) {
174
            list($name1, $name2)=explode('.', $name);
175
            $_SESSION[$name1][$name2]=$value;
176
        } else {
177
            $_SESSION[$name]=$value;
178
        }
179
    }
180
    return null;
181
}
182
183
184
function admin_is_login() {
185
    $user=session('admin_user_auth');
186
    if (empty($user)) {
187
        return 0;
188
    } else {
189
        $auth_sign=session('admin_user_auth_sign');
190
        if (data_auth_sign($user) != $auth_sign) {
191
            return 0;
192
        }
193
        return $user['uid'];
194
    }
195
}
196
function json($str) {
197
    $obj=json_encode($str, JSON_UNESCAPED_UNICODE);
198
    header('Content-Type: application/json');
199
    echo $obj;
200
}
201
/**
202
 * 浏览器友好的变量输出
203
 * @param mixed         $var 变量
204
 * @param boolean       $echo 是否输出 默认为true 如果为false 则返回输出字符串
205
 * @param string        $label 标签 默认为空
206
 * @param integer       $flags htmlspecialchars flags
207
 * @return void|string
208
 */
209
function dump($var, $echo=true, $label=null, $flags=ENT_SUBSTITUTE)
210
{
211
    $label=(null === $label) ? '' : rtrim($label).':';
212
    ob_start();
213
    var_dump($var);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($var); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
214
    $output=ob_get_clean();
215
    $output=preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
216
    if (IS_CLI) {
217
        $output=PHP_EOL.$label.$output.PHP_EOL;
218
    } else {
219
        if (!extension_loaded('xdebug')) {
220
            $output=htmlspecialchars($output, $flags);
221
        }
222
        $output='<pre>'.$label.$output.'</pre>';
223
    }
224
    if ($echo) {
225
        echo($output);
226
        return;
227
    } else {
228
        return $output;
229
    }
230
}
231
232
233
/**
234
 * 获取输入参数 支持过滤和默认值
235
 * 使用方法:
236
 * <code>
237
 * I('id',0); 获取id参数 自动判断get或者post
238
 * I('post.name','','htmlspecialchars'); 获取$_POST['name']
239
 * I('get.'); 获取$_GET
240
 * </code>
241
 * @param string $name 变量的名称 支持指定类型
242
 * @param mixed $default 不存在的时候默认值
243
 * @param mixed $filter 参数过滤方法
244
 * @param mixed $datas 要获取的额外数据源
245
 * @return mixed
246
 */
247
function I($name, $default='', $filter=null, $datas=null)
0 ignored issues
show
Coding Style introduced by
I uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
I uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
I uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
I uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
I uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
I uses the super-global variable $_COOKIE which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
I uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
248
{
249
    static $_PUT=null;
250
    if (strpos($name, '/')) {
251
        // 指定修饰符
252
        list($name, $type)=explode('/', $name, 2);
253
    } else {
254
        // 默认强制转换为字符串
255
        $type='s';
256
    }
257
    if (strpos($name, '.')) {
258
        // 指定参数来源
259
        list($method, $name)=explode('.', $name, 2);
260
    } else {
261
        // 默认为自动判断
262
        $method='param';
263
    }
264
    switch (strtolower($method)) {
265
        case 'get':
266
            $input=&$_GET;
267
            break;
268
        case 'post':
269
            $input=&$_POST;
270
            break;
271
        case 'put':
272
            if (is_null($_PUT)) {
273
                parse_str(file_get_contents('php://input'), $_PUT);
274
            }
275
            $input=$_PUT;
276
            break;
277
        case 'param':
278
            switch ($_SERVER['REQUEST_METHOD']) {
279
                case 'POST':
280
                    $input=$_POST;
281
                    break;
282
                case 'PUT':
283
                    if (is_null($_PUT)) {
284
                        parse_str(file_get_contents('php://input'), $_PUT);
285
                    }
286
                    $input=$_PUT;
287
                    break;
288
                default:
289
                    $input=$_GET;
290
            }
291
            break;
292
        case 'path':
293
            $input=array();
294
            if (!empty($_SERVER['PATH_INFO'])) {
295
                $depr=C('URL_PATHINFO_DEPR');
296
                $input=explode($depr, trim($_SERVER['PATH_INFO'], $depr));
297
            }
298
            break;
299
        case 'request':
300
            $input=&$_REQUEST;
301
            break;
302
        case 'session':
303
            $input=&$_SESSION;
304
            break;
305
        case 'cookie':
306
            $input=&$_COOKIE;
307
            break;
308
        case 'server':
309
            $input=&$_SERVER;
310
            break;
311
        case 'globals':
312
            $input=&$GLOBALS;
313
            break;
314
        case 'data':
315
            $input=&$datas;
316
            break;
317
        default:
318
            return null;
319
    }
320
    if ('' == $name) {
321
        // 获取全部变量
322
        $data=$input;
323
        $filters=isset($filter) ? $filter : 'htmlspecialchars';
324
        if ($filters) {
325
            if (is_string($filters)) {
326
                $filters=explode(',', $filters);
0 ignored issues
show
Unused Code introduced by
$filters is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
327
            }
328
            else if (is_array($filters)) {
329
                foreach ($filters as $filter) {
330
                    $data=array_map_recursive($filter, $data); // 参数过滤
331
                }
332
            } else {
333
                throw new \RuntimeException('$filters must be an array or string.');
334
            }
335
        }
336
    } elseif (isset($input[$name])) {
337
        // 取值操作
338
        $data=$input[$name];
339
        $filters=isset($filter) ? $filter : 'htmlspecialchars';
340
        if ($filters) {
341
            if (is_string($filters)) {
342
                if (0 === strpos($filters, '/')) {
343
                    if (1 !== preg_match($filters, (string) $data)) {
344
                        // 支持正则验证
345
                        return isset($default) ? $default : null;
346
                    }
347
                } else {
348
                    $filters=explode(',', $filters);
349
                }
350
            } elseif (is_int($filters)) {
351
                $filters=array($filters);
352
            }
353
354
            if (is_array($filters)) {
355
                foreach ($filters as $filter) {
356
                    $filter=trim($filter);
357
                    if (function_exists($filter)) {
358
                        $data=is_array($data) ? array_map_recursive($filter, $data) : $filter($data); // 参数过滤
359
                    } else {
360
                        $data=filter_var($data, is_int($filter) ? $filter : filter_id($filter));
361
                        if (false === $data) {
362
                            return isset($default) ? $default : null;
363
                        }
364
                    }
365
                }
366
            }
367
        }
368
        if (!empty($type)) {
369
            switch (strtolower($type)) {
370
                case 'a':    // 数组
371
                    $data=(array) $data;
372
                    break;
373
                case 'd':    // 数字
374
                    $data=(int) $data;
375
                    break;
376
                case 'f':    // 浮点
377
                    $data=(float) $data;
378
                    break;
379
                case 'b':    // 布尔
380
                    $data=(boolean) $data;
381
                    break;
382
                case 's':// 字符串
383
                default:
384
                    $data=(string) $data;
385
            }
386
        }
387
    } else {
388
        // 变量默认值
389
        $data=isset($default) ? $default : null;
390
    }
391
    is_array($data) && array_walk_recursive($data, 'think_filter');
392
    return $data;
393
}
394
function array_map_recursive($filter, $data)
395
{
396
    $result=array();
397
    foreach ($data as $key => $val) {
398
        $result[$key]=is_array($val)
399
            ? array_map_recursive($filter, $val)
400
            : call_user_func($filter, $val);
401
    }
402
    return $result;
403
}
404
function think_filter(&$value)
405
{
406
    // TODO 其他安全过滤
407
408
    // 过滤查询特殊字符
409
    if (preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i', $value)) {
410
        $value .= ' ';
411
    }
412
}
413
/**
414
 * @param string $name
415
 *
416
 * @return string|null
417
 */
418
function config($name=null,$value=null,$default=null){
419
    $config=\puck\Conf::load();
420
    if ($name===null){
421
        return $config->all();
422
    }
423
    if ($value===null){
424
        return $config->get($name,$default);
425
    }
426
    $config->set($name,$value);
427
}
428
/**
429
 * 字符串命名风格转换
430
 * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
431
 * @param string $name 字符串
432
 * @param integer $type 转换类型
433
 * @return string
434
 */
435
function parse_name($name, $type=0) {
436
    if ($type) {
437
        return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function($match) {return strtoupper($match[1]); }, $name));
438
    } else {
439
        return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
440
    }
441
}
442
443
if (! function_exists('app')) {
444
    /**
445
     * Get the available container instance.
446
     *
447
     * @param  string  $make
448
     * @return mixed|\Laravel\Lumen\Application
449
     */
450
    function app($make = null)
451
    {
452
        if (is_null($make)) {
453
            return Container::getInstance();
454
        }
455
        return Container::getInstance()->make($make);
456
    }
457
}