【转】影响浏览器本地缓存的因素及解决方案

浏览器缓存是很重要的,一次交互,有95%以上的时间是在处理前端的,如果能提高前端的性能,对提高整个系统的性能是很有帮助的。本专题主要讲的是如何更好地使用浏览器缓存,同时包括了一些今后浏览器缓存的发展趋势,如:globalStorage等。

影响浏览器本地缓存的因素及解决方案
因素:子域名
具体描述:berg.sharej.com/img/123.gif 这个图片,如果按照 sharej.com/berg/img/123.gif这样的方式访问,需要重新加载一次。类似的,大小写不同也会造成重复下载
解决办法:统一使用一个地址可避免重复下载。

因素:Meta头
具体描述:<META HTTP-EQUIV="Pragma" CONTENT="no-cache">或者使用脚本输出了要求浏览器不缓存网页的header
解决方案:合理的按照需求使用。

因素:Firefox的cache机制
具体描述:即使是应用了no-cache 头,firefox还是要先cache ,再根据过期设定决定是否使用。via
解决方案:一般无需解决。因为firefox缓存这些文件只是用作前进/后退。

因素:随机文件名
具体描述:可使用abc.js? 2007120来使浏览器重新加载js文件。一种更安全的方是abc_v071201.js来使浏览器重加载(可通过地址重写实现)。
解决方案:在js、css文件升级后,必要时可进行此处理,避免用户浏览器缓存的旧的文件。

因素:innerHTML
具体描述:IE6在window.onload中用innerHTML动态插入图片的时候会忽略Cache策略,一次加载多张相同图片时,会重复请求。
解决方案:避免在window.onload中使用innerHTML插入图片。

因素:IE6无法缓存背景图片的bug
具体描述:IE6的 ““temporay internet files”设置为“每次访问此页时检查”时, 背景图片将无法被缓存,在鼠标滑过链接背景图片更换时,会产生闪烁。
解 决方案:document.execCommand("BackgroundImageCache", false, true);在ie6下执行这条语句即可,Firefox执行时会报错(可用try-cache解决)。用expression也可以达到这个效果最好是 用CSS Sprites解决问题。

在浏览器端预先缓存图片的实现
使用Image()对象缓存
使用JavaScript新建一个新的Image()对象,然后将希望预装载的图片URL传递给此对象。通过onLoad()事件句柄同步装载到页面上。demo

通过数组(arrays)缓存多个图片
定义了变量i以及名为imageObj的Image()对象。然后定义了新数组images[],每一个数组元素将存储需要预装载图片的地址来源。最后,使用一个for()循环来遍历整个数组,并对每个元素指定Image()对象,以此将图片都预装载到缓存中。
demo

上面这两种方法都需要浏览器支持javascript才能正常缓存。

使用CSS隐藏需要缓存的图片
采用css的display:none;属性来隐藏图片。
demo

使用css中的背景图片
可以为一个元素定义背景样式,然后将背景图片移到不可见的位置。IE6在““temporay internet files”设置为“每次访问此页时检查”时无效。
demo
上面这两种方法都需要浏览器正常解释css才能正常使用

相册中图片的预加载
上面提到了四种预先缓存图片的方法,个人感觉第二种方法最好。因为使用第二种方法可以方便的控制加载的时间,不会影响之前页面的打开速度,而且只要支持js的浏览器都能正常使用。
demo
这个例子比较简单,但是已经能实现预加载了,在打开缩略图页面时,只要开启了缓存的浏览器,大图就会在页面结束后逐一被载入。但是一些具体的加载策略还没有做考虑。

鼠标滑过背景图的切换
如前所述,IE6的 “temporay internet files”设置为“每次访问此页时检查”时, 背景图片将无法被缓存,在鼠标滑过链接时(不管是否有背景图切换),会产生闪烁。其他浏览器都能很好的通过超链接的hover来设置背景图片实现鼠标滑 过,背景图切换。

IE6闪烁的原因
首先总结ie6中发生闪烁的原因,最后给出一个解决方案。

定义一个这样的样式:

.Example a{
background-image:url(some image);
}
下面是所有会引发闪烁的原因:

Background
当此元素background被设置成以下的值时,会发生闪烁:
background-color: transparent
background-repeat: repeat
background-position: 只要设置了都会闪烁

元素的面积
需要这个元素不闪烁,这个元素的面积必须要大于2500px^2。 =。=

.example a {
width: 50px;
height: 50px;
background-image:url(some image);
}
.example a {
width: 50px;
height: 40px;
background-image:url(some image);
}
上面一个样式不会闪烁而下面一个样式会闪烁……

图片是否透明gif
当背景图片是一个带透明效果gif时,会闪烁。

跨浏览器的解决办法
<script>
try {
document.execCommand(‘BackgroundImageCache’, false, true);
} catch(e) {}
</script>
<style>
a{ background:transparent url(logo.gif) no-repeat scroll left bottom;line-height:300px;padding:30px;}
a:hover{ background-position:-2000px 100%;}
</style>
<a href="/">&nbsp;</a>
其中logo为一个包含原图和翻转图片的大图片。在IE6,IE7,firefox2.0,opear9下测试通过

IE中的userdata的使用
Cookies也能达到在客户端缓存数据的作用,但是cookies的大小限制很严格(4K),所以不能用来缓存过多的用户数据, userdata的出现解决了这个问题。每个网页的UserData存储区数据大小可以达到64 Kb,每个域名可以达到640 Kb。
IE 5以上的IE浏览器才支持userdata这个行为。在用户机器上,userdata默认是存储在这个位置:C:Documents and Settingsyour login nameApplication DataMicrosoftInternet ExplorerUserData
userData行为通过sessions为每个对象分配UserData存储区。使用save和load方法 将UserData存储区数据保存在缓存 (cache)中。一旦UserData存储区保存以后,即使IE浏览器关闭或者刷新了,下一次进入该页面,数据也能够重新载入而不会丢失。
在HTML、HEAD、TITLE和STYLE标记上应用了userData行为后使用save和load方法将会出错。

使用前,必须先声明样式:

或者使用脚本绑定:
object.style.behavior = "url(‘#default#userData’)"
object.addBehavior ("#default#userData")

csdn中列有userdata成员和方法表。

demo

Userdata 的作用域问题
当我在/forum/a这个页面中执行一次u.Save("sss", "just a forum", 365, "forum");后,userdata的目录下出现了一个sss[1].xml文件,内容是:

同时,在/forum/b这个页面中执行alert(u.Load("sss", "forum"));时,能够取到userdata中的内容。 而在“/”这个页面中是取不到刚才存放进去的内容的,同样的,在“/topic/1234”也是取不到内容的。
类似的,执行u.Save("forum", "just a forum", 365, "value");后再alert的结果和上面的结果相同。
个人觉得userdata和cookies一样,是和path相关的。同一目录下的所有页面能共享同一个文件中的同一属性(Attribute)。因此在使用的时候要注意目录结构的问题。

Userdata的超时设置
Expires这个属性是用来设置userdata的超时时间的。Userdata的超时设置是针对一个文件的,一旦过期,整个文件都过期了,不能单独设置每个属性的过期时间。

其他问题
如果 userdata被人为删除,此时执行o.getAttribute()、o. setAttribute()会报错:“Error:数据无效。”在使用这两个方法之前, try-catch o.load()可以屏蔽这个错误,但是userdata就无法正常使用了,除非修改存储的文件名。

删除userdata的时候不能像删除cookie一样,用new Date(0)来制造过期时间。315532799000 是格林威治时间1979年12月31日23时59分59秒。这是删除UserData的最靠前的一个有效expires时间了。

如果在一个浏览器进程中重复删除、写入userdata数据,userdata空间将很快被撑满,因为每次删除都是逻辑删除,等到浏览器进程结束后才会真正执行删除操作。

非IE浏览器“userdata”的解决方案
sessionStorage
从firefox 2.0开始,开始支持HTML5,同时也就支持了sessionStorage,这是一个只能在session生命周期内使用的对象,最大的用途在于用于 保存一些临时的数据防止用户意外刷新页面,同时,在浏览器意外关闭并恢复页面时,sessionStrorage中存储的信息也会被同时恢复。 Firefox默认允许一个域名存储5120KB的数据。
demo(必须要上传到服务器上才能正常运行)

下面是HTML5定义的接口:
interface Storage {
readonly attribute unsigned long length;
DOMString key(in unsigned long index);
DOMString getItem(in DOMString key);
void setItem(in DOMString key, in DOMString data);
void removeItem(in DOMString key);
};

作用域问题
Firefox中的sessionStorage在域名下任意页面存储后,整个域名下都可以使用存储的项目。

其他问题
在浏览器crash后,restore页面的session也不见了,(firefox2.0) 。

globalStorage
这个也是html5中提出来,在浏览器关闭以后,使用globalStorage存储的信息仍能够保留下来,并且存储容量比IE的userdata大得多,一个域下面是5120k。和sessionStorage一样,域中任何一个页面存储的信息都能被所有的页面共享。

作用域
globalStorage[‘z.baidu.com’] 所有z.baidu.com下面的页面都可以使用这块空间
globalStorage[‘baidu.com’] 所有baidu.com下面的页面都可以使用这块空间
globalStorage[‘com’]:所有com域名都可以 共享的使用这一块空间
globalStorage[”] :所有页面都可以使用的空间

现在Firefox只支持当前域下的globalStorage存储, 如果使用公用域会导致一个这样一个类似的错误“Security error" code: "1000”。

过期时间
按照HTML5的描述,globalStorage只在安全问题或者当用户要求时才会过期,浏览器应该避免删除那些正在被脚本访问的数据,并且userdata应该是用户可写的。

因此我们的脚本要能够控制过期时间,可以在globalStorage的某个区域存储过期时间,在load的时候判断是否过期,可以在一定程度上解决过期时间的问题。

存储时,同时存储过期时间
Save = function(content, expires, attribute, fileName){
var date = new Date();
date.setSeconds(date.getSeconds() + expires);
globalStorage[domain][fileName + "__expires"] = date.getTime();
}
Load时判断是否过期,过期则删除:
Load = function(attribute, fileName){
var date = new Date();
if(parseInt(globalStorage[domain][fileName + "__expires"]) < parseInt(date.getTime()) ){
d.Remove(attribute, fileName);
d.Remove(attribute, fileName + "__expires");
}
return globalStorage[domain][fileName + attribute];
}

Firefox about url

There are a few special URLs, which begin with about:, that you can type into the Location Bar. (In Thunderbird, which has no Location Bar, or in SeaMonkey, you can also use them as "Mail Start Page".)

        

  • about: — The same page as "Help -> About".
  •     

  • about:about — Lists all these about: URLs (Mozilla Suite/SeaMonkey only).
  •     

  • about:blank — A blank page. Useful for setting as your homepage.
  •     

  • about:bloat — Displays BloatView output (disabled in release builds).    
              

    • about:bloat?new
    •         

    • about:bloat?clear
    •     

        

  •     

  • about:buildconfig — Reveals details about your Mozilla build options.
  •     

  • about:cache — Displays cache statistics and disk cache directory location.    
              

    • about:cache?device=memory — Lists memory cache entries.
    •         

    • about:cache?device=disk — Lists disk cache entries.
    •     

        

  •     

  • about:cache-entry — Shows information about a cache entry. Used in about:cache links. Requires parameters.
  •     

  • about:config — GUI for modifying user preferences.
  •     

  • about:crashes — List of Breakpad crash reports, with links and datestamps. Only in products based on Gecko 1.9 or later (Firefox 3, Thunderbird 3, SeaMonkey 2).
  •     

  • about:credits — The list of contributors to the Mozilla projects.
  •     

  • about:logo — Displays the application logo (Mozilla Suite, SeaMonkey, and Firefox 3).
  •     

  • about:kitchensink — Was never included in Mozilla for the reasons listed in Bug 122411 ("Mozilla does not have a kitchen sink"). You can install an extension that adds it though 🙂
  •     

  • about:license — shows the Mozilla Public License and the Netscape Public License for the piece of software. ( Only in products based on Gecko 1.8 or later)
  •     

  • about:mozilla — The famous Book of Mozilla.
  •     

  • about:plugins — Lists all your plugins as well as other useful information.
  •     

  • about:robots — Easter egg, see bug 417302. Beginning with March 8th, 2008 trunk builds, it’s now available on Firefox 3.0b5..

[edit]

Extensions

Certain extensions add a few additional about: URLs.

        

  • Firesomething adds two excerpts from The Book of Mozilla, Extended edition (about:firefox and about:firesomething).
  •     

  • InfoLister adds about:info, a listing of your extensions, themes, and plugins.
  •     

  • about:kitchensink extension
  •     

  • MR Tech’s About:About

[edit]

External Links

        

  • Place in Mozilla’s code where these are listed

什么是about:config¤
about: config是Firefox的设置页面,Firefox提供了不少高级设置选项在这里以便让你可以更加详细地控制Firefox的运行方式。官方不推荐 用户手工修改about:config的设置。所以,如果你对于你想修改的内容不是非常确定的话,请不要去改变它。)
打开Firefox中 about:config设置的方法是在Firefox地址栏输入about:config,然后回车。这份列表包括了尽可能多的 Mozilla 参数。虽然它并不完整,但它可以说是目前互联网上最全面的一份参数说明了。此列表适用于 Mozilla Suite, Mozilla Firebird, Mozilla Thunderbird或其派生的产品及相关扩展。如果没有找到您需要的参数,您还可以到MozillaZine站的英文版About:config entries (http://kb.mozillazine.org/About:config_Entries)中寻找。
注意:所有使用到 FOO 或者 BAR 的地方都是通配符。使用数字或文本替换它(具体用什么取决于上下文环境),Mozilla 将只列出匹配此模式的选项。
about:config 中的条目非常多,我们把它按照字母顺序分割为若干小块。比如,凡是以字母 a 开头的项均列入到A页中,以此类推。
目前,about:config 说明还不完善,期待你的翻译和改进。

¤正文介绍¤

1、accessibilityNavigation aids and useability * 浏览辅助工具

1、 accessibility.accesskeycausesactivation * 是否允许通过accesskey属性来激活相应的事件(默认值true),比如网页中一个设置了accesskey属性为“k”的按钮(button), 可以通过Alt+k来产生一个点击(click事件)。

2、accessibility.browsewithcaret * 用光标来浏览网页(可通过F7开关)

3、accessibility.disablecache * 不使用cache

4、accessibility.disableenumvariant * [有待测试]

5、accessibility.tabfocus * 设定可以通过按TAB键来依次获得哪些页面元素的焦点
1 : Text field form controls only * 仅表单中的文本输入框
2 : All form controls except text fields * 除了文本输入框外的其它表单输入控件
3 : All form controls * 表单中的所有输入控件
4 : Hyperlinks and hyperlinked images * 超级链接和超级链接图片
7 : All form controls and hyperlinks * 表单中所有的输入控件和超级链接

6、accessibility.typeaheadfind * 打开\"type-ahead find\"(现在叫\"Find as you type\")功能,
如名字所说,敲入几个字母,将快速定位到第一个包含这些字母的链接上。
或许可以翻译成\"即敲即找\"。

7、accessibility.typeaheadfind.autostart * 快速启动type-ahead find功能而无须按/键(寻找文本)或者’键(寻找链接)。

8、accessibility.typeaheadfind.enablesound * 允许在type-ahead find找不到时发出报错声(Linux/Unix下默认关闭,其他平台默认打开)

9、accessibility.typeaheadfind.enabletimeout * 从键名上来看,这段英文估计也是错误的……应该是允许超时之类

10、accessibility.typeaheadfind.linksonly * 只允许type-ahead find定位链接

11、accessibility.typeaheadfind.soundURL * 给出报错声音的文件名(.wav), * default:默认声音 * beep:系统蜂鸣声

12、 accessibility.typeaheadfind.startlinksonly * 限制type-ahead find只从链接开头搜索而不是从任何地方开始,*(比如输入kmc将定位到链接文字为\"kmc is a boy\"的链接,但是不会定位到\"All boys are not kmc!\"上面)

13、accessibility.typeaheadfind.timeout * 在type-ahead find自动失效之前的超时时间

14、accessibility.usebrailledisplay * 填入在Mozilla中用的盲文输出程序的命令行启动命令(没有时填blank)

15、accessibility.usetexttospeech * 通过键入命令行在Mozilla中启动读屏软件

16、accessibility.warn_on_browsewithcaret * 当用用光标来浏览网页是否给出提示(参见accessibility.browsewithcaret)

17、adblock.enable * 广告屏蔽开启

18、adblock.fastcollapse *

19、adblock.frameobjects *

20、adblock.hide* 广告隐藏

21、adblock.linkcheck *

22、adblock.pageblock *

23、adblock.patterns *

24、addressbook.throbber * 地址簿throbber的设置

25、addressbook.throbber.url * 点击throbber转向的链接地址

26、advanced.always_load_images * 访问页面是总是载入所有图片

27、advanced.mailftp * 对匿名ftp,发送用户的邮件地址作为密码(类似于FlashFxp里面的设置)

28、advanced.system.supportDDEExec * 支持执行DDE命令行

29、alerts.height * 字面意思应该是提示框的高度,实际修改后未见效果

30、alerts.slideIncrement * \"滑出\"提示效果(类似于气泡提示)的步进值(单位:象素)

31、alerts.slideIncrementTime * \"滑出\"动画效果的间隔时间,数字越小滑动速度越快(单位:毫秒)

32、alerts.totalOpenTime * 设定提示的持续时间(单位:毫秒)

33、alexarankstatuspref.state *

34、app.build_id

35、app.extensions.version * 安装扩展时向扩展报告的Firefox版本号

36、app.id

37、app.update.autoUpdateEnable

38、app.update.enable

39、app.update.interval

40、app.update.lastupdatedate * 记录最后一次更新的时间

41、app.update.performed

42、app.update.updatesAvailable

43、app.update.url

44、app.version

45、application.use_ns_plugin_finder* 寻找Netscape浏览器的插件

46、autoadmin.append_emailaddr * 自动添加收到的e-mail的地址到地址簿

47、autoadmin.failover_to_cached * 如果不能访问页面,自动加载缓存的页面来替代

48、autoadmin.global_config_url

49、autoadmin.offline_failover * 如果不能在线浏览,自动切换到离线浏览方式

50、autoadmin.refresh_interval * 加载autoadmin.global_config_url指定的配置文件的时间间隔,以分钟计

51、autocomplete.grab_during_popup * (仅适用于 X11)指定自动完成弹出控制是否应该获取键盘输入。* 默认值为 true。 本首选项可设置为 false,以规避一个 XKB 不能正确设置模式切换的 bug。

52、autocomplete.ungrab_during_mode_switch * (仅适用于 X11)本选项是 autocomplete.grab_during_popup 的补充。
*若两个首选项都为 true,在自动完成会话期间,模式切换键被按下/弹起时,应用程序放弃/获取键盘输入。
* 若两个首选项中任何一个为 false,则在自动完成会话期间,应用程序不会放弃已获取的键盘输入。
* 默认值为 true。

53、autoupdate.enabled * 允许自动更新

54、backups.number_of_prefs_copies * 根据配置文件生成的拷贝份数()

55、bidi.characterset * 浏览器怎样决定使用的字符集
* 1 : 文档指定的字符集
* 2 : 默认字符集

56、bidi.clipboardtextmode * 使用的剪贴板类型
* 1 : Logical
* 2 : Visual
* 3 : Source
57、bidi.controlstextmode
* 1 : Logical
* 2 : Visual
* 3 : Container
58、bidi.direction * 选择文字阅读顺序
* 1 : Left-to-right * 从左到右
* 2 : Right-to-left * 从右到左
59、bidi.numeral* 怎样显示数字
* 1 : 规则的上下文数字
* 2 : 印地语上下文数字
* 3 : 阿拉伯数字
* 4 : 印地语数字(天城体字母)
60、bidi.support* 选择双向语言支持的提供者
* 1 : Mozilla浏览器
* 2 : 操作系统
* 3 : 禁用
61、bidi.texttype * 1 : Charset * 2 : Logical * 3 : Visual

62、browser.active_color * 激活链接的颜色 * 默认的链接颜色(#RRGGBB)

63、browser.anchor_color *

64、browser.allowpopups * 允许未请求的弹出窗口

65、browser.always_reuse_window * 当 OS 请求打开一个 URL 时,总是重用已经存在的 Mozilla 窗口。

66、browser.blink_allowed * 允许使用<blink>标签

67、browser.block * 浏览器拦截功能设置

68、browser.block.target_new_window * 阻止链接打开新窗口

69、browser.bookmarks * 浏览器收藏夹

70、browser.bookmarks.added_static_root * Mozilla是否导入了系统收藏夹(对每个用户配置只询问一次)

71、browser.bookmarks.confirm_sorting * 激活对收藏夹排序时的确认询问对话框

72、browser.bookmarks.import_system_favourites * 是否导入系统收藏夹(一般是IE收藏夹)到Mozilla

73、browser.cache * 浏览器缓存

74、browser.cache.check_doc_frequency * 设定检查是否需要更新缓存文档的频率
* 0 : Once per session * 每个进程一次 每次启动Firefox时检查
* 1 : Each time * 每次访问此页时检查
* 2 : Never * 不检查
* 3 : When appropriate/automatically * 自动
75、browser.cache.disk * 浏览器磁盘缓存

76、Browser disk cache settings * 浏览器磁盘缓存设置

77、browser.cache.disk.capacity * 磁盘缓存大小(单位: KB)

78、browser.cache.disk.enable * 是否使用磁盘缓存

79、browser.cache.disk.parent_directory * 存放缓存文件的路径

80、browser.cache.disk_cache_ssl * 是否通过HTTPS/SSL(数据加密)方式来获得缓存文档

80、browser.cache.enable * 允许缓存从浏览器获取的文档()估计是pdf, doc之列

81、browser.cache.memory * 浏览器内存缓存

82、Browser memory cache settings *浏览器内存缓存设置

83、browser.cache.memory.capacity * 内存缓存大小(单位:KB)

84、browser.cache.memory.enable * 是否使用内存缓存

85、browser.chrome.favicons * 是否在地址栏显示网站的个性化图标

86、browser.chrome.site_icons * 是否在收藏夹显示网站的个性化图标

87、browser.chrome.toolbar_tips * 是否在指向浏览器工具栏图标时显示提示

88、browser.chrome.toolbar_style * 设定浏览器工具栏风格
* 0 : Pictures Only * 仅图片
* 1 : Text Only * 仅文字

关于httpwatch的使用

今天想下载几段戏曲,但是很多网页播放器能播放的东西都不是好下载的,首先找数据源就比较麻烦,下面介绍一种办法。
1. 打开httpwatch,查看可以播放戏曲的页面,等所有的东西都加在完成后,观察所有请求中的time列,如果戏曲还在加载过程中,那么肯定有一列为“*”,就是还没有加载完的意思,那么这个请求就是播放的数据源,直接复制出来下载吧。

2. 直接复制出来未必就能直接下载,这些东西一般通过几种方法来判断;

   根据referer判断,这个不用于防止下载,主要是用于防止盗链
   根据agent判断,这个应该是防止使用非浏览器的工具下载的,如:可能不能简单实用wget或curl下载,但是修改了agent就可以下载了

会员中心设计的一些分析

最近在做会员中心的改造,为了避免在改造中出现一些不必要的失误,就先了解一下其他网站会员中心的做法。

QQ校友的会员中心: http://xiaoyou.qq.com/

1. 对外显示的只有一个程序  /index.php, 所有的页面显示和表单的处理操作都通过参数控制,我曾经写的第一个网站就是这么做的,是刘明教我的
2. 修改信息没有采用无刷新的方式
3. 页面清新、简约;赏心悦目

Firefox 的表单重复提交的bug

Firefox 3.5确实有一些新功能,而且启动的速度也很快,但是偶尔遇到bug真的很郁闷,下面是我写的一个非常简单的代码高亮的工具,如果您使用的是IE或您比较幸运的话,每次点击按钮都会打开一个新的窗口;我用的是Firefox 3.5 ,有时候也可以每次点击按钮都打开一个新的窗口的,但是有时就只打开一次,在点击也没有用了。

    
     不需要 <?php  和 ?>  ,会自动添加

form 表单默认提交按钮

根据xhtml的规范,表单里第一个button的类型默认是submit的,所以即使不写type="submit" 第一个button也是可以作为submit使用的,但是IE没有按照规范来实现,所以如果不希望第一个button作为提交按钮的话,IE中直接不指定button的type就没有问题,但是Firefox中就不行,下面两个表单在Firefox中的表现是不一样的,但是在IE中表现是一样的,不信分别使用IE和Firefox试试。

下面两个表单的代码如下:

<form action="javascript:alert('submit form');">
    <
input type="text" />
    <
button onclick="alert('actived button');">submit</button>
</
form>
<
form action="javascript:alert('submit form');">
    <
input type="text" />
    <
button type="buttononclick="alert('actived button');">submit</button>
</
form>

        
        

张新芳《祭塔》

视频地址: http://www.56.com/u91/v_NDUyMzgxNTI.html
戏词:
娘的儿休提起当年以往
提起来当年事叫娘悲伤
娘本是一条白蛇深山修养
数千年才修成二八女娇娘
那一日在洞中我精神不爽
一心心出洞去游玩时光
行走在黑风山上一阵风声响
偶遇了小青儿拦挡为娘
娘这里好言好语对她言讲
她那里恶言恶语将娘来伤
俺们二人杀有得三十余仗
也不分谁输谁赢并谁刚强
娘举起捆仙绳将她锁绑
捆三捆放三放我没把她的命伤
小青儿见为娘恩深义广
她情愿做个奴婢前前后后左左右右
铺床叠被端茶捧水侍奉为娘
娘带着小青儿到西湖玩赏
偶遇了儿的父姓许名仙字汉文同船过江
船行在江心内冷雨往下降
眼看看大雨淋湿娘的衣裳
儿的父在船仓把好心献上
他才将一把雨伞赠于为娘
次一日儿父讨伞灵王府上
小青儿做个媒红配对成双
皆只为儿父家贫日无度养
为娘我盗官宝才惹下祸殃
县官长把儿父带奔到公堂上
问一个犯法死罪绑到法场
为娘我灵王府心血潮涨
屈指算就知儿父遭了冤枉
急慌忙驾祥云公堂以上
只闹得天昏地暗天昏地暗
地暗天昏日月未有光
县官长在公堂仔细思想
他就知儿的父有了冤枉
二一次把儿父带奔到公堂上
问一个死罪饶活难免
充军发配发配充军去到镇江
为娘我带青儿镇江赶上
十字口开药店名叫个明伦堂
在那里生意茂盛财源聚广
皆只为五月五日庆贺端阳
儿的父在大街药酒灌上
叫为娘我陪他同饮酒浆
为娘我听一言胆颤觉丧
千年蛇最怕的是药酒雄黄
为娘我就推说精神不爽
怀揣着十个月我一点也不敢尝
儿的父他只知一阵疯狂
头顶着那杯酒扎跪在地当央
在小房难也难坏我逼也逼煞娘
就知道用下腹去要遭祸殃
为娘我把药酒用到腹上
好一似千把钢刀刺娘胸膛
我随时离了位躺在牙床上
不小心露出来当年一日一日当年那个形状
儿的父见娘醉难过心上
捧香茶掀罗帏吓死在地当央
为娘我酒醒来抬头观望
见儿父躺地下半阴不阳
急慌忙将儿父搂抱怀上
连唤他数十声不应一腔
无奈何盗灵芝灵鹫山上
偶遇了白鹤童子拦挡为娘
我手拿着斩仙剑来往军阵闯
不小心将童子的左膀来伤
众群仙他一见恶气往上
摆下了雄黄阵捉拿为娘
好一个南极仙恩深意广
他才将灵芝草赠于为娘
为娘我把灵芝带回府上
叫青儿下灶伙去煎药熬汤
不多那一时将药熬停当
真可叹儿的父牙关紧
他难送下去灵丹妙药汤
在小房难也难坏我愁也愁煞娘
无奈何我一星一点一点一星
才送下去灵丹妙药汤
费千心治好了儿父病恙
一心心还愿到金山寺上
儿的父还愿到金山寺上
老法海挡住他不叫下山冈
为娘我带青儿金山赶上
偶遇了老法海才结下冤枉
娘这里好言好语对他言讲
他那里恶言恶语将娘来伤
娘一怒搬来了水兵虾将
一心心发海水漫他山冈
眼看看水漫到金山顶上
又谁知老法海的武艺高强
老法海搬来了天兵天将
众神圣执着法宝捉拿为娘
紫金钵扎至在山门以上
只打的有为娘我披头散发
满脸血流身带重伤
眼看看有为娘阵前命丧
魁星爷捧谕旨下了天堂
他言说白蛇女命不该丧
怀揣着当朝一品一品当朝
儿啊你是个状元郎
众啊众神圣一起归上苍
有为娘逃出阵才半阴不阳
我走也难行走站也站不上
多亏了丫鬟姐姐儿的小姑娘
把为娘搀至到断桥亭上
那时节儿的父他又下山冈
灵王府被法海用火焚丧
无奈何姑母家中才把身藏
到那里才有个安乐模样
那时节小冤家你就要离娘
娘生儿我也曾受过苦况
娘生儿我也曾见过阎王
娘生儿刚刚有三天以上
老法海来化斋起下不良
紫金钵扎至为娘青丝发以上
将一座雷峰塔压住为娘
把为娘压塔下一切不讲
但愿得我的儿你子子孙
子子孙孙永在朝廊
我的儿在家把姑母奉上
报一报养育恩胜似为娘
这本是前情话对儿细讲对儿细讲
我的小娇儿啊
但不知何一日我才能出离塔房

PHP 中的数字字符串的比较

下面看一段代码:
<?php
echo "230119198107190323" == "230119198107190324";
?>

这段代码太简单了,但是或许您未必能猜出其值; 这里显然是两个字符串的比较,而且最后一位是不相同的,所以应该输出为空,而实际上输出为:1;

再看这段代码:
<?php
echo strcmp("230119198107190323", "230119198107190324");
?>

这个是字符串的比较,明显前面的小于后面的,输出为:-1; 这个没有疑问;

为什么第一段代码会显示相等呢?可能是PHP做了自动类型转换了,但是有些不太明白,都是字符串,干嘛还要转换呢?先做个测试验证一下:

看看这段代码:
<?php
echo "a230119198107190323"
== "a230119198107190324";
?>

输出结果为空,看来PHP还真是自动转换类型了。

去PHP的源码里面找找,看看怎么处理的:

1. 可能和oprator有关,进入PHP的源码目录
>find . -name ‘*operator*’
./Zend/tests/zend_operators.phpt
./Zend/zend_operators.c
./Zend/zend_operators.h

还果然有

2. 打开zend_operators.c ,查找 == ,确实有些相关的东西
找到了函数:zend_string_to_double ,真的就是通过该函数处理的吗? 用gdb验证一下吧:
将上面第一段代码保存为a.php
> gdb php
> set args a.php
> break
zend_string_to_double
> r
> Program exited normally.
难道没有执行函数
zend_string_to_double? 有可能,那么PHP的类型转换是在什么地方进行的呢?我除了知道程序必定经过main函数外,就再也不知道程序会经过哪里,但是我如果就在mian处设置断点,我就很难跟了,怎么办?
这样,我将a.php 写成
<?php
sleep
(1);
echo
"a230119198107190323" == "a230119198107190324";

?>
这次我在 sleep处设置断点就可以了,然后再往下跟就里字符串的比较很近了。事实却是如此,时间不早了;我不在具体调试了,下面直接给出比较时所在的堆栈:
(gdb) bt
#0  zendi_smart_strcmp (result=0xbfe72c7c, s1=0x97c8d0c, s2=0x97c8cec)
at /usr/home/wucheng/software/php/php-5.1.5/Zend/zend_operators.h:76
#1  0x081f29a6 in compare_function (result=0xbfe72c7c, op1=0x97c8d0c, op2=0x97c8cec)
at /usr/home/wucheng/software/php/php-5.1.5/Zend/zend_operators.c:1342
#2  0x081f3cf2 in is_equal_function (result=0xbfe72c7c, op1=0x97c8d0c, op2=0x97c8cec)
at /usr/home/wucheng/software/php/php-5.1.5/Zend/zend_operators.c:1498
#3  0x08267d19 in ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER (execute_data=0xbfe72ca0)
at /usr/home/wucheng/software/php/php-5.1.5/Zend/zend_execute.c:200
#4  0x0820d0a1 in execute (op_array=0x97c9414)
at /usr/home/wucheng/software/php/php-5.1.5/Zend/zend_vm_execute.h:92
#5  0x081f59a2 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
at /usr/home/wucheng/software/php/php-5.1.5/Zend/zend.c:1109
#6  0x081c1dfd in php_execute_script (primary_file=0xbfe751a0)
at /usr/home/wucheng/software/php/php-5.1.5/main/main.c:1737
#7  0x0826e629 in main (argc=2, argv=0xbfe75274)
at /usr/home/wucheng/software/php/php-5.1.5/sapi/cli/php_cli.c:1093

相关参考: http://bugs.php.net/bug.php?id=6019&edit=1

‘1’与‘l’的区别

好久没有因为‘1’ 和 ‘l’ 而烦恼了,他们很像,但是就是不相等,如果单独比较,可能会意识到这根本就不是一个字母,但是和其他数字混淆到一起就很难注意到了,尤其你的程序比较复杂的时候,你是不会怀疑到这根本就不是一个字母的。怎么检查这种错误呢?
1. 重新输入一遍,如果要比较的内容不长的话
2. 编辑器支持的话,直接转换成大写观察一下
3. 将字符串的16进制编码输出出来比较一下,至少很快知道是哪个字母的地方出错的;PHP里面使用unpack函数,命令行可以使用 od -x

何谓“易”、“经”

《易经》名字简释:
上日下月为”易“,如日月之行,”易“取”变化“之意;
“经” 乃 “方法、永恒”之意;
“易经” 取 “变化的道理” 之意;
“周易” 之 “周”,取 “圆满”之意,也可演绎为“简”, “周易” 也做 “简易”,描述”简单的变化的道理“;

     《易经》最大的神秘之处,即在于由一阴一阳的排列组合中,居然能包罗时空万象,
阐释天人义理。如果说易理就是宇宙之真理,这实在并不是过誉。
     正因为一阴一阳之组合,实系以简驭繁之原理,人们想了解其精要时,就会发现内
容艰涩难解,虽穷年累月仍不得其门而入。
     事实上,《易经》虽然人人能读,但绝非人人能懂。绝大部份的人,也只是从圣人
注易的字里行间,学得一点为人处事之道而已。
     本书所提供的,是一种经过分析后、设计给电脑程序处理的数据。根据这些数据,
建立起以待分析的模式,然后再大量收集数据,循着同样的模式,以求归纳出新的结构。
与计算机数据所不同的是,本书是给人看的,所以用文字概念而非程序语言来描述。
     《周易》是由两个部份所组成,一是《易经》本身,以六十四卦为纲,每卦六爻,
以各爻之变化为目,分别以爻辞界定之。爻辞的内容说明,即该爻变动之下发生的事件,
以及其吉凶吝咎等情况。另一部份是《易传》,计有七种,分为十篇,后人称之为<十
翼>。<十翼>只是一种解释《易经》的著作,本书不加介绍,读者有兴趣,请自行参
阅。
     一般人读易,不过为求了解卦、爻辞,以资与自己的遭遇相印证,力求趋吉避凶。
本书之目的,乃基于《易经》历经数千年,时过境迁,在理解及应用上,究竟有无改进
之道?要达到这个目的,必须要回答以下三个问题:为什么卦爻与爻辞有如是关系?其
必然性的因果是什么?是不是还有其它变化存在?
     为此,首先要彻底了解卦、爻辞,然后利用科学工具,以科学方法加以整理,做全
面的分析探讨。本书即为彻底了解卦、爻辞的第一步,如果不先了解,从何下手研究?
又能研究些什么?而了解的结果,若仅仅是自己主观的认定,而没有客观的考量,其价
值也有待质疑。在这些理由下,遂有本书之出版,以求各界有心人士之指正。
     下一步将是《易理探微》一书之发表,理论部份早已书就。有了理论,再加以实验,
由实验再求印证,以合乎科学精神。实验部份目前已经有近千件占卜实例,全系以计算
机测试,测中率约在百分之八十上下。整理后的数据,将录入《易理探微》中,由于我
们时间有限,故可能要到年底才能出版(至于占卜之程序及内容,碍于序言中之原因,
目前尚未决定是否发表)。
     综观当今世事,表面上经济繁荣、知识普及。事实上人心败坏、社会的维系功能彻
底破产。易道精妙至极,古往今来,人事之变迁无所不包,易明易晦亦在易中。读者阅
之,即为缘也,要知读易有三大优点,今略述于下:
     一、学习做人处世的道理:易为天理,然天理玄妙,常人无从认知。圣人为启众聪,
特将之演为做人处世的道理,以教化万民。实则人理、世道皆为天理之一部份,仅象征
之形式有所不同而已。惜因古圣人所用之文字,今人多不识,未经适当诠释,难以理解。
古今注《易经》者众多,本书仅参阅三本:程颐之《易程传》(泉源出版社)、朱熹之
《周易本义》及来知德之《来注易经图解》(武陵公司)。
     朱熹之《周易本义》简单明了,只说易理如何,而不说明原因,常令人觉得迂腐不
堪。程颐的《易程传》则在如何之外,尚以爻位来解释为什么,看起来好象言之成理,
但都是主观的附会,没有系统的必然性,说服力不足。《来注易经图解》则完全以象征
符号说明,穿凿附会可以说极尽能事,已经超出了义理的范畴。
     因为卦、爻辞是供卜筮时判断之用,其文字内容必得符合各种相关的情况,经常采
用了一些先民的判例,因此很难掌握。原文极为艰涩,且若干文字各家解释不一,甚至
有不加说明者。读者不宜细加追究,重要的是知其吉凶吝咎。在本书中,特以“释”总
括其概要,系参考前述三家之说明,择其可信者,力求合情合理。
     二、磨练心性观念:正因为《易经》难读,在读易之前,任谁都会再三考虑,为什
么要读易?读了有什么好处?老实说,学易不但没有好处,甚至令人鄙视名利、远离荣
华。时到今日,除了研习命相占卜之术者外,《易经》早就被打入冷宫了。
     《易经》是客观事物变易之学,懂易即表示懂得必然之理,既属必然,其间无分毫
可资增减。即令爻中有吉凶之谓,实则趋、避之间,不过存乎一心而已。今人在西式教
育下,功利至上,读书的目的,是为了就业、争取自己最大的名利。故对功成业就、志
得意满的人而言,懂易不过表示博学多闻,高人一等。只有对有心追求人生真理的人,
《易经》才是通向另一片天地的一扇门户。
     到得真正沉浸在《易经》里,日深月久,一字一爻地穷思竭虑。苟心不静,我念一
起,实难以为继。待入得门来,意又难宁,面对似是而非之理,很可能到此为止,不得
再进一步。唯有在心静意宁,人我尽泯之下,始得洞烛幽冥。
     问题在于,若不为己谋,即令道通天人,所为何来?再说,从古至今,又能有几人
达此境界?是以能不计成败得失、潜心学易者,其心性及观念,多多少少已在磨练之中。
但若为了磨练而习易,则又落入下乘了。
     三、培养抽象思维的能力:一般人对语言文字的认知,不过止于表面之字义,以之
沟通应用而已。事实上,语言文字是人类有别于万物的智能结晶,是一种符号索引系统。
宇宙万象无穷无尽,而人之认知应用能力有限。在经过不断的演进后,自然而然发展出
这种以简驭繁、相当于一种分类索引的法则。
     在此分类索引下,其水平向可称为分类定义,垂直向则为属性层次。所有水平向的
定义,在另一层次中,其定义之名称将随所属层次的特性而改变。由于此系统是从人类
的生活行为中自然发展而得,故生活经验所形成的认知,即成为水平向的第一层定义。
随着文化发展的日趋繁复,再加上实际需要,以及经验及学识过人的个人的努力,遂在
第一层定义下,更引申出垂直向的属性定义。
     因此,同样的语言文字,对不同能力与经验的个体来说,具有绝对不同的效应。教
育的意义,第一步是使受教者充分了解语言文字的分类索引功能,这是能力的培训。然
后再教以专业技术,也就是语言文字所代表的某一层次的属性认知。
     中国传统教育方式,是令学子以艰苦卓绝的心态,熟读经书,使之由习惯成自然,
得以从文字运用上领略文字所蕴藏的「智能」。所以读书人不仅深谙语言文字的威力,
且知道如何与人沟通、充分发挥自己的能力。然而物极必反,剥复相因,在饱学之余,
读书人过于轻视技能,以致在生产制造技术上,落居西方之后。
     今日之教育则又矫枉过正,专重技术知识,完全忽略了语言文字的智性。尤其是大
力推广白话文的结果,导致年轻人不识经书,仅以文字的表面应用为满足。久而久之,
劣币驱逐良币,文字深层的引申义渐失其传,舞文弄墨成为雕虫小技。这也是为什么尽
管教育普及,一般专家学者的理解、判断能力反而低落的原因。
     《易经》中之象数,正代表了垂直分类中的引申定义。在失道之时,有心人不妨按
图索骥,或能有所获(此中详细论证,请见《易理探微》)。