thinkphp 实现多数据库 连接 解决办法

一、全局配置定义

return array(
    'DB_TYPE' => 'mysql',
    'DB_HOST' => '127.0.0.1',
    'DB_NAME' => 'thinkcmf',
    'DB_USER' => 'root',
    'DB_PWD' => 'root',
    'DB_PORT' => '3306',
    'DB_PREFIX' => 'cmf_',
    //密钥
    "AUTHCODE" => '2oF6v4m67BdQnfwMSf',
    //cookies
    "COOKIE_PREFIX" => '03a9uH_',
);

如果我们已经在配置文件中配置了额外的数据库连接信息,例如:

return array(
    //数据库1
    'DB_TYPE' => 'mysql',
    'DB_HOST' => '127.0.0.1',
    'DB_NAME' => 'thinkcmf',
    'DB_USER' => 'root',
    'DB_PWD' => 'root',
    'DB_PORT' => '3306',
    'DB_PREFIX' => 'cmf_',
    //密钥
    "AUTHCODE" => '2oF6v4m67BdQnfwMSf',
    //cookies
    "COOKIE_PREFIX" => '03a9uH_',
    //数据库2
    'DB_CONFIG2' => array(
        'db_type'  => 'mysql',
        'db_user'  => 'root',
        'db_pwd'   => 'root',
        'db_host'  => '127.0.0.1',
        'db_port'  => '3306',
        'db_name'  => 'repast'
       ),
    );

二、实例化定义

$User = M('User','cmf_','DB_CONFIG2');

第三方登录接口实现 thinkphp 微信登陆 qq登陆 微博登陆

<?php

class PassportAction extends CommonAction{
private $create_fields = array(‘account’, ‘password’, ‘nickname’);
public function register(){
if ($this->isPost()) {
if (isMobile(htmlspecialchars($_POST[‘account’]))) {
if (!($scode = trim($_POST[‘scode’]))) {
$this->fengmiMsg(‘请输入短信验证码!’);
}
$scode2 = session(‘scode’);
if (empty($scode2)) {
$this->fengmiMsg(‘请获取短信验证码!’);
}
if ($scode != $scode2) {
$this->fengmiMsg(‘请输入正确的短信验证码!’);
}
}
$data = $this->createCheck();
$invite_id = (int) cookie(‘invite_id’);
if (!empty($invite_id)) {
$data[‘invite_id’] = $invite_id;
}
$password2 = $this->_post(‘password2’);
if ($password2 !== $data[‘password’]) {
$this->fengmiMsg(‘两次密码不一致’);
}
//开始其他的判断了
if (true == D(‘Passport’)->register($data)) {
$this->fengmiMsg(‘恭喜您,注册成功!’, U(‘index/index’));
}
$this->error(D(‘Passport’)->getError());
} else {
//分销开始
$fuid = (int) cookie(‘fuid’);
if ($fuid) {
$profit_min_rank_id = (int) $this->_CONFIG[‘site’][‘profit_min_rank_id’];
$fuser = D(‘Users’)->find($fuid);
if ($fuser) {
$flag = false;
if ($profit_min_rank_id) {
$modelRank = D(‘Userrank’);
$rank = $modelRank->find($profit_min_rank_id);
$userRank = $modelRank->find($fuser[‘rank_id’]);
if ($rank) {
if ($userRank && $userRank[‘prestige’] >= $rank[‘prestige’]) {
$flag = true;
} else {
$flag = false;
}
} else {
$flag = false;
}
} else {
$flag = true;
}
$fuser[‘nickname’] = empty($fuser[‘nickname’]) ? $fuser[‘account’] : $fuser[‘nickname’];
if ($flag) {
$this->assign(‘fuser’, $fuser);
}
}
}
//分销结束
$this->display();
}
}

private function createCheck(){
$data = $this->checkFields($this->_post(‘data’, false), $this->create_fields);
$data[‘fuid1’] = htmlspecialchars($_POST[‘fuid1’]);//微信自动分享
$data[‘account’] = htmlspecialchars($_POST[‘account’]);
if (!isMobile($data[‘account’])) {
session(‘verify’, null);
$this->fengmiMsg(‘只允许手机号注册,请检查~’);
}
$data[‘password’] = htmlspecialchars($data[‘password’]);
//整合UC的时候需要
$register_password = $this->_CONFIG[‘register’][‘register_password’];
if (empty($data[‘password’]) || strlen($data[‘password’]) < $register_password) {
session(‘verify’, null);
$this->fengmiMsg(‘请输入正确的密码!密码长度必须要在’ . $register_password . ‘个字符以上’, 2000, true);
}
$data[‘nickname’] = $data[‘account’];
$data[‘token’] = $data[‘token’];
$data[‘ext0’] = $data[‘account’];
//兼容UCENTER
$data[‘mobile’] = $data[‘account’];
$data[‘reg_ip’] = get_client_ip();
$data[‘reg_time’] = NOW_TIME;
return $data;
}

public function sendsms() {
if (!($mobile = htmlspecialchars($_POST[‘mobile’]))) {
die(‘请输入正确的手机号码’);
}
if (!isMobile($mobile)) {
die(‘请输入正确的手机号码’);
}
if ($user = D(‘Users’)->getUserByAccount($mobile)) {
die(‘手机号码已经存在!’);
}
$randstring = session(‘scode’);
if (empty($randstring)) {
$randstring = rand_string(6, 1);
session(‘scode’, $randstring);
}

//大鱼短信蜂蜜独家
if($this->_CONFIG[‘sms’][‘dxapi’] == ‘dy’){
D(‘Sms’)->DySms($this->_CONFIG[‘site’][‘sitename’], ‘sms_yzm’, $mobile, array(‘sitename’=>$this->_CONFIG[‘site’][‘sitename’],’code’ => $randstring));
}else{
D(‘Sms’)->sendSms(‘sms_code’, $mobile, array(‘code’ => $randstring));
}
//end
die(‘1’);
}
public function bind()
{
$this->display();
}
public function index()
{
$this->redirect(‘login’);
}
public function login() {
if ($this->isPost()) {
$account = $this->_post(‘account’);
if (empty($account)) {
$this->fengmiMsg(‘请输入用户名!’);
}
$password = $this->_post(‘password’);
if (empty($password)) {
$this->fengmiMsg(‘请输入登录密码!’);
}
$backurl = $this->_post(‘backurl’, ‘htmlspecialchars’);
if (empty($backurl)) {
$backurl = U(‘mcenter/index/index’);
}
if (true == D(‘Passport’)->login($account, $password)) {
$this->fengmiMsg(‘恭喜您登录成功!’, $backurl);
} else {
$this->fengmiMsg(D(‘Passport’)->getError());
}
} else {
if (!empty($_SERVER[‘HTTP_REFERER’]) && strstr($_SERVER[‘HTTP_REFERER’], $_SERVER[‘HTTP_HOST’]) && !strstr($_SERVER[‘HTTP_REFERER’], ‘passport’)) {
$backurl = $_SERVER[‘HTTP_REFERER’];
} else {
$backurl = U(‘mcenter/index/index’);
}
$this->assign(‘backurl’, $backurl);
$this->display();
}
}

public function wblogin()
{
$login_url = ‘https://api.weibo.com/oauth2/authorize?client_id=’ . $this->_CONFIG[‘connect’][‘wb_app_id’] . ‘&response_type=code&redirect_uri=’ . urlencode(__HOST__ . U(‘passport/wbcallback’));
header(“Location:{$login_url}”);
die;
}
public function qqlogin()
{
$state = md5(uniqid(rand(), TRUE));
session(‘state’, $state);
$login_url = ‘https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=’ . $this->_CONFIG[‘connect’][‘qq_app_id’] . ‘&redirect_uri=’ . urlencode(__HOST__ . U(‘passport/qqcallback’)) . ‘&state=’ . $state . ‘&scope=’;
header(“Location:{$login_url}”);
die;
}
public function wxlogin()
{
$state = md5(uniqid(rand(), TRUE));
cookie(‘wx_back_url’, $_SERVER[‘HTTP_REFERER’]);
session(‘state’, $state);
$login_url = ‘https://open.weixin.qq.com/connect/oauth2/authorize?appid=’ . $this->_CONFIG[‘weixin’][‘appid’] . ‘&redirect_uri=’ . urlencode(__HOST__ . U(‘passport/wxcallback’)) . ‘&response_type=code&scope=snsapi_base&state=’ . $state . ‘#wechat_redirect’;
header(“Location:{$login_url}”);
die;
}
public function wbcallback()
{
import(‘@/Net.Curl’);
$curl = new Curl();
$params = array(‘grant_type’ => ‘authorization_code’, ‘code’ => $_REQUEST[‘code’], ‘client_id’ => $this->_CONFIG[‘connect’][‘wb_app_id’], ‘client_secret’ => $this->_CONFIG[‘connect’][‘wb_app_key’], ‘redirect_uri’ => __HOST__ . U(‘passport/qqcallback’));
$url = ‘https://api.weibo.com/oauth2/access_token’;
$response = $curl->post($url, http_build_query($params));
$params = json_decode($response, true);
if (isset($params[‘error’])) {
echo ‘<h3>error:</h3>’ . $params[‘error’];
echo ‘<h3>msg :</h3>’ . $params[‘error_code’];
die;
}
$url = ‘https://api.weibo.com/2/account/get_uid.json?source=’ . $this->_CONFIG[‘connect’][‘wb_app_key’] . ‘&access_token=’ . $params[‘access_token’];
$result = $curl->get($url);
$user = json_decode($result, true);
if (isset($user[‘error’])) {
echo ‘<h3>error:</h3>’ . $user[‘error’];
echo ‘<h3>msg :</h3>’ . $user[‘error_code’];
die;
}
$data = array(‘type’ => ‘weibo’, ‘open_id’ => $user[‘uid’], ‘token’ => $params[‘access_token’]);
$this->thirdlogin($data);
}
public function wxcallback()
{
if ($_REQUEST[‘state’] == session(‘state’)) {
import(‘@/Net.Curl’);
$curl = new Curl();
if (empty($_REQUEST[‘code’])) {
$this->error(‘授权后才能登陆!’, U(‘passport/login’));
}
$token_url = ‘https://api.weixin.qq.com/sns/oauth2/access_token?appid=’ . $this->_CONFIG[‘weixin’][‘appid’] . ‘&secret=’ . $this->_CONFIG[‘weixin’][‘appsecret’] . ‘&code=’ . $_REQUEST[‘code’] . ‘&grant_type=authorization_code’;
$str = $curl->get($token_url);
$params = json_decode($str, true);
if (!empty($params[‘errcode’])) {
echo ‘<h3>error:</h3>’ . $params[‘errcode’];
echo ‘<h3>msg :</h3>’ . $params[‘errmsg’];
die;
}
if (empty($params[‘openid’])) {
$this->error(‘登录失败’, U(‘passport/login’));
}
$data = array(‘type’ => ‘weixin’, ‘open_id’ => $params[‘openid’], ‘token’ => $params[‘refresh_token’]);
$this->thirdlogin($data);
}
}
public function qqcallback()
{
import(‘@/Net.Curl’);
$curl = new Curl();
if ($_REQUEST[‘state’] == session(‘state’)) {
$token_url = ‘https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&’ . ‘client_id=’ . $this->_CONFIG[‘connect’][‘qq_app_id’] . ‘&redirect_uri=’ . urlencode(__HOST__ . U(‘passport/qqcallback’)) . ‘&client_secret=’ . $this->_CONFIG[‘connect’][‘qq_app_key’] . ‘&code=’ . $_REQUEST[‘code’];
$response = $curl->get($token_url);
if (strpos($response, ‘callback’) !== false) {
$lpos = strpos($response, ‘(‘);
$rpos = strrpos($response, ‘)’);
$response = substr($response, $lpos + 1, $rpos – $lpos – 1);
$msg = json_decode($response);
echo ‘<h3>error:</h3>’ . $msg->error;
echo ‘<h3>msg :</h3>’ . $msg->error_description;
die;
}
$params = array();
parse_str($response, $params);
if (empty($params)) {
die;
}
$graph_url = ‘https://graph.qq.com/oauth2.0/me?access_token=’ . $params[‘access_token’];
$str = $curl->get($graph_url);
if (strpos($str, ‘callback’) !== false) {
$lpos = strpos($str, ‘(‘);
$rpos = strrpos($str, ‘)’);
$str = substr($str, $lpos + 1, $rpos – $lpos – 1);
}
$user = json_decode($str, true);
if (isset($user[‘error’])) {
echo ‘<h3>error:</h3>’ . $user[‘error’];
echo ‘<h3>msg :</h3>’ . $user[‘error_description’];
die;
}
if (empty($user[‘openid’])) {
die;
}
$data = array(
‘type’ => ‘qq’,
‘client_id’=>$user[‘client_id’],
‘open_id’ => $user[‘openid’],
‘token’ => $params[‘access_token’]
);
$this->thirdlogin($data);
}
}
public function wxstart() {
if ($_REQUEST[‘state’] == session(‘state’)) {
import(‘@/Net.Curl’);
$curl = new Curl();
if (empty($_REQUEST[‘code’])) {
$this->error(‘授权后才能登陆!’, U(‘passport/login’));
}
$token_url = ‘https://api.weixin.qq.com/sns/oauth2/access_token?appid=’ . $this->_CONFIG[‘weixin’][‘appid’] . ‘&secret=’ . $this->_CONFIG[‘weixin’][‘appsecret’] . ‘&code=’ . $_REQUEST[‘code’] . ‘&grant_type=authorization_code’;
$str = $curl->get($token_url);
$params = json_decode($str, true);
if (!empty($params[‘errcode’])) {
echo ‘<h3>error:</h3>’ . $params[‘errcode’];
echo ‘<h3>msg :</h3>’ . $params[‘errmsg’];
die;
}
if (empty($params[‘openid’])) {
$this->error(‘登录失败’, U(‘passport/login’));
}
$info_url = ‘https://api.weixin.qq.com/sns/userinfo?access_token=’ . $params[‘access_token’] . ‘&openid=’ . $params[‘openid’] . ‘&lang=zh_CN’;
$info = $curl->get($info_url);
$info = json_decode($info, true);
$data = array(‘type’ => ‘weixin’, ‘open_id’ => $params[‘openid’], ‘token’ => $params[‘refresh_token’], ‘nickname’ => $info[‘nickname’], ‘headimgurl’ => $info[‘headimgurl’]);
$this->wxconn($data);
}
}
//微信自动注册为用户
private function wxconn($data)
{
$connect = D(‘Connect’)->getConnectByOpenid($data[‘type’], $data[‘open_id’]);
if (empty($connect)) {
$connect = $data;
$connect[‘connect_id’] = D(‘Connect’)->add($data);
} else {
D(‘Connect’)->save(array(‘connect_id’ => $connect[‘connect_id’], ‘token’ => $data[‘token’], ‘nickname’ => $data[‘nickname’]));
}
if (empty($connect[‘uid’])) {
session(‘connect’, $connect[‘connect_id’]);
// 用户数据整理
$host = explode(‘.’, $this->_CONFIG[‘site’][‘host’]);
$account = uniqid() . ‘@’ . $host[1] . ‘.’ . $host[2];
if ($data[‘nickname’] == ”) {
$nickname = $data[‘type’] . $connect[‘connect_id’];
} else {
$nickname = $data[‘nickname’];
}
$user = array(‘account’ => $account, ‘password’ => rand(10000000, 999999999), ‘nickname’ => $nickname, ‘ext0’ => $account, ‘face’ => $data[‘headimgurl’], ‘token’ => $data[‘token’], ‘reg_time’ => NOW_TIME, ‘reg_ip’ => get_client_ip());
//注册用户资料
if (!D(‘Passport’)->register($user)) {
$this->error(‘创建帐号失败’);
}
// 注册第三方接口
$token = D(‘Passport’)->getToken();
$connect[‘uid’] = $token[‘uid’];
D(‘Connect’)->save(array(‘connect_id’ => $connect[‘connect_id’], ‘uid’ => $connect[‘uid’]));
// 注册成功智能跳转
$backurl = session(‘backurl’);
if (!empty($backurl)) {
header(“Location:{$backurl}”);
} else {
header(‘Location:’ . U(‘index/index’));
}
} else {
setuid($connect[‘uid’]);
session(‘access’, $connect[‘connect_id’]);
// 注册成功智能跳转
$backurl = session(‘backurl’);
if (!empty($backurl)) {
header(“Location:{$backurl}”);
} else {
header(‘Location:’ . U(‘index/index’));
}
}
die;
}
private function thirdlogin($data)
{
if ($this->_CONFIG[‘connect’][‘debug’]) {
//调试状态下 可以直接就登录 不是调试状态就要走绑定用户名的流程
//$data[‘type’] = ‘test’;
//DEBUG状态是直接登录
$connect = D(‘Connect’)->getConnectByOpenid($data[‘type’], $data[‘open_id’]);
if (empty($connect)) {
$connect = $data;
$connect[‘connect_id’] = D(‘Connect’)->add($data);
} else {
D(‘Connect’)->save(array(‘connect_id’ => $connect[‘connect_id’], ‘token’ => $data[‘token’]));
}
//如果是qq登录则获取
if($data[‘type’]==’qq’) {
$user_info = D(‘Connect’)->user_info($data[‘client_id’], $data[‘open_id’],$data[‘token’]);
$nickname = $user_info[‘nickname’];
$face = $user_info[‘figureurl_qq_2’] ==”?$user_info[‘figureurl_qq_1’]:$user_info[‘figureurl_qq_2’];
}
//结束

//p($face);die;

if (empty($connect[‘uid’])) {
$account = $data[‘type’] . rand(100000, 999999) . ‘@qq.com’;
$user = array(
‘account’ => $account,
‘password’ => rand(100000, 999999),
‘nickname’ => $nickname,
‘face’ =>$face,//这里只写入QQ注册头像
‘ext0’ => $account,
‘create_time’ => NOW_TIME,
‘create_ip’ => get_client_ip()
);

if (!D(‘Passport’)->register($user)) {
$this->error(‘创建帐号失败’);
}

$token = D(‘Passport’)->getToken();
$connect[‘uid’] = $token[‘uid’];
D(‘Connect’)->save(array(‘connect_id’ => $connect[‘connect_id’], ‘uid’ => $connect[‘uid’]));
}
setuid($connect[‘uid’]);
session(‘access’, $connect[‘connect_id’]);
header(‘Location:’ . U(‘mcenter/index/index’));
die;
} else {
$connect = D(‘Connect’)->getConnectByOpenid($data[‘type’], $data[‘open_id’]);
if (empty($connect)) {
$connect = $data;
$connect[‘connect_id’] = D(‘Connect’)->add($data);
} else {
D(‘Connect’)->save(array(‘connect_id’ => $connect[‘connect_id’], ‘token’ => $data[‘token’]));
}
if (empty($connect[‘uid’])) {
session(‘connect’, $connect[‘connect_id’]);
header(‘Location: ‘ . U(‘passport/bind’));
} else {
setuid($connect[‘uid’]);
session(‘access’, $connect[‘connect_id’]);
header(‘Location:’ . U(‘index/index’));
}
die;
}
}
public function logout(){
cookie(‘BAOCMS_TOKEN’, 0);
cookie(‘goods’, null);
D(‘Passport’)->logout();
$this->success(‘退出登录成功!’, U(‘mobile/passport/login’));
}
public function weixincheck()
{
$state = $this->_param(‘state’);
if (empty($state)) {
$this->error(‘非法访问’, U(‘index/index’));
}
if ($this->uid) {
$wxconn = D(‘Weixinconn’)->where(array(‘state’ => $state))->find();
$data = array();
$data[‘conn_id’] = $wxconn[‘conn_id’];
$data[‘status’] = 1;
$data[‘user_id’] = $this->uid;
D(‘Weixinconn’)->save($data);
$this->success(‘扫描成功,请等待电脑端响应!’, U(‘index/index’));
}
}
//两种找回密码的方式 1个是通过邮件 //填写了2个就改密码相对来说是不太合理,但是毕竟逻辑和操作相对简单一些!
public function forget()
{
$way = (int) $this->_param(‘way’);
$this->assign(‘way’, $way);
$this->display();
}
public function newpwd()
{
$account = $this->_post(‘account’);
if (empty($account)) {
session(‘verify’, null);
$this->fengmiMsg(‘请输入用户名!’);
}
$user = D(‘Users’)->getUserByAccount($account);
if (empty($user)) {
session(‘verify’, null);
$this->fengmiMsg(‘用户不存在!’);
}
$way = (int) $this->_param(‘way’);
$password = rand_string(8, 1);
if ($way == 1) {
$yzm = $this->_post(‘yzm’);
if (strtolower($yzm) != strtolower(session(‘verify’))) {
session(‘verify’, null);
$this->fengmiMsg(‘验证码不正确!’);
}
$email = $this->_post(’email’);
if (empty($email) || $email != $user[’email’]) {
$this->fengmiMsg(‘邮件不正确’);
}
D(‘Passport’)->uppwd($user[‘account’], ”, $password);
D(‘Email’)->sendMail(’email_newpwd’, $email, ‘重置密码’, array(‘newpwd’ => $password));
} elseif ($way == 2) {
$mobile = htmlspecialchars($_POST[‘mobile’]);
if (!($scode = trim($_POST[‘scode’]))) {
$this->fengmiMsg(‘请输入短信验证码!’);
}
$scode2 = session(‘scode’);
if (empty($scode2)) {
$this->fengmiMsg(‘请获取短信验证码!’);
}
if ($scode != $scode2) {
$this->fengmiMsg(‘请输入正确的短信验证码!’);
}
D(‘Passport’)->uppwd($user[‘account’], ”, $password);
if($this->_CONFIG[‘sms’][‘dxapi’] == ‘dy’){
D(‘Sms’)->DySms($this->_CONFIG[‘site’][‘sitename’], ‘sms_user_newpwd’, $mobile, array(
‘sitename’=>$this->_CONFIG[‘site’][‘sitename’],
‘newpwd’ => $password
));
}else{
D(‘Sms’)->sendSms(‘sms_newpwd’, $mobile, array(‘newpwd’ => $password));
}
}
$this->fengmiMsg(‘重置密码成功!’, U(‘passport/suc’, array(‘way’ => $way)));
}
public function findsms()
{
if (!($mobile = htmlspecialchars($_POST[‘mobile’]))) {
die(‘请输入正确的手机号码’);
}
if (!isMobile($mobile)) {
die(‘请输入正确的手机号码’);
}
if (!($account = htmlspecialchars($_POST[‘account’]))) {
die(‘请填写账号’);
}
if ($user = D(‘Users’)->getUserByAccount($account)) {
if (empty($user[‘mobile’])) {
die(‘你还未绑定手机号,请选择其他方式!’);
} else {
if ($user[‘mobile’] != $mobile) {
die(‘请填写您的绑定手机号!’);
}
}
}
$randstring = session(‘scode’);
if (empty($randstring)) {
$randstring = rand_string(6, 1);
session(‘scode’, $randstring);
}
//大鱼短信
if($this->_CONFIG[‘sms’][‘dxapi’] == ‘dy’){
D(‘Sms’)->DySms($this->_CONFIG[‘site’][‘sitename’], ‘sms_yzm’, $mobile, array(‘sitename’=>$this->_CONFIG[‘site’][‘sitename’], ‘code’ => $randstring));
}else{
D(‘Sms’)->sendSms(‘sms_code’, $mobile, array(‘code’ => $randstring));
}

die(‘1’);
}
public function suc()
{
$way = (int) $this->_get(‘way’);
switch ($way) {
case 1:
$this->success(‘密码重置成功!请登录邮箱查看!’, U(‘passport/login’));
break;
default:
$this->success(‘密码重置成功!请查看验证手机!’, U(‘passport/login’));
break;
}
}
//增加的
public function avatar($user_id)
{
$user = D(‘Users’)->find($user_id);
if ($user[‘face’] != ”) {
$fileres = file_get_contents($this->CONFIG[‘site’][‘host’] . “/attachs/{$user[‘face’]}”);
} else {
$fileres = file_get_contents($this->CONFIG[‘site’][‘host’] . ‘/attachs/avatar.jpg’);
}
header(‘Content-type:image/jpg’);
echo $fileres;
}
}

ThinkPHP try.catch无法捕获异常 解决办法- ThinkPHP 框架

我想用try..catch..捕获 数据库查询异常,但是无法捕获,仍然看到错误页面,如附图,哪位请帮忙解决。

 

在程序中捕获异常,有时很有用。
注意命名空间
catch(\Exception $e)
并且建议捕获 \Think\Exception 而不是 \Exception
受教了,在THINKPHP中的公共类库和应用类库都是使用命名空间进行扩展的,所以这里的异常类捕获应该写成try{//try something… }catch( \Exception $e){//do something…}
为什么捕获\Think\Exception 呢,求大神解答
为什么捕获\Think\Exception 呢,求大神解答
很好,找了这么久的错误,没想到就这样解决了

thinkphp ajax 下拉加载

function loaddata(page, obj, sc) {
    var link = page.replace('0000', niunum);
    showLoader('正在加载中....');

    $.get(link, function (data) {
        if (data != 0) {
            obj.append(data);
        }
        niulock = 0;
        hideLoader();
    }, 'html');
    if (sc === true) {
        $(window).scroll(function () {
			var wh = $(window).scrollTop();
			var xh = $(document).height() - $(window).height() - 70;
            if (!niulock && wh >= xh ) {
                niulock = 1;
                niunum++;
                var link = page.replace('0000', niunum);
                showLoader('正在加载中....');
				var timeout = setTimeout(function(){
					niulock = 0;
					hideLoader();
				},5000);
                $.get(link, function (data) {
                    if (data != 0) {
						if(timeout){ //清除定时器
							clearTimeout(timeout);
							timeout = null;
						}
                        obj.append(data);
                    }
                    niulock = 0;
                    hideLoader();
                }, 'html');
            }
        });
    }
}
<script>
$(document).ready(function () {
loaddata(‘/mobile/tuan/loaddata/t/1479548691/p/0000.html’, $(“#tuan-list”), true);
});
</script>

public function loaddata()
{
$Tuan = D('Tuan');
import('ORG.Util.Page');
// 导入分页类
$map = array('audit' => 1, 'closed' => 0, 'city_id' => $this->city_id, 'end_date' => array('EGT', TODAY));
if ($keyword = $this->_param('keyword', 'htmlspecialchars')) {
$map['title'] = array('LIKE', '%' . $keyword . '%');
}
$cat = (int) $this->_param('cat');
if ($cat) {
$catids = D('Tuancate')->getChildren($cat);
if (!empty($catids)) {
$map['cate_id'] = array('IN', $catids);
} else {
$map['cate_id'] = $cat;
}
}
$area = (int) $this->_param('area');
if ($area) {
$map['area_id'] = $area;
}
$order = $this->_param('order', 'htmlspecialchars');
$lat = addslashes(cookie('lat'));
$lng = addslashes(cookie('lng'));
if (empty($lat) || empty($lng)) {
$lat = $this->city['lat'];
$lng = $this->city['lng'];
}
$orderby = '';
switch ($order) {
case 3:
//$orderby = " (ABS(lng - '{$lng}') + ABS(lat - '{$lat}') ) asc ";
$orderby = array('create_time' => 'desc');
break;
case 2:
$orderby = array('orderby' => 'asc', 'tuan_id' => 'desc');
break;
default:
$orderby = array('sold_num' => 'desc');
break;
}
$count = $Tuan->where($map)->count();
// 查询满足要求的总记录数
$Page = new Page($count, 10);
// 实例化分页类 传入总记录数和每页显示的记录数
$show = $Page->show();
// 分页显示输出
$var = C('VAR_PAGE') ? C('VAR_PAGE') : 'p';
$p = $_GET[$var];
if ($Page->totalPages < $p) {
die('0');
}
$list = $Tuan->where($map)->order($orderby)->limit($Page->firstRow . ',' . $Page->listRows)->select();
foreach ($list as $k => $val) {
if ($val['shop_id']) {
$shop_ids[$val['shop_id']] = $val['shop_id'];
}
$val['end_time'] = strtotime($val['end_date']) - NOW_TIME + 86400;
$list[$k] = $val;
}
if ($shop_ids) {
$shops = D('Shop')->itemsByIds($shop_ids);
$ids = array();
foreach ($shops as $k => $val) {
$shops[$k]['d'] = getDistance($lat, $lng, $val['lat'], $val['lng']);
$d = getDistanceNone($lat, $lng, $val['lat'], $val['lng']);
$ids[$d][] = $k;
}
ksort($ids);
$showshops = array();
foreach ($ids as $arr1) {
foreach ($arr1 as $val) {
$showshops[$val] = $shops[$val];
}
}
$this->assign('shops', $showshops);
}
$this->assign('list', $list);
// 赋值数据集
$this->assign('page', $show);
// 赋值分页输出
$this->display();
}

 

<script>
function daojishi(id) {
var t = Math.floor($(“#” + id).attr(‘rel’));
t–;
var d = Math.floor(t / 60 / 60 / 24);
var h = Math.floor(t / 60 / 60 % 24);
var m = Math.floor(t / 60 % 60);
var s = Math.floor(t % 60);
if (d < 10) {
d = ‘0’ + d;
}
if (h < 10) {
h = ‘0’ + h;
}
if (m < 10) {
m = ‘0’ + m;
}
if (s < 10) {
s = ‘0’ + s;
}
$(“#” + id).attr(‘rel’, t);
$(“#” + id).html(d + ‘:’ + h + ‘:’ + m + ‘:’ + s);
}
</script>
<foreach name=”shops” item=”var”>
<div class=”tuan-shop”>
<div class=”shop-con”>
<div class=”shop-name”><a title=”<{$var.shop_name}>” href=”<{:U(‘shop/detail’,array(‘shop_id’=>$var[‘shop_id’]))}>”><{$var.shop_name}></a></div>
<div class=”shop-tags”>
<!–暂时可以不用开始–>
<if condition=”$var[‘is_renzheng’] eq 1″> <span class=”z”>证</span> </if>
<gt name=”var.card_date” value=”$today”><span class=”k”>卡</span></gt>
<gt name=”var.wei_date” value=”$today”> <span class=”w”>微</span></gt>
<if condition=”$var[‘is_ding’] eq 1″> <span class=”d”>订</span></if>
<gt name=”var.yuyue_date” value=”$today”><span class=”d”>订</span></gt>
<!–暂时可以不用结束–>
<div class=”shop-local”><span class=”mui-icon mui-icon-location”></span><{$var.d}></div>
</div>
</div>

<div class=”main-tuan”>
<ul>
<foreach name=”list” item=”item”>
<eq name=”item.shop_id” value=”$var[‘shop_id’]”>

<php>
if($item[‘bg_date’] <= $today && $item[‘end_date’] > $today){

$tt = strtotime($item[‘end_date’])-time();
$item[‘djs_time’] = $tt;
$item[‘djs_str’] = ‘距结束’;

}elseif($item[‘bg_date’] >$today){
$tt = strtotime($item[‘bg_date’])-time();
$item[‘djs_time’] = $tt;
$item[‘djs_str’] = ‘距开始’;

}
</php>
<script type=”text/javascript” language=”javascript”>
setInterval(function () {
daojishi(“daojishi_<{$item.tuan_id}>”);
}, 1000);
</script>

<li>
<a class=”line” href=”<{:U(‘tuan/detail’,array(‘tuan_id’=>$item[‘tuan_id’]))}>” >
<div class=”container”>
<img class=”x4″ src=”__ROOT__/attachs/<{$item.photo}>” />
<div class=”des x8″>
<h5><{$item.title}></h5>
<p class=”intro”>
<em class=”clock_ico”></em>
<{$item[‘djs_str’]}>
<span id=”daojishi_<{$item.tuan_id}>” rel=”<{$item[‘djs_time’]}>” >00:00:00:00</span>
</p>
<p class=”info”>
<span>¥ <em><{:round($item[‘tuan_price’]/100,2)}></em></span> <del>¥ <{:round($item[‘price’]/100,2)}></del>

<span class=”text-little float-right badge bg-yellow margin-small-top padding-right”>已售<{$item.sold_num}></span>
</p>
</div>
</div>
</a>
</li>
</eq>
</foreach>
</ul>
</div>
</div>
</foreach>

关于thinkphp框架头部公共文件的调用问题 ‘LAYOUT_ON’=>true, ‘LAYOUT_NAME’=>’layout’,

ThinkPHP的模板引擎内置了布局模板功能支持,可以方便的实现模板布局以及布局嵌套功能。

有三种布局模板的支持方式:

第一种方式:全局配置方式

这种方式仅需在项目配置文件中添加相关的布局模板配置,就可以简单实现模板布局功能,比较适用于全站使用相同布局的情况,需要配置开启LAYOUT_ON 参数(默认不开启),并且设置布局入口文件名LAYOUT_NAME(默认为layout)。

  1. 'LAYOUT_ON'=>true,
  2. 'LAYOUT_NAME'=>'layout',

开启LAYOUT_ON后,我们的模板渲染流程就有所变化,例如:

  1. namespace Home\Controller;
  2. use Think\Controller;
  3. Class UserController extends Controller{
  4. Public function add() {
  5. $this->display('add');
  6. }
  7. }

在不开启LAYOUT_ON布局模板之前,会直接渲染 Application/Home/View/User/add.html 模板文件,开启之后,首先会渲染Application/Home/View/layout.html 模板,布局模板的写法和其他模板的写法类似,本身也可以支持所有的模板标签以及包含文件,区别在于有一个特定的输出替换变量{__CONTENT__},例如,下面是一个典型的layout.html模板的写法:

  1. <include file="Public:header" />
  2. {__CONTENT__}
  3. <include file="Public:footer" />

读取layout模板之后,会再解析User/add.html 模板文件,并把解析后的内容替换到layout布局模板文件的{CONTENT} 特定字符串。

当然可以通过设置来改变这个特定的替换字符串,例如:

  1. 'TMPL_LAYOUT_ITEM' => '{__REPLACE__}'

一个布局模板同时只能有一个特定替换字符串。

采用这种布局方式的情况下,一旦User/add.html 模板文件或者layout.html布局模板文件发生修改,都会导致模板重新编译。

如果需要指定其他位置的布局模板,可以使用:

  1. 'LAYOUT_NAME'=>'Layout/layoutname',

就表示采用Application/Home/View/Layout/layoutname.html作为布局模板。

如果某些页面不需要使用布局模板功能,可以在模板文件开头加上 {__NOLAYOUT__} 字符串。

如果上面的User/add.html 模板文件里面包含有{__NOLAYOUT__},则即使当前开启布局模板,也不会进行布局模板解析。

第二种方式:模板标签方式

这种布局模板不需要在配置文件中设置任何参数,也不需要开启LAYOUT_ON,直接在模板文件中指定布局模板即可,相关的布局模板调整也在模板中进行。

以前面的输出模板为例,这种方式的入口还是在User/add.html 模板,但是我们可以修改下add模板文件的内容,在头部增加下面的布局标签(记得首先关闭前面的LAYOUT_ON设置,否则可能出现布局循环):

  1. <layout name="layout" />

表示当前模板文件需要使用layout.html 布局模板文件,而布局模板文件的写法和上面第一种方式是一样的。当渲染User/add.html 模板文件的时候,如果读取到layout标签,则会把当前模板的解析内容替换到layout布局模板的{CONTENT} 特定字符串。

一个模板文件中只能使用一个布局模板,如果模板文件中没有使用任何layout标签则表示当前模板不使用任何布局。

如果需要使用其他的布局模板,可以改变layout的name属性,例如:

  1. <layout name="newlayout" />

还可以在layout标签里面指定要替换的特定字符串:

  1. <layout name="Layout/newlayout" replace="{__REPLACE__}" />

由于所有include标签引入的文件都支持layout标签,所以,我们可以借助layout标签和include标签相结合的方式实现布局模板的嵌套。例如,上面的例子

  1. <include file="Public:header" />
  2. <div id="main" class="main" >
  3. {__CONTENT__}
  4. </div>
  5. <include file="Public:footer" />

在引入的header和footer模板文件中也可以添加layout标签,例如header模板文件的开头添加如下标签:

  1. <layout name="menu" />

这样就实现了在头部模板中引用了menu布局模板。

也可以采用两种布局方式的结合,可以实现更加复杂的模板布局以及嵌套功能。

第三种方式:使用layout控制模板布局

使用内置的layout方法可以更灵活的在程序中控制模板输出的布局功能,尤其适用于局部需要布局或者关闭布局的情况,这种方式也不需要在配置文件中开启LAYOUT_ON。例如:

  1. namespace Home\Controller;
  2. use Think\Controller;
  3. Class UserController extends Controller{
  4. Public function add() {
  5. layout(true);
  6. $this->display('add');
  7. }
  8. }

表示当前的模板输出启用了布局模板,并且采用默认的layout布局模板。

如果当前输出需要使用不同的布局模板,可以动态的指定布局模板名称,例如:

  1. namespace Home\Controller;
  2. use Think\Controller;
  3. Class UserController extends Controller{
  4. Public function add() {
  5. layout('Layout/newlayout');
  6. $this->display('add');
  7. }
  8. }

或者使用layout方法动态关闭当前模板的布局功能(这种用法可以配合第一种布局方式,例如全局配置已经开启了布局,可以在某个页面单独关闭):

  1. namespace Home\Controller;
  2. use Think\Controller;
  3. Class UserController extends Controller{
  4. Public function add() {
  5. layout(false); // 临时关闭当前模板的布局功能
  6. $this->display('add');
  7. }
  8. }

三种模板布局方式中,第一种和第三种是在程序中配置实现模板布局,第二种方式则是单纯通过模板标签在模板中使用布局。具体选择什么方式,需要根据项目的实际情况来了。

include标签

使用include标签在当前模板中包含公共模板,例如常见的header和footer等公共模板,include标签最常用的属性是file,但是支持不同的用法,其用法基本和我们常用的模板渲染方法display方法差不多。例如:
包含Public目录下面的header模板

1
<include file="Public:header" />

包含当前模板目录下面的menu模板

1
<include file="menu" />

表示包含blue模板主题下面的User/read模板文件,include标签所支持的模板深度只能到操作层次,也就是说ThinkPHP默认的模板结构采用的是:主题/模块/操作.模板后缀,使用上述用法包含模板的时候,file属性不需要指定模板后缀,如果你的模板结构不是标准结构,可以采用包含完整模板文件的方式:

1
<include file="./Tpl/default/header.html" />

include标签可以一定程度上简化重复的模板书写,和便于同步修改,不足就是如果公共模板文件发生更改,但是当前的主模板文件没有更改,则不会自动更新模板缓存,除非你设置了模板缓存有效期,那么在缓存过期后会自动更新模板缓存。

防火墙代码 日志文件 360log.txt $Safexss = new Safexss();


/*
防火墙代码
日志文件 360log.txt
*/
$Safexss = new Safexss(); //SQL注入检查

if (!get_magic_quotes_gpc()){ //XXS防护
//$_GET && $_GET = Safexss::deepAddslashes($_GET);
// $_POST && $_POST = Safexss::deepAddslashes($_POST);
//$_COOKIE && $_COOKIE = Safexss::deepAddslashes($_COOKIE);
//$_REQUEST && $_REQUEST = Safexss::deepAddslashes($_REQUEST);
}
class Safexss{

public $getfilter="'|\b(alert|confirm|prompt)\b|<[^>]*?>|^\\+\/v(8|9)|\\b(and|or)\\b.+?(>|<|=|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";

//public $postfilter="^\\+\/v(8|9)|\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|<\\s*img\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
public $postfilter="^\\+\/v(8|9)|\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";

public $cookiefilter="\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
function __construct(){
foreach($_GET as $key=>$value){
$this->StopAttack($key,$value,$this->getfilter);
}

foreach($_POST as $key=>$value){
$this->StopAttack($key,$value,$this->postfilter);
}

foreach($_COOKIE as $key=>$value){
$this->StopAttack($key,$value,$this->cookiefilter);
}
}

function customError($errno, $errstr, $errfile, $errline){
echo "<b>Error number:</b> [$errno],error on line $errline in $errfile<br />";
die();
}

function StopAttack($StrFiltKey,$StrFiltValue,$ArrFiltReq){
if(is_array($StrFiltValue)){
$StrFiltValue=implode($StrFiltValue);
}
if (preg_match("/".$ArrFiltReq."/is",$StrFiltValue)==1){
$this->slog("<br><br>操作IP: ".$_SERVER["REMOTE_ADDR"]."<br>操作时间: ".strftime("%Y-%m-%d %H:%M:%S")."<br>操作页面:".$_SERVER["PHP_SELF"]."<br>提交方式: ".$_SERVER["REQUEST_METHOD"]."<br>提交参数: ".$StrFiltKey."<br>提交数据: ".$StrFiltValue);
header("Location:/");
exit();
}
}

function slog($logs){
$toppath="./360log.txt";
$Ts=fopen($toppath,"a+");
fputs($Ts,$logs."\r\n");
fclose($Ts);
}

public static function deepAddslashes($value){
if(empty($value)){
return $value;
}else{
return is_array($value) ? array_map('Safexss::deepAddslashes', $value) : addslashes($value);
}
}
}

thinkphp 缩略图模糊解决办法 ThinkPHP水印功能,修复PNG透明水印增加JPEG图片质量可调整

TP自带有图片类,有给图片加水印的功能。
这里完善了:
1,png水印透明
2,加水印后质量调整(只限于JPG格式)
代码如下:
红色为原系统的
绿色为修改过的

ThinkPHP\Lib\ORG\Util/
/**
+———————————————————-
* 为图片添加水印
+———————————————————-
* @static public
+———————————————————-
* @param string $source 原文件名
* @param string $water 水印图片
* @param string $$savename 添加水印后的图片名
* @param string $alpha 水印的透明度
+———————————————————-
* @return string
+———————————————————-
* @throws ThinkExecption
+———————————————————-
*/
static public function water($source, $water, $savename=null, $alpha=80) {
//检查文件是否存在
if (!file_exists($source) || !file_exists($water))
return false;

//图片信息
$sInfo = self::getImageInfo($source);
$wInfo = self::getImageInfo($water);

//如果图片小于水印图片,不生成图片
if ($sInfo[“width”] < $wInfo[“width”] || $sInfo[‘height’] < $wInfo[‘height’])
return false;

//建立图像
$sCreateFun = “imagecreatefrom” . $sInfo[‘type’];
$sImage = $sCreateFun($source);
$wCreateFun = “imagecreatefrom” . $wInfo[‘type’];
$wImage = $wCreateFun($water);

//设定图像的混色模式
imagealphablending($wImage, true);

//图像位置,默认为右下角右对齐
$posY = $sInfo[“height”] – $wInfo[“height”];
$posX = $sInfo[“width”] – $wInfo[“width”];

/* 为了保持PNG的透明效果 使用imagecopy */
imagecopy($sImage, $wImage, $posX, $posY, 0, 0, $wInfo[‘width’], $wInfo[‘height’]);
//生成混合图像,这是系统的
// imagecopymerge($sImage, $wImage, $posX, $posY, 0, 0, $wInfo[‘width’],$wInfo[‘height’], $alpha);
//输出图像
$ImageFun = ‘Image’ . $sInfo[‘type’];
//如果没有给出保存文件名,默认为原图像名
if (!$savename) {
$savename = $source;
@unlink($source);
}
//保存图像,如果是jpg,则设置一下水印质量
if ($sInfo[‘type’] == “jpg” || $sInfo[‘type’] == “jpeg”) {
imagejpeg($sImage, $savename, 90);//第3个参数即使质量大小,因为只有imagejpeg支持这个参数
} else {
$ImageFun($sImage, $savename);
}
//$ImageFun($sImage, $savename);
imagedestroy($sImage);
}

BAOCMS首页头尾常见模块修改教程

1、手机CMS图片代码路径:\themes\default\Pchome\public\topOne.html 第9—13行

2、文字代码路径:\themes\default\Pchome\index\index.html 第154—157行

3、代码路径:\themes\default\Pchome\public\footer.html 第23–32行

4、代码路径\themes\default\Pchome\public\footer.html 第61行

5、代码路径\themes\default\Pchome\public\footer.html 第67—73行

6、代码路径\themes\default\Pchome\public\top.html 第148–153行

了解更多操作教程可以关注我们:

修改thinkphp框架首页幻灯全屏显示,分类缩放baocms

第一步–\themes\default\Pchome\statics\css\style.css 227-228行 修改幻灯区域大小(默认 960*320)。
第二步–index.html: 第三行<include file=”public:nav2″/> 调用nav2(可缩放)分类。
第三步–然后注销index.html 144行代码:<!– <div class=”left
sy_partOne_cate”><include file=”public:cate”/></div>–>
第四步–\themes\default\Pchome\statics\css\style.css  230.231行 修改高度和宽度

1