文章列表
 
您正在查看 "默认分类" 分类下的文章

2010年10月17日 星期日 下午 5:54
作者:老王

不知不觉中我已经在百度空间写了四年的博客了,四年前,我本打算使用火丁笔记huoding.com)作为博客,不过当时由于懒惰而选择了使用百度空间;四年后,为了对得起年复一年的域名续费,我终于勤快了一下,正式启用了火丁笔记。多数人看到这个名字后都会纳闷它是什么含义,其实很简单: 火丁为“灯”,即LAMP!

欢迎访问火丁笔记:http://huoding.com/

火丁的订阅地址:http://huoding.com/feed
 
2010年09月27日 星期一 下午 4:03
欢迎访问我的新主页:http://huoding.com/

ThinkInLAMP聚集了一群热爱LAMP技术的狂热分子,每个月都会组织一次技术分享交流会议,这次“锅巴”牵头搞了一次MySQL专场技术分享交流会议,从目前释出的日程表来看,绝对有料,而且不收取任何费用,相当给力,有兴趣的网友不妨去听听(号外:中午管饭)。




备注ThinkInLAMP官方网站
 
2010年08月30日 星期一 下午 6:29
欢迎访问我的新主页:http://huoding.com/

作者:老王

这里说的User-Agent改变不是说Safari里那种User-Agent手动切换(这个功能在开发菜单里能找到),而是指多次请求的过程中,User-Agent自动就改变了。乍一听起来似乎不太可能,但确实存在这样的情况,问题浏览器IE(安装Chrome Frame)。

下面重现一下问题:

首先,安装Chrome Frame

然后,编写一个测试脚本,比如PHP:<?php echo $_SERVER['HTTP_USER_AGENT']; ?>。

最后,打开IE(我测试的是IE8)浏览器浏览测试脚本。

第一次浏览:Mozilla/4.0 (compatible; MSIE 8.0; 仿金并瓦木每:此处删除若干字) chromeframe/...
第二次刷新:Mozilla/4.0 (compatible; MSIE 8.0; 仿金并瓦木每:此处删除若干字)

由于大家安装的插件类型,版本不同,所以结果也会有所差异,不过足以表明User-Agent改变了。

User-Agent改变会有什么问题?很多时候(比如SSO多域名整合),我们为了增加安全性,会把User-Agent作为一个重要参照,如果它发生变化,势必会带来影响,鉴于Chrome Frame是Google出品,必然有一定的市场份额,所以这个问题应该了解,否则遇到问题就只有抓瞎了。
 
2010年08月22日 星期日 下午 6:59
欢迎访问我的新主页:http://huoding.com/

作者:老王

以产品为中心的网站URL

URL设计是个很有讲究的问题,很多网站在这方面显得过于随意。

比如说我们有一个照相机网站,数据库里保存着canon 550d,其id是123,那举一个不好的例子:

http://www.foo.com/pictures/123.html
http://www.foo.com/comments/123.html

为什么说这些URL不好,看看下面的URL设计:

http://www.foo.com/123/pictures
http://www.foo.com/123/comments

这样就好多了,为什么这么说呢,因为对一个产品网站来说,产品是中心,URL的设计无疑应该以产品为中心来设计,而且URL本身就是有层次的,所以善用这种层次就会让网站URL更有条理性。否则如开始那样设计URL就变成以功能为中心来设计URL了,而不是以产品为中心。

不过我们还能做得更好,比如:

http://www.foo.com/canon/550d/pictures
http://www.foo.com/canon/550d/comments

抛弃id这种索然无味的标识符,采用更具语义的品牌名字和型号名字,会得到更友好的URL。

因为这样更有层次感:canon品牌中550d型号的图片(评论),不管是对浏览者而言,还是对搜索引擎而言,这种层次感都更简单易懂。

URL设计相关文章:

关于 URL 的一些不可不知的知识
Guidelines for URI Design

Write mysqlnd plugins in PHP

这算是最近最Coooool的一个新闻了,借助一个PECL扩展mysqlnd_uh,用PHP写Mysqlnd插件,不再有C语言门槛,这意味着你可以用PHP代码实现类似MySQL Proxy的功能,非常有诱惑力。详细信息参见PHP @ FrOSCon: the power of mysqlnd plugins

MySQL衍生版本

1:Percona Server
2:MariaDB
3:Drizzle

MySQL按时间点还原

如果是通过mysqldump备份备份的话,以InnoDB为例,命令大概如下:

mysqldump --all-databases --single-transaction --flush-logs --master-data=2 ...

这里的master-data很重要,这样可以在备份文件里生成类似下面的语句:

CHANGE MASTER TO MASTER_LOG_FILE='...',MASTER_LOG_POS=...;

在还原的时候,就可以通过MASTER_LOG_FILE和MASTER_LOG_POS确定二进制日志的起始位置:

mysqlbinlog --start-date=... --stop-date=...

命令里的flush-logs也是必要的,这样可以生成新的日志文件,查找起来就方便多了。

注意:flush-logs有副作用,如果你没有做好错误日志的备份,那么多次flush-logs后,错误日志会丢失。

Linux下查看硬盘信息


dmesg命令结果里有硬盘信息,但是太乱了,不容易查看。

如果是SCSI硬盘:

# cat /proc/scsi/scsi
Attached devices:
Host: scsi0 Channel: 00 Id: 00 Lun: 00
Vendor: MAXTOR   Model: ATLAS10K5_147SAS Rev: BMU6
Type:   Direct-Access                    ANSI SCSI revision: 05
Host: scsi1 Channel: 00 Id: 00 Lun: 00
Vendor: TEAC     Model: DVD-ROM DV28SV   Rev: D.0J
Type:   CD-ROM                           ANSI SCSI revision: 05


如果是IDE硬盘,估计很少有网站会用,但记一下命令也是值得的:

# find /proc/ide/ide[0-9]/hd? -type f -name model -exec cat {} \;

经过网友提示,还有一个smartctl命令可以查看硬盘信息:

# smartctl -i /dev/sda
smartctl version 5.38 [x86_64-redhat-linux-gnu] Copyright (C) 2002-8 Bruce Allen
Home page is http://smartmontools.sourceforge.net/

Device: MAXTOR   ATLAS10K5_147SAS Version: BMU6
Serial number: J4H05LFK
Device type: disk
Transport protocol: SAS
Local Time is: Mon Aug 23 11:05:50 2010 CST
Device does not support SMART


MySQL与GUID(UUID) COMB

在这里,我把GUID,UUID两个名词看做一样的东西,都是指一个唯一ID。

GUID(UUID)大家并不陌生,但是GUID COMB就不是很常见了。最初的概念由Jimmy Nilsson提出。先看看GUID(UUID),在MySQL里多数人似乎不喜欢使用它,主要原因在于InnoDB的影响:

1:InnoDB是聚集主键,也就是说数据要按照主键物理排序,由于GUID(UUID)的无序性,会打来巨大的磁盘IO操作。
2:InnoDB中非主键索引都包含主键,GUID(UUID)本身都很长,所以索引也会变大。

其中主要瓶颈集中在第一个问题上,至于第二个问题,还可以忍受。

正是为了解决第一个问题,于是出现了GUID(UUID) COMB,对于COMB类型的GUID(UUID)来说,它在保持唯一性的前提下,并不是完全无序的,大体上有一定的顺序性,如此一来就避免了巨大的磁盘IO。

MySQL本身有一个UUID函数,例子如下:

mysql> SELECT UUID();

603fd892-adec-11df-b4c2-676ff78bcf6c
61d8f29b-adec-11df-b4c2-676ff78bcf6c

多执行几次会发现MySQL UUID函数本身有一定的顺序性,但这种顺序性有限,重启服务之类的操作还会影响它。

网上到处搜索了一下,最后才发现MySQL下似乎现在还没有众所周知的GUID(UUID)COMB方案。
 
2010年07月18日 星期日 下午 6:31
欢迎访问我的新主页:http://huoding.com/

作者:老王

方法名中的add和set

浏览Java的API文档是很有意思的事情,比如说:HttpServletResponse

在HttpServletResponse里有三个比较有意思的方法:

public void addCookie(Cookie cookie)
public void setHeader(java.lang.String name, java.lang.String value)

public void addHeader(java.lang.String name, java.lang.String value)

先看addCookie,为什么这个方法叫addCookie呢?如果换到PHP里,很多都是定义为:

setCookie($name, $value, array $options)

那么到底是addCookie好?还是setCookie好呢?从阅读者的直觉上来看,一个set方法往往意味着给某个键设置某个值,在这里,键就是$name,值就是$value。既然是键,就说明其有唯一性,但对Cookie而言,$name是不具备唯一性的,比如说不同域下可以共存同名的Cookie,所以说单就名字而言,addCookie比setCookie更合理,以后大家起名时,不要set,add想用什么就用什么,多思考一下是有好处的。

再看看addHeader和setHeader,为什么会有两个看似一样的方法呢?不过换到PHP里,很多都是定义为:

setHeader($name, $value, $replace = true)

那么到底是一个方法好,还是分成两个方法好?这里先看看如果用一个方法的话,一般如何使用:

setHeader($name, $value, true)
setHeader($name, $value, false)

其中true表示重置先前同名header,false则不是重置,而是追加(用逗号分割,详见header函数)。

再看看如果用两个方法的话,情况如何:

setHeader 对应 setHeader($name, $value, true)
addHeader 对应
setHeader($name, $value, false)

对比二者的区别,如果单纯使用一个setHeader方法,方法参数里会出现一个布尔型参数,而使用两个方法的话,则是通过set,add这样的动词来区分方法含义的。从阅读者的角度看,任何时候,布尔型参数都是让人费解的,不能准确的用直觉去判断其含义,相对而言,用明确的词汇来描述方法意图更好。

Javascript中给select添加option

最容易想到方法是通过innerHTML来添加,代码如下:

<select id="select"></select>
<button id="button">Add</button>
<script>
document.getElementById("button").onclick = function() {
document.getElementById("select").innerHTML = "<option value="bar">foo</option>";
};
</script>


innerHTML使用起来非常方便,可惜这段代码虽然在Firefox里无恙,但是在IE里却不会正常运行,解决:

document.getElementById("select").options.add(new Option("foo", "bar"));

new Option([text], [value], [defaultSelected], [selected])

如果你想选中某项,应该使用selected,至于defaultSelected,它表示的是是否缺省选中,如果你使用reset重置功能的话,则有用。

如此一来,就兼容了Firefox和IE了。为了照顾IE这个差等生,习惯用Firefox的我们不得不多考虑一下。

顺手记录options常用的几种操作:

删除所有选项:<select>.options.length = 0;
删除当前选项:<select>.options.remove(<select>.selectedIndex);
获取当前值 :<select>.options[<select>.selectedIndex].value;
获取当前文本:<select>.options[<select>.selectedIndex].text;
修改当前节点:<select>.options[index] = new Option("Text", "Value");

PHP领域对象都应该实现ArrayAccess

PHP里,领域对象是否值得使用,存争议,有的人认为在PHP里,使用数组是最佳实战;还有的人则认为随着复杂性的提高,领域对象是救命稻草。

抛开细节,先看看两种方式调用时的最初印象,举个一般的例子:

数组:<h1><?php echo $article['title']; ?></h1>
对象:<h1><?php echo $article->getTitle(); ?></h1>

数组和对象的选择,不一定非得是二选一的结果,在项目开发初期,复杂度较低,此时更注重开发效率,使用数组是更好的选择,但是随着项目的演化,复杂度越来越高,此时更注重维护效率,使用对象是更好的选择。所以我们要是能够在二者之间自由切换就最好不过了。但从上面的代码可以看到,二者的使用方式存在较大差异,一旦切换,很多调用代码都要重写,所以,我们说PHP领域对象都应该实现ArrayAccess,如此一来,你可以通过数组方式来访问对象,切换就简单多了。

CRON环境变量问题

使用CRON,基本都遇到过环境变量问题,比如说某个命令没有找到,一般来说,都是建议使用完整的路径,以避免依赖系统的PATH环境变量,但其实重新设 置一下PATH之类的环境变量是很简单的,请看:

# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/


写代码要细心

看一段PHP代码,设想一下它的输出结果,可以用来做面试题:

<?php if ($a = 100 && $b = 200) { var_dump($a, $b); } ?>

逻辑的层次划分

这个问题我印象中已经说过几次了,不过鉴于其重要性,再说一次也不嫌多。

在MVC中,单就M而言,逻辑分为两种:应用逻辑和领驭逻辑,不同的逻辑应该放在不同的层次,这样结构才清晰,比如说这个例子:我的CMS有个功能,有网友回复文章的话,则给文章作者发一封电子邮件通知他一下,同时因为有回复,说明文章受欢迎,就要给文章作者加适当的积分,以资鼓励。

上面的逻辑不算太复杂,但是编码时还是应该考虑逻辑分层,如果我们不分层的话,比如说,所有的逻辑都在控制器中完成,会有什么问题呢?假如现在我新加一个逻辑,如果用户使用手机上网,回复了文章的话,则不使用电子邮件通知,而使用手机短信通知作者,同时给文章作者加积分。由于我们把所有的逻辑都在控制器中实现了,所以其中的积分逻辑被重复实现了,把它单独划分成领域逻辑就会避免这个问题了


BTW:发现一个不错的项目,http://www.phpdocx.com/

 
   
 
 
文章存档
 
     
 
最新文章评论
  

[表情]
 

不错!
 

linux大师之路,www.linuxmr.com
 

引导一直没有整明白说。
 

[表情]
   
帮助中心 | 空间客服 | 投诉中心 | 空间协议
©2012 Baidu