ecmall 学习记录

1.

	/* 载入配置项 */
        $setting =& af(MODULE);
        Conf::load($setting->getAll());

 af方法定义如下:

/**
 *    获取数组文件对象
 *
 *    @author    Garbin
 *    @param     string $type
 *    @param     array  $params
 *    @return    void
 */
function &af($type, $params = array())
{
    static $types = array();
    if (!isset($types[$type]))
    {
        /* 加载数据文件基础类 */
        include_once(ROOT_PATH . '/includes/arrayfile.base.php');
        include(ROOT_PATH . '/includes/arrayfiles/' . $type . '.arrayfile.php');
        $class_name = ucfirst($type) . 'Arrayfile';
        $types[$type]   =   new $class_name($params);
    }

    return $types[$type];
}

 其实就是加载了两个文件,然后返回了一个实例化的对象,上面载入配置项 af 传参的MODULE是指当前模块的名字,

关于af方法 注释说是没有返回值,但是下面return的是一个对象,af里引入了两个类文件,其实,实例化的就是basearrayfile这个对象,因为引入的类文件里继承的这个basearrayfile对象,然后调用里面的方法获取配置信息,至于什么时候要获取配置信息,就要看项目需求了,比如,会员年费有可能是100,也有可能是200,这个时候不能在程序里写死,所以要在配置文件里配置,这样要改的话就改配置文件,就不用改程序代码了,通过查询配置文件,就可以得到修改后的价格。配置文件在data目录下名为XXX..inc.php.

m 实例化模型对象,这个是最常用的 也就相当于TP框架里的直接实例化一张表,可以对表的内容进行增删查改。

bm 实例化的是业务对象,也就是继承自模型对象(m方法实例化的),不过逻辑相对复杂,就抽象出来行成业务对象,进行业务逻辑处理,也会有增删改查,业务多的时候需要逻辑分层,这个时候用bm,(可以参考线上商城的goods.model.php)我还是不太懂,大腿毕竟是大腿,等过几年接触的东西多了,业务实现的多了,说不定我就懂了......此处应该有表情,可是这个编辑器没有,我能怎么办呢,我也很无奈。

2017.6.9

 

关于ecmall的模块开发

什么时候用到模块开发? 一个新的项目需求,需要分析,经常用的是直接写控制器 也就是在项目文件夹下的app里写前台控制器,在admin/app里写后台控制器。

开发过程中,常用的就是直接在app目录下写控制器,适用于简单的需求,可快速开发,扩展性较差,相应的功能在后台需要添加相应的菜单。

开发模块适用于较大,较为复杂的项目需求,模块的扩展性较好,模块开发也要写前后台模块,后台扩展里可以进行模块的管理。

关于模块开发和直接写控制器,在逻辑上,业务上没有区别,只是不同的做法而已,module比较容易扩展,app比较容易开发。

模块访问就是 index.php?module=XX&act=XXX

直接写控制器的访问就是 index.php?app=XX&act=XXX

 

关于ecmall的模版

前台模版是在项目目录下的themes 里面分为mall 和store 。mall 是商城模版,store是店铺模版。至于控制器引入上传模版还是店铺模版就看继承的父类了,继承mallbase的就引入mall,继承storebase就引入store。

2017.6.12


1.ecmall 自带的写入日志方法:do_log4php("函数名","类名",$param);   $param是参数

在类里调用写入之日的方法 需要先加载函数工具库  import('functions.lib');  

生成的日志存在于 temp/logs。  

配置路径就在 log4php.properties文件中,这个文件就在项目根目录下,找不到的话可以用everything找一下。

 

2.ecmall 引入微信jsssdk类库 import('文件名'); ecmall 引入微信类库;ecmall生成微信签名

判断是否为微信端:

function isWeixin()
{	
	if ( strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false ) {
		return true;
	}	
	return false;
}

获取微信签名:

		/*start@author:hans@date:20160718*/
		//引入微信授权
		if( isWeixin() ){
			import('weixinsdk');
			import('functions.lib');
			$weixin_config = require_once('data/weixin_config.php');
			$jssdk = new JSSDK($weixin_config['appId'], $weixin_config['appSecret']);
			$signPackage = $jssdk->GetSignPackage();
		//do_log4php("display","FrontendApp",$signPackage);
			$this->assign('wxsignPackage',$signPackage);
		}
		/*end@author:hans@date:20160718*/

 

3.后台一级菜单设置有个开启伪静态,开了和不开的区别很大,测试系统上没有开,线上开了,所以店铺分享可以正常用。

 

4.关于JS-SSDK中获得微信签名方法的修改

     //地址没有入口文件  2017615 	xiaolu   
    if (empty($request_uri)){    //没有入口文件的时候request_uri是为空的  打印一下$_SERVER 就知道该用什么啦
    
    	$request_uri=$_SERVER['REQUEST_URI'];
    }
   if (strpos($_SERVER['REQUEST_URI'],"from=")){  //如果是从分享的地址进来的,会有from 
  	 
   		 $request_uri=$_SERVER['REQUEST_URI'];
     }
    //end
    $url = "$protocol$_SERVER[HTTP_HOST]$request_uri";

    $timestamp = time();
    $nonceStr = $this->createNonceStr();

 这个是针对功能需求进行的修改。

 

5. 个人中心:member.app.php index()   $this->_curitem('overview');            //这个方法调用了_get_member_menu() 菜单数据就是从这里拿到的

个人中心的菜单在 frontend.base.php里的 _get_member_menu()方法中以数组的形式定义的

 

6.$user = $this->visitor->get();获取用户信息

$this->visitor->调用的方法   在ecapp.base.php里  访问者基础类 class BaseVisitor extends Object 中,访问者基础类,集合了当前访问用户的操作。

2017-7-4


1.在ecmall.php 中 336行有一个函数

function lang_file($file)
{
    return ROOT_PATH . '/languages/' . LANG . '/' . $file . '.lang.php';
}

 这个是函数不在LANG 类中。函数可以直接用。类的函数也叫成员方法,不能在类外直接调用,要实例化类。

 ecmall.php中 有四个类:ecmall,object,lang,conf,其他的还有系统常量,兼容配置,主要的还是 函数方法。

 

 2.conf 类 (跟配置相关)

   /**
     *    加载配置项
     *
     *    @author    Garbin
     *    @param     mixed $conf
     *    @return    bool
     */
    function load($conf)
    {
        $old_conf = isset($GLOBALS['ECMALL_CONFIG']) ? $GLOBALS['ECMALL_CONFIG'] : array();
        if (is_string($conf))
        {
            $conf = include_once($conf);
        }
        if (is_array($old_conf) && is_array($conf))
        {
            $GLOBALS['ECMALL_CONFIG'] = array_merge($old_conf, $conf);
        }
        else
        {
            $GLOBALS['ECMALL_CONFIG'] = $conf;
        }
    }
    /**
     *    获取配置项
     *
     *    @author    Garbin
     *    @param     string $k
     *    @return    mixed
     */
    static function get($key = '')
    {
        $vkey = $key ? strtokey("{$key}", '$GLOBALS[\'ECMALL_CONFIG\']') : '$GLOBALS[\'ECMALL_CONFIG\']';

        return eval('if(isset(' . $vkey . '))return ' . $vkey . ';else{ return null; }');
    }

 一般用到加载配置项,都是 先 load 再 get  。

load() 就是将 配置文件赋值给全局变量 $GLOBALS['ECMALL_CONFIG']  

get() 就通过键  来获取在load()中刚刚被赋值的 $GLOBALS['ECMALL_CONFIG']  中对应键的值。

 

小例子:

控制器代码:

goods.inc.php中的部分配置:

在控制器中加载配置项:

load()传参是字符串,也就是引入了配置项并且赋值给了全局变量$GLOBALS['ECMALL_CONFIG'];

然后在调用get方法 加载键为category_good_num对应的值。 从而获得商品配置。

 

2017-7-7.点滴知识,重在积累。

 

 

---------------------------华丽的分隔线--------------------------------------

1.ecmall.php中的

import()函数:

function import()
{
    $c = func_get_args();
    if (empty($c))
    {
        return;
    }
    array_walk($c, create_function('$item, $key', 'include_once(ROOT_PATH . \'/includes/libraries/\' . $item . \'.php\');'));
}

func_get_args() 将传给当前函数所有的参数 组成 牵引 数组 并返回:

function foo() {     // returns an array of all passed arguments 
 $args = func_get_args();   
 foreach ($args as $k => $v) {
  echo “arg”.($k+1).”: $v\n”;
  }  
}  
foo();  /* 没用任何输出*/  
foo(‘hello’);  /* 输出  arg1: hello  */ 
foo(‘hello’, ‘world’, ‘again’);  /*输出 arg1: hello  arg2: world  arg3: again  */  

 现在举个例子 (=_=)

 import("function.lib"); //调用上面的引入类函数

// 然后 function_get_args() 返回的是

// array(1) { [0]=> string(12) "function.lib" }

// 接着 create_function()创建了一个新函数: 有两个参数$item和$key,方法体是 :

// include_once(ROOT_PATH . \'/includes/libraries/\' . $item . \'.php\');

// 即引入 根目录下指定路径里的 $item.php文件 //然后 array_walk($c,areate_function(...))

// array_walk()作用就是 将第一个参数$c(数组) 遍历循环,$c 的每一个值都传到creat_function 中执行一次。
// 根据上面$c只有一个键值对, 那么,import("functions.lib")执行的结果就是引入了  项目根目录/includes/libraries/functions.lib.php

 

原来以为import()是把整个项目目录遍历查找同名文件引进来,还琢磨着万一有了同名文件怎么办,直到看了类库才知道,同名文件的想法是有多蠢(→_→)

 

2.ecmall 适配php5.5 需要用到的 preg_replace_callback()函数:

<?php
// 将文本中的年份增加一年.
$text = "today is 04/01/2002\n";

function next_year($matches)
{
  // 通常: $matches[0]是完成的匹配
  // $matches[1]是第一个捕获子组的匹配
  // 以此类推
  return $matches[1].($matches[2]+1);
}
echo preg_replace_callback(
            "|(\d{2}/\d{2}/)(\d{4})|",
            "next_year",
            $text);
 
?>

 一个例子,定义$text,定义了回调函数next_year,调用preg_replace_callback()

第一个参数:正则表达式,第二个是参数是回调函数,最好是直接将函数写进来,第三个是要进行匹配的字符串。

在next_year中打印 $matches:

array(3) { [0]=> string(10) "04/01/2002" [1]=> string(6) "04/01/" [2]=> string(4) "2002" }  

为什么会分成04/01 和 2002 呢?

这和正则表达式有关系:(\d{2}/\d{2}/)(\d{4}第一对()就是$matches[1]。也叫做第一个捕获子组的匹配,第二对()就是$matches[2];

通常: $matches[0]是完成的匹配 , $matches[1]是第一个捕获子组的匹配 , 以此类推

然后会执行年份加一,并且将结果返回。先看最终结果: today is 04/01/2003

修改next_year的ruturn 语句为 $matches[1]."------".($matches[2]+1);

再进行输出,结果为today is 04/01/------2003

这样看来,preg_replace_callback('匹配表达式a','回调函数b',‘需要匹配的内容c’)就是 将  c 在  a 中匹配到的 内容  d 替换 成 经过 b  处理后的 d  最终返回处理后的 c。

preg_replace_callback()中传入 回调函数 b 的 $matches 是数组的形式,要用下标【1】【2】(我是这么理解的 = =) 在正则表达式中 \1 \2 同样是指 第一个捕获子组 第二个捕获子组

在model.app.php中  //$fields = preg_replace('/([a-zA-Z0-9_]+)\.([a-zA-Z0-9_*]+)/e', "\$this->_getFieldTable('\\1') . '.\\2'", $fields); 这里的'\\1'. '.\\2' 就是指第一,第二个捕获子组的匹配,用了转义符号 \ 。

也就是这样:

 

<?php
// 将文本中的年份增加一年.
$text = "today is 04/01/2002\n";

// echo preg_replace_callback(
//             "|(\d{2}/\d{2}/)(\d{4})|",
//             function ($matches)
// 			{
//  				 return $matches[1].($matches[2]+1);
// 			},
//             $text);

echo preg_replace('|(\d{2}/\d{2}/)(\d{4})|', "\\1 ----\\2", $text);  //在这里 加 1, 我试了半天也没加成功,难道是被抛弃了?
 
?>

 

 输出结果是:today is 04/01/ ----2002   同样也是 用 \1 ----\2 (这里我把转义符去掉了)来替换了已经匹配到的内容,现在这个函数好像不太用了,都用preg_replace_callback()

 

上面可以写成这样:

<?php
// 将文本中的年份增加一年.
$text = "today is 04/01/2002\n";

echo preg_replace_callback(
            "|(\d{2}/\d{2}/)(\d{4})|",
            function ($matches)
			{
 				 return $matches[1].($matches[2]+1);//新的日月年来替换文本内被匹配的内容
			},
            $text);
 
?>

 执行结果是一样的。

 

测试:

$string  =  'April 15, 2003' ;
$pattern  =  '/(\w+) (\d+), (\d+)/i' ;
$replacement  =  '\\1 18,\\3';

echo  preg_replace ( $pattern ,  $replacement ,  $string );   //输出 April 18,2003

 修改后:

$string  =  'April 15, 2003' ;
$pattern  =  '/(\w+) (\d+), (\d+)/i' ;
echo preg_replace_callback(
		$pattern,
		function($msg){
			return $msg[1]."&nbsp;".($msg[2]+3).",".$msg[3];
		},
		$string


	)    //输出 April 18,2003

 

 

2017/7/10
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值