近日,北京大学北大未名BBS的热门话题版面上,题为“现在京户到底有多重要?”的帖子赫然跻身前十名,从300余个跟帖中可以看出,在临近毕业签约阶段,户口的热度仍在不断升温。
上周,中国青年报社会调查中心与腾讯网教育频道联合实施的一项调查(有3518人参与,九成以上是青年)显示,77.1%的人认为,找工作最好能解决户口,但户口不是决定性因素。同时,有11.1%的人认为,户口是其择业的决定性因素,一定要签能够解决户口的单位。
调查显示,在面临户口和高薪的选择中,75.1%的人会选择高薪但却解决不了户口的工作。但是,这并不意味着高薪工作都能够打动每一位应届大学生求职的心,有12.6%的应届大学生仍然会选择低薪、解决户口的工作,他们仍然宁为户口而折腰。
中国人民大学的一位研究生小余告诉记者,“我本科4年,研究生3年都在北京度过,已经对这个城市产生了留恋和归属感,我想留在北京工作发展,我会选择户口而不是高薪”,她的理由是,薪水可以随着时间、经验、职位的提升而增加,但是户口一旦打回原籍,成为非应届生,再想调出来就相当困难了。
在文章开头提到的热门帖子上,有人跟帖说,“对于月薪两三千的人,户口的价值是他三四年的薪水,当然非常重要。对于月薪两三万的人,户口也就是他三四个月的薪水,这就不是很重要。”一位名为“手可摘星”的网友更是将户口与薪水之间的关系进行了量化处理,“本科起薪满12万,硕士满18万,博士、MBA满24万,不需要考虑户口,本科起薪低于4万,硕士低于6万,博士、MBA低于9万,一定要有户口”。然而,近两年的就业形势日趋严峻,如果以他的标准来衡量,那么,能找到类似高薪工作的毕业生应该只占少数。
调查发现,当被问及应届大学生毕业年薪是多少才能弥补户口所带来的影响时,67.8%的人认为,年薪超过10万元以上才能弥补户口所带来的损失和影响,甚至,有14.6%的人认为,这个数字应该超过20万元。
户口与爱情,这两个貌似毫无关联的词语,却在严峻的就业现实下被紧紧拴在了一起。调查显示,38.9%的人坚持选择户口是因为“户口会带给我安全感和归属感”。在大学生中普遍存在着这样一种观点,如果没有户口,个人的终身大事都会受到牵连。男的娶不到,女的嫁不了。
“我目前单身,如果找的工作解决不了户口,恐怕连找对象都成问题。”北京某高校大四毕业生小杨对记者说,“在北京、上海、深圳这样的大城市,如果毕业不能落户口,始终会有一种漂泊的感觉,就像二等公民,与农民工差不多”。一位北京的单身女大学生告诉记者,“我要找另一半,优先考虑有北京户口的,这样我才有安全感,从长远考虑,可以免除许多麻烦和后顾之忧”。
在解决户口这个问题上,“小两口”有一定优势。
今年的应届毕业生小马告诉记者,为了让男朋友能够找到一份高薪工作,她选择了一个低薪带户口的工作,为了爱情和家庭的长远利益,她做出了让步和牺牲。
调查发现,与小马有同样境遇的人并非少数,25.6%的人选择户口正是出于“为配偶缓解择业压力”的考虑,事实上,这种选择使“小两口”分工明确,可以达到资源的有效整合,是一个理性的选择。
如果实在无法落户,14%的调查参与者会买户口来解决这个问题,44.9%的人持观望态度。
户口为什么会有如此巨大的吸引力,让大家不惜为此花费重金呢?78.5%的调查参与者认为,户口承载了太多的社会功能,越是大城市,户口背后捆绑的各种福利和特殊资源就越多。
73.1%的人选择户口是因为它和住房公积金、医疗保障、养老保险等诸多社会保障制度挂钩。62.7%的人是为了解决未来子女的教育平等问题。
1953年,为减少城市人口和就业压力,保障城市经济发展,国家开始制止农民盲目流入城市,限制了公民的自由迁徙。1984年,国务院批转公安部《关于农民进入城镇落户问题的通知》,文件规定,有经营能力、有固定住所或在乡镇企业单位长期务工的农村居民,公安机关应准予落城镇常住户口。城乡户籍的坚冰首次出现裂缝。但是时至今日,户籍制度仍然没有完全放开,很多没有户口的人在城市生活仍然要受到户籍的诸多限制。因此,近年来,要求户籍改革的呼声越来越大,在不久前结束的今年两会上,户籍制度改革的讨论仍然备受关注。
调查中,66.4%的人认为,户籍制度将在未来的5~15年内被取消。“户籍制度改革势在必行,但这是一个理性而复杂的过程,改革绝不等于取消和完全放开。”这位调查参与者呼吁,“户籍制度改革在两会上年年开花,但不要年年不结果。”
上周,中国青年报社会调查中心与腾讯网教育频道联合实施的一项调查(有3518人参与,九成以上是青年)显示,77.1%的人认为,找工作最好能解决户口,但户口不是决定性因素。同时,有11.1%的人认为,户口是其择业的决定性因素,一定要签能够解决户口的单位。
调查显示,在面临户口和高薪的选择中,75.1%的人会选择高薪但却解决不了户口的工作。但是,这并不意味着高薪工作都能够打动每一位应届大学生求职的心,有12.6%的应届大学生仍然会选择低薪、解决户口的工作,他们仍然宁为户口而折腰。
中国人民大学的一位研究生小余告诉记者,“我本科4年,研究生3年都在北京度过,已经对这个城市产生了留恋和归属感,我想留在北京工作发展,我会选择户口而不是高薪”,她的理由是,薪水可以随着时间、经验、职位的提升而增加,但是户口一旦打回原籍,成为非应届生,再想调出来就相当困难了。
在文章开头提到的热门帖子上,有人跟帖说,“对于月薪两三千的人,户口的价值是他三四年的薪水,当然非常重要。对于月薪两三万的人,户口也就是他三四个月的薪水,这就不是很重要。”一位名为“手可摘星”的网友更是将户口与薪水之间的关系进行了量化处理,“本科起薪满12万,硕士满18万,博士、MBA满24万,不需要考虑户口,本科起薪低于4万,硕士低于6万,博士、MBA低于9万,一定要有户口”。然而,近两年的就业形势日趋严峻,如果以他的标准来衡量,那么,能找到类似高薪工作的毕业生应该只占少数。
调查发现,当被问及应届大学生毕业年薪是多少才能弥补户口所带来的影响时,67.8%的人认为,年薪超过10万元以上才能弥补户口所带来的损失和影响,甚至,有14.6%的人认为,这个数字应该超过20万元。
户口与爱情,这两个貌似毫无关联的词语,却在严峻的就业现实下被紧紧拴在了一起。调查显示,38.9%的人坚持选择户口是因为“户口会带给我安全感和归属感”。在大学生中普遍存在着这样一种观点,如果没有户口,个人的终身大事都会受到牵连。男的娶不到,女的嫁不了。
“我目前单身,如果找的工作解决不了户口,恐怕连找对象都成问题。”北京某高校大四毕业生小杨对记者说,“在北京、上海、深圳这样的大城市,如果毕业不能落户口,始终会有一种漂泊的感觉,就像二等公民,与农民工差不多”。一位北京的单身女大学生告诉记者,“我要找另一半,优先考虑有北京户口的,这样我才有安全感,从长远考虑,可以免除许多麻烦和后顾之忧”。
在解决户口这个问题上,“小两口”有一定优势。
今年的应届毕业生小马告诉记者,为了让男朋友能够找到一份高薪工作,她选择了一个低薪带户口的工作,为了爱情和家庭的长远利益,她做出了让步和牺牲。
调查发现,与小马有同样境遇的人并非少数,25.6%的人选择户口正是出于“为配偶缓解择业压力”的考虑,事实上,这种选择使“小两口”分工明确,可以达到资源的有效整合,是一个理性的选择。
如果实在无法落户,14%的调查参与者会买户口来解决这个问题,44.9%的人持观望态度。
户口为什么会有如此巨大的吸引力,让大家不惜为此花费重金呢?78.5%的调查参与者认为,户口承载了太多的社会功能,越是大城市,户口背后捆绑的各种福利和特殊资源就越多。
73.1%的人选择户口是因为它和住房公积金、医疗保障、养老保险等诸多社会保障制度挂钩。62.7%的人是为了解决未来子女的教育平等问题。
1953年,为减少城市人口和就业压力,保障城市经济发展,国家开始制止农民盲目流入城市,限制了公民的自由迁徙。1984年,国务院批转公安部《关于农民进入城镇落户问题的通知》,文件规定,有经营能力、有固定住所或在乡镇企业单位长期务工的农村居民,公安机关应准予落城镇常住户口。城乡户籍的坚冰首次出现裂缝。但是时至今日,户籍制度仍然没有完全放开,很多没有户口的人在城市生活仍然要受到户籍的诸多限制。因此,近年来,要求户籍改革的呼声越来越大,在不久前结束的今年两会上,户籍制度改革的讨论仍然备受关注。
调查中,66.4%的人认为,户籍制度将在未来的5~15年内被取消。“户籍制度改革势在必行,但这是一个理性而复杂的过程,改革绝不等于取消和完全放开。”这位调查参与者呼吁,“户籍制度改革在两会上年年开花,但不要年年不结果。”
我已经在 10.210.71.254上安装了. 你可以直接测试.
webbench最多可以模拟3万个并发连接去测试网站的负载能力,个人感觉要比Apache自带的ab压力测试工具好,安装使用也特别方便。
1、适用系统:Linux
2、编译安装:
引用
wget http://blog.s135.com/soft/linux/webbench/webbench-1.5.tar.gz
tar zxvf webbench-1.5.tar.gz
cd webbench-1.5
make && make install
3、使用:
引用
webbench -c 500 -t 30 http://127.0.0.1/test.jpg
参数说明:-c表示并发数,-t表示时间(秒)
4、测试结果示例:
引用
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://127.0.0.1/test.jpg
500 clients, running 30 sec.
Speed=3230 pages/min, 11614212 bytes/sec.
Requests: 1615 susceed, 0 failed.
webbench最多可以模拟3万个并发连接去测试网站的负载能力,个人感觉要比Apache自带的ab压力测试工具好,安装使用也特别方便。
1、适用系统:Linux
2、编译安装:
引用
wget http://blog.s135.com/soft/linux/webbench/webbench-1.5.tar.gz
tar zxvf webbench-1.5.tar.gz
cd webbench-1.5
make && make install
3、使用:
引用
webbench -c 500 -t 30 http://127.0.0.1/test.jpg
参数说明:-c表示并发数,-t表示时间(秒)
4、测试结果示例:
引用
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://127.0.0.1/test.jpg
500 clients, running 30 sec.
Speed=3230 pages/min, 11614212 bytes/sec.
Requests: 1615 susceed, 0 failed.
主要是要这个:
5000并发,请求数100w
ab -c 5000 -n 1000000 'http://10.70.62.28/riddle.php?iid=56764&qid=56866&uid=1
&reply=56867,56868'
5000并发,请求数100w:
ab -c 5000 -n 1000000 'http://10.71.183.167/question.js'
rpm -qf /usr/bin/nload
nload-0.7.4-1.el6.x86_64
ab压测了一下10.70.62.28(就是白天压测掉的厉害的那台),测试结果我觉得挺好的。
并发4000,完成100w请求
cpu负载5左右浮动
Complete requests: 1000000
Failed requests: 21659
请求失败数是21659,计算了一下,100个人里有2个人失败
Requests per second: 5986.29 [#/sec] (mean) 相当于LR中的tps,几乎就是6000了
Time per request: 668.193 [ms] (mean) 用户等待每个请求时间,668毫秒
Time per request: 0.167 [ms] 服务器处理每个请求时间 0.167毫秒
网卡流量-取最大值
进-112Mbps
出-86Mbps
单独统计了一下nginx日志中http状态
"200" 978350
"500" 21664
状态码是500有21664,符合ab的测试结果中的 Failed requests: 21659
单独以ip地址建的web虚机,压测的产生的ngxin访问日志、错误日志也是单独的,就是为了统计一下http状态码的数量,然后和ab结果进行对比。
__________________________________________
apache压力测试ab
ab是Apache超文本传输协议(HTTP)的性能测试工具。其设计意图是描绘当前所安装的Apache的执行性能,主要是显示你安装的Apache每秒可以处理多少个请求
ab是Apache超文本传输协议(HTTP)的性能测试工具。其设计意图是描绘当前所安装的Apache的执行性能,主要是显示你安装的Apache每秒可以处理多少个请求。
概要
ab [ -A auth-username ] [ -c concurrency ] [ -C cookie-name=value ] [ -d ] [ -e csv-file ] [ -g gnuplot-file ] [ -h ] [ -H custom-header ] [ -i ] [ -k ] [ -n requests ] [ -p POST-file ] [ -P proxy-auth-username ] [ -q ] [ -s ] [ -S ] [ -t timelimit ] [ -T content-type ] [ -v verbosity] [ -V ] [ -w ] [ -x <table>-attributes ] [ -X proxy[] ] [ -y <tr>-attributes ] [ -z <td>-attributes ] [http://]hostname[:port]/path
选项
-A auth-username:password
对服务器提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。无论服务器是否需要(即, 是否发送了401认证需求代码),此字符串都会被发送。
-c concurrency
一次产生的请求个数。默认是一次一个。
-C cookie-name=value
对请求附加一个Cookie:行。 其典型形式是name=value的一个参数对。此参数可以重复。
-d
不显示"percentage served within XX [ms] table"的消息(为以前的版本提供支持)。
-e csv-file
产生一个以逗号分隔的(CSV)文件,其中包含了处理每个相应百分比的请求所需要(从1%到100%)的相应百分比的(以微妙为单位)时间。由于这种格式已经“二进制化”,所以比'gnuplot'格式更有用。
-g gnuplot-file
把所有测试结果写入一个'gnuplot'或者TSV (以Tab分隔的)文件。此文件可以方便地导入到Gnuplot, IDL, Mathematica, Igor甚至Excel中。其中的第一行为标题。
-h
显示使用方法。
-H custom-header
对请求附加额外的头信息。此参数的典型形式是一个有效的头信息行,其中包含了以冒号分隔的字段和值的对 (如, "Accept-Encoding: zip/zop;8bit").
-i
执行HEAD请求,而不是GET。
-k
启用HTTP KeepAlive功能,即, 在一个HTTP会话中执行多个请求。默认时,不启用KeepAlive功能.
-n requests
在测试会话中所执行的请求个数。默认时,仅执行一个请求,但通常其结果不具有代表意义。
-p POST-file
包含了需要POST的数据的文件.
-P proxy-auth-username:password
对一个中转代理提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。无论服务器是否需要(即, 是否发送了401认证需求代码),此字符串都会被发送。
-q
如果处理的请求数大于150, ab每处理大约10%或者100个请求时,会在stderr输出一个进度计数。此-q标记可以抑制这些信息。
-s
用于编译中(ab -h会显示相关信息)使用了SSL的受保护的https,而不是http协议的时候。此功能是实验性的,也是很简陋的。最好不要用。
-S
不显示中值和标准背离值,而且在均值和中值为标准背离值的1到2倍时,也不显示警告或出错信息。默认时,会显示最小值/均值/最大值等数值。(为以前的版本提供支持).
-t timelimit
测试所进行的最大秒数。其内部隐含值是-n 50000。它可以使对服务器的测试限制在一个固定的总时间以内。默认时,没有时间限制。
-T content-type
POST数据所使用的Content-type头信息。
-v verbosity
设置显示信息的详细程度 - 4或更大值会显示头信息, 3或更大值可以显示响应代码(404, 200等), 2或更大值可以显示警告和其他信息。
-V
显示版本号并退出。
-w
以HTML表的格式输出结果。默认时,它是白色背景的两列宽度的一张表。
-x <table>-attributes
设置<table>属性的字符串。 此属性被填入<table 这里 >.
-X proxy[:port]
对请求使用代理服务器。
-y <tr>-attributes
设置<tr>属性的字符串.
-z <td>-attributes
设置<td>属性的字符串.
缺陷
程序中有各种静态声明的固定长度的缓冲区。另外,对命令行参数、服务器的响应头和其他外部输入的解析也很简单,这可能会有不良后果。
它没有完整地实现HTTP/1.x; 仅接受某些'预想'的响应格式。 strstr(3)的频繁使用可能会带来性能问题,即, 你可能是在测试ab而不是服务器的性能。
----------------------------------------------------------------------------------------------------------------------
ex: 要執行 1000 次的 connection, 20 次的 concurrent (並行, 同時).
語法: ab -n 1000 -c 20 http://localhost/abc.php
產生出來的結果. 主要要注意的是以下幾個.
Time taken for tests: 總共執行花了多久的時間.(以上 1000 次共多久)
Requests per second: 每秒平均可以處理多少個 connection.
假设我们要对 echo.fcg 做测试,仿真 1000 次的联机请求,而且同一时间有 20 个并行的 (concurrent) 联机请求的情况,只要在命令列模式下执行 $ ab -n 1000 -c 20 http://localhost/fcgi-bin/echo.fcg 稍等一会,ApacheBench 会把结果秀出来,
This is ApacheBench, Version 1.3 Copyright c 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright c 1998-1999 The Apache Group, http://www.apache.org/ Benchmarking localhost (be patient)...
Server Software: Apache/1.3.6
Server Hostname: localhost
Server Port: 80
Document Path: /fcgi-bin/echo.fcg
Document Length: 995 bytes
Concurrency Level: 20
Time taken for tests: 6.859 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 1142000 bytes HTML transferred: 995000 bytes
Requests per second: 145.79
Transfer rate: 166.50 kb/s received Connnection Times (ms) min avg
max Connect: 0 4 61
Processing: 62 128 771
Total: 62 132 832
以上结果指出,在同时间 20 个联机请求 (Concurrency Level) 的情况下,完成 1000 次的联机请求,共花了 6.859 秒 (Time taken for tests),因此这个程序每秒平均可以处理 (Requests per second) 145.79 个联机请求。 在接下来的评比测试中,我们就以每秒可以处理的联机请求数目来做为效能评比的依据。
5000并发,请求数100w
ab -c 5000 -n 1000000 'http://10.70.62.28/riddle.php?iid=56764&qid=56866&uid=1
&reply=56867,56868'
5000并发,请求数100w:
ab -c 5000 -n 1000000 'http://10.71.183.167/question.js'
rpm -qf /usr/bin/nload
nload-0.7.4-1.el6.x86_64
ab压测了一下10.70.62.28(就是白天压测掉的厉害的那台),测试结果我觉得挺好的。
并发4000,完成100w请求
cpu负载5左右浮动
Complete requests: 1000000
Failed requests: 21659
请求失败数是21659,计算了一下,100个人里有2个人失败
Requests per second: 5986.29 [#/sec] (mean) 相当于LR中的tps,几乎就是6000了
Time per request: 668.193 [ms] (mean) 用户等待每个请求时间,668毫秒
Time per request: 0.167 [ms] 服务器处理每个请求时间 0.167毫秒
网卡流量-取最大值
进-112Mbps
出-86Mbps
单独统计了一下nginx日志中http状态
"200" 978350
"500" 21664
状态码是500有21664,符合ab的测试结果中的 Failed requests: 21659
单独以ip地址建的web虚机,压测的产生的ngxin访问日志、错误日志也是单独的,就是为了统计一下http状态码的数量,然后和ab结果进行对比。
__________________________________________
apache压力测试ab
ab是Apache超文本传输协议(HTTP)的性能测试工具。其设计意图是描绘当前所安装的Apache的执行性能,主要是显示你安装的Apache每秒可以处理多少个请求
ab是Apache超文本传输协议(HTTP)的性能测试工具。其设计意图是描绘当前所安装的Apache的执行性能,主要是显示你安装的Apache每秒可以处理多少个请求。
概要
ab [ -A auth-username ] [ -c concurrency ] [ -C cookie-name=value ] [ -d ] [ -e csv-file ] [ -g gnuplot-file ] [ -h ] [ -H custom-header ] [ -i ] [ -k ] [ -n requests ] [ -p POST-file ] [ -P proxy-auth-username ] [ -q ] [ -s ] [ -S ] [ -t timelimit ] [ -T content-type ] [ -v verbosity] [ -V ] [ -w ] [ -x <table>-attributes ] [ -X proxy[] ] [ -y <tr>-attributes ] [ -z <td>-attributes ] [http://]hostname[:port]/path
选项
-A auth-username:password
对服务器提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。无论服务器是否需要(即, 是否发送了401认证需求代码),此字符串都会被发送。
-c concurrency
一次产生的请求个数。默认是一次一个。
-C cookie-name=value
对请求附加一个Cookie:行。 其典型形式是name=value的一个参数对。此参数可以重复。
-d
不显示"percentage served within XX [ms] table"的消息(为以前的版本提供支持)。
-e csv-file
产生一个以逗号分隔的(CSV)文件,其中包含了处理每个相应百分比的请求所需要(从1%到100%)的相应百分比的(以微妙为单位)时间。由于这种格式已经“二进制化”,所以比'gnuplot'格式更有用。
-g gnuplot-file
把所有测试结果写入一个'gnuplot'或者TSV (以Tab分隔的)文件。此文件可以方便地导入到Gnuplot, IDL, Mathematica, Igor甚至Excel中。其中的第一行为标题。
-h
显示使用方法。
-H custom-header
对请求附加额外的头信息。此参数的典型形式是一个有效的头信息行,其中包含了以冒号分隔的字段和值的对 (如, "Accept-Encoding: zip/zop;8bit").
-i
执行HEAD请求,而不是GET。
-k
启用HTTP KeepAlive功能,即, 在一个HTTP会话中执行多个请求。默认时,不启用KeepAlive功能.
-n requests
在测试会话中所执行的请求个数。默认时,仅执行一个请求,但通常其结果不具有代表意义。
-p POST-file
包含了需要POST的数据的文件.
-P proxy-auth-username:password
对一个中转代理提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。无论服务器是否需要(即, 是否发送了401认证需求代码),此字符串都会被发送。
-q
如果处理的请求数大于150, ab每处理大约10%或者100个请求时,会在stderr输出一个进度计数。此-q标记可以抑制这些信息。
-s
用于编译中(ab -h会显示相关信息)使用了SSL的受保护的https,而不是http协议的时候。此功能是实验性的,也是很简陋的。最好不要用。
-S
不显示中值和标准背离值,而且在均值和中值为标准背离值的1到2倍时,也不显示警告或出错信息。默认时,会显示最小值/均值/最大值等数值。(为以前的版本提供支持).
-t timelimit
测试所进行的最大秒数。其内部隐含值是-n 50000。它可以使对服务器的测试限制在一个固定的总时间以内。默认时,没有时间限制。
-T content-type
POST数据所使用的Content-type头信息。
-v verbosity
设置显示信息的详细程度 - 4或更大值会显示头信息, 3或更大值可以显示响应代码(404, 200等), 2或更大值可以显示警告和其他信息。
-V
显示版本号并退出。
-w
以HTML表的格式输出结果。默认时,它是白色背景的两列宽度的一张表。
-x <table>-attributes
设置<table>属性的字符串。 此属性被填入<table 这里 >.
-X proxy[:port]
对请求使用代理服务器。
-y <tr>-attributes
设置<tr>属性的字符串.
-z <td>-attributes
设置<td>属性的字符串.
缺陷
程序中有各种静态声明的固定长度的缓冲区。另外,对命令行参数、服务器的响应头和其他外部输入的解析也很简单,这可能会有不良后果。
它没有完整地实现HTTP/1.x; 仅接受某些'预想'的响应格式。 strstr(3)的频繁使用可能会带来性能问题,即, 你可能是在测试ab而不是服务器的性能。
----------------------------------------------------------------------------------------------------------------------
ex: 要執行 1000 次的 connection, 20 次的 concurrent (並行, 同時).
語法: ab -n 1000 -c 20 http://localhost/abc.php
產生出來的結果. 主要要注意的是以下幾個.
Time taken for tests: 總共執行花了多久的時間.(以上 1000 次共多久)
Requests per second: 每秒平均可以處理多少個 connection.
假设我们要对 echo.fcg 做测试,仿真 1000 次的联机请求,而且同一时间有 20 个并行的 (concurrent) 联机请求的情况,只要在命令列模式下执行 $ ab -n 1000 -c 20 http://localhost/fcgi-bin/echo.fcg 稍等一会,ApacheBench 会把结果秀出来,
This is ApacheBench, Version 1.3 Copyright c 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Copyright c 1998-1999 The Apache Group, http://www.apache.org/ Benchmarking localhost (be patient)...
Server Software: Apache/1.3.6
Server Hostname: localhost
Server Port: 80
Document Path: /fcgi-bin/echo.fcg
Document Length: 995 bytes
Concurrency Level: 20
Time taken for tests: 6.859 seconds
Complete requests: 1000
Failed requests: 0
Total transferred: 1142000 bytes HTML transferred: 995000 bytes
Requests per second: 145.79
Transfer rate: 166.50 kb/s received Connnection Times (ms) min avg
max Connect: 0 4 61
Processing: 62 128 771
Total: 62 132 832
以上结果指出,在同时间 20 个联机请求 (Concurrency Level) 的情况下,完成 1000 次的联机请求,共花了 6.859 秒 (Time taken for tests),因此这个程序每秒平均可以处理 (Requests per second) 145.79 个联机请求。 在接下来的评比测试中,我们就以每秒可以处理的联机请求数目来做为效能评比的依据。
正则表达式用于字符串处理、表单验证等场合,实用高效。现将一些常用的表达式收集于此,以备不时之需。
匹配中文字符的正则表达式: [\u4e00-\u9fa5]
评注:匹配中文还真是个头疼的事,有了这个表达式就好办了
匹配双字节字符(包括汉字在内):[^\x00-\xff]
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
匹配空白行的正则表达式:\n\s*\r
评注:可以用来删除空白行
匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?|<.*? />
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力
匹配首尾空白字符的正则表达式:^\s*|\s*$
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
评注:表单验证时很实用
匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*
评注:网上流传的版本功能很有限,上面这个基本可以满足需求
匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
评注:表单验证时很实用
匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
评注:匹配形式如 0511-4405222 或 021-87888822
匹配腾讯QQ号:[1-9][0-9]{4,}
评注:腾讯QQ号从10000开始
匹配中国邮政编码:[1-9]\d{5}(?!\d)
评注:中国邮政编码为6位数字
匹配身份证:\d{15}|\d{18}
评注:中国的身份证为15位或18位
匹配ip地址:\d+\.\d+\.\d+\.\d+
评注:提取ip地址时有用
匹配特定数字:
^[1-9]\d*$ //匹配正整数
^-[1-9]\d*$ //匹配负整数
^-?[1-9]\d*$ //匹配整数
^[1-9]\d*|0$ //匹配非负整数(正整数 + 0)
^-[1-9]\d*|0$ //匹配非正整数(负整数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ //匹配非负浮点数(正浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ //匹配非正浮点数(负浮点数 + 0)
评注:处理大量数据时有用,具体应用时注意修正
匹配特定字符串:
^[A-Za-z]+$ //匹配由26个英文字母组成的字符串
^[A-Z]+$ //匹配由26个英文字母的大写组成的字符串
^[a-z]+$ //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$ //匹配由数字和26个英文字母组成的字符串
^\w+$ //匹配由数字、26个英文字母或者下划线组成的字符串
评注:最基本也是最常用的一些表达式
许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符“转义”,即,将反斜杠字符 (\) 放在它们前面。下表列出了特殊字符以及它们的含义:
$ 匹配输入字符串结尾的位置。
如果设置了 RegExp 对象的 Multiline 属性,那么 $ 还匹配 \n 或 \r 前面的位置。若要匹配 $ 字符本身,请使用 \$。
( ) 标记子表达式的开始和结束。可以捕获子表达式以供以后使用。
若要匹配这两个字符,请使用 \( 和 \)。
* 零次或多次匹配前面的字符或子表达式。
若要匹配 * 字符,请使用 \*。
+ 一次或多次匹配前面的字符或子表达式。
若要匹配 + 字符,请使用 \+。
. 匹配除换行符 \n 之外的任何单个字符。
若要匹配 .,请使用 \。
[ ] 标记中括号表达式的开始。
若要匹配这些字符,请使用 \[ 和 \]。
? 零次或一次匹配前面的字符或子表达式,或指示“非贪心”限定符。
若要匹配 ? 字符,请使用 \?。
\ 将下一字符标记为特殊字符、文本、反向引用或八进制转义符。
例如,字符 n 匹配字符 n。\n 匹配换行符。序列 \\ 匹配 \,序列 \( 匹配 (。
/ 表示文本正则表达式的开始或结束。
若要匹配 / 字符,请使用 \/。
^ 匹配输入字符串开始处的位置,但在中括号表达式中使用的情况除外,在那种情况下它对字符集求反。
若要匹配 ^ 字符本身,请使用 \^。
{ } 标记限定符表达式的开始。
若要匹配这些字符,请使用 \{ 和 \}。
| 指出在两个项之间进行选择。
若要匹配 | ,请使用 \|
preg_match() 返回 pattern 所匹配的次数。要么是 0 次(没有匹配)或 1 次,因为 preg_match() 在第一次匹配之后将停止搜索。preg_match_all() 则相反,会一直搜索到 subject 的结尾处。如果出错 preg_match() 返回 FALSE。
提示:
如果只想查看一个字符串是否包含在另一个字符串中,不要用 preg_match()。可以用 strpos() 或 strstr() 替代,要快得多。
例1609.在文本中搜索“php”
copy to clipboard
<?php
// 模式定界符后面的 "i" 表示不区分大小写字母的搜索
if (preg_match ("/php/i", "PHP is the web scripting language of choice.")) {
print "A match was found.";
} else {
print "A match was not found.";
}
?>
例1610.搜索单词“web”
copy to clipboard
<?php
/* 模式中的 \b 表示单词的边界,因此只有独立的 "web" 单词会被匹配,
* 而不会匹配例如 "webbing" 或 "cobweb" 中的一部分 */
if (preg_match ("/\bweb\b/i", "PHP is the web scripting language of choice.")) {
print "A match was found.";
} else {
print "A match was not found.";
}
if (preg_match ("/\bweb\b/i", "PHP is the website scripting language of choice.")) {
print "A match was found.";
} else {
print "A match was not found.";
}
?>
例1611.从 URL 中取出域名
copy to clipboard
<?php
// 从 URL 中取得主机名
preg_match("/^(http:\/\/)?([^\/]+)/i",
"http://www.php.net/index.html", $matches);
$host = $matches[2];
// 从主机名中取得后面两段
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
echo "domain name is: {$matches[0]}\n";
?>
匹配中文字符的正则表达式: [\u4e00-\u9fa5]
评注:匹配中文还真是个头疼的事,有了这个表达式就好办了
匹配双字节字符(包括汉字在内):[^\x00-\xff]
评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
匹配空白行的正则表达式:\n\s*\r
评注:可以用来删除空白行
匹配HTML标记的正则表达式:<(\S*?)[^>]*>.*?|<.*? />
评注:网上流传的版本太糟糕,上面这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力
匹配首尾空白字符的正则表达式:^\s*|\s*$
评注:可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式
匹配Email地址的正则表达式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
评注:表单验证时很实用
匹配网址URL的正则表达式:[a-zA-z]+://[^\s]*
评注:网上流传的版本功能很有限,上面这个基本可以满足需求
匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
评注:表单验证时很实用
匹配国内电话号码:\d{3}-\d{8}|\d{4}-\d{7}
评注:匹配形式如 0511-4405222 或 021-87888822
匹配腾讯QQ号:[1-9][0-9]{4,}
评注:腾讯QQ号从10000开始
匹配中国邮政编码:[1-9]\d{5}(?!\d)
评注:中国邮政编码为6位数字
匹配身份证:\d{15}|\d{18}
评注:中国的身份证为15位或18位
匹配ip地址:\d+\.\d+\.\d+\.\d+
评注:提取ip地址时有用
匹配特定数字:
^[1-9]\d*$ //匹配正整数
^-[1-9]\d*$ //匹配负整数
^-?[1-9]\d*$ //匹配整数
^[1-9]\d*|0$ //匹配非负整数(正整数 + 0)
^-[1-9]\d*|0$ //匹配非正整数(负整数 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ //匹配正浮点数
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ //匹配负浮点数
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ //匹配浮点数
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ //匹配非负浮点数(正浮点数 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ //匹配非正浮点数(负浮点数 + 0)
评注:处理大量数据时有用,具体应用时注意修正
匹配特定字符串:
^[A-Za-z]+$ //匹配由26个英文字母组成的字符串
^[A-Z]+$ //匹配由26个英文字母的大写组成的字符串
^[a-z]+$ //匹配由26个英文字母的小写组成的字符串
^[A-Za-z0-9]+$ //匹配由数字和26个英文字母组成的字符串
^\w+$ //匹配由数字、26个英文字母或者下划线组成的字符串
评注:最基本也是最常用的一些表达式
许多元字符要求在试图匹配它们时特别对待。若要匹配这些特殊字符,必须首先使字符“转义”,即,将反斜杠字符 (\) 放在它们前面。下表列出了特殊字符以及它们的含义:
$ 匹配输入字符串结尾的位置。
如果设置了 RegExp 对象的 Multiline 属性,那么 $ 还匹配 \n 或 \r 前面的位置。若要匹配 $ 字符本身,请使用 \$。
( ) 标记子表达式的开始和结束。可以捕获子表达式以供以后使用。
若要匹配这两个字符,请使用 \( 和 \)。
* 零次或多次匹配前面的字符或子表达式。
若要匹配 * 字符,请使用 \*。
+ 一次或多次匹配前面的字符或子表达式。
若要匹配 + 字符,请使用 \+。
. 匹配除换行符 \n 之外的任何单个字符。
若要匹配 .,请使用 \。
[ ] 标记中括号表达式的开始。
若要匹配这些字符,请使用 \[ 和 \]。
? 零次或一次匹配前面的字符或子表达式,或指示“非贪心”限定符。
若要匹配 ? 字符,请使用 \?。
\ 将下一字符标记为特殊字符、文本、反向引用或八进制转义符。
例如,字符 n 匹配字符 n。\n 匹配换行符。序列 \\ 匹配 \,序列 \( 匹配 (。
/ 表示文本正则表达式的开始或结束。
若要匹配 / 字符,请使用 \/。
^ 匹配输入字符串开始处的位置,但在中括号表达式中使用的情况除外,在那种情况下它对字符集求反。
若要匹配 ^ 字符本身,请使用 \^。
{ } 标记限定符表达式的开始。
若要匹配这些字符,请使用 \{ 和 \}。
| 指出在两个项之间进行选择。
若要匹配 | ,请使用 \|
preg_match() 返回 pattern 所匹配的次数。要么是 0 次(没有匹配)或 1 次,因为 preg_match() 在第一次匹配之后将停止搜索。preg_match_all() 则相反,会一直搜索到 subject 的结尾处。如果出错 preg_match() 返回 FALSE。
提示:
如果只想查看一个字符串是否包含在另一个字符串中,不要用 preg_match()。可以用 strpos() 或 strstr() 替代,要快得多。
例1609.在文本中搜索“php”
copy to clipboard
<?php
// 模式定界符后面的 "i" 表示不区分大小写字母的搜索
if (preg_match ("/php/i", "PHP is the web scripting language of choice.")) {
print "A match was found.";
} else {
print "A match was not found.";
}
?>
例1610.搜索单词“web”
copy to clipboard
<?php
/* 模式中的 \b 表示单词的边界,因此只有独立的 "web" 单词会被匹配,
* 而不会匹配例如 "webbing" 或 "cobweb" 中的一部分 */
if (preg_match ("/\bweb\b/i", "PHP is the web scripting language of choice.")) {
print "A match was found.";
} else {
print "A match was not found.";
}
if (preg_match ("/\bweb\b/i", "PHP is the website scripting language of choice.")) {
print "A match was found.";
} else {
print "A match was not found.";
}
?>
例1611.从 URL 中取出域名
copy to clipboard
<?php
// 从 URL 中取得主机名
preg_match("/^(http:\/\/)?([^\/]+)/i",
"http://www.php.net/index.html", $matches);
$host = $matches[2];
// 从主机名中取得后面两段
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
echo "domain name is: {$matches[0]}\n";
?>
在对正则表达式有了较为全面的了解之后,就可以在Perl,PHP,以及ASP等程式中使用正则表达式了。
下面以PHP语言为例,使用验证用户在线输入的邮件地址以及网址的格式是否正确。PHP 提供了eregi()或ereg()资料处理函数实现字串比对剖析的模式匹配操作ereg()函数的使用格式如下:
ereg (pattern, string)
其中,pattern代表正则表达式的模式;而string则是执行查找替换操作的目标对象,如Email地址值。本函式以 pattern 的规则来剖析比对字串 string,找到则传回值为 true。函式ereg()与eregi()的区别就是前者区分大小写,后者与大小写无关。使用PHP编写的程序代码如下:
<?php
if (ereg("^([a-z0-9_-])+@([a-zZ0-9_-])+(\.[a-z0-9_-])+[a-z]{2,3}$",$email))
{ echo "您的 E-Mail 通过初步检查!";}
else
{ echo "不是合法的E-Mail 地址,请重新输入!";}
?>
这个例子是可对使用者输入的 E-Mail 作简单的检查,检查使用者的 E-Mail 字串是否有 @ 字元,在 @ 字元前有小写英文字母、数字或下"_",在 @ 之后有数节字串,最后的小数点后只能有二个或三个小写英文字母。如webmaster@mail.sever.net, hello_2001@88new.cn就可以通过检查,而New99@253.com(出现大写字母)和new99@253.comn(最后的小数点后只能超过3个英文字母)就不能通过检查。
我们通过调用自定义正规则判别函式也可以进行检查操作,如下面的网址检验函式:
function VerifyWebSiteAddr ($strWebSiteAddr){
return (eregi ("^([_0-9a-z-]+.)+([0-9a-z-]+.)+[a-z]{2,3}$", $strWebSiteAddr));
}
我们知道,PHP程式的运行必须有服务器支持,如果您在自己的主页上想实现以上功能, 嵌入式脚本语言Javascript或许是好的选择。Javascript中带有一个功能强大的RegExp()对象,可以用来进行正则表达式的匹配操作。其中的test()方法可以检验目标对象中是否包含匹配模式,并相应的返回true或false。只须在HTML文档的<head>区域添加一段Javascript代码。
< language="Javascript1.2">
function verifyAddress(obj){
var email = obj.email.value;
var pattern = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;
flag = pattern.test(email);
if(flag){
alert("您的 E-Mail 通过初步检查!");
return true;}
else{
alert("不是合法的E-Mail 地址,请重新输入!");
return false;}
}
</script>
然后在网页中输入信息的表单域<form>标签区域内中加入一行如下代码:
<onSubmit="return verifyAddress(this);">
当按下提交按钮后,首先运行verifyAddress()函式,进行匹配识别,如果满足条件则发送表单信息到目标页面,否则返回错误信息。
事实上,正则表达式的功能远非本文提到的这一点,下次,给大家介绍一种使用正则表达式从任意指定网页中析取任意种类文本信息(如网页中所有的图片文件名)的技巧。
Html源文件中image标签的析取
上篇,我们介绍了正则表达式的概念及其在网络编程中使用正则表达式验证用户在线输入的邮件地址以及网址的格式是否正确的应用实例,今天介绍一种从指定网页源文件中析取image标签的的编程技巧,即从网页源文件中,解析出所有的插图文件名(包括图片路径),也就是标签<img src=http://www.host01.com/Get/asp/regex/".../.../abc.jpg"> 中的文件名http://www.host01.com/Get/asp/regex/".../.../abc.jpg"(有的可能是gif格式)。编程环境:PHP+Apache for Win98。
首先, 用文本编辑器新建一个PHP类型的文件:abstractSRCfrompage.php3。为了方便讲解,我们打算是在浏览器表单域中输入需要析取image标签的网页的URL(或本机文档),提交后执行析取操作,所以在该文件中,我们要建立一个用于输入网址的表单,举例如下:
<form action=" abstractSRCfrompage.php3" method="post">
输入网址<input type=text name=filename><br>
<input type=submit name=submit value="提交">
</form>
输入正确的网址,提交后表单信息被送到abstractSRCfrompage.php3页面,由于表单本身就在该页面,所以相当于被送到自身页面,下面我们需要编写析取处理的PHP代码,紧接着表单代码段后写入如下代码:
<?php
if ($filename!=""){
$fp = fopen($filename, "r"); file://若输入不为空,开启本地或者远程档案;
while ($buffer = fgets($fp, 1024)) {
$source .=$buffer; }
fclose($fp);
file://查找$source中是否有<img ...src=http://www.host01.com/Get/asp/regex/".../...gif | jpg"> 这样的标记
if(eregi("(<img)+[^<>]+(src=\")+[^\*\"<>|]+(\.)+((gif)|(jpg))+(\")",$source)) {
echo "找到图片标签:)<br>";}
else{
echo "未发现图片标签:(<br>";}
file://拆分,第一次用标签,<img ...src=拆分,得到了以图形文件名开头的数组,
$splitres=split("((\">)|())+(<img)+[^<>]+(src=\")",$source);
echo "找到: $imagenums-1个图片<br>分别为:<br>";
for($i=1;$i<sizeof($splitres);$i++){
file://二次拆分,用"拆分。因为文件名能含有",得到的拆分数组的第一个元素就是路径+文件名了;
unset($imgname); // 再次使用前删除imgname变量;
$imgname=spliti("\"",$splitres[$i]);//将析取的图片信息依次赋给imgname变量
echo "$i=>".$imgname[0]."<br>"; file://输出析取的图片信息
}
}
?>
该段程序的设计思路是:PHP程式判断是否输入了档案名称(网址URL或本机档案名),若不为空则以只读方式打开该档案;接着使用函式fgets(fp,length)取得档案指标fp所指的行并传回该行内长度为length-1 的字串,上例中就是1024-1=1023;然后利用字串比对剖析函式ereg()查找$source中是否含有<img ...src=http://www.host01.com/Get/asp/regex/".../...gif | jpg"> 这样的标记(关于该函式在上篇中有详细的介绍);假如找到的话,则利用split()函式按一定的规则执行两次拆分,去掉标记中的<img…src=字符和"字符,结果得到数组splitres,其中的每一个元素都是以图形路径+文件名开头的数组;用for循环在屏幕上输出每个数组的第一个元素值,即我们所需要的所有图形路径+文件名。
其中函式sizeof($splitres)返回个数;在for循环中,依次将数组splitres的每个元素(也是数组)赋给数组变量imgname,并输出imgname的第一个元素值(为找到的一个图形路径+文件名),当执行下次循环时,删除变量imgname,达到重复使用的目的。大家可以仔细研究其中的奥妙。
好了,写好后,将abstractSRCfrompage.php3存到你的服务器指定目录下,启动Apache服务器,在浏览器中打开它,随便输入一个存在的网页名称或是远程URL,看看效果如何。
如果有兴趣,你可以尝试析取HTML文档中的任意感兴趣的信息,如果稍加改装,做一个网站文本搜索引擎岂不更妙?
下面以PHP语言为例,使用验证用户在线输入的邮件地址以及网址的格式是否正确。PHP 提供了eregi()或ereg()资料处理函数实现字串比对剖析的模式匹配操作ereg()函数的使用格式如下:
ereg (pattern, string)
其中,pattern代表正则表达式的模式;而string则是执行查找替换操作的目标对象,如Email地址值。本函式以 pattern 的规则来剖析比对字串 string,找到则传回值为 true。函式ereg()与eregi()的区别就是前者区分大小写,后者与大小写无关。使用PHP编写的程序代码如下:
<?php
if (ereg("^([a-z0-9_-])+@([a-zZ0-9_-])+(\.[a-z0-9_-])+[a-z]{2,3}$",$email))
{ echo "您的 E-Mail 通过初步检查!";}
else
{ echo "不是合法的E-Mail 地址,请重新输入!";}
?>
这个例子是可对使用者输入的 E-Mail 作简单的检查,检查使用者的 E-Mail 字串是否有 @ 字元,在 @ 字元前有小写英文字母、数字或下"_",在 @ 之后有数节字串,最后的小数点后只能有二个或三个小写英文字母。如webmaster@mail.sever.net, hello_2001@88new.cn就可以通过检查,而New99@253.com(出现大写字母)和new99@253.comn(最后的小数点后只能超过3个英文字母)就不能通过检查。
我们通过调用自定义正规则判别函式也可以进行检查操作,如下面的网址检验函式:
function VerifyWebSiteAddr ($strWebSiteAddr){
return (eregi ("^([_0-9a-z-]+.)+([0-9a-z-]+.)+[a-z]{2,3}$", $strWebSiteAddr));
}
我们知道,PHP程式的运行必须有服务器支持,如果您在自己的主页上想实现以上功能, 嵌入式脚本语言Javascript或许是好的选择。Javascript中带有一个功能强大的RegExp()对象,可以用来进行正则表达式的匹配操作。其中的test()方法可以检验目标对象中是否包含匹配模式,并相应的返回true或false。只须在HTML文档的<head>区域添加一段Javascript代码。
< language="Javascript1.2">
function verifyAddress(obj){
var email = obj.email.value;
var pattern = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;
flag = pattern.test(email);
if(flag){
alert("您的 E-Mail 通过初步检查!");
return true;}
else{
alert("不是合法的E-Mail 地址,请重新输入!");
return false;}
}
</script>
然后在网页中输入信息的表单域<form>标签区域内中加入一行如下代码:
<onSubmit="return verifyAddress(this);">
当按下提交按钮后,首先运行verifyAddress()函式,进行匹配识别,如果满足条件则发送表单信息到目标页面,否则返回错误信息。
事实上,正则表达式的功能远非本文提到的这一点,下次,给大家介绍一种使用正则表达式从任意指定网页中析取任意种类文本信息(如网页中所有的图片文件名)的技巧。
Html源文件中image标签的析取
上篇,我们介绍了正则表达式的概念及其在网络编程中使用正则表达式验证用户在线输入的邮件地址以及网址的格式是否正确的应用实例,今天介绍一种从指定网页源文件中析取image标签的的编程技巧,即从网页源文件中,解析出所有的插图文件名(包括图片路径),也就是标签<img src=http://www.host01.com/Get/asp/regex/".../.../abc.jpg"> 中的文件名http://www.host01.com/Get/asp/regex/".../.../abc.jpg"(有的可能是gif格式)。编程环境:PHP+Apache for Win98。
首先, 用文本编辑器新建一个PHP类型的文件:abstractSRCfrompage.php3。为了方便讲解,我们打算是在浏览器表单域中输入需要析取image标签的网页的URL(或本机文档),提交后执行析取操作,所以在该文件中,我们要建立一个用于输入网址的表单,举例如下:
<form action=" abstractSRCfrompage.php3" method="post">
输入网址<input type=text name=filename><br>
<input type=submit name=submit value="提交">
</form>
输入正确的网址,提交后表单信息被送到abstractSRCfrompage.php3页面,由于表单本身就在该页面,所以相当于被送到自身页面,下面我们需要编写析取处理的PHP代码,紧接着表单代码段后写入如下代码:
<?php
if ($filename!=""){
$fp = fopen($filename, "r"); file://若输入不为空,开启本地或者远程档案;
while ($buffer = fgets($fp, 1024)) {
$source .=$buffer; }
fclose($fp);
file://查找$source中是否有<img ...src=http://www.host01.com/Get/asp/regex/".../...gif | jpg"> 这样的标记
if(eregi("(<img)+[^<>]+(src=\")+[^\*\"<>|]+(\.)+((gif)|(jpg))+(\")",$source)) {
echo "找到图片标签:)<br>";}
else{
echo "未发现图片标签:(<br>";}
file://拆分,第一次用标签,<img ...src=拆分,得到了以图形文件名开头的数组,
$splitres=split("((\">)|())+(<img)+[^<>]+(src=\")",$source);
echo "找到: $imagenums-1个图片<br>分别为:<br>";
for($i=1;$i<sizeof($splitres);$i++){
file://二次拆分,用"拆分。因为文件名能含有",得到的拆分数组的第一个元素就是路径+文件名了;
unset($imgname); // 再次使用前删除imgname变量;
$imgname=spliti("\"",$splitres[$i]);//将析取的图片信息依次赋给imgname变量
echo "$i=>".$imgname[0]."<br>"; file://输出析取的图片信息
}
}
?>
该段程序的设计思路是:PHP程式判断是否输入了档案名称(网址URL或本机档案名),若不为空则以只读方式打开该档案;接着使用函式fgets(fp,length)取得档案指标fp所指的行并传回该行内长度为length-1 的字串,上例中就是1024-1=1023;然后利用字串比对剖析函式ereg()查找$source中是否含有<img ...src=http://www.host01.com/Get/asp/regex/".../...gif | jpg"> 这样的标记(关于该函式在上篇中有详细的介绍);假如找到的话,则利用split()函式按一定的规则执行两次拆分,去掉标记中的<img…src=字符和"字符,结果得到数组splitres,其中的每一个元素都是以图形路径+文件名开头的数组;用for循环在屏幕上输出每个数组的第一个元素值,即我们所需要的所有图形路径+文件名。
其中函式sizeof($splitres)返回个数;在for循环中,依次将数组splitres的每个元素(也是数组)赋给数组变量imgname,并输出imgname的第一个元素值(为找到的一个图形路径+文件名),当执行下次循环时,删除变量imgname,达到重复使用的目的。大家可以仔细研究其中的奥妙。
好了,写好后,将abstractSRCfrompage.php3存到你的服务器指定目录下,启动Apache服务器,在浏览器中打开它,随便输入一个存在的网页名称或是远程URL,看看效果如何。
如果有兴趣,你可以尝试析取HTML文档中的任意感兴趣的信息,如果稍加改装,做一个网站文本搜索引擎岂不更妙?
在这里我想总结一下取得地址栏内URL及文件所属的我更路径的一些信息:
运用$_SERVER[ ]我们可以来完成许多事情:它是一个包含头部(headers),路径信息及脚本位置的数组,数组的实体由web服务器创建。
这是一个“superglobal”,或者可以描述为自动全局变量。这只不过意味这它在所有的脚本中都有效。在函数或方法中您不需要使用global $_SERVER; 访问它,就如同使用 $HTTP_SERVER_VARS 一样。 $HTTP_SERVER_VARS 包含着同样的信息,但是不是一个自动全局变量。(注意: $HTTP_SERVER_VARS 和 $_SERVER 是不同的变量,PHP 处理它们的方式不同。)如果设置了 register_globals 指令,这些变量也在所有脚本中可用;也就是,分离了 $_SERVER 和 $HTTP_SERVER_VARS 数组。
$_SERVER['HTTP_HOST'] 取得当前请求的Host:头部内容
$_SERVER['PHP_SELF']这可能是我们最为经常用到的了,它返回当前调用 的页的文件名,如果是http://localhost/test/2005/test.php, 那么将会返回/test/2005/test.php
$_SERVER['SCRIPT_NAME']它将返回包含当前脚本的路径。这在页面需要指向自己时非常有用
$_SERVER['SCRIPT_FILENAME']它将返回当前文件所在的绝对路径信息
$_SERVER['REQUEST_URI']返回访问此页面所需的URI,包括"/"
当然还有许多路径函数:
dirname(),返回路径信息中的目录部分,前面是带有"/"的
basename()返回路径中的基本的文件名部分,当然也可以设置后缀来控制输出。
realpath(),返回路径信息的绝对规范化的路径
运用$_SERVER[ ]我们可以来完成许多事情:它是一个包含头部(headers),路径信息及脚本位置的数组,数组的实体由web服务器创建。
这是一个“superglobal”,或者可以描述为自动全局变量。这只不过意味这它在所有的脚本中都有效。在函数或方法中您不需要使用global $_SERVER; 访问它,就如同使用 $HTTP_SERVER_VARS 一样。 $HTTP_SERVER_VARS 包含着同样的信息,但是不是一个自动全局变量。(注意: $HTTP_SERVER_VARS 和 $_SERVER 是不同的变量,PHP 处理它们的方式不同。)如果设置了 register_globals 指令,这些变量也在所有脚本中可用;也就是,分离了 $_SERVER 和 $HTTP_SERVER_VARS 数组。
$_SERVER['HTTP_HOST'] 取得当前请求的Host:头部内容
$_SERVER['PHP_SELF']这可能是我们最为经常用到的了,它返回当前调用 的页的文件名,如果是http://localhost/test/2005/test.php, 那么将会返回/test/2005/test.php
$_SERVER['SCRIPT_NAME']它将返回包含当前脚本的路径。这在页面需要指向自己时非常有用
$_SERVER['SCRIPT_FILENAME']它将返回当前文件所在的绝对路径信息
$_SERVER['REQUEST_URI']返回访问此页面所需的URI,包括"/"
当然还有许多路径函数:
dirname(),返回路径信息中的目录部分,前面是带有"/"的
basename()返回路径中的基本的文件名部分,当然也可以设置后缀来控制输出。
realpath(),返回路径信息的绝对规范化的路径
王石是谁?股民们都知道,房奴们都知道,这次十元门事件之后,网民们、灾民们也都知道了,要是谁还说自己还不知道,大概相当于股民还不知道股市里有只股票叫深万科。
王石是个大富豪,估摸着把那些钱从银行取出来,几栋大别墅都堆不下,看一眼,许多人即使不犯心脏病,可能也会犯高血压。不过,这钱是人家自己挣来的,羡慕也没用,人家想咋花就咋花,哪怕扔进水里听个响儿,或者当厕纸用,那也是人家自己的事儿,别人管不着。至于耗费巨资娶儿媳妇儿,也是人之常情,寻常百姓家娶媳妇,父母不也是经常掏出棺材本、养老钱给小两口买新房、买靓车吗?怎么王石就不行呢?再说,那几百万对王石来说恐怕只相当于寻常家庭的几百块钱吧,这样的父母还不够节俭?至于人家爱攀登世界高峰,那只是个人爱好,和寻常人家打麻将、钓鱼没什么区别,人家花自己的钱,无可厚非,唠叨这些事儿实在没什么意思,说多了人家会认为咱们犯了红眼病!
汶川大地震发生后,王石迅速地捐出了200万善款。有钱出钱,有力出力,全民齐心抗击灾害,钱不在多少,而在于爱心,有人多点,有人少点,都是善举,值得尊敬。捐助不受道德、法律约束,仅仅是爱心、爱国的体现。网友们提出质疑,刚刚在经历房地产暴利时代赚得盆满钵满的超级富豪王石显得有点小家子气,也是心忧灾区的同胞之情的体现,但也仅仅是说说而已,抒发一下郁闷,过些日子自然烟消云散了,总不会有人会跑到万科去要、去抢吧?
可是,一向稳重、睿智、大气度的王总犯了一个低级错误,在博客对此阐述了自己的看法,并提出了令人诧异的所谓“常态”、“十元”、“负担”等几个观点,一石激起千层浪,引发了全国网民的齐声声讨,王总顿时陷入了“困境”,导致其多年精心培育、维护的个人和企业形象大为受损。经常在电视上曝光,在经济界地位崇高的王总大概过于相信自己的口才,同时对网络的力量有些不屑一顾吧,始料未及,竟然发展到如此境地。我想,王总一定是相当地后悔!
如果王总捐助200万之后,针对网民的质疑采取不问不理的态度,或者干脆躲到珠穆朗玛峰上闭关修炼,过些日子自然就风平浪静了。相对于中国地产巨鳄,200万的确有点少,但总比其他一些不捐助的更有社会责任感、更有爱心吧,比上不足,比下还有余呢,网民除了失望还能怎样?
如果王总捐出200万之后,发现网民有意见,不妨赶紧再忍痛拿出个800万,凑齐1000万,我想此事也能立即化解,风平浪静。网民们并不贪心,差不多像个样子就好,也不会想着剜你的肉,只不过在你大腿上拔根毛而已,再说大家也并非为自己,而是为解救受难的同胞,是爱国心、同胞情的体现,想必经常站在高山之颠高瞻远瞩的王总能够体谅吧?
可是向来高瞻远瞩的王总却老马失蹄,盛怒之下方寸大乱,做出了不恰当的解释,终于引火烧身了。几十年一遇的特大地震,死伤惨重,被王总轻描淡写称之为“常态”,你捐助多少是你自己的事情,又凭什么限制员工的爱心捐助不能超过十元呢?这是什么心态?
不要说区区两百万,就是一两千万对万科而言,不过是几套房子而已,又怎么就成了负担了?作为房地产暴利时代的既得利益者,从老百姓身上赚取了那么多违反常理的超额利润,稍微拿出一点无关痛痒的小钱怎么就不行呢?你经常谈到的所谓企业的社会责任感又该怎么体现呢?即便从商业角度而言,平时你花了那么多钱做商业广告,充满战略眼光的您为什么不把握这次树立企业和个人形象的好机会呀,这可是一举两得、一石二鸟、一箭三雕的绝好时机啊!你看,人家王老吉就很机灵,听说凉茶都被热情的网民买脱销了,难道万科不想自己的房子热销吗?王总呀,您老久经沙场,可不该犯这种小迷糊啊!
虽然王总不小心老马失了蹄,但王总毕竟还是王总,生姜还是老的辣,王总是见过大世面的人,大风大浪都走过了,像这种小河沟自然不在话下。你看,王总不是决定拿出一亿参与震后重建工作了?而且还信誓旦旦不从中谋取任何商业利益。虽然迟了点,终究还是拿出了点社会责任感,应该予以褒奖、肯定,革命不分先后嘛!不过,我不清楚,这一个亿会不会增加万科的负担,王总会不会心痛许久呢?还有,会不会在王总心里留下“捐助阴影”呢?
王石是个大富豪,估摸着把那些钱从银行取出来,几栋大别墅都堆不下,看一眼,许多人即使不犯心脏病,可能也会犯高血压。不过,这钱是人家自己挣来的,羡慕也没用,人家想咋花就咋花,哪怕扔进水里听个响儿,或者当厕纸用,那也是人家自己的事儿,别人管不着。至于耗费巨资娶儿媳妇儿,也是人之常情,寻常百姓家娶媳妇,父母不也是经常掏出棺材本、养老钱给小两口买新房、买靓车吗?怎么王石就不行呢?再说,那几百万对王石来说恐怕只相当于寻常家庭的几百块钱吧,这样的父母还不够节俭?至于人家爱攀登世界高峰,那只是个人爱好,和寻常人家打麻将、钓鱼没什么区别,人家花自己的钱,无可厚非,唠叨这些事儿实在没什么意思,说多了人家会认为咱们犯了红眼病!
汶川大地震发生后,王石迅速地捐出了200万善款。有钱出钱,有力出力,全民齐心抗击灾害,钱不在多少,而在于爱心,有人多点,有人少点,都是善举,值得尊敬。捐助不受道德、法律约束,仅仅是爱心、爱国的体现。网友们提出质疑,刚刚在经历房地产暴利时代赚得盆满钵满的超级富豪王石显得有点小家子气,也是心忧灾区的同胞之情的体现,但也仅仅是说说而已,抒发一下郁闷,过些日子自然烟消云散了,总不会有人会跑到万科去要、去抢吧?
可是,一向稳重、睿智、大气度的王总犯了一个低级错误,在博客对此阐述了自己的看法,并提出了令人诧异的所谓“常态”、“十元”、“负担”等几个观点,一石激起千层浪,引发了全国网民的齐声声讨,王总顿时陷入了“困境”,导致其多年精心培育、维护的个人和企业形象大为受损。经常在电视上曝光,在经济界地位崇高的王总大概过于相信自己的口才,同时对网络的力量有些不屑一顾吧,始料未及,竟然发展到如此境地。我想,王总一定是相当地后悔!
如果王总捐助200万之后,针对网民的质疑采取不问不理的态度,或者干脆躲到珠穆朗玛峰上闭关修炼,过些日子自然就风平浪静了。相对于中国地产巨鳄,200万的确有点少,但总比其他一些不捐助的更有社会责任感、更有爱心吧,比上不足,比下还有余呢,网民除了失望还能怎样?
如果王总捐出200万之后,发现网民有意见,不妨赶紧再忍痛拿出个800万,凑齐1000万,我想此事也能立即化解,风平浪静。网民们并不贪心,差不多像个样子就好,也不会想着剜你的肉,只不过在你大腿上拔根毛而已,再说大家也并非为自己,而是为解救受难的同胞,是爱国心、同胞情的体现,想必经常站在高山之颠高瞻远瞩的王总能够体谅吧?
可是向来高瞻远瞩的王总却老马失蹄,盛怒之下方寸大乱,做出了不恰当的解释,终于引火烧身了。几十年一遇的特大地震,死伤惨重,被王总轻描淡写称之为“常态”,你捐助多少是你自己的事情,又凭什么限制员工的爱心捐助不能超过十元呢?这是什么心态?
不要说区区两百万,就是一两千万对万科而言,不过是几套房子而已,又怎么就成了负担了?作为房地产暴利时代的既得利益者,从老百姓身上赚取了那么多违反常理的超额利润,稍微拿出一点无关痛痒的小钱怎么就不行呢?你经常谈到的所谓企业的社会责任感又该怎么体现呢?即便从商业角度而言,平时你花了那么多钱做商业广告,充满战略眼光的您为什么不把握这次树立企业和个人形象的好机会呀,这可是一举两得、一石二鸟、一箭三雕的绝好时机啊!你看,人家王老吉就很机灵,听说凉茶都被热情的网民买脱销了,难道万科不想自己的房子热销吗?王总呀,您老久经沙场,可不该犯这种小迷糊啊!
虽然王总不小心老马失了蹄,但王总毕竟还是王总,生姜还是老的辣,王总是见过大世面的人,大风大浪都走过了,像这种小河沟自然不在话下。你看,王总不是决定拿出一亿参与震后重建工作了?而且还信誓旦旦不从中谋取任何商业利益。虽然迟了点,终究还是拿出了点社会责任感,应该予以褒奖、肯定,革命不分先后嘛!不过,我不清楚,这一个亿会不会增加万科的负担,王总会不会心痛许久呢?还有,会不会在王总心里留下“捐助阴影”呢?
http://hometown.aol.de/_ht_a/memtronic/
download:http://download.microsoft.com/download/7/b/9/7b90644d-1af0-42b9-b76d-a2770319a568/dotnetfx.exe
http://www.x2blog.cn/supNate/UserFiles/X2JSCompactor.rar
blogurl:http://www.x2blog.cn/supnate/?tid=4175
对哦无奈哦:下载
download:http://download.microsoft.com/download/7/b/9/7b90644d-1af0-42b9-b76d-a2770319a568/dotnetfx.exe
http://www.x2blog.cn/supNate/UserFiles/X2JSCompactor.rar
blogurl:http://www.x2blog.cn/supnate/?tid=4175
对哦无奈哦:下载
# 将domain.com/xxx转向www.domain.com/xxx
RewriteCond %{HTTP_HOST} ^domain.com [NC]
RewriteRule ^(.*)$ http://www.domain.com$1 [R=301,NC]
# 将xxx.domain.com/yyy...重定向到www.domain.com/xxx/yyy..., xxx 5-20位, 字母开头只含字母, 数字以及"-"和"_"
RewriteCond %{SERVER_NAME} ^([a-z][a-z0-9\-\_]{4,19})\.domain\.com [NC]
RewriteRule ^(.+)$ %{SERVER_NAME}$1 [C]
RewriteRule ^([a-z][a-z0-9\-\_]{4,19})\.domain\.com(.*)$ http://www.domain.com/$1$2 [R=301,NC]
# 将首页www.domain.com转向www.domain.com/html/index.html
RewriteCond %{HTTP_HOST} www\.domain\.com
RewriteRule ^/$ http://www.domain.com/html/index.html [R=301,L]
RewriteCond %{HTTP_HOST} ^domain.com [NC]
RewriteRule ^(.*)$ http://www.domain.com$1 [R=301,NC]
# 将xxx.domain.com/yyy...重定向到www.domain.com/xxx/yyy..., xxx 5-20位, 字母开头只含字母, 数字以及"-"和"_"
RewriteCond %{SERVER_NAME} ^([a-z][a-z0-9\-\_]{4,19})\.domain\.com [NC]
RewriteRule ^(.+)$ %{SERVER_NAME}$1 [C]
RewriteRule ^([a-z][a-z0-9\-\_]{4,19})\.domain\.com(.*)$ http://www.domain.com/$1$2 [R=301,NC]
# 将首页www.domain.com转向www.domain.com/html/index.html
RewriteCond %{HTTP_HOST} www\.domain\.com
RewriteRule ^/$ http://www.domain.com/html/index.html [R=301,L]
工作三年了,各个方面都表现不错,但是职位上一直没有什么变化。眼看跟公司的合同到期了,公司为了留住人才,提拔我作了部门经理,呵呵,真是很高兴。但老板私下里也跟我说,我各个方面都不错,业务、人缘、能力都可以,但是还缺少管理者的气质,还要练练。
这管理者的气质怎么练呢?苦恼了很久;作为新提拔的经理,员工们也都不是很佩服。终于有一天,在酒席上,老板吐了真言,小王,你去买个lenovo的手机用用。老板就是老板!这句点拨,事后证明,绝对可以与当年一位道家达人暗示一位孙姓的猴子三更到后门学艺之事相媲美!
正巧,手机刚丢。于是,直奔国美,790元购得一款lenovo的G620C手机。那么,这个lenovo手机和当管理者有什么联系呢?我深深的陷入了思考,经过清晰的分析,得出以下论断:
1、从价位和品牌看,老板应该不是想让我买了送他,所以肯定不是索贿;
2、当好一个管理者的秘籍,肯定包含在这个手机里。一定要好好体会,成为一名成功的管理者---我暗地下了决心!
功夫不负有心人,刚开始用lenovo手机的第一天,我就发现了一个问题,这手机经常莫名的死机。开始我还很着急,后来我悟到了,这就是做一名成功的管理者的秘籍之一--不和员工交流!过去刚提拔起来的时候,和大家都很熟悉,交流也很多,所以大家跟我也都很随便;现在我明白了,这是管理者的大忌,于是我学着lenovo手机的样,经常在和下属交流的时候,打断或者是离开(死机),下属们渐渐的对我产生了畏惧,感觉我是一个爱生气的人,刚毕业的美女小刘也不敢只穿吊带来上班了,呵呵,好厉害的招数!看着老板赞许的目光,我知道,我悟到了~~ 但这是远远不够的。
刚开始用lenovo手机的第二天,我就又发现了一个问题,这手机会音量突然变的很小,以至于我早上放在枕边的手机铃声不能叫醒我。开始我还很着急,后来我悟到了,这就是做一名成功的管理者的秘籍之二--低音量。过去作业务人员的时候,办事干练,嗓门也大;现在我明白了,这是管理者的大忌--显的没城府,于是我学着lenovo手机的样,经常在开会的时候,说话声音越来越小,下属们生怕漏听了哪句话,开会的时候再也不嘻嘻吁吁的了,一个个紧张的不行,树着耳朵大气不敢出一声。刚毕业的美女小刘也总是凑到我身边听我安排工作,呵呵,好管用的招数!看着老板赞许的目光,我知道,我又悟到了~~ 但这还是远远不够的。
刚开始用lenovo手机的第三天,我就又发现了一个问题,这手机发短信经常发着发着,手机屏幕就只显示半屏。开始我还很着急,后来我悟到了,这就是做一名成功的管理者的秘籍之三--说话说一半。过去是汇报工作,跟领导说话一定要说清楚;现在向下属安排工作,就不能说的太明白了,这是管理者的大忌,于是我学着lenovo手机的样,经常在安排工作的时候,说到一半不说了,下属们走出我办公室的时候,往往是一脸狐疑,不知道我到底让他们干什么。但是又不敢问,于是干完工作来找我的时候,总是提心吊胆的,生怕我批评他们没领会领导意图!刚毕业的美女小刘总也是急得红着耳朵走出办公室。呵呵,好辛辣的招数!看着老板赞许的目光,我知道,我又悟到了~~ 但这还是远远不够的。
刚开始用lenovo手机的第四天,我就又发现了一个问题,这手机号称彩屏手机,其实除了桌面是彩色的,其他包括短信、游戏、设置等都是黑白的。操作界面的程序都编的非常可笑,以至于有时候我会以为某段程序是用foxbase编写的。开始我还很着急,后来我悟到了,这就是做一名成功的管理者的秘籍之四--做表面文章。开始做部门经理的时候,生怕某些工作做的不细,事事都追求完美,而且做完了不向上级汇报,总觉得是自己部门应该做的,这是管理者的大忌。于是我学着lenovo手机的样,在处理部门工作的时候,更多的是向上级老总们宣传做了多少工作,至于工作的效果,也没人细问。挂了羊头卖了狗肉,业绩大了还省了成本,呵呵,好刁钻的招数!看着老板赞许的目光,我知道,我又悟到了~~ 但这还是远远不够的。
刚开始用lenovo手机的第五天,我就又发现了一个问题,这手机里有一个大家都非常熟悉的游戏--黑白棋,这游戏我在红白机上玩过、在文曲星上玩过,但是还是没想到这老游戏lenovo还是能做出新花样。居然在整个棋盘下满棋局结束的时候,它不会象别的游戏一样跳出一个“you win”或者“you lose”的字样,而是不管胜负就显示“game over”,胜负让你自己去判断。而且虽然是彩屏,但实际连棋盘和“game over”都混在一起黑白显示,不仔细注意你还真看不出显示了一句E文。开始我还很着急,后来我悟到了,这就是做一名成功的管理者的秘籍之五--别告诉下属结果。开始做部门经理的时候,喜欢让下属知道上级是怎么评价他的工作的,以增强下属的责任心和成就感。其实这是管理者的大忌。于是我学着lenovo手机的样,在下属询问某项工作结果的时候,我故做神秘的应对,让下属们觉得神秘、觉得上级工作不好对付不敢随便交差。呵呵,好古怪的招数!看着老板赞许的目光,我知道,我又悟到了~~ 但这还是远远不够的。
刚开始用lenovo手机的第六天晚上,我终于不能忍受这古怪的机器了,频繁的死机、半屏,号称彩屏的黑白界面,经常令人哭笑不得的操作设计,内心的烦恼、愤怒差点让我把手机从窗户扔出去。我发誓明天一定要退掉手机。终于,我象杨过悟出黯然销魂掌一样,悟出了人生的真谛――比丢了手机更痛苦的事,就是丢了手机以后买了一款让人想扔的手机!!聪明如我,在气愤之余,悟到了做一名成功的管理者的终极秘籍――秘籍之六--让下属体会人生的真谛,苦上加苦!!正好公司裁员,我们部门必须裁一个,但是我还没决定。员工们人人自危,但是大家都觉得老杨肯定不会被裁掉――老杨的媳妇也刚刚失业,家里很困难。但是,心慈手软是管理者的大忌,于是我学着lenovo手机的样,向员工们宣布,裁掉老杨!!员工们从此以后谁也不敢有意见了,这么绝情的上司,谁敢忍。连刚毕业的美女小刘,和擦肩而过的时候,也有意无意的用胸脯蹭一下我的胳膊!呵呵,好歹毒的招数!看着老板赞许的目光,我知道,我又悟到了~~ 但这还是远远不够的.
在用lenovo手机的第七天早上,我一早来到国美准备退手机。国美说退可以,但是需要 lenovo的检测中心出具质量不合格的检测报告。靠,这不是欺负人吗?lenovo怎么会说自己的手机不合格。硬着头皮到了检测中心,结果很明显,检测中心告诉我手机没有任何问题!也就是说,退是不可能了!想到我这一生以来最难以煎熬的几天,我誓要把手机卖掉。于是到了商店外,放眼望去,数十个收购旧手机的贩子。随便找了一个一问,手机贩子居然告诉我,这手机他买也就350元(原价790啊!),但是给他200块钱,他就能帮我开出质量不合格的检测报告。果真,他轻而易举的从号称“联想阳光服务”的检测中心里开出了质量不合格的检测报告,我也付了他200元,回到国美退掉了手机。退掉手机的感觉,爽!没有比这再爽的事了。有过退手机经历的人一定有同感。在快感之余,我悟到了做一名成功的管理者的最终极秘籍――秘籍之七(完结篇)--用钱搞定关键人物!!以前怕人说三道四,从来不去老板家,老板的私人情况也不了解。这绝对是管理者的大忌,于是我学着退掉lenovo手机的样,摸清了情况,结识了老板正在上学的儿子,帮他报销了几千块给正在追求的女朋友买衣服的发票。呵呵,女朋友有了新衣服,当然乐了,老板儿子追求得手,当然爽了,老板儿子高兴,老板能不高兴吗?呵呵,好曲折的招数! 看着老板赞许的目光,我知道,我又悟到了~~
掌握了七大秘籍,公司上下刮目相看。部门经理这一工作,我算称职了。但是我自觉和老板比,还有很多差距。听说lenovo收购IBM的笔记本业务了,看来我当上总裁是有希望了~~~
这管理者的气质怎么练呢?苦恼了很久;作为新提拔的经理,员工们也都不是很佩服。终于有一天,在酒席上,老板吐了真言,小王,你去买个lenovo的手机用用。老板就是老板!这句点拨,事后证明,绝对可以与当年一位道家达人暗示一位孙姓的猴子三更到后门学艺之事相媲美!
正巧,手机刚丢。于是,直奔国美,790元购得一款lenovo的G620C手机。那么,这个lenovo手机和当管理者有什么联系呢?我深深的陷入了思考,经过清晰的分析,得出以下论断:
1、从价位和品牌看,老板应该不是想让我买了送他,所以肯定不是索贿;
2、当好一个管理者的秘籍,肯定包含在这个手机里。一定要好好体会,成为一名成功的管理者---我暗地下了决心!
功夫不负有心人,刚开始用lenovo手机的第一天,我就发现了一个问题,这手机经常莫名的死机。开始我还很着急,后来我悟到了,这就是做一名成功的管理者的秘籍之一--不和员工交流!过去刚提拔起来的时候,和大家都很熟悉,交流也很多,所以大家跟我也都很随便;现在我明白了,这是管理者的大忌,于是我学着lenovo手机的样,经常在和下属交流的时候,打断或者是离开(死机),下属们渐渐的对我产生了畏惧,感觉我是一个爱生气的人,刚毕业的美女小刘也不敢只穿吊带来上班了,呵呵,好厉害的招数!看着老板赞许的目光,我知道,我悟到了~~ 但这是远远不够的。
刚开始用lenovo手机的第二天,我就又发现了一个问题,这手机会音量突然变的很小,以至于我早上放在枕边的手机铃声不能叫醒我。开始我还很着急,后来我悟到了,这就是做一名成功的管理者的秘籍之二--低音量。过去作业务人员的时候,办事干练,嗓门也大;现在我明白了,这是管理者的大忌--显的没城府,于是我学着lenovo手机的样,经常在开会的时候,说话声音越来越小,下属们生怕漏听了哪句话,开会的时候再也不嘻嘻吁吁的了,一个个紧张的不行,树着耳朵大气不敢出一声。刚毕业的美女小刘也总是凑到我身边听我安排工作,呵呵,好管用的招数!看着老板赞许的目光,我知道,我又悟到了~~ 但这还是远远不够的。
刚开始用lenovo手机的第三天,我就又发现了一个问题,这手机发短信经常发着发着,手机屏幕就只显示半屏。开始我还很着急,后来我悟到了,这就是做一名成功的管理者的秘籍之三--说话说一半。过去是汇报工作,跟领导说话一定要说清楚;现在向下属安排工作,就不能说的太明白了,这是管理者的大忌,于是我学着lenovo手机的样,经常在安排工作的时候,说到一半不说了,下属们走出我办公室的时候,往往是一脸狐疑,不知道我到底让他们干什么。但是又不敢问,于是干完工作来找我的时候,总是提心吊胆的,生怕我批评他们没领会领导意图!刚毕业的美女小刘总也是急得红着耳朵走出办公室。呵呵,好辛辣的招数!看着老板赞许的目光,我知道,我又悟到了~~ 但这还是远远不够的。
刚开始用lenovo手机的第四天,我就又发现了一个问题,这手机号称彩屏手机,其实除了桌面是彩色的,其他包括短信、游戏、设置等都是黑白的。操作界面的程序都编的非常可笑,以至于有时候我会以为某段程序是用foxbase编写的。开始我还很着急,后来我悟到了,这就是做一名成功的管理者的秘籍之四--做表面文章。开始做部门经理的时候,生怕某些工作做的不细,事事都追求完美,而且做完了不向上级汇报,总觉得是自己部门应该做的,这是管理者的大忌。于是我学着lenovo手机的样,在处理部门工作的时候,更多的是向上级老总们宣传做了多少工作,至于工作的效果,也没人细问。挂了羊头卖了狗肉,业绩大了还省了成本,呵呵,好刁钻的招数!看着老板赞许的目光,我知道,我又悟到了~~ 但这还是远远不够的。
刚开始用lenovo手机的第五天,我就又发现了一个问题,这手机里有一个大家都非常熟悉的游戏--黑白棋,这游戏我在红白机上玩过、在文曲星上玩过,但是还是没想到这老游戏lenovo还是能做出新花样。居然在整个棋盘下满棋局结束的时候,它不会象别的游戏一样跳出一个“you win”或者“you lose”的字样,而是不管胜负就显示“game over”,胜负让你自己去判断。而且虽然是彩屏,但实际连棋盘和“game over”都混在一起黑白显示,不仔细注意你还真看不出显示了一句E文。开始我还很着急,后来我悟到了,这就是做一名成功的管理者的秘籍之五--别告诉下属结果。开始做部门经理的时候,喜欢让下属知道上级是怎么评价他的工作的,以增强下属的责任心和成就感。其实这是管理者的大忌。于是我学着lenovo手机的样,在下属询问某项工作结果的时候,我故做神秘的应对,让下属们觉得神秘、觉得上级工作不好对付不敢随便交差。呵呵,好古怪的招数!看着老板赞许的目光,我知道,我又悟到了~~ 但这还是远远不够的。
刚开始用lenovo手机的第六天晚上,我终于不能忍受这古怪的机器了,频繁的死机、半屏,号称彩屏的黑白界面,经常令人哭笑不得的操作设计,内心的烦恼、愤怒差点让我把手机从窗户扔出去。我发誓明天一定要退掉手机。终于,我象杨过悟出黯然销魂掌一样,悟出了人生的真谛――比丢了手机更痛苦的事,就是丢了手机以后买了一款让人想扔的手机!!聪明如我,在气愤之余,悟到了做一名成功的管理者的终极秘籍――秘籍之六--让下属体会人生的真谛,苦上加苦!!正好公司裁员,我们部门必须裁一个,但是我还没决定。员工们人人自危,但是大家都觉得老杨肯定不会被裁掉――老杨的媳妇也刚刚失业,家里很困难。但是,心慈手软是管理者的大忌,于是我学着lenovo手机的样,向员工们宣布,裁掉老杨!!员工们从此以后谁也不敢有意见了,这么绝情的上司,谁敢忍。连刚毕业的美女小刘,和擦肩而过的时候,也有意无意的用胸脯蹭一下我的胳膊!呵呵,好歹毒的招数!看着老板赞许的目光,我知道,我又悟到了~~ 但这还是远远不够的.
在用lenovo手机的第七天早上,我一早来到国美准备退手机。国美说退可以,但是需要 lenovo的检测中心出具质量不合格的检测报告。靠,这不是欺负人吗?lenovo怎么会说自己的手机不合格。硬着头皮到了检测中心,结果很明显,检测中心告诉我手机没有任何问题!也就是说,退是不可能了!想到我这一生以来最难以煎熬的几天,我誓要把手机卖掉。于是到了商店外,放眼望去,数十个收购旧手机的贩子。随便找了一个一问,手机贩子居然告诉我,这手机他买也就350元(原价790啊!),但是给他200块钱,他就能帮我开出质量不合格的检测报告。果真,他轻而易举的从号称“联想阳光服务”的检测中心里开出了质量不合格的检测报告,我也付了他200元,回到国美退掉了手机。退掉手机的感觉,爽!没有比这再爽的事了。有过退手机经历的人一定有同感。在快感之余,我悟到了做一名成功的管理者的最终极秘籍――秘籍之七(完结篇)--用钱搞定关键人物!!以前怕人说三道四,从来不去老板家,老板的私人情况也不了解。这绝对是管理者的大忌,于是我学着退掉lenovo手机的样,摸清了情况,结识了老板正在上学的儿子,帮他报销了几千块给正在追求的女朋友买衣服的发票。呵呵,女朋友有了新衣服,当然乐了,老板儿子追求得手,当然爽了,老板儿子高兴,老板能不高兴吗?呵呵,好曲折的招数! 看着老板赞许的目光,我知道,我又悟到了~~
掌握了七大秘籍,公司上下刮目相看。部门经理这一工作,我算称职了。但是我自觉和老板比,还有很多差距。听说lenovo收购IBM的笔记本业务了,看来我当上总裁是有希望了~~~
function init_space_user_friend_unicode()
{
if(typeof SpaceUserFriend !="undefined")
{
try{
//*
SpaceUserFriend.traceInfo = function (sMSG) {
alert("信息: " + sMSG)
};
//*/
}catch(e){
}
var tmp=SpaceUserFriend.createContent();
//alert(tmp)
document.getElementById("innerDiv").innerHTML=tmp;
SpaceUserFriend.init();
}else
{
setTimeout(function(){
init_space_user_friend_unicode();
},100
)
}
}init_space_user_friend_unicode();
经常会在js里用到数组,比如 多个名字相同的input, 若是动态生成的, 提交时就需要判断其是否是数组.
if(document.mylist.length != "undefined" ) {} 这个用法有误.
正确的是 if( typeof(document.mylist.length) != "undefined" ) {}
或 if( !isNaN(document.mylist.length) ) {}
typeof的运算数未定义,返回的就是 "undefined".
运算数为数字 typeof(x) = "number"
字符串 typeof(x) = "string"
布尔值 typeof(x) = "boolean"
对象,数组和null typeof(x) = "object"
函数 typeof(x) = "function"
typeof 运算符返回一个用来表示表达式的数据类型的字符串。
可能的字符串有:"number"、"string"、"boolean"、"object"、"function" 和 "undefined"。
如:
alert(typeof (123));//typeof(123)返回"number"
alert(typeof ("123"));//typeof("123")返回"string"
typeof 运算符
返回一个用来表示表达式的数据类型的字符串。
typeof[()expression[]] ;
expression 参数是需要查找类型信息的任意表达式。
说明
typeof 运算符把类型信息当作字符串返回。typeof 返回值有六种可能: "number," "string," "boolean," "object," "function," 和 "undefined."
typeof 语法中的圆括号是可选项。
在很多情况下,需要定期的刷新页面,比如显示股票或者比赛比分的页面(当然现在一般都是通过ajax去定期的从后台取数据,然后更新局部页面),又或者你网站的域名换了以后,当用户打开旧网站的时候重定向到新域名(告诉用户5秒钟后转到另一个页面等等)。
<html>
<head>
<script type="text/javascript">
function delayedRedirect(){
window.location = "http://www.collin.cn"
}
</script>
</head>
<body onLoad="setTimeout('delayedRedirect()', 5000)">
<h2>5秒钟后你将重定向到www.collin.cn!</h2>
</body>
</html>
{
if(typeof SpaceUserFriend !="undefined")
{
try{
//*
SpaceUserFriend.traceInfo = function (sMSG) {
alert("信息: " + sMSG)
};
//*/
}catch(e){
}
var tmp=SpaceUserFriend.createContent();
//alert(tmp)
document.getElementById("innerDiv").innerHTML=tmp;
SpaceUserFriend.init();
}else
{
setTimeout(function(){
init_space_user_friend_unicode();
},100
)
}
}init_space_user_friend_unicode();
经常会在js里用到数组,比如 多个名字相同的input, 若是动态生成的, 提交时就需要判断其是否是数组.
if(document.mylist.length != "undefined" ) {} 这个用法有误.
正确的是 if( typeof(document.mylist.length) != "undefined" ) {}
或 if( !isNaN(document.mylist.length) ) {}
typeof的运算数未定义,返回的就是 "undefined".
运算数为数字 typeof(x) = "number"
字符串 typeof(x) = "string"
布尔值 typeof(x) = "boolean"
对象,数组和null typeof(x) = "object"
函数 typeof(x) = "function"
typeof 运算符返回一个用来表示表达式的数据类型的字符串。
可能的字符串有:"number"、"string"、"boolean"、"object"、"function" 和 "undefined"。
如:
alert(typeof (123));//typeof(123)返回"number"
alert(typeof ("123"));//typeof("123")返回"string"
typeof 运算符
返回一个用来表示表达式的数据类型的字符串。
typeof[()expression[]] ;
expression 参数是需要查找类型信息的任意表达式。
说明
typeof 运算符把类型信息当作字符串返回。typeof 返回值有六种可能: "number," "string," "boolean," "object," "function," 和 "undefined."
typeof 语法中的圆括号是可选项。
在很多情况下,需要定期的刷新页面,比如显示股票或者比赛比分的页面(当然现在一般都是通过ajax去定期的从后台取数据,然后更新局部页面),又或者你网站的域名换了以后,当用户打开旧网站的时候重定向到新域名(告诉用户5秒钟后转到另一个页面等等)。
<html>
<head>
<script type="text/javascript">
function delayedRedirect(){
window.location = "http://www.collin.cn"
}
</script>
</head>
<body onLoad="setTimeout('delayedRedirect()', 5000)">
<h2>5秒钟后你将重定向到www.collin.cn!</h2>
</body>
</html>
向东 CHINAREN 说:
说实话,我很佩服你,真的,你教会我很多,感激!
加密助手 说:
--- 系统提示: 以下会话未被加密 ---
Wang.Z.B 说:
靠
Wang.Z.B 说:
怎么跟他妈的告别似的
向东 CHINAREN 说:
你丫不是快要走了嘛,一年也快到了吧。。
Wang.Z.B 说:
哈哈
Wang.Z.B 说:
还早呢
Wang.Z.B 说:
我12月才来的
向东 CHINAREN 说:
那提前走啊。。
向东 CHINAREN 说:
我看你学的strus也差不多了吧,干那个去?还是回原来公司?
向东 CHINAREN 说:
有空聊聊,你知道那个播客哥们张宴去哪儿了吗?呵呵
加密助手 说:
--- 系统提示: 以下会话未被加密 ---
Wang.Z.B 说:
不知道啊
向东 CHINAREN 说:
豆瓣
Wang.Z.B 说:
视频啊
向东 CHINAREN 说:
好想去豆瓣了。。。
向东 CHINAREN 说:
豆瓣是搞视频的啊?
Wang.Z.B 说:
好想吃豆瓣了
Wang.Z.B 说:
不是吗
Wang.Z.B 说:
我以为是土豆呢
您发送了一个闪屏振动。
向东 CHINAREN 说:
http://www.douban.com/
向东 CHINAREN 说:
估计应该是这个吧。。
Wang.Z.B 说:
是
向东 CHINAREN 说:
这网站好像不乍的嘛。。。做什么的啊。。?
加密助手 说:
--- 系统提示: 以下会话未被加密 ---
Wang.Z.B 说:
这叫什么商务模式啊
向东 CHINAREN 说:
我也不懂咯。。。呵呵
Wang.Z.B 说:
感觉跟口碑网相似
加密助手 说:
--- 系统提示: 以下会话未被加密 ---
Wang.Z.B 说:
你怎么知道他去了豆瓣
向东 CHINAREN 说:
听播客一个哥们说的。
Wang.Z.B 说:
这样啊
Wang.Z.B 说:
这孙子好像也不上msn
向东 CHINAREN 说:
呵呵,是啊,应该没有用那个号码了。。
Wang.Z.B 说:
就是
Wang.Z.B 说:
把你给抛弃了
向东 CHINAREN 说:
呵呵,我晕,我又不是母的。。。(*^__^*) 嘻嘻……
Wang.Z.B 说:
你好好研究研究播客,到时候给我讲讲,我挺感兴趣的,觉得有前途
Wang.Z.B 说:
以后肯定是视频与语音的天下,mail必死
向东 CHINAREN 说:
呵呵,那你要搞视频和语言,得学习flash server,已经做出来了,可以跨平台的。。
向东 CHINAREN 说:
人无横财不富,搞IT得有风投得有前沿。。。我觉得
加密助手 说:
--- 系统提示: 以下会话未被加密 ---
Wang.Z.B 说:
不光fms,包括架构了,包括如何缓存,如何均衡,以及内容的制作过程,得学点这个
Wang.Z.B 说:
你现在别想一下子吃个胖子,风投哪那么容易拿啊
说实话,我很佩服你,真的,你教会我很多,感激!
加密助手 说:
--- 系统提示: 以下会话未被加密 ---
Wang.Z.B 说:
靠
Wang.Z.B 说:
怎么跟他妈的告别似的
向东 CHINAREN 说:
你丫不是快要走了嘛,一年也快到了吧。。
Wang.Z.B 说:
哈哈
Wang.Z.B 说:
还早呢
Wang.Z.B 说:
我12月才来的
向东 CHINAREN 说:
那提前走啊。。
向东 CHINAREN 说:
我看你学的strus也差不多了吧,干那个去?还是回原来公司?
向东 CHINAREN 说:
有空聊聊,你知道那个播客哥们张宴去哪儿了吗?呵呵
加密助手 说:
--- 系统提示: 以下会话未被加密 ---
Wang.Z.B 说:
不知道啊
向东 CHINAREN 说:
豆瓣
Wang.Z.B 说:
视频啊
向东 CHINAREN 说:
好想去豆瓣了。。。
向东 CHINAREN 说:
豆瓣是搞视频的啊?
Wang.Z.B 说:
好想吃豆瓣了
Wang.Z.B 说:
不是吗
Wang.Z.B 说:
我以为是土豆呢
您发送了一个闪屏振动。
向东 CHINAREN 说:
http://www.douban.com/
向东 CHINAREN 说:
估计应该是这个吧。。
Wang.Z.B 说:
是
向东 CHINAREN 说:
这网站好像不乍的嘛。。。做什么的啊。。?
加密助手 说:
--- 系统提示: 以下会话未被加密 ---
Wang.Z.B 说:
这叫什么商务模式啊
向东 CHINAREN 说:
我也不懂咯。。。呵呵
Wang.Z.B 说:
感觉跟口碑网相似
加密助手 说:
--- 系统提示: 以下会话未被加密 ---
Wang.Z.B 说:
你怎么知道他去了豆瓣
向东 CHINAREN 说:
听播客一个哥们说的。
Wang.Z.B 说:
这样啊
Wang.Z.B 说:
这孙子好像也不上msn
向东 CHINAREN 说:
呵呵,是啊,应该没有用那个号码了。。
Wang.Z.B 说:
就是
Wang.Z.B 说:
把你给抛弃了
向东 CHINAREN 说:
呵呵,我晕,我又不是母的。。。(*^__^*) 嘻嘻……
Wang.Z.B 说:
你好好研究研究播客,到时候给我讲讲,我挺感兴趣的,觉得有前途
Wang.Z.B 说:
以后肯定是视频与语音的天下,mail必死
向东 CHINAREN 说:
呵呵,那你要搞视频和语言,得学习flash server,已经做出来了,可以跨平台的。。
向东 CHINAREN 说:
人无横财不富,搞IT得有风投得有前沿。。。我觉得
加密助手 说:
--- 系统提示: 以下会话未被加密 ---
Wang.Z.B 说:
不光fms,包括架构了,包括如何缓存,如何均衡,以及内容的制作过程,得学点这个
Wang.Z.B 说:
你现在别想一下子吃个胖子,风投哪那么容易拿啊
<html>
<script language="javascript">
function updatedoc()
{
document.writeln("abc<br>");
document.writeln("def<br>");
document.writeln('<script language="javascript">');
document.writeln('function updatedoc()');
document.writeln('{');
document.writeln(' document.writeln("first<br>");');
document.writeln(' document.writeln("second<br>");');
document.writeln('}');
document.writeln('</scr'+'ipt>');
document.writeln('<input type=button name="update" value="更新" onclick="updatedoc()">');
}
</script>
<input type=button name="update" value="更新" onclick="updatedoc()">
</html>
/*这里不能写作</script>,否则系统会报错,其默认与上面的<script language="javascript"> 匹配。所以应当注意^_^*/
URL:http://www.cnblogs.com/happiness/archive/2006/04/18/377880.html
<script language="javascript">
function updatedoc()
{
document.writeln("abc<br>");
document.writeln("def<br>");
document.writeln('<script language="javascript">');
document.writeln('function updatedoc()');
document.writeln('{');
document.writeln(' document.writeln("first<br>");');
document.writeln(' document.writeln("second<br>");');
document.writeln('}');
document.writeln('</scr'+'ipt>');
document.writeln('<input type=button name="update" value="更新" onclick="updatedoc()">');
}
</script>
<input type=button name="update" value="更新" onclick="updatedoc()">
</html>
/*这里不能写作</script>,否则系统会报错,其默认与上面的<script language="javascript"> 匹配。所以应当注意^_^*/
URL:http://www.cnblogs.com/happiness/archive/2006/04/18/377880.html
http://www.picavr.com/news/2008-02/4172.htm
用USB接口的数据采集系统,使用简单方便,无需外接电源,还可以利用PC机强大的运算能力处理数据。这类系统一般都要用单片机做接口控制,对于不会使用单片机的人是个难题。这里介绍一个不用单片机的USB数据采集系统,只要会用VB编程就可以实现。
参考链接:http://www.picavr.com/news/2008-02/4172.htm

一、系统的硬件构成
本系统的电原理如上图,CH371是USB接口芯片,MAX197多路AD转换器做数据采集,电脑对采集的数据进行处理。
CH371是南京沁恒电子出品的一种简单易用的USB接口芯片,它包括芯片本身和计算机端的通用驱动程序。CH371以硬件逻辑实现了USB通信协议传输控制的整个过程,通用驱动程序通过软件向计算机应用层提供设备级接口,因此用户不必考虑USB通信协议、固件程序、驱动程序、底层数据传输过程等,就可以设计出各种USB接口设备。
CH371有多种工作方式,除了数据传输方式外,它还可以工作在一种主控方式,即使没有连结单片机、DSP等控制器,也可以输出控制信号和输入数据。CH371的D7~D0、A3~A0都是双向引脚,它们可以被分为两组,分别设置用于输入或输出。把CH371的A3~A0与MAX197的CS、WR、RD、HBEN四根输入控制线相连,把D7~D0和MAX197的并行数据端口相连,就可以通过软件直接控制MAX197的工作。
MAX197是MAXIM推出的12位AD转换器,单5伏供电,内置4.096伏电压基准,外围电路很简单,仅需外接几只电容就可以工作。MAX197有内外两种时钟和采样模式,模拟输入量程和极性可选,有0~5伏、0~10伏、±5伏、±10伏四种。有8个模拟输入通道。所有这些都可以通过软件来选择,即向MAX197写入一个字节的控制字来实现,控制字的各位功能见下表:
位
PD1
PD0
ACQMOD
RNG
BIP
A2
A1
A0
功能
内外时钟和电源管理模式
内外控制采样模式
模拟信号量程
模拟信号极性
模拟输入通道选择
二、系统的软件设计
1. CH371计算机端的软件接口
CH371在计算机端提供了三个层次的软件接口,最高层是应用层接口。应用层接口是由CH371动态链接库DLL提供的面向功能应用的API函数。每个函数实现一个具体的功能,并用简便易用的API参数代替设备级接口中所要求的数据格式,所有API在调用后都有操作状态返回,用户只要选择特定的API函数就可以实现所需的功能。
CH371动态链接库DLL提供的的API函数包括设备管理、数据传输、中断查询、I2C操作和直接控制等几类,我们这里要用的是两个直接控制函数。
CH371GetStatus(ByVal iIndex As Long, ByVal iStatus As Long,ByRef iDataReg As Long)As Boolean
它的功能是通过CH371直接输入数据和状态,其中iIndex指定CH37设备序号,iStatus指向一个双字单元,用于保存状态数据。Bit7~Bit0对应CH371的D7~D0引脚。IDataReg指向一个双字单元,用于保存数据寄存器的数据。
CH371SetControl(ByVal iIndex As Long, ByVal iCtrData As Byte, ByVal iCtrlAddr As Byte,ByVal iData0e As Boolean, ByVal iAddr0e As Boolean)As Boolean
它的功能是通过CH371直接输出控制信号。ICtrData是准备写入D7~D0数据寄存器的数据, iCtrlAddr是准备写入A3~A0数据寄存器的数据, 它们都必须在输出使能时才可以输出数据。iData0e控制D7~D0输出使能,1输出、0输入。iAddr0e控制A3~A0输出使能,1输出、0输入。
2. VB应用程序
应用程序是用VB编写的,它的核心就是调用上述两个API函数,通过CH371的D7~D0和A3~A0向MAX197写入控制字,启动模数转换,最后读出转换结果。VB要使用CH371动态链接库中的API函数,首先要用Declare语句在全局模块的代码段声明这些函数,CH371芯片厂商在其提供的VB DEMO中,有两个MODULE已经包含了CH371所有的API函数,用户只需要在自己的工程项目中将其加入即可。通过这两个函数调用,向MAX197写入控制字,设定模数转换器的工作方式、选择输入通道、启动模数转换,最后读入转换结果,存入电脑,再做进一步处理
参考链接:http://www.picavr.com/news/2008-02/4172.htm
由于CH371芯片的功能有限,对于新客户建议用下列芯片代替CH371,
新的芯片比CH371功能更多,更易使用,数据传输速度更快,成本更低
1、如果应用电路中有单片机或者DSP等,打算通过USB与计算机通讯,
那么建议用CH372或者CH375或者CH374代替CH371,
因为CH372/CH375/CH374的缓冲区是CH371的8倍,所以传输速度更快,
可达每秒300K甚至800K字节以上,即使是MCS51单片机也能够达到300KB
2、如果应用电路中没有单片机和DSP,只是打算通过CH371直接控制
外部逻辑电路,那么建议用CH341代替CH371,
因为CH341可以提供异步串口、并口以及类似I2C的两线串行接口,
CH341的串口波特率支持从50bps到2000000bps,支持速率控制,
CH341的并口有两种时序,分别是8位仿EPP并口和8位仿MEM并口,
并口的速度可达每秒300K字节,不但速度快而且容易I/O扩展,
CH341的仿I2C接口的时钟约为200KHz,传输速度约为每秒7KB
3、CH372或CH375或CH374必须在单片机或DSP的控制下才能与计算机通讯,
CH375和CH374还能与USB设备(如U盘、USB打印机、USB摄像头)通讯,
CH341可以直接与计算机通讯,不需要单片机或者DSP,可以用于
I/O扩展,I/O控制,简单的AD或者DA,USB转串口、USB转并口等。
4、网站上有用CH375或者CH374或者CH372升级CH371的详细说明,
注意,CH372/CH375/CH374和CH341与CH371的部分引脚不同
5、如果有其它技术问题,请联系技术支持EMAIL:
tech@winchiphead.com
用USB接口的数据采集系统,使用简单方便,无需外接电源,还可以利用PC机强大的运算能力处理数据。这类系统一般都要用单片机做接口控制,对于不会使用单片机的人是个难题。这里介绍一个不用单片机的USB数据采集系统,只要会用VB编程就可以实现。
参考链接:http://www.picavr.com/news/2008-02/4172.htm

一、系统的硬件构成
本系统的电原理如上图,CH371是USB接口芯片,MAX197多路AD转换器做数据采集,电脑对采集的数据进行处理。
CH371是南京沁恒电子出品的一种简单易用的USB接口芯片,它包括芯片本身和计算机端的通用驱动程序。CH371以硬件逻辑实现了USB通信协议传输控制的整个过程,通用驱动程序通过软件向计算机应用层提供设备级接口,因此用户不必考虑USB通信协议、固件程序、驱动程序、底层数据传输过程等,就可以设计出各种USB接口设备。
CH371有多种工作方式,除了数据传输方式外,它还可以工作在一种主控方式,即使没有连结单片机、DSP等控制器,也可以输出控制信号和输入数据。CH371的D7~D0、A3~A0都是双向引脚,它们可以被分为两组,分别设置用于输入或输出。把CH371的A3~A0与MAX197的CS、WR、RD、HBEN四根输入控制线相连,把D7~D0和MAX197的并行数据端口相连,就可以通过软件直接控制MAX197的工作。
MAX197是MAXIM推出的12位AD转换器,单5伏供电,内置4.096伏电压基准,外围电路很简单,仅需外接几只电容就可以工作。MAX197有内外两种时钟和采样模式,模拟输入量程和极性可选,有0~5伏、0~10伏、±5伏、±10伏四种。有8个模拟输入通道。所有这些都可以通过软件来选择,即向MAX197写入一个字节的控制字来实现,控制字的各位功能见下表:
位
PD1
PD0
ACQMOD
RNG
BIP
A2
A1
A0
功能
内外时钟和电源管理模式
内外控制采样模式
模拟信号量程
模拟信号极性
模拟输入通道选择
二、系统的软件设计
1. CH371计算机端的软件接口
CH371在计算机端提供了三个层次的软件接口,最高层是应用层接口。应用层接口是由CH371动态链接库DLL提供的面向功能应用的API函数。每个函数实现一个具体的功能,并用简便易用的API参数代替设备级接口中所要求的数据格式,所有API在调用后都有操作状态返回,用户只要选择特定的API函数就可以实现所需的功能。
CH371动态链接库DLL提供的的API函数包括设备管理、数据传输、中断查询、I2C操作和直接控制等几类,我们这里要用的是两个直接控制函数。
CH371GetStatus(ByVal iIndex As Long, ByVal iStatus As Long,ByRef iDataReg As Long)As Boolean
它的功能是通过CH371直接输入数据和状态,其中iIndex指定CH37设备序号,iStatus指向一个双字单元,用于保存状态数据。Bit7~Bit0对应CH371的D7~D0引脚。IDataReg指向一个双字单元,用于保存数据寄存器的数据。
CH371SetControl(ByVal iIndex As Long, ByVal iCtrData As Byte, ByVal iCtrlAddr As Byte,ByVal iData0e As Boolean, ByVal iAddr0e As Boolean)As Boolean
它的功能是通过CH371直接输出控制信号。ICtrData是准备写入D7~D0数据寄存器的数据, iCtrlAddr是准备写入A3~A0数据寄存器的数据, 它们都必须在输出使能时才可以输出数据。iData0e控制D7~D0输出使能,1输出、0输入。iAddr0e控制A3~A0输出使能,1输出、0输入。
2. VB应用程序
应用程序是用VB编写的,它的核心就是调用上述两个API函数,通过CH371的D7~D0和A3~A0向MAX197写入控制字,启动模数转换,最后读出转换结果。VB要使用CH371动态链接库中的API函数,首先要用Declare语句在全局模块的代码段声明这些函数,CH371芯片厂商在其提供的VB DEMO中,有两个MODULE已经包含了CH371所有的API函数,用户只需要在自己的工程项目中将其加入即可。通过这两个函数调用,向MAX197写入控制字,设定模数转换器的工作方式、选择输入通道、启动模数转换,最后读入转换结果,存入电脑,再做进一步处理
参考链接:http://www.picavr.com/news/2008-02/4172.htm
由于CH371芯片的功能有限,对于新客户建议用下列芯片代替CH371,
新的芯片比CH371功能更多,更易使用,数据传输速度更快,成本更低
1、如果应用电路中有单片机或者DSP等,打算通过USB与计算机通讯,
那么建议用CH372或者CH375或者CH374代替CH371,
因为CH372/CH375/CH374的缓冲区是CH371的8倍,所以传输速度更快,
可达每秒300K甚至800K字节以上,即使是MCS51单片机也能够达到300KB
2、如果应用电路中没有单片机和DSP,只是打算通过CH371直接控制
外部逻辑电路,那么建议用CH341代替CH371,
因为CH341可以提供异步串口、并口以及类似I2C的两线串行接口,
CH341的串口波特率支持从50bps到2000000bps,支持速率控制,
CH341的并口有两种时序,分别是8位仿EPP并口和8位仿MEM并口,
并口的速度可达每秒300K字节,不但速度快而且容易I/O扩展,
CH341的仿I2C接口的时钟约为200KHz,传输速度约为每秒7KB
3、CH372或CH375或CH374必须在单片机或DSP的控制下才能与计算机通讯,
CH375和CH374还能与USB设备(如U盘、USB打印机、USB摄像头)通讯,
CH341可以直接与计算机通讯,不需要单片机或者DSP,可以用于
I/O扩展,I/O控制,简单的AD或者DA,USB转串口、USB转并口等。
4、网站上有用CH375或者CH374或者CH372升级CH371的详细说明,
注意,CH372/CH375/CH374和CH341与CH371的部分引脚不同
5、如果有其它技术问题,请联系技术支持EMAIL:
tech@winchiphead.com
用PHP的ob_start();控制您的浏览器cache!
Output Control 函数可以让你自由控制脚本中数据的输出。它非常地有用,特别是对于:当你想在数据已经输出后,再输出文件头的情况。输出控制函数不对使用 header() 或 setcookie(), 发送的文件头信息产生影响,只对那些类似于 echo() 和 PHP 代码的数据块有作用。
我们先举一个简单的例子,让大家对Output Control有一个大致的印象:
Example 1.
所有对header()函数有了解的人都知道,这个函数会发送一段文件头给浏览器,但是如果在使用这个函数之前已经有了任何输出(包括空输出,比如空格,回车和换行)就会提示出错。如果我们去掉第一行的ob_start(),再执行此程序,我们会发现得到了一条错误提示:"Header had all ready send by"!但是加上ob_start,就不会提示出错,原因是当打开了缓冲区,echo后面的字符不会输出到浏览器,而是保留在服务器,直到你使用 flush或者ob_end_flush才会输出,所以并不会有任何文件头输出的错误!
一、 相关函数简介:
1、Flush:刷新缓冲区的内容,输出。
函数格式:flush()
说明:这个函数经常使用,效率很高。
2、ob_start :打开输出缓冲区
函数格式:void ob_start(void)
说明:当缓冲区激活时,所有来自PHP程序的非文件头信息均不会发送,而是保存在内部缓冲区。为了输出缓冲区的内容,可以使用ob_end_flush()或flush()输出缓冲区的内容。
3 、ob_get_contents :返回内部缓冲区的内容。
使用方法:string ob_get_contents(void)
说明:这个函数会返回当前缓冲区中的内容,如果输出缓冲区没有激活,则返回 FALSE 。
4、ob_get_length:返回内部缓冲区的长度。
使用方法:int ob_get_length(void)
说明:这个函数会返回当前缓冲区中的长度;和ob_get_contents一样,如果输出缓冲区没有激活。则返回 FALSE。
5、ob_end_flush :发送内部缓冲区的内容到浏览器,并且关闭输出缓冲区。
使用方法:void ob_end_flush(void)
说明:这个函数发送输出缓冲区的内容(如果有的话)。
6、ob_end_clean:删除内部缓冲区的内容,并且关闭内部缓冲区
使用方法:void ob_end_clean(void)
说明:这个函数不会输出内部缓冲区的内容而是把它删除!
7、ob_implicit_flush:打开或关闭绝对刷新
使用方法:void ob_implicit_flush ([int flag])
说明:使用过Perl的人都知道$|=x的意义,这个字符串可以打开/关闭缓冲区,而ob_implicit_flush函数也和那个一样,默认为关闭缓冲区,打开绝对输出后,每个脚本输出都直接发送到浏览器,不再需要调用 flush()
二、深入了解:
1. 关于Flush函数:
这个函数在PHP3中就出现了,是一个效率很高的函数,他有一个非常有用的功能就是刷新browser的cache.我们举一个运行效果非常明显的例子来说明flush.
Example 2.
CODE<?php
for($i = 1; $i <= 300; $i++ ) print(" ");
// 这一句话非常关键,cache的结构使得它的内容只有达到一定的大小才能从浏览器里输出
// 换言之,如果cache的内容不达到一定的大小,它是不会在程序执行完毕前输出的。经
// 过测试,我发现这个大小的底限是256个字符长。这意味着cache以后接收的内容都会
// 源源不断的被发送出去。
For($j = 1; $j <= 20; $j++) {
echo $j."
";
flush(); //这一部会使cache新增的内容被挤出去,显示到浏览器上
sleep(1); //让程序"睡"一秒钟,会让你把效果看得更清楚
}
?>
具体效果你可以到这里看看http://www.php2000.com/~uchinaboy/out.php
PHP2000的最新的PHP聊天室就是用的这个技术,可惜的是源代码未公开 L
注:如果在程序的首部加入ob_implicit_flush()打开绝对刷新,就可以在程序中不再使用flush(),这样做的好处是:提高效率!
2. 关于ob系列函数:
我想先引用我的好朋友y10k的一个例子:
Example 3.
比如你用得到服务器和客户端的设置信息,但是这个信息会因为客户端的不同而不同,如果想要保存phpinfo()函数的输出怎么办呢?在没有缓冲区控制之前,可以说一点办法也没有,但是有了缓冲区的控制,我们可以轻松的解决:
CODE<?php
ob_start(); //打开缓冲区
phpinfo(); //使用phpinfo函数
$info=ob_get_contents(); //得到缓冲区的内容并且赋值给$info
$file=fopen(\'info.txt\',\'w\'); //打开文件info.txt
fwrite($file,$info); //写入信息到info.txt
fclose($file); //关闭文件info.txt
?>
用以上的方法,就可以把不同用户的phpinfo信息保存下来,这在以前恐怕没有办法办到!其实上面就是将一些"过程"转化为"函数"的方法!
或许有人会问:"难道就这个样子吗?还有没有其他用途?"当然有了,比如笔者论坛的PHP 语法加亮显示就和这个有关(PHP默认的语法加亮显示函数会直接输出,不能保存结果,如果在每次调用都显示恐怕会很浪费CPU,笔者的论坛就把语法加亮函数显示的结果用控制缓冲区的方法保留了),大家如果感兴趣的话可以来看看http://www.zphp.com/bbs/!
可能现在大家对ob_start()的功能有了一定的了解,上面的一个例子看似简单,但实际上已经掌握了使用ob_start()的要点。
<1>.使用ob_start打开browser的cache,这样可以保证cache的内容在你调用flush(),ob_end_flush()(或程序执行完毕)之前不会被输出。
< 2>.现在的你应该知道你所拥有的优势:可以在任何输出内容后面使用header,setcookie以及session,这是ob_start一个很大的特点;也可以使用ob_start的参数,在cache被写入后,然后自动运行命令,比如ob_start(\"ob_gzhandler\ ");而我们最常用的做法是用ob_get_contents()得到cache中的内容,然后再进行处理……
<3>.当处理完毕后,我们可以使用各种方法输出,flush(),ob_end_flush(),以及等到程序执行完毕后的自动输出。当然,如果你用的是ob_get_contents(),那么就要你自己控制输出方式了。
来,让我们看看能用ob系列函数做些什么……
一、 静态模版技术
简介:所谓静态模版技术就是通过某种方式,使得用户在client端得到的是由PHP产生的html页面。如果这个html页面不会再被更新,那么当另外的用户再次浏览此页面时,程序将不会再调用PHP以及相关的数据库,对于某些信息量比较大的网站,例如sina,163,sohu。类似这种的技术带来的好处是非常巨大的。
我所知道的实现静态输出的有两种办法:
<1>.通过y10k修改的phplib的一个叫template.inc.php类实现。
<2>.使用ob系列函数实现。
对于第一种方法,因为不是这篇文章所要研究的问题,所以不再赘述。
我们现在来看一看第二种方法的具体实现:
Example 4.
CODE<?php
ob_start();//打开缓冲区
?>
php页面的全部输出
<?
$content = ob_get_contents();//取得php页面输出的全部内容
$fp = fopen("output00001.html", "w"); //创建一个文件,并打开,准备写入
fwrite($fp, $content); //把php页面的内容全部写入output00001.html,然后……
fclose($fp);
?>
这样,所谓的静态模版就很容易的被实现了……
二、 捕捉输出
以上的Example 4.是一种最简单的情况,你还可以在写入前对$content进行操作……
你可以设法捕捉一些关键字,然后去对它进行再处理,比如Example 3.所述的PHP语法高亮显示。个人认为,这个功能是此函数最大的精华所在,它可以解决各种各样的问题,但需要你有足够的想象力……
Example 5.
CODE<?
Function run_code($code) {
If($code) {
ob_start();
eval($code);
$contents = ob_get_contents();
ob_end_clean();
}else {
echo "错误!没有输出";
exit();
}
return $contents;
}
以上这个例子的用途不是很大,不过很典型$code的本身就是一个含有变量的输出页面,而这个例子用eval把$code中的变量替换,然后对输出结果再进行输出捕捉,再一次的进行处理……
Example 6. 加快传输
CODE<?
/*
** Title.........: PHP4 HTTP Compression Speeds up the Web
** Version.......: 1.20
** Author........: catoc <catoc@163.net>
** Filename......: gzdoc.php
** Last changed..: 18/10/2000
** Requirments...: PHP4 >= 4.0.1
** PHP was configured with --with-zlib[=DIR]
** Notes.........: Dynamic Content Acceleration compresses
** the data transmission data on the fly
** code by sun jin hu (catoc) <catoc@163.net>
** Most newer browsers since 1998/1999 have
** been equipped to support the HTTP 1.1
** standard known as \"content-encoding.\"
** Essentially the browser indicates to the
** server that it can accept \"content encoding\"
** and if the server is capable it will then
** compress the data and transmit it. The
** browser decompresses it and then renders
** the page.
**
** Modified by John Lim (jlim@natsoft.com.my)
** based on ideas by Sandy McArthur, Jr
** Usage........:
** No space before the beginning of the first \'<?\' tag.
** ------------Start of file----------
** |<?
** | include(\'gzdoc.php\');
** |? >
** |<HTML>
** |... the page ...
** |</HTML>
** |<?
** | gzdocout();
** |? >
** -------------End of file-----------
*/
ob_start();
ob_implicit_flush(0);
function CheckCanGzip(){
global $HTTP_ACCEPT_ENCODING;
if (headers_sent() || connection_timeout() || connection_aborted()){
return 0;
}
if (strpos($HTTP_ACCEPT_ENCODING, \'x-gzip\') !== false) return \"x-gzip\";
if (strpos($HTTP_ACCEPT_ENCODING,\'gzip\') !== false) return \"gzip\";
return 0;
}
/* $level = compression level 0-9, 0=none, 9=max */
function GzDocOut($level=1,$debug=0){
$ENCODING = CheckCanGzip();
if ($ENCODING){
print \"n<!-- Use compress $ENCODING -->n\";
$Contents = ob_get_contents();
ob_end_clean();
if ($debug){
$s = \"<p>Not compress length: \".strlen($Contents);
$s .= \"
Compressed length: \".strlen(gzcompress($Contents,$level));
$Contents .= $s;
}
header(\"Content-Encoding: $ENCODING\");
print \"x1fx8bx08x00x00x00x00x00\";
$Size = strlen($Contents);
$Crc = crc32($Contents);
$Contents = gzcompress($Contents,$level);
$Contents = substr($Contents, 0, strlen($Contents) - 4);
print $Contents;
print pack(\'V\',$Crc);
print pack(\'V\',$Size);
exit;
}else{
ob_end_flush();
exit;
}
}
?>
这是catoc的一段很早以前的代码,是在weblogs.com看到的,他利用了zlib的函数,对传输的内容进行了压缩,测试表明,对于10k以上的页面,会产生效果,而且页面越大,效果越明显…
Output Control 函数可以让你自由控制脚本中数据的输出。它非常地有用,特别是对于:当你想在数据已经输出后,再输出文件头的情况。输出控制函数不对使用 header() 或 setcookie(), 发送的文件头信息产生影响,只对那些类似于 echo() 和 PHP 代码的数据块有作用。
我们先举一个简单的例子,让大家对Output Control有一个大致的印象:
Example 1.
所有对header()函数有了解的人都知道,这个函数会发送一段文件头给浏览器,但是如果在使用这个函数之前已经有了任何输出(包括空输出,比如空格,回车和换行)就会提示出错。如果我们去掉第一行的ob_start(),再执行此程序,我们会发现得到了一条错误提示:"Header had all ready send by"!但是加上ob_start,就不会提示出错,原因是当打开了缓冲区,echo后面的字符不会输出到浏览器,而是保留在服务器,直到你使用 flush或者ob_end_flush才会输出,所以并不会有任何文件头输出的错误!
一、 相关函数简介:
1、Flush:刷新缓冲区的内容,输出。
函数格式:flush()
说明:这个函数经常使用,效率很高。
2、ob_start :打开输出缓冲区
函数格式:void ob_start(void)
说明:当缓冲区激活时,所有来自PHP程序的非文件头信息均不会发送,而是保存在内部缓冲区。为了输出缓冲区的内容,可以使用ob_end_flush()或flush()输出缓冲区的内容。
3 、ob_get_contents :返回内部缓冲区的内容。
使用方法:string ob_get_contents(void)
说明:这个函数会返回当前缓冲区中的内容,如果输出缓冲区没有激活,则返回 FALSE 。
4、ob_get_length:返回内部缓冲区的长度。
使用方法:int ob_get_length(void)
说明:这个函数会返回当前缓冲区中的长度;和ob_get_contents一样,如果输出缓冲区没有激活。则返回 FALSE。
5、ob_end_flush :发送内部缓冲区的内容到浏览器,并且关闭输出缓冲区。
使用方法:void ob_end_flush(void)
说明:这个函数发送输出缓冲区的内容(如果有的话)。
6、ob_end_clean:删除内部缓冲区的内容,并且关闭内部缓冲区
使用方法:void ob_end_clean(void)
说明:这个函数不会输出内部缓冲区的内容而是把它删除!
7、ob_implicit_flush:打开或关闭绝对刷新
使用方法:void ob_implicit_flush ([int flag])
说明:使用过Perl的人都知道$|=x的意义,这个字符串可以打开/关闭缓冲区,而ob_implicit_flush函数也和那个一样,默认为关闭缓冲区,打开绝对输出后,每个脚本输出都直接发送到浏览器,不再需要调用 flush()
二、深入了解:
1. 关于Flush函数:
这个函数在PHP3中就出现了,是一个效率很高的函数,他有一个非常有用的功能就是刷新browser的cache.我们举一个运行效果非常明显的例子来说明flush.
Example 2.
CODE<?php
for($i = 1; $i <= 300; $i++ ) print(" ");
// 这一句话非常关键,cache的结构使得它的内容只有达到一定的大小才能从浏览器里输出
// 换言之,如果cache的内容不达到一定的大小,它是不会在程序执行完毕前输出的。经
// 过测试,我发现这个大小的底限是256个字符长。这意味着cache以后接收的内容都会
// 源源不断的被发送出去。
For($j = 1; $j <= 20; $j++) {
echo $j."
";
flush(); //这一部会使cache新增的内容被挤出去,显示到浏览器上
sleep(1); //让程序"睡"一秒钟,会让你把效果看得更清楚
}
?>
具体效果你可以到这里看看http://www.php2000.com/~uchinaboy/out.php
PHP2000的最新的PHP聊天室就是用的这个技术,可惜的是源代码未公开 L
注:如果在程序的首部加入ob_implicit_flush()打开绝对刷新,就可以在程序中不再使用flush(),这样做的好处是:提高效率!
2. 关于ob系列函数:
我想先引用我的好朋友y10k的一个例子:
Example 3.
比如你用得到服务器和客户端的设置信息,但是这个信息会因为客户端的不同而不同,如果想要保存phpinfo()函数的输出怎么办呢?在没有缓冲区控制之前,可以说一点办法也没有,但是有了缓冲区的控制,我们可以轻松的解决:
CODE<?php
ob_start(); //打开缓冲区
phpinfo(); //使用phpinfo函数
$info=ob_get_contents(); //得到缓冲区的内容并且赋值给$info
$file=fopen(\'info.txt\',\'w\'); //打开文件info.txt
fwrite($file,$info); //写入信息到info.txt
fclose($file); //关闭文件info.txt
?>
用以上的方法,就可以把不同用户的phpinfo信息保存下来,这在以前恐怕没有办法办到!其实上面就是将一些"过程"转化为"函数"的方法!
或许有人会问:"难道就这个样子吗?还有没有其他用途?"当然有了,比如笔者论坛的PHP 语法加亮显示就和这个有关(PHP默认的语法加亮显示函数会直接输出,不能保存结果,如果在每次调用都显示恐怕会很浪费CPU,笔者的论坛就把语法加亮函数显示的结果用控制缓冲区的方法保留了),大家如果感兴趣的话可以来看看http://www.zphp.com/bbs/!
可能现在大家对ob_start()的功能有了一定的了解,上面的一个例子看似简单,但实际上已经掌握了使用ob_start()的要点。
<1>.使用ob_start打开browser的cache,这样可以保证cache的内容在你调用flush(),ob_end_flush()(或程序执行完毕)之前不会被输出。
< 2>.现在的你应该知道你所拥有的优势:可以在任何输出内容后面使用header,setcookie以及session,这是ob_start一个很大的特点;也可以使用ob_start的参数,在cache被写入后,然后自动运行命令,比如ob_start(\"ob_gzhandler\ ");而我们最常用的做法是用ob_get_contents()得到cache中的内容,然后再进行处理……
<3>.当处理完毕后,我们可以使用各种方法输出,flush(),ob_end_flush(),以及等到程序执行完毕后的自动输出。当然,如果你用的是ob_get_contents(),那么就要你自己控制输出方式了。
来,让我们看看能用ob系列函数做些什么……
一、 静态模版技术
简介:所谓静态模版技术就是通过某种方式,使得用户在client端得到的是由PHP产生的html页面。如果这个html页面不会再被更新,那么当另外的用户再次浏览此页面时,程序将不会再调用PHP以及相关的数据库,对于某些信息量比较大的网站,例如sina,163,sohu。类似这种的技术带来的好处是非常巨大的。
我所知道的实现静态输出的有两种办法:
<1>.通过y10k修改的phplib的一个叫template.inc.php类实现。
<2>.使用ob系列函数实现。
对于第一种方法,因为不是这篇文章所要研究的问题,所以不再赘述。
我们现在来看一看第二种方法的具体实现:
Example 4.
CODE<?php
ob_start();//打开缓冲区
?>
php页面的全部输出
<?
$content = ob_get_contents();//取得php页面输出的全部内容
$fp = fopen("output00001.html", "w"); //创建一个文件,并打开,准备写入
fwrite($fp, $content); //把php页面的内容全部写入output00001.html,然后……
fclose($fp);
?>
这样,所谓的静态模版就很容易的被实现了……
二、 捕捉输出
以上的Example 4.是一种最简单的情况,你还可以在写入前对$content进行操作……
你可以设法捕捉一些关键字,然后去对它进行再处理,比如Example 3.所述的PHP语法高亮显示。个人认为,这个功能是此函数最大的精华所在,它可以解决各种各样的问题,但需要你有足够的想象力……
Example 5.
CODE<?
Function run_code($code) {
If($code) {
ob_start();
eval($code);
$contents = ob_get_contents();
ob_end_clean();
}else {
echo "错误!没有输出";
exit();
}
return $contents;
}
以上这个例子的用途不是很大,不过很典型$code的本身就是一个含有变量的输出页面,而这个例子用eval把$code中的变量替换,然后对输出结果再进行输出捕捉,再一次的进行处理……
Example 6. 加快传输
CODE<?
/*
** Title.........: PHP4 HTTP Compression Speeds up the Web
** Version.......: 1.20
** Author........: catoc <catoc@163.net>
** Filename......: gzdoc.php
** Last changed..: 18/10/2000
** Requirments...: PHP4 >= 4.0.1
** PHP was configured with --with-zlib[=DIR]
** Notes.........: Dynamic Content Acceleration compresses
** the data transmission data on the fly
** code by sun jin hu (catoc) <catoc@163.net>
** Most newer browsers since 1998/1999 have
** been equipped to support the HTTP 1.1
** standard known as \"content-encoding.\"
** Essentially the browser indicates to the
** server that it can accept \"content encoding\"
** and if the server is capable it will then
** compress the data and transmit it. The
** browser decompresses it and then renders
** the page.
**
** Modified by John Lim (jlim@natsoft.com.my)
** based on ideas by Sandy McArthur, Jr
** Usage........:
** No space before the beginning of the first \'<?\' tag.
** ------------Start of file----------
** |<?
** | include(\'gzdoc.php\');
** |? >
** |<HTML>
** |... the page ...
** |</HTML>
** |<?
** | gzdocout();
** |? >
** -------------End of file-----------
*/
ob_start();
ob_implicit_flush(0);
function CheckCanGzip(){
global $HTTP_ACCEPT_ENCODING;
if (headers_sent() || connection_timeout() || connection_aborted()){
return 0;
}
if (strpos($HTTP_ACCEPT_ENCODING, \'x-gzip\') !== false) return \"x-gzip\";
if (strpos($HTTP_ACCEPT_ENCODING,\'gzip\') !== false) return \"gzip\";
return 0;
}
/* $level = compression level 0-9, 0=none, 9=max */
function GzDocOut($level=1,$debug=0){
$ENCODING = CheckCanGzip();
if ($ENCODING){
print \"n<!-- Use compress $ENCODING -->n\";
$Contents = ob_get_contents();
ob_end_clean();
if ($debug){
$s = \"<p>Not compress length: \".strlen($Contents);
$s .= \"
Compressed length: \".strlen(gzcompress($Contents,$level));
$Contents .= $s;
}
header(\"Content-Encoding: $ENCODING\");
print \"x1fx8bx08x00x00x00x00x00\";
$Size = strlen($Contents);
$Crc = crc32($Contents);
$Contents = gzcompress($Contents,$level);
$Contents = substr($Contents, 0, strlen($Contents) - 4);
print $Contents;
print pack(\'V\',$Crc);
print pack(\'V\',$Size);
exit;
}else{
ob_end_flush();
exit;
}
}
?>
这是catoc的一段很早以前的代码,是在weblogs.com看到的,他利用了zlib的函数,对传输的内容进行了压缩,测试表明,对于10k以上的页面,会产生效果,而且页面越大,效果越明显…
在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能。
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1): 为了与 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。
mysql> SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15
//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.
//如果只给定一个参数,它表示返回最大的记录行数目:
mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行
//换句话说,LIMIT n 等价于 LIMIT 0,n。
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.
$start = $offset * ($page-1);
$limit = $start.','.$offset;
$sql = 'SELECT * FROM record '.$where.' ORDER BY ctime DESC LIMIT '.$limit;
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset
LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1): 为了与 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。
mysql> SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15
//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.
//如果只给定一个参数,它表示返回最大的记录行数目:
mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行
//换句话说,LIMIT n 等价于 LIMIT 0,n。
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.
$start = $offset * ($page-1);
$limit = $start.','.$offset;
$sql = 'SELECT * FROM record '.$where.' ORDER BY ctime DESC LIMIT '.$limit;
大 多数人都知道爱迪生有句名言:天才是99%的汗水加上1%的灵感。今天在网上看到一篇文章,有人在文章的回复部分提到,爱迪生这句名言本身不是这样,是教 科书断章取义,爱迪生的原话因该是:天才是1%的灵感加上99%的汗水,但1%的灵感最重要,甚至比99%的汗水都重要。
很显然,如果加上后面的话,两种名言的版本表达的是完全不同的立场,但到底是不是这样呢?
随即到Google中查了一下,这篇文章:《中国教材:为什么要篡改爱迪生和爱因斯坦的名言?》可能是后一种名言版本的导火索,论证很充分,似乎是真的?但在这篇文章的评论处,有人以事实推翻了论证:
链接2: http://www.ortolon.com/articles_sterling_inspiration.htm
一开头便是这么写的:
“Inspiration and Perspiration
By Cindi Myers
Thomas Edison said, “Genius is one percent inspiration and ninety-nine percent perspiration.”
Without the one percent of inspiration, all the perspiration in the world is only a bucket of sweat….”
这后一段话翻译过来,跟原文所讲的那段加长版的名言非常贴切,想必应是原文理论之根据了。然而谁都不可能忽略的是:“没有1%的灵感,所有的汗水……”这句话并不在爱迪生名言的引号之内!
注意上面的标题
Inspiration and Perspiration
By Cindi Myers
已明确指出此文是Cindi Myers所写的一篇议论文。所以引号外的话不过是Cindi Myers的一句评价罢了。可惜口牙。
我想至此,考究结束,出处应该就是这里了。原文作者一开始便站在了错误的论据上。
不过,在我看来,论点却是好的……
该评论的作者摆出了事实,英文原句是否如他所说呢?随即到Google中搜索:Genius is one percent inspiration and ninety-nine percent perspiration,在出现的英文搜索结果中,几乎就是这句原话,没有所谓的“但1%的灵感最重要,甚至比99%的汗水都重要”的意思, 呵呵~~,在此可以确信,持第二种名言版本观点的人原来也有点断章取义了,教科书并没有更改爱迪生的名言。
说实话,当我看到第二种版本的时候,我有点信了,如果没有后面的确认,我可能还会给别人讲之前的爱迪生名言是错的,应该是什么什么等等。所以, 网上的信息应该有选择性地来吸收,不能见风是风,见雨是雨,即使是非常有“正义感”、感觉非常“权威”的那种,否则的话,只能是以讹传讹!
很显然,如果加上后面的话,两种名言的版本表达的是完全不同的立场,但到底是不是这样呢?
随即到Google中查了一下,这篇文章:《中国教材:为什么要篡改爱迪生和爱因斯坦的名言?》可能是后一种名言版本的导火索,论证很充分,似乎是真的?但在这篇文章的评论处,有人以事实推翻了论证:
链接2: http://www.ortolon.com/articles_sterling_inspiration.htm
一开头便是这么写的:
“Inspiration and Perspiration
By Cindi Myers
Thomas Edison said, “Genius is one percent inspiration and ninety-nine percent perspiration.”
Without the one percent of inspiration, all the perspiration in the world is only a bucket of sweat….”
这后一段话翻译过来,跟原文所讲的那段加长版的名言非常贴切,想必应是原文理论之根据了。然而谁都不可能忽略的是:“没有1%的灵感,所有的汗水……”这句话并不在爱迪生名言的引号之内!
注意上面的标题
Inspiration and Perspiration
By Cindi Myers
已明确指出此文是Cindi Myers所写的一篇议论文。所以引号外的话不过是Cindi Myers的一句评价罢了。可惜口牙。
我想至此,考究结束,出处应该就是这里了。原文作者一开始便站在了错误的论据上。
不过,在我看来,论点却是好的……
该评论的作者摆出了事实,英文原句是否如他所说呢?随即到Google中搜索:Genius is one percent inspiration and ninety-nine percent perspiration,在出现的英文搜索结果中,几乎就是这句原话,没有所谓的“但1%的灵感最重要,甚至比99%的汗水都重要”的意思, 呵呵~~,在此可以确信,持第二种名言版本观点的人原来也有点断章取义了,教科书并没有更改爱迪生的名言。
说实话,当我看到第二种版本的时候,我有点信了,如果没有后面的确认,我可能还会给别人讲之前的爱迪生名言是错的,应该是什么什么等等。所以, 网上的信息应该有选择性地来吸收,不能见风是风,见雨是雨,即使是非常有“正义感”、感觉非常“权威”的那种,否则的话,只能是以讹传讹!





