背景:当使用对字符串验证的土图片破解后,有用snoopy去伪装请求,如下:破解完成上面的验证码,我们就可以使用snoopy(比curl要轻量,所以我喜欢)来模拟浏览器器,访问网站了。
来自:
http://blog.csdn.net/ugg/article/details/3953137
http://blog.csdn.net/ugg/article/details/3972368
snoopy是一个php类,用来模仿web浏览器的功能,它能完成获取网页内容和发送表单的任务。
下面是它的一些特征:
1、方便抓取网页的内容
2、方便抓取网页的文字(去掉HTML代码)
3、方便抓取网页的链接
4、支持代理主机
5、支持基本的用户/密码认证模式
6、支持自定义用户agent,referer,cookies和header内容
7、支持浏览器转向,并能控制转向深度
8、能把网页中的链接扩展成高质量的url(默认)
9、方便提交数据并且获取返回值
10、支持跟踪HTML框架(v0.92增加)
11、支持再转向的时候传递cookies
下面是简单的例子,比如说我们抓取我的blog的文字
^_^,不错把,在比如抓取链接
使用snoopy提交数据实现登陆
模拟登陆可以用curl或者socket来实现,当curl需要服务器相应的启用curl module,自己socket实现相对比较麻烦,使用snoopy就简单了很多啦。
在这里,我们使用喜悦国际村做为例子。(^_^,纯属研究)
首先,我们要获取到登陆需要发送什么字段,目标地址是什么。这里我们使用snoopy的fetchform来实现。
当然你也可以直接查看http://www.jackxiang.com/happy/…的源代码来实现,不过这样更加方便把。这里,我们获取到目标和提交的数据,下一步就可以实现模拟登陆了。代码如下:
参考使用php snoopy 类模拟GET/POST请求:http://outofmemory.cn/code-snippet/2463/usage-php-snoopy-class-moni-GET-POST-request
Download 类名:http://sourceforge.net/projects/snoopy/
代码参考:http://www.nowamagic.net/librarys/veda/detail/855
来自:
http://blog.csdn.net/ugg/article/details/3953137
http://blog.csdn.net/ugg/article/details/3972368
snoopy是一个php类,用来模仿web浏览器的功能,它能完成获取网页内容和发送表单的任务。
下面是它的一些特征:
1、方便抓取网页的内容
2、方便抓取网页的文字(去掉HTML代码)
3、方便抓取网页的链接
4、支持代理主机
5、支持基本的用户/密码认证模式
6、支持自定义用户agent,referer,cookies和header内容
7、支持浏览器转向,并能控制转向深度
8、能把网页中的链接扩展成高质量的url(默认)
9、方便提交数据并且获取返回值
10、支持跟踪HTML框架(v0.92增加)
11、支持再转向的时候传递cookies
下面是简单的例子,比如说我们抓取我的blog的文字
include "Snoopy.class.php";
$snoopy = new Snoopy;
$snoopy->fetchtext("http://www.phpobject.net/blog");
echo $snoopy->results;
$snoopy = new Snoopy;
$snoopy->fetchtext("http://www.phpobject.net/blog");
echo $snoopy->results;
^_^,不错把,在比如抓取链接
include "Snoopy.class.php";
$snoopy = new Snoopy;
$snoopy->fetchlinks("http://www.phpobject.net/blog");
print_r($snoopy->results);
$snoopy = new Snoopy;
$snoopy->fetchlinks("http://www.phpobject.net/blog");
print_r($snoopy->results);
使用snoopy提交数据实现登陆
模拟登陆可以用curl或者socket来实现,当curl需要服务器相应的启用curl module,自己socket实现相对比较麻烦,使用snoopy就简单了很多啦。
在这里,我们使用喜悦国际村做为例子。(^_^,纯属研究)
首先,我们要获取到登陆需要发送什么字段,目标地址是什么。这里我们使用snoopy的fetchform来实现。
include "Snoopy.class.php";
$snoopy = new Snoopy;
$snoopy->fetchform("http://www.jackxiang.com/happy/logging.php?action=login");
print $snoopy->results;
$snoopy = new Snoopy;
$snoopy->fetchform("http://www.jackxiang.com/happy/logging.php?action=login");
print $snoopy->results;
当然你也可以直接查看http://www.jackxiang.com/happy/…的源代码来实现,不过这样更加方便把。这里,我们获取到目标和提交的数据,下一步就可以实现模拟登陆了。代码如下:
include "Snoopy.class.php";
$snoopy = new Snoopy;
$submit_url = "http://www.jackxiang.com/happy/logging.php?action=login";
$submit_vars["loginmode"] = "normal";
$submit_vars["styleid"] = "1";
$submit_vars["cookietime"] = "315360000";
$submit_vars["loginfield"] = "username";
$submit_vars["username"] = "********"; //你的用户名
$submit_vars["password"] = "*******"; //你的密码
$submit_vars["questionid"] = "0";
$submit_vars["answer"] = "";
$submit_vars["loginsubmit"] = "提 交";
$snoopy->submit($submit_url,$submit_vars);
print $snoopy->results;
^_^,是不是显示你已经登陆了?使用snoopy就是这么简单!$snoopy = new Snoopy;
$submit_url = "http://www.jackxiang.com/happy/logging.php?action=login";
$submit_vars["loginmode"] = "normal";
$submit_vars["styleid"] = "1";
$submit_vars["cookietime"] = "315360000";
$submit_vars["loginfield"] = "username";
$submit_vars["username"] = "********"; //你的用户名
$submit_vars["password"] = "*******"; //你的密码
$submit_vars["questionid"] = "0";
$submit_vars["answer"] = "";
$submit_vars["loginsubmit"] = "提 交";
$snoopy->submit($submit_url,$submit_vars);
print $snoopy->results;
参考使用php snoopy 类模拟GET/POST请求:http://outofmemory.cn/code-snippet/2463/usage-php-snoopy-class-moni-GET-POST-request
Download 类名:http://sourceforge.net/projects/snoopy/
代码参考:http://www.nowamagic.net/librarys/veda/detail/855
来源:http://blog.s135.com/tcsql/
1、编译安装TCSQL需要的扩展库
wget http://www.monkey.org/~provos/libevent-1.4.12-stable.tar.gz
tar zxvf libevent-1.4.12-stable.tar.gz
cd libevent-1.4.12-stable/
./configure --prefix=/usr
make && make install
cd ../
wget http://oss.metaparadigm.com/json-c/json-c-0.9.tar.gz
tar zxvf json-c-0.9.tar.gz
cd json-c-0.9/
./configure --prefix=/usr/local/json-c-0.9
make && make install
cd ../
wget http://www.1978th.net/tokyocabinet/tokyocabinet-1.4.33.tar.gz
tar zxvf tokyocabinet-1.4.33.tar.gz
cd tokyocabinet-1.4.33/
./configure --prefix=/usr/local/tokyocabinet-1.4.33
make && make install
cd ../
echo "/usr/local/json-c-0.9/lib/" > /etc/ld.so.conf.d/json-c-0.9.conf
echo "/usr/local/tokyocabinet-1.4.33/lib/" > /etc/ld.so.conf.d/tokyocabinet-1.4.33.conf
/sbin/ldconfig
2、编译TCSQL数据库
注:二进制程序及源码目前只对金山公司内部开放。
gcc -o tcsql tcsql.c -levent -ljson -I/usr/local/json-c-0.9/include/json/ -L/usr/local/json-c-0.9/lib/ -ltokyocabinet -lz -lbz2 -lrt -lpthread -lm -lc -I/usr/local/tokyocabinet-1.4.33/include/ -L/usr/local/tokyocabinet-1.4.33/lib/
二、TCSQL数据库的启动
1、以自定义方式,作为守护进程启动:
ulimit -SHn 65535
./tcsql -l 192.168.8.34 -p 3888 -x /data0/tcsql/data -t 3 -d
2、以默认值,作为守护进程启动:
ulimit -SHn 65535
./tcsql -d
注:请确保文件描述符数量够用(系统默认值为1024),以便TCSQL承担上万连接数的并发访问。
1、编译安装TCSQL需要的扩展库
wget http://www.monkey.org/~provos/libevent-1.4.12-stable.tar.gz
tar zxvf libevent-1.4.12-stable.tar.gz
cd libevent-1.4.12-stable/
./configure --prefix=/usr
make && make install
cd ../
wget http://oss.metaparadigm.com/json-c/json-c-0.9.tar.gz
tar zxvf json-c-0.9.tar.gz
cd json-c-0.9/
./configure --prefix=/usr/local/json-c-0.9
make && make install
cd ../
wget http://www.1978th.net/tokyocabinet/tokyocabinet-1.4.33.tar.gz
tar zxvf tokyocabinet-1.4.33.tar.gz
cd tokyocabinet-1.4.33/
./configure --prefix=/usr/local/tokyocabinet-1.4.33
make && make install
cd ../
echo "/usr/local/json-c-0.9/lib/" > /etc/ld.so.conf.d/json-c-0.9.conf
echo "/usr/local/tokyocabinet-1.4.33/lib/" > /etc/ld.so.conf.d/tokyocabinet-1.4.33.conf
/sbin/ldconfig
2、编译TCSQL数据库
注:二进制程序及源码目前只对金山公司内部开放。
gcc -o tcsql tcsql.c -levent -ljson -I/usr/local/json-c-0.9/include/json/ -L/usr/local/json-c-0.9/lib/ -ltokyocabinet -lz -lbz2 -lrt -lpthread -lm -lc -I/usr/local/tokyocabinet-1.4.33/include/ -L/usr/local/tokyocabinet-1.4.33/lib/
二、TCSQL数据库的启动
1、以自定义方式,作为守护进程启动:
ulimit -SHn 65535
./tcsql -l 192.168.8.34 -p 3888 -x /data0/tcsql/data -t 3 -d
2、以默认值,作为守护进程启动:
ulimit -SHn 65535
./tcsql -d
注:请确保文件描述符数量够用(系统默认值为1024),以便TCSQL承担上万连接数的并发访问。
很高兴能够看到这个时候mysql还能出个新版本,mysql 5.5.0是所谓的milestone version,这次带来了一些有趣的东西,按照重要程度(我主观上的)列一下:
◦支持Semisynchronous Replication,这个是从早期google的semi-sync patch转过来的,能够做到master-slave的半同步复制
◦集成Innodb plugin 1.0.6
◦新的partition语法
这个版本还不适合用在正式环境。想想以后也许可以用mysql mmm + mysql 5.5提供可用性更好的服务,前提是它已经足够稳定,或者是percona版本?
http://dev.mysql.com/downloads/mysql/5.5.html
官方不建议用于production环境
MySQL是现在最流行的开放源代码数据库.绝大多数PHP网站的数据库后台都是采用这一数据库.是一个多线程的,结构化查询语言(SQL)数据库服务器.MySQL 的执行性能非常高,运行速度非常快,并非常容易使用.是一个非常捧的数据库.
近日,关于Oracle收购Sun后MySQL将如何发展的问题可谓是热点新闻,很高兴能够看到这个时候mysql还能出个新版 本,而原来的 MySQL 5.4 在官网上已经没有链接,看来是升级为 5.5 版本了,官网上同时还提供一个从 5.4 升级到 5.5 的指南。MySQL 5.5.0是所谓的里程碑版本,这次带来了一些有趣的东西,按照重要程度(我主观上的)列一下:
* 支持半同步复制,这个是从早期google 的semi-sync patch转过来的,能够做到master-slave的半同步复制
* 集成Innodb plugin 1.0.6
* 支持 SQL 标准 SIGNAL 和 RESIGNAL 语句
* 增强XML功能,支持 LOAD XML 语句
* 可通过 ALTER TABLE … TRUNCATE PARTITION 来删除某个表在某个分区上的所有数据
* 增加了 TO_SECONDS 函数
* 新的 partition语法
* Key caches are now supported for indexes on partitioned MyISAM tables, using the CACHE INDEX and LOAD INDEX INTO CACHE statements
这个版本还不适合用在正式环境。想想以后也许可以用mysql mmm + mysql 5.5提供可用性更好的服务,前提是它已经足够稳定,或者是percona版本?
下载地址
5.5 版
http://dev.mysql.com/downloads/mysql/5.5.html
5.1 版
http://dev.mysql.com/downloads/mysql/5.1.html
◦支持Semisynchronous Replication,这个是从早期google的semi-sync patch转过来的,能够做到master-slave的半同步复制
◦集成Innodb plugin 1.0.6
◦新的partition语法
这个版本还不适合用在正式环境。想想以后也许可以用mysql mmm + mysql 5.5提供可用性更好的服务,前提是它已经足够稳定,或者是percona版本?
http://dev.mysql.com/downloads/mysql/5.5.html
官方不建议用于production环境
MySQL是现在最流行的开放源代码数据库.绝大多数PHP网站的数据库后台都是采用这一数据库.是一个多线程的,结构化查询语言(SQL)数据库服务器.MySQL 的执行性能非常高,运行速度非常快,并非常容易使用.是一个非常捧的数据库.
近日,关于Oracle收购Sun后MySQL将如何发展的问题可谓是热点新闻,很高兴能够看到这个时候mysql还能出个新版 本,而原来的 MySQL 5.4 在官网上已经没有链接,看来是升级为 5.5 版本了,官网上同时还提供一个从 5.4 升级到 5.5 的指南。MySQL 5.5.0是所谓的里程碑版本,这次带来了一些有趣的东西,按照重要程度(我主观上的)列一下:
* 支持半同步复制,这个是从早期google 的semi-sync patch转过来的,能够做到master-slave的半同步复制
* 集成Innodb plugin 1.0.6
* 支持 SQL 标准 SIGNAL 和 RESIGNAL 语句
* 增强XML功能,支持 LOAD XML 语句
* 可通过 ALTER TABLE … TRUNCATE PARTITION 来删除某个表在某个分区上的所有数据
* 增加了 TO_SECONDS 函数
* 新的 partition语法
* Key caches are now supported for indexes on partitioned MyISAM tables, using the CACHE INDEX and LOAD INDEX INTO CACHE statements
这个版本还不适合用在正式环境。想想以后也许可以用mysql mmm + mysql 5.5提供可用性更好的服务,前提是它已经足够稳定,或者是percona版本?
下载地址
5.5 版
http://dev.mysql.com/downloads/mysql/5.5.html
5.1 版
http://dev.mysql.com/downloads/mysql/5.1.html
PHP是目前网站开发中最受热捧的一款开源技术,最近发布了新版。该版本主要是提升了PHP5.3 的稳定性,修复了一些安全漏洞和bug。
主要修改位置如下:
Added "max_file_uploads" INI directive, which can be set to limit the number of file uploads per-request to 20 by default, to prevent possible DOS via temporary file exhaustion.
Added missing sanity checks around exif processing.
Fixed a safe_mode bypass in tempnam().
Fixed a open_basedir bypass in posix_mkfifo().
Fixed failing safe_mode_include_dir.
PHP团队建议所有PHP使用者升级至PHP 5.3.1。
详细内容请看ChangeLog:http://www.php.net/ChangeLog-5.php#5.3.1
下载地址:http://www.php.net/get/php-5.3.1.tar.gz/from/a/mirror
主要修改位置如下:
Added "max_file_uploads" INI directive, which can be set to limit the number of file uploads per-request to 20 by default, to prevent possible DOS via temporary file exhaustion.
Added missing sanity checks around exif processing.
Fixed a safe_mode bypass in tempnam().
Fixed a open_basedir bypass in posix_mkfifo().
Fixed failing safe_mode_include_dir.
PHP团队建议所有PHP使用者升级至PHP 5.3.1。
详细内容请看ChangeLog:http://www.php.net/ChangeLog-5.php#5.3.1
下载地址:http://www.php.net/get/php-5.3.1.tar.gz/from/a/mirror
主要问题:
Fedora13 Alpha版本内核版本为:
2.6.33-0.52.rc8.git6.fc13.i686.PAE
其下载地址为:
ftp://rpmfind.net/linux/fedora/releases/test/13-Alpha/Fedora/i386/os/Packages/kernel-devel-2.6.33-0.52.rc8.git6.fc13.i686.rpm
注:不同的版本可在此网站找到相应的文件。
----- 如果网络畅通,可以 运行 [ yum -y install kernel-devel ],进行安装就6M,很快
参考网页:http://www.51ciw.com/debian_install/09_VMwareTools/VMwareTools.htm
为什么要装 VMware Tools?
因为它可以改善 Virtual Machine 的运行性能,而且可以让 Host OS 和 Guest OS 互通有无,这样我们就不用伤脑筋,要架设什么服务器,来沟通两个 OS,现在就让我们开始吧!
VMware Tools所在位置:VMware 安装路径 \VMware\VMware Workstation\linux.iso
[root@rd01 ~]# mount /cdrom
# 有时可能加载不了,这时就要先将系统关闭,再手动指定 ISO 映像,看下图
[root@rd01 ~]# cd /cdrom
[root@rd01 ~]# ls -a
[root@rd01 ~]# cp VMwareTools-5.5.1-19175.tar.gz /tmp
[root@rd01 ~]# cd /tmp
[root@rd01 ~]# tar zxpf VMwareTools-5.5.1-19175.tar.gz
[root@rd01 ~]# cd vmware-tools-distrib
[root@rd01 vmware-tools-distrib]# ./vmware-install.pl
Creating a new installer database using the tar3 format.
Installing the content of the package.
# 安装过程的画面,全部使用默认值,一直按 Enter 就对了
In which directory do you want to install the binary files?
[/usr/bin]
What is the directory that contains the init directories (rc0.d/ to rc6.d/)?
[/etc/rc.d]
What is the directory that contains the init scripts?
[/etc/rc.d/init.d]
In which directory do you want to install the daemon files?
[/usr/sbin]
In which directory do you want to install the library files?
[/usr/lib/vmware-tools]
The path "/usr/lib/vmware-tools" does not exist currently. This program is goingto create it, including needed parent directories. Is this what you want?
[yes]
In which directory do you want to install the documentation files?
[/usr/share/doc/vmware-tools]
The path "/usr/share/doc/vmware-tools" does not exist currently. This program isgoing to create it, including needed parent directories. Is this what you want?
[yes]
The installation of VMware Tools 5.5.1 build-19175 for Linux completed
successfully. You can decide to remove this software from your system at any
time by invoking the following command: "/usr/bin/vmware-uninstall-tools.pl".
Before running VMware Tools for the first time, you need to configure it by
invoking the following command: "/usr/bin/vmware-config-tools.pl". Do you want
this program to invoke the command for you now? [yes]
Stopping VMware Tools services in the virtual machine:
Guest operating system daemon: [ 确定 ]
Trying to find a suitable vmhgfs module for your running kernel.
The module bld-2.6.9-5.EL-i686-RHEL4 loads perfectly in the running kernel.
pcnet32 30153 0
Unloading pcnet32 module
Trying to find a suitable vmxnet module for your running kernel.
The module bld-2.6.9-5.EL-i686-RHEL4 loads perfectly in the running kernel.
Detected X.org version 6.8.
关闭控制台鼠标服务: [ 确定 ]
启动控制台鼠标服务: [ 确定 ]
Please choose one of the following display sizes (1 - 13):
# 显示分辨率,这里是以 1024x768 为例
# VMware Tools 安装的时候,会自动修改 X server 的配置文件
[1] "640x480"
[2]< "800x600"
[3] "1024x768"
[4] "1152x864"
[5] "1280x800"
[6] "1152x900"
[7] "1280x1024"
[8] "1376x1032"
[9] "1400x1050"
[10] "1680x1050"
[11] "1600x1200"
[12] "1920x1200"
[13] "2364x1773"
Please enter a number between 1 and 13:
[2] 3
X Window System Version 6.8.2
Release Date: 9 February 2005
X Protocol Version 11, Revision 0, Release 6.8.2
Build Operating System: Linux 2.6.9-34.EL i686 [ELF]
Current Operating System: Linux rd01.domain 2.6.9-34.EL #1 Wed Mar 8 00:07:35 CST 2006 i686
Build Date: 04 May 2006
Build Host: x8664-build.centos.org
Before reporting problems, check http://wiki.X.Org
to make sure that you have the latest version.
Module Loader present
OS Kernel: Linux version 2.6.9-34.EL (buildcentos@build-i386) (gcc version 3.4.5 20051201 (Red Hat 3.4.5-2)) #1 Wed Mar 8 00:07:35 CST 2006 P
Markers: (--) probed, (**) from config file, (==) default setting,
(++) from command line, (!!) notice, (II) informational,
(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(++) Log file: "/tmp/vmware-config0/XF86ConfigLog.3131", Time: Mon Jun 12 20:57:34 2006
(++) Using config file: "/tmp/vmware-config0/XF86Config.3131"
(WW) VMWARE(0): Failed to set up write-combining range (0xf0000000,0x1000000)
X is running fine with the new config file.
Starting VMware Tools services in the virtual machine:
Switching to guest configuration: [ 确定 ]
Guest filesystem driver: [ 确定 ]
DMA setup: [ 确定 ]
Guest operating system daemon: [ 确定 ]
The configuration of VMware Tools 5.5.1 build-19175 for Linux for this running
kernel completed successfully.
You must restart your X session before any mouse or graphics changes take
effect.
You can now run VMware Tools by invoking the following command:
"/usr/bin/vmware-toolbox" during an XFree86 session.
To use the vmxnet driver, restart networking using the following commands:
/etc/init.d/network stop
rmmod pcnet32
rmmod vmxnet
depmod -a
modprobe vmxnet
/etc/init.d/network start
Enjoy,
--the VMware team
[root@rd01 vmware-tools-distrib]# shutdown -r now
# 修改完成之后,重新启动计算机,让 VMware Tools 生效
# 重新启动计算机之后,我们就会发觉到,当我们要离开 Guest OS 的时候,不再需要按 Ctrl + Alt 了,
# 现在我们来共享 Host OS 的文件夹给 Guest 使用,〔VM〕→〔设置 Ctrl + D〕
# 注:左下角原本都会显示「You do not have VMware Tools installed」,现在我们装了 VMware Tools,就不再显示了
# 这就是共享完毕的画面,然后我们就需要到 Guest OS 内,看看可不可以读取到刚刚共享的目录
# 顺利的话,我们只要到「/mnt/hgfs」文件夹,就可以看到刚刚共享的文件夹了
Fedora13 Alpha版本内核版本为:
2.6.33-0.52.rc8.git6.fc13.i686.PAE
其下载地址为:
ftp://rpmfind.net/linux/fedora/releases/test/13-Alpha/Fedora/i386/os/Packages/kernel-devel-2.6.33-0.52.rc8.git6.fc13.i686.rpm
注:不同的版本可在此网站找到相应的文件。
----- 如果网络畅通,可以 运行 [ yum -y install kernel-devel ],进行安装就6M,很快
参考网页:http://www.51ciw.com/debian_install/09_VMwareTools/VMwareTools.htm
为什么要装 VMware Tools?
因为它可以改善 Virtual Machine 的运行性能,而且可以让 Host OS 和 Guest OS 互通有无,这样我们就不用伤脑筋,要架设什么服务器,来沟通两个 OS,现在就让我们开始吧!
VMware Tools所在位置:VMware 安装路径 \VMware\VMware Workstation\linux.iso
[root@rd01 ~]# mount /cdrom
# 有时可能加载不了,这时就要先将系统关闭,再手动指定 ISO 映像,看下图
[root@rd01 ~]# cd /cdrom
[root@rd01 ~]# ls -a
[root@rd01 ~]# cp VMwareTools-5.5.1-19175.tar.gz /tmp
[root@rd01 ~]# cd /tmp
[root@rd01 ~]# tar zxpf VMwareTools-5.5.1-19175.tar.gz
[root@rd01 ~]# cd vmware-tools-distrib
[root@rd01 vmware-tools-distrib]# ./vmware-install.pl
Creating a new installer database using the tar3 format.
Installing the content of the package.
# 安装过程的画面,全部使用默认值,一直按 Enter 就对了
In which directory do you want to install the binary files?
[/usr/bin]
What is the directory that contains the init directories (rc0.d/ to rc6.d/)?
[/etc/rc.d]
What is the directory that contains the init scripts?
[/etc/rc.d/init.d]
In which directory do you want to install the daemon files?
[/usr/sbin]
In which directory do you want to install the library files?
[/usr/lib/vmware-tools]
The path "/usr/lib/vmware-tools" does not exist currently. This program is goingto create it, including needed parent directories. Is this what you want?
[yes]
In which directory do you want to install the documentation files?
[/usr/share/doc/vmware-tools]
The path "/usr/share/doc/vmware-tools" does not exist currently. This program isgoing to create it, including needed parent directories. Is this what you want?
[yes]
The installation of VMware Tools 5.5.1 build-19175 for Linux completed
successfully. You can decide to remove this software from your system at any
time by invoking the following command: "/usr/bin/vmware-uninstall-tools.pl".
Before running VMware Tools for the first time, you need to configure it by
invoking the following command: "/usr/bin/vmware-config-tools.pl". Do you want
this program to invoke the command for you now? [yes]
Stopping VMware Tools services in the virtual machine:
Guest operating system daemon: [ 确定 ]
Trying to find a suitable vmhgfs module for your running kernel.
The module bld-2.6.9-5.EL-i686-RHEL4 loads perfectly in the running kernel.
pcnet32 30153 0
Unloading pcnet32 module
Trying to find a suitable vmxnet module for your running kernel.
The module bld-2.6.9-5.EL-i686-RHEL4 loads perfectly in the running kernel.
Detected X.org version 6.8.
关闭控制台鼠标服务: [ 确定 ]
启动控制台鼠标服务: [ 确定 ]
Please choose one of the following display sizes (1 - 13):
# 显示分辨率,这里是以 1024x768 为例
# VMware Tools 安装的时候,会自动修改 X server 的配置文件
[1] "640x480"
[2]< "800x600"
[3] "1024x768"
[4] "1152x864"
[5] "1280x800"
[6] "1152x900"
[7] "1280x1024"
[8] "1376x1032"
[9] "1400x1050"
[10] "1680x1050"
[11] "1600x1200"
[12] "1920x1200"
[13] "2364x1773"
Please enter a number between 1 and 13:
[2] 3
X Window System Version 6.8.2
Release Date: 9 February 2005
X Protocol Version 11, Revision 0, Release 6.8.2
Build Operating System: Linux 2.6.9-34.EL i686 [ELF]
Current Operating System: Linux rd01.domain 2.6.9-34.EL #1 Wed Mar 8 00:07:35 CST 2006 i686
Build Date: 04 May 2006
Build Host: x8664-build.centos.org
Before reporting problems, check http://wiki.X.Org
to make sure that you have the latest version.
Module Loader present
OS Kernel: Linux version 2.6.9-34.EL (buildcentos@build-i386) (gcc version 3.4.5 20051201 (Red Hat 3.4.5-2)) #1 Wed Mar 8 00:07:35 CST 2006 P
Markers: (--) probed, (**) from config file, (==) default setting,
(++) from command line, (!!) notice, (II) informational,
(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(++) Log file: "/tmp/vmware-config0/XF86ConfigLog.3131", Time: Mon Jun 12 20:57:34 2006
(++) Using config file: "/tmp/vmware-config0/XF86Config.3131"
(WW) VMWARE(0): Failed to set up write-combining range (0xf0000000,0x1000000)
X is running fine with the new config file.
Starting VMware Tools services in the virtual machine:
Switching to guest configuration: [ 确定 ]
Guest filesystem driver: [ 确定 ]
DMA setup: [ 确定 ]
Guest operating system daemon: [ 确定 ]
The configuration of VMware Tools 5.5.1 build-19175 for Linux for this running
kernel completed successfully.
You must restart your X session before any mouse or graphics changes take
effect.
You can now run VMware Tools by invoking the following command:
"/usr/bin/vmware-toolbox" during an XFree86 session.
To use the vmxnet driver, restart networking using the following commands:
/etc/init.d/network stop
rmmod pcnet32
rmmod vmxnet
depmod -a
modprobe vmxnet
/etc/init.d/network start
Enjoy,
--the VMware team
[root@rd01 vmware-tools-distrib]# shutdown -r now
# 修改完成之后,重新启动计算机,让 VMware Tools 生效
# 重新启动计算机之后,我们就会发觉到,当我们要离开 Guest OS 的时候,不再需要按 Ctrl + Alt 了,
# 现在我们来共享 Host OS 的文件夹给 Guest 使用,〔VM〕→〔设置 Ctrl + D〕
# 注:左下角原本都会显示「You do not have VMware Tools installed」,现在我们装了 VMware Tools,就不再显示了
# 这就是共享完毕的画面,然后我们就需要到 Guest OS 内,看看可不可以读取到刚刚共享的目录
# 顺利的话,我们只要到「/mnt/hgfs」文件夹,就可以看到刚刚共享的文件夹了
Linux系统下使用USB转串口连接工业设备 在Windows下可以使用超级终端来连接交换机和路由器等工业设备,而且在Windows下使用usb转串口的线也有相应的驱动,但是如何在Linux下使用呢?
首先要有一个Linux下的终端软件叫minicom如果没有装这个的朋友可以到自己的源中去下载,然后你就要插上你的usb转串口的线,在 Linux下Usb转串口的线几乎不需要驱动,你插上以后在你的dev的目录下应该会有一个ttyUSB0的文件,如果有那么恭喜你了,你的这根线现在是可用的了。进入到终端输入su以root用户进行登录,使用minicom必须要用root用户,然后输入minicom -s 进行设置,进入设置界面以后你会看到有几个选项,分别是:
Filename and Paths, File transfer and protocols, Serial port setup, Modem and dialing, Screen and keyboard, Save setup as df1, Save setup as...... , Exit from minicom
进入Serial port setup
将第一项改成 A—Serial Device : /dev/ttyUSB0
第二项:B—lockfile Location: /var/lock
第五项:E—Bps/par/Bits :57600(这里要注意,这个值要改成你的连接的设备的波特率,我这里的是57600)
第七项:F—Hardware Flow Control: yes
然后退出进入Modem and dialing
将A—initing string B-Rest string K-Hang-up string 这三项的值去掉。
然后退出选择 Save as df1,然后选择EXIT FROM MINICOM 到这里的终端已经设置好了。
接下来你就可以将你的串口线接上设备,然后在终端下输入minicom就可以对设备进行调试了。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dongliqiang2006/archive/2009/11/06/4778931.aspx
首先要有一个Linux下的终端软件叫minicom如果没有装这个的朋友可以到自己的源中去下载,然后你就要插上你的usb转串口的线,在 Linux下Usb转串口的线几乎不需要驱动,你插上以后在你的dev的目录下应该会有一个ttyUSB0的文件,如果有那么恭喜你了,你的这根线现在是可用的了。进入到终端输入su以root用户进行登录,使用minicom必须要用root用户,然后输入minicom -s 进行设置,进入设置界面以后你会看到有几个选项,分别是:
Filename and Paths, File transfer and protocols, Serial port setup, Modem and dialing, Screen and keyboard, Save setup as df1, Save setup as...... , Exit from minicom
进入Serial port setup
将第一项改成 A—Serial Device : /dev/ttyUSB0
第二项:B—lockfile Location: /var/lock
第五项:E—Bps/par/Bits :57600(这里要注意,这个值要改成你的连接的设备的波特率,我这里的是57600)
第七项:F—Hardware Flow Control: yes
然后退出进入Modem and dialing
将A—initing string B-Rest string K-Hang-up string 这三项的值去掉。
然后退出选择 Save as df1,然后选择EXIT FROM MINICOM 到这里的终端已经设置好了。
接下来你就可以将你的串口线接上设备,然后在终端下输入minicom就可以对设备进行调试了。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dongliqiang2006/archive/2009/11/06/4778931.aspx
来源:http://blog.csdn.net/dongliqiang2006/archive/2009/09/16/4557703.aspx
Linux 下串口编程(中断) 收藏
Linux 下串口编程的文章网上是满天飞,但大都是出自一篇文章,而且写的都是些基本的操作,像控制 RTS/CTS 等串口引脚状态,接收发送二进制数据等,都没有很好的说明,我在使用中遇到了些问题,写出来,希望能对大家有所帮助,少走弯路,呵呵!
我使用的操作系统是 Redhat9 , gcc 版本是 3.2.2
其实在 linux 下对串口的设置主要是通过 termios 这个结构体实现的,但是这个结构体却没有提供控制 RTS 或获得 CTS 等串口引脚状态的接口,可以通过 ioctl 系统调用来获得 / 控制。
获得:
ioctl(fd, TIOCMGET, &controlbits);
if (controlbits & TIOCM_CTS)
printf(“ 有信号 \n”);
else
printf(“ 无信号 \n”);
设置:
ioctl(fd, TIOCMGET, &ctrlbits) ;
if (flag)
ctrlbits |= TIOCM_RTS;
else
ctrlbits &= ~TIOCM_RTS;
ioctl(fd, TIOCMSET, &ctrlbits);
其实 TIOCM_RTS 有效后是把串口的 RTS 设置为有信号,但串口的电平为低时是有信号,为高时为无信号,和用 TIOCMGET 获得的状态正好相反,也就是说 TIOCMGET/TIOCMSET 只是获得 / 控制串口的相应引脚是否有信号,并不反应当前串口的真实电平高低。
网上许多流行的 linux 串口编程的版本中都没对 c_iflag ( termios 成员变量 )这个变量进行有效的设置,这样传送 ASCII 码时没什么问题,但传送二进制数据时遇到 0x0d,0x11 和 0x13 却会被丢掉。不用说也知道,这几个肯定是特殊字符,被用作特殊控制了。关掉 ICRNL 和 IXON 选项即可解决。
c_iflag &= ~(ICRNL | IXON);
0x0d 回车符 CR
0x11 ^Q VSTART 字符
0x13 ^S VSTOP 字符
ICRNL 将输入的 CR 转换为 NL
IXON 使起动 / 停止输出控制流起作用
在《 UNIX 环境高级编程 第二版》第 18 章第 11 小节看到把终端 I/O 设置为原始模式(串口通讯就是终端 I/O 的原始模式)时输入属性设置为
term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
屏蔽了许多属性,怪不得有人说如果是使用串口通讯 c_iflag 和 c_oflag 都设置为 0 就行了!
以下是我的设置的一些重要的串口属性
term.c_cflag |= CLOCAL | CREAD;
term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
term.c_oflag &= ~OPOST;
term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dongliqiang2006/archive/2009/09/16/4557703.aspx
结合:
如何实现linux下的串口中断编程?
http://wenwen.soso.com/z/q139628708.htm
Linux 下串口编程(中断) 收藏
Linux 下串口编程的文章网上是满天飞,但大都是出自一篇文章,而且写的都是些基本的操作,像控制 RTS/CTS 等串口引脚状态,接收发送二进制数据等,都没有很好的说明,我在使用中遇到了些问题,写出来,希望能对大家有所帮助,少走弯路,呵呵!
我使用的操作系统是 Redhat9 , gcc 版本是 3.2.2
其实在 linux 下对串口的设置主要是通过 termios 这个结构体实现的,但是这个结构体却没有提供控制 RTS 或获得 CTS 等串口引脚状态的接口,可以通过 ioctl 系统调用来获得 / 控制。
获得:
ioctl(fd, TIOCMGET, &controlbits);
if (controlbits & TIOCM_CTS)
printf(“ 有信号 \n”);
else
printf(“ 无信号 \n”);
设置:
ioctl(fd, TIOCMGET, &ctrlbits) ;
if (flag)
ctrlbits |= TIOCM_RTS;
else
ctrlbits &= ~TIOCM_RTS;
ioctl(fd, TIOCMSET, &ctrlbits);
其实 TIOCM_RTS 有效后是把串口的 RTS 设置为有信号,但串口的电平为低时是有信号,为高时为无信号,和用 TIOCMGET 获得的状态正好相反,也就是说 TIOCMGET/TIOCMSET 只是获得 / 控制串口的相应引脚是否有信号,并不反应当前串口的真实电平高低。
网上许多流行的 linux 串口编程的版本中都没对 c_iflag ( termios 成员变量 )这个变量进行有效的设置,这样传送 ASCII 码时没什么问题,但传送二进制数据时遇到 0x0d,0x11 和 0x13 却会被丢掉。不用说也知道,这几个肯定是特殊字符,被用作特殊控制了。关掉 ICRNL 和 IXON 选项即可解决。
c_iflag &= ~(ICRNL | IXON);
0x0d 回车符 CR
0x11 ^Q VSTART 字符
0x13 ^S VSTOP 字符
ICRNL 将输入的 CR 转换为 NL
IXON 使起动 / 停止输出控制流起作用
在《 UNIX 环境高级编程 第二版》第 18 章第 11 小节看到把终端 I/O 设置为原始模式(串口通讯就是终端 I/O 的原始模式)时输入属性设置为
term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
屏蔽了许多属性,怪不得有人说如果是使用串口通讯 c_iflag 和 c_oflag 都设置为 0 就行了!
以下是我的设置的一些重要的串口属性
term.c_cflag |= CLOCAL | CREAD;
term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
term.c_oflag &= ~OPOST;
term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dongliqiang2006/archive/2009/09/16/4557703.aspx
结合:
如何实现linux下的串口中断编程?
http://wenwen.soso.com/z/q139628708.htm
PHP是一种弱类型语言,如果程序里有许多变量,加上PHP许多函数命名都十分混乱,乱上加乱,看得也就眼花缭乱了。
统一编码风格,甚至变量命名,在团队开发中非常重要。
本人从事多年PHP开发,为使所带领的团队更加效,渐渐形成了一种PHP的命名习惯(后面有朋友说是早已存在的匈牙利命名法),使自己的程序看起来十分明了。
下面我就把经验给大家,不一定适用于别人,但还是分享一下。
string,字符串型,在变量前面加str
复制PHP内容到剪贴板
PHP代码:
//下面一个变量为字串型
$strMessage = 'Hello World!' ;
array,数组型, 在变量前面加a, 一维数组使用名词单数,多维数组使用词复数
复制PHP内容到剪贴板
PHP代码:
//下面一个变量为一维数组
$aData = array ( 1 , 2 , 3 , 4 , 5 ,6) ;
//下面一个变量为多维数组
$aMembers = array ( 'id' => 123456 , 'username' => 'ABC' , 'email' => 'abc#abc.com' ) ;
integer,整数型变量,在前面加上'n'
复制PHP内容到剪贴板
PHP代码:
//下面一个变量为整数
$nCount = $pBS->Member->getCount() ;
boolean,布尔型在前面加上'b'
复制PHP内容到剪贴板
PHP代码:
//下面一个变量为布尔型
$bEncode = true ;
float,浮点型, 在前面加上'f'
复制PHP内容到剪贴板
PHP代码:
//下面一个变量为浮点型
$fSave = 0.8 ; // 8折
指针类型,比如类。在前面加上'p'
复制PHP内容到剪贴板
PHP代码:
//下面是一个类的实例化
$pBP = new BluePage ;
resource,资源型,在前面加上'rs'
复制PHP内容到剪贴板
PHP代码:
$rsConn = mysql_connect ( 'localhost' , 'user' , 'pw' ) ;
$rsHandle = fopen( $strFilename );
未明变量,使用mx
复制PHP内容到剪贴板
PHP代码:
$mxData = getData() ;
自定义函数,使用fn_开头
复制PHP内容到剪贴板
PHP代码:
function fn_HaltError ( $strErrorMessage )
{
// do sth...
}
一个综合的例子(使用分页类):
复制PHP内容到剪贴板
PHP代码:
include ( "lib/BluePage.class.php" ) ;
$pBP = new BluePage ;
$rsConn = mysql_connect( 'localhost' , 'root' , '123456' ) or die( mysql_error() ) ;
mysql_select_db( 'test' , $rsConn );
$strQuery = "SELECT COUNT(`id`) FROM test" ;
$nCount = $pBP->myGetCount( $strQuery , $rsConn ) ; //取得总数
if ( $nCount < 1 )
{
fn_HaltError( $aMessages['nodata'] ) ;
}
$nShowNum = 10 ;
//分页数组与html
$aPDatas = $pBP->get( $nCount , $nShowNum ) ;
$strHtml = $pBP->getHTML( $aPDatas ) ;
// 分页数据里包含有offset,取数据
$strQuery = "SELECT * FROM test LIMIT " . $aPDatas['offset'] . ", " . $nShowNum ;
$rsResult = mysql_query( $strQuery );
统一编码风格,甚至变量命名,在团队开发中非常重要。
本人从事多年PHP开发,为使所带领的团队更加效,渐渐形成了一种PHP的命名习惯(后面有朋友说是早已存在的匈牙利命名法),使自己的程序看起来十分明了。
下面我就把经验给大家,不一定适用于别人,但还是分享一下。
string,字符串型,在变量前面加str
复制PHP内容到剪贴板
PHP代码:
//下面一个变量为字串型
$strMessage = 'Hello World!' ;
array,数组型, 在变量前面加a, 一维数组使用名词单数,多维数组使用词复数
复制PHP内容到剪贴板
PHP代码:
//下面一个变量为一维数组
$aData = array ( 1 , 2 , 3 , 4 , 5 ,6) ;
//下面一个变量为多维数组
$aMembers = array ( 'id' => 123456 , 'username' => 'ABC' , 'email' => 'abc#abc.com' ) ;
integer,整数型变量,在前面加上'n'
复制PHP内容到剪贴板
PHP代码:
//下面一个变量为整数
$nCount = $pBS->Member->getCount() ;
boolean,布尔型在前面加上'b'
复制PHP内容到剪贴板
PHP代码:
//下面一个变量为布尔型
$bEncode = true ;
float,浮点型, 在前面加上'f'
复制PHP内容到剪贴板
PHP代码:
//下面一个变量为浮点型
$fSave = 0.8 ; // 8折
指针类型,比如类。在前面加上'p'
复制PHP内容到剪贴板
PHP代码:
//下面是一个类的实例化
$pBP = new BluePage ;
resource,资源型,在前面加上'rs'
复制PHP内容到剪贴板
PHP代码:
$rsConn = mysql_connect ( 'localhost' , 'user' , 'pw' ) ;
$rsHandle = fopen( $strFilename );
未明变量,使用mx
复制PHP内容到剪贴板
PHP代码:
$mxData = getData() ;
自定义函数,使用fn_开头
复制PHP内容到剪贴板
PHP代码:
function fn_HaltError ( $strErrorMessage )
{
// do sth...
}
一个综合的例子(使用分页类):
复制PHP内容到剪贴板
PHP代码:
include ( "lib/BluePage.class.php" ) ;
$pBP = new BluePage ;
$rsConn = mysql_connect( 'localhost' , 'root' , '123456' ) or die( mysql_error() ) ;
mysql_select_db( 'test' , $rsConn );
$strQuery = "SELECT COUNT(`id`) FROM test" ;
$nCount = $pBP->myGetCount( $strQuery , $rsConn ) ; //取得总数
if ( $nCount < 1 )
{
fn_HaltError( $aMessages['nodata'] ) ;
}
$nShowNum = 10 ;
//分页数组与html
$aPDatas = $pBP->get( $nCount , $nShowNum ) ;
$strHtml = $pBP->getHTML( $aPDatas ) ;
// 分页数据里包含有offset,取数据
$strQuery = "SELECT * FROM test LIMIT " . $aPDatas['offset'] . ", " . $nShowNum ;
$rsResult = mysql_query( $strQuery );
测试驱动的开发和单元测试是确保代码在经过修改和重大调整之后依然能如我们期望的一样工作的最新方法。在本文中,您将学习到如何在模块、数据库和用户界面(UI)层对自己的 PHP 代码进行单元测试。
Web 应用程序是 24x7 不间断运行的,因此我的程序是否还在运行这个问题会在晚上一直困扰我。单元测试已经帮我对自己的代码建立了足够的信心 —— 这样我就可以安稳地睡个好觉了。
单元测试 是一个为代码编写测试用例并自动运行这些测试的框架。测试驱动的开发 是一种单元测试方法,其思想是应该首先编写测试程序,并验证这些测试可以发现错误,然后才开始编写需要通过这些测试的代码。当所有测试都通过时,我们开发的特性也就完成了。这些单元测试的价值是我们可以随时运行它们 —— 在签入代码之前,重大修改之后,或者部署到正在运行的系统之后都可以。
PHP 单元测试
对于 PHP 来说,单元测试框架是 PHPUnit2。可以使用 PEAR 命令行作为一个 PEAR 模块来安装这个系统:% pear install PHPUnit2。
在安装这个框架之后,可以通过创建派生于 PHPUnit2_Framework_TestCase 的测试类来编写单元测试。
模块单元测试
我发现开始单元测试最好的地方是在应用程序的业务逻辑模块中。我使用了一个简单的例子:这是一个对两个数字进行求和的函数。为了开始测试,我们首先编写测试用例,如下所示。
清单 1. TestAdd.php <?php
require_once 'Add.php';
require_once 'PHPUnit2/Framework/TestCase.php';
class TestAdd extends PHPUnit2_Framework_TestCase
{
function test1() { $this->assertTrue( add( 1, 2 ) == 3 ); }
function test2() { $this->assertTrue( add( 1, 1 ) == 2 ); }
}
?>
这个 TestAdd 类有两个方法,都使用了 test 前缀。每个方法都定义了一个测试,这个测试可以与清单 1 一样简单,也可以十分复杂。在本例中,我们在第一个测试中只是简单地断定 1 加 2 等于 3,在第二个测试中是 1 加 1 等于 2。
PHPUnit2 系统定义了 assertTrue() 方法,它用来测试参数中包含的条件值是否为真。然后,我们又编写了 Add.php 模块,最初让它产生错误的结果。
清单 2. Add.php <?php
function add( $a, $b ) { return 0; }
?>
现在运行单元测试时,这两个测试都会失败。
清单 3. 测试失败 % phpunit TestAdd.php
PHPUnit 2.2.1 by Sebastian Bergmann.
FF
Time: 0.0031270980834961
There were 2 failures:
1) test1(TestAdd)
2) test2(TestAdd)
FAILURES!!!
Tests run: 2, Failures: 2, Errors: 0, Incomplete Tests: 0.
现在我知道这两个测试都可以正常工作了。因此,可以修改 add() 函数来真正地做实际的事情了。 <?php
function add( $a, $b ) { return $a+$b; }
?>
现在这两个测试都可以通过了。
清单 4. 测试通过
% phpunit TestAdd.php
PHPUnit 2.2.1 by Sebastian Bergmann.
..
Time: 0.0023679733276367
OK (2 tests)
%
尽管这个测试驱动开发的例子非常简单,但是我们可以从中体会到它的思想。我们首先创建了测试用例,并且有足够多的代码让这个测试运行起来,不过结果是错误的。然后我们验证测试的确是失败的,接着实现了实际的代码使这个测试能够通过。
我发现在实现代码时我会一直不断地添加代码,直到拥有一个覆盖所有代码路径的完整测试为止。在本文的最后,您会看到有关编写什么测试和如何编写这些测试的一些建议。
数据库测试
在进行模块测试之后,就可以进行数据库访问测试了。数据库访问测试 带来了两个有趣的问题。首先,我们必须在每次测试之前将数据库恢复到某个已知点。其次,要注意这种恢复可能会对现有数据库造成破坏,因此我们必须对非生产数据库进行测试,或者在编写测试用例时注意不能影响现有数据库的内容。
数据库的单元测试是从数据库开始的。为了阐述这个问题,我们需要使用下面的简单模式。
清单 5. Schema.sql DROP TABLE IF EXISTS authors;
CREATE TABLE authors (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name TEXT NOT NULL,
PRIMARY KEY ( id )
);
清单 5 是一个 authors 表,每条记录都有一个相关的 ID。
接下来,就可以编写测试用例了。
清单 6. TestAuthors.php <?php
require_once 'dblib.php';
require_once 'PHPUnit2/Framework/TestCase.php';
class TestAuthors extends PHPUnit2_Framework_TestCase
{
function test_delete_all()
{
$this->assertTrue( Authors::delete_all() );
}
function test_insert()
{
$this->assertTrue( Authors::delete_all() );
$this->assertTrue( Authors::insert( 'Jack' ) );
}
function test_insert_and_get()
{
$this->assertTrue( Authors::delete_all() );
$this->assertTrue( Authors::insert( 'Jack' ) );
$this->assertTrue( Authors::insert( 'Joe' ) );
$found = Authors::get_all();
$this->assertTrue( $found != null );
$this->assertTrue( count( $found ) == 2 );
}
}
?>
Web 应用程序是 24x7 不间断运行的,因此我的程序是否还在运行这个问题会在晚上一直困扰我。单元测试已经帮我对自己的代码建立了足够的信心 —— 这样我就可以安稳地睡个好觉了。
单元测试 是一个为代码编写测试用例并自动运行这些测试的框架。测试驱动的开发 是一种单元测试方法,其思想是应该首先编写测试程序,并验证这些测试可以发现错误,然后才开始编写需要通过这些测试的代码。当所有测试都通过时,我们开发的特性也就完成了。这些单元测试的价值是我们可以随时运行它们 —— 在签入代码之前,重大修改之后,或者部署到正在运行的系统之后都可以。
PHP 单元测试
对于 PHP 来说,单元测试框架是 PHPUnit2。可以使用 PEAR 命令行作为一个 PEAR 模块来安装这个系统:% pear install PHPUnit2。
在安装这个框架之后,可以通过创建派生于 PHPUnit2_Framework_TestCase 的测试类来编写单元测试。
模块单元测试
我发现开始单元测试最好的地方是在应用程序的业务逻辑模块中。我使用了一个简单的例子:这是一个对两个数字进行求和的函数。为了开始测试,我们首先编写测试用例,如下所示。
清单 1. TestAdd.php <?php
require_once 'Add.php';
require_once 'PHPUnit2/Framework/TestCase.php';
class TestAdd extends PHPUnit2_Framework_TestCase
{
function test1() { $this->assertTrue( add( 1, 2 ) == 3 ); }
function test2() { $this->assertTrue( add( 1, 1 ) == 2 ); }
}
?>
这个 TestAdd 类有两个方法,都使用了 test 前缀。每个方法都定义了一个测试,这个测试可以与清单 1 一样简单,也可以十分复杂。在本例中,我们在第一个测试中只是简单地断定 1 加 2 等于 3,在第二个测试中是 1 加 1 等于 2。
PHPUnit2 系统定义了 assertTrue() 方法,它用来测试参数中包含的条件值是否为真。然后,我们又编写了 Add.php 模块,最初让它产生错误的结果。
清单 2. Add.php <?php
function add( $a, $b ) { return 0; }
?>
现在运行单元测试时,这两个测试都会失败。
清单 3. 测试失败 % phpunit TestAdd.php
PHPUnit 2.2.1 by Sebastian Bergmann.
FF
Time: 0.0031270980834961
There were 2 failures:
1) test1(TestAdd)
2) test2(TestAdd)
FAILURES!!!
Tests run: 2, Failures: 2, Errors: 0, Incomplete Tests: 0.
现在我知道这两个测试都可以正常工作了。因此,可以修改 add() 函数来真正地做实际的事情了。 <?php
function add( $a, $b ) { return $a+$b; }
?>
现在这两个测试都可以通过了。
清单 4. 测试通过
% phpunit TestAdd.php
PHPUnit 2.2.1 by Sebastian Bergmann.
..
Time: 0.0023679733276367
OK (2 tests)
%
尽管这个测试驱动开发的例子非常简单,但是我们可以从中体会到它的思想。我们首先创建了测试用例,并且有足够多的代码让这个测试运行起来,不过结果是错误的。然后我们验证测试的确是失败的,接着实现了实际的代码使这个测试能够通过。
我发现在实现代码时我会一直不断地添加代码,直到拥有一个覆盖所有代码路径的完整测试为止。在本文的最后,您会看到有关编写什么测试和如何编写这些测试的一些建议。
数据库测试
在进行模块测试之后,就可以进行数据库访问测试了。数据库访问测试 带来了两个有趣的问题。首先,我们必须在每次测试之前将数据库恢复到某个已知点。其次,要注意这种恢复可能会对现有数据库造成破坏,因此我们必须对非生产数据库进行测试,或者在编写测试用例时注意不能影响现有数据库的内容。
数据库的单元测试是从数据库开始的。为了阐述这个问题,我们需要使用下面的简单模式。
清单 5. Schema.sql DROP TABLE IF EXISTS authors;
CREATE TABLE authors (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name TEXT NOT NULL,
PRIMARY KEY ( id )
);
清单 5 是一个 authors 表,每条记录都有一个相关的 ID。
接下来,就可以编写测试用例了。
清单 6. TestAuthors.php <?php
require_once 'dblib.php';
require_once 'PHPUnit2/Framework/TestCase.php';
class TestAuthors extends PHPUnit2_Framework_TestCase
{
function test_delete_all()
{
$this->assertTrue( Authors::delete_all() );
}
function test_insert()
{
$this->assertTrue( Authors::delete_all() );
$this->assertTrue( Authors::insert( 'Jack' ) );
}
function test_insert_and_get()
{
$this->assertTrue( Authors::delete_all() );
$this->assertTrue( Authors::insert( 'Jack' ) );
$this->assertTrue( Authors::insert( 'Joe' ) );
$found = Authors::get_all();
$this->assertTrue( $found != null );
$this->assertTrue( count( $found ) == 2 );
}
}
?>
MySQL与PHP乱码原理与解决
时间:2008-12-28 10:53:40 来源: 作者:analyzer
MySQL与PHP产生乱码原因:
Mysql数据库默认的编码是utf8,如果这种编码与你的PHP网页不一致,可能就会造成MySQL乱码.
MySQL中创建表时会让你选择一种编码,如果这种编码与你的网页编码不一致,也可能造成MYSQL乱码.
MySQL创建表时添加字段是可以选择编码的,如果这种编码与你的网页编码不一致,也可能造成MySQL乱码.
用户提交页面的编码与显示数据的页面编码不一致,就肯定会造成PHP页面乱码.
如用户输入资料的页面是big5码, 显示用户输入的页面却是gb2312,这种100%会造成PHP页面乱码.
PHP页面字符集不正确.
PHP连接MySQL数据库语句指定的编码不正确.
注意:
很多人都怀疑mysql版本不一致会导致乱码,相信看了本说明你就不会这样认为了.
平时你在某些网站看到的文字可能有几种编码, 如你看到一个繁体字,它有可能是big5编码,也有可能是utf-8编码的,更有可能是gb码的,没错,也就是说有简体编码的繁体字,也有繁体编码的简体字,一定要了解这一点.
如果你是做一个简体编码的网页,编码定为GB2312,如果有香港和台湾地区的访客提交繁体的信息,就可能会造成乱码,解决方法:
将网站编码设为 utf-8,这样可以兼容世界上所有字符,
如果网站已经运作了好久,已有很多旧数据,不能再更改简体中文的设定,那么建议将页面的编码设为 GBK, GBK与GB2312的区别就在于:GBK能比GB2312显示更多的字符,要显示简体码的繁体字,就只能用GBK.
使用MySQL与PHP产生乱码的原因都了解得很清楚了,那么解决就不困难了.
MySQL与PHP产生乱码的解决办法:
如果安装Mysql的编码已不能更改,很多朋友是购买虚拟主机建立网站,无权更改MYSQL的安装编码,这一关我们可以跳过,因为只要后面的步聚正确,一样能解决乱码问题
修改数据库编码,如果是数据库编码不正确,可以在phpmyadmin 执行如下命令:
Alter DATABASE 'test' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
以上命令就是将test数据库的编码设为utf8.
修改表的编码:
Alter TABLE 'category' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
以上命令就是将一个表category的编码改为utf8.
修改字段的编码:
Alter TABLE 'test' CHANGE 'dd' 'dd' VARCHAR( 45 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
以上命令就是将test表中 dd的字段编码改为utf8.
如果是这种情况容易解决,只需检查下页面,修改源文件的charset即可.
这种情况也是修改页面charset即可.
在连接数据库的语句中.
mysql_connect('localhost','user','password');
mysql_select_db('my_db');
mysql_query("set names utf8;"); //select 数据库之后加多这一句
为了避免PHP页面乱码的发生,PHP页面开始第一句
header("content-type:text/html; charset=utf-8");
//强行指定页面的编码,以避免乱码
注意:
照以上方法修改以后只能保证你新插入的数据不会乱码,举个例:如果你用户已提交的数据是BIG5,你却想通过以上方法改为可以在GB2312的网页正确显示是不可能的, 这种文字内码的变换只能通过另写程序来解决.
时间:2008-12-28 10:53:40 来源: 作者:analyzer
MySQL与PHP产生乱码原因:
Mysql数据库默认的编码是utf8,如果这种编码与你的PHP网页不一致,可能就会造成MySQL乱码.
MySQL中创建表时会让你选择一种编码,如果这种编码与你的网页编码不一致,也可能造成MYSQL乱码.
MySQL创建表时添加字段是可以选择编码的,如果这种编码与你的网页编码不一致,也可能造成MySQL乱码.
用户提交页面的编码与显示数据的页面编码不一致,就肯定会造成PHP页面乱码.
如用户输入资料的页面是big5码, 显示用户输入的页面却是gb2312,这种100%会造成PHP页面乱码.
PHP页面字符集不正确.
PHP连接MySQL数据库语句指定的编码不正确.
注意:
很多人都怀疑mysql版本不一致会导致乱码,相信看了本说明你就不会这样认为了.
平时你在某些网站看到的文字可能有几种编码, 如你看到一个繁体字,它有可能是big5编码,也有可能是utf-8编码的,更有可能是gb码的,没错,也就是说有简体编码的繁体字,也有繁体编码的简体字,一定要了解这一点.
如果你是做一个简体编码的网页,编码定为GB2312,如果有香港和台湾地区的访客提交繁体的信息,就可能会造成乱码,解决方法:
将网站编码设为 utf-8,这样可以兼容世界上所有字符,
如果网站已经运作了好久,已有很多旧数据,不能再更改简体中文的设定,那么建议将页面的编码设为 GBK, GBK与GB2312的区别就在于:GBK能比GB2312显示更多的字符,要显示简体码的繁体字,就只能用GBK.
使用MySQL与PHP产生乱码的原因都了解得很清楚了,那么解决就不困难了.
MySQL与PHP产生乱码的解决办法:
如果安装Mysql的编码已不能更改,很多朋友是购买虚拟主机建立网站,无权更改MYSQL的安装编码,这一关我们可以跳过,因为只要后面的步聚正确,一样能解决乱码问题
修改数据库编码,如果是数据库编码不正确,可以在phpmyadmin 执行如下命令:
Alter DATABASE 'test' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
以上命令就是将test数据库的编码设为utf8.
修改表的编码:
Alter TABLE 'category' DEFAULT CHARACTER SET utf8 COLLATE utf8_bin
以上命令就是将一个表category的编码改为utf8.
修改字段的编码:
Alter TABLE 'test' CHANGE 'dd' 'dd' VARCHAR( 45 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL
以上命令就是将test表中 dd的字段编码改为utf8.
如果是这种情况容易解决,只需检查下页面,修改源文件的charset即可.
这种情况也是修改页面charset即可.
在连接数据库的语句中.
mysql_connect('localhost','user','password');
mysql_select_db('my_db');
mysql_query("set names utf8;"); //select 数据库之后加多这一句
为了避免PHP页面乱码的发生,PHP页面开始第一句
header("content-type:text/html; charset=utf-8");
//强行指定页面的编码,以避免乱码
注意:
照以上方法修改以后只能保证你新插入的数据不会乱码,举个例:如果你用户已提交的数据是BIG5,你却想通过以上方法改为可以在GB2312的网页正确显示是不可能的, 这种文字内码的变换只能通过另写程序来解决.
你有没有想过PHP是怎么在浏览器里输出“你好世界”的?我也是看了PHP内核和扩展后才知道的。也许有些朋友也想知道其中原理,那就让我们开始吧。
在上一篇网志里我简单介绍了“在我浏览这个页面之前都发生了些什么?”这个问题。如果你错过了就点这里看看吧。现在我要讨论的是“PHP是怎样在浏览器里输出内容”这个问题。
简介
先看看下面这个过程:
我们从未手动开启过PHP的相关进程,它是随着Apache的启动而运行的;
PHP通过mod_php5.so模块和Apache相连(具体说来是SAPI,即服务器应用程序编程接口);
PHP总共有三个模块:内核、Zend引擎、以及扩展层;
PHP内核用来处理请求、文件流、错误处理等相关操作;
Zend引擎(ZE)用以将源文件转换成机器语言,然后在虚拟机上运行它;
扩展层是一组函数、类库和流,PHP使用它们来执行一些特定的操作。比如,我们需要mysql扩展来连接MySQL数据库;
当ZE执行程序时可能会需要连接若干扩展,这时ZE将控制权交给扩展,等处理完特定任务后再返还;
最后,ZE将程序运行结果返回给PHP内核,它再将结果传送给SAPI层,最终输出到浏览器上。
深入探讨
等等,没有这么简单。以上过程只是个简略版,让我们再深入挖掘一下,看看幕后还发生了些什么。
Apache启动后,PHP解释程序也随之启动;
PHP的启动过程有两步;
第一步是初始化一些环境变量,这将在整个SAPI生命周期中发生作用;
第二步是生成只针对当前请求的一些变量设置。
PHP启动第一步
不清楚什么第一第二步是什么?别担心,我们接下来详细讨论一下。让我们先看看第一步,也是最主要的一步。要记住的是,第一步的操作在任何请求到达之前就发生了。
启动Apache后,PHP解释程序也随之启动;
PHP调用各个扩展的MINIT方法,从而使这些扩展切换到可用状态。看看php.ini文件里打开了哪些扩展吧;
MINIT的意思是“模块初始化”。各个模块都定义了一组函数、类库等用以处理其他请求。
一个典型的MINIT方法如下:
PHP_MINIT_FUNCTION(extension_name){
/* Initialize functions, classes etc */
}
PHP启动第二步
当一个页面请求发生时,SAPI层将控制权交给PHP层。于是PHP设置了用于回复本次请求所需的环境变量。同时,它还建立一个变量表,用来存放执行过程中产生的变量名和值。
PHP调用各个模块的RINIT方法,即“请求初始化”。一个经典的例子是Session模块的RINIT,如果在php.ini中启用了Session模块,那在调用该模块的RINIT时就会初始化$_SESSION变量,并将相关内容读入;
RINIT方法可以看作是一个准备过程,在程序执行之间就会自动启动。
一个典型的RINIT方法如下:
PHP_RINIT_FUNCTION(extension_name) {
/* Initialize session variables, pre-populate variables, redefine global variables etc */
}
PHP关闭第一步
如同PHP启动一样,PHP的关闭也分两步:
一旦页面执行完毕(无论是执行到了文件末尾还是用exit或die函数中止),PHP就会启动清理程序。它会按顺序调用各个模块的RSHUTDOWN方法。
RSHUTDOWN用以清除程序运行时产生的符号表,也就是对每个变量调用unset函数。
一个典型的RSHUTDOWN方法如下:
PHP_RSHUTDOWN_FUNCTION(extension_name) {
/* Do memory management, unset all variables used in the last PHP call etc */
}
PHP关闭第二步
最后,所有的请求都已处理完毕,SAPI也准备关闭了,PHP开始执行第二步:
PHP调用每个扩展的MSHUTDOWN方法,这是各个模块最后一次释放内存的机会。
一个典型的RSHUTDOWN方法如下:
PHP_MSHUTDOWN_FUNCTION(extension_name) {
/* Free handlers and persistent memory etc */
}
这样,整个PHP生命周期就结束了。要注意的是,只有在服务器没有请求的情况下才会执行“启动第一步”和“关闭第二步”。
在上一篇网志里我简单介绍了“在我浏览这个页面之前都发生了些什么?”这个问题。如果你错过了就点这里看看吧。现在我要讨论的是“PHP是怎样在浏览器里输出内容”这个问题。
简介
先看看下面这个过程:
我们从未手动开启过PHP的相关进程,它是随着Apache的启动而运行的;
PHP通过mod_php5.so模块和Apache相连(具体说来是SAPI,即服务器应用程序编程接口);
PHP总共有三个模块:内核、Zend引擎、以及扩展层;
PHP内核用来处理请求、文件流、错误处理等相关操作;
Zend引擎(ZE)用以将源文件转换成机器语言,然后在虚拟机上运行它;
扩展层是一组函数、类库和流,PHP使用它们来执行一些特定的操作。比如,我们需要mysql扩展来连接MySQL数据库;
当ZE执行程序时可能会需要连接若干扩展,这时ZE将控制权交给扩展,等处理完特定任务后再返还;
最后,ZE将程序运行结果返回给PHP内核,它再将结果传送给SAPI层,最终输出到浏览器上。
深入探讨
等等,没有这么简单。以上过程只是个简略版,让我们再深入挖掘一下,看看幕后还发生了些什么。
Apache启动后,PHP解释程序也随之启动;
PHP的启动过程有两步;
第一步是初始化一些环境变量,这将在整个SAPI生命周期中发生作用;
第二步是生成只针对当前请求的一些变量设置。
PHP启动第一步
不清楚什么第一第二步是什么?别担心,我们接下来详细讨论一下。让我们先看看第一步,也是最主要的一步。要记住的是,第一步的操作在任何请求到达之前就发生了。
启动Apache后,PHP解释程序也随之启动;
PHP调用各个扩展的MINIT方法,从而使这些扩展切换到可用状态。看看php.ini文件里打开了哪些扩展吧;
MINIT的意思是“模块初始化”。各个模块都定义了一组函数、类库等用以处理其他请求。
一个典型的MINIT方法如下:
PHP_MINIT_FUNCTION(extension_name){
/* Initialize functions, classes etc */
}
PHP启动第二步
当一个页面请求发生时,SAPI层将控制权交给PHP层。于是PHP设置了用于回复本次请求所需的环境变量。同时,它还建立一个变量表,用来存放执行过程中产生的变量名和值。
PHP调用各个模块的RINIT方法,即“请求初始化”。一个经典的例子是Session模块的RINIT,如果在php.ini中启用了Session模块,那在调用该模块的RINIT时就会初始化$_SESSION变量,并将相关内容读入;
RINIT方法可以看作是一个准备过程,在程序执行之间就会自动启动。
一个典型的RINIT方法如下:
PHP_RINIT_FUNCTION(extension_name) {
/* Initialize session variables, pre-populate variables, redefine global variables etc */
}
PHP关闭第一步
如同PHP启动一样,PHP的关闭也分两步:
一旦页面执行完毕(无论是执行到了文件末尾还是用exit或die函数中止),PHP就会启动清理程序。它会按顺序调用各个模块的RSHUTDOWN方法。
RSHUTDOWN用以清除程序运行时产生的符号表,也就是对每个变量调用unset函数。
一个典型的RSHUTDOWN方法如下:
PHP_RSHUTDOWN_FUNCTION(extension_name) {
/* Do memory management, unset all variables used in the last PHP call etc */
}
PHP关闭第二步
最后,所有的请求都已处理完毕,SAPI也准备关闭了,PHP开始执行第二步:
PHP调用每个扩展的MSHUTDOWN方法,这是各个模块最后一次释放内存的机会。
一个典型的RSHUTDOWN方法如下:
PHP_MSHUTDOWN_FUNCTION(extension_name) {
/* Free handlers and persistent memory etc */
}
这样,整个PHP生命周期就结束了。要注意的是,只有在服务器没有请求的情况下才会执行“启动第一步”和“关闭第二步”。
前言:这两天机器坏了,正在送修中,写个系列的大型网站架构的文章,希望对有志在互联网做出一番事业的站长朋友们一些帮助。
注意:这里的大型网站架构只包括高互动性高交互性的数据型大型网站,基于大家众所周知的原因,我们就不谈新闻类和一些依靠HTML静态化就可以实现的架构了,我们以高负载高数据交换高数据流动性的网站为例,比如海内,开心网等类似的web2.0系列架构。我们这里不讨论是PHP还是JSP或者.NET环境,我们从架构的方面去看问题,实现语言方面并不是问题,语言的优势在于实现而不是好坏,不论你选择任何语言,架构都是必须要面对的。
文入正题:
首先讨论一下大型网站需要注意和考虑的问题
A. 海量数据的处理。
众所周知,对于一些相对小的站点来说,数据量并不是很大,select和update就可以解决我们面对的问题,本身负载量不是很大,最多再加几个索引就可以搞定。对于大型网站,每天的数据量可能就上百万,如果一个设计不好的多对多关系,在前期是没有任何问题的,但是随着用户的增长,数据量会是几何级的增长的。在这个时候我们对于一个表的select和update的时候(还不说多表联合查询)的成本的非常高的。
B. 数据并发的处理
在一些时候,2.0的CTO都有个尚方宝剑,就是缓存。对于缓存,在高并发高处理的时候也是个大问题。在整个应用程序下,缓存是全局共享的,然而在我们进行修改的时候就,如果两个或者多个请求同时对缓存有更新的要求的情况下,应用程序会直接的死掉。这个时候,就需要一个好的数据并发处理策略以及缓存策略。
另外,就是数据库的死锁问题,也许平时我们感觉不到,死锁在高并发的情况下的出现的概率是非常高的,磁盘缓存就是一个大问题。
C. 文件存贮的问题
对于一些支持文件上传的2.0的站点,在庆幸硬盘容量越来越大的时候我们更多的应该考虑的是文件应该如何被存储并且被有效的索引。常见的方案是对文件按照日期和类型进行存贮。但是当文件量 是海量的数据的情况下,如果一块硬盘存贮了500个G的琐碎文件,那么维护的时候和使用的时候磁盘的Io就是一个巨大的问题,哪怕你的带宽足够,但是你的磁盘也未必响应过来。如果这个时候还涉及上传,磁盘很容易就over了。
也许用raid和专用存贮服务器能解决眼下的问题,但是还有个问题就是各地的访问问题,也许我们的服务器在北京,可能在云南或者新疆的访问速度如何解决?如果做分布式,那么我们的文件索引以及架构该如何规划。
所以我们不得不承认,文件存贮是个很不容易的问题
D. 数据关系的处理
我们可以很容易的规划出一个符合第三范式的数据库,里面布满了多对多关系,还能用GUID来替换INDENTIFY COLUMN 但是,多对多关系充斥的2.0时代,第三范式是第一个应该被抛弃的。必须有效的把多表联合查询降到最低。
E. 数据索引的问题
众所周知,索引是提高数据库效率查询的最方面最廉价最容易实现的方案。但是,在高UPDATE的情况下,update和delete付出的成本会高的无法想想,笔者遇到过一个情况,在更新一个聚焦索引的时候需要10分钟来完成,那么对于站点来说,这些基本上是不可忍受的。
索引和更新是一对天生的冤家,问题A,D,E这些是我们在做架构的时候不得不考虑的问题,并且也可能是花费时间最多的问题,
F. 分布式处理
对于2.0网站由于其高互动性,CDN实现的效果基本上为0,内容是实时更新的,我们常规的处理。为了保证各地的访问速度,我们就需要面对一个绝大的问题,就是如何有效的实现数据同步和更新,实现各地服务器的实时通讯有是一个不得不需要考虑的问题。
G. Ajax的利弊分析
成也AJAX,败也AJAX,AJAX成为了主流趋势,突然发现基于XMLHTTP的post和get是如此的容易。客户端get或者post到服务器数据,服务器接到数据请求之后返回来,这是一个很正常的AJAX请求。但是在AJAX处理的时候,如果我们使用一个抓包工具的话,对数据返回和处理是一目了然。对于一些计算量大的AJAX请求的话,我们可以构造一个发包机,很容易就可以把一个webserver干掉。
H. 数据安全性的分析
对于HTTP协议来说,数据包都是明文传输的,也许我们可以说我们可以用加密啊,但是对于G问题来说的话,加密的过程就可能是明文了(比如我们知道的QQ,可以很容易的判断他的加密,并有效的写一个跟他一样的加密和解密方法出来的)。当你站点流量不是很大的时候没有人会在乎你,但是当你流量上来之后,那么所谓的外挂,所谓的群发就会接踵而来(从qq一开始的群发可见端倪)。也许我们可以很的意的说,我们可以采用更高级别的判断甚至HTTPS来实现,注意,当你做这些处理的时候付出的将是海量的database,io以及CPU的成本。对于一些群发,基本上是不可能的。笔者已经可以实现对于百度空间和qq空间的群发了。大家愿意试试,实际上并不是很难。
I. 数据同步和集群的处理的问题
当我们的一台databaseserver不堪重负的时候,这个时候我们就需要做基于数据库的负载和集群了。而这个时候可能是最让人困扰的的问题了,数据基于网络传输根据数据库的设计的不同,数据延迟是很可怕的问题,也是不可避免的问题,这样的话,我们就需要通过另外的手段来保证在这延迟的几秒或者更长的几分钟时间内,实现有效的交互。比如数据散列,分割,内容处理等等问题
K.数据共享的渠道以及OPENAPI趋势
Openapi已经成为一个不可避免的趋势,从google,facebook,myspace到海内校内,都在考虑这个问题,它可以更有效的留住用户并激发用户的更多的兴趣以及让更多的人帮助你做最有效的开发。这个时候一个有效的数据共享平台,数据开放平台就成为必不可少的途径了,而在开放的接口的情况保证数据的安全性和性能,又是一个我们必须要认真思考的问题了。
当然还有更多需要考虑的问题,我这里就写一个最需要考虑的问题,欢迎补充。
下一篇文章将针对问题A,提出具体的解决方案和思路
注意:这里的大型网站架构只包括高互动性高交互性的数据型大型网站,基于大家众所周知的原因,我们就不谈新闻类和一些依靠HTML静态化就可以实现的架构了,我们以高负载高数据交换高数据流动性的网站为例,比如海内,开心网等类似的web2.0系列架构。我们这里不讨论是PHP还是JSP或者.NET环境,我们从架构的方面去看问题,实现语言方面并不是问题,语言的优势在于实现而不是好坏,不论你选择任何语言,架构都是必须要面对的。
文入正题:
首先讨论一下大型网站需要注意和考虑的问题
A. 海量数据的处理。
众所周知,对于一些相对小的站点来说,数据量并不是很大,select和update就可以解决我们面对的问题,本身负载量不是很大,最多再加几个索引就可以搞定。对于大型网站,每天的数据量可能就上百万,如果一个设计不好的多对多关系,在前期是没有任何问题的,但是随着用户的增长,数据量会是几何级的增长的。在这个时候我们对于一个表的select和update的时候(还不说多表联合查询)的成本的非常高的。
B. 数据并发的处理
在一些时候,2.0的CTO都有个尚方宝剑,就是缓存。对于缓存,在高并发高处理的时候也是个大问题。在整个应用程序下,缓存是全局共享的,然而在我们进行修改的时候就,如果两个或者多个请求同时对缓存有更新的要求的情况下,应用程序会直接的死掉。这个时候,就需要一个好的数据并发处理策略以及缓存策略。
另外,就是数据库的死锁问题,也许平时我们感觉不到,死锁在高并发的情况下的出现的概率是非常高的,磁盘缓存就是一个大问题。
C. 文件存贮的问题
对于一些支持文件上传的2.0的站点,在庆幸硬盘容量越来越大的时候我们更多的应该考虑的是文件应该如何被存储并且被有效的索引。常见的方案是对文件按照日期和类型进行存贮。但是当文件量 是海量的数据的情况下,如果一块硬盘存贮了500个G的琐碎文件,那么维护的时候和使用的时候磁盘的Io就是一个巨大的问题,哪怕你的带宽足够,但是你的磁盘也未必响应过来。如果这个时候还涉及上传,磁盘很容易就over了。
也许用raid和专用存贮服务器能解决眼下的问题,但是还有个问题就是各地的访问问题,也许我们的服务器在北京,可能在云南或者新疆的访问速度如何解决?如果做分布式,那么我们的文件索引以及架构该如何规划。
所以我们不得不承认,文件存贮是个很不容易的问题
D. 数据关系的处理
我们可以很容易的规划出一个符合第三范式的数据库,里面布满了多对多关系,还能用GUID来替换INDENTIFY COLUMN 但是,多对多关系充斥的2.0时代,第三范式是第一个应该被抛弃的。必须有效的把多表联合查询降到最低。
E. 数据索引的问题
众所周知,索引是提高数据库效率查询的最方面最廉价最容易实现的方案。但是,在高UPDATE的情况下,update和delete付出的成本会高的无法想想,笔者遇到过一个情况,在更新一个聚焦索引的时候需要10分钟来完成,那么对于站点来说,这些基本上是不可忍受的。
索引和更新是一对天生的冤家,问题A,D,E这些是我们在做架构的时候不得不考虑的问题,并且也可能是花费时间最多的问题,
F. 分布式处理
对于2.0网站由于其高互动性,CDN实现的效果基本上为0,内容是实时更新的,我们常规的处理。为了保证各地的访问速度,我们就需要面对一个绝大的问题,就是如何有效的实现数据同步和更新,实现各地服务器的实时通讯有是一个不得不需要考虑的问题。
G. Ajax的利弊分析
成也AJAX,败也AJAX,AJAX成为了主流趋势,突然发现基于XMLHTTP的post和get是如此的容易。客户端get或者post到服务器数据,服务器接到数据请求之后返回来,这是一个很正常的AJAX请求。但是在AJAX处理的时候,如果我们使用一个抓包工具的话,对数据返回和处理是一目了然。对于一些计算量大的AJAX请求的话,我们可以构造一个发包机,很容易就可以把一个webserver干掉。
H. 数据安全性的分析
对于HTTP协议来说,数据包都是明文传输的,也许我们可以说我们可以用加密啊,但是对于G问题来说的话,加密的过程就可能是明文了(比如我们知道的QQ,可以很容易的判断他的加密,并有效的写一个跟他一样的加密和解密方法出来的)。当你站点流量不是很大的时候没有人会在乎你,但是当你流量上来之后,那么所谓的外挂,所谓的群发就会接踵而来(从qq一开始的群发可见端倪)。也许我们可以很的意的说,我们可以采用更高级别的判断甚至HTTPS来实现,注意,当你做这些处理的时候付出的将是海量的database,io以及CPU的成本。对于一些群发,基本上是不可能的。笔者已经可以实现对于百度空间和qq空间的群发了。大家愿意试试,实际上并不是很难。
I. 数据同步和集群的处理的问题
当我们的一台databaseserver不堪重负的时候,这个时候我们就需要做基于数据库的负载和集群了。而这个时候可能是最让人困扰的的问题了,数据基于网络传输根据数据库的设计的不同,数据延迟是很可怕的问题,也是不可避免的问题,这样的话,我们就需要通过另外的手段来保证在这延迟的几秒或者更长的几分钟时间内,实现有效的交互。比如数据散列,分割,内容处理等等问题
K.数据共享的渠道以及OPENAPI趋势
Openapi已经成为一个不可避免的趋势,从google,facebook,myspace到海内校内,都在考虑这个问题,它可以更有效的留住用户并激发用户的更多的兴趣以及让更多的人帮助你做最有效的开发。这个时候一个有效的数据共享平台,数据开放平台就成为必不可少的途径了,而在开放的接口的情况保证数据的安全性和性能,又是一个我们必须要认真思考的问题了。
当然还有更多需要考虑的问题,我这里就写一个最需要考虑的问题,欢迎补充。
下一篇文章将针对问题A,提出具体的解决方案和思路
在配置多个SSL的虚拟主机的时候,很容易想当然的像配置普通HTTP虚拟主机一样,新建一个Virtualhost后reload服务器。可用浏览器访问的时候,却提示证书为已经存在的某个虚拟主机的SSL证书,造成配置失败。
网上查询得知,一个普通的SSL证书是独占服务器端口。也就是说,如果Apache服务器上的虚拟主机A使用了SSL_A,并监听端口443,那即使新配置了虚拟主机B,如果虚拟主机是按照配置的,那用户访问时候读取的仍然是SSL_A。这和普通虚拟空间可以通过设置域名来区别虚拟主机是不同的。
要解决这个问题,实现一个Apache服务器上提供多个SSL虚拟主机,可以:
使用多域名SSL证书,可以实现一个IP,一个443端口上多个SSL虚拟主机;
为所有SSL虚拟主机配置单独的端口。比如,默认的虚拟主机使用443,其他的使用8080或8081等,且每个SSL虚拟主机必须独占一个端口;
为Apache服务器配置多个IP,每个SSL虚拟主机独占IP。如果只有一张物理网卡,可以配置为网卡配置子接口;
使用mod_gnutls模块,创建多个SSL虚拟主机
总之,Apache的SSL虚拟主机配置需要保证每个SSL虚拟主机有独立的IP:Port组合,如果不能提供这个条件,那只好多域名SSL证书了。
网上查询得知,一个普通的SSL证书是独占服务器端口。也就是说,如果Apache服务器上的虚拟主机A使用了SSL_A,并监听端口443,那即使新配置了虚拟主机B,如果虚拟主机是按照配置的,那用户访问时候读取的仍然是SSL_A。这和普通虚拟空间可以通过设置域名来区别虚拟主机是不同的。
要解决这个问题,实现一个Apache服务器上提供多个SSL虚拟主机,可以:
使用多域名SSL证书,可以实现一个IP,一个443端口上多个SSL虚拟主机;
为所有SSL虚拟主机配置单独的端口。比如,默认的虚拟主机使用443,其他的使用8080或8081等,且每个SSL虚拟主机必须独占一个端口;
为Apache服务器配置多个IP,每个SSL虚拟主机独占IP。如果只有一张物理网卡,可以配置为网卡配置子接口;
使用mod_gnutls模块,创建多个SSL虚拟主机
总之,Apache的SSL虚拟主机配置需要保证每个SSL虚拟主机有独立的IP:Port组合,如果不能提供这个条件,那只好多域名SSL证书了。
MySQL环境变量设置,将%MySQL_HOME%下的MySQL Server 5.1\bin放到Path下。
MySQL的mysqldump工具,基本用法是:
shell> mysqldump [OPTIONS] database [tables]
通过执行mysqldump --help,得到当前mysqldump版本支持的选项表。
通过执行mysqldump –V,得到当前mysqldump版本。
几个常用的例子(在mysqldump Ver 10.13 Distrib 5.1.30, for Win32 (ia32)下测试通过)
1.导出整个数据库
mysqldump -u 用户名 -p 数据库名 > 导出的文件名
mysqldump -u root -p student >d:\student.sql
2.导出一个数据库结构
mysqldump -u root -p -d --add-drop-table student >d:\student_structure.sql
-d 没有数据 --add-drop-table 在每个create语句之前增加一个drop table
3.导出一个表
mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名
mysqldump -u root -p schoolproject student>d:\schoolproject_student.sql
4.导入数据库
shell> mysqladmin –u root –p create target_db_name
shell> mysql –u root –p target_db_name < backup-file.sql
就是:shell> mysql 数据库名 < 文件名
或者使用source 命令
进入mysql数据库控制台,mysql -u root –p
mysql>use 数据库
然后使用source命令,后面参数为脚本文件(.sql文件)
mysql>source d:\student.sql
MySQL的mysqldump工具,基本用法是:
shell> mysqldump [OPTIONS] database [tables]
通过执行mysqldump --help,得到当前mysqldump版本支持的选项表。
通过执行mysqldump –V,得到当前mysqldump版本。
几个常用的例子(在mysqldump Ver 10.13 Distrib 5.1.30, for Win32 (ia32)下测试通过)
1.导出整个数据库
mysqldump -u 用户名 -p 数据库名 > 导出的文件名
mysqldump -u root -p student >d:\student.sql
2.导出一个数据库结构
mysqldump -u root -p -d --add-drop-table student >d:\student_structure.sql
-d 没有数据 --add-drop-table 在每个create语句之前增加一个drop table
3.导出一个表
mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名
mysqldump -u root -p schoolproject student>d:\schoolproject_student.sql
4.导入数据库
shell> mysqladmin –u root –p create target_db_name
shell> mysql –u root –p target_db_name < backup-file.sql
就是:shell> mysql 数据库名 < 文件名
或者使用source 命令
进入mysql数据库控制台,mysql -u root –p
mysql>use 数据库
然后使用source命令,后面参数为脚本文件(.sql文件)
mysql>source d:\student.sql
Ubuntu是一套基于Debian的Linux系统,它追求的是“Just Work”,最新的7.10版本发布于2007年10月,不同于其他Linux发行版本,Ubuntu的所有版本都是免费的,包括企业版。
第一次安装Ubuntu,发现比较“奇怪”的一点是,在安装过程中,不像其他发布版本那样,要求设置root的密码,也就无法以root登录了。经过去网上查询才发现:Ubuntu默认是关闭root帐户的,这样做有如下优点:
起初Ubuntu团队希望安装尽可能的简单,不使用root,在安装期间的两个用户交互步骤可以省略。(科林·沃森)
更进一步, 如果在安装中使用root,用户将被要求永远记住他们选择的密码--即使他们很少使用到它。Root密码经常被对Unix安全模型不熟悉的用户忘记。(马特·齐默曼)
它防止了缺省登录时“我能做任何事情”--在较大的变化发生之前,你将被提示输入口令,这可以使你考虑你这样做的结果。 如果你作为root登录,你可以删除一些“没用的文件夹”并且不会意识到你正处于错误的目录,那时已经太晚了。它是在Unix下长时间使用“su-command-^D”练习的情况下,代替一直呆在root shell--除非你做严重的系统维护(那时你仍然可以使用 "sudo su")。(吉姆·奇塔姆 和 安德鲁·索巴拉)
Sudo 增加了运行命令的日志记录(在/var/log/auth.log)。如果你陷入困境,你总是可以返回并看见那些运行的命令。(安德鲁·Zbikowski)
开启root帐号的方法:
为了启用root 帐号(也就是设置一个口令)使用:
sudo passwd root
当你使用完毕后屏蔽root帐号使用:
sudo passwd -l root
这个将锁住root帐号。
如何在终端模式下切换到root身份?
sudo -s -H
Password: <在此输入密码>
allen:用root帐户怎么也登陆不了。原来默认是关闭的。汗一个...-_-!! 帐户已经启用 哈哈YES
第一次安装Ubuntu,发现比较“奇怪”的一点是,在安装过程中,不像其他发布版本那样,要求设置root的密码,也就无法以root登录了。经过去网上查询才发现:Ubuntu默认是关闭root帐户的,这样做有如下优点:
起初Ubuntu团队希望安装尽可能的简单,不使用root,在安装期间的两个用户交互步骤可以省略。(科林·沃森)
更进一步, 如果在安装中使用root,用户将被要求永远记住他们选择的密码--即使他们很少使用到它。Root密码经常被对Unix安全模型不熟悉的用户忘记。(马特·齐默曼)
它防止了缺省登录时“我能做任何事情”--在较大的变化发生之前,你将被提示输入口令,这可以使你考虑你这样做的结果。 如果你作为root登录,你可以删除一些“没用的文件夹”并且不会意识到你正处于错误的目录,那时已经太晚了。它是在Unix下长时间使用“su-command-^D”练习的情况下,代替一直呆在root shell--除非你做严重的系统维护(那时你仍然可以使用 "sudo su")。(吉姆·奇塔姆 和 安德鲁·索巴拉)
Sudo 增加了运行命令的日志记录(在/var/log/auth.log)。如果你陷入困境,你总是可以返回并看见那些运行的命令。(安德鲁·Zbikowski)
开启root帐号的方法:
为了启用root 帐号(也就是设置一个口令)使用:
sudo passwd root
当你使用完毕后屏蔽root帐号使用:
sudo passwd -l root
这个将锁住root帐号。
如何在终端模式下切换到root身份?
sudo -s -H
Password: <在此输入密码>
allen:用root帐户怎么也登陆不了。原来默认是关闭的。汗一个...-_-!! 帐户已经启用 哈哈YES
一、简介
如果你对Unix/Linux有所了解的话,你应该知道他们大都自带了C和C++的编译器,分别是GCC和G++。Unix在程序安装及Make等许多地方使用到了这些编译器。利用一些控制台命令,C++和PHP, 我将向你介绍怎样生成一个完整的C++程序例子,他可以在用PHP程序来执行,并能获得相应的输出结果。我将先生成C++程序代码,并编译它,谈后讨论我们将如果通过使用PHP的函数passthru来执行这个程序。从某种意义上来说,这边文章给我们提供一种通过Web页面来访问一般程序的方法。
为了能更好的理解这篇文章,你应该有一台运行着apache和最新版本php的unix/Linux服务器。同时也应该掌握C++, unix控制台命令,当然一些PHP的编程经验也是必需的。
二、编写一个C++程序
阅读全文
如果你对Unix/Linux有所了解的话,你应该知道他们大都自带了C和C++的编译器,分别是GCC和G++。Unix在程序安装及Make等许多地方使用到了这些编译器。利用一些控制台命令,C++和PHP, 我将向你介绍怎样生成一个完整的C++程序例子,他可以在用PHP程序来执行,并能获得相应的输出结果。我将先生成C++程序代码,并编译它,谈后讨论我们将如果通过使用PHP的函数passthru来执行这个程序。从某种意义上来说,这边文章给我们提供一种通过Web页面来访问一般程序的方法。
为了能更好的理解这篇文章,你应该有一台运行着apache和最新版本php的unix/Linux服务器。同时也应该掌握C++, unix控制台命令,当然一些PHP的编程经验也是必需的。
二、编写一个C++程序

同时在线访问量继续增大 对于1G内存的服务器明显感觉到吃力严重时甚至每天都会死机 或者时不时的服务器卡一下 这个问题曾经困扰了我半个多月MySQL使用是很具伸缩性的算法,因此你通常能用很少的内存运行或给MySQL更多的被存以得到更好的性能。
安装好mysql后,配制文件应该在/usr/local/mysql/share/mysql目录中,配制文件有几个,有my-huge.cnf my-medium.cnf my-large.cnf my-small.cnf,不同的流量的网站和不同配制的服务器环境,当然需要有不同的配制文件了。
阅读全文
安装好mysql后,配制文件应该在/usr/local/mysql/share/mysql目录中,配制文件有几个,有my-huge.cnf my-medium.cnf my-large.cnf my-small.cnf,不同的流量的网站和不同配制的服务器环境,当然需要有不同的配制文件了。
