Passed
Push — master ( 47aa65...ade1c9 )
by kill
02:28
created

function.php (15 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * 获取客户端IP地址
5
 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
6
 * @param boolean $adv 是否进行高级模式获取(有可能被伪装)
7
 * @return mixed
8
 */
9
function get_client_ip($type=0, $adv=true)
0 ignored issues
show
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...
10
{
11
    $type=$type ? 1 : 0;
12
    static $ip=null;
13
    if (null !== $ip) {
14
        return $ip[$type];
15
    }
16
    if ($adv) {
17
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
18
            $arr=explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
19
            $pos=array_search('unknown', $arr);
20
            if (false !== $pos) {
21
                unset($arr[$pos]);
22
            }
23
            $ip=trim($arr[0]);
24
        } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
25
            $ip=$_SERVER['HTTP_CLIENT_IP'];
26
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
27
            $ip=$_SERVER['REMOTE_ADDR'];
28
        }
29
    } elseif (isset($_SERVER['REMOTE_ADDR'])) {
30
        $ip=$_SERVER['REMOTE_ADDR'];
31
    }
32
    // IP地址合法验证
33
    $long=sprintf("%u", ip2long($ip));
34
    $ip=$long ? array($ip, $long) : array('0.0.0.0', 0);
35
    return $ip[$type];
36
}
37
//2为直接输出数组
38
function show_json($arr, $type=2)
39
{
40
    if (isset($arr['status']) && $type == 2) {
41
        $ret=$arr;
42
    }
43
    else {
44
        $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...
45
        $ret['data']=$arr;
46
    }
47
48
    $obj=json_encode($ret);
49
    header('Content-Type: application/json');
50
    echo $obj;
51
    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...
52
}
53
54
function success($arr)
55
{
56
    show_json($arr, 1);
57
}
58
59
function error($arr)
60
{
61
/*    $db=\MysqliDb::getInstance();
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
62
    $db->_transaction_status_check();*/
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
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
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...
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...
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...
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...
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...
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...
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);
327
            }
328
            foreach ($filters as $filter) {
0 ignored issues
show
The expression $filters of type object|integer|double|null|array|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

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