广告效果统计
场景二维码获取:
通过浏览器下载
代码如下:
<?php
$appid = "wxd1fc65357aca6efa";
$appsecret = "55a5a3a73b3f1603240a1c27cb0b270f";
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
$jsoninfo = json_decode($output, true);
$access_token = $jsoninfo["access_token"]; //获取access_token
//临时
//$qrcode = '{"expire_seconds": 1800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 10000}}}';
//永久
$qrcode = '{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 7000}}}';
$url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=$access_token";
$result = https_request($url,$qrcode);
$jsoninfo = json_decode($result, true);
$ticket = $jsoninfo["ticket"];
function https_request($url, $data = null){
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
if (!empty($data)){
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
$url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=".urlencode($ticket);
echo $url;
?>
输出url
,然后在浏览器地址栏中访问,就可以下载了。
如图所示:
生成二维码后,将7个二维码放到7个不同的广告投放地,并且引导用户关注,这样才能获得用户关注的相关数据
数据统计
我们需要设计一张表,用于统计存储记录,SQL代码如下:
-- 生成日期: 2018 年 08 月 31 日 19:55
-- 服务器版本: 5.6.23
-- PHP 版本: 5.3.3
SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
--
-- 数据库: `app_dq095`
--
-- --------------------------------------------------------
--
-- 表的结构 `qrcode`
--
CREATE TABLE IF NOT EXISTS `qrcode` (
`id` int(16) NOT NULL AUTO_INCREMENT,
`scene` varchar(6) NOT NULL COMMENT '场景',
`year` varchar(4) NOT NULL COMMENT '年',
`month` varchar(2) NOT NULL COMMENT '月',
`day` varchar(2) NOT NULL COMMENT '日',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
--
-- 转存表中的数据 `qrcode`
--
INSERT INTO `qrcode` (`id`, `scene`, `year`, `month`, `day`) VALUES
(1, '7000', '2018', '08', '31'),
(2, ' 4000', '2018', '08', '31'),
(3, ' 6000', '2018', '08', '31'),
(4, ' 6000', '2018', '08', '31');
连接数据库,定义class_mysql类,如下所示:
<?php
class class_mysql
{
function __construct(){
//用 户 名 : $user
//密 码 : $pwd
//主库域名 : $host
//从库域名 : SAE_MYSQL_HOST_S
//端 口 : $port
//数据库名 : $dbname
$dbname = "app_dq095";
$host = "w.rdc.sae.sina.com.cn";
$port = "3306";
$user = "4k514n103z";
$pwd = "2402314li2j1i5im1xy2xizj5y332w2x41k2z203";
/*接着调用mysql_connect()连接服务器*/
$db = mysql_connect($host,$user,$pwd);
if(!$db){
die("Connect Server Failed: " . mysql_error($db));
}
/*连接成功后立即调用mysql_select_db()选中需要连接的数据库*/
if (!mysql_select_db($dbname)) {
die("Select Database Failed: " . mysql_error($db));
}
mysql_query("set names utf-8",$db);
return $db;
}
//返回数组
function query_array($sql){
$result = mysql_query($sql);
if(!$result)return false;
$arr = array();
while ($row = mysql_fetch_assoc($result)) {
$arr[] = $row;
}
return $arr;
}
//只执行
function query($sql)
{
if (!($query = mysql_query($sql))){
return false;
}
return $query;
}
}
当用户关注二维码的时候,后台根据关注时间消息,将该二维码的值写入数据库中。事件相应部分代码如下:
private function receiveEvent($object)
{
$content = "";
switch ($object->Event)
{
case "subscribe":
$content = "欢迎关注 德强1012";
if (!empty($object->EventKey)){
$sceneid = str_replace("qrscene_"," ",$object->EventKey);
require_once('coon.php');
$db = new class_mysql();
$sql = "INSERT INTO `qrcode` (`id`, `scene`, `year`, `month`, `day`) VALUES (NULL, '".$sceneid."', '".date("Y")."', '".date("m")."', '".date("d")."')";
$db->query($sql);
}
break;
case "unsubscribe":
$content = "取消关注";
break;
case "SCAN":
$content = "扫描场景 ".$object->EventKey;
break;
default:
break;
}
if (is_array($content)){
$result = $this->transmitNews($object, $content);
}else{
$result = $this->transmitText($object, $content);
}
return $result;
}
这样就能统计到用户关注的数据了。
mysql中最终存储的数据如下所示:
我们使用SQL语句来获取统计数据。
代码如下:
select count(scene) ,scene from qrcode where year=2018 and month=08 group by scene;
如图所示:
我们使用JpGroup来生成统计图
JpGroup是PHP下的一个面向对象的图表创建工具,你只需从数据中读取相关数据,定义标题,图表类型,就能轻松画出折线图,柱形图,饼状图等图表。官方网站为:https://jpgraph.net/
。
下面是用8月分场景统计数据创建的一个柱形统计图
代码如下:
<?php
// content="text/plain; charset=utf-8"
require_once ('jpgraph/jpgraph.php');
require_once ('jpgraph/jpgraph_bar.php');
require_once ('jpgraph/jpgraph_line.php');
// 数据
$data_follow = array(140,110,77,104,29,161,13);
// 构造对象
$graph = new Graph(320,440); //屏幕分辨率
// 基本参数
$graph->SetScale("textlin"); //线性标尺
$graph->SetY2Scale('lin',0,100); //对数
$graph->Set90AndMargin(50,0,65,0); //旋转90度
$graph->yaxis->SetTitleMargin(25);
// 标题与字体
$graph->title->Set("Scene Analysis");
$graph->title->SetFont(FF_FONT1,FS_BOLD);
$graph->xaxis->title->Set("Sce");
$graph->yaxis->title->Set("Num");
$graph->y2axis->SetColor('black','blue');
$graph->y2axis->SetLabelFormat('%2d');
// 生成柱状图
$bplot = new BarPlot($data_follow);
$bplot->SetFillColor("orange@0.2");
$bplot->SetValuePos('center');
$bplot->value->SetFormat("%d");
$bplot->value->SetFont(FF_ARIAL,FS_NORMAL,9);
$bplot->value->Show();
// 柱状图叠到图形中
$graph->Add($bplot);
// 生成图形
return $graph->Stroke();
?>
折线柱形统计图:
代码如下:
<?php
// content="text/plain; charset=utf-8"
require_once ('jpgraph/jpgraph.php');
require_once ('jpgraph/jpgraph_bar.php');
require_once ('jpgraph/jpgraph_line.php');
// some data
$data_weight = array(120,130,123,100,150,160,170,200,220,240);
$data_fat = array(22,20,12,16,15,24,37,39,40,44);
// Create the graph.
$graph = new Graph(250,400);
// $graph->SetAngle(90);
// Setup some basic graph parameters
$graph->SetScale("textlin");
$graph->SetY2Scale('lin',0,100);
// $graph->img->SetMargin(50,70,30,40);
$graph->Set90AndMargin(40,40,60,40);
$graph->yaxis->SetTitleMargin(30);
$graph->SetMarginColor('#EEEEEE');
// $title = iconv("UTF-8", "gb2312", $title);
// Setup titles and fonts
$graph->title->Set("Health Monitor");
$graph->xaxis->title->Set("T");
$graph->yaxis->title->Set("W");
$graph->title->SetFont(FF_FONT1,FS_BOLD);
// Turn the tickmarks
$graph->xaxis->SetTickSide(SIDE_DOWN);
$graph->yaxis->SetTickSide(SIDE_LEFT);
$graph->y2axis->SetTickSide(SIDE_RIGHT);
$graph->y2axis->SetColor('black','blue');
$graph->y2axis->SetLabelFormat('%2d.0');
// Create a bar pot
$bplot = new BarPlot($data_weight);
// Create accumulative graph
$lplot = new LinePlot($data_fat);
// We want the line plot data point in the middle of the bars
$lplot->SetBarCenter();
// Use transperancy
$lplot->SetFillColor('lightblue@0.6');
$lplot->SetColor('blue@0.6');
$graph->AddY2($lplot);
// Setup the bars
$bplot->SetFillColor("orange@0.2");
$bplot->SetValuePos('center');
$bplot->value->SetFormat("%d");
$bplot->value->SetFont(FF_ARIAL,FS_NORMAL,9);
$bplot->value->Show();
// Add it to the graph
$graph->Add($bplot);
// Send back the HTML page which will call this script again
// to retrieve the image.
return $graph->Stroke();
?>
index.php整体代码如下:
<?php
/*
CopyRight 2018 All Rights Reserved
*/
define("TOKEN", "weixin");
$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET['echostr'])) {
$wechatObj->responseMsg();
}else{
$wechatObj->valid();
}
class wechatCallbackapiTest
{
public function valid()
{
$echoStr = $_GET["echostr"];
if($this->checkSignature()){
echo $echoStr;
exit;
}
}
private function checkSignature()
{
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
if($tmpStr == $signature){
return true;
}else{
return false;
}
}
public function responseMsg()
{
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
if (!empty($postStr)){
$this->logger("R ".$postStr);
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$RX_TYPE = trim($postObj->MsgType);
switch ($RX_TYPE)
{
case "event":
$result = $this->receiveEvent($postObj);
break;
case "text":
$result = $this->receiveText($postObj);
break;
}
$this->logger("T ".$result);
echo $result;
}else {
echo "";
exit;
}
}
private function receiveEvent($object)
{
$content = "";
switch ($object->Event)
{
case "subscribe":
$content = "欢迎关注 德强1012";
if (!empty($object->EventKey)){
$sceneid = str_replace("qrscene_"," ",$object->EventKey);
require_once('coon.php');
$db = new class_mysql();
$sql = "INSERT INTO `qrcode` (`id`, `scene`, `year`, `month`, `day`) VALUES (NULL, '".$sceneid."', '".date("Y")."', '".date("m")."', '".date("d")."')";
$db->query($sql);
}
break;
case "unsubscribe":
$content = "取消关注";
break;
case "SCAN":
$content = "扫描场景 ".$object->EventKey;
break;
default:
break;
}
if (is_array($content)){
$result = $this->transmitNews($object, $content);
}else{
$result = $this->transmitText($object, $content);
}
return $result;
}
private function receiveText($object)
{
$keyword = trim($object->Content);
include("airquality.php");
$content = getAirQualityChina($keyword);
if(is_array($content)){
$result = $this->transmitNews($object, $content);
}else{
$result = $this->transmitText($object, $content);
}
return $result;
}
private function transmitText($object, $content)
{
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
$result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);
return $result;
}
private function transmitNews($object, $arr_item)
{
if(!is_array($arr_item))
return;
$itemTpl = " <item>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
<PicUrl><![CDATA[%s]]></PicUrl>
<Url><![CDATA[%s]]></Url>
</item>
";
$item_str = "";
foreach ($arr_item as $item)
$item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);
$newsTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<Content><![CDATA[]]></Content>
<ArticleCount>%s</ArticleCount>
<Articles>
$item_str</Articles>
</xml>";
$result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($arr_item));
return $result;
}
private function logger($log_content)
{
if(isset($_SERVER['HTTP_BAE_ENV_APPID'])){ //BAE
require_once "BaeLog.class.php";
$logger = BaeLog::getInstance();
$logger ->logDebug($log_content);
}else if(isset($_SERVER['HTTP_APPNAME'])){ //SAE
sae_set_display_errors(false);
sae_debug($log_content);
sae_set_display_errors(true);
}else if($_SERVER['REMOTE_ADDR'] != "127.0.0.1"){ //LOCAL
$max_size = 10000;
$log_filename = "log.xml";
if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);}
file_put_contents($log_filename, date('H:i:s')." ".$log_content."\r\n", FILE_APPEND);
}
}
}
?>