123

ecshop URL简单重写

大概在网上调查了一下,ecshop的URL重写主要是为了SEO搜索引擎优化使用。

而简单重写基本就可以满足伪静态的处理需求,ECSHOP v2.7.2,操作步骤如下:

1 打开httpd.conf文件中LoadModule rewrite_module注释。

2 将 ecshop 目录下的htaccess.txt 重命名为 .htaccess。

3 去掉.htaccess文件中RewriteBase /前注释。

4 如修改了httpd.conf文件,则需要重启Apache。

5 进入 ecshop 管理中心->商店设置,将 URL 重写设置为启用。

使用lazyload实现页面缓载

主要是想结合Jquery实现未在屏幕显示区域外的网页,

暂时只加载一张空白图片的效果。

需要用到jquery.js以及相关lazyload处理代码。(这个网上真有)

在页面head处加载完成以上js文件后,

在页面适当处填写页面缓载js代码如下:

$(“.img1 img”).lazyload(
{
placeholder : “空白图片路径”,
effect: “缓载时图片显示效果”,
threshold : 300 //延伸缓载高度300
});

另外$(“.img1 img”)处,这样写是可以指定只有class名为img1下的img才做页面缓载。

当然id等也可以按照jQuery规则使用。

ecshop 保存用户购物车数据

ecshop的购物车记录储存在cart表中,用户向购物车中添加商品时会在其中产生一条记录

靠session_id与用户产生映射关系。当注册用户退出登录或者游客关闭浏览器时,session被销毁,同时删除掉cart表中与之对应的记录。所以ecshop的购物车功能,无法在用户下次登录时记录之前的购物车信息。这在某些场景,如用户误关掉浏览器时十分不方便。
为了解决这个问题,首先要在用户登录时,将他以户已游客身份,产生的购物车数据加上user_id。
然后要将该用户的历史购物车记录中的session_id改为本次的session_id。
最后要在用户退出登录时,保存住注册用户在cart表中的购物车记录。
 
具体实现方法:
一、在includes/lib_main.php
中定义如下方法并在update_user_info()方法中的末尾处执行
/**
* 用户登陆后,载入上一次退出时的购物车信息,并与此次登录前购物车信息合并
*
* @access  public
* @return  void
*/
function merge_cart_history()
{
if (!$_SESSION[“user_id”])
{
return false;
}
$sql = “update ” . $GLOBALS[“ecs”]->table(“cart”) . ” set user_id = ” . $_SESSION[“user_id”] . ” where session_id = “”.SESS_ID.”””;//为用户以游客身份时(登录之前),产生的购物车记录添加user_id
$GLOBALS[“db”]->query($sql);

 $sql1 = “update ” . $GLOBALS[“ecs”]->table(“cart”) . ” set session_id =”” . SESS_ID . “” where user_id = “” . $_SESSION[“user_id”] . “””;//将用户历史购物车记录的session_id,改为本次的session_id
$GLOBALS[“db”]->query($sql1);
$re = $GLOBALS[“db”]->getAll(“select goods_id, rec_id, sum(goods_number) as goods_number from ” . $GLOBALS[“ecs”]->table(“cart”) . ” where user_id = “{$_SESSION[“user_id”]}” and session_id = “”.SESS_ID.”” group by goods_id”);//汇总历史购物记录与本次购物记录中,每一种商品的数量
if($re){
foreach ($re as $k => $v)
{
$sql = “update ” . $GLOBALS[“ecs”]->table(“cart”) . ” set goods_number = ” . $v[“goods_number”] . ” where rec_id = ” . $v[“rec_id”];
$GLOBALS[“db”]->query($sql); //每种商品保留一条记录

$sql = “delete from ” . $GLOBALS[“ecs”]->table(“cart”) . ” where rec_id <> {$v[“rec_id”]} and user_id = “{$_SESSION[“user_id”]}” and session_id = “” . SESS_ID . “” and goods_id = ” . $v[“goods_id”];//删除多余的记录
$GLOBALS[“db”]->query($sql);
}
}
}

二、将includes/cls_session.php中的destroy_session()方法做如下修改:

将$this->db->query(“DELETE FROM ” . $GLOBALS[“ecs”]->table(“cart”) . ” WHERE session_id = “$this->session_id””);

改为$this->db->query(“DELETE FROM ” . $GLOBALS[“ecs”]->table(“cart”) . ” WHERE session_id = “$this->session_id” AND `user_id`=0″);

既销毁当销毁session时,只将cart表中user_id等于0(未登录用户)的购物车记录删除。

改完收工。

 

AppCan 中的AJAX通讯实践

手机应用开发必不可少的就是与网络进行交互。常见的与网络交互都是通过http或https请求方式。这两种方式在以浏览器引擎为核心的Appcan平台中,都是支持的。为了减少数据大小,建议在与网络数据传输时采用json数据格式。
在浏览器中,用异步方式(Ajax)在A网站访问B网站的接口,这种行为被认为是不安全的。为什么呢?想象一个场景:通过Ajax异步请求别的网站接口,返回一个字符串,字符串内容为”<script>//dosomething</script>”,那么这个数据内容就危险了,浏览器会执行<script>标签里面的js代码。这种方式就是所谓的”跨域访问”。这种限制是浏览器做的,其实请求数据已经返回回来。
那么,如何解决跨域访问问题呢,可有几种解决方式
利用第三方网站,比如委托给google网站,google提供了一套跨域访问的js库。
Jquery的$.getJSON方法,这种需要返回数据格式为json格式
在返回头的content-type中设置为application/json
利用Appcan的Native模式开发的widget,也是属于跨域访问的范畴,因此,也会碰到上述情况,这里介绍两种Appcan中的解决方案:
一、Jquery的$.getJSON(url,function(data){});第一个参数是url获取数据地址,第二个参数成功取得数据时调用;
其中,url中必须带有jsoncallback参数,参数值为”?”,Jquery会在请求时替换为一个随机的唯一数:
http://xxxx.php?jsoncallback=?&name1=value1&name2=value2
用$.getJSON时,数据的返回格式要是xxx({“a”:”1″,”b”:”2″})
例如:
xxx({“status”:”true”,”listData”:[{“id”:”261803″,”title”:”虚拟投影键盘”,”name”:”前沿科技”,”summary”:”这款虚拟投影键盘设计独特,每一个敲击都不会相互干扰,可以同时接受。”},{“id”:”261994″,”title”:”科学家发现”最大黑洞””,”name”:”环球快递”,”summary”:”美国加州大学伯克利分校的天文学家尼古拉斯•麦克康纳尔和他的同事发现了两个目前已知最大的黑洞。”}}]})
注意:需验证{“a”:”1″,”b”:”2″}json格式的正确性,可在jsonlint.com网站上验证,如果格式不合法将获取不到数据
 
服务器端需要返回
echo  $[“jsoncallback”].”(“.json_encode($data).”)”; $data为PHP数组
 
二、Appcan封装的uexXmlHttpMgr对象方法如下:
uexXmlHttpMgr.open(String inXmlHttpID, String inMethods, String inUrl);第一个参数:

inXmlHttpID:异步请求操作ID;必须值。(随机不重复)

第二个参数:

inMethods:异步请求类型;(get,post)

第三个参数:

inUrl:异步请求地址;
通过uexXmlHttpMgr.onData函数获取值。
uexXmlHttpMgr.onData(inOpCode,inResult)
inOpCode:操作ID,由发起请求时传入的值,随机不重复;
inResult:服务器返回的任意数据;String类型。
使用方式:

function xmlHttp (){
             var url = document .getElementById ( “add”). value ;
             uexXmlHttpMgr .open (1 , “GET” , url ,“” );
             uexXmlHttpMgr .send (1 );
       }
       function httpSuccess (opid ,status ,result ){
             if (status ==1 ){
             uexXmlHttpMgr .close (1 );
             document .getElementById ( “adre”). value   = result ;
          }
       }

       window .uexOnload = function (){
             uexXmlHttpMgr .onData = httpSuccess ;
             uexWidgetOne .cbError = function( opCode , errorCode , errorInfo ){
                   alert (“errorCode:”   errorCode   “\nerrorInfo:”   errorInfo );
             }
       }
< div data-role =”header  class =” ui-header ui-bar-b ui-header-fixed ui-bar-glass >

< h1 class =”ui-title  tabindex =” 0 role =” heading aria-level=” 1 >
跨域异步请求
</ h1>
</ div>

< div id=” page_5 “ class =”ui-page ui-body-c ui-page-active  tabindex =” 0 >
< div class =”ui-content ui-body-c ui-fixed-top ui-fixed-bottom m-bottom  >
< label for =”text-6  class =” ui-input-text  >请求内容: </ label>
< textarea placeholder =”http://192.168.10.109/phdmyadmin/test.php?func=show    name =”textarea-2  id =” add class=” ui-input-text ui-body-null ui-btn-corner-all ui-shadow-inset ui-btn-d >http://192.168.10.109/phdmyadmin/test.php?func=show </ textarea>
< label for =”text-6  class =” ui-input-text  >请求结果: </ label>
< textarea placeholder =””  name =”textarea-3  id =” adre class =”ui-input-text ui-body-null ui-btn-corner-all ui-shadow-inset ui-btn-d ></textarea >
< div data-role =”button  class =” ui-btn-corner-all ui-btn  ui-btn-e  ui-shadow onclick =xmlHttp( )> < span class =” ui-btn-inner ui-btn-corner-all > <span class=” ui-btn-text “> 发送请求 </span > </ span></ div >

</ div>
</ div>

该方法返回数据只要是正确的json格式就可以;

 
<script>
       /*
       * 跨域异步post请求
       * arguments[0]请求的ID
       * arguments[1]请求php文件中的方法名
       * arguments[2]需要传输的POST键值对像
       */
       function xmlHttp()
       {
             var id    = arguments[0 ] ? arguments [0]: “0”;//真机环境下需要数字作为ID
             var func  = arguments [1] ? arguments[1 ]:“show”;
             var url     = “http://192.168.10.109/phpmyadmin/test.php?func=”  func ;//一定要加HTTP://
             uexXmlHttpMgr.open(id, “POST”, url,“” );
             if(arguments [2])
             {
                   var postKey = “”;
                   var postValue =“” ;
                   for(var key in arguments[2 ])
                   {
                         postKey = key ;
                         postValue = arguments [2][ key];
                         uexXmlHttpMgr.setPostData (id ,“0”, postKey,postValue );//post参数
                   }
             }
             uexXmlHttpMgr.send(id);
             //alert(“发送请求”)
       }
       /*
       * 查询
       */
       function httpSuccess (opid ,status ,result )
       {
             if(status == -1)
             {
                   //alert(“传输失败” )
             }
             if(status == 0)
             {
                   //alert(“正在传输”)
             }
             if(status == 1)
             {
                   //alert(“传输完成”)
                   uexXmlHttpMgr.close(opid);
                   var test = “<input type=”text” id=”content_add”>”
                                “<input type=”button” value=”添加” onclick=”insertItem()”>”;
                   var tmpl = “<div>”
                                “<input type=”text” id=”content_${index:}” value=”${content}”>”
                                “<input type=”button” value=”修改” onclick=”saveItem(${id},${index:})”>”
                                “<input type=”button” value=”删除” onclick=”deleteItem(${id},${id})”>”
                                “</div>”;         
                   var json = eval (result );
                  
                   test  = zy_tmpl (tmpl ,json ,zy_tmpl_count (json ));
                   $( “#content”).html(test);
             }
       }
       /*
       * 修改
       */
       function saveItem ()
       {
             var id = arguments [0];
             var input = $ (“#content_”  arguments[1 ]);
             var content =  input.val();
      
             xmlHttp(“1” ,“save”,{ “id”:id ,“content”: content})
       }
       /*
       * 添加
       */
       function insertItem ()
       {
             var input = $ (“#content_add”);
             var content = var  input.val();
             xmlHttp(“2” ,“insert”,{ “content”:var content })
       }
       /*
       * 删除
       */
       function deleteItem ()
       {
             var id = arguments [0];
             xmlHttp(“3” ,“delete”,{ “id”:id })
       }
       window.uexOnload = function()
       {
             uexXmlHttpMgr.onData = httpSuccess ;//请求数据成功后的回调函数
            
            
   }
</script>
<input class=”btn  type =”button value=” 开始 onclick=”xmlHttp() >
服务端PHP文件

<?php
$cfg_dbhost = “localhost”;
$cfg_dbname = “sitrust”;
$cfg_dbuser = “root”;
$cfg_dbpwd = “”;

$conn = mysql_connect($cfg_dbhost, $cfg_dbuser, $cfg_dbpwd) or die (“不能连接数据库服务器: ” . mysql_error());
mysql_select_db($cfg_dbname, $conn) or die (“不能选择数据库: ” . mysql_error());
mysql_query(“set names utf8”);
/*
**执行$_GET[“func”])传入的方法
*/
if(!empty($_GET[“func”]))
{
 $func = $_GET[“func”];
 $func();
}
/*
**查询
*/
function show()
{
 Global $conn;
 $sql = “select * from `test`”;
 $result = mysql_query($sql,$conn);
 while( $row = mysql_fetch_array($result) )
 {
  $content[] = $row;
 }
  //json数据返回客户端
  echo json_encode($content);
}
/*
**修改
*/
function save()
{
 Global $conn;
 $id = $_POST[“id”];
 $content = $_POST[“content”];
 $sql = “UPDATE `sitrust`.`test` SET `content` = “”.$content.”” WHERE `test`.`id` =”.$id;
 if(mysql_query($sql,$conn))
 { 
  show();
 }
 else
 {
  return false;
 }
}
/*
**删除
*/
function delete()
{
 Global $conn;
 $id = $_POST[“id”];
 $sql = “DELETE FROM `sitrust`.`test` WHERE `test`.`id` = “.$id;
 if(mysql_query($sql,$conn))
 { 
  show();
 }
 else
 {
  return false;
 }
}
/*
**添加
*/
function insert()
{
 Global $conn;
 $content = $_POST[“content”];
 $sql = “INSERT INTO `sitrust`.`test` (`content` ) VALUES (“”.$content.””);”;
 if(mysql_query($sql,$conn))
 { 
  show();
 }
 else
 {
  return false;
 }
}

 

SVN数据自动备份

上次星官神仙提到,用Windows 批处理文件可以实现备份。如何让计算机自己来做呢,下面介绍一下计算机里的任务计划,实现自动备份。

打开任务计划,在开始菜单->控制面板->任务计划->添加任务计划

单击浏览选项,把批处理文件加入里面。

我们要每天都要备份,选择每天,17:45分运行。

需要输入用户名和密码。

完成后将在任务计划里多出一条您刚增加的任务。

一切OK。感谢诸位神仙。

windows 批处理svn数据源远程备份

暂且使用windows备份机对svn服务器进行备份,

用到了bat文件,可以一次批量处理整个svn服务器数据源的备份工作。

bat文件代码如下:

: sync运行路径

@set localSvnBinPath=C:\Program Files\VisualSVN Server\bin

: svn数据源存放路径

@set localSvnPath=file:///F:/Repositories/

: svn用户名

@set serverSvnUser=svn用户名

: svn密码

@set serverSvnPassword=svn密码

: 数据源数组

@set svnRep=svn各数据源名(用半角空格分隔)

cd %localSvnBinPath%

: 循环删除各数据源SVN修订号0 svn:sync-lock的保护

@for %%r in (%svnRep%) do (

svn propdel svn:sync-lock –(两个减号)revprop -r 0 %localSvnPath%%%r

)

: 循环执行各数据源sync同步备份

@for %%r in (%svnRep%) do (

svnsync sync %localSvnPath%%%r –(两个减号)username %serverSvnUser% –(两个减号)password %serverSvnPassword%

)

@echo backup svn is completed!

@pause

svn远程备份

为了防止svn服务器崩溃等原因导致的数据丢失,

学习了一下使用svnsync进行svn远程备份。

1 搭建备份机环境

首先在备份机安装与服务器相同版本的VisualSVN-Server,

创建想要备份的svn数据源文件夹,

例如:与服务器端svn数据源相同的test,(file:///F:/Repositories/test)

之后在test\hooks文件夹下复制pre-revprop-change.tmpl ,

将其扩展名改为pre-revprop-change.bat,并将其内容清空,只留”exit 0″一行代码。

别忘记把服务器端所有用户也创建在备份机端的svnServer内。

2 初始化备份信息

在备份机DOS命令行下,cd c:\Program Files\VisualSVN Server\bin根目录下输入:

svnsync init file:///F:/Repositories/test  https://服务器ip:端口/svn/test

根据结果提示选择(P)ermanently,长期不变方式,

并根据提示输入备份机用户名,服务器svn用户名以及密码。

结果显示Copied properties for revision 0.则表示成功。

3 连接服务器进行备份

首次执行备份时需要删除SVN修订号0 svn:sync-lock的保护。

svn propdel svn:sync-lock –(两个减号)revprop -r 0  file:///F:/Repositories/test

之后就可以执行备份命令,来完成备份。

svnsync sync file:///F:/Repositories/test –(两个减号)username username –(两个减号)password password

123