JSSDKApi::getnonceStr()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 13
rs 9.4285
cc 3
eloc 8
nc 2
nop 0
1
<?php
2
namespace Wechat\API;
3
4
use Wechat\Utils\JSON;
5
6
/**
7
 * 微信JSSDK相关接口.
8
 *
9
 * @author Tian.
10
 */
11
class JSSDKApi extends BaseApi
12
{
13
14
    /**
15
     * 获取JSSDK的配置数组
16
     *
17
     * @param array $APIs
18
     * @param bool  $debug
19
     * @param bool  $json
20
     *
21
     * @return string|array
22
     */
23
    public function config(array $APIs, $debug = false, $json = true)
24
    {
25
        $signPackage = $this->getSignature();
26
27
        $base = [
28
            'debug' => $debug,
29
        ];
30
31
        $config = array_merge($base, $signPackage, ['jsApiList' => $APIs]);
32
33
        return $json ? JSON::encode($config) : $config;
34
    }
35
36
    /**
37
     * 获取JSSDK接口认证.
38
     *
39
     * @author Tian
40
     *
41
     * @date   2015-12-08
42
     *
43
     * @return string 认证签名.
44
     */
45
    public function getTicket()
46
    {
47
        $key    = 'JSAPI_TICKET' . $this->getAppId();
48
        $ticket = $this->cache($key);
49
        if (!$ticket) {
50
            $this->module = 'ticket';
51
            $queryStr     = [
52
                'type' => 'jsapi',
53
            ];
54
            $res          = $this->_get('getticket', $queryStr, false);
55
56
            if (!$res) {
57
                return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by Wechat\API\JSSDKApi::getTicket of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
58
            }
59
60
            $ticket  = $res['ticket'];
61
            $expires = $res['expires_in'];
62
63
            $this->cache($key, $ticket, $expires - 1000);
64
        }
65
66
        return $ticket;
67
    }
68
69
    /**
70
     * 获取JSSDK签名.
71
     *
72
     * @author Tian
73
     *
74
     * @date   2015-12-08
75
     *
76
     * @return string
77
     */
78
    public function getSignature()
0 ignored issues
show
Coding Style introduced by
getSignature 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...
79
    {
80
        /** @var int $timestamp */
81
        $timestamp = $this->getTimeStamp();
82
        $nonceStr  = $this->getnonceStr();
83
        $ticket    = $this->getTicket();
84
85
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
86
87
        $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
88
89
        /** @var array $signature_array */
90
        $signature_array              = [];
91
        $signature_array['appId']     = $this->getAppId();
92
        $signature_array['nonceStr']  = $nonceStr;
93
        $signature_array['timestamp'] = $timestamp;
94
        $signature_array['signature'] = $this->getSignatures($ticket, $nonceStr, $timestamp, $url);
95
96
        return $signature_array;
97
    }
98
99
    /**
100
     * 生成签名
101
     *
102
     * @param string $ticket
103
     * @param string $nonce
104
     * @param int    $timestamp
105
     * @param string $url
106
     *
107
     * @return string
108
     */
109
    public function getSignatures($ticket, $nonce, $timestamp, $url)
110
    {
111
        return sha1("jsapi_ticket={$ticket}&noncestr={$nonce}&timestamp={$timestamp}&url={$url}");
112
    }
113
114
    /**
115
     * 获取唯一时间戳.
116
     *
117
     * @author Tian
118
     *
119
     * @date   2015-12-08
120
     *
121
     * @return int timestamp
122
     */
123
    public function getTimeStamp()
124
    {
125
        static $timestamp;
126
        if (!$timestamp) {
127
            $timestamp = time();
128
        }
129
130
        return $timestamp;
131
    }
132
133
    /**
134
     * 获取唯一随机串.
135
     *
136
     * @author Tian
137
     *
138
     * @date   2015-12-08
139
     *
140
     * @return string
141
     */
142
    public function getnonceStr()
143
    {
144
        static $nonceStr;
145
        if (!$nonceStr) {
146
            $chars    = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
147
            $nonceStr = '';
148
            for ($i = 0; $i < 16; $i++) {
149
                $nonceStr .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
150
            }
151
        }
152
153
        return $nonceStr;
154
    }
155
}
156