Captcha为Laravel 5 应用生成验证码例子

 更新时间:2016年11月25日 16:16  点击:2225
验证码(Captcha)开源软件了,我们可以利用它结合Laravel 5生成验证码了,并且它在不断的更新算法比较难破解了,下面来看一篇Captcha为Laravel 5 应用生成验证码例子具体如下。

Laravel Captcha

1、安装

我们通过 Composer 安装 Captcha 扩展包:

composer require mews/captcha

注:Windows中使用该扩展包还需要安装 GD2 扩展(在php.ini中取消php_gd2.dll前面的注释)。

2、配置

使用Captcha服务提供者之前还需要在config/app.php中注册服务提供者:

'providers' => [
    // ...
    Mews\Captcha\CaptchaServiceProvider::class,
]

同时注册下相应门面:

'aliases' => [
    // ...
    'Captcha' => Mews\Captcha\Facades\Captcha::class,
]

如果要使用自定义的配置,还可以发布配置文件到config目录:

$ php artisan vendor:publish

编辑新生成的captcha.php:

return [
    'default' => [
        'length' => 5,
        'width' => 120,
        'height' => 36,
        'quality' => 90,
    ],
    // ...
];

3、使用示例

// app/Http/routes.php

Route::any('captcha-test', function()
{
    if (Request::getMethod() == 'POST')
    {
        $rules = ['captcha' => 'required|captcha'];
        $validator = Validator::make(Input::all(), $rules);
        if ($validator->fails())
        {
            echo '<p style="color: #ff0000;">Incorrect!</p>';
        }
        else
        {
            echo '<p style="color: #00ff30;">Matched :)</p>';
        }
    }

    $form = '<form method="post" action="captcha-test">';
    $form .= '<input type="hidden" name="_token" value="' . csrf_token() . '">';
    $form .= '<p>' . captcha_img() . '</p>';
    $form .= '<p><input type="text" name="captcha"></p>';
    $form .= '<p><button type="submit" name="check">Check</button></p>';
    $form .= '</form>';
    return $form;
});


显示效果如下:

Laravel Captcha

如果要返回原生图片,可以调用这个函数:

captcha();
或者

Captcha::create();
如果要返回URL:

captcha_src();
或者

Captcha::src();
如果要返回HTML:

captcha_img();
我们这个示例中使用的就是这个函数,或者调用Captcha门面上的方法:

Captcha::img();
要使用配置文件captcha.php中不同的配置项,可以这样调用:

captcha_img('flat');
Captcha::img('inverse');

注意:

在laravel 5.2中这个包会出现验证码怎么也无法验证成功的问题,因为5.2采用了middleware分组,并没有使用全局中间件导致这个包没有启用session导致上述问题。解决办法:在

vendor/mews/captcha/src/CaptchaServiceProvider.php
29行的

this->app['router']->get('captcha/{config?}', '\Mews\Captcha\CaptchaController@getCaptcha')
后面添加

->middleware('web');

确认你的web中间件分组内有StartSession中间件。另外你也可以添加5.2新特性频率限制到后面

->middleware('throttle:60,1')

以防止恶意攻击。

Laravel 5.1中500错误是程序错误,程序错误一定是系统自带的500错误,如果我们想自定义的话可以和小编来看看如何做。

500错误页面

编辑PHP文件app/Exceptions/Handler.php内容如下:

 代码如下 复制代码

public function render($request, Exception $e)
{

    if ($e instanceof ModelNotFoundException) {
        $e = new NotFoundHttpException($e->getMessage(), $e);
    }

    if($e instanceof \Symfony\Component\Debug\Exception\FatalErrorException
        && !config('app.debug')) {
        return response()->view('errors.default', [], 500);
    }

    return parent::render($request, $e);
}

然后编辑自定义错误页面对应视图文件errors.default.blade.php。

公众号菜单添加删除如果是单号可以直接登录后台操作了,但如果我们开了开发接口那么这个菜单的操作也必须通过接口来实现了,下面我们来看一篇关于php版微信实现公众号菜单添加删除操作例子。

为了以最快方式调试新菜单功能,就用Debug方式去生成新菜单。请参数微信教程2的 wechat-json类。导入该文件后,我们用Debug方式生成一个新菜单:
if (isset($argc)  && $argc >= 1 && $argv[0] == __FILE__) {
    $client = new WechatJSON(array(
        WechatJSON::APP_ID => 'wx78acfe8023sfsd4d51',
        WechatJSON::APP_SECRET => '9ba3476db1ffsfsf512e0b22f630fa',
    ));
 
    $res = $client->call('/menu/create',array (
            'button' => array(
                array (
                    'name' => '扫码',
                    'sub_button' => array(
                        array(
                            'name' => '扫码不提示',
                            'type' => 'scancode_push',
                            'key' => 'rselfmenu_0_0',
                            'sub_button' =>array ()
                        ),
                        array(
                            'name' => '扫码带提示',
                            'type' => 'scancode_waitmsg',
                            'key' => 'rselfmenu_0_1',
                            'sub_button' =>array ()
                        ),
                    ),
                ),
                array(
                    'name' => '发图',
                    'sub_button' => array(
                        array(
                            'name' => '系统拍照发图',
                            'type' => 'pic_sysphoto',
                            'key' => 'rselfmenu_1_0',
                            'sub_button' => array()
                        ),
                        array(
                            'name' => '拍照或者相册发图',
                            'type' => 'pic_photo_or_album',
                            'key' => 'rselfmenu_1_1',
                            'sub_button' => array()
                        ),
                        array(
                            'name' => '微信相册发图',
                            'type' => 'pic_weixin',
                            'key' => 'rselfmenu_1_2',
                            'sub_button' => array()
                        ),
                    )
                ),
                array(
                    'name' => '发送位置',
                    'type' => 'location_select',
                    'key' => 'rselfmenu_2_0'
                )
            )
        )
        , WechatJSON::JSON);
    if (!$res) {
        var_dump($client->_error);
    }
    var_export($res);
}

执行后,取消关注再关注,让新菜单生效!
效果图:


menu-expland


测试结果如下:
scancode_push事件:
array (
  'tousername' => 'gh_e2a2b3bd35ff',
  'fromusername' => 'on0eVjnYStxkCSaaCamYCpMZDmwA',
  'createtime' => '1411629272',
  'msgtype' => 'event',
  'event' => 'scancode_push',
  'eventkey' => '6',
  'scancodeinfo' =>
  SimpleXMLElement::__set_state(array(
     'ScanType' => 'qrcode',
     'ScanResult' => 'http://www.baidu.com/',
  )),
array (
  'tousername' => 'gh_e2a2b3bd35ff',
  'fromusername' => 'on0eVjnYStxkCSaaCamYCpMZDmwA',
  'createtime' => '1411629475',
  'msgtype' => 'event',
  'event' => 'scancode_push',
  'eventkey' => '6',
  'scancodeinfo' =>
  SimpleXMLElement::__set_state(array(
     'ScanType' => 'qrcode/EAN_13',
     'ScanResult' => '6925082946487',
     'EventKey' =>
    SimpleXMLElement::__set_state(array(
    )),
  )),
)

 





scan-jump scan-product

 


上面是在菜单上点击《扫码不提示》后的log,有两种情况出现,第一种是如果你扫的是二维码是URL,它就会跳转到网页(注包括服务号生成的二维码),第二种是如果你扫的是条形码,就会跳转到搜索到该商品的详细信息,也就是大家常用的查价格。

scancode_waitmsg事件:
array (
  'tousername' => 'gh_e2a2b3bd35ff',
  'fromusername' => 'on0eVjnYStxkCSaaCamYCpMZDmwA',
  'createtime' => '1411629302',
  'msgtype' => 'event',
  'event' => 'scancode_waitmsg',
  'eventkey' => '6',
  'scancodeinfo' =>
  SimpleXMLElement::__set_state(array(
     'ScanType' => 'qrcode',
     'ScanResult' => 'http://www.111cn.net/',
  )),

 

scan-msg


上面是点击菜单《扫码提示》后的log,推送XML跟scancode_push时差不多,但它不会跳转到网址或者商品信息。博主认为,这有利于后台取得scancodeinfo的信息来进一步处理!打个比方,自己自定义二维码信息,然后截取处理。类似于原服务号的参数二维码。
注意,以上两个菜单扫描事件和微信APP的扫一扫,是有区别的。具体你看事件就能看出来,scan事件!
pic_sysphoto事件、pic_photo_or_album事件和pic_weixin事件
array (
  'tousername' => 'gh_e2a2b3bd35ff',
  'fromusername' => 'on0eVjnYStxkCSaaCamYCpMZDmwA',
  'createtime' => '1411627313',
  'msgtype' => 'image',
  'picurl' => 'http://mmbiz.qpic.cn/mmbiz/L8zbjcLqNFvEZ4dne4MGQQGR8xuHk4KhEk3icghU6a4bFTXnP2oeicr5VaBVJa10w4MYOOEia4udqicT5fdtAADHYg/0',
  'msgid' => '6062893143676022221',
  'mediaid' => 'i7hYOlSXbUCaC7Z9Elx4WpBqQq37-hR0El5w-frPfD5WCdBC7x46DPO6HL7zMfgd',
)

 





pic-menu pic-menu-ok

 


上面是点《发图》后,三个子菜单选择或者拍好,发图后的log信息,从图中我们看到事件是推过来了image,其他信息,相信大家都知道是什么,不解释。
location_select事件:
array (
  'tousername' => 'gh_e2a2b3bd35ff',
  'fromusername' => 'on0eVjnYStxkCSaaCamYCpMZDmwA',
  'createtime' => '1411627424',
  'msgtype' => 'event',
  'event' => 'location_select',
  'eventkey' => '6',
  'sendlocationinfo' =>
  SimpleXMLElement::__set_state(array(
     'Location_X' => '23',
     'Location_Y' => '113',
     'Scale' => '15',
     'Label' =>
    SimpleXMLElement::__set_state(array(
    )),
     'Poiname' =>
    SimpleXMLElement::__set_state(array(
    )),
  )),
)





location-menu2 location-menu


上面是点击菜单《发送位置》后的log,我们可以看出事件是location_select,不像发图那样变成image,最有价值的信息是我们要取的sendlocationinfo里的

登录授权功能我们通常是绑定自己的网站了,最近在开发了一个微信登录绑定自己公司的网站会员ID了,下面我们来把这个例子与原理介绍一下吧。

用户授权也是高级接口那部分内容,只是把它独立出来,这样让整个微信框架条理清晰些,但我们用它首先要在微信后台设置OA2的URL,这里的URL和教程一的有所不同。它是不带http://开头的域名。
首先登陆你的微信后台找到《开发者中心》:

auth-one


点击修改填入我们的域名如下格式:

auth-two

好了,最基本要点的OA2要求搞好,下面我们用个WechatAuth类生成一个OA2的URL格式,然后再从服务号里,以链接或者菜单又或者图文,跳到微信内置的WEB里就实现了我们取openid或者授权取用户消息!

例子代码生成snsapi_base或者snsapi_userinfo:
$auth = new WechatAuth(array(
        WechatAuth::APP_ID => 'wx32259fc5sd5aac12B',
        WechatAuth::APP_SECRET => '7ef73d3c56fcd0d984862ff217d2c648',
    ));
    $url = $auth->getLoginUrl(array(
        'redirect_uri' => 'http://www.demo.com/wp/ken',
        'scope' => 'snsapi_userinfo' //snsapi_base
    ));
    echo $url;

执行后,我们会得到如下OA2的URL:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx32259fc5d5aac13d&redirect_uri=http%3A%2F%2Fwww.demo.com%2Fwp%2Fken&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirects

然后我们在服务号里以刚才说到的菜单好,链接好 点击转到微信内置的浏览器里,如果你的scope方式为snsapi_userinfo时会弹出授权界面,base时不会弹默认执行后会返回openid:

auth-three

好了,OA2无非就是让我们生成特定格式的URL,让我们点过去取openid或者用户信息(无论是否关注了你的服务号,只要确认授权),可以运用本站微信的实例有相关OA2的运用或者留言给我!
WechatAuth类:

<?php
/**
 * 微信 OAuth2.0授权接口
 * Class WechatAuth
 */
class WechatAuth {
 
    const
        JSON = 'json',
        POST = 'post',
        GET = 'get',
        APP_ID = 'appid',
        APP_SECRET = 'secret',
        API_URL_PREFIX = 'https://api.weixin.qq.com/sns';
 
    public
        $_error_number = 0,
        $_error,
        $_APPID,
        $_APPSECRET;
 
    protected
        $_cache = array(),
        $_options,
        $_openid,
        $_access_token,
        $_refresh_token,
        $_timeout = 30;
 
    static protected
        $_instance;
 
    /**
     * 单例模式
     * @param array $options
     * @return WechatAuth
     */
    static public function getInstance(array $options = array()) {
        if (empty(self::$_instance)) {
            self::$_instance = new WechatAuth($options);
        }
 
        return self::$_instance;
    }
 
    /**
     * @param array $options {WechatAuth::APP_ID:"", WechatAuth::APP_SECRET:""}
     */
    public function __construct(array $options = array()) {
        $this->_options = array(
            'timeout' => $this->_timeout,
        );
        $_options = array_merge($this->_options, $options);
        $this->_APPID = $_options['appid'];
        $this->_APPSECRET = $_options['secret'];
        $this->_timeout = $_options['timeout'];
    }
 
    /**
     * 提交请求
     * @param $url
     * @param array $params
     * @param string $type Webchat_API::POST|Webchat_API::GET
     * @return bool|mixed
     */
    public function request($url, $params = array(), $type = self::POST) {
        $ch = curl_init();
        if ($type == self::GET) {
            $url = $url.'?'.http_build_query($params);
        }
        curl_setopt_array($ch, array(
            CURLOPT_URL => $url,
            CURLOPT_TIMEOUT => $this->_timeout,
            CURLOPT_USERAGENT => 'wordpress_wechat_client/0.1.'.rand(1,6),
            CURLOPT_HEADER => 0,
            CURLOPT_FOLLOWLOCATION => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_SSL_VERIFYPEER => 0,
            CURLOPT_SSLVERSION => 3,
//            CURLOPT_VERBOSE => 1,
        ));
        if ($type == self::POST) {
            curl_setopt($ch, CURLOPT_PORT, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        }
        if ($type == self::JSON) {
            //微信的破接口竟然不支持unicode转义符,违反JSON协定,只能把JSON字符中的unicode转回来
            $data = preg_replace('/\\\\u([a-f0-9]{4})/e', "json_decode('\"$0\"', 1)", json_encode($params));
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
        }
        $res = curl_exec($ch);
        $this->_error_number = curl_errno($ch);
        $this->_error = curl_error($ch);
        curl_close($ch);
 
        if ($this->_error_number) {
            return false;
        }
        return $this->parseResult($res);
    }
 
    /**
     * 处理返回结果
     * @param $res
     * @return bool|mixed
     */
    protected function parseResult($res) {
        $res = json_decode($res, true);
        if (!empty($res)) {
            if (isset($res['errcode']) && $res['errcode']) {
                $this->_error_number = $res['errcode'];
                $this->_error = $res['errmsg'];
                return false;
            }
 
            return $res;
        }
 
        return false;
    }
 
    /**
     * 获取当前URL
     * @return string
     */
    static public function getCurrentUrl() {
        $pageURL = 'http';
        if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") {
            $pageURL .= "s";
        }
        $pageURL .= "://";
        if (isset($_SERVER['SERVER_PORT']) && $_SERVER["SERVER_PORT"] != "80") {
            $pageURL .= $_SERVER["SERVER_NAME"] . ":" . $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
        } else {
            if(isset($_SERVER["SERVER_NAME"]) && isset($_SERVER["REQUEST_URI"]))
                $pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
        }
        return $pageURL;
    }
 
    /**
     * 获取访问token
     * @param bool $refresh 是否强制刷新
     * @return bool|mixed
     */
    public function getAuthAccessToken($refresh = false) {
        $code = isset($_GET['code']) ? $_GET['code'] : '';
        $state = isset($_GET['state']) ? $_GET['state'] : '';
        $cache = $this->cache('auth_access_token');
        if ($cache && ! $refresh) {
            return array('access_token' => $cache, 'code' => $code, 'state' => $state);
        }
        $res = $this->request(self::API_URL_PREFIX.'/oauth2/access_token', array(
            self::APP_ID => $this->_APPID,
            self::APP_SECRET => $this->_APPSECRET,
            'code' => $code,
            'grant_type' => 'authorization_code',
        ), self::GET);
        if ($res) {
            $this->cache('auth_access_token', $res['access_token']);
            $this->cache('auth_refresh_token', $res['refresh_token']);
            $this->cache('auth_openid', $res['openid']);
        } else {
            if ($this->_error_number == 42001) {
                return $this->refreshAccessToken();
            }
        }
       return array('access_token' => $res['access_token'], 'code' => $code, 'state' => $state);
    }
 
    /**
     * 刷新访问token
     * @return mixed
     */
    public function refreshAccessToken() {
        $code = isset($_GET['code']) ? $_GET['code'] : '';
        $state = isset($_GET['state']) ? $_GET['state'] : '';
        $cache = $this->cache('auth_refresh_token');
        if ($cache) {
            $this->_refresh_token = $cache;
        }
 
        $res = $this->request(self::API_URL_PREFIX.'/oauth2/refresh_token', array(
            self::APP_ID => $this->_APPID,
            'refresh_token' => $this->_refresh_token,
            'grant_type' => 'refresh_token',
        ), self::GET);
 
        if ($res) {
            $this->cache('auth_access_token', $res['access_token']);
            $this->cache('auth_refresh_token', $res['refresh_token']);
            $this->cache('auth_openid', $res['openid']);
        }
        return array('access_token' => $res['access_token'], 'code' => $code, 'state' => $state);
    }
 
    /**
     * 获取用户信息
     * @param bool $refresh 是否强制刷新
     * @return bool|mixed
     */
    public function getUserInfo($refresh = false) {
        $this->_access_token = $this->getAuthAccessToken($refresh);
        $cache =  $this->cache('auth_openid');
        if ($cache) {
            $this->_openid = $cache;
        }
 
        $res = $this->request(self::API_URL_PREFIX.'/userinfo', array(
            'access_token' => $this->_access_token,
            'openid' => $this->_openid,
        ), self::GET);
 
 
        if ($res) {
            return $res;
        }
 
        return false;
    }
 
    /**
     * 获取用户授权地址
     * @param array $options
     * @return string
     */
    public function getLoginUrl($options = array()) {
        $_options = array(
            self::APP_ID => $this->_APPID,
            'redirect_uri' => self::getCurrentUrl(),
            'response_type' => 'code',
            'scope' => 'snsapi_base', //snsapi_base | snsapi_userinfo
            'state' => 'STATE',
        );
        $params = array_merge($_options, $options);
 
        return 'https://open.weixin.qq.com/connect/oauth2/authorize?'.http_build_query($params).'#wechat_redirects';
    }
 
    /**
     * 缓存接口Session实现
     * @param $key 缓存索引key
     * @param null $value 缓存值
     * @return bool|mixed
     */
    public function cache($key, $value = null) {
        if (!session_id()) {
            session_start();
        }
        if (empty($value)) {
            if (isset($_SESSION[$key])) {
                return $_SESSION[$key];
            }
            return false;
        }
        $_SESSION[$key] = $value;
        return false;
    }
}

主动发送内容我们需要调用微信官方的api然后再推送给客户了,下面我们来看一篇关于php版微信开发主动发送实例,具体的如下所示。

为了方便调试用CLI方式作测试,记得代码中替换你的appid和appsecret:

比如我们想取公众号的组数据:
if (isset($argc)  && $argc >= 1 && $argv[0] == __FILE__) {
    $client = new WechatJSON(array(
        WechatJSON::APP_ID => 'wx78acfe8257asDb1',
        WechatJSON::APP_SECRET => '9ba3476db1ff75654aBceae0b20fb9',
    ));
    $res = $client->call('/groups/get');
    if (!$res) {
        var_dump($client->_error);
    }
    var_dump($res);
}

如下图所示:

group-test

又或者我们生成菜单:

if (isset($argc)  && $argc >= 1 && $argv[0] == __FILE__) {
    $client = new WechatJSON(array(
        WechatJSON::APP_ID => 'wx78acfe8257asDb1',
        WechatJSON::APP_SECRET => '9ba3476db1ff75654aBceae0b20fb9',
    ));
    $res = $client->call('/menu/create', array(
        'button' => array(
            array(
                'type' => 'click',
                'name' => '测试铵钮',
                'key' => 'test_btn'
            ),array(
                'type' => 'view',
                'name' => '测试跳转',
                'url' => 'http://www.baidu.com'
            ))
        ),WechatJSON::JSON);
    if (!$res) {
        var_dump($client->_error);
    }
    var_dump($res);
}

成功后返回OK如下图:

menu-test

其他接口可以大家可以自己自由获取或者提交POST GET等这里不熬述了!有问题留言

微信高级接口API 类:
<?php
/**
 * 微信 高级接口API  Class WechatJSON
 */
class WechatJSON {
    const
        QR_SCENE = 'QR_SCENE',
        QR_LIMIT_SCENE = 'QR_LIMIT_SCENE',
        IMAGE = 'image',
        VOICE = 'voice',
        VIDEO = 'video',
        NEWS = 'news',
        MPNEWS = 'mpnews',
        THUMB = 'thumb',
        API_URL_PREFIX = 'https://api.weixin.qq.com/cgi-bin',
        AUTH_API_URL = 'https://api.weixin.qq.com/sns/oauth2/access_token',
        AUTH_URL = 'https://open.weixin.qq.com/connect/oauth2/authorize',
        PAY_URL = 'https://api.weixin.qq.com/pay',
        APP_ID = 'appid',
        APP_SECRET = 'secret',
        TIMEOUT = 'timeout',
        JSON = 'json',
        POST = 'post',
        GET = 'get',
        API_TYPE_CGI = 'cgi',
        API_TYPE_PAY = 'pay';
    public
        $_error_number = 0,
        $_error,
        $_APPID,
        $_APPSECRET;
 
    protected
        $_cache = array(),
        $_options,
        $_auth_access_token,
        $_access_token,
        $_timeout = 30;
 
    static protected
        $_no_need_token_apis = array(
        '/showqrcode',
    ),
        $_instance;
 
    /**
     * 单例模式
     * @param array $options
     * @return Wechat_API
     */
    static public function getInstance(array $options = array()) {
        if (empty(self::$_instance)) {
            self::$_instance = new self ($options);
        }
 
        return self::$_instance;
    }
 
    /**
     * @param array $options {Wechat_API::APP_ID:"", Wechat_API::APP_SECRET:"", Wechat_API::TIMEOUT:""}
     */
    public function __construct(array $options = array()) {
        $this->_options = array(
            'timeout' => $this->_timeout,
        );
        $_options = array_merge($this->_options, $options);
        $this->_APPID = $_options['appid'];
        $this->_APPSECRET = $_options['secret'];
        $this->_timeout = $_options['timeout'];
    }
 
    /**
     * 提交请求
     * @param $url
     * @param array $params
     * @param string $type Wechat_API::POST|Wechat_API::GET
     * @return bool|mixed
     */
    public function request($url, $params = array(), $type = self::POST, $format_result = true) {
        $ch = curl_init();
        if ($type == self::GET) {
            $url = $url.'?'.http_build_query($params);
        }
        curl_setopt_array($ch, array(
            CURLOPT_URL => $url,
            CURLOPT_TIMEOUT => $this->_timeout,
            CURLOPT_USERAGENT => 'wordpress_wechat_client/0.1.'.rand(1,6),
            CURLOPT_HEADER => 0,
            CURLOPT_FOLLOWLOCATION => 1,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_SSL_VERIFYPEER => 0,
            CURLOPT_SSLVERSION => 3,
//            CURLOPT_VERBOSE => 1,
        ));
        if ($type == self::POST) {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        }
        if ($type == self::JSON) {
            //微信的破接口竟然不支持unicode转义符,违反JSON协定,只能把JSON字符中的unicode转回来
            $data = preg_replace('/\\\\u([a-f0-9]{4})/e', "json_decode('\"$0\"', 1)", json_encode($params));
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
        }
 
        $res = curl_exec($ch);
        $this->_error_number = curl_errno($ch);
        $this->_error = curl_error($ch);
        curl_close($ch);
 
        if ($this->_error_number) {
            return false;
        }
        return ($format_result ? $this->parseResult($res) : $res);
    }
 
    /**
     * 处理返回结果
     * @param $res
     * @return bool|mixed
     */
    protected function parseResult($res) {
        $res = json_decode($res, true);
        if (!empty($res)) {
            if (isset($res['errcode']) && $res['errcode']) {
                $this->_error_number = $res['errcode'];
                $this->_error = $res['errmsg'];
                return false;
            }
            return $res;
        }
        return false;
    }
 
    public function getAccessToken() {
        $cache = $this->cache($this->_APPID.':'.'access_token');
        if ($cache) {
            return $cache;
        }
        $res = $this->request(self::API_URL_PREFIX.'/token', array(
                'grant_type' => 'client_credential',
                self::APP_ID => $this->_APPID,
                self::APP_SECRET => $this->_APPSECRET,
            ), self::GET);
        if ($res) {
            $this->cache($this->_APPID.':'.'access_token', $res['access_token']);
            return $res['access_token'];
        }
        return false;
    }
 
    /**
     * 预留缓存接口 (强烈建议实现此接口,用于缓存access_token,每次查询会节省很多时间)
     * @param $key 缓存索引key
     * @param null $value 缓存值
     * @param int $timeout 缓存超时时间
     * @return bool|mixed
     */
    public function cache($key, $value = null, $timeout = 7200) {
        if (!session_id()) {
            session_start();
        }
        if (empty($value)) {
            if (isset($_SESSION[$key])) {
                return $_SESSION[$key];
            }
            return false;
        }
        $_SESSION[$key] = $value;
        return false;
    }
 
    /**
     * 调用具体的接口 注意:使用创建数据时使用Wechat_API::JSON
     * @param $api_name REST规格接口名称
     * @param array $params 接口参数
     * @param string $type Wechat_API::GET|Wechat_API::POST|Wechat_API::JSON
     * @return bool|mixed
     */
    public function call($api_name, $params = array(), $type = self::GET, $api_type = self::API_TYPE_CGI) {
        if($api_type == self::API_TYPE_PAY) {
            $url = self::PAY_URL.$api_name;
        } else {
            $url = self::API_URL_PREFIX.$api_name;
        }
        if (in_array($api_name, self::$_no_need_token_apis)) {
            $res = $this->request($url, $params, $type);
            if ($res) {
                return $res;
            }
        }
        $this->_access_token = $this->getAccessToken();
        if ($this->_access_token) {
            if ($type == self::JSON) {
                $url = $url.'?access_token='.$this->_access_token;
            } else {
                $params['access_token'] = $this->_access_token;
            }
            $res = $this->request($url, $params, $type);
            if ($res) {
                return $res;
            }
        }
        return false;
    }
 
    /**
     * 生成二维码
     *
     * @param int $scene_id 场景ID 临时二维码int32 | 永久二维码 < 1000
     * @param string $type 二维码类型 Wechat_API::QR_LIMIT_SCENE | Wechat_API::QR_SCENE 临时二维码|永久二维码
     * @return bool|mixed
     */
    public function GetQrCode($scene_id = 0, $type = self::QR_LIMIT_SCENE) {
        $res = $this->call('/qrcode/create', array(
            'expire_seconds' => 1800,
            'action_name' => $type,
            'action_info' => array(
                'scene' => array(
                    'scene_id' => $scene_id,
                )
            )
        ), self::JSON);
        if ($res && isset($res['ticket'])) {
            $res = $this->request('https://mp.weixin.qq.com/cgi-bin/showqrcode', array(
                'ticket' => $res['ticket'],
            ), self::GET, false);
            if ($res) {
                return $res;
            }
        }
        return false;
    }
 
    public function MediaUpload($file_full_path, $type = self::THUMB) {
        $this->_access_token = $this->getAccessToken();
        $res = false;
        if ($this->_access_token) {
            $url = 'http://file.api.weixin.qq.com/cgi-bin/media/upload?';
            $url = $url.'access_token='.$this->_access_token.'&type='.$type;
            $res = $this->request($url, array(
                'media' => '@'.$file_full_path,
            ), self::POST);
        }
        return $res;
    }
 
    public function GetMedia($media_id) {
        $this->_access_token = $this->getAccessToken();
        if ($this->_access_token) {
            $res = $this->request('http://file.api.weixin.qq.com/cgi-bin/media/get', array(
                'access_token' => $this->_access_token,
                'media_id' => $media_id,
            ), self::GET, false);
            if ($res) {
                $res_json = json_decode($res, 1);
                if (!$res_json) {
                    return $res;
                }
                $this->_error_number = $res_json['errcode'];
                $this->_error = $res_json['errmsg'];
            }
        }
        return false;
    }
}

[!--infotagslink--]

相关文章

  • PHP 验证码不显示只有一个小红叉的解决方法

    最近想自学PHP ,做了个验证码,但不知道怎么搞的,总出现一个如下图的小红叉,但验证码就是显示不出来,原因如下 未修改之前,出现如下错误; (1)修改步骤如下,原因如下,原因是apache权限没开, (2)点击打开php.int., 搜索extension=ph...2013-10-04
  • JS实现随机生成验证码

    这篇文章主要为大家详细介绍了JS实现随机生成验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-06
  • jQuery Real Person验证码插件防止表单自动提交

    本文介绍的jQuery插件有点特殊,防自动提交表单的验证工具,就是我们经常用到的验证码工具,先给大家看看效果。效果图如下: 使用说明 需要使用jQuery库文件和Real Person库文件 同时需要自定义验证码显示的CSS样式 使用实例...2015-11-08
  • php实现点击可刷新验证码

    验证码类文件 CreateImg.class.php <&#63;php class ValidationCode { private $width,$height,$codenum; public $checkcode; //产生的验证码 private $checkimage; //验证码图片 private $disturbColor = ''; /...2015-11-08
  • 基于JavaScript实现验证码功能

    这篇文章主要介绍了基于JavaScript实现验证码功能的相关资料...2017-04-03
  • 单击按钮发送验证码,出现倒计时的简单实例

    下面小编就为大家带来一篇单击按钮发送验证码,出现倒计时的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 代码...2017-07-06
  • PHP验证码生成与验证例子

    验证码是一个现在WEB2.0中常见的一个功能了,像注册、登录又或者是留言页面,都需要注册码来验证当前操作者的合法性,我们会看到有些网站没有验证码,但那是更高级的验证了,...2016-11-25
  • Jquery插件实现点击获取验证码后60秒内禁止重新获取

    通过jquery.cookie.js插件可以快速实现“点击获取验证码后60秒内禁止重新获取(防刷新)”的功能效果图:先到官网(http://plugins.jquery.com/cookie/)下载cookie插件,放到相应文件夹,代码如下:复制代码 代码如下: <!DOCTYPE ht...2015-03-15
  • 基于Pytorch版yolov5的滑块验证码破解思路详解

    这篇文章主要介绍了基于Pytorch版yolov5的滑块验证码破解思路详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-25
  • Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法

    这篇文章主要介绍了Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下...2016-06-24
  • 工信部的ICP备案网站登录时验证码一直输入不正确怎么回事

    工信部的ICP备案网站登录时验证码一直输入不正确怎么回事,为了防止一些机器采集人工信部对于查询验证做得识别度极低,所以许多的朋友都会发现输入验证码一直有问题了,那...2016-10-10
  • jQuery实现发送验证码控制按钮禁用功能

    最近接到新需求,需要实现一个点击发送验证码之后,按钮禁用,在5秒之后取消禁用,看似需求很简单,实现起来还真的好好动动脑筋,下面小编把jquery控制按钮禁用核心代码分享给大家,需要的朋友参考下吧...2021-07-24
  • GoDaddy怎么开启手机验证码登录?

    GoDaddy怎么开启手机验证码登录?最近老听朋友说gd用户盗了,然后域名丢失了,今天 我们一起来看看关于GoDaddy开启手机验证码登录的教程. 给账户添加多重验证是为了账...2016-10-10
  • python网络爬虫实现发送短信验证码的方法

    这篇文章主要介绍了python网络爬虫实现发送短信验证码的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-25
  • Web制作验证码功能实例代码

    web开发中,经常会使用验证码功能,例如登录、注册,或其他关键功能之前经常会使用。下面通过实例代码给大家介绍Web制作验证码功能实例代码,感兴趣的朋友一起看看吧...2017-06-24
  • C#验证码识别基础方法实例分析

    这篇文章主要介绍了C#验证码识别基础方法实例分析,较为详细的总结了C#验证码的实现思路及具体步骤,并对实现思路进行了总结归纳,具有很好的实用价值,需要的朋友可以参考下...2020-06-25
  • 深入学习.net验证码生成及使用方法

    这篇文章主要介绍了.net验证码生成及使用方法,先了解验证码是什么以及其作用,最后分享了如何制作验证码,内容很全面,感兴趣的小伙伴们可以参考一下...2021-09-22
  • SpringBoot使用Captcha生成验证码

    这篇文章主要介绍了SpringBoot如何使用Captcha生成验证码,帮助大家更好的理解和学习使用SpringBoot,感兴趣的朋友可以了解下...2021-04-24
  • php 验证码详细生成与使用方法

    注意:以下代码需要打开php教程的gd库,修改php.in文件的配置,把已经注释掉的行之前的分号取消即可:extension=php_gd2.dll。 $width = 165; $height = 120; ...2016-11-25
  • Python利用Pillow(PIL)库实现验证码图片的全过程

    这篇文章主要给大家介绍了关于Python利用Pillow(PIL)库实现验证码图片的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-05