ThinkPHP模板图片的路径设置

Aside

我们知道在ThinkPHP中程序和模板是分开的。
如何设置模板中包含的图片,模板的路径,可以显示正确,同时在用dreamwave等开发工具中可以离线查看呢?
原来我们是用ThinkPHP的__PUBLIC__这个变量来指示到根目录的public路径下,这样方面了程序,但是美工麻烦了,dreamwave看不到图片。也用不了dreamwave cs4中可以快捷的跳转到包含的js脚本或css文件的功能。
官方网站上也找不到例子和解决的办法。
今天偶然试了一下,可以解决:
把图片,脚本,css等文件放到tpl模板目录下,和模板文件平级。如下图:

ThinkPHP目录部署

ThinkPHP目录部署

在模板中采用如下地址如:

home为项目的文件夹,如果你是其他项目,可以改名字。
在dreamwaver等支持文件跟踪的IDE中可以看到效果了,如下:

dreamwave效果

dreamwave效果

CSS设置PNG图片透明引起IE6卡死

最近有反应发现新站点IE6下莫名卡死,但是卡死的状态不是很明显。似乎是偶尔。只有在每次打开IE6前先清空起缓存(工具->intenet选项->浏览历史)然后再打开页面,则可以看到明显的卡死现象。

然后是逐步分析。发现有如下风骚CSS。删除之,卡死现象消失。

<span class=”msn” style=”_filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=’msn.png’ ,sizingMethod=’crop’);“></span>

需要说明的是:_filter这是网上流行的IE6支持PNG图片透明的写法。但是,本来IE6就是不支持PNG透明的,如果硬要来,虽然是有HACK,但是应谨慎使用。因为就像本例,卡死的现象,一般开发的可能是感觉不到(现在开发的都好少用IE6了,只是调试浏览器兼容的时候随便点点,而有缓存时不会出现卡死情况),但是普通用户,如果是IE6进来的,浏览时候感觉可能就很不好了,第一次进你网站卡死,可能就直接关掉了。

excel中用VBA解决梯度计算提成

任务描述:计算工资提成,要求按梯度计算。比如到达一个梯度按一定比例算提成。有点类似公积金计算方法。
本来我是想用公式解决的。但是:1,想不出快捷计算扣除数。2,那个梯度是动态的,不同的时节梯度又不一样。so~~
而且要求不要列出每个等级数据。把最后结果列出来就行了。
倒啊,真把我当万能的了,好吧那我就是万能的,哈利路亚,荣耀归主。
完成效果如下图:红色框部分为可以自定义的。

excel提成计算

宏代码如下,写得也许有点繁琐,但是比较急,而且VBA不熟悉。so~~。大家可以精简一下。我是没有发现在VBA里怎么调用有返回值的函数(貌似return不能用,囧)。然后写了X个if。

Sub setValue()
' 快捷键: Ctrl+e
Count = Worksheets("Sheet1").Range("B1").Value - Worksheets("Sheet1").Range("B2").Value
grade1 = Worksheets("Sheet1").Range("B3").Value
bete1 = Worksheets("Sheet1").Range("c3").Value
If (Count &gt; grade1) Then
count1 = grade1 * bete1
grade2 = Worksheets("Sheet1").Range("B4").Value
bete2 = Worksheets("Sheet1").Range("C4").Value
Count = Count - grade1
If (Count &gt; grade2) Then
count2 = grade2 * bete2
grade3 = Worksheets("Sheet1").Range("B5").Value
bete3 = Worksheets("Sheet1").Range("C5").Value
Count = Count - grade2
If (Count &gt; grade3) Then
count3 = grade3 * bete3
Count = Count - grade3
grade4 = Worksheets("Sheet1").Range("B6").Value
bete4 = Worksheets("Sheet1").Range("C6").Value
Total = count1 + count2 + count3 + Count * bete4
Else
count3 = Count * bete3
Total = count1 + count2 + count3
End If
Else
count2 = Count * bete2
Total = count1 + count2
End If
Else
Total = Count * bete1
End If

Range("A9:I100").Select
Range("A9").Select
ActiveCell.Formula = Total
Range("A9").Select
Selection.AutoFill Destination:=Range("A9:A100"), Type:=xlFillDefault
Range("A9:A100").Select

Range("d9").Select
ActiveCell.FormulaR1C1 = "=RC[-1]*RC[-3]"
Range("d9").Select
Selection.AutoFill Destination:=Range("d9:d100"), Type:=xlFillDefault

End Sub

thinkphp模板标签:if和eq的区别和比较

在TP模板语言中。if和eq都可以用于变量的比较。总结以下几点:

1.两个变量的比较:

<if condition=”$item.group_id eq $one.group_id”>
<eq name=”item.group_id” value=”$one.group_id”>

前者的IF是判断失败的,用后者的<neq>(或<eq>)则OK。需要注意:name那里是不用加$变量符号的,而value那里要加$变量符号。


2.还有值为空(null)的时候:

<if condition=”name neq ‘NULL’”>just a test</if>
<neq name=”name” velue=”">just a test</neq>

前者的IF是判断失败的,用后者的<neq>(或<eq>)则可以识别null为”"

3.多维数组且下标为0的时候:

<if condition=”name.0 neq ‘test’”>just a test</if>
<eq name=”name.0″ velue=”test”>just a test</eq>
前者用IF是根本不能通过编译的,用后面的eq就可以

ThinkPHP-系统发生错误-解决

ThinkPHP的错误提示真是不够友好。直接显示:

系统发生错误

您可以选择 [ 重试 ] [ 返回 ] 或者 [ 回到首页 ]

[ 错误信息 ]

您浏览的页面暂时发生了错误!请稍后再试~

让人无语。不过这一般都是在控制器中出的问题。可以这样检查一下:

检查控制器。看看能进到控制器没有,设断点输出一下。如果没有进入方法。可以在构造函数__construct()中设断点。

var_dump(C())把配置打印出来看看,有很多时候,是数据库参数设置错,连不上。

记得清空一下Runtime缓存文件夹再重试。

检查控制器名字,路径对了没有?

其他问题参考:

ThinkPHP开发常见问题Q&A

解决DWZ文件上传表单提交

因为Ajax不支持enctype=”multipart/form-data” 所以用隐藏iframe来处理无刷新表单提交。

比如:在a.html中,用<iframe src=”b.html” style=”width:750px; border: 0px;”></iframe>

而b.html中,用非AJAX的表单提交。如下:

<form method=”post” action=”url” enctype=”multipart/form-data” >

……

</form>

至此,问题解决。

解决开启apache的rewrite重写功能

给同事重新配置环境,记录过程。
1.开启rewrite模块的调用
Apache 2.x 中URL重写,是通过mod_rewrite.so 来实现的,在 httpd.conf 中,我们会发现类似如下的一行,是有关rewrite模块的,模块名是 mod_rewrite.so 。开启它。
2.设置AllowOverride(注意这里,原来我就是这个设为none,即使apache显示rewrite模块开启了,但是重写还是用不了)在 httpd.conf 中,我们会看到比如:
<Directory “/opt/www”>
Options FollowSymLinks
#AllowOverride None 注:把这行前面加#号,然后加下面的一行  ,也就是   AllowOverride ALL
AllowOverride ALL
Order allow,deny
Allow from all
</Directory>
如果AllowOverride指令被设置为None ,那么.htaccess文件将被完全忽略。事实上,服务器根本不会读取.htaccess文件。当此指令设置为 All时,所有具有”.htaccess”作用域的指令都允许出现在.htaccess文件中。
3.重启httpd服务器

解决开启apache的URL重写功能
1.开启rewrite模块的调用Apache 2.x 中URL重写,是通过mod_rewrite.so 来实现的,在 httpd.conf 中,我们会发现类似如下的一行,是有关rewrite模块的,模块名是 mod_rewrite.so 。开启它。
2.设置DocumentRoot的Directory(注意这里,原来我就是这个设为none,即使apache显示rewrite模块开启了,但是重写还是用不了)在 httpd.conf 中,我们会看到比如:<Directory “/opt/www”>Options FollowSymLinks#AllowOverride None 注:把这行前面加#号,然后加下面的一行  ,也就是   AllowOverride ALL AllowOverride ALL    Order allow,denyAllow from all</Directory>
如果AllowOverride指令被设置为None ,那么.htaccess文件将被完全忽略。事实上,服务器根本不会读取.htaccess文件。当此指令设置为 All时,所有具有”.htaccess”作用域的指令都允许出现在.htaccess文件中。

3.重启httpd服务器

SVN 服务器端简要配置步骤和常见问题解决

又重新配了一次SVN服务器,我把过程和遇到的错误及解决办法记录下来。

过程简化为6步:

  1. 安装Subversion:我装的是Setup-Subversion-1.6.4.msi
  2. 建立版本库:开始->运行->cmd->进入SVN服务端的安装目录下面的bin目录,试用create命令建立版本库,如: svnadmin create E:\svn\doc
  3. 开启服务: svnserve.exe –daemon –root E:\svn\doc svnserve 将会在端口 3690 等待请求 –daemon(两个短横线)选项告诉 svnserve 以守护进程方式运行,这样在手动终止之前不会退出。注意不要关闭命令行窗口,关闭窗口会把 svnserve 停止。 –root设置根目录,也可不用这个命令可以存在一个批处理文件中,设置为计划任务,每次开机启动,这样就启动服务了。或者使用windows服务注册,这里不说明,自己找资料。
  4. 设置密码和权限:(1)打开E:\svn\doc\conf下的svnserve.conf,把#password-db = passwd前的#去掉,注意不要留空格,否则会报错;如果默认所有帐户都具有全部权限,则不要把#authz-db = authz前的#去掉,否则要进入E:\svn\doc\conf下的authz文件为每个帐户设定权限。(2)进入E:\svn\doc\conf下的passwd文件,在[users]下增加sally=sallypsw,则为用户sally创建了密码sallypsw。
  5. 安装TortoiseSVN客户端软件:当然不装也行,但是TSVN是图形化软件,可视化和可操作性都大大简化。我装的是TortoiseSVN-1.6.8.19260-win32-svn-1.6.11.msi + LanguagePack_1.6.8.19260-win32-zh_CN.msi,后面是语言包,可装可不装。安装了语言包后,还要在设置->语言那里选择中文,才可用。
  6. 导入:使用TSVN在服务器上或在客户端为版本库导入文件/文件夹

一些常见错误及解决:

  1. Q:出现”svnserve.conf:12: Option expected”错误 A:打开svnserve.conf文件中的第12行,该错误是由于该行的前面有空格引起的,把左边多出的空格删除掉即可;
  2. Q:输入URL(svn://127.0.0.1/SVN_PRJ)点下一步出现”svn://127.0.0.1/SVN_PRJ non-existent in revision ’7′”错误 A:URL错了,应该输入svn://127.0.0.1即可
  3. Q:svn 璁よ瘉澶辫触 A:上如果出现此错误,此错误是“认证失败”,有两种解决方式,一个是把Author这个配置文件写好,另一个是把svnserve.conf文件中的#authz-db = authz这个去掉,这个注释掉的意思是不再去读取AUTHOR文件里的信息

使用bat批处理做ftp自动下载

不是因为懒,不想每天从手动从服务器更新数据下来。确实是要提高效率。想找一个自动ftp下载的工具,找了很多,BatchSync FTP很好用,但是始终找不到破解版。后来和小熊同学一起配合下,终于把批处理的ftp下载搞定了,小巧绿色环保原生态,下面分享一下使用bat批处理做ftp自动下载的方法。

新建一个bat,随便名字如download.bat,敲入如下代码:

set ymd=%date:~0,10%

md “C:\backup\%ymd%”

cd C:\backup\%ymd%

@echo off

echo open 127.0.0.1>ftp.src

echo username>>ftp.src

echo password>>ftp.src

echo cd “/%ymd%/”>>ftp.src

echo prompt n>>ftp.src

echo type binary>>ftp.src

echo runique y>>ftp.src

echo mget *>>ftp.src

echo bye>>ftp.src

ftp -s:ftp.src

del ftp.src

解释:

红色部分用真实的ftp地址,用户名,密码代替。代码解释:

  1. 首先在本地新建一个以当天日期为名的文件夹
  2. 然后生成一个ftp.src的临时文件,这个文件有ftp操作的步骤,注意,要用另外一个文件存储ftp命令(FTP命令详解)。
  3. 使用ftp.src文件链接ftp服务器,开始下载
  4. 下载完成,删除临时文件ftp.src

还有几点需要注意的是,为什么要生成临时文件又删除?其实做成单独的文件也可以,但是这个ftp脚本限制了下载的文件只能存储在当前批处理脚本的路径下,而我希望按每天的日期来分别下载。而ftp命令中并不支持诸如%date:~0,10%这样的环境变量。所以这里就耍了一个小聪明。每天生成当天文件夹和当天脚本->下载好文件->删除脚本。如果你不用日期分割,可以把echo部分抽出来写一个文件。

ICBC工行1.0.0.3支付接口,php开发

搞了很久,终于,在今天下班之后,工行技术工程师联系电话过来。好消息,有新进展了,自愿被迫加班1个小时,终于搞定了ICBC1.0.0.3接口的成功DEMO。

下面做分享和开发说明:

1.安装环境,接口开发要用到两个动态库文件,安装好,方法见:Php 使用 动态链接库的方法

2.把ICBC提供的两个公钥文件,一个私钥文件,放到固定一个目录(建议安全起见,在web目录以外)。记着是共3个文件,原来ICBC只给我一个公钥,一个私钥,可以支付,但是返回数据总是验证出错(囧)。

3.此demo包括两个文件:SendToBank.php,这是发送数据到银行网关的页面和ReceiveFromBank.php接受返回数据并做检查的页面

3.SendToBank.php代码:

<?php
date_default_timezone_set(‘Asia/Shanghai’);//时区设置对的话这句可以不要,因为ICBC银行服务器端要对交易时间要求,超过当前时间一小时的予以交易的
?>
<html>
<head>
<title>sendtobank</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>
</head>
<body>
点击按钮测试
<p>
<?php
//接口名称
$interfaceName=”ICBC_PERBANK_B2C”;
//接口版本号
$interfaceVersion=”1.0.0.3″;
//订单号
$orderid=’111222333′.rand(111,999);
//订单金额
$amount=’1′;
//支付币种
$curType=”001″;
//商户代码
$merID=”2103*****88888″;
//商城账号
$merAcct=”210320611******88888″;
//检验联名标志
$verifyJoinFlag=”0″;
//通知类型
$notifyType=”HS”;
//接收通知地址,就是验证返回数据的页面
$merURL=”http://www.youdomain.com/ReceiveFromBank.php”;
//结果发送类型
$resultType=”0″;
//交易日期时间
$orderDate = date(‘YmdHis’);
//加密字符串明文形式
$src = ‘<?xml version=”1.0″ encoding=”GBK” standalone=”no”?>’;
$src .= ‘<B2CReq>’;
$src .= “<interfaceName>{$interfaceName}</interfaceName>”;
$src .= “<interfaceVersion>{$interfaceVersion}</interfaceVersion>”;
$src .= “<orderInfo>”;
$src .= “<orderDate>{$orderDate}</orderDate>”;
$src .= “<orderid>{$orderid}</orderid>”;
$src .= “<amount>{$amount}</amount>”;
$src .= “<curType>{$curType}</curType>”;
$src .= “<merID>{$merID}</merID>”;
$src .= “<merAcct>{$merAcct}</merAcct>”;
$src .= “</orderInfo>”;
$src .= “<custom>”;
$src .= “<verifyJoinFlag>{$verifyJoinFlag}</verifyJoinFlag>”;
$src .= “<Language></Language>”;
$src .= “</custom>”;
$src .= “<message>”;
$src .= “<goodsID></goodsID>”;
$src .= “<goodsName></goodsName>”;
$src .= “<goodsNum></goodsNum>”;
$src .= “<carriageAmt></carriageAmt>”;
$src .= “<merHint></merHint>”;
$src .= “<remark1></remark1>”;
$src .= “<remark2></remark2>”;
$src .= “<merURL>{$merURL}</merURL>”;
$src .= “<merVAR></merVAR>”;
$src .= “</message>”;
$src .= “</B2CReq>”;
echo($src);
//创建对象
$bb = new COM(“ICBCEBANKUTIL.B2CUtil”);
//进行初始化,第一个参数是ICBC的公钥,第二个参数是你自己的公钥,第三个参数是你的私钥,第四个参数是密码
$bb->init(“D:\icbc\admin.crt”,”D:\icbc\my.crt”,”D:\icbc\my.key”,”88888″);
//交易数据,要进行base64编码
$trandata = base64_encode($src);
//订单签名数据merSignMsg的值
$ssrc = $bb->signC($src,strlen($src));
//获取商城证书公钥merCert的值
$cert=$bb->getCert(1);
?>
</p>
<form name=”sendOrder” method=”post” action=”https://mybank.icbc.com.cn/servlet/ICBCINBSEBusinessServlet”>
<input type=”hidden” name=”interfaceName” value=”<?php echo($interfaceName);?>”>
<input type=”hidden” name=”interfaceVersion” value=”<?php echo($interfaceVersion);?>”>
<input type=”hidden” name=”tranData” value=”<?php echo($trandata);?>” >
<input type=”hidden” name=”merSignMsg” value=”<?php echo($ssrc);?>” >
<input type=”hidden” name=”merCert” value=”<?php echo($cert);?>” >
<input type=”submit” value=”sumbit”>
</form>
</body>
</html>
4.ReceiveFromBank.php,代码:
<?php
$bb = new COM(“ICBCEBANKUTIL.B2CUtil”);
//进行初始化,第一个参数是ICBC的公钥,第二个参数是你自己的公钥,第三个参数是你的私钥,第四个参数是密码
$bb->init(“D:\icbc\admin.crt”,”D:\icbc\my.crt”,”D:\icbc\my.key”,”88888″);
if(count($_POST)>0){
//base64解码
$trandata = base64_decode($_POST['notifyData']);
$signMsg = $_POST["signMsg"];
$rc=$bb->verifySignC($trandata,strlen($trandata),$signMsg,strlen($signMsg));
if($rc==0){
echo ‘支付成功了!’;
//为了安全,这里还应该对返回的支付金额和本地数据进行比对,这里使用php的xml对象进行解析
$xmlparser = xml_parser_create();
//把返回的xml字串存入$myxml数组中
xml_parse_into_struct($xmlparser,$trandata,$myxml);
$amount = $myxml[6]["value"];//订单金额,可以通过打印数组查看其他的参数下标
//以下是数据比对,不赘述…
}else{
echo(“支付失败,错误代码:{$rc}”);
}
}
?>
5.整理此文档,也是对自己这段时间在ICBC挣扎的一个总结,开始以为做支付接口开发,和提供商沟通好,看清文档就行。包括以前开发过的环讯支付和正在进行的支付宝,不得不说,IPS和Alipay的大家风范,文档和DOMO都准备得很完善。只有这个ICBC,包括他们自己技术工程师都说,他们这样提供face to face 的技术支持是别的行没有的,包括ICBC的其他行,也是丢一个文档给你自己做,demo?那是某的。所以我想,这还是有一些必要的,何况现在网上可以search得到的,很多是1.0.0.0的不可以跳转回商户网站的版本。
6.最后还是要感谢ICBC的一系列技术工程师,特别是YL。很多时候在早晨不到9点在我挤公车上班的时候,在中午1点午餐刚结束要休息的时候,在下午6点过了下班时间准备闪人的时候,还有周末在家的时候。都能接到ICBC询问开发进度的电话,我不得不对对银行工作有了更新更敬佩的认识。
7.路漫漫其修远兮,吾将上下而coding… 更多精彩请关注:liufangfang.netwww.guilincits.com