[转载][机器学习]信息&熵&信息增益 - 风痕影默 - 博客园

mikel阅读(769)

来源: [转载][机器学习]信息&熵&信息增益 – 风痕影默 – 博客园

关于对信息、熵、信息增益是信息论里的概念,是对数据处理的量化,这几个概念主要 是在决策树里用到的概念,因为在利用特征来分类的时候会对特征选取顺序的选择,这几个概念比较抽象,我也花了好长时间去理解(自己认为的理解),废话不多 说,接下来开始对这几个概念解释,防止自己忘记的同时,望对其他人有个借鉴的作用,如有错误还请指出。

1、信息

这个是熵和信息增益的基础概念,我觉得对于这个概念的理解更应该把他认为是一用名 称,就比如‘鸡‘(加引号意思是说这个是名称)是用来修饰鸡(没加引号是说存在的动物即鸡),‘狗’是用来修饰狗的,但是假如在鸡还未被命名为’鸡’的时 候,鸡被命名为‘狗’,狗未被命名为‘狗’的时候,狗被命名为’鸡’,那么现在我们看到狗就会称其为‘鸡’,见到鸡的话会称其为‘鸡’,同理,信息应该是 对一个抽象事物的命名,无论用不用‘信息’来命名这种抽象事物,或者用其他名称来命名这种抽象事物,这种抽象事物是客观存在的。

引用香农的话,信息是用来消除随机不确定性的东西,当然这句话虽然经典,但是还是 很难去搞明白这种东西到底是个什么样,可能在不同的地方来说,指的东西又不一样,从数学的角度来说可能更加清楚一些,数学本来就是建造在悬崖之上的一种理 论,一种抽象的理论,利用抽象来解释抽象可能更加恰当,同时也是在机器学习决策树中用的定义,如果带分类的事物集合可以划分为多个类别当中,则某个类 (xi)的信息定义如下:

I(x)用来表示随机变量的信息,p(xi)指是当xi发生时的概率,这里说一下 随机变量的概念,随机变量时概率论中的概念,是从样本空间到实数集的一个映射,样本空间是指所有随机事件发生的结果的并集,比如当你抛硬币的时候,会发生 两个结果,正面或反面,而随机事件在这里可以是,硬币是正面;硬币是反面;两个随机事件,而{正面,反面}这个集合便是样本空间,但是在数学中不会说用 ‘正面’、‘反面’这样的词语来作为数学运算的介质,而是用0表示反面,用1表示正面,而“正面->1”,”反面->0″这样的映射便为随机 变量,即类似一个数学函数。

2、熵

既然信息已经说完,熵说起来就不会那么的抽象,更多的可能是概率论的定义,熵是约翰.冯.诺依曼建议使用的命名(当然是英文),最初原因是因为大家都不知道它是什么意思,在信息论和概率论中熵是对随机变量不确定性的度量,与上边联系起来,熵便是信息的期望值,可以记作:

熵只依赖X的分布,和X的取值没有关系,熵是用来度量不确定性,当熵越大,概率说X=xi的不确定性越大,反之越小,在机器学期中分类中说,熵越大即这个类别的不确定性更大,反之越小,当随机变量的取值为两个时,熵随概率的变化曲线如下图:

当p=0或p=1时,H(p)=0,随机变量完全没有不确定性,当p=0.5时,H(p)=1,此时随机变量的不确定性最大

条件熵

条件熵是用来解释信息增益而引入的概念,概率定义:随机变量X在给定条件下随机变量Y的条件熵,对定义描述为:X给定条件下Y的条件干率分布的熵对X的数学期望,在机器学习中为选定某个特征后的熵,公式如下:

这里可能会有疑惑,这个公式是对条件概率熵求期望,但是上边说是选定某个特征的熵,没错,是选定某个特征的熵,因为一个特征可以将待分类的事物集合分为多类,即一个特征对应着多个类别,因此在此的多个分类即为X的取值。

3、信息增益

信息增益在决策树算法中是用来选择特征的指标,信息增益越大,则这个特征的选择性越好,在概率中定义为:待分类的集合的熵和选定某个特征的条件熵之差(这里只的是经验熵或经验条件熵,由于真正的熵并不知道,是根据样本计算出来的),公式如下:

注意:这里不要理解偏差,因为上边说了熵是类别的,但是在这里又说是集合的熵,没区别,因为在计算熵的时候是根据各个类别对应的值求期望来等到熵

4、信息增益算法(举例,摘自统计学习算法)

训练数据集合D,|D|为样本容量,即样本的个数(D中元素个数),设有K个类 Ck来表示,|Ck|为Ci的样本个数,|Ck|之和为|D|,k=1,2…..,根据特征A将D划分为n个子集D1,D2…..Dn,|Di| 为Di的样本个数,|Di|之和为|D|,i=1,2,….,记Di中属于Ck的样本集合为Dik,即交集,|Dik|为Dik的样本个数,算法如 下:

输入:D,A

输出:信息增益g(D,A)

(1)D的经验熵H(D)

 

此处的概率计算是根据古典概率计算,由于训练数据集总个数为|D|,某个分类的个数为|Ck|,在某个分类的概率,或说随机变量取某值的概率为:|Ck|/|D|

(2)选定A的经验条件熵H(D|A)

 

此处的概率计算同上,由于|Di|是选定特征的某个分类的样本个数, 则|Di|/|D|,可以说为在选定特征某个分类的概率,后边的求和可以理解为在选定特征的某个类别下的条件概率的熵,即训练集为Di,交集Dik可以理 解在Di条件下某个分类的样本个数,即k为某个分类,就是缩小训练集为Di的熵

(3)信息增益

人的潜能都是被逼出来的

mikel阅读(813)

最近手头钱紧,工资不发,网赚项目频频出现变故,结果造成入不敷出,好在有先见之明建立个自己的根据地才不至于吃不起饭,但是也被钱逼得难受。

于是发现人的潜能是无限的,人穷未必智短,只是没有穷到那份儿上,如果真的穷得无路可走的时候,自己拼了老命也会想出出路来,所以说生于忧患,死于安乐。

过去总结自己操作项目的历史,前期穷凶极恶的想项目赚钱的方法,后期找到可行的方法,每日的收入爆棚,然后稳定期,自己就有点儿膨胀了,认为互联网就是我的提款机了,结果忘记了原始资金积累,好在都投资在了其他项目上,没有挥霍消费掉,否则今天的日子会更不好过。

记住一点儿,没有永远赚钱的项目,时刻要两条腿儿走路!

沸腾的年代里不只是互联网热

mikel阅读(938)

从国家刺激创业开始,这个年代就开始沸腾起来,各种激情澎湃的创业者纷至沓来的将民间的积蓄席卷着进入市场,大家都被这突如其来的热钱惹得纷纷侧目,好像不创业就不好意思说自己是这个年代的人一样,各个都想当老板。

互联网+到股市的牛市崛起,就像这个注定不降温的夏日里的太阳,让整个世界都灼热在群情激奋的大潮中,身处大潮中的我们这些在互联网上这么多年的人还能按捺得住吗?从微商到自媒体各个都不敢落后,不知道是红了樱桃还是绿了芭蕉,反正都在忙。

忙什么就不知道有没有价值了,一个概念出来就会崛起一批网站,然后一个概念倒下,也总会剩者为王的留下几个老大,于是就这么此消彼长的类似股票的k线图一样,永远在波涛汹涌的时代的浪潮下淘洗着创业者和利润。

从企业转型到互联网+再到移动互联网的革命,每一个都不只是互联网热,都和传统经济挂钩,总有着千丝万缕的联系,所以说不要听信互联网会革命的说法,什么互联网企业和传统企业的界限会越来越模糊,直至没有,这才是事物发展的规律。

生存还是死亡

mikel阅读(1095)

苦逼到没有朋友的程序猿要生存只能寻找自己的出路,很多人问怎么转型?

有卖果汁的;有卖肉夹馍的;还有卖大饼的;都是媒体报道的,结论只有一个除了干程序干啥都可以发家致富,美其名曰降维逆袭。

可多少转型失败的就不得而知了。反正就是不写程序有可能活,写程序只能苦逼一辈子,要么创业要么等死,悲观的言论弥漫在程序猿的队伍中,混的好的弄个项目经理当当,公司上市弄个原始股东,套现买房买车从此踏上了高富帅的行列;混得不好的只能写一辈子代码,最后加不动班了,只能做个运营维护什么的,就这么一辈子过去了。

所以说横竖都是死,不如创业来的痛快,创业不成还能到什么地步,大不了继续打工了,倒是给自己一个机会,可很多人迈不出这一步,就是因为留恋安逸的朝九晚五的生活,没有创业的压力,老婆孩子热炕头儿的安逸的生活。

当突然一天发现公司开不起自己的工资,自己没了收入来源,银行里还没有存款支付房租的时候,才发现自己这么多年真的是白活了!面对着居高不下的房价,在这个自己土生土长的城市里居然买不起10平方米的落脚地儿的时候,真的不知道自己怎么活过这么多年的?!

所以说生于忧患死于安乐,要么生存要么死亡!自己给自己创造一个生存机会吧!

什么才是核心竞争力?

mikel阅读(1618)

每每创业公司最难得到的是市场,可最终决定市场的东西很多不单单是产品还有营销,市场认可度很高的产品哪个不是披荆斩棘从众多产品中拼搏而出来的。

每个公司都在寻找核心竞争力,从硬件到软件都在寻找,可往往忽略了人的因素,没有合适的人才是真的没有核心竞争力,一个公司要正常运转,在风起云涌的市场中立于不败之地,最重要的是人。

为什么那些大公司出来创业的ceo什么的更容易成功,就在于他们会获得的更多人脉和资源,多少产品是源于一个想法,只有找到合适的人实现了。

最终核心竞争力都是围绕着人来的,产品的因素会越来越小。

[转载]微信授权登录并获取用户信息接口开发 - __kelly_ - 博客园

mikel阅读(1376)

来源: [转载]微信授权登录并获取用户信息接口开发 – __kelly_ – 博客园

近排在做微信接口开发,所以总结一下微信授权登录并获取用户信息 这个接口的开发流程。

一、首先你的微信公众号要获得相应的AppID和AppSecret,申请微信登录且通过审核后,才可开始接入流程。

二、授权流程

1、流程说明

 

(1). 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;

 

 

(2). 通过code参数加上AppID和AppSecret等,通过API换取access_token;

 

(3). 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

2、获取access_token时序图:

三、开发(我的用是CI框架,其实用什么框架都一样,MVC模式就行了)

1、请求CODE

weixin.php


<?php
class weixinController extends CI_Controller {
public $userInfo;
public $wxId;


public function __construct(){
parent::__construct();

//只要用户一访问此模块,就登录授权,获取用户信息
$this->userInfo = $this->getWxUserInfo();
}


/**
* 确保当前用户是在微信中打开,并且获取用户信息
*
* @param string $url 获取到微信授权临时票据(code)回调页面的URL
*/
private function getWxUserInfo($url = '') {
//微信标记(自己创建的)
$wxSign = $this->input->cookie('wxSign');
//先看看本地cookie里是否存在微信唯一标记,
//假如存在,可以通过$wxSign到redis里取出微信个人信息(因为在第一次取到微信个人信息,我会将其保存一份到redis服务器里缓存着)
if (!empty($wxSign)) {
//如果存在,则从Redis里取出缓存了的数据
$userInfo = $this->model->redisCache->getData("weixin:sign_{$wxSign}");
if (!empty($userInfo)) {
//获取用户的openid
$this->wxId = $userInfo['openid'];
//将其存在cookie里
$this->input->set_cookie('wxId', $this->wxId, 60*60*24*7);
return $userInfo;
}
}

//获取授权临时票据(code)
$code = $_GET['code'];
if (empty($code)) {
if (empty($url)) {
$url = rtirm($_SERVER['QUERY_STRING'], '/');
//到WxModel.php里获取到微信授权请求URL,然后redirect请求url
redirect($this->model->wx->getOAuthUrl(baseUrl($url)));
}
}


}












}
?>

获取code的Controller代码

Wxmodel.php


<?php
class WxModel extends ModelBase{
public $appId;
public $appSecret;
public $token;

public function __construct() {
parent::__construct();

//审核通过的移动应用所给的AppID和AppSecret
$this->appId = 'wx0000000000000000';
$this->appSecret = '00000000000000000000000000000';
$this->token = '00000000';
}

/**
* 获取微信授权url
* @param string 授权后跳转的URL
* @param bool 是否只获取openid,true时,不会弹出授权页面,但只能获取用户的openid,而false时,弹出授权页面,可以通过openid获取用户信息
*
*/
public function getOAuthUrl($redirectUrl, $openIdOnly, $state = '') {
$redirectUrl = urlencode($redirectUrl);
$scope = $openIdOnly ? 'snsapi_base' : 'snsapi_userinfo';
$oAuthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->appId}&redirect_uri={$redirectUrl}&response_type=code&scope=$scope&state=$state";
return $oAuthUrl;
}

获取code的Model代码

这里附上请求参数说明和返回值说明

请求参数说明:

 

响应返回值说明:

 

当请求成功,会redirect到请求参数中的redirect_uri的值中去,其实又回到weixin.php 的$this->userInfo = $this->getWxUserInfo();这行去,然后再一次进入到getWxUserInfo()方法,此时

1
2
//获取授权临时票据(code)
$code = $_GET['code'];

这行也已经能获取得到code的值了。接着进行第二步。

 

2、通过code获取access_token

weixin.php


<?php
class weixinController extends CI_Controller {
public $userInfo;
public $wxId;


public function __construct(){
parent::__construct();

//只要用户一访问此模块,就登录授权,获取用户信息
$this->userInfo = $this->getWxUserInfo();
}


/**
* 确保当前用户是在微信中打开,并且获取用户信息
*
* @param string $url 获取到微信授权临时票据(code)回调页面的URL
*/
private function getWxUserInfo($url = '') {
//微信标记(自己创建的)
$wxSign = $this->input->cookie('wxSign');
//先看看本地cookie里是否存在微信唯一标记,
//假如存在,可以通过$wxSign到redis里取出微信个人信息(因为在第一次取到微信个人信息,我会将其保存一份到redis服务器里缓存着)
if (!empty($wxSign)) {
//如果存在,则从Redis里取出缓存了的数据
$userInfo = $this->model->redisCache->getData("weixin:sign_{$wxSign}");
if (!empty($userInfo)) {
//获取用户的openid
$this->wxId = $userInfo['openid'];
//将其存在cookie里
$this->input->set_cookie('wxId', $this->wxId, 60*60*24*7);
return $userInfo;
}
}

//获取授权临时票据(code)
$code = $_GET['code'];
if (empty($code)) {
if (empty($url)) {
$url = rtirm($_SERVER['QUERY_STRING'], '/');
//到WxModel.php里获取到微信授权请求URL,然后redirect请求url
redirect($this->model->wx->getOAuthUrl(baseUrl($url)));
}
}
/***************这里开始第二步:通过code获取access_token****************/
$result = $this->model->wx->getOauthAccessToken($code);

//如果发生错误
if (isset($result['errcode'])) {
return array('msg'=>'授权失败,请联系客服','result'=>$result);
}

//到这一步就说明已经取到了access_token
$this->wxId = $result['openid'];
$accessToken = $result['access_token'];
$openId = $result['openid'];

//将openid和accesstoken存入cookie中
$this->input->set_cookie('wx_id', $this->wxId, 60*60*24*7);
$this->input->set_cookie('access_token', $accessToken);

获取access_token的控制器代码

WxModel.php


<?php
class WxModel extends ModelBase{
public $appId;
public $appSecret;
public $token;

public function __construct() {
parent::__construct();

//审核通过的移动应用所给的AppID和AppSecret
$this->appId = 'wx0000000000000000';
$this->appSecret = '00000000000000000000000000000';
$this->token = '00000000';
}


/**
* 获取微信授权url
* @param string 授权后跳转的URL
* @param bool 是否只获取openid,true时,不会弹出授权页面,但只能获取用户的openid,而false时,弹出授权页面,可以通过openid获取用户信息
*
*/
public function getOAuthUrl($redirectUrl, $openIdOnly, $state = '') {
$redirectUrl = urlencode($redirectUrl);
$scope = $openIdOnly ? 'snsapi_base' : 'snsapi_userinfo';
$oAuthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->appId}&redirect_uri={$redirectUrl}&response_type=code&scope=$scope&state=$state#wechat_redirect";
return $oAuthUrl;
}


/**
* 获取access_token
*/
public function getoAuthAccessToken($code) {
return json_decode(file_get_contents("https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->AppId}&secret={$this->AppSecret}&code={$authCode}&grant_type=authorization_code",true);
}

获取access_token的Model代码

这里附上参数说明

请求参数说明:

 

响应返回值说明:

当返回错误时是这样子的:

 

3、通过access_token调用接口(获取用户信息)
获取access_token后,进行接口调用,有以下前提:

(1)access_tokec有效且未超时;

(2)微信用户已授权给第三方应用账号相应的接口作用域(scope)。

 

以下是获取用户信息的代码

weixin.php


<?php
class weixinController extends CI_Controller {
public $userInfo;
public $wxId;


public function __construct(){
parent::__construct();

//只要用户一访问此模块,就登录授权,获取用户信息
$this->userInfo = $this->getWxUserInfo();
}


/**
* 确保当前用户是在微信中打开,并且获取用户信息
*
* @param string $url 获取到微信授权临时票据(code)回调页面的URL
*/
private function getWxUserInfo($url = '') {
//微信标记(自己创建的)
$wxSign = $this->input->cookie('wxSign');
//先看看本地cookie里是否存在微信唯一标记,
//假如存在,可以通过$wxSign到redis里取出微信个人信息(因为在第一次取到微信个人信息,我会将其保存一份到redis服务器里缓存着)
if (!empty($wxSign)) {
//如果存在,则从Redis里取出缓存了的数据
$userInfo = $this->model->redisCache->getData("weixin:sign_{$wxSign}");
if (!empty($userInfo)) {
//获取用户的openid
$this->wxId = $userInfo['openid'];
//将其存在cookie里
$this->input->set_cookie('wxId', $this->wxId, 60*60*24*7);
return $userInfo;
}
}

//获取授权临时票据(code)
$code = $_GET['code'];
if (empty($code)) {
if (empty($url)) {
$url = rtirm($_SERVER['QUERY_STRING'], '/');
//到WxModel.php里获取到微信授权请求URL,然后redirect请求url
redirect($this->model->wx->getOAuthUrl(baseUrl($url)));
}
}
/***************这里开始第二步:通过code获取access_token****************/
$result = $this->model->wx->getOauthAccessToken($code);

//如果发生错误
if (isset($result['errcode'])) {
return array('msg'=>'授权失败,请联系客服','result'=>$result);
}

//到这一步就说明已经取到了access_token
$this->wxId = $result['openid'];
$accessToken = $result['access_token'];
$openId = $result['openid'];

//将openid和accesstoken存入cookie中
$this->input->set_cookie('wx_id', $this->wxId, 60*60*24*7);
$this->input->set_cookie('access_token', $accessToken);

/*******************这里开始第三步:通过access_token调用接口,取出用户信息***********************/
$this->userInfo = $this->model->wx->getUserInfo($openId, $accessToken);

//自定义微信唯一标识符
$wxSign =substr(md5($this->wxId.'k2a5dd'), 8, 16);
//将其存到cookie里
$this->input->set_cookie('wxSign', $wxSign, 60*60*24*7);
//将个人信息缓存到redis里
$this->library->redisCache->set("weixin:sign_{$wxSign}", $userInfo, 60*60*24*7);
return $userInfo;
}












}
?>

获取用户信息的Controller

WxModel.php


<?php
class WxModel extends ModelBase{
public $appId;
public $appSecret;
public $token;

public function __construct() {
parent::__construct();

//审核通过的移动应用所给的AppID和AppSecret
$this->appId = 'wx0000000000000000';
$this->appSecret = '00000000000000000000000000000';
$this->token = '00000000';
}


/**
* 获取微信授权url
* @param string 授权后跳转的URL
* @param bool 是否只获取openid,true时,不会弹出授权页面,但只能获取用户的openid,而false时,弹出授权页面,可以通过openid获取用户信息
*
*/
public function getOAuthUrl($redirectUrl, $openIdOnly, $state = '') {
$redirectUrl = urlencode($redirectUrl);
$scope = $openIdOnly ? 'snsapi_base' : 'snsapi_userinfo';
$oAuthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->appId}&redirect_uri={$redirectUrl}&response_type=code&scope=$scope&state=$state#wechat_redirect";
return $oAuthUrl;
}


/**
* 获取access_token
*/
public function getoAuthAccessToken($code) {
return json_decode(file_get_contents("https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->AppId}&secret={$this->AppSecret}&code={$authCode}&grant_type=authorization_code",true);
}

/**
* 获取用户信息
*/
public function getUserInfo($openId, $accessToken) {
$url = 'https://api.weixin.qq.com/sns/userinfo';
//获取用户微信账号信息
$userInfo = $this->callApi("$url?access_token=$accessToken&openid=$openId&lang=zh-CN");

if ($userInfo['errcode']) {
return array('msg'=>'获取用户信息失败,请联系客服', $userInfo);
}

$userInfo['wx_id'] = $openId;

return $userInfo;
}

/**
* 发起Api请求,并获取返回结果
* @param string 请求URL
* @param mixed 请求参数 (array|string)
* @param string 请求类型 (GET|POST)
* @return array
*/
public function callApi($apiUrl, $param = array(), $method = 'GET') {
$result = curl_request_json($error, $apiUrl, $params, $method);
//假如返回的数组有错误码,或者变量$error也有值
if (!empty($result['errcode'])) {
$errorCode = $result['errcode'];
$errorMsg = $result['errmsg'];
} else if ($error != false) {
$errorCode = $error['errorCode'];
$errorMsg = $error['errorMessage'];
}

if (isset($errorCode)) {
//将其插入日志文件
file_put_contents("/data/error.log", "callApi:url=$apiUrl,error=[$errorCode]$errorMsg");

if ($errorCode === 40001) {
//尝试更正access_token后重试
try {
$pos = strpos(strtolower($url), 'access_token=');
if ($pos !==false ) {
$pos += strlen('access_token=');
$pos2 = strpos($apiUrl, '&' ,$pos);
$accessTokened = substr($apiUrl, $pos, $pos2 === false ? null : ($pos2 - $pos));
return $this->callApi(str_replace($accessTokened, $this->_getApiToken(true), $apiUrl), $param, $method);
}
}catch (WeixinException $e) {

}
}
//这里抛出异常,具有的就不详说了
throw new WeixinException($errorMessage, $errorCode);
}
return $result;
}

/**
* 获取微信 api 的 access_token 。 不同于 OAuth 中的 access_token ,参见  http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token
*
* @param bool 是否强制刷新 accessToken
*/
private function _getApiToken($forceRefresh = false) {
//先查看一下redis里是否已经缓存过access_token
$accessToken = $this->library->redisCache->get('Weixin:AccessToken');
if($forceRefresh || empty($accessToken)) {
$result = $this->callApi("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appId}&secret={$this->appSecret}");
$accessToken = $result['access_token'];
$expire = max(1, intval($result['expires_in']) - 60);
//将access_token缓存到redis里去
$this->library->redisCache->set('Weixin:AccessToken', $accessToken, $expire);
}
return $accessToken;
}







?>

获取用户信息的Model

Common.php


<?php
/**
*   发起一个HTTP(S)请求,并返回json格式的响应数据
*   @param array 错误信息  array($errorCode, $errorMessage)
*   @param string 请求Url
*   @param array 请求参数
*   @param string 请求类型(GET|POST)
*   @param int 超时时间
*   @param array 额外配置
*
*   @return array
*/
public function curl_request_json(&$error, $url, $param = array(), $method = 'GET', $timeout = 10, $exOptions = null) {
$error = false;
$responseText = curl_request_text($error, $url, $param, $method, $timeout, $exOptions);
$response = null;
if ($error == false && $responseText > 0) {
$response = json_decode($responseText, true);

if ($response == null) {
$error = array('errorCode'=>-1, 'errorMessage'=>'json decode fail', 'responseText'=>$responseText);
//将错误信息记录日志文件里
$logText = "json decode fail : $url";
if (!empty($param)) {
$logText .= ", param=".json_encode($param);
}
$logText .= ", responseText=$responseText";
file_put_contents("/data/error.log", $logText);
}
}
return $response;
}

/**
*  发起一个HTTP(S)请求,并返回响应文本
*   @param array 错误信息  array($errorCode, $errorMessage)
*   @param string 请求Url
*   @param array 请求参数
*   @param string 请求类型(GET|POST)
*   @param int 超时时间
*   @param array 额外配置
*
*   @return string
*/
public function curl_request_text(&$error, $url, $param = array(), $method = 'GET', $timeout = 15, $exOptions = NULL) {
//判断是否开启了curl扩展
if (!function_exists('curl_init')) exit('please open this curl extension');

//将请求方法变大写
$method = strtoupper($method);

$ch = curl_init();
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HEADER, false);
if (isset($_SERVER['HTTP_USER_AGENT'])) curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
if (isset($_SERVER['HTTP_REFERER'])) curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_REFERER']);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
switch ($method) {
case 'POST':
curl_setopt($ch, CURLOPT_POST, true);
if (!empty($param)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, (is_array($param)) ? http_build_query($param) : $param);
}
break;

case 'GET':
case 'DELETE':
if ($method == 'DELETE') {
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
}
if (!empty($param)) {
$url = $url.(strpos($url, '?') ? '&' : '?').(is_array($param) ? http_build_query($param) : $param);
}
break;
}
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_URL, $url);
//设置额外配置
if (!empty($exOptions)) {
foreach ($exOptions as $k => $v) {
curl_setopt($ch, $k, $v);
}
}
$response = curl_exec($ch);

$error = false;
//看是否有报错
$errorCode = curl_errno($ch);
if ($errorCode) {
$errorMessage = curl_error($ch);
$error = array('errorCode'=>$errorCode, 'errorMessage'=>$errorMessage);
//将报错写入日志文件里
$logText = "$method $url: [$errorCode]$errorMessage";
if (!empty($param)) $logText .= ",$param".json_encode($param);
file_put_contents('/data/error.log', $logText);
}

curl_close($ch);

return $response;



}













?>

获取用户信息的自定义函数

通过以上三步调用接口,就可以获取到用户的微信账号信息了。

大家可以认真看看代码, 里面很多地方我都带上了注释,很容易理解。希望想学习的朋友可以认真看看。

 

 

如果此博文有哪里讲得让人难以理解的,欢迎留言交流,如文章有解释出的地方,欢迎指出。

如果您觉得能在此博文学到新知识,请在下方为我顶一个,如文章有解释错的地方,欢迎指出。

互相学习,共同进步!

什么是创新?

mikel阅读(973)

创新不一定是创造出一个没有的东西,创新也不是打破现有的规则,不破不立。

创新也不是只有财力雄厚的大公司才能做的事儿,也不是只有个人主义的类似比尔盖茨、乔布斯这种天才才能做的事儿,每个人都可以,因为创新源于生活,也归于生活,你现实生活中遇到过哪些不顺手的东西,不方便的事都可以是个创新的机会,苹果掉在牛顿头上才有万有引力定律。要有一颗不安分的心才能捕捉到创新的机会。

很喜欢看央视的科技频道的发明创新栏目,那里面很有创新的发明家,他们就是源于生活中的点滴创造发明出提高效率或者方便生活的东西,这是普通老百姓创新出来的。

互联网同样也是创新的摇篮,很多种概念和模式,又有很多的网站出现,从热热闹闹的媒体报道到移动互联网的应用每天都有新的东西出现风靡一时,都是爱创新的人们在做。

网站被移动互联网冲击的不少站长哀叹“站长已死”,我看不见得,只是缺乏创新而已,奶酪被别人动了后才发现自己没了收益,结果一部分人在抱怨台风来的太快,实不知是自己安于安逸而忘记了变化的存在,创新没有了只能等死,网站的模式为什么不能嫁接移动互联网的模式,不是你存我亡的竞争,各取所长融合才是最终的殊途同归的真途径。

android中sharedPreferences的用法

mikel阅读(937)

SharedPreferences介绍:
 

做软件开发应该都知道,很多软件会有配置文件,里面存放这程序运行当中的各个属性值,由于其配置信息并不多,如果采用数据库来存放并不划算,因为数据库连 接跟操作等耗时大大影响了程序的效率,因此我们使用键值这种一一对应的关系来存放这些配置信息。SharedPreferences正是Android中 用于实现这中存储方式的技术。

SharedPreferences的使用非常简单,能够轻松的存放数据和读取数据。SharedPreferences只能保存简单类型的数据,例如,String、int等。一般会将复杂类型的数据转换成Base64编码,然后将转换后的数据以字符串的形式保存在 XML文件中,再用SharedPreferences保存。

 
    使用SharedPreferences保存key-value对的步骤如下:  (1)使用Activity类的getSharedPreferences方法获得SharedPreferences对象,其中存储key-value的文件的名称由getSharedPreferences方法的第一个参数指定。

(2)使用SharedPreferences接口的edit获得SharedPreferences.Editor对象。

(3)通过SharedPreferences.Editor接口的putXxx方法保存key-value对。其中Xxx表示不同的数据类型。例如:字符串类型的value需要用putString方法。

(4)通过SharedPreferences.Editor接口的commit方法保存key-value对。commit方法相当于数据库事务中的提交(commit)操作。

具体代码的书写流程为:

A、存放数据信息

1、打开Preferences,名称为setting,如果存在则打开它,否则创建新的Preferences

SharedPreferences settings = getSharedPreferences(“setting”, 0);

2、让setting处于编辑状态

SharedPreferences.Editor editor = settings.edit();

3、存放数据

editor.putString(“name”,”ATAAW”);
editor.putString(“URL”,”ATAAW.COM”);

4、完成提交

editor.commit();

B、读取数据信息

1、获取Preferences

SharedPreferences settings = getSharedPreferences(“setting”, 0);

2、取出数据

String name = settings.getString(“name”,”默认值”);
String url = setting.getString(“URL”,”default”);

以上就是Android中SharedPreferences的使用方法,其中创建的Preferences文件存放位置可以在Eclipse中查看:

DDMS->File Explorer /<package name>/shared_prefs/setting.xml

主要代码 具体如下(仅供参考):

在onCreate方法中调用restorePrefs()方法:

//读取     功能的实现
   private void restorePrefs() {
 // TODO Auto-generated method stub
    //SharedPreferences是一种轻量级的数据存储方式.是以键值对来存储应用程序的
      //配置信息的一种方式,它只能存储基本数据类型。
    //声明一个优先级设置 类型 settings,载入配置文件
 SharedPreferences settings = getPreferences(BMI.MODE_PRIVATE);

 //使用getXXX函数从优先级设置读取不同类型的内容 得到优先级设置参数的内容
 String pref_height = settings.getString(PREF_HEIGHT, “”);

 //此一句为唤醒记忆语句
  field_height.setText(pref_height);
  field_weight.requestFocus();//设置焦点字段 到“体重”字段上 用户只需直接输入体重数字就可以了

}
  
   //存储    在Activity每次变暗,也就是离开当前屏幕时,记住设置的身高值     即 存储优先级设置
   protected void onPause()
   {
    super.onPause();
    Log.v(“BMI”, “onPause1”);
    //获得SharedPreferences对象
    SharedPreferences settings = getPreferences(BMI.MODE_PRIVATE);
    //获得SharedPreferences.Editor
    SharedPreferences.Editor editor = settings.edit();
    //保存组件的值   为优先级设置填写不同类型的内容
    //用”field_height”界面组件标识符来取得身高的字符串 然后保存到PREF_HEIGHT所代表的优先级设置参数中
    editor.putString(PREF_HEIGHT, field_height.getText().toString());
    //提交保存的结果   将改变写到系统中
    editor.commit();
   }

自媒体不是给别人看的

mikel阅读(1616)

自媒体不是给别人的看的,这就是我的观点,别说做媒体不给别人看的叫什么媒体,的确自媒体也算媒体,就应该有很多人看才能称之为媒体,自媒体的主体是个人,不同于传统媒体是公司运营,自媒体的个人属性决定了内容,很多时候都有着个人观点。

自媒体借助各个平台传播开来,可很多人拘泥于平台,固步自封的是自己,不是别人。每个媒体都需要依附传播渠道,平台只不过是助阵传播的渠道。

从QQ空间到微信、头条各个都是大名鼎鼎的大平台,蜂拥而至的自媒体人后,更加热闹非凡了,管理上也就越加严格。

移动联盟那些事儿

mikel阅读(1064)

很多个人开发者接触最多的就是各种移动联盟,大大小小遍地开花,互联网升级到移动互联网时代的大台风下,更是让很多传统广告联盟看到了商机,于是纷纷入驻移动联盟,也就成就了个人开发者的各种创业传奇,毕竟大家一个有用户,一个有广告,各取所需无可厚非,很公平。

等真正接入了各个联盟的广告后才发现,做开发者赚钱很辛苦,钱一天不到账上,就不是自己的,所有都是联盟说着算,什么提现门槛还有结算周期,人家把握着你的命脉,毕竟辛辛苦苦开发出来的应用上架了,好不容易有了小名气,有人用了,可就是不盈利,接入联盟看着每日收入报表很happy,可怎么就钱没见多呢?!这是个问题也是个难题,联盟不能实时结算要的就是控制资金流速,否则回款不及时要遭殃,毕竟他也只是中间商而已,开发者天天提现,他也受不了,关键还是最终客户的问题,各种挑剔和审查流量,推延支付等等让联盟没办法。最终只能苦了开发者。