商城培训内容
一、目录结构(MVC模式)
(1)视图(View)
存放在views文件夹下,主要存放显示页面的php文件
(2)模型(Model)
存放在models文件夹下,存放对数据库表的操作方法
(3)控制(Controller)
存放在controllers文件夹下,存放控制方法。从用户接受请求,讲模型与视图匹配在一起,共同完成用户的请求。
(4)其他文件
config文件夹:存放商城的备置文件。例如数据库文件(db.ini.php),备置文件(config.ini.php)等。
api文件夹:存放接口文件。例如快递接口文件(logistic.php)。
static文件夹:存放css文件,js文件,图片。
task文件夹:存放计划任务文件。
二、查找文件
例子:根据 `http://shop.yuanfeng.com/index.php?ctl=Buyer_Cart&met=cart` 地址查找文件
`index.php` 是入口文件。
`ctl=Buyer_Cart` 控制器文件路径 `shop/controllers/Buyer/CartCtl.php`
`met=cart` 是 `CartCtl.php` 中的`cart`方法。
public function cart(){
$data = $this->getCart();
$this->data->addBody(-140, $data);
if ($this->typ == 'json') {
$new_data = array();
$sum = 0;
$count = $data['count'];
unset($data['count']);
$new_data['count'] = $count;
$cart_list = array_values($data);
$new_data['cart_list'] = $cart_list;
if ( !empty($cart_list) ) {
foreach ($cart_list as $key => $val) {
foreach ($val['goods'] as $k => $v) {
$sum += $v['goods_num'] * $v['now_price'];
}
}
}
$new_data['sum'] = $sum;
$this->data->addBody(-140, $new_data);
}else{
include $this->view->getView();
}
}
$this->data->addBody(-140,$new_data); //返回数据
include $this->view->getView(); //加载页面
}
如果是加载页面,则页面的路径为 `shop/views/default/Buyer/CartCtl/cart.php`
在文件中有几种表示路径的方法:
<?=$this->view->js?>/cart.js //对应文件 shop/static/default/js/cart.js
<?= $this->view->js_com ?>/sppl.js //shop/static/common/js/sppl.js
<?= $this->view->css ?>/tips.css //shop/static/default/css/tips.css
<?=$this->view->img?>/mask.png //shop/static/default/images/mask.png
三、model方法(对数据表的操作)
例子:
shop/models/Cart.php
shop/models/CartModel.php
`Cart.php`与`CartModel.php`这两个文件都是对购物车表进行操作的文件。Cart.php文件主要定义了增删改查这四个方法。
<?php if (!defined('ROOT_PATH'))
{
exit('No Permission');
}
/**
*
*
* @category Framework
* @package __init__
* @author Yf <service@yuanfeng.cn>
* @copyright Copyright (c) 2010, 朱羽婷
* @version 1.0
* @todo
*/
class Cart extends Yf_Model
{
public $_cacheKeyPrefix = 'c|Cart|';
public $_cacheName = 'cart';
public $_tableName = 'cart';
public $_tablePrimaryKey = 'cart_id';
/**
* @param string $user User Object
* @var string $db_id 指定需要连接的数据库Id
* @return void
*/
public function __construct(&$db_id = 'shop', &$user = null)
{
$this->_tableName = TABEL_PREFIX . $this->_tableName;
parent::__construct($db_id, $user);
}
/**
* @param int $config_key 主键值
* @return array $rows 返回的查询内容
* @access public
*/
public function getCart($cart_id = null, $sort_key_row = null)
{
$rows = array();
$rows = $this->get($cart_id, $sort_key_row);
return $rows;
}
/**
* 插入
* @param array $field_row 插入数据信息
* @param bool $return_insert_id 是否返回inset id
* @param array $field_row 信息
* @return bool 是否成功
* @access public
*/
public function addCart($field_row, $return_insert_id = false)
{
$add_flag = $this->add($field_row, $return_insert_id);
//$this->removeKey($config_key);
return $add_flag;
}
/**
* 根据主键更新表内容
* @param mix $config_key 主键
* @param array $field_row key=>value数组
* @return bool $update_flag 是否成功
* @access public
*/
public function editCart($cart_id = null, $field_row = array(), $flag = true)
{
$update_flag = $this->edit($cart_id, $field_row, $flag);
return $update_flag;
}
public function editCartNum($cart_id = null, $field_row = array())
{
$update_flag = $this->edit($cart_id, $field_row);
return $update_flag;
}
/**
* 更新单个字段
* @param mix $config_key
* @param array $field_name
* @param array $field_value_new
* @param array $field_value_old
* @return bool $update_flag 是否成功
* @access public
*/
public function editCartSingleField($cart_id, $company)
{
$update_flag = $this->editSingleField($cart_id, $company);
return $update_flag;
}
/**
* 删除操作
* @param int $config_key
* @return bool $del_flag 是否成功
* @access public
*/
public function removeCart($cart_id)
{
$del_flag = $this->remove($cart_id);
//$this->removeKey($config_key);
return $del_flag;
}
}
?>
*商城中只能单表查询,不能多表联查。
*`Cart.php`只写最基本的增删改查方法,最好不要把其他的方法写入这个文件。
* editCart方法中的第3个参数表示的是修改数字符号为“+=” 还是“=”,例如editCart(1,array(goods_num=>3),true)),表示的是goods_num = goods_num + 3。editCart(1,array(goods_num=>3),false)),表示的是goods_num = 3。
几种经常使用的查找方法
`listByWhere` 返回带分页的数据
`getOne` 根据主键查找数据
`getByWhere` 根据条件查找数据
更多方法可以在`libraries/Yf/Model.php`中查找。
四、controller方法
例子:获取当前用户的购物车数据
地址为:`http://shop.bbc-builder.com/index.php?ctl=Buyer_Cart&met=cart`
CartCtl.php中定义的cart方法上面已经写出。其中`$data = $this->getCart();`的getCart()方法如下:
/**
* 获取购物车列表
*
* @author Zhuyt
*/
public function getCart()
{
$user_id = Perm::$row['user_id'];
$Goods_BaseModel = new Goods_BaseModel();
$cord_row = array();
$order_row = array();
$cond_row = array('user_id' => $user_id);
$order_row['cart_id'] = 'DESC';
$data = $this->cartModel->getCardList($cond_row, $order_row);
foreach ($data as $key => $value) {
$goods_detail = $Goods_BaseModel->getGoodsDetailInfoByGoodId($value['goods'][0]['goods_id']);
if (!empty($goods_detail['common_base']['common_spec_name'])) {
//商品规格颜色图
if (!empty($goods_detail['common_base']['common_spec_value_color'])) {
$data[$key]['goods'][0]['goods_base']['goods_image'] = $goods_detail['common_base']['common_spec_value_color'][$value['goods'][0]['goods_base']['color_id']];
}
}
}
if ($data) {
$status = 200;
$msg = __('success');
} else {
$status = 250;
$msg = __('failure');
}
$this->data->addBody(-140, $data, $msg, $status);
return $data;
}
使用model方法先实例化对象。
$this->cartModel = new CartModel();
获取数据后根据实际需求决定是返回数据还是加载页面。
五、view中显示数据
例子:购物车页面
<div class="cart_goods">
<ul class='cart_goods_head clearfix'><li class="done"><?=_('操作')?></li>
<li class="price_all"><?=_('小计')?>(<?=(Web_ConfigModel::value('monetary_unit'))?>)</li>
<li class="goods_num"><?=_('数量')?></li>
<li class="goods_price"><?=_('单价')?>(<?=(Web_ConfigModel::value('monetary_unit'))?>)</li>
<li class="goods_name"><?=_('商品')?></li>
<li class="cart_goods_all cart-checkbox " style="float:left;"><input class="checkall" type="checkbox" data-type="all"><div class="select_all"><?=_('全选')?></div></li>
</ul>
<form id="form" action="?ctl=Buyer_Cart&met=confirm" method='post'>
<ul class="cart_goods_list clearfix">
<?php foreach($data as $key=>$val){?>
<li class="carts_content">
<div class="bus_imfor clearfix">
<p class="bus_name">
<input class="checkshop checkitem" type="checkbox" data-type="all">
<span><i class="iconfont icon-icoshop"></i><a href="<?= Yf_Registry::get('url') ?>?ctl=Shop&met=index&id=<?=($key)?>"><?=($val['shop_name'])?></a></span>
</p>
</div>
<table id="table_list" class="table_list">
<tbody class="rel_good_infor">
<?php foreach($val['goods'] as $k=>$v){ ?>
<tr class="row_line">
<td class="goods_sel cart-checkbox">
<p>
<input class="checkitem" type="checkbox" name="product_id[]" value="<?=($v['cart_id'])?>" <?php if($v['IsHaveBuy']){?>disabled="" title="您已达限购数量" <?php }?> >
</p>
</td>
<td class="goods_img"><img src="<?=($v['goods_base']['goods_image'])?>"/></td>
<td class="goods_name_reset">
<a target="_blank" href="<?= Yf_Registry::get('url') ?>?ctl=Goods_Goods&met=goods&gid=<?=($v['goods_base']['goods_id'])?>"><?=($v['goods_base']['goods_name'])?></a>
<?php if(isset($v['goods_base']['promotion_type'])): ?>
<p class="sal_price">
<?php if($v['goods_base']['promotion_type'] == 'groupbuy' && $v['goods_base']['down_price']): ?>
<?=_('团购,直降:')?><?=format_money($v['goods_base']['down_price'])?>
<?php endif;?>
<?php if($v['goods_base']['promotion_type'] == 'xianshi' && $v['goods_base']['down_price']): ?>
<?=_('限时折扣,直降:')?><?=format_money($v['goods_base']['down_price'])?>
<?php endif;?>
</p>
<?php endif; ?>
<p>
<?php if(!empty($v['goods_base']['spec'])){foreach($v['goods_base']['spec'] as $sk => $sv){ ?>
<?=($sv)?>
<?php }}?>
</p>
</td>
<td class="goods_price">
<?php if($v['old_price'] > 0){?><p class="ori_price"><?=($v['old_price'])?></p><?php }?>
<p class="now_price"><?=($v['now_price'])?></p>
</td>
<td class="goods_num">
<?php
if($v['buy_limit'] && !$v['IsHaveBuy'])
{
$data_max = $v['buy_residue'];
}
else
{
$data_max = $v['goods_base']['goods_stock'];
}
?>
<a class="<?php if($v['goods_num'] == 1){?>no_<?php }?>reduce" ><?=_('-')?></a><input id="nums" data-id="<?=($v['cart_id'])?>" data-max="<?=($data_max)?>" value="<?=($v['goods_num'])?>"><a class="<?php if($data_max <= 1){?>no_<?php }?>add" ><?=_('+')?></a>
</td>
<td class="price_all cell<?=($v['cart_id'])?>">
<span class="subtotal"><?=($v['sumprice'])?></span>
</td>
<td class="done del"><a data-param="{'ctl':'Buyer_Cart','met':'delCartByCid','id':'<?=($v['cart_id'])?>'}"><?=_('删除')?></a></td>
</tr>
<?php }?>
</tbody>
</table>
</li>
<?php }?>
</ul>
</form>
</div>
五、其他
(1)在shop中调用其他项目的方法 `get_url_with_encrypt`
定义方法的文件:`libraries\__init__.php`
//可以判断请求时间是否超过某个期限
function get_url_with_encrypt($key, $url, $formvars = array(), $typ = 'JSON', $method = 'POST')
{
$formvars['rtime'] = get_time();
$hash_row = $formvars;
array_multiksort($hash_row, SORT_STRING);
$hash_row['key'] = $key;
$tmp_str = http_build_query($hash_row);
Yf_Log::log('$tmp_str:' . $tmp_str, Yf_Log::INFO, 'get_url_with_encrypt');
Yf_Log::log('$url:' . $url, Yf_Log::INFO, 'get_url_with_encrypt');
$formvars["token"] = md5($tmp_str);
Yf_Log::log($hash_row, Yf_Log::INFO, 'get_url_with_encrypt');
Yf_Log::log($formvars, Yf_Log::INFO, 'get_url_with_encrypt');
$rs = get_url($url, $formvars, $typ, $method);
Yf_Log::log($rs, Yf_Log::INFO, 'get_url_with_encrypt');
return $rs;
}
例如:
在shop中调用paycenter中的用户信息。
//会员的钱
$key = Yf_Registry::get('shop_api_key');
$formvars = array();
$user_id = Perm::$userId;
$formvars['user_id'] = $user_id;
$formvars['app_id'] = Yf_Registry::get('shop_app_id');
$money_row = get_url_with_encrypt($key, sprintf('%sindex.php?ctl=Api_User_Info&met=getUserResourceInfo&typ=json',
Yf_Registry::get('paycenter_api_url')), $formvars);
在shop中验证接口合法性的方法`check_url_with_encrypt`
定义方法的文件:`libraries\__init__.php`
function check_url_with_encrypt($key, $formvars = array())
{
Yf_Log::log($formvars, Yf_Log::INFO, 'check_url_with_encrypt');
$token = $formvars['token'];
unset($formvars['token']);
$hash_row = $formvars;
array_multiksort($hash_row, SORT_STRING);
$hash_row['key'] = $key;
$tmp_str = http_build_query($hash_row);
Yf_Log::log('$tmp_str:' . $tmp_str, Yf_Log::INFO, 'check_url_with_encrypt');
Yf_Log::log('md5-key:' . md5($tmp_str), Yf_Log::INFO, 'check_url_with_encrypt');
//可以判断请求时间是否超过某个期限, 1分钟内
if ((get_time() - $hash_row['rtime'] < 60000) && $token == md5($tmp_str)) {
return true;
} else {
return false;
}
}
例如:`shop\controllers\Api\Controller.php`
if (!check_url_with_encrypt($key, $data)){
$this->data->setError(__('API接口有误,请确保APP KEY及APP ID正确'), 301); $d = $this->data->getDataRows();
$protocol_data = Yf_Data::encodeProtocolData($d);
echo $protocol_data; exit();
}
底层防SQL注入:
/**
* 转义字符函数
*
* @param mixed $content contents should be addslashes
*
* @return mixed $content
*
*/
function quotes(&$content)
{
if (is_array($content)) {
foreach ($content as $key => $value) {
$content[$key] = quotes($value);
}
} else {
$content = addslashes($content);
}
return $content;
}
在`libraries\Yf\Model.php`文件的174行
$value = htmlspecialchars($value);
验证否登录方法在该模块下的控制器里controllers=>plugin 文件夹下Perm.php
添加免验证登录的控制器文件在此添加(一般用于未登录下的数据显示获取)
public function checkPerm()
{
$data = new Yf_Data();
//无需权限判断的文件
$not_perm = array(
'Upload',
'Login',
'Api',
'ImApi',
'Index',
'Base_District',
'Connect_Qq',
'Connect_Weixin',
'Connect_Weibo',
'Transport',
'Shop',
'GroupBuy',
'Points',
'Voucher',
'Article_Base',
'Shop_Index',
'RedPacket',
'Supplier_Index',
'Supplier_Goods',
'PinTuan',
'Qr',
'Informationlist',
'Webconfig',
'Explore_UnExplore',
'Bargain_UnBargain',
'WxPublicTool_Index',
'Bill',
'Special_Column',
'WxPublicTool_SellerWx',
'Common',
'Distribution_NewBuyer_UploadWap',
'Distribution_NewBuyer_Goods',
'WeChatCs_Index',
'Test',
'Live',
'Shop_GoodsCat',
'Seller_Trade_Order',
'QiShou_Base',
'QiShou_Cash',
'QiShou_Evaluation',
'QiShou_Income',
'QiShou_Info',
'UploadAlbum',
'Api_Album',
);
//不需要登录
if (!isset($_REQUEST['ctl']) || (isset($_REQUEST['ctl']) && in_array($_REQUEST['ctl'], $not_perm)) || (isset($_REQUEST['ctl']) && 'Api_' == substr($_REQUEST['ctl'], 0, 4)) || (isset($_REQUEST['ctl']) && 'WebPosApi_' == substr($_REQUEST['ctl'], 0, 10)) || (isset($_REQUEST['ctl']) && 'Goods_' == substr($_REQUEST['ctl'], 0, 6)) ||(in_array($_REQUEST['ctl'],$GLOBALS['extends_ini'])))
{
if (Perm::checkUserPerm())
{
}
}
elseif (Perm::checkUserPerm())
{
}
else
{
// Perm::removeUserInfo();
if ('e' == $_REQUEST['typ'])
{
$url = Yf_Registry::get('url') . '?ctl=Login&met=login&typ=e';
if (request_string('forward_self'))
{
//$forward = '&forward=//:' . $_SERVER['HTTP_HOST'] . urlencode($_SERVER['REQUEST_URI']);
$forward = '&forward=' . urlencode('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
$forward = str_replace('forward_self', 'x_self', $forward);
$url = $url . $forward;
}
else
{
if (isset($_SERVER['HTTP_REFERER']))
{
$forward = '&forward=' . urlencode($_SERVER['HTTP_REFERER']);
$url = $url . $forward;
}
}
location_to($url);
}
else
{
if('json' == $_REQUEST['typ'] && Perm::checkUserPerm())
{
}
else
{
$data->setError(__('需要登录'), 30);
return $this->outputError($data);
}
}
}
}
日志添加文件在开发过程中对于特定节点进行日志监控通过此方法提添加
```
$arra指要记录的数据
$log_name指要添加的日志名称
Yf_Log::log($array, Yf_Log::INFO, $log_name);
```
操作日志则是在controllers=>plugin 文件夹下的log.php添加
public function addLog()
{
//同步,直接操作日志数据库
if (true || isset($ccmd_rows[$_REQUEST['ctl']][$_REQUEST['met']]['log']))
{
$Yf_Registry = Yf_Registry::getInstance();
$ccmd_rows = $Yf_Registry['ccmd_rows'];
$rights_id = @$ccmd_rows[$_REQUEST['ctl']][$_REQUEST['met']]['rid'];
$data = array();
if (Perm::$login)
{
$data['user_id'] = Perm::$row['user_id']; // 玩家Id
$data['user_account'] = Perm::$row['user_account']; // 角色账户
//$data['user_name'] = Perm::$row['user_realname'] ; // 角色名称
}
else
{
}
$data['action_id'] = $rights_id; // 行为id == protocal_id -> rights_id
$data['log_param'] = $_REQUEST; // 请求的参数,|| 详细数据,可以通过controller结束赋值全部变量来或获取
$data['log_ip'] = get_ip(); //
$logActionModel = new Log_ActionModel();
$log_id = $logActionModel->addAction($data, true);
}
//异步,队列操作
}
- 序言
- 系统要求
- 版本更新日志
- 远丰商城技术对接说明
- 开发指导
- 系统架构
- 负载集群
- 云存储
- 框架内容
- 基础
- 开发规范
- 目录结构
- 架构
- 架构总览
- 数据库
- 数据库连接
- 基本使用
- 缓存
- 配置
- 路由
- 数据字典
- ucenter
- shop
- paycenter
- ucenter_admin
- shop_admin
- paycenter_admin
- shop1
- shop2
- shop3
- 通讯内容
- 商家中心
- 顶部导航栏
- 店铺信息栏
- 店铺及商品提示栏
- 交易提示栏
- 销售情况统计栏
- 集群架构图
- 单品销量排行栏
- 店铺运营推广栏
- 平台联系方式栏
- 订单物流
- 商品
- 商品列表
- 商品详情
- 商品发布与编辑
- 分销商品
- 关联版式
- 商品规格
- 图片空间
- 淘宝导入
- 订单流程
- 交易订单
- 订单退款/退货
- 促销
- 团购管理
- 加价购
- 限时折扣
- 满即送
- 代金券管理
- 分销
- 店铺
- 店铺设置
- 自销产品供应商
- 实体店铺
- 品牌申请
- 店铺信息
- 消费者保障服务
- 门店账号
- 分销商--产品供应商
- 分销明细
- 批发市场
- 商家微信公众号
- 售后服务
- 咨询管理
- 投诉管理
- 退款管理
- 退货管理
- 杂项
- 远程上传图片
- 接口(废弃,参考最外层接口项)
- 接口说明
- 品牌
- 商品规格
- 商品类型
- 商品分类
- 商品
- 订单
- 商品/店铺收藏
- 足迹
- 退款及退货
- 商家店铺
- 会员
- 入驻协议
- 订单接口
- 商品接口
- 订单物流接口
- 商家中心接口
- 促销接口
- 快递鸟物流接口
- 代金券接口
- 首页版块
- 团购
- 平台红包
- 限时折扣接口
- 拼团接口
- wap首页模板
- JS
- 银联支付
- 多语言
- 商品评分
- 图片加载
- 买家申请退款退货
- 商家退款退货
- 平台退款退货
- 添加发票
- 提交订单
- 确认订单
- 运费销售区域
- 获取会员地址
- 充值
- 导出XLS
- 商城系统集成
- 多语言实现
- 三级分销推广链接发展推广员
- app.ini.php
- 去分销
- 版本更新
- 物流支持
- 运营人员建议
- 业务逻辑
- 统计结算
- 客服消息
- 账号
- 三级分销
- IM
- 配置
- 平台帐号
- 活动数据表说明
- 接口
- 数据库中间键
- MyCat的优势
- 概念说明
- Mycat的下载及安装
- 参数配置案列
- Mycat读写分离
- 基本命令
- 常见错误