tp6 where whereOR关联使用

Db::name($this->table)->alias($alias)
->where($condition)
->where(function ($query) use ($condition_or) {
    $query->whereOr($condition_or);
})
->order($order);

遇到whereOr和where组合链式操作会把or条件和and条件并列处理

使用闭包放在where里就可以加上类似 and ( xxx or xxx)的条件了

nginx负载均衡

#1.拉取nginx镜像

sudo docker pull 
registry.cn-hangzhou.aliyuncs.com/leokim_php_env/leokim_nginx

#2.查看nginx容器是否正常运行

docker run -dit -p 8000:80 --name load_balance_nginx e548f1a579cf

#3.复制nginx配置文件和网页文件到宿主机 方便修改配置文件

docker cp nginx_main:/etc/nginx/conf.d/default.conf ./ 
docker cp nginx_main:/usr/share/nginx/html/index.html ./

修改

#4.修改index.html内容 不同容器展示内容分别改成1、2、3

<html><h1>This is nginx service 3</h1></html>

#5.关闭nginx_main 删除所有已关闭容器,为了名称不会重复

docker stop load_balance_nginx
docker rm $(docker ps -aq)

#6.运行负载均衡服务器 load_balance_nginx

docker run --name load_balance_nginx -dit -p 8000:80 \
-v /Users/leokim/Documents/docker_config/default_lb.conf:/etc/nginx/conf.d/default.conf \
-v /Users/leokim/Documents/docker_config/index.html:/usr/share/nginx/html/index.html \
e548f1a579cf

#7.运行集群服务器1

docker run --name nginx_1 -dit -p 9000:80 \
-v /Users/leokim/Documents/docker_config/default_cs.conf:/etc/nginx/conf.d/default.conf \
-v /Users/leokim/Documents/docker_config/index_1.html:/usr/share/nginx/html/index.html \
e548f1a579cf

#8.运行集群服务器2

docker run --name nginx_2 -dit -p 9001:80 \
-v /Users/leokim/Documents/docker_config/default_cs.conf:/etc/nginx/conf.d/default.conf \
-v /Users/leokim/Documents/docker_config/index_2.html:/usr/share/nginx/html/index.html \
e548f1a579cf


#9.运行集群服务器3

docker run --name nginx_3 -dit -p 9003:80 \
-v /Users/leokim/Documents/docker_config/default_cs.conf:/etc/nginx/conf.d/default.conf \
-v /Users/leokim/Documents/docker_config/index_3.html:/usr/share/nginx/html/index.html \
e548f1a579cf


#10. 访问http://localhost:8000/ 查看负载均衡效果


#11. 配置weight并查看配置权重后负载均衡效果

docker stop load_balance_nginx
docker rm $(docker ps -aq)
docker run --name load_balance_nginx -dit -p 8000:80 \
-v /Users/leokim/Documents/docker_config/default_lb.conf:/etc/nginx/conf.d/default.conf \
-v /Users/leokim/Documents/docker_config/index.html:/usr/share/nginx/html/index.html \
e548f1a579cf

nginx 负载均衡

环境:

Centos 7
Docker
Nginx

本次利用宿主机和两个nginx容器来实现负载均衡 宿主机无任何内容 只搭载一台nginx服务器 并由此台服务器将请求转发给两个nginx容器来进行处理 那就让我们的实验开始吧!


一、安装相关环境
1.安装Docker(个人推荐配置阿里云源 )
2.宿主机安装Nginx
下面我比较偷懒 直接wget Nginx rpm包
老规矩 先关防火墙和selinux

[root@cany ~]# systemctl stop firewalld.service[root@cany ~]# setenforce 0[root@cany ~]# yum install docker -y[root@cany ~]# wget http://dl.Fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm[root@cany ~]# yum install nginx -y

用命令测试是否成功安装 能否开启服务

[root@cany ~]# systemctl start docker.service[root@cany ~]# systemctl start nginx.service   Centos 7 启动服务命令与6.x不同哦

测试web界面是否显示?

Docker部署nginx实现负载均衡

完全ok啦 没问题!!!

下面我们来删除掉nginx默认html 并创建一个空白index.html

[root@cany ~]# cd /usr/share/nginx/html/[root@cany html]# rm *rm: remove regular file ‘404.html’? y
rm: remove regular file ‘50x.html’? y
rm: remove regular file ‘index.html’? y
rm: remove regular file ‘nginx-logo.png’? y
rm: remove regular file ‘poweredby.png’? y
[root@cany html]# touch index.html

为什么要创建一个空白index.html呢?
答:其实我一开始也是全删的 结果发现访问无效 才想起要让nginx有响应才会触发nginx.conf配置 也就是才会触发我们配置的负载均衡 这是我个人的理解 有错误敬请提出

二、安装Nginx容器
1.pull nginx镜像

[root@cany ~]# docker pull hub.c.163.com/library/nginx:latest             下载最新Nginx镜像Trying to pull repository hub.c.163.com/library/nginx ... 
latest: Pulling from hub.c.163.com/library/nginx5de4b4d551f8: Pull complete d4b36a5e9443: Pull complete 0af1f0713557: Pull complete Digest: sha256:f84932f738583e0169f94af9b2d5201be2dbacc1578de73b09a6dfaaa07801d6

2.pull完成使用docker images命令查看

[root@cany ~]# docker imagesREPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
hub.c.163.com/library/nginx   latest              46102226f2fd        9 months ago        109.4 MB

3.Docker run 创建容器

[root@cany ~]# docker run -p 8080:80 --name nginx_web1 -it hub.c.163.com/library/nginx /bin/bash             容器名:nginx_web1  映射容器8080端口到宿主机的80端口上

进入nginx_web1容器的nginx目录下 创建一个index.html

root@53cda1b9de1e:/# cd /usr/share/nginx/html/root@53cda1b9de1e:/usr/share/nginx/html# ls 50x.html  index.html
root@53cda1b9de1e:/usr/share/nginx/html# rm *root@53cda1b9de1e:/usr/share/nginx/html# echo hello nginx_web1 Cany > index.html root@53cda1b9de1e:/usr/share/nginx/html# exit

下面创建多一个新的nginx容器

[root@cany ~]# docker run -p 8081:80 --name nginx_web2 -it hub.c.163.com/library/nginx /bin/bash             容器名:nginx_web2  映射容器8081端口到宿主机的80端口上

进入nginx_web2容器的nginx目录下 创建一个index.html

root@41b3eec738b5:/# cd /usr/share/nginx/html/root@41b3eec738b5:/usr/share/nginx/html# ls 50x.html  index.html
root@41b3eec738b5:/usr/share/nginx/html# rm *root@41b3eec738b5:/usr/share/nginx/html# echo hello nginx_web2 Cany > index.htmlroot@41b3eec738b5:/usr/share/nginx/html# exit

exit退出后容器不运行 先启动两个nginx容器再执行启动服务命令

[root@cany ~]# docker start 41b3eec738b541b3eec738b5
[root@cany ~]# docker start 53cda1b9de1e53cda1b9de1e
[root@cany ~]# docker exec -d 41b3eec738b5  service nginx start [root@cany ~]# docker exec -d 53cda1b9de1e  service nginx start

三、配置主机host文件
宿主机ip 10.2.4.88 对应 www.abc.top
Docker部署nginx实现负载均衡

四、配置宿主机Nginx.conf文件

[root@cany ~]# find / -name nginx.conf      查找nginx.conf文件/etc/nginx/nginx.conf

在http段加入以下代码

upstream www.abc.top { 
      server  10.2.4.88:8080 weight=10; 
      server  10.2.4.88:8081 weight=20; 
} 

server{ 
    listen 80; 
    server_name www.abc.top; 
    location / { 
        proxy_pass         http://www.abc.top; 
        proxy_set_header   Host             $host; 
        proxy_set_header   X-Real-IP        $remote_addr; 
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for; 
    } 
}

配置如下图

Docker部署nginx实现负载均衡

保存配置并重启宿主机Nginx

[root@cany ~]# systemctl restart nginx.service

查看Nginx容器运行状态
Docker部署nginx实现负载均衡

五、测试
Docker部署nginx实现负载均衡

那就再刷新多几次?

Docker部署nginx实现负载均衡

web1 web2 看出来了吧?
实验成功!!!

人人商城 – 手机端多模版

目前人人商城不支持手机端页面的多模版

/addons/ewei_shopv2/core/web/sysset/index.php 

function shop 添加 

$data['mobile_default_template'] = isset($_POST['data']['mobile_default_template']) && !empty($_POST['data']['mobile_default_template']) ? $_POST['data']['mobile_default_template'] : 'default';

/addons/ewei_shopv2/template/web_v3/sysset/index.html

添加

            <div class="form-group">
                <label class="col-lg control-label">手机端默认模版</label>
                <div class="col-sm-9 col-xs-12">
                    <input class="form-control" name="data[mobile_default_template]" 
                    value="{php echo isset($data['mobile_default_template']) && !empty($data['mobile_default_template']) ? $data['mobile_default_template'] : 'default'}"/>
                </div>
            </div>

这样就能把模版名存到数据库的(ims_ewei_shop_sysset)表了,存进去的时候是序列化过的 所以存取的修改也比较简单

addons/ewei_shopv2/core/inc/page.php

line:376

有一个后端加载前端默认模版的地方

image.png修改成

$template = $_W['shopset']['shop']['mobile_default_template'];

然后再把模版里用到mobile/default的地方的default统一修改成“$_W['shopset']['shop']['mobile_default_template']”就可以了

微信返佣转账

//发送红包start
$url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack';

//获取openID
$uid = $list['uid'];
$result  = pdo_fetch("SELECT openid FROM ims_meepo_online_user WHERE id=:id",array(':id'=>$uid));
$open_id = $result['openid'];
$money   = (float)$list['money'];

$package = array();
$package['nonce_str'] = random(8);
$package['mch_billno'] = 'xxx'.rand(10000000000000,99999999999999);
$package['mch_id'] = '1515256111';
$package['wxappid'] = 'wx57a837f1e72026c3';
$package['send_name'] = 'xxxx';
$package['re_openid'] = $open_id;
$package['total_amount'] = $money*100;
$package['total_num'] = 1;
$package['wishing'] = 'xxxx佣金'.date('Y-m-d');
$package['client_ip'] = CLIENT_IP;
$package['act_name'] = 'xxxxx佣金';
$package['remark'] = '根据会员后台提现的金额返佣.';
$package['scene_id'] = 'PRODUCT_5';

ksort($package, SORT_STRING);
$string1 = '';
foreach($package as $key => $v) {
	if (empty($v)) {
		continue;
	}
	$string1 .= "{$key}={$v}";
}
$string1 .= "key=2nHuHsDijB4Ye7mNN22QxFAP3AW6l3hT";

$package['sign'] = strtoupper(md5($string1));
$dat = array2xml($package);

load()->func('communication');

$certPath = 'E:\xxxxx/apiclient_cert.pem';
$keyPath = 'E:\xxxxx\cert/apiclient_key.pem';

$extra = array(
	CURLOPT_SSL_VERIFYPEER=>false,
	CURLOPT_SSL_VERIFYHOST=>false,
	CURLOPT_SSLCERTTYPE=>'PEM',
	CURLOPT_SSLKEYTYPE=>'PEM',
	CURLOPT_SSLCERT=>$certPath,
	CURLOPT_SSLKEY=>$keyPath,
	CURLOPT_POST=>1
);
$response = ihttp_request($url, $dat, $extra);

if($response['errno'] == 58){
	$err_msg = $response['message'];
	die(json_encode(error('-1',$err_msg)));
}else{
	$xml = $response['content'];
	$result = xml2array($xml);

	if($result['result_code'] == 'SUCCESS'){
		$pdo_list = pdo_update("meepo_online_money_page",array('order_static'=>$is_best),array('id'=>$id));
		die(json_encode(error('0','success')));
	}else if($result['result_code'] == 'FAIL'){
		//alert error
		$err_msg = $result['return_msg'];
		die(json_encode(error('-1',$err_msg)));
	}
}

//exit;
//echo $response;

//发送红包end

微擎 人人商城 路由追踪

随便举个栗子

https://ssl.infowei.com/app/index.php?i=2&c=entry&m=ewei_shopv2&do=mobile&r=get_recommand&page=1&merchid=0&_=1568885489792

从链接可以看到访问的是/app/index.php

i(uniacid)->2

controller ->entry

module->ewei_shopv2

r->get_recommand

首先来看/app/index.php这个文件

1.初始化了框架

2.一直到最后controller 都是entry 然后运行_forward, 然后我们跟着forward找到$file(/app/source/entry/site.ctrl.php)

在执行__init.php之前 action 参数是空

$init = IA_ROOT . "/app/source/{$controller}/__init.php";
if(is_file($init)) {
	require $init;
}

然后/app/source/entry/__init.php里

if (empty($action)) {
	$action = 'site';
}

然后我们就获取到了action,用来在下面拼接file的路径(/app/source/entry/site.ctrl.php)

我不是太确定在这里是如何执行site.ctrl.php的, 追踪的时候发现require之后会直接执行site.ctrl.php

ok先不管 继续往下走

require _forward($controller, $action);
function _forward($c, $a) {
	$file = IA_ROOT . '/app/source/' . $c . '/' . $a . '.ctrl.php';
	return $file;
}

3.在site.ctrl.php会执行$site->$method()

在这里

$site->ewei_shopv2(这个应用)

$method->doMobileMobile

它会直接执行到/addons/ewei_shopv2/site.php 的 doMobileMobile方法

<?php
/**
 * [WeEngine System] Copyright (c) 2014 WE7.CC
 * WeEngine is NOT a free software, it under the license terms, visited http://www.we7.cc/ for more details.
 */

defined('IN_IA') or exit('Access Denied');

if (!empty($_W['uniacid'])) {
	$link_uniacid = table('uni_link_uniacid')->getMainUniacid($_W['uniacid'], $entry['module']);
	if (!empty($link_uniacid)) {
		$_W['uniacid'] = $link_uniacid;
		$_W['account']['link_uniacid'] = $link_uniacid;
	}
}

$site = WeUtility::createModuleSite($entry['module']);
if(!is_error($site)) {
	$do_function = $site instanceof WeModuleSite ? 'doMobile' : 'doPage';
	$method = $do_function . ucfirst($entry['do']);
	exit($site->$method());
}
exit();
require_once IA_ROOT . '/addons/ewei_shopv2/version.php';
require_once IA_ROOT . '/addons/ewei_shopv2/defines.php';
require_once EWEI_SHOPV2_INC . 'functions.php';
class Ewei_shopv2ModuleSite extends WeModuleSite
{
   public function getMenus()
   {
      global $_W;
      return array(
   array('title' => '管理后台', 'icon' => 'fa fa-shopping-cart', 'url' => webUrl())
   );
   }

   public function doWebWeb()
   {
      m('route')->run();
   }

   public function doMobileMobile()
   {
      m('route')->run(false);
   }

   public function payResult($params)
   {
      return m('order')->payResult($params);
   }
}

4.跟踪m()方法到 /addons/ewei_shopv2/core/inc/functions.php

if (!function_exists('m')) {
    function m($name = '')
    {
        static $_modules = array();
        if (isset($_modules[$name])) {

            return $_modules[$name];
        }
        $model = EWEI_SHOPV2_CORE . "model/" . strtolower($name) . '.php';

        if (!is_file($model)) {
            die(' Model ' . $name . ' Not Found!');
        }
        require_once $model;
        $class_name = ucfirst($name) . "_EweiShopV2Model";
        $_modules[$name] = new $class_name();
        return $_modules[$name];
    }
}

5.执行到了/addons/ewei_shopv2/core/model/route.php 的run方法

方法很长我没有仔细去看 我们的路由参数只有一段 所以直接进入这里

case 0:
   $file = $root . 'index.php';
   $class = 'Index';
case 1:
   $file = $root . $routes[0] . '.php';

   if (is_file($file)) {
      $class = ucfirst($routes[0]);
   }
   else if (is_dir($root . $routes[0])) {
      $file = $root . $routes[0] . '/index.php';
      $class = 'Index';
   }
   else {
      $method = $routes[0];
      $file = $root . 'index.php';
      $class = 'Index';
   }

   $_W['action'] = $routes[0];
   break;

最后执行到这里  $instance是Index_EweiShopV2Page的实例 $method是get_recommand

include $file;
$class = ucfirst($class) . '_EweiShopV2Page';
$instance = new $class();

if (!method_exists($instance, $method)) {
   show_message('控制器 ' . $_W['controller'] . ' 方法 ' . $method . ' 未找到!');
}

$instance->$method();
exit();

$file-> /addons/ewei_shopv2/core/mobile/index.php

文件的类名就是“Index_EweiShopV2Page”

6.在index.php里可以找到function

function get_recommand(){
   global $_W, $_GPC;
   $args = array(
      'page' => $_GPC['page'],
      'pagesize' => 6,
      'isrecommand' => 1,
      'order' => 'displayorder desc,createtime desc',
      'by' => ''
   );
   $recommand = m('goods')->getList($args);
   show_json(1,array('list'=>$recommand['list'], 'pagesize'=>$args['pagesize'], 'total'=>$recommand['total'], 'page'=>intval($_GPC['page'])));
}