在CI框架下面實現了自定義菜單功能.寫了一個model,一個類庫.順便附帶access_token的實現方式php
<?php class Makemenu{ public $menustr; public function __construct(){ } public function init(){ $this->dolist(); return $this->setmenu(); } private function dolist(){ $CI =& get_instance(); $CI -> load ->model("Menu_model","menu"); $plist = $CI->menu ->isplist(); foreach($plist as $pid){ $pidarr[] = $pid['pid']; } $list = $CI->menu ->maketree($CI->menu->getlist()); foreach($list as $btn){ if(in_array($btn['id'],$pidarr)){ //生成不帶key和url的連接做爲父級菜單 $btn_arr[$btn['id']] = array("type"=>$btn['menutype'], "name"=>$btn['content']); }elseif($btn['pid'] == 0){ //生成有操做的一級菜單 $btn_arr[$btn['id']] = array("type"=>$btn['menutype'], "name"=>$btn['content'], "key"=>$btn['clickkey'], "url"=>$btn['url']); }else{ //生成子菜單 $btn_arr[$btn['pid']]['sub_button'][] = array("type"=>$btn['menutype'], "name"=>$btn['content'], "key"=>$btn['clickkey'], "url"=>$btn['url']); } } $btnarr['button'] = array_values($btn_arr); $r = $this->menustr = json_encode($btnarr,JSON_UNESCAPED_UNICODE); return $r; } private function setmenu(){ $accesstoken = get_access_token(); $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={$accesstoken}"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_AUTOREFERER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $this->menustr); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $info = curl_exec($ch); if (curl_errno($ch)) { return curl_error($ch); } curl_close($ch); return $info; } }
上面是library裏面的內容,主要是根據數據表生成菜單的json串sql
<?php class Menu_model extends CI_Model { public $table_name; public function __construct(){ parent::__construct(); $this->load->database(); $this->table_name = "data_menu"; } public function query($sql){ return $this->db->query($sql); } public function getone($id){ $get_sql = "select * from {$this->table_name} where id = {$id}"; return $this->query($get_sql)->row(); } public function addone($data){ if(($data['pid'] == 0)&&($this->checksum()>=3)){ //一級菜單不超過3個 return "toomany1"; }elseif(($data['pid']!=0)&&($this->checksum($data['pid']))>=7){ //二級菜單不超過7個 return "toomany2"; } if(is_array($data)&&!empty($data)){ $keys = "`".implode("`,`",array_keys($data))."`"; $vals = "'".implode("','",array_values($data))."'"; $insert_sql = "insert into {$this->table_name} ($keys) values ($vals)"; return $this->query($insert_sql); }else{ return false; } } public function del($id){ $infos = $this->getone($id); $del_sql = "delete from {$this->table_name} where id = {$id} and pid = {$id}"; return $this->query($del_sql); } private function checksum($id = ''){ if($id == ''){ $get_sql = "select count(1) as total from {$this->table_name} where pid =0"; }else{ $id = intval($id); $get_sql = "select count(1) as total from {$this->table_name} where pid ={$id}"; } $r = $this->db->query($get_sql)->row(); return $r->total; } public function getplist(){ //獲取一級菜單 $get_sql = "select * from {$this->table_name} where pid=0 order by menuorder asc"; return $this->db->query($get_sql)->result_array(); } public function isplist(){ $get_sql = "select pid from {$this->table_name} where pid <> 0 group by pid"; return $this->db->query($get_sql)->result_array(); } public function getlist(){ $get_sql = "select * from {$this->table_name} where 1 order by pid asc, menuorder asc"; return $this->db->query($get_sql)->result_array(); } public function maketree($data){ $pids = array(); foreach($data as $k=>$v){ if($v['pid'] == 0){ $pids[$v['id']][] = $v; }else{ $pids[$v['pid']][] = $v; } } list($t1,$t2,$t3) = array_values($pids); $r = array_merge_recursive(is_array($t1)?$t1:array(),is_array($t2)?$t2:array(),is_array($t3)?$t3:array()); return $r; } public function update($data){ if(is_array($data)&&!empty($data)){ $id = $data['id']; unset($data['id']); foreach($data as $k=>$v){ $update_arr[] = "`".$k."` = '".$v."'"; } $update_fs = implode(",",$update_arr); $update_sql = "update {$this->table_name} set {$update_fs} where id = {$id}"; return $this->query($update_sql); }else{ return false; } } }
上面是model裏面的各類方法.數據庫
數據庫的表結構以下,附建立表的語句.json
CREATE TABLE `menu` ( `id` int(11) NOT NULL AUTO_INCREMENT, `content` varchar(20) DEFAULT NULL, `pid` int(11) DEFAULT '0', `menutype` enum('click','view','scancode_push','scancode_waitmsg','pic_sysphoto','pic_photo_or_album','pic_weixin','location_select') DEFAULT 'view' COMMENT '消息類型', `url` varchar(200) DEFAULT NULL COMMENT '連接地址', `clickkey` varchar(20) DEFAULT NULL COMMENT '事件KEY', `menuorder` int(11) DEFAULT NULL COMMENT '排序', `submenu` tinyint(2) DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8
Field | Type | Comment | |
主鍵 | id | int(11) NOT NULL | <ID> |
content | varchar(20) NULL | <內容> | |
pid | int(11) NULL | <父類ID> | |
menutype | enum('click','view','scancode_push','scancode_waitmsg','pic_sysphoto','pic_photo_or_album','pic_weixin','location_select') NULL | 消息類型 | |
url | varchar(200) NULL | 連接地址 | |
clickkey | varchar(20) NULL | 事件KEY | |
menuorder | int(11) NULL | 排序 | |
submenu | tinyint(2) NULL | <是不是子菜單> |
下面是寫在system/core/common.php下面的獲取token的方法,其實要作一個加鹽處理,要麼會有噁心的人作惡心的事情.api
function get_access_token(){ //從微信服務器獲取access_token 並保留一個小時 $old_filename = APPPATH."cache/".md5(date("YmdH",time()-3600)).".php"; @unlink($old_filename); $filename = APPPATH."cache/".md5(date("YmdH",time())).".php"; if(is_file($filename)){ $r = include($filename); }else{ $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".APPID."&secret=".APPSECRET; $access_token = file_get_contents($url); $res = "<?php return ".var_export(json_decode($access_token,1),1).";"; file_put_contents($filename,$res); $r = include($filename); } return ($r['access_token']); }
前面的菜單管理就不寫了,就是管理那個表的數據,保證數據表裏面的數據沒問題便可.服務器
在控制器裏面只須要微信
$this->load->library("Makemenu");app
而後調用 $this->makemenu->dolist();框架
就會推送到微信的服務器. 還須要注意在入口文件定義兩個常量 APPID和APPSECRET .curl
放出來給你們,但願有用,也給我本身備份個.