生活仍在继续

被和谐差不多两个月了, 电脑坏掉了加上最近工作比较忙, 所以这么久才把新域名弄好, 赶紧写点什么, 证明我还建在。

10月末被和谐的, 原因嘛, 不说了, 怪郁闷的, 说点实话比啥都难。 以前被和谐几次换个ip就ok了, 没想到这次换啥都不灵了, 只能把米换了,这次有机记性了, 以后敏感话题一律都不对外发表。

六月份买的电脑莫名其妙总死机, 折腾几个月了, 也没修出什么名堂, 拿维修站检测说死也不死机, 拿回来不到10分钟就死的一塌糊涂, 后来更过分, 只在windows下死再ubuntu下一切正常, 后来没辙把电脑搬单位去了, 最近忙也没时间研究, 只能先放着, 过年家里没人免得丢了。

最近两个月够忙活的, 11月初赶上上个项目结束, 日本老板来国内, 那个压力呀, 天天忙活, 天天赶进度还加班。 11月末去了趟北京, 逛了4天感触颇深, 北京也不过如此, 现在这个情况让我挺犹豫的, 我所看到的再加上最近经济不景气各大公司大量裁员造成的就业压力, 合同马上到期了我正考虑明年是不是出去发展, 其实很多东西还是让我挺留恋的。

从北京回来公司开始用symfony做新项目, 最近一个月学到了不少东西, 作为世界顶尖的开发框架, 果然非同凡响, 项目质量和效率都直线上升, 估计把symfony吃透得用个一年左右, 吃透这个最少也能折腾个三五年, 作为一个php开发人员, 对于php和symfony的前景, 我还是相当有信心的。

最近和两个同事一起转移到ubuntu阵营了, 这次都做的比较绝, 彻底干掉了windows, 半个多月下来, 感觉还是挺好的, 除了不能用支付宝, 其他一切ok, 工作效率上的提升的确是可以看到的, 所以以后会一直坚持下去, 向更深层次发展。

电脑坏了之后晚上就没有什么用电脑的机会了, 所以最近休息的不错, 白天也不怎么困了, 晚上回去看看电视, 打打扑克, 锻炼锻炼身体就到睡觉点了。 仔细算一算, 除了上网查资料和再淘宝买东西, 有快五十天没在网上露过面了, 最近项目收尾, 工作比较琐碎, 今天上了会儿QQ, 真的是好久不见了, 真没想到会又这么多朋友和我打招呼, 以前天天挂着都是不说话的, 寒暄上两句真让我挺感动的。

再过两天就元旦了, 又是新的一年, 一转眼工作一年多了, 真不可思议, 昨天买了元旦的火车票, 3个月没回家了, 回去看看爸妈。

url重写后的路径问题

以前用FleaPHP的url_rewrite模式一直有一个很头痛的问题, 就是页面上相关资源的路径问题.

问题大概是这样的, 为了让url更加友好我们使用apache的mod_rewrite将类似

http://localhost/?controller=default&action=index&a=1

这样的路径重写成

http://localhost/default/index/a/1

或者

http://localhost/default/index/a/1.html

这样, 但是如果是这样那么浏览器请求页面相关资源的基地址就发生了改变, 从原来的documentroot下变成了documentroot/default/index/a, 如果你要在页面上显示一个图片 1.jpg, 那么原来本来应该在documentroot/1.jpg下找到的文件却变成了documentroot/default/index/a/1.jpg, 那结果肯定是找不到的.

为了解决这个问题以前用过很多方法, 用的最多的就是使用绝对路径来解决这个问题, 这是有一个前提的, 就是程序一定要放在虚拟机的根目录下, 这样在html中要将所有的资源都是用/开头, /的意思是从根目录下开始寻找, 在localhost下的任何一个程序在任何目录中使用/1.jpg都会被指向documentroot/1.jpg, 这里再强调一个概念, “./“是当前目录, “../“是上级目录, “/“是根目录.

上面这个方法实际上已经可以解决这个问题了, 但是有局限, 就是程序的目录是固定的, 一定要在虚拟机根目录下, 这样或多或少会带来一些麻烦, 至少我觉得调试不方便. 于是又有了第二个解决方案, 也就是上面方案的升级版. 我们在全局定义一个常量 define('PRE_DIR', '/'); 这样的话要将程序中所有的资源路径都写成类似 dir/filename.jpg, 这样的话资源会被定为到 /dir/filename.jpg, 如果要将程序放在二级目录 test/下的话, 只要将PRE_DIR的值改成'/test/'就可以了.

其实在这之后又有了升级版, 但是不打算介绍太多, 因为这不是重点, 在手动改目录之后大家就想到要程序自动检测当前目录, 这个以前有做过, 是个不错的想法, 代码不少, 但是找不到了.

还有个东西我觉得比较神奇的, smarty有一个自动替换的插件, 可以自动在所有模板的资源链接前面加前缀, 当然前提是你已经定义了这个前缀, 插件名不记得了, 太久不用找不到了.

还是说重点吧, 昨天bobhero给我提供了一个新的思路, 利用mod_rewrite重新对资源进行定向, 后来到网上找相关的资料, 没有找到, 只找到了一些mod_rewrite的教程什么的. 研究了一下午也没研究出来, 因为url太复杂了, 很多情况都要考虑进去, 正则说什么就写不明白了, 今天早上终于搞定了.

1
2
3
4
5
6
7
8
9
#.htaccess

RewriteEngine on

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^.]*)(\.html)?$ index.php/$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]*)/(.*\..*)$ $2

起作用的其实就这些东西,  可能还会有错误, 不过的确生效了.简单解释一下, RewriteCond %{REQUEST_FILENAME} !-f是条件语句, 意思是说如果请求的文件不存在下面的规则才生效. 第一条规则RewriteRule ^([^.]*)(.html)?$ index.php/$1 [L]是FLEAPHP的重写规则.

下面两条才是为了解决路径问题的, RewriteRule ^([^/]*)/(...)$ $2的作用大概是这样, 比如url是这样controller/action/page/1,那么该页的style/css.css可能变成了controller/action/page/style/css.css, 这条语句就是要将controller/action/page/style/css.css指向action/page/style/css.css, 而由于某种机制请求每更换一次目录就会再执行一次根目录下的.htaccess中的重写规则, 由于action/page/style/css.css也不存在所以又被定向到page/style/css.css, 同理page/style/css.css也不存在, 再向上 style/css.css, 由于文件存在而不再执行重写规则, 向用户返回style/css.css的内容.

总的来说最后的这个方法除了apache受点累还是很完美的, 这样大概可能每个资源请求都会被重定向4次以上, 目前还不清楚对执行效率有多大的影响.

参考资料:

竹笋炒肉:Apache的Mod_rewrite学习

使用PHP收发邮件

这两天都在测试邮件, 搞得头都大了, 现在技术问题都已经解决了, 记录一下.

发送邮件一直都是一个难题, 以前没用过mail函数, 因为多数的环境下都不支持, 曾经改写过Discuz的邮件类, 也用过像PHPMailer这样的邮件发送库来解决邮件发送的问题, 但实际上用的都是SMTP. 昨天bobhero在公司内网服务器上配置了sendmail, 简单配置了之后可以使用smtp, imap和pop3. 但按照网上的教程配置了之后php的mail()函数一直都无法发送邮件, 在搜索引擎上寻找很久没有结果, 最后bobhero重新编译了配置文件, 终于成功.

编译命令

make -C /etc/mail

收邮件要比发邮件复杂的多, 网上资源巨少, 好不容易有几篇英文的帖子和我情况类似也没有解决办法.

接受邮件使用php的imap库, 遇到的问题主要在imap_open()上

连接163使用

imap_open("{pop3.163.com:110/pop3}INBOX", $username, $password);

取得的7bit数据使用imap_qprint()解码.

连接gmail使用

imap_open("imap.gmail.com:993/imap/ssl", $username, $password);

最难弄的就是连接本地的imap服务器, Outlook是可以从服务器上收取邮件的, 但是php就是收不到并返回错误Certificate failure for 102.com: Self-signed certificate or untrusted authority: OU=IMAP server, CN=imap.example.com, E=postmaster@example.com, 使用telnet链接也没有问题, 从昨天下午研究到今天中午也没解决这个错误, 网上搜不到解决办法, 最后实在没办法了, 用IP Sniffer截php.exe的数据包, 然后用telnet进行模拟, 发现php.exe在和imap服务器链接成功之后使用了TLS(一个什么传输安全协议), 刚想放弃就在php.net上看到原来imap_open()还有一个参数是/notls, 我的天, 终于得救了.

imap_open("{localhost:143/imap/notls}INBOX", $username, $password);

研究期间发现telnet很好玩, 可以用telnet检查某项服务是否开启, 比如smtp, telnet 192.168.1.102 25, 如果服务是开启的就会建立一个连接, 可以用指令进行smtp 的相关操作, 而指令内容也就是smtp协议的相关内容, 其他协议pop, imap等等都可以这么玩.

相关端口:

smtp 协议 25端口

imap 协议 143端口

imap/ssl 993端口

imap/ssl/novalidate-cert 995端口

nntp协议 119端口

相关资源:

中国协议分析网 http://www.cnpaf.net/

RFC文档 http://www.faqs.org/rfcs/

保留用户输入的错误数据

最近公司项目比较闲, 所以很多时间都在整理代码, 这几天就又有了一个这样的需求, 当用户提交了错误的信息, 提示错误并保留用户输入的数据。

起初第一个想法就是使用COOKIE, 后来又考虑使用$_SESSION, 其实两者无明显区别,大概流程是这样的, 每个请求的前面都加入下面的逻辑:

1
2
3
4
5
6
7
8
9
10
if(有保存的数据){
if(数据是不是本动作产生的){
如果是则取得数据
}
清空保存的数据
}

if(是一个POST请求){
保存用户的请求数据
}

这样处理的话消息处理需要中间页跳转,就是说错误提示是一个单独的页面,这样基本可以做到将数据保存到下一个请求。这个方法后来在显示上比较麻烦,就是需要判断有没有取得的数据,有的话输出没有的话不输出, 如果使用模板引擎的话处理起来更加复杂, 于是又提出了另一种解决方案。

将表单和处理程序放在一起(可能是一个function , MVC中应该是一个action中),这样的话需要显示表单或者处理数据要准备一套结构相同的数据传给页面,然后由本页显示错误消息, 不需要使用COOKIE.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function actionCreate(){
if(是POST请求){
过滤数据
验证数据并生成错误
if(没有错误){
向数据库插入数据
}else{
将错误数据提交给显示层
}
}else if(是GET请求并且必要参数正确){
从数据库取得显示数据提交给显示层
}else{
返回一个参数错误
}
$this->display('create.html');
}

可以说这个方法是比较完美的, 目前来说没有什么不足之处, 但是有很多细节是需要注意的, 比如form的action要提交给自身并且携带参数, 虽然参数无作用, 但可以用来刷新页面(window.location.href=window.location.href), 显示层刷新页面的功能是必须的, 因为如果是修改操作那么输入错误之后将会保留错误的信息。

接下来还可以通过控制错误消息的结构识别错误是由哪一个表单项产生的, 如果需要还可以对错误进行自动修改等等。

工作不是生活的全部

昨天看褪墨的一篇文章, 里面有这么一个章节,看过之后很有感触.

工作不是生活的全部

你是不是经常在晚上和周末加班?如果你花费所有的时间在工作上,那你用什么时间去消费你赚的钱呢?不要因为放下手边额外的工作而有罪恶感,休闲时间和工作时间同等重要。从工作中得到满足感的确是令人高兴的事情,但是我们只是埋头工作的话,我们的生活会失去应有的平衡。

这说的的确很有道理, 有时候觉得每天的生活就是在工作, 特别是毕业之后, 学习的机会更少了. 我经常和朋友抱怨工作这样那样的不顺利, 这样那样的辛苦, 但后来才发现原来根本不用这样, 工作只是一种赚钱的手段而已.

对我来说, 工作只能让我有东西吃, 有衣服穿, 有地方住, 除了学习之外工作只是为了赚钱, 再抽象一点说就是在用痛苦交换幸福.

我想工作可能不能帮助任何人实现他们的梦想, 除非他们的梦想是给别人打工然后回家养活老婆孩子, 工作也不可能代替任何人的生活, 家庭, 感情, 梦想, 这些东西工作永远都不可能替代, 工作只是多数人在为少数人的生活, 家庭和梦想在努力而已.

昨天用Open Office做了这样一个表格, 然后恍然大悟, 工作之外, 做回我自己, 梦想就在眼前.