当前位置:首页 > 开发教程 > 软件工程 >

yershop商城系统开发一——thinkphp和onethink简析

时间:2016-06-08 10:46 来源: 作者: 收藏

考察了拷贝构造函数和赋值构造函数,以及通过子类构造时调用基类构造函数时候,基类构造函数调用同名的virtual函数(基类和之类中都有,同名覆盖),调用时仍然是调用的基类中的该函数。/********************************************************************

yershop商城系统是基于thinkphp和onethink开发而来,此系列将详细分析我在二次开发中所面临的种种问题。
本篇简要分析日常在二次开发中涉及到的thinkphp和onethink知识。

yershop目录结构了解

yershop商城系统开发一——thinkphp和onethink简析
此为我的项目中在zendstudio中截图
Addons:扩展插件目录,里面包含了第三方登陆插件、编辑器插件等;
Application:项目目录,之后详细介绍
Data:数据库备份目录
Public:js、css、image网站图片资源保存
Uploads:上传图片、文件目录(SAE环境下存储于storage中)
Runtime:运行中动态生成的程序(在检查标签语法出错时很有用,文件可删除)
Thinkphp:Thinkphp包,yershop系统或onethink在开发中均对Thinkphp包有改动,勿直接换该文件
yershop商城系统开发一——thinkphp和onethink简析

Application目录

Common:公共配置,进入应用程序后,首先加载此文件夹内容;
User:用户模块,提供用户注册之类的核心方法;
Install:安装模块,安装异常时可在此检查代码;
Home:PC网站模块;
Wap:手机网站模块;(个人开发,免费下载包无)
Wei:嫁接weiphp2.0到商城所用模块(个人自定义模块,免费下载包无)

Common目录

yershop商城系统开发一——thinkphp和onethink简析
此处重点关注 Common文件夹/function.phpConf文件夹/config.php 两个文件
function.php为全局方法,Home、Wap、自定义模块等其它模块 均可调用其内方法;
config.php 为全局配置文件,需要注意的是数据库连接以及User模块下同名文件的数据库连接。

问:PC站和手机站如何在输入主域名后直接访问对应模块(Home or Wap)?
答: 在config.php文件开头根据访问源指定要加载的模块,代码如下
if(!ismobile()){
$module = 'Home';
}else{
$module = 'Wap';
}
return array(
/* 模块相关配置 */
'AUTOLOAD_NAMESPACE' => array('Addons' => ONETHINK_ADDON_PATH), //扩展模块列表
'DEFAULT_MODULE' => $module,

ismobile()方法可使用function.php里已有的判断说否为手机方法,此处贴代码:

function ismobile() {
    // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
    if (isset ($_SERVER['HTTP_X_WAP_PROFILE']))
        return true;

    //此条摘自TPM智能切换模板引擎,适合TPM开发
    if(isset ($_SERVER['HTTP_CLIENT']) &&'PhoneClient'==$_SERVER['HTTP_CLIENT'])
        return true;
    //如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
    if (isset ($_SERVER['HTTP_VIA']))
        //找不到为flase,否则为true
        return stristr($_SERVER['HTTP_VIA'], 'wap')  true : false;
    //判断手机发送的客户端标志,兼容性有待提高
    if (isset ($_SERVER['HTTP_USER_AGENT'])) {
        $clientkeywords = array(
                'nokia','sony','ericsson','mot','samsung','htc','sgh','lg','sharp','sie-','philips','panasonic','alcatel','lenovo','iphone','ipod','blackberry','meizu','android','netfront','symbian','ucweb','windowsce','palm','operamini','operamobi','openwave','nexusone','cldc','midp','wap','mobile'
        );
        //从HTTP_USER_AGENT中查找手机浏览器的关键字
        if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
            return true;
        }
    }
    //协议法,因为有可能不准确,放到最后判断
    if (isset ($_SERVER['HTTP_ACCEPT'])) {
        // 如果只支持wml并且不支持html那一定是移动设备
        // 如果支持wml和html但是wml在html之前则是移动设备
        if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
            return true;
        }
    }
    return false;
}

Home目录

yershop商城系统开发一——thinkphp和onethink简析
Home下也有 Common/function.php 和 Conf/config.php 两个文件,但作用域仅限Home模块
注意:该function.php里的方法不能有和Common模块下总function.php里 重名 的方法,否则报 无法重载的错误。

Home/Conf/config.php文件

此文件内可配置仅针对PC端网站使用的配置,例如支付宝配置信息
有学习价值的配置信息:

/* 主题设置 */
    'DEFAULT_THEME' =>  'monkey',  // 默认模板主题名称,与View文件相关
    'URL_MODEL'            => '2', //URL模式:2为隐藏index.php的rewrite模式
    'PICTURE_UPLOAD_DRIVER'=>defined('SAE_TMP_PATH')  'Sae' : 'local',
    //本地上传文件驱动配置
    'UPLOAD_LOCAL_CONFIG'=>array(), 
    'UPLOAD_SAE_CONFIG'=>array(
    'rootPath'=>'',
    'domain'=>'upload',
    ),
    'SAE_Domain'  => 'http://' . $_SERVER['HTTP_APPNAME'] . '-upload.stor.sinaapp.com',//sae的storage支持所需

Controller控制器文件夹及文件

thinkphp设置默认加载Index控制器中index()方法,在这里所有文件都继承了HomeController,在HomeController.class.php文件里可定义多数页面都需要加载的方法,如

/* 空操作,用于输出404页面 */
public function _empty(){
        $this->redirect('Index/index');
    }
//初始化方法,本方法总会被最先加载
protected function _initialize(){
        /* 读取站点配置 */
        $config = api('Config/lists');
        C($config); //添加配置

        if(!C('WEB_SITE_CLOSE')){
            $this->error('站点已经关闭,请稍后访问~');
        }
    }

View视图文件夹

yershop商城系统开发一——thinkphp和onethink简析
因为在Home模块的config.php文件中设置了'DEFAULT_THEME' => 'monkey',故会加载View/monkey文件夹

问:Controller与View的关联?
答:需要前台展现的页面,如用户登陆页面,只需在UserController.class.php文件login()方法最后使用

//显示登录表单
$this->display();

如果需要指定加载模版,

//显示登录表单
$this->display('User/index');

则会调用User控制器下login方法,展现User文件夹下index.html模版页面
一定要学会根据URL判断所加载文件的位置!
例如:www.xxx.com/index.php/Home/User/login.html
文件后台代码位置:Home/Controller/UserController.class.php->login()方法;
默认前台代码位置:Home/View/(default文件夹 or 自定义 or null)/User/login.html。
少数文件会加载指定模版,但后台代码位置一般不会有误。

问:我自己创建了一个控制器,但每次访问都直接跳转到了Index/index里?
答:排除代码错误问题
1.控制器命名:
(1)首字母大写;
(2)XxxController.class.php中,Xxx中有其它大写字母,例如WxPayController.class.php;
2.类名与文件名不统一
文件名为:UserController.class.php,则类名必须为UserController

namespace Home\Controller;
/**
 * 用户控制器
 * 包括用户中心,用户登录及注册
 */
class UserController extends HomeController {...

3.在Thinkphp核心程序中设置了跳转(weiphp中),Thinkphp包是最先被加载的,在weiphp中Thinkphp/Library/Think/Controller.class.php中有一个初始化函数,设定了未登录跳转。作为参考
4.View文件夹中base母版文件被添加了跳转代码(同样存在与weiphp)
5.后台设置了限制访问的目录(weiphp含有)
6.在没有以上问题,请新建控制器文件,从已有能正常访问的控制器代码复制,修改class类名。

View视图中类似asp.net的母版实现及修改

打开Index/index.html文件,可以看到

<extend name="Base/common" />

<block name="body">
...
</block>

extend,母版位置为Base文件夹/common.html文件,找到打开

<!DOCTYPE HTML>
<html>
<head>
    <include file="Public/head"/>
</head>
<body>
    <!-- 工具条 -->
    <include file="Public/toolbar"/>
    <!-- /工具条 -->
    <!-- 头部 -->
    <div class="yershop_wrapper">
        <include file="Public/header"/>
        <include file="Public/menu"/>
    <!-- /头部 -->

    <!-- 主体 -->
    <include file="Public/body"/>
    <!-- /主体 -->

   <!-- 购物车js -->
   <include file="Public/cart_js"/>
   <!-- /购物车js -->
    <!-- 底部 -->

    <include file="Public/footer"/></div>
     <include file="Public/kefu"/>
    <!-- /底部 -->
</body>
</html>

母版页使用 include 将其它页面包含进来,注意写法。
而在被包含的页面中打开Public文件夹/body.html文件,在其中我们会看到

 <block name="body">
 </block>

这段代码,这就决定了index.html文件

<block name="body">
...内容
</block>
中内容部分最终被加载到哪个位置。
block这段代码对于内容部分、额外加载的css、js代码部分常用,因为每个页面都要使用同样的母版,但内容以及内容的css、js可能不同,block就起到很好的自定义作用。
其它固定的内容,则不需要使用。

常用操作

后台给前台传参

后台:

...某控制器下的方法内{
//参数
$a = 3;
$this -> assign('xxx',$a);
//一维数组
$yidata = M('order')->where(array('id'=>$a))->find();
$this -> assign('yiwei',$yidata);
//二维数组
$erdata = M('order')->where(array('status'=>1))->select();
$this -> assign('erwei',$erdata);
$this -> display();
}

对应前台使用

后台传了参数:
{$xxx}
后台传递了一维数组获取:
{$yiwei.id} or {$yiwei['id']}
后台传递了二维数组获取:
<volist name="erwei" id="vo">
 第{$key}个参数id是:{$vo.id} or {$vo['id']}
</volist>

对于不确定的数组内容,使用var_dump()函数打印数据在前台输出查看

在前台页面调用方法,U函数带参链接书写方式

{:data("Y-m-d H:i:s",$vo['create_time'])}
{:U('Wap/Article/index',array('category'=>'jste'))}//调用wap模块下Article控制器下index方法,url传递参数category为jste
{:U('Article/detailid='.$vo['id'])}//调用当前模块下Article控制器下detail方法,并传递参数id为变量值

绝对不要将上述形式的函数(冒号开头)的参数写成 $vo.create_time形式,否则无法解析,写成原生数组形式

{$vo.id|get_cover_id|get_cover='path'}
/* 先解析{$vo.id},之后其作为get_cover_id函数的参数,返回商品封面图片的cover_id,第三步通过第二步得到的cover_id,将其和path作为get_cover两个参数传递。
*/

前台使用原生php程序

<php>
$a = 1;
if($a > 0 ){
</php>
<h1>a > 0显示</h1>
<php> } </php>

或者

<php
$a = 1;
if($a > 0 ){
echo '<h1>a > 0显示</h1>';
}
 >

此两种方法各有千秋,如果html代码较多,使用第一种;较少可用第二种。

===================
原版出处-csdn:blog.csdn.net/afanxingzhou。
学习交流Q724122005,承接小项目开发。

0
0
   

软件工程阅读排行

最新文章