Category Archives: 编程

How to: Implement Dynamic Route in CakePHP

I’ve found a method to implement Dynamic Route in CakePHP.
If we develop a CMS program using CakePHP, we often let people to define their menu code. The menu code basically is the URL path.
For example: An admin create a menu named ‘Milk Product’, and give this menu a code ‘product’.
He wish to access this menu [...]

Wordpress不能在别人评论后给我发送邮件的解决办法

这是一个非常诡异的问题.
遇到问题后, 我google了一下. 发现有些人遇到了和我类似的问题. 但是他们的问题原因仅仅是服务器不支持php的mail函数, 他们只需要安装wp mail smtp组件就可以发送了.
而我确定我的服务器支持mail函数.
我对于php还是新手, 还不知道怎么在windows上测试php的mail函数. 所以就只能在本地把文件改改, 然后上传到服务器上做发送邮件测试.
Wordpress调用的是PHPMailer组件发送邮件, 经过几个小时的调试之后, 我发现问题的原因在于2点:
1. PHPMailer的Sender属性为空. 这个属性为空将直接导致不会发送任何邮件.
2. PHPMail的MailSend方法中是这么调用mail函数的:
$rt = @mail($to, $this->EncodeHeader($this->SecureHeader($this->Subject)), $body, $header, $params);
我注意到如果把$this->EncodeHeader($this->SecureHeader($this->Subject))替换成固定的字符串, 并且将Sender属性设置为我的email地址, Wordpress就可以给我发送评论邮件了.
关于字符编码的问题我不是很懂, 大概看看这个EncodeHeader函数, 没看懂.
$this->Subject的内容是”[想当摄影师的程序员] Comment: “Symbian S60 V3系统不破解也能提升权限””
如果直接用var_dump($this->EncodeHeader($this->SecureHeader($this->Subject))), 会得到一串加了编码前缀的base64字符串. “=?utf-8?B?W+aDs+W9k+aRhOW9seW4iOeahOeoi+W6j+WRmF0gTmV3IENvbW1lbnQgT24=?= =?utf-8?B?OiBTeW1iaWFuIFM2MCBWM+ezu+e7n+S4jeegtOino+S5n+iDveaPkOWNhw==?= =?utf-8?B?5p2D6ZmQ?=”
bin2hex函数可以将任意内容转换成十六进制的字符串.
于是我调用了两次bin2hex方法.
var_dump(bin2hex($this->EncodeHeader($this->SecureHeader($this->Subject))))
var_dump(bin2hex(“=?utf-8?B?W+aDs+W9k+aRhOW9seW4iOeahOeoi+W6j+WRmF0gTmV3IENvbW1lbnQgT24=?= =?utf-8?B?OiBTeW1iaWFuIFM2MCBWM+ezu+e7n+S4jeegtOino+S5n+iDveaPkOWNhw==?= =?utf-8?B?5p2D6ZmQ?=”))
发现转出来的十六进制码竟然有差别.
3d3f7574662d383f423f572b6144732b57396b2b6152684f573973655734694f6561684f656f692b57366a2b57
526d463067546d563349454e766257316c626e51675432343d3f3d0a203d3f7574662d383f423f4f694254655
731696157467549464d324d4342574d2b657a752b65376e2b53346a656567744f696e6f2b53356e2b6944766
561506b4f574e68773d3d3f3d0a203d3f7574662d383f423f35703244365a6d513f3d
3d3f7574662d383f423f572b6144732b57396b2b6152684f573973655734694f6561684f656f692b57366a2b57
526d463067546d563349454e766257316c626e51675432343d3f3d203d3f7574662d383f423f4f694254655
731696157467549464d324d4342574d2b657a752b65376e2b53346a656567744f696e6f2b53356e2b6944766
561506b4f574e68773d3d3f3d203d3f7574662d383f423f35703244365a6d513f3d
你会看到第一个方法比第二个方法多出两个0a
不知道为什么.
为了不使用PHPMailer的EncodeHeader函数, 我调用了PHP自带的函数. 做了以下修改:
$subject = ‘=?UTF-8?B?’ . base64_encode($this->Subject) . ‘?=’;
$rt = @mail($to, $subject, $body, $header, $params);
这样我就可以收到邮件了.
关于刚才说的第一个问题, 我也不清楚是怎么回事.
干脆我就直接给Sender属性赋值好了. 将以下两句加到MailSend函数的开头.
$this->Sender = ‘这里填上自己的email地址’;

CakePHP报500错误的解决方法

我把CakePHP做的网站传到主机上, 发现只有首页能打开. 点其他链接都报500错误. 在看不到日志的情况下问题出现的可能性是多种多样的.
后来google一下, 发现有人遇到过类似的问题, 解决方法是换个主机…….
不信邪. 首页能打开就说明我的配置没错, CakePHP是能正常运行的. 可能问题出现在URL的Rewrite上, 于是我尝试使用/index.php?url=service (注: service是controller的名字)来打开, 可以打开. 更加证实了CakePHP是没问题的想法. 于是我就修改了.htaccess.
原来内容是
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
我改成
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} [...]

Javascript 排序问题

我们买了个web表格控件, 点击表头可以排序的, 对于英文没问题, 是按照英文字母顺序排的, 但是中文就乱了. 不按拼音顺序, 也不按笔画顺序.
后来在网上找了一下, 发现Javascript的sort方法对于中文是按照内码来排的.
如果想让其按拼音来排, 需要用localCompare
原始顺序是: 猪zhu-1,我wo-2,啊a-3,你ni-4,他ta-5,地di-6
Javascript本身的sort排序后是: 他ta-5,你ni-4,啊a-3,地di-6,我wo-2,猪zhu-1
按照拼音排序结果是: 啊a-3,地di-6,你ni-4,他ta-5,我wo-2,猪zhu-1
具体请看代码
HTML+Cheetah语言: Javascript 排序问题
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=“http://www.w3.org/1999/xhtml”>
<head>
<meta http-equiv=“Content-Type” content=“text/html; charset=utf-8″ />
<title>Sort Test</title>
</head>
<body>
<script type=“text/javascript”>
function mysort()
{
var s = “猪zhu-1,我wo-2,啊a-3,你ni-4,他ta-5,地di-6″;
alert(“The original is:\n” + s);
var a = s.split(“,”);
a.sort();
alert(“This is wrong:\n” + a);
a.sort(function(c1, c2)
{
return c1.localeCompare(c2);
});
alert(“This is right:\n” + a);
}
</script>
<input type=“button” value=“test” onclick=“mysort()” />
</body>
</html>

在BlueHost上安装Subversion

一开始是按照Bluehost论坛上的方法来安装, 但是发现无法支持http, https协议, 又按照半瓶墨水的方法来安装, 这次支持http协议了, 但是依然不支持https.
后来google了一下, 经过多次摸索, 终于安装成功, 下面分享经验.
cd ~
mkdir install
mkdir src
cd src
#下载
wget http://subversion.tigris.org/downloads/subversion-1.6.4.tar.gz
wget http://subversion.tigris.org/downloads/subversion-deps-1.6.4.tar.gz
wget http://www.openssl.org/source/openssl-0.9.8k.tar.gz
tar xzvf openssl-0.9.8k.tar.gz
tar xzvf subversion-deps-1.6.4.tar.gz
mv subversion-1.6.4 deps
tar xzvf subversion-1.6.4.tar.gz
#编译OpenSSL
cd openssl-0.9.8k
./config –prefix=$HOME/install/openssl
make
make install
cd ..
cd deps
#编译apr
cd apr
./configure –prefix=$HOME/install/apr LDFLAGS=”-L/lib64″
make
make install
cd ..
#编译apr-util
cd apr-util
./configure –prefix=$HOME/install/apr-util –with-apr=$HOME/install/apr LDFLAGS=”-L/lib64″
make
make install
cd ..
#编译serf
cd serf
./configure –prefix=$HOME/install/serf –with-apr=$HOME/install/apr –with-apr-util=$HOME/install/apr-util –with-openssl=$HOME/install/openssl LDFLAGS=”-L/lib64″
make
make install
cd ..
#编译zlib
cd zlib
./configure –prefix=$HOME/install/zlib
make
make install
cd ..
#编译neon, subversion是否支持https就看这个组件编译的时候是否支持ssl了, 编译完成后, 你会看到一个summary, [...]

封装YUI Table

以前做Research的时候用C#把YUI的Table封装了起来.
这里是代码, 仅供参考.

Html里的标签<button>

大家一般写按钮, 都会写<input type=”button” value=”按钮文字” />
但是还有一个标签可以用就是<button></button>, 两者功能一样, 但是button的功能更丰富
这个标签里面允许定义其他html标签作为按钮文字
例如:
<button><img src=”some.gif” /></button>
<button><strong>这是加粗的文字</strong></button>
<button>是标准的html元素, 可以放心使用
但是<button>也有麻烦的地方, 就是用button提交form的时候不会触发form的onsubmit事件.
Button的问题, 请参考深入理解 __doPostBack

页面中同时存在VBScript和Javascript时请注意

当一个页面里面同事存在Javascript和VBScript的时候,我们的页面可能会发生错误,错位位置在
<body
oncontextmenu=”return false;”
onkeydown=”parPage.KeyControl(event)”
onhelp=”parPage.goHelp(event)”
bottomMargin=”2″
leftMargin=”2″ topMargin=”2″ rightMargin=”2″>
此时,当触发了oncontextmenu事件后,浏览器不知道这个return false语句到底用什么引擎来解析,所以就会出现找不到对象或者类似的莫明其妙的错误.解决办法是在事件处理前,加上语言名称前缀:javascript:return false;
<body
oncontextmenu=”javascript:return false;”
onkeydown=”javascript:parPage.KeyControl(event)”
onhelp=”javascript:parPage.goHelp(event)”
bottomMargin=”2″ leftMargin=”2″ topMargin=”2″ rightMargin=”2″>
这样就不会出来那种无聊的错误了.
有人说写上这句就默认为javascript了,好像这句话不起作用
<meta name=”vs_defaultClientScript” content=”JavaScript”>

jQuery基础

0. jQuery基础
jQuery是一个轻量级的javascript类库, 只有14k(未压缩的版本有77k)
jQuery有什么好处呢?
我想好处有以下几点:
1. 简化了html对象的操作, 起码写的字少了, 而且原来需要自己写循环做的, 现在一句话就搞定
2. 提高了代码的浏览器兼容性. 现在的4种主流浏览器之间的js脚本或多或少都会存在兼容性问题, 用jQuery, 会让你不用关心兼容性.
比如Ajax请求, ie和firefox的对象完全不一样
还有box模型的问题, 比如一个div外面加了一个边框, 然后为这个div设定一个宽度, ie和firefox对这个div的实际宽度理解的就不一样. ie会认为div的实际宽度是div的宽度+边框宽度, 而firefox认为div的实际宽度就是你设定的宽度, 不过div的有效宽度就是div的宽度-边框宽度了, 这个问题会影响一个元素的实际位置. 所以一定要用jquery的offset方法来取元素的位置, 用width来取宽度
所有的jQuery选择器返回值都是jQuery对象, 而不是html元素. 所以一些普通的用法, 比如InnerHTML都是无效的.
更多更详细的参考请访问http://docs.jquery.com/Main_Page
别人写的基础教程 http://bbs.jquery.org.cn/frame.php?frameon=yes&referer=http%3A//bbs.jquery.org.cn/viewthread.php%3Ftid%3D129%26highlight%3D
1. 选取元素
$(“#myid”)效果等于document.getElementById(“myid”), 但是写的字符要少好多啊.
如果需要将jQuery对象转换成html元素, 则只需要取其第0个元素即可. 例如$(“#myid”)返回的是jQuery对象, 而$(“#myid”)[0]返回的就是html元素
如果选择所有的img元素, 那么这么写: $(“img”)
如果选择带有class=”TextBox”的div元素(<div class=”TextBox”></div>), 那么这么写: $(“div.TextBox”)
选择带有myattr属性的元素$(“div[myattr]“)
选择带有myattr属性, 并且属性值等于myclass的元素$(“div[myattr='myclass']“)
属性不等于[myattr!='myclass']
属性以my开头[myattr^='my']
属性以class结尾[myattr$='class']
属性包含cla这三个字符[myattr*='cla']
如果一个选择会返回多个元素, 并且希望每返回一个元素, 就把某些属性应用到该元素上, 可以这么写
$(“div”).each(function()
{
$(this).css(“background-color”, “#F00″);
alert($(this).html());
$(this).width(“200px”);
});
2.事件
给页面加onload事件处理方法
$(function()
{
alert(“页面结构加载完毕, 但是可能某些图片尚未加载(一般情况下, 此事件就够用了)”);
});
可以给页面绑定多个onload事件处理方法
$(function()
{
alert(“我首先被执行”);
});
$(function()
{
alert(“我第二被执行”);
});
绑定特殊事件
$(“#myid”).keydown(function()
{
alert(“触发了keydown事件”);
});
除了这些常用的, 不常用的事件需要通过bind方法绑定
3. 元素属性/方法
得到一个元素的高度, $(“#myid”).height()
得到一个元素的位置, $(“#myid”).offset() 返回的是一个offset对象, 如果取元素位置的top, 则$(“#myid”).offset().top,?取left则$(“#myid”).offset().left
得到一个元素的innerHTML, $(“#myid”).html()
得到一个元素的innerText, $(“#myid”).text()
得到一个文本框的值, $(“#myid”).val()
得到一个元素的属性, $(“#myid”).attr(“myattribute”)
以上这些方法有个基本特征, 就是不带参数表示取值, 带有参数表示设定值(除了offset), [...]

水晶报表Bug之无法打印

公司产品用到了水晶报表, 产品用Install Shield做的安装包, 安装包里的水晶报表用MergeModule来安装, 这样客户只要安装我们的产品就可以了, 不用单独安装Crystal Report程序.
但是有些测试人员发现, 他们测试机上的水晶报表无法打印, 一按打印按钮, 就报Javascript错误.
后来慢慢查了一下他的Js脚本, 发现最终错误在export.js里的document.dlgform.action = opener.document.getElementById(\”crystal_handler_page\”).value;
因为页面上没有crystal_handler_page, 所以这里会出错.
google了一下, 没发现有价值的资料, 只有一个俄罗斯论坛上有人问过这个问题, 别人的回答是因为什么Adobe字体的问题. 但我们的问题是, 有些人的测试机上是好的, 有些人的测试机是不能打印的. 我感觉不是什么字体问题.
今天早上找了台不出错的测试机, 看看crystal_handler_page里面的值是什么, 结果发现就是opener的地址. 晕, 这么复杂干嘛? 不如直接取opener.location.href了.
我就把这句话改为document.dlgform.action = opener.location.href;
问题解决.
后来发现, 这可能是那个MergeModule的问题, 新安装的MergeModule已经修复了这个问题.