Archive for 电脑知识

网众Linux服务器常用命令

// June 25th, 2010 // 1 Comment » // 服务器配置管理

1, cd /mnt————————————-进入MNT 目录
2, ls——————————————查看mnt 目录下的文件
3, mkdir usb ———————————-新建节usb 文件夹
4, mount /dev/sdf1 /mnt/usd ——————-加载U盘(sdf1 注:f为U盘符必需加数字1)
5, cd /usd ————————————进入USB目录
6, ls——————————————查看 USB 目录 找到所需要的 服务端版本
7, cp nxp*** /root —————————-复制服务端到root目录下
8, umount /mnt/usb —————————-卸载掉U盘
9, cd~ —————————————-回到root 目录
10,sh nxp*** ———————————-安装服务端
11,ethtool eth0 或ethtool eth1 —————-查看所用网卡 以yes/no 表示
12,vnc restart ——————————–重启vnc 远程联接服务
13,reboot ————————————-重启服务器
14,halt —————————————关闭服务器
15,history ————————————查看此命令前所执行过的命令
16,ethtool -k eth0 / eth1 ———————查看网卡流量 试用情况 yes/no (小写的k)
17,ethtool -K eth0/eth1 tx off —————-关闭 网卡较验 解决 开机后黑屏问题 (大写的K)
18,df -h ————————————–查看磁盘 使用空间的信息
19,ifconfig ———————————–查看网卡及相对的IP 配置
20,netconfig ———————————-配置服务器名及IP 网关 DNS
21,nxpbootmgr ———————————启动管理器
22,nxpiomgr ———————————–数据管理器
23,cd /etc/rc.d/ ——————————进入 rc.d 目录 找到rc.local 文件
24,nc rs.local ——————————-编辑rc.local文件 在最后加nxp restart 命令
25,cat /proc/partitions ———————–查看磁盘 信息 数量及所有盘符
26,tar xf ————————————-解压.tar 压缩包的命令
27,gftp —————————————在命令窗口 打开FTP 窗口
28,FTP——————————— ——-download.netzone.soft.com 端口2121 名ldk5 密码 52399548
29,help ————————————–命令的使用说明(如:rm –help)
30,w ——————————————查看磁盘和CPU 内存 使用量
31,top 或 pstree ——————————查看 进程
32,xconfig ———————————–配置 桌面
33,killall ———————————–杀死或关闭某进程或服务 如:(killall nxpbootmgr.exe)
34,cd /var/log ——————————–进入 log 文件目录
35,less syslog ——————————–用less命令打开syslog 日志文件
36,hdparm -Tt /dev/sda/ ———————–测磁盘读写速度 分别加盘符sda,adb… md0或md1
37,nzsyscfg **********************************-磁盘管理
38,dmesg 或dmesg |more 或 dmesg |grep “error”——————-看系统日志
39,tcpdump arp ——————————–Linux 系统下抓包
40,opt/netzone/nxp/——–目录下建文件夹名为:conf 在conf文件夹内建空文件名为:dont_sync_time重启服务
41,cat —————————————-打开 文件
mdmesg ————————————-加载启动信息
lspci ————————————–查看PCI信息
mount ————————————–挂载信息
mdadm -D /dev/md0 ————————–检查软阵列 nxpver 版本
mke2fs -j /dev/sda3————————-格式化回写分区 或是 md0 要先卸载

——————————————服务器是否是硬盘是否有报错 打开终端:dmesg |grep “error”

——————————————-看看是否有硬盘错误信息 打开终端:cat /opt/netzone/nxp/syslog.txt

l 重起服务器:reboot
l 重起服务:nxp restart
l 停止服务:nxp stop
l 开启服务: nxp start
l 结束启动服务器进程:killall nxpbootmgr.exe
l 打开启动服务器进程:nxpbootmgr
l 结束数据服务器进程:killall nxp iomgr.exe
l 打开文件系统:thunarkillall nxpiomgr.exe
l 打开数据服务器进程:nxp iomgr
l 打开系统配置工具:nzsyscfg
l 打开网众控制台:nzcon
l 配置服务器IP:netconfig
l 查看IP地址:ifconfig
l 配置图行界面:xconfig
l 查看系统日志:dmesg 或dmesg |more 或 dmesg |grep “error”
l 查看进程:top 或 pstree
l 显示当前负载:W
l 检测硬盘读写:hdparm -Tt /dev/
l 查看磁盘空间:df 或 df -h
l 查看PCI信息: lspci
l 执行:sh
l 拷贝:cp
l 改名:mv
l 编辑:xedit 或 nc 或 nedit
l 查看当前网卡状态:ifconfig eth0/1

手动加载29320驱动
aic79XX   自已添加 /etc/rc.d 目录编辑 rc.modules文件,最后一行加
/sbin/modprobe aic79xx
手动加载LSI1030驱动
nedit /etc/rc.d/rc.modules
最后一行加上/sbin/modprobe mptscsih(ft3xx TX4000阵列)
或挂载modprobe mptscsih。 cd /etc/rc.d
ech0 /sbin/modprobe mptscsih >>rc.modules

网众连接:
export DISPLAY=60.63.246.96:1 Xterm &
端口:
AUTO Y 21 TO 21 192.168.1.251
网众:5901

优化硬盘读写参数:
elvtune -r 1024 -w 2048 /dev/sda /dev/sdb

软阵列设置
(注意网众软阵列工作站母盘阵列卷大小一定为64K)
/usr/lib/netzone/mdconfig
./mdconfig(/sda3—sdb 工作站回写   /Sdc–sdb工作站母盘)
或/usr/lib/netzone/mkraid
nzsyscfg配置命令

XP安装客户端无法启动
HKEY_LOCAL_MACHINE\SYSTEM\CurrentCcontrolSet\Control\class\<4D36E972- E325-11CE-BFC1-08002BE10318>修改upperfilter,把NXP去掉。

客户端版本:
HKEY_LOCAL_MACHINE\SOFTWARE\NETZONESOFT\NXD XP\Option
CFG   工作站对应的配置只读
DISK   磁盘只读
super   超级工作站只读
severIP nxp 服务端
nxpclient 客户端

页面文件大小:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentCcontrolSet\SEVVICES\nxdinit\
pagefile   c:\pagefile.sys 512 512

故障:
一.工作站有一台工作站在XP滚动条不断滚动?
首先把这台工作站的IP地址换一下,一般是IP地址冲突.
如果有太多的或全部的的话,有可能更网众服务端有问题,请更换服务端.

二.服务器一切正常,所有工作无法启动,无法引导?
首先:打开nxp管理器看看有没有什么报错,如果没有一切正常,能看到工作站记录.
检查服务器网络是否连接正常,打开网站看服务器络是否能打开网站.
重启一下nxp服务(打开终端nxp restart)

三.服务器很卡,工作站也很卡?
首先检查一下,服务器负载(打开终端:w—-看第一个三位数是否大于5,如果大于5说明服务器负载很重,低下5说明服务器负载正常).
检查一下,服务器是否是硬盘是否有报错(打开终端:dmesg—–看看是否有硬盘错误信息.
打开终端:cat /opt/netzone/nxp/syslog.txt—-看看有没有什么特殊的报错)
最后,看一下服务端和客户端的使用.更换一个好的服务端和客户端.

四.服务器死机?(服务器Caps Lock灯和Scroll Lock灯闪烁)
最常见的服务器内存出问题,更换内存测试.
其次检查硬盘是否正常,如没有报错.更换电源测试.

五.打开NXP管理器报错,报配置不完整?
查看磁盘是否满了.用df -h 查看磁盘空间,如果满了
1. 先把挂载的分区umount
一般需要先停止服务,然后执行umount /mnt
如果无法卸载,需要重新启动一下服务器
2. 格式化回写分区
mke2fs -j /dev/sda3
3. 重新挂载回写分区
mount /mnt /dev/sda3
进入终端:
cd /opt/netzone/nxp/sysback
cp 20060305.CFG ../SYSINFO.CFG
nxp restart从启一下nxp服务

如果没满,新建一个磁盘,把所有工作站选中,编辑一下.
nxp restart从启一下nxp服务

加载启动项:
echo nxp restart >> /etc/rc.d/rc.local

cat /var/log/syslog |grep error |more
查看日志错误信息!

Adobe Acrobat 9 Pro Extended 注册码

// April 23rd, 2010 // No Comments » // 电脑知识

138018537074855827353932
138013877929332185223441
138015781574000494225490
138017482815450322611848

adobe cs5 序列号

// April 23rd, 2010 // No Comments » // Adobe技术总汇, hack一下

Adobe CS5 序列号

1325-1558-5864-4422-1094-1126
1325-1958-5864-4422-1094-1178

php curl详解

// April 4th, 2010 // 2 Comments » // PHP基础知识累积

目前为目最全的CURL中文说明了,采集用到,原出处不详…
PHP中的CURL函数库(Client URL Library Function)
curl_close — 关闭一个curl会话
curl_copy_handle — 拷贝一个curl连接资源的所有内容和参数
curl_errno — 返回一个包含当前会话错误信息的数字编号
curl_error — 返回一个包含当前会话错误信息的字符串
curl_exec — 执行一个curl会话
curl_getinfo — 获取一个curl连接资源句柄的信息
curl_init — 初始化一个curl会话
curl_multi_add_handle — 向curl批处理会话中添加单独的curl句柄资源
curl_multi_close — 关闭一个批处理句柄资源
curl_multi_exec — 解析一个curl批处理句柄
curl_multi_getcontent — 返回获取的输出的文本流
curl_multi_info_read — 获取当前解析的curl的相关传输信息
curl_multi_init — 初始化一个curl批处理句柄资源
curl_multi_remove_handle — 移除curl批处理句柄资源中的某个句柄资源
curl_multi_select — Get all the sockets associated with the cURL extension, which can then be “selected”
curl_setopt_array — 以数组的形式为一个curl设置会话参数
curl_setopt — 为一个curl设置会话参数
curl_version — 获取curl相关的版本信息
curl_init()函数的作用初始化一个curl会话,curl_init()函数唯一的一个参数是可选的,表示一个url地址。
curl_exec()函数的作用是执行一个curl会话,唯一的参数是curl_init()函数返回的句柄。
curl_close()函数的作用是关闭一个curl会话,唯一的参数是curl_init()函数返回的句柄。
$ch = curl_init(“http://www.baidu.com/“);
curl_exec($ch);
curl_close($ch);
?>
curl_version()函数的作用是获取curl相关的版本信息,curl_version()函数有一个参数,不清楚是做什么的
print_r(curl_version())
?>
curl_getinfo()函数的作用是获取一个curl连接资源句柄的信息,curl_getinfo()函数有两个参数,第一个参数是curl的资源句柄,第二个参数是下面一些常量:
$ch = curl_init(“http://www.baidu.com/“);
print_r(curl_getinfo($ch));
?>
可选的常量包括:
CURLINFO_EFFECTIVE_URL
最后一个有效的url地址
CURLINFO_HTTP_CODE
最后一个收到的HTTP代码
CURLINFO_FILETIME
远程获取文档的时间,如果无法获取,则返回值为“-1”
CURLINFO_TOTAL_TIME
最后一次传输所消耗的时间
CURLINFO_NAMELOOKUP_TIME
名称解析所消耗的时间
CURLINFO_CONNECT_TIME
建立连接所消耗的时间
CURLINFO_PRETRANSFER_TIME
从建立连接到准备传输所使用的时间
CURLINFO_STARTTRANSFER_TIME
从建立连接到传输开始所使用的时间
CURLINFO_REDIRECT_TIME
在事务传输开始前重定向所使用的时间
CURLINFO_SIZE_UPLOAD
上传数据量的总值
CURLINFO_SIZE_DOWNLOAD
下载数据量的总值
CURLINFO_SPEED_DOWNLOAD
平均下载速度
CURLINFO_SPEED_UPLOAD
平均上传速度
CURLINFO_HEADER_SIZE
header部分的大小
CURLINFO_HEADER_OUT
发送请求的字符串
CURLINFO_REQUEST_SIZE
在HTTP请求中有问题的请求的大小
CURLINFO_SSL_VERIFYRESULT
Result of SSL certification verification requested by setting CURLOPT_SSL_VERIFYPEER
CURLINFO_CONTENT_LENGTH_DOWNLOAD
从Content-Length: field中读取的下载内容长度
CURLINFO_CONTENT_LENGTH_UPLOAD
上传内容大小的说明
CURLINFO_CONTENT_TYPE
下载内容的“Content-type”值,NULL表示服务器没有发送有效的“Content-Type: header”
curl_setopt()函数的作用是为一个curl设置会话参数。curl_setopt_array()函数的作用是以数组的形式为一个curl设置会话参数。
$ch = curl_init();
$fp = fopen(“example_homepage.txt“, “w“);
curl_setopt($ch, CURLOPT_FILE, $fp);
$options = array(
CURLOPT_URL => ‘http://www.baidu.com/‘,
CURLOPT_HEADER => false
);
curl_setopt_array($ch, $options);
curl_exec($ch);
curl_close($ch);
fclose($fp);
?>
可设置的参数有:
CURLOPT_AUTOREFERER
自动设置header中的referer信息
CURLOPT_BINARYTRANSFER
在启用CURLOPT_RETURNTRANSFER时候将获取数据返回
CURLOPT_COOKIESESSION
启用时curl会仅仅传递一个session cookie,忽略其他的cookie,默认状况下curl会将所有的cookie返回给服务端。session cookie是指那些用来判断服务器端的session是否有效而存在的cookie。
CURLOPT_CRLF
启用时将Unix的换行符转换成回车换行符。
CURLOPT_DNS_USE_GLOBAL_CACHE
启用时会启用一个全局的DNS缓存,此项为线程安全的,并且默认为true。
CURLOPT_FAILONERROR
显示HTTP状态码,默认行为是忽略编号小于等于400的HTTP信息
CURLOPT_FILETIME
启用时会尝试修改远程文档中的信息。结果信息会通过curl_getinfo()函数的CURLINFO_FILETIME选项返回。
CURLOPT_FOLLOWLOCATION
启用时会将服务器服务器返回的“Location:”放在header中递归的返回给服务器,使用CURLOPT_MAXREDIRS可以限定递归返回的数量。
CURLOPT_FORBID_REUSE
在完成交互以后强迫断开连接,不能重用。
CURLOPT_FRESH_CONNECT
强制获取一个新的连接,替代缓存中的连接。
CURLOPT_FTP_USE_EPRT
TRUE to use EPRT (and LPRT) when doing active FTP downloads. Use FALSE to disable EPRT and LPRT and use PORT only.
Added in PHP 5.0.0.
CURLOPT_FTP_USE_EPSV
TRUE to first try an EPSV command for FTP transfers before reverting back to PASV. Set to FALSE to disable EPSV.
CURLOPT_FTPAPPEND
TRUE to append to the remote file instead of overwriting it.
CURLOPT_FTPASCII
An alias of CURLOPT_TRANSFERTEXT. Use that instead.
CURLOPT_FTPLISTONLY
TRUE to only list the names of an FTP directory.
CURLOPT_HEADER
启用时会将头文件的信息作为数据流输出。
CURLOPT_HTTPGET
启用时会设置HTTP的method为GET,因为GET是默认是,所以只在被修改的情况下使用。
CURLOPT_HTTPPROXYTUNNEL
启用时会通过HTTP代理来传输。
CURLOPT_MUTE
讲curl函数中所有修改过的参数恢复默认值。
CURLOPT_NETRC
在连接建立以后,访问~/.netrc文件获取用户名和密码信息连接远程站点。
CURLOPT_NOBODY
启用时将不对HTML中的body部分进行输出。
CURLOPT_NOPROGRESS
启用时关闭curl传输的进度条,此项的默认设置为true
CURLOPT_NOSIGNAL
启用时忽略所有的curl传递给php进行的信号。在SAPI多线程传输时此项被默认打开。
CURLOPT_POST
启用时会发送一个常规的POST请求,类型为:application/x-www-form-urlencoded,就像表单提交的一样。
CURLOPT_PUT
启用时允许HTTP发送文件,必须同时设置CURLOPT_INFILE和CURLOPT_INFILESIZE
CURLOPT_RETURNTRANSFER
讲curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
CURLOPT_SSL_VERIFYPEER
FALSE to stop cURL from verifying the peer’s certificate. Alternate certificates to verify against can be specified with the CURLOPT_CAINFO option or a certificate directory can be specified with the CURLOPT_CAPATH option. CURLOPT_SSL_VERIFYHOST may also need to be TRUE or FALSE if CURLOPT_SSL_VERIFYPEER is disabled (it defaults to 2). TRUE by default as of cURL 7.10. Default bundle installed as of cURL 7.10.
CURLOPT_TRANSFERTEXT
TRUE to use ASCII mode for FTP transfers. For LDAP, it retrieves data in plain text instead of HTML. On Windows systems, it will not set STDOUT to binary mode.
CURLOPT_UNRESTRICTED_AUTH
在使用CURLOPT_FOLLOWLOCATION产生的header中的多个locations中持续追加用户名和密码信息,即使域名已发生改变。
CURLOPT_UPLOAD
启用时允许文件传输
CURLOPT_VERBOSE
启用时会汇报所有的信息,存放在STDERR或指定的CURLOPT_STDERR中
CURLOPT_BUFFERSIZE
每次获取的数据中读入缓存的大小,这个值每次都会被填满。
CURLOPT_CLOSEPOLICY
不是CURLCLOSEPOLICY_LEAST_RECENTLY_USED就是CURLCLOSEPOLICY_OLDEST,还存在另外三个,但是curl暂时还不支持。.
CURLOPT_CONNECTTIMEOUT
在发起连接前等待的时间,如果设置为0,则不等待。
CURLOPT_DNS_CACHE_TIMEOUT
设置在内存中保存DNS信息的时间,默认为120秒。
CURLOPT_FTPSSLAUTH
The FTP authentication method (when is activated): CURLFTPAUTH_SSL (try SSL first), CURLFTPAUTH_TLS (try TLS first), or CURLFTPAUTH_DEFAULT (let cURL decide).
CURLOPT_HTTP_VERSION
设置curl使用的HTTP协议,CURL_HTTP_VERSION_NONE(让curl自己判断),CURL_HTTP_VERSION_1_0(HTTP/1.0),CURL_HTTP_VERSION_1_1(HTTP/1.1)
CURLOPT_HTTPAUTH
使用的HTTP验证方法,可选的值 有:CURLAUTH_BASIC,CURLAUTH_DIGEST,CURLAUTH_GSSNEGOTIATE,CURLAUTH_NTLM,CURLAUTH_ANY,CURLAUTH_ANYSAFE, 可以使用“|”操作符分隔多个值,curl让服务器选择一个支持最好的值,CURLAUTH_ANY等价于CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM,CURLAUTH_ANYSAFE等价于CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM
CURLOPT_INFILESIZE
设定上传文件的大小
CURLOPT_LOW_SPEED_LIMIT
当传输速度小于CURLOPT_LOW_SPEED_LIMIT时,PHP会根据CURLOPT_LOW_SPEED_TIME来判断是否因太慢而取消传输。
CURLOPT_LOW_SPEED_TIME
The number of seconds the transfer should be below CURLOPT_LOW_SPEED_LIMIT for PHP to consider the transfer too slow and abort.
当传输速度小于CURLOPT_LOW_SPEED_LIMIT时,PHP会根据CURLOPT_LOW_SPEED_TIME来判断是否因太慢而取消传输。
CURLOPT_MAXCONNECTS
允许的最大连接数量,超过是会通过CURLOPT_CLOSEPOLICY决定应该停止哪些连接
CURLOPT_MAXREDIRS
指定最多的HTTP重定向的数量,这个选项是和CURLOPT_FOLLOWLOCATION一起使用的。
CURLOPT_PORT
一个可选的用来指定连接端口的量
CURLOPT_PROXYAUTH
The HTTP authentication method(s) to use for the proxy connection. Use the same bitmasks as described in CURLOPT_HTTPAUTH. For proxy authentication, only CURLAUTH_BASIC and CURLAUTH_NTLM are currently supported.
CURLOPT_PROXYPORT
The port number of the proxy to connect to. This port number can also be set in CURLOPT_PROXY.
CURLOPT_PROXYTYPE
Either CURLPROXY_HTTP (default) or CURLPROXY_SOCKS5.
CURLOPT_RESUME_FROM
在恢复传输时传递一个字节偏移量(用来断点续传)
CURLOPT_SSL_VERIFYHOST
1 to check the existence of a common name in the SSL peer certificate.
2 to check the existence of a common name and also verify that it matches the hostname provided.
CURLOPT_SSLVERSION
The SSL version (2 or 3) to use. By default PHP will try to determine this itself, although in some cases this must be set manually.
CURLOPT_TIMECONDITION
如果在CURLOPT_TIMEVALUE指定的某个时间以后被编辑过,则使用CURL_TIMECOND_IFMODSINCE返回页面,如果没有被修 改过,并且CURLOPT_HEADER为true,则返回一个”304 Not Modified”的header,CURLOPT_HEADER为false,则使用CURL_TIMECOND_ISUNMODSINCE,默认值为 CURL_TIMECOND_IFMODSINCE
CURLOPT_TIMEOUT
设置curl允许执行的最长秒数
CURLOPT_TIMEVALUE
设置一个CURLOPT_TIMECONDITION使用的时间戳,在默认状态下使用的是CURL_TIMECOND_IFMODSINCE
CURLOPT_CAINFO
The name of a file holding one or more certificates to verify the peer with. This only makes sense when used in combination with CURLOPT_SSL_VERIFYPEER.
CURLOPT_CAPATH
A directory that holds multiple CA certificates. Use this option alongside CURLOPT_SSL_VERIFYPEER.
CURLOPT_COOKIE
设定HTTP请求中“Set-Cookie:”部分的内容。
CURLOPT_COOKIEFILE
包含cookie信息的文件名称,这个cookie文件可以是Netscape格式或者HTTP风格的header信息。
CURLOPT_COOKIEJAR
连接关闭以后,存放cookie信息的文件名称
CURLOPT_CUSTOMREQUEST
A custom request method to use instead of “GET” or “HEAD” when doing a HTTP request. This is useful for doing “DELETE” or other, more obscure HTTP requests. Valid values are things like “GET”, “POST”, “CONNECT” and so on; i.e. Do not enter a whole HTTP request line here. For instance, entering “GET /index.html HTTP/1.0\r\n\r\n” would be incorrect.
Note: Don’t do this without making sure the server supports the custom request method first.
CURLOPT_EGBSOCKET
Like CURLOPT_RANDOM_FILE, except a filename to an Entropy Gathering Daemon socket.
CURLOPT_ENCODING
header中“Accept-Encoding: ”部分的内容,支持的编码格式为:”identity”,”deflate”,”gzip”。如果设置为空字符串,则表示支持所有的编码格式
CURLOPT_FTPPORT
The value which will be used to get the IP address to use for the FTP “POST” instruction. The “POST” instruction tells the remote server to connect to our specified IP address. The string may be a plain IP address, a hostname, a network interface name (under Unix), or just a plain ‘-’ to use the systems default IP address.
CURLOPT_INTERFACE
在外部网络接口中使用的名称,可以是一个接口名,IP或者主机名。
CURLOPT_KRB4LEVEL
KRB4(Kerberos 4)安全级别的设置,可以是一下几个值之一:”clear”,”safe”,”confidential”,”private”。默认的值 为”private”,设置为null的时候表示禁用KRB4,现在KRB4安全仅能在FTP传输中使用。
CURLOPT_POSTFIELDS
在HTTP中的“POST”操作。如果要传送一个文件,需要一个@开头的文件名
CURLOPT_PROXY
设置通过的HTTP代理服务器
CURLOPT_PROXYUSERPWD
连接到代理服务器的,格式为“[username]:[password]”的用户名和密码。
CURLOPT_RANDOM_FILE
设定存放SSL用到的随机数种子的文件名称
CURLOPT_RANGE
设置HTTP传输范围,可以用“X-Y”的形式设置一个传输区间,如果有多个HTTP传输,则使用逗号分隔多个值,形如:”X-Y,N-M”。
CURLOPT_REFERER
设置header中”Referer: ” 部分的值。
CURLOPT_SSL_CIPHER_LIST
A list of ciphers to use for SSL. For example, RC4-SHA and TLSv1 are valid cipher lists.
CURLOPT_SSLCERT
传递一个包含PEM格式证书的字符串。
CURLOPT_SSLCERTPASSWD
传递一个包含使用CURLOPT_SSLCERT证书必需的密码。
CURLOPT_SSLCERTTYPE
The format of the certificate. Supported formats are “PEM” (default), “DER”, and “ENG”.
CURLOPT_SSLENGINE
The identifier for the crypto engine of the private SSL key specified in CURLOPT_SSLKEY.
CURLOPT_SSLENGINE_DEFAULT
The identifier for the crypto engine used for asymmetric crypto operations.
CURLOPT_SSLKEY
The name of a file containing a private SSL key.
CURLOPT_SSLKEYPASSWD
The secret password needed to use the private SSL key specified in CURLOPT_SSLKEY.
Note: Since this option contains a sensitive password, remember to keep the PHP script it is contained within safe.
CURLOPT_SSLKEYTYPE
The key type of the private SSL key specified in CURLOPT_SSLKEY. Supported key types are “PEM” (default), “DER”, and “ENG”.
CURLOPT_URL
需要获取的URL地址,也可以在PHP的curl_init()函数中设置。
CURLOPT_USERAGENT
在HTTP请求中包含一个”user-agent”头的字符串。
CURLOPT_USERPWD
传递一个连接中需要的用户名和密码,格式为:“[username]:[password]”。
CURLOPT_HTTP200ALIASES
设置不再以error的形式来处理HTTP 200的响应,格式为一个数组。
CURLOPT_HTTPHEADER
设置一个header中传输内容的数组。
CURLOPT_POSTQUOTE
An array of FTP commands to execute on the server after the FTP request has been performed.
CURLOPT_QUOTE
An array of FTP commands to execute on the server prior to the FTP request.
CURLOPT_FILE
设置输出文件的位置,值是一个资源类型,默认为STDOUT (浏览器)。
CURLOPT_INFILE
在上传文件的时候需要读取的文件地址,值是一个资源类型。
CURLOPT_STDERR
设置一个错误输出地址,值是一个资源类型,取代默认的STDERR。
CURLOPT_WRITEHEADER
设置header部分内容的写入的文件地址,值是一个资源类型。
CURLOPT_HEADERFUNCTION
设置一个回调函数,这个函数有两个参数,第一个是curl的资源句柄,第二个是输出的header数据。header数据的输出必须依赖这个函数,返回已写入的数据大小。
CURLOPT_PASSWDFUNCTION
设置一个回调函数,有三个参数,第一个是curl的资源句柄,第二个是一个密码提示符,第三个参数是密码长度允许的最大值。返回密码的值。
CURLOPT_READFUNCTION
设置一个回调函数,有两个参数,第一个是curl的资源句柄,第二个是读取到的数据。数据读取必须依赖这个函数。返回读取数据的大小,比如0或者EOF。
CURLOPT_WRITEFUNCTION
设置一个回调函数,有两个参数,第一个是curl的资源句柄,第二个是写入的数据。数据写入必须依赖这个函数。返回精确的已写入数据的大小
curl_copy_handle()函数的作用是拷贝一个curl连接资源的所有内容和参数
$ch = curl_init(“http://www.baidu.com/“);
$another = curl_copy_handle($ch);
curl_exec($another);
curl_close($another);
?>
curl_error()函数的作用是返回一个包含当前会话错误信息的字符串。
curl_errno()函数的作用是返回一个包含当前会话错误信息的数字编号。
curl_multi_init()函数的作用是初始化一个curl批处理句柄资源。
curl_multi_add_handle()函数的作用是向curl批处理会话中添加单独的curl句柄资源。curl_multi_add_handle()函数有两个参数,第一个参数表示一个curl批处理句柄资源,第二个参数表示一个单独的curl句柄资源。
curl_multi_exec()函数的作用是解析一个curl批处理句柄,curl_multi_exec()函数有两个参数,第一个参数表示一个批处理句柄资源,第二个参数是一个引用值的参数,表示剩余需要处理的单个的curl句柄资源数量。
curl_multi_remove_handle()函数表示移除curl批处理句柄资源中的某个句柄资源,curl_multi_remove_handle()函数有两个参数,第一个参数表示一个curl批处理句柄资源,第二个参数表示一个单独的curl句柄资源。
curl_multi_close()函数的作用是关闭一个批处理句柄资源。
$ch1 = curl_init();
$ch2 = curl_init();
curl_setopt($ch1, CURLOPT_URL, “http://www.baidu.com/“);
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch2, CURLOPT_URL, “http://www.google.com/“);
curl_setopt($ch2, CURLOPT_HEADER, 0);
$mh = curl_multi_init();
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);
do {
curl_multi_exec($mh,$flag);
} while ($flag > 0);
curl_multi_remove_handle($mh,$ch1);
curl_multi_remove_handle($mh,$ch2);
curl_multi_close($mh);
?>
curl_multi_getcontent()函数的作用是在设置了CURLOPT_RETURNTRANSFER的情况下,返回获取的输出的文本流。
curl_multi_info_read()函数的作用是获取当前解析的curl的相关传输信息。
curl_multi_select()
Get all the sockets associated with the cURL extension, which can then be “selected”

目前为目最全的CURL中文说明了,采集用到,原出处不详…
PHP中的CURL函数库(Client URL Library Function)
curl_close — 关闭一个curl会话curl_copy_handle — 拷贝一个curl连接资源的所有内容和参数curl_errno — 返回一个包含当前会话错误信息的数字编号curl_error — 返回一个包含当前会话错误信息的字符串curl_exec — 执行一个curl会话curl_getinfo — 获取一个curl连接资源句柄的信息curl_init — 初始化一个curl会话curl_multi_add_handle — 向curl批处理会话中添加单独的curl句柄资源curl_multi_close — 关闭一个批处理句柄资源curl_multi_exec — 解析一个curl批处理句柄curl_multi_getcontent — 返回获取的输出的文本流curl_multi_info_read — 获取当前解析的curl的相关传输信息curl_multi_init — 初始化一个curl批处理句柄资源curl_multi_remove_handle — 移除curl批处理句柄资源中的某个句柄资源curl_multi_select — Get all the sockets associated with the cURL extension, which can then be “selected”curl_setopt_array — 以数组的形式为一个curl设置会话参数curl_setopt — 为一个curl设置会话参数curl_version — 获取curl相关的版本信息
curl_init()函数的作用初始化一个curl会话,curl_init()函数唯一的一个参数是可选的,表示一个url地址。curl_exec()函数的作用是执行一个curl会话,唯一的参数是curl_init()函数返回的句柄。curl_close()函数的作用是关闭一个curl会话,唯一的参数是curl_init()函数返回的句柄。

$ch = curl_init(“http://www.baidu.com/“);curl_exec($ch);curl_close($ch);?>curl_version()函数的作用是获取curl相关的版本信息,curl_version()函数有一个参数,不清楚是做什么的

print_r(curl_version())?>curl_getinfo()函数的作用是获取一个curl连接资源句柄的信息,curl_getinfo()函数有两个参数,第一个参数是curl的资源句柄,第二个参数是下面一些常量:

$ch = curl_init(“http://www.baidu.com/“);print_r(curl_getinfo($ch));?>可选的常量包括:
CURLINFO_EFFECTIVE_URL最后一个有效的url地址
CURLINFO_HTTP_CODE最后一个收到的HTTP代码
CURLINFO_FILETIME远程获取文档的时间,如果无法获取,则返回值为“-1”
CURLINFO_TOTAL_TIME最后一次传输所消耗的时间
CURLINFO_NAMELOOKUP_TIME名称解析所消耗的时间
CURLINFO_CONNECT_TIME建立连接所消耗的时间
CURLINFO_PRETRANSFER_TIME从建立连接到准备传输所使用的时间
CURLINFO_STARTTRANSFER_TIME从建立连接到传输开始所使用的时间
CURLINFO_REDIRECT_TIME在事务传输开始前重定向所使用的时间
CURLINFO_SIZE_UPLOAD上传数据量的总值
CURLINFO_SIZE_DOWNLOAD下载数据量的总值
CURLINFO_SPEED_DOWNLOAD平均下载速度
CURLINFO_SPEED_UPLOAD平均上传速度
CURLINFO_HEADER_SIZEheader部分的大小
CURLINFO_HEADER_OUT发送请求的字符串
CURLINFO_REQUEST_SIZE在HTTP请求中有问题的请求的大小
CURLINFO_SSL_VERIFYRESULTResult of SSL certification verification requested by setting CURLOPT_SSL_VERIFYPEER
CURLINFO_CONTENT_LENGTH_DOWNLOAD从Content-Length: field中读取的下载内容长度
CURLINFO_CONTENT_LENGTH_UPLOAD上传内容大小的说明
CURLINFO_CONTENT_TYPE下载内容的“Content-type”值,NULL表示服务器没有发送有效的“Content-Type: header”
curl_setopt()函数的作用是为一个curl设置会话参数。curl_setopt_array()函数的作用是以数组的形式为一个curl设置会话参数。

$ch = curl_init();$fp = fopen(“example_homepage.txt“, “w“);curl_setopt($ch, CURLOPT_FILE, $fp);$options = array(CURLOPT_URL => ‘http://www.baidu.com/‘,CURLOPT_HEADER => false);curl_setopt_array($ch, $options);curl_exec($ch);curl_close($ch);fclose($fp);?>可设置的参数有:
CURLOPT_AUTOREFERER自动设置header中的referer信息
CURLOPT_BINARYTRANSFER在启用CURLOPT_RETURNTRANSFER时候将获取数据返回
CURLOPT_COOKIESESSION启用时curl会仅仅传递一个session cookie,忽略其他的cookie,默认状况下curl会将所有的cookie返回给服务端。session cookie是指那些用来判断服务器端的session是否有效而存在的cookie。
CURLOPT_CRLF启用时将Unix的换行符转换成回车换行符。
CURLOPT_DNS_USE_GLOBAL_CACHE启用时会启用一个全局的DNS缓存,此项为线程安全的,并且默认为true。
CURLOPT_FAILONERROR显示HTTP状态码,默认行为是忽略编号小于等于400的HTTP信息
CURLOPT_FILETIME启用时会尝试修改远程文档中的信息。结果信息会通过curl_getinfo()函数的CURLINFO_FILETIME选项返回。
CURLOPT_FOLLOWLOCATION启用时会将服务器服务器返回的“Location:”放在header中递归的返回给服务器,使用CURLOPT_MAXREDIRS可以限定递归返回的数量。
CURLOPT_FORBID_REUSE在完成交互以后强迫断开连接,不能重用。
CURLOPT_FRESH_CONNECT强制获取一个新的连接,替代缓存中的连接。
CURLOPT_FTP_USE_EPRTTRUE to use EPRT (and LPRT) when doing active FTP downloads. Use FALSE to disable EPRT and LPRT and use PORT only.Added in PHP 5.0.0.
CURLOPT_FTP_USE_EPSVTRUE to first try an EPSV command for FTP transfers before reverting back to PASV. Set to FALSE to disable EPSV.
CURLOPT_FTPAPPENDTRUE to append to the remote file instead of overwriting it.
CURLOPT_FTPASCIIAn alias of CURLOPT_TRANSFERTEXT. Use that instead.
CURLOPT_FTPLISTONLYTRUE to only list the names of an FTP directory.
CURLOPT_HEADER启用时会将头文件的信息作为数据流输出。
CURLOPT_HTTPGET启用时会设置HTTP的method为GET,因为GET是默认是,所以只在被修改的情况下使用。
CURLOPT_HTTPPROXYTUNNEL启用时会通过HTTP代理来传输。
CURLOPT_MUTE讲curl函数中所有修改过的参数恢复默认值。
CURLOPT_NETRC在连接建立以后,访问~/.netrc文件获取用户名和密码信息连接远程站点。
CURLOPT_NOBODY启用时将不对HTML中的body部分进行输出。
CURLOPT_NOPROGRESS启用时关闭curl传输的进度条,此项的默认设置为true
CURLOPT_NOSIGNAL启用时忽略所有的curl传递给php进行的信号。在SAPI多线程传输时此项被默认打开。
CURLOPT_POST启用时会发送一个常规的POST请求,类型为:application/x-www-form-urlencoded,就像表单提交的一样。
CURLOPT_PUT启用时允许HTTP发送文件,必须同时设置CURLOPT_INFILE和CURLOPT_INFILESIZE
CURLOPT_RETURNTRANSFER讲curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
CURLOPT_SSL_VERIFYPEERFALSE to stop cURL from verifying the peer’s certificate. Alternate certificates to verify against can be specified with the CURLOPT_CAINFO option or a certificate directory can be specified with the CURLOPT_CAPATH option. CURLOPT_SSL_VERIFYHOST may also need to be TRUE or FALSE if CURLOPT_SSL_VERIFYPEER is disabled (it defaults to 2). TRUE by default as of cURL 7.10. Default bundle installed as of cURL 7.10.
CURLOPT_TRANSFERTEXTTRUE to use ASCII mode for FTP transfers. For LDAP, it retrieves data in plain text instead of HTML. On Windows systems, it will not set STDOUT to binary mode.
CURLOPT_UNRESTRICTED_AUTH在使用CURLOPT_FOLLOWLOCATION产生的header中的多个locations中持续追加用户名和密码信息,即使域名已发生改变。
CURLOPT_UPLOAD启用时允许文件传输
CURLOPT_VERBOSE启用时会汇报所有的信息,存放在STDERR或指定的CURLOPT_STDERR中
CURLOPT_BUFFERSIZE每次获取的数据中读入缓存的大小,这个值每次都会被填满。
CURLOPT_CLOSEPOLICY不是CURLCLOSEPOLICY_LEAST_RECENTLY_USED就是CURLCLOSEPOLICY_OLDEST,还存在另外三个,但是curl暂时还不支持。.
CURLOPT_CONNECTTIMEOUT在发起连接前等待的时间,如果设置为0,则不等待。
CURLOPT_DNS_CACHE_TIMEOUT设置在内存中保存DNS信息的时间,默认为120秒。
CURLOPT_FTPSSLAUTHThe FTP authentication method (when is activated): CURLFTPAUTH_SSL (try SSL first), CURLFTPAUTH_TLS (try TLS first), or CURLFTPAUTH_DEFAULT (let cURL decide).
CURLOPT_HTTP_VERSION设置curl使用的HTTP协议,CURL_HTTP_VERSION_NONE(让curl自己判断),CURL_HTTP_VERSION_1_0(HTTP/1.0),CURL_HTTP_VERSION_1_1(HTTP/1.1)
CURLOPT_HTTPAUTH使用的HTTP验证方法,可选的值 有:CURLAUTH_BASIC,CURLAUTH_DIGEST,CURLAUTH_GSSNEGOTIATE,CURLAUTH_NTLM,CURLAUTH_ANY,CURLAUTH_ANYSAFE, 可以使用“|”操作符分隔多个值,curl让服务器选择一个支持最好的值,CURLAUTH_ANY等价于CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM,CURLAUTH_ANYSAFE等价于CURLAUTH_DIGEST | CURLAUTH_GSSNEGOTIATE | CURLAUTH_NTLM
CURLOPT_INFILESIZE设定上传文件的大小
CURLOPT_LOW_SPEED_LIMIT当传输速度小于CURLOPT_LOW_SPEED_LIMIT时,PHP会根据CURLOPT_LOW_SPEED_TIME来判断是否因太慢而取消传输。
CURLOPT_LOW_SPEED_TIMEThe number of seconds the transfer should be below CURLOPT_LOW_SPEED_LIMIT for PHP to consider the transfer too slow and abort.当传输速度小于CURLOPT_LOW_SPEED_LIMIT时,PHP会根据CURLOPT_LOW_SPEED_TIME来判断是否因太慢而取消传输。
CURLOPT_MAXCONNECTS允许的最大连接数量,超过是会通过CURLOPT_CLOSEPOLICY决定应该停止哪些连接
CURLOPT_MAXREDIRS指定最多的HTTP重定向的数量,这个选项是和CURLOPT_FOLLOWLOCATION一起使用的。
CURLOPT_PORT一个可选的用来指定连接端口的量
CURLOPT_PROXYAUTHThe HTTP authentication method(s) to use for the proxy connection. Use the same bitmasks as described in CURLOPT_HTTPAUTH. For proxy authentication, only CURLAUTH_BASIC and CURLAUTH_NTLM are currently supported.
CURLOPT_PROXYPORTThe port number of the proxy to connect to. This port number can also be set in CURLOPT_PROXY.
CURLOPT_PROXYTYPEEither CURLPROXY_HTTP (default) or CURLPROXY_SOCKS5.
CURLOPT_RESUME_FROM在恢复传输时传递一个字节偏移量(用来断点续传)
CURLOPT_SSL_VERIFYHOST1 to check the existence of a common name in the SSL peer certificate.2 to check the existence of a common name and also verify that it matches the hostname provided.
CURLOPT_SSLVERSIONThe SSL version (2 or 3) to use. By default PHP will try to determine this itself, although in some cases this must be set manually.
CURLOPT_TIMECONDITION如果在CURLOPT_TIMEVALUE指定的某个时间以后被编辑过,则使用CURL_TIMECOND_IFMODSINCE返回页面,如果没有被修 改过,并且CURLOPT_HEADER为true,则返回一个”304 Not Modified”的header,CURLOPT_HEADER为false,则使用CURL_TIMECOND_ISUNMODSINCE,默认值为 CURL_TIMECOND_IFMODSINCE
CURLOPT_TIMEOUT设置curl允许执行的最长秒数
CURLOPT_TIMEVALUE设置一个CURLOPT_TIMECONDITION使用的时间戳,在默认状态下使用的是CURL_TIMECOND_IFMODSINCE
CURLOPT_CAINFOThe name of a file holding one or more certificates to verify the peer with. This only makes sense when used in combination with CURLOPT_SSL_VERIFYPEER.
CURLOPT_CAPATHA directory that holds multiple CA certificates. Use this option alongside CURLOPT_SSL_VERIFYPEER.
CURLOPT_COOKIE设定HTTP请求中“Set-Cookie:”部分的内容。
CURLOPT_COOKIEFILE包含cookie信息的文件名称,这个cookie文件可以是Netscape格式或者HTTP风格的header信息。
CURLOPT_COOKIEJAR连接关闭以后,存放cookie信息的文件名称
CURLOPT_CUSTOMREQUESTA custom request method to use instead of “GET” or “HEAD” when doing a HTTP request. This is useful for doing “DELETE” or other, more obscure HTTP requests. Valid values are things like “GET”, “POST”, “CONNECT” and so on; i.e. Do not enter a whole HTTP request line here. For instance, entering “GET /index.html HTTP/1.0\r\n\r\n” would be incorrect.Note: Don’t do this without making sure the server supports the custom request method first.
CURLOPT_EGBSOCKETLike CURLOPT_RANDOM_FILE, except a filename to an Entropy Gathering Daemon socket.
CURLOPT_ENCODINGheader中“Accept-Encoding: ”部分的内容,支持的编码格式为:”identity”,”deflate”,”gzip”。如果设置为空字符串,则表示支持所有的编码格式
CURLOPT_FTPPORTThe value which will be used to get the IP address to use for the FTP “POST” instruction. The “POST” instruction tells the remote server to connect to our specified IP address. The string may be a plain IP address, a hostname, a network interface name (under Unix), or just a plain ‘-’ to use the systems default IP address.
CURLOPT_INTERFACE在外部网络接口中使用的名称,可以是一个接口名,IP或者主机名。
CURLOPT_KRB4LEVELKRB4(Kerberos 4)安全级别的设置,可以是一下几个值之一:”clear”,”safe”,”confidential”,”private”。默认的值 为”private”,设置为null的时候表示禁用KRB4,现在KRB4安全仅能在FTP传输中使用。
CURLOPT_POSTFIELDS在HTTP中的“POST”操作。如果要传送一个文件,需要一个@开头的文件名
CURLOPT_PROXY设置通过的HTTP代理服务器
CURLOPT_PROXYUSERPWD连接到代理服务器的,格式为“[username]:[password]”的用户名和密码。
CURLOPT_RANDOM_FILE设定存放SSL用到的随机数种子的文件名称
CURLOPT_RANGE设置HTTP传输范围,可以用“X-Y”的形式设置一个传输区间,如果有多个HTTP传输,则使用逗号分隔多个值,形如:”X-Y,N-M”。
CURLOPT_REFERER设置header中”Referer: ” 部分的值。
CURLOPT_SSL_CIPHER_LISTA list of ciphers to use for SSL. For example, RC4-SHA and TLSv1 are valid cipher lists.
CURLOPT_SSLCERT传递一个包含PEM格式证书的字符串。
CURLOPT_SSLCERTPASSWD传递一个包含使用CURLOPT_SSLCERT证书必需的密码。
CURLOPT_SSLCERTTYPEThe format of the certificate. Supported formats are “PEM” (default), “DER”, and “ENG”.
CURLOPT_SSLENGINEThe identifier for the crypto engine of the private SSL key specified in CURLOPT_SSLKEY.
CURLOPT_SSLENGINE_DEFAULTThe identifier for the crypto engine used for asymmetric crypto operations.
CURLOPT_SSLKEYThe name of a file containing a private SSL key.
CURLOPT_SSLKEYPASSWDThe secret password needed to use the private SSL key specified in CURLOPT_SSLKEY.Note: Since this option contains a sensitive password, remember to keep the PHP script it is contained within safe.
CURLOPT_SSLKEYTYPEThe key type of the private SSL key specified in CURLOPT_SSLKEY. Supported key types are “PEM” (default), “DER”, and “ENG”.
CURLOPT_URL需要获取的URL地址,也可以在PHP的curl_init()函数中设置。
CURLOPT_USERAGENT在HTTP请求中包含一个”user-agent”头的字符串。
CURLOPT_USERPWD传递一个连接中需要的用户名和密码,格式为:“[username]:[password]”。
CURLOPT_HTTP200ALIASES设置不再以error的形式来处理HTTP 200的响应,格式为一个数组。
CURLOPT_HTTPHEADER设置一个header中传输内容的数组。
CURLOPT_POSTQUOTEAn array of FTP commands to execute on the server after the FTP request has been performed.
CURLOPT_QUOTEAn array of FTP commands to execute on the server prior to the FTP request.
CURLOPT_FILE设置输出文件的位置,值是一个资源类型,默认为STDOUT (浏览器)。
CURLOPT_INFILE在上传文件的时候需要读取的文件地址,值是一个资源类型。
CURLOPT_STDERR设置一个错误输出地址,值是一个资源类型,取代默认的STDERR。
CURLOPT_WRITEHEADER设置header部分内容的写入的文件地址,值是一个资源类型。
CURLOPT_HEADERFUNCTION设置一个回调函数,这个函数有两个参数,第一个是curl的资源句柄,第二个是输出的header数据。header数据的输出必须依赖这个函数,返回已写入的数据大小。
CURLOPT_PASSWDFUNCTION设置一个回调函数,有三个参数,第一个是curl的资源句柄,第二个是一个密码提示符,第三个参数是密码长度允许的最大值。返回密码的值。
CURLOPT_READFUNCTION设置一个回调函数,有两个参数,第一个是curl的资源句柄,第二个是读取到的数据。数据读取必须依赖这个函数。返回读取数据的大小,比如0或者EOF。
CURLOPT_WRITEFUNCTION设置一个回调函数,有两个参数,第一个是curl的资源句柄,第二个是写入的数据。数据写入必须依赖这个函数。返回精确的已写入数据的大小
curl_copy_handle()函数的作用是拷贝一个curl连接资源的所有内容和参数

$ch = curl_init(“http://www.baidu.com/“);$another = curl_copy_handle($ch);curl_exec($another);curl_close($another);?>curl_error()函数的作用是返回一个包含当前会话错误信息的字符串。curl_errno()函数的作用是返回一个包含当前会话错误信息的数字编号。
curl_multi_init()函数的作用是初始化一个curl批处理句柄资源。curl_multi_add_handle()函数的作用是向curl批处理会话中添加单独的curl句柄资源。curl_multi_add_handle()函数有两个参数,第一个参数表示一个curl批处理句柄资源,第二个参数表示一个单独的curl句柄资源。curl_multi_exec()函数的作用是解析一个curl批处理句柄,curl_multi_exec()函数有两个参数,第一个参数表示一个批处理句柄资源,第二个参数是一个引用值的参数,表示剩余需要处理的单个的curl句柄资源数量。curl_multi_remove_handle()函数表示移除curl批处理句柄资源中的某个句柄资源,curl_multi_remove_handle()函数有两个参数,第一个参数表示一个curl批处理句柄资源,第二个参数表示一个单独的curl句柄资源。curl_multi_close()函数的作用是关闭一个批处理句柄资源。

$ch1 = curl_init();$ch2 = curl_init();curl_setopt($ch1, CURLOPT_URL, “http://www.baidu.com/“);curl_setopt($ch1, CURLOPT_HEADER, 0);curl_setopt($ch2, CURLOPT_URL, “http://www.google.com/“);curl_setopt($ch2, CURLOPT_HEADER, 0);$mh = curl_multi_init();curl_multi_add_handle($mh,$ch1);curl_multi_add_handle($mh,$ch2);do {curl_multi_exec($mh,$flag);} while ($flag > 0);curl_multi_remove_handle($mh,$ch1);curl_multi_remove_handle($mh,$ch2);curl_multi_close($mh);?>curl_multi_getcontent()函数的作用是在设置了CURLOPT_RETURNTRANSFER的情况下,返回获取的输出的文本流。
curl_multi_info_read()函数的作用是获取当前解析的curl的相关传输信息。
curl_multi_select()Get all the sockets associated with the cURL extension, which can then be “selected”

ActionScript3使用Socket查看邮件介绍pop3命令和相关内容

// March 18th, 2010 // 2 Comments » // AS3知识积累, Flex积累

什么是 POP3
POP3 (Post Office Protocol  3) 即邮局协议的第 3 个版本,它规定怎样将个人计算机连接到 Internet 的邮件服务器和下载电子邮件的电子协议。它是因特网电子邮件的第一个离线协议标准,  POP3 允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循 POP3  协议的接收邮件服务器,用来接收电子邮件的。
POP3 命令
POP3 命令包括:
USER username  认证用户名
PASS password 认证密码认证,认证通过则状态转换
APOP name,digest  认可一种安全传输口令的办法,执行成功导致状态转换,请参见 RFC 1321 。
STAT 处理请求 server  回送邮箱统计资料,如邮件数、邮件总字节数
UIDL n 处理 server 返回用于该指定邮件的唯一标识,如果没有指定,返回所有的。
LIST n  处理 server 返回指定邮件的大小等
RETR n 处理 server 返回邮件的全部文本
DELE n 处理 server 标记删除,QUIT  命令执行时才真正删除
RSET 处理撤消所有的 DELE 命令
TOP n,m 处理 返回 n 号邮件的前 m 行内容,m 必须是自然数
NOOP 处理 server 返回一个肯定的响应
QUIT  希望结束会话。如果 server 处于”处理” 状态,则现在进入”更新”状态,删除那些标记成删除的邮件。如果 server 处于”认可”状态,则结束会话时  server 不进入”更新”状态 。
使用 telnet 连接 Winmail Server  收信
例如:安装Winmail  的邮件服务器 IP 是 192.168.0.1(蓝色字体内容由客户端输入,红色字体内容是服务返回的)
telnet 119.119.119.212 110—————————– 使用 telnet 命令连接服务器 110 端口
Trying 119.119.119.212…——————————  正在连接服务器 110 端口
Connected to 119.119.119.212.————————– 连接服务器 110 端口成功
+OK Winmail  Mail Server POP3 ready
user username—————————————— 输入用户名, username 为具体的用户名
+OK—————————————————-  执行命令成功
pass password—————————————— 输入用户密码,password 为具体的密码
+OK 2 messages—————————————–  密码认证通过
(-ERR authorization failed—————————– 密码认证失败)
stat————————————————— 邮箱状态
+OK 2 6415——————————————— 2  为该信箱总邮件数,6415 为总字节数
list————————————————— 列出每封邮件的字节数
+OK—————————————————-  执行命令成功,开始显示,左边为邮件的序号,右边为该邮件的大小
1 537————————————————– 第 1 封邮件,大小为 537 字节
2 5878————————————————- 第  2 封邮件,大小为 5878 字节
.
top  1————————————————– 接收第 1 封邮件
+OK—————————————————-  接收成功, 返回第 1 封邮件头
Return-Path:  <test1@look.com>
Delivered-To: test2@look.com
Received: (winmail  server invoked for smtp delivery); Mon, 25 Oct 2004 14:24:27 +0800
From:  test1@look.com
To: test2@look.com
Date: Mon, 25 Oct 2004 14:24:27  +0800
Subject: test mail
.
retr 1————————————————-  接收第 1 封邮件
+OK—————————————————- 接收成功, 返回第 1 封邮件全部内容
Return-Path:  <test1@look.com>
Delivered-To: test2@look.com
Received: (winmail  server invoked for smtp delivery); Mon, 25 Oct 2004 14:24:27 +0800
From:  test1@look.com
To: test2@look.com
Date: Mon, 25 Oct 2004 14:24:27  +0800
Subject: test mail
Hi, test2
This is a test mail, you don’t  reply it.
.
dele 1————————————————- 删除第 1 封邮件
+OK—————————————————-  删除成功
dele 2————————————————- 删除第 2 封邮件
+OK—————————————————-  删除成功
quit————————————————— 结束会话
+OK—————————————————-  执行命令成功

ActionScript3使用Socket查看邮件介绍pop3命令和相关内容
什么是 POP3POP3 (Post Office Protocol  3) 即邮局协议的第 3 个版本,它规定怎样将个人计算机连接到 Internet 的邮件服务器和下载电子邮件的电子协议。它是因特网电子邮件的第一个离线协议标准,  POP3 允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时删除保存在邮件服务器上的邮件,而POP3服务器则是遵循 POP3  协议的接收邮件服务器,用来接收电子邮件的。
POP3 命令POP3 命令包括:USER username  认证用户名PASS password 认证密码认证,认证通过则状态转换APOP name,digest  认可一种安全传输口令的办法,执行成功导致状态转换,请参见 RFC 1321 。STAT 处理请求 server  回送邮箱统计资料,如邮件数、邮件总字节数UIDL n 处理 server 返回用于该指定邮件的唯一标识,如果没有指定,返回所有的。LIST n  处理 server 返回指定邮件的大小等RETR n 处理 server 返回邮件的全部文本DELE n 处理 server 标记删除,QUIT  命令执行时才真正删除RSET 处理撤消所有的 DELE 命令TOP n,m 处理 返回 n 号邮件的前 m 行内容,m 必须是自然数NOOP 处理 server 返回一个肯定的响应QUIT  希望结束会话。如果 server 处于”处理” 状态,则现在进入”更新”状态,删除那些标记成删除的邮件。如果 server 处于”认可”状态,则结束会话时  server 不进入”更新”状态 。
使用 telnet 连接 Winmail Server  收信例如:安装Winmail  的邮件服务器 IP 是 192.168.0.1(蓝色字体内容由客户端输入,红色字体内容是服务返回的)
telnet 119.119.119.212 110—————————– 使用 telnet 命令连接服务器 110 端口Trying 119.119.119.212…——————————  正在连接服务器 110 端口Connected to 119.119.119.212.————————– 连接服务器 110 端口成功+OK Winmail  Mail Server POP3 readyuser username—————————————— 输入用户名, username 为具体的用户名+OK—————————————————-  执行命令成功pass password—————————————— 输入用户密码,password 为具体的密码+OK 2 messages—————————————–  密码认证通过(-ERR authorization failed—————————– 密码认证失败)stat————————————————— 邮箱状态+OK 2 6415——————————————— 2  为该信箱总邮件数,6415 为总字节数list————————————————— 列出每封邮件的字节数+OK—————————————————-  执行命令成功,开始显示,左边为邮件的序号,右边为该邮件的大小1 537————————————————– 第 1 封邮件,大小为 537 字节2 5878————————————————- 第  2 封邮件,大小为 5878 字节.top  1————————————————– 接收第 1 封邮件+OK—————————————————-  接收成功, 返回第 1 封邮件头Return-Path:  <test1@look.com>Delivered-To: test2@look.comReceived: (winmail  server invoked for smtp delivery); Mon, 25 Oct 2004 14:24:27 +0800From:  test1@look.comTo: test2@look.comDate: Mon, 25 Oct 2004 14:24:27  +0800Subject: test mail.retr 1————————————————-  接收第 1 封邮件+OK—————————————————- 接收成功, 返回第 1 封邮件全部内容Return-Path:  <test1@look.com>Delivered-To: test2@look.comReceived: (winmail  server invoked for smtp delivery); Mon, 25 Oct 2004 14:24:27 +0800From:  test1@look.comTo: test2@look.comDate: Mon, 25 Oct 2004 14:24:27  +0800Subject: test mail
Hi, test2This is a test mail, you don’t  reply it.
.dele 1————————————————- 删除第 1 封邮件+OK—————————————————-  删除成功dele 2————————————————- 删除第 2 封邮件+OK—————————————————-  删除成功quit————————————————— 结束会话+OK—————————————————-  执行命令成功

Windows Product Key Update Tool

// February 17th, 2010 // No Comments » // 说明集锦

http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.windowsupdate&tid=93ca4aae-4cac-4719-9d8b-1ad7a26af402&p=1

可以更新windows 序列号的更新工具!

用替换VistaOEM授权文件的方法激活破解Windows Server 2008 Datacenter

// February 15th, 2010 // No Comments » // hack一下

1 在您的计算机中安装好 Windows Server 2008,点 开始 -> 运行,输入Services.msc(或者 开始 ->
程序 -> 管理工具 – > 服务)。在服务中找到 “Software Licensing”设置启动类型为”已禁用”,禁用该服务。

2 重新您的计算机,之后,打开 C:\Windows\ServiceProfiles\NetworkService\AppData\Roaming\Microsoft\SoftwareLicensing 目录,删除名为 tokens.dot 的文件,用破解压缩包中的同名文件替换。再次打开服务,将 Software Licensing 设置为 “自动”。

3 运行破解压缩包中 vistaactivation.exe 程序

点击continue,选择Vista Ultimate

再单击continue,中途会弹出一些错误提示,不要理他,结束后单击finish,
系统会自动重新启动。
注意:在单击finish重启之前请先把第四步中的序列号写到纸上,不然你重启后
就不能进入系统了,呵呵。

4重启之后,Windows Server 2008 会要求您输入一个CD-KEY,填入下面
这个序列号:6F2D7-2PCG6-YQQTB-FWK9V-932CC ,等待几分钟让系统激活!
这样,您就拥有了一个激活的Windows Server 2008!o(∩_∩)o…而且可以通过

文件名: crack.rar

AS3及Flex的百条常用知识(二)

// February 11th, 2010 // No Comments » // AS3知识积累, Flex积累

【自动大小调整和对齐】
TextField.autoSize = TextFieldAutoSize.LEFT;
可选之值:
flash.text.TextFieldAutoSize.CENTER
flash.text.TextFieldAutoSize.LEFT
flash.text.TextFieldAutoSize.NONE
flash.text.TextFieldAutoSize.RIGHT

【指示文本字段是否自动换行】
TextField.wordWrap = true; //自动换行

【用程序手段滚动文字】
水平方向以像素为单位,而垂直方向以行做单位:
scrollV: 指出文字框可见区域的最顶行,可读写;
bottomScrollV: 指出文字框内最底端可见行,只读;
maxScrollV: scrollV的最大值,只读;
numLines: 定义多行文本字段中的文本行数,只读;
TextField.scrollV = field.maxScrollV; //滚动到最后一页

【响应滚动事件】
field.addEventListener(Event.SCROLL, onTextScroll);

【样式化文字的方法】
1. 使用HTML标签进行样式化;
2. 使用TextFormat对象;
3. 使用CSS.
例如: HTML是用<font>标签,TextFormat对象是设定font属性,而CSS是使用font-family属性的.
受支持的层叠样式表(CSS)属性和值,及其相应的ActionScript属性名称(小括号内):
color(color),display(display),font-family(fontFamily),font-size(fontSize),font-style(fontStyle),font-weight(fontWeight),kerning(kerning),leading(leading),letter-spacing(letterSpacing),margin-left(marginLeft),margin-right(marginRight),text-align(textAlign),text-decoration(textDecoration),text-indent(textIndent)
受支持的HTML实体: <(小于号: <), >(大于号: >), &(和: &), “(双引号: “), ‘(撇号,单引号: ‘)
其中样式对象的两种写法:
写法一:
var sampleStyle.:Object = new Object();
sampleStyle.color = “#FFFFFF”;
sampleStyle.textAlign = “center”;
css.setStyle(“.sample”, sampleStyle);
写法二:
var sampleStyle.:Object = {color: “#FFFFFF”, textAlign: “center”};
css.setStyle(“.sample”, sampleStyle);

【对用户输入的文字进行样式化】
使用defaultTextFormat属性,样式会施加至用户键入输入框的文字身上:
var formatter:TextFormat = new TextFormat();
formatter.color = 0x0000FF; //把文字变成蓝色
field.defaultTextFormat = formatter;

【对现有文字的一部分进行样式化】
TextFormat.setTextFormat(format:TextFormat, beginIndex:int = -1, endIndex:int = -1):void

【设定文字框的字体】
例子:
HTML: field.htmlText = “<font face=’Arial’>Formatted text</font>”;
TextFormat: formatter.font = “Arial”;
CSS: P{ font-family: Arial; }
也可以使用以逗号隔开的字体清单: formatter.font = “Arial, Verdana, Helvetica”;
注意:
字体和字体群组不同.字体群组有三种: _sans,_serif以及_typewriter.
_sans群组一般就是指Arial或Helvetica这种字体;
_serif群组一般就是指Times或Times New Roman这种字体;
_typewriter群组一般就是指Courier或Courier New这种字体.

【嵌入字体】
使用[Embed]后设标签.[Embed]后设标签应该出现在ActionScript文件中,处于类宣告之外.你可以内嵌TrueType字体或系统字体.内嵌TrueType字体时的语法:
[Embed(source="pathToTtfFile", fontName="FontName", mimeType="application/x-font-truetype")]
pathToTtfFile: ttf文件的路径,TrueType字体的路径可以是相对的,也可以是绝对的;
FontName: 字体名称;
内嵌系统字体的语法:
[Embed(systemFont="Times New Roman", fontName="Times New Roman", mimeType="application/x-font-truetype")]
fontName: 以相同名称作为实际系统字体名称.
注意: 在使用嵌入字体时,要把TextField的embedFonts属性设为true,这样TextField只能用内嵌字体了.如果你试着替 embedFonts设为true的TextField使用设备字体,什么都不会显示.如果embedFonts设为true,就无法指定以逗号相隔的字体清单.

【建立可以旋转的文字】
使用内嵌字体.当你旋转文字框时,设备字体就会消失.

【显示Unicode文字】
1. 从外部来源载入Unicode文字;
2. 假如你的编辑器支持Unicode(如 Flex Builder),则可以直接在ActionScript程序中使用该字符;
3. 使用Unicode转义字符,ActionScript里所有Unicode转义字符都以\u开头,后面再跟四位十六进制数字.
注意: 如果你想取得Unicode字符,在Windows下使用: 开始>所有程序>附件>系统工具>字符映射表.

【把Flash Player的焦点带给文字框】
stage.focus = field;
把焦点移除:
stage.focus = null;
注意: 当.swf文件首次载入至网页浏览器时,并没有焦点.因此,以程序的方式把焦点指定给Flash应用程序的一个元素前,必须先把焦点移至Flash Player.

【以ActionScript选取文字】
使用TextField.setSelection(beginIndex:int, endIndex:int):void
为了可以正常选取文字,文字框必须具有焦点:
stage.focus = field; //把焦点设给文字框
field.text = “This is example text”; //设定文字
field.setSelection(0, 4); //把”This”这个单词以高亮显示
使用只读的selectionBeginIndex和selectionEndIndex属性访问所选取的字符范围的索引.

【在文字内设定安插点(游标位置)并访问游标位置的索引值】
可以使用TextField.setSelection()把起始和结尾的索引参数都设成相同值,在文字内设定游标位置(假设具有焦点):
field.setSelection(0, 0); //在第一个字符前摆放安插点
trace(field.caretIndex); //输出游标位置的索引值

【当文本字段受到选取或取消选取时给予响应】
获得焦点时: FocusEvent.FOCUS_IN
失去焦点时: FocusEvent.FOCUS_OUT
通过键盘(Tab键)把焦点移除时: FocusEvent.KEY_FOCUS_CHANGE
通过鼠标把焦点移除时: FocusEvent.MOUSE_FOCUS_CHANGE
FocusEvent 类有一个relatedObject属性.就FOCUS_IN事件而言,relatedObject属性是刚才拥有焦点的对象的引用地址;对于 FOCUS_OUT,KEY_FOCUS_CHANGE以及MOUSE_FOCUS_CHANGE事件,relatedObject属性是刚接收到焦点的对象的引用地址.
FOCUS_IN和FOCUS_OUT事件都是在焦点改变后发生的,所以两者都是不可取消的事件.对于KEY_FOCUS_CHANGE和MOUSE_FOCUS_CHANGE事件,可以使用FocusEvent.preventDefault()方法取消默认行为:
field.addEventListener(FocusEvent.KEY_FOCUS_CHANGE, onKeyFocus);
private function onKeyFocus(event:FocusEvent):void {
if(field.text == “”) {
event.preventDefault(); //当field没有任何文字前,不允许使用Tab键把焦点移除
}
//event.relatedObject就是刚才拥有焦点的对象的引用地址,即下一个获得焦点的对象的引用地址
}

AS3及Flex的百条常用知识

// February 11th, 2010 // 1 Comment » // AS3知识积累, Flex积累

【改变输出swf的尺度,背景颜色或帧频】
在”Navigator”窗框里右键你的项目>选中”Properties”>选中”ActionScript. Compiler”>在”Additional compiler arguments”里输入你所需要的命令
如想改变背景颜色,请输入: -default-background-color 0xffffff

【鼠标坐标】
mouseX mouseY

【检查变量类型并返回布尔值】
is

【检查变量类型并返回类型】
typeof

【检查对象类型并返回该对象】
as

【是数字但不是有效数字问题】
var quantity:Number = 15 – “rabbits”;
trace(typeof quantity); //显示: “number” , 但它是NaN (not a number)
trace(quantity is Number); //true
trace(quantity != NaN); //false
//使用isNaN()函数检测:
isNaN(quantity); //true
//检测变量是否内含有效数字:
!isNaN(quantity); //false

【取消默认的严格编译模式】
在”Navigator”窗框里右键你的项目>选中”Properties”>选中”ActionScript. Compiler”>取消”Enabel compile-time type checking”选项

【基元数据类型和复杂数据类型好比”值类型”和”引用类型”】
基元数据类型类似按值传递:
var intOne:int = 1;
var intTwo:int = 1;
trace(intOne == intTwo); //true

【复杂数据类型类似按引用传递】
var arrayOne:Array = new Array(“a”, “b”);
var arrayTwo:Array = arrayOne;
trace(arrayOne == arrayTwo); //true
//———————————–
var arrayOne:Array = new Array(“a”, “b”);
var arrayTwo:Array = new Array(“a”, “b”);
trace(arrayOne == arrayTwo); //false

【优化逻辑AND(&&)和OR(||)的小知识】
对于逻辑And(&&):
除非条件表达式的前半部分为真,否则,ActionScript不会再去求算逻辑AND运算符的后半部.如果前半部为假,整个条件表达式一定为假,所以再去求算后半部就没效率了.
对于逻辑OR(||):
除非条件表达式前半部为假,否则,ActionScript不会再去求算逻辑OR运算符的后半部,如果前半部为真,整个条件表达式一定为真.
总结:使用逻辑AND(&&)时,把结果最可能为false的表达式放到前面;使用逻辑OR(||)时,把结果最可能为true的表达式放到前面.

【Timer类注意事项】
不要认为Timer可以极其准确;使用Timer时间间隔不要低于10毫秒.

【private,protected,internal,public访问权限】
private:只能在类本身内部访问,按惯例,命名私有成员时以下划线”_”开头;
protected:可以由类本身或任何子类访问.但这是以实例为基础的.换言之,类实例可以访问自己的保护成员或者父类的保护成员,但不能访问相同类的其它实例的保护成员,按惯例,命名保护成员时以下划线”_”开头;
internal:可以由类本身或者相同包内的任何类访问;
public:可以在类内部访问,也可以由类实例访问,或者声明为static时,可以直接从类访问.

【一个函数具有未知个数的参数,用arguments对象或”…(rest)”符号访问它的参数】
注意:使用”…(rest)”参数会使 arguments 对象不可用;
private funciton average():void{
trace(arguments.length); //输出参数的个数
// arguments的类型是:object,但可以像访问数组一样去访问它
trace(arguments[1]); //输出第二个参数
}
private function average(…argu):void{
trace(argu[1]); //输出第二个参数,argu参数名是自定义的.
}

【错误处理try,catch,finally】
private function tryError():void{
try {
trace(“测试开始-try”);
throwError();
}catch(errObject:Error) {
trace(“错误信息:” + errObject.message);
trace(“测试结束-catch”);
return;
}finally{
trace(“虽然catch里已经有return方法,但位于return方法后面的finally里的代码依然会被执行.其实无论return方法是在try里,还是catch里,finally里的代码始终会被执行”);
}
trace(“前面已经有return了,此处是不会再执行的.除非没有抛出错误,以使catch里的代码没有被执行”);
}
private function throwError():void{
throw new Error(“抛出错误”);
}

【for…in与for each…in的区别】
与for…in循环不同的是,for each…in循环中的迭代变量包含属性所保存的值,而不包含属性的名称(或主键,索引).

【命名包路径的小技巧】
使用相应于拥有者和相关项目的包名称会比较好.按惯例来讲,包名称的开头应该是逆向的网址名称.例如,如果Example Corp(examplecorp.com)写了一些ActionScript3.0类,就会把所有类放在com.examplecorp包内(或者 com.examplecorp的子包内).如此一来,如果英国有另一家Example Corp(examplecorp.co.uk)也写了一些ActionScript3.0类,只要使用包uk.co.examplecorp,就可确保唯一性.
当类属于特定应用程序的一部分时,就应该放在该应用程序特定的子包内.例如,Example Corp可能有个应用程序名叫WidgetStore.如果WidgetStore应用程序使用一个名为ApplicationManager的类,则此类就应该放在com.examplecorp.widgetstore包内,或者位于该包的子包内.
按惯例来说,包名称的开头是小写字母.

【隐式的取出方法(getter)和设定方法(setter)】
public function get count():uint {
return _count;
}
public function set count(value:uint):uint {
if(value < 100){
_count = value;
}else {
throw Error();
}
}

【确保类是绝不会有子类,使用final】
final public class Example{}

【super关键字的使用】
super(); //父类的构造函数,只能在类实例构造函数内部使用
super.propertyName; //调用父类的属性,属性需要声明为public或protected
super.methodName(); //调用父类的方法,方法需要声明为public或protected

【建立常数,使用关键字const而不是var】
static public const EXAMPLE:String = “example”;

【检测播放器版本】
flash.system.Capabilities.version
对于8.5版以前的任何Flash Player版本,这种方法都不适用.

【判断客户端系统】
flash.system.Capabilities.os

【检测播放器类型】
flash.system.Capabilities.playerType
可能的值有:
“StandAlone”,用于独立的 Flash Player
“External”,用于外部的 Flash Player 或处于测试模式下
“PlugIn”,用于 Flash Player 浏览器插件
“ActiveX”,用于 Microsoft Internet Explorer 使用的 Flash Player ActiveX 控件

【检测系统语言】
flash.system.Capabilities.language

【判断用户是否启用了IME(输入法编辑器)】
flash.system.IME.enabled

【检测屏幕的分辨率】
flash.system.Capabilities.screenResolutionX
flash.system.Capabilities.screenResolutionY

【把弹出窗口居中的算法】
X = (舞台宽/2)-(窗口宽/2)
Y = (舞台高/2)-(窗口高/2)

【控制影片配合Player的方式,包括缩放问题】
stage.scaleMode
可供选择值:flash.display.StageScaleMode

【舞台的对齐方式】
stage.align
可供选择值:flash.display.StageAlign

【隐藏Flash Player的右键菜单】
stage.showDefaultContextMenu = false;

【检测系统是否具有音频功能】
flash.system.Capabilities.hasAudio

【检测播放器是在具有MP3解码器的系统上运行,还是在没有MP3解码器的系统上运行】
flash.system.Capabilities.hasMP3

【检测播放器能 (true) 还是不能 (false) 播放流式视频】
flash.system.Capabilities.hasStreamingVideo

【检测播放器是在支持 (true) 嵌入视频的系统上运行,还是在不支持 (false) 嵌入视频的系统上运行】
flash.system.Capabilities.hasEmbeddedVideo

【检测播放器能 (true) 还是不能 (false) 对视频流(如来自 Web 摄像头的视频流)进行编码】
flash.system.Capabilities.hasVideoEncoder

【显示 Flash Player 中的”安全设置”面板】
flash.system.Security.showSettings();
可供选择项:flash.system.SecurityPanel

【让其它域的.swf访问本域的.swf】
在本域的.swf文件里加上:flash.system.Security.allowDomain()
或者使用安全策略文件”crossdomain.xml”.在Flash 8以前,这个文件必须放在.swf所在域的根目录,现在,你可以使用flash.system.Security.loadPolicyFile(),指定安全策略文件所在的位置.拒绝任何域的做法是在<cross-domain-policy>标签内什么也不填,安全策略文件也支持通用字符 “*”:
<?xml version=”1.0″?>
<!– http://www.mydomain.com/crossdomain.xml –>
<cross-domain-policy>
<allow-access-from domain=”www.riahome.cn ” />
<allow-access-from domain=”*.Y-boy.cn” />
<allow-access-from domain=”210.38.196.48″ />
<allow-access-from domain=”*” />
</cross-domain-policy>

【数字的不同进制之间的转换】
parseInt(str:String, radix:uint = 0):Number 返回十进制的数,参数radix表示要分析的数字的基数.如果省略radix,就默认为10,除非字符串的开头是”0x”,”0X”或”0″:
trace(parseInt(“0×12″)); //设定radix为16,输出:18
trace(parseInt(“017″)); //设定radix为8,输出:15
或者使用Number,uint和int对象的toString(radix)方法.

【使用Math.round()对一个数取整,四舍五入】
Math.round()
trace(Math.round(204.499)); //输出:204
trace(Math.round(401.5)); //输出:402

【使用Math.floor()对一个数向下取整,就是只要整数部分而不理会小数分】
trace(Math.floor(204.99)); //输出:204

【使用Math.ceil()对一个数向上取整,只要小数部分不为零,整数部分就加1】
trace(Math.ceil(401.01)); //输出:402

【产生一个随机数】
使用Math.random()产生一个伪随机数n,其中 0 <= n < 1

【把数字取至最近的小数点位,即指定精确度】
1. 决定你要取的数字的小数点位数:例如,如果你想把90.337取成90.34,就表示你要取到两位小数点位,也就是说你想取至最近的0.01;
2. 让输入值除以步骤1所选的数字(此例为0.01);
3. 使用Math.round()把步骤2所计得的值取成最近的整数;
4. 把步骤3所得的结果乘以步骤2用于除法的那个值.
例如,要把90.337取成两个小数点位数,可以使用:
trace(Math.round(90.337/0.01)*0.01); //输出:90.34

【把数字取成一个整数的最接近倍数值】
例1,这样会把92.5取成5的最近倍数值:
trace(Math.round(92.5/5)*5); //输出:95
例2,这样会把92.5取成10的最近倍数值:
trace(Math.round(92.5/10)*10); //输出:90

【在指定数值范围内获得随机数】
//可取范围:[min, max]
private function randRange(min:Number, max:Number):Number {
var randomNum:Number = Math.floor(Math.random() * (max – min + 1)) + min;
return randomNum;
}
应用例子:
模拟投银币,即希望得到随机布尔值(true 或 false): randRange(0, 1);
模拟投骰子,即希望得到随机六个值: randRange(1, 6);
为避免被缓存而需要产生一个独一无二的数字追加在URL尾端,通常最佳方法是取得当前毫秒数.

【弧度(radian)与度数(degree)之间的转换】
从弧度转为度数: degrees = radians * 180 / Math.PI
从度数转为弧度: radians = degrees * Math.PI / 180

【计算两点之间的距离】
勾股定理: c2 = a2 + b2
假设有两个影片剪辑mc1和mc2,则它们两点间的距离c为:
var c:Number = Math.sqrt(Math.pow(mc1.x – mc2.x, 2) + Math.pow(mc1.y – mc2.y, 2));

【模拟圆周运动】
已知圆心o(x0, y0),半径r和弧度angle,求圆上任意一点P(x, y)的坐标:
x = x0 + (Math.cos(angle) * r);
y = y0 + (Math.sin(angle) * r);
注意:舞台的x轴正方向水平向右,y轴正方向垂直向下.

【模拟椭圆运动】
已知圆心o(x0, y0),长轴a,短轴b以及弧度angle,求圆上任意一点P(x, y)的坐标:
x = x0 + (Math.cos(angle) * a);
y = y0 + (Math.sin(angle) * b);

【华氏温度和摄氏温度之间的转换】
华氏温度 = 摄氏度数 * 9 / 5 + 32
摄氏温度 = (华氏度数 – 32) * 5 /9

【公斤与磅之间的转换】
公斤 = 磅 * 2.2
磅 = 公斤 / 2.2

【向数组尾端添加元素】
var array:Array = new Array();
array.push(“a”, “b”);
//向数组尾端添加单一元素也可以这样:
array[array.length] = “c”;
//如果以索引设定的元素不存在,数组本身会自动扩展以包含足够的元素数目.介于中间的元素会被设为undefined:
array[5] = “e”;
trace(array[4]); //输出: undefined

【向数组开端添加元素】
var array:Array = ["a", "b"];
array.unshift(“c”, “d”);
trace(array); //输出: c,d,a,b

【删除数组中第一个元素并返回该元素,使用shift()方法】
var letters:Array = new Array(“a”, “b”, “c”);
var firstLetter:String = letters.shift();
trace(letters); //输出: b,c
trace(firstLetter); //输出: a

【删除数组中最后一个元素并返回该元素的值,使用pop()方法】
var letters:Array = new Array(“a”, “b”, “c”);
trace(letters); //输出: a,b,c
var letter:String = letters.pop();
trace(letters); //输出: a,b
trace(letter); //输出: c

【删除数组中的元素,给数组添加新元素并返回删除的元素,使用splice()方法】
splice(startIndex:int, deleteCount:uint, … values):Array
startIndex: 一个整数,它指定数组中开始进行插入或删除的位置处的元素的索引;
deleteCount: 一个整数,它指定要删除的元素数量;
… values: 用逗号分隔的一个或多个值的可选列表或数组,此列表或数组将插入到此数组中由 startIndex 参数指定的位置.

【查找数组中第一个相匹配的元素】
var array:Array = ["a", "b", "c", "d", "a", "b", "c", "d"];
var match:String = “b”;
for(var i:int = 0; i < array.length; i++) {
if(array[i] == match) {
trace(“Element with index ” + i + ” found to match ” + match);
//输出: Element with index 1 found to match b
break;
}
}

【查找数组中最后一个相匹配的元素】
var array:Array = ["a", "b", "c", "d", "a", "b", "c", "d"];
var match:String = “b”;
for(var i:int = array.length – 1; i >= 0; i–) {
if(array[i] == match) {
trace(“Element with index ” + i + ” found to match ” + match);
//输出: Element with index 5 found to match b
break;
}
}

【把字符串转成数组】
使用String.split()方法:
var list:String = “I am YoungBoy.”;
var words:Array = list.split(” “); //以空格作为分隔符将字符串切割
trace(words); //输出: I,am,YoungBoy.

【把数组转成字符串】
使用String.join()方法:
var myArr:Array = new Array(“one”, “two”, “three”);
var myStr:String = myArr.join(” and “);
trace(myArr); //输出: one,two,three
trace(myStr); //输出: one and two and three

【使用对象数组处理相关数据】
var cars:Array = new Array();
cars.push({make:”Mike”, year:1997, color:”blue”});
cars.push({make:”Kelly”, year:1986, color:”red”});
for(var i:int = 0; i < cars.length; i++) {
trace(cars[i].make + ” – ” + cars[i].year + ” – ” + cars[i].color);
}
//输出:
// Mike – 1997 – blue
// Kelly – 1986 – red

【在数组中获取最小或最大值】
var scores:Array = [10, 4, 15, 8];
scores.sort(Array.NUMERIC);
trace(“Minimum: ” + scores[0]);
trace(“Maximum: ” + scores[scores.length - 1]);

【使用for … in语句读取关联数组元素】
var myObject:Object = new Object();
myObject.name = “YoungBoy”;
myObject.age = 20;
for(var i:String in myObject) {
trace(i + “: ” + myObject[i]);
}
//输出: name: YoungBoy
// age: 20
注意: for … in循环不会显示对象所有的内建属性.例如,循环会显示执行期间新增的特殊属性,但是,不会列出内建对象的方法,即使都是储存在对象属性内.

【AVM(ActionScript. Virtual Machine,虚拟机)和渲染引擎(Rendering Engine)】
AVM负责执行ActionScript程序,而渲染引擎则是把对象绘制在显示器上.

【指出容器的显示清单中有多少显示对象】
每个容器都有numChildren属性.

【把项目新增至显示清单】
addChild(child:DisplayObject)
addChildAt(child:DisplayObject, index:int)
index: 添加该子项的索引位置.如果指定当前占用的索引位置,则该位置以及所有更高位置上的子对象会在子级列表中上移一个位置.

【从显示清单中移除项目】
removeChild(child:DisplayObject)
removeChildAt(index:int)
index: 要删除的 DisplayObject 的子索引,该子项之上的任何显示对象的索引位置都减去1.
如果想移除窗口所有子元件,可以结合removeChildAt(),numChildren属性以及for循环.因为每次一个子元件被移除时,索引位置都会变化,所以,有两种方法可以处理所有子元件的移除:
1. 总是移除位置0的子元件;
2. 倒过来移除子元件,也就是从尾端开始.

【更改现有子项在显示对象容器中的位置】
setChildIndex(child:DisplayObject, index:int):void
可能用到的方法:
返回 DisplayObject 的 child 实例的索引位置: getChildIndex(child:DisplayObject):int
返回位于指定索引处的子显示对象实例: getChildAt(index:int):DisplayObject
注意: 当子元件移到低于它现在所在位置的索引时,那么,从标的索引起,直到子元件索引前面的那个索引的所有子元件都会令其索引增加1,而该子元件就会指定至标的索引.当子元件移到较高索引时,从该子元件索引之上的那个索引起,直到标的索引的所有子元件都会令其索引往下减1,而该子元件就会指定至标的索引值.

【关于TextField以垂直方式把文字摆在按钮表面中心点的小技巧】
textField.y = (_height – textField.textHeight) / 2;
textField.y -= 2; //减2个像素以调整偏移量

【外部.swf影片载入和互动】
1. 监听init事件;
2. 透过content属性存取所载入的影片.
当所载入的影片做好足够的初始化工作,使其方法和属性可以接受互动时,init事件就会被发起.只有在载入器发起init事件后,才能控制影片.所载入的影片还没初始化就试着与它互动,是会产生执行期间错误的.
_loader.contentLoaderInfo.addEventListener(Event.INIT, handleInit); //当载入的.swf的属性和方法可用时
_loader.load(new URLRequest(“ExternalMovie.swf”));
private function handleInit(event:Event):void {
var movie:* = _loader.content;
trace(movie.getColor());
movie.setColor(0xFF0000);
}

【TextField有两种类型:动态(dynamic)和输入(input),默认值为动态.改变TextField类型方法】
field.type = TextFieldType.INPUT; //selectable属性默认值为true
flash.text.TextFieldType.INPUT和flash.text.TextFieldType.DYNAMIC

【过滤文字输入】
TextField.restrict = “此处为可输入的内容”;
field.restrict = “^此处为禁止输入的内容”;
restrict属性支持一些类似正则表达式的样式:
field.restrict = “a-zA-z”; //只允许大小字母
field.restrict = “a-zA-z “; //只允许字母和空格
field.restrict = “0-9″; //只允许数字
field.restrict = “^abcdefg”; //除了小写字母abcdefg不允许外,其它都允许
field.restrict = “^a-z”; //所有小写字母都不允许,但是,其它内容都允许,包括大写字母
field.restrict = “0-9^5″; //只允许数字,但5例外
让restrict字符包含具有特殊意义的字母(例如-和^):
field.restrict = “0-9\\-”; //允许数字和破折号
field.restrict = “0-9\\^”; //允许数字和^
field.restrict = “0-9\\\\”; //允许数字和反斜杠
你也可以使用Unicode转义序列,指定允许的内容.例如:
field.restrict = “^\u001A”;
注意:ActionScript有区分大小写的,如果restrict属性设为abc,允许字母的大写形式(A,B和C)输入时会变成小写对待形式(a,b和c),反之亦然.restrict属性只影响用户可以输入的内容,脚本可将任何文本放入文本字段中.

【设定输入框的最大长度】
TextField.maxChars:int

【向TextField追加内容】
TextField.appendText(text:String):void
与通过对 text 属性使用加法赋值来连接两个字符串(例如 field.text += moreText)相比,此方法的效率更高.

【显示HTML格式的文字】
TextField.htmlText = “<b>Html text</b>”;
支持的HTML标签集有: <b>,<i>,<u>,<font>(有face,size以及color属性),< p>,<br>,<a>,<li>,<img>以及<textformat>(有 leftmargin,rightmargin,blockindent,indent,leading以及tabstops属性,相应于 TextFormat类的同名属性)

【缩减空白】
TextField.condenseWhite = true;
删除具有HTML文本的文本字段中的额外空白(空格,换行符等),如同多数HTML浏览器所做的那样.
注意: 在设置 htmlText 属性之前设置 condenseWhite 属性

AS3及Flex的百条常用知识

JavaScript与ActionScript3交互

// January 24th, 2010 // No Comments » // AS3知识积累, javascript and CSS

TestData.as

package {
import flash.display.Sprite;
import flash.events.TimerEvent;
import flash.text.TextField;
import flash.utils.Timer;
import flash.external.ExternalInterface;

public class TestDate extends Sprite
{

private var i:int=0;
private var timer:Timer=new Timer(1000,60);

internal var jsReady:Boolean;
internal var aa:String =”hi”;
private var output:TextField=new TextField();
public function TestDate()
{
this.addChild(this.output);
this.timer.addEventListener(TimerEvent.TIMER,timerHandler);
this.timer.start();
this.output.appendText(‘开始时间’+”\n”);
this.output.autoSize=’12px’;

}

private function timerHandler(event:TimerEvent):void{

jsReady = new Boolean(ExternalInterface.call(“JSReady”,aa));
this.output.appendText(“runing:”+(i++)+”\n”);
if(jsReady){
ExternalInterface.addCallback(“sayHello”,sayHello);
ExternalInterface.call(“setSwfReady”,true);
if(ExternalInterface.available)ExternalInterface.call(“callAS”,”");
this.timer.stop();
}
}

public function sayHello(txt:String):void{
this.output.appendText(“JS: “+txt+”\n”);
}
}
}

javascript

<script language="JavaScript" type="text/javascript">
var jsReady=false;
var swfReady=false;
function atReady(){
jsReady=true;
}

function JSReady(){
return jsReady;
}
function setSwfReady(ready){
swfReady=ready;
}

function callAS(){
if(swfReady){
TestDate.sayHello(“Hello,World”);
}
}

function show(str){
document.getElementById(“show”).innerHTML=”test:”+str;
}

</script>

[整理] 页面跳转代码

// January 14th, 2010 // No Comments » // PHP基础知识累积, javascript and CSS

这年头,真是好记性不如烂笔头。学的快,忘的快。刚才工作中要用到页面跳转,却又记不清楚了。
故特意整理了一下,用做以后参考。
第一篇: JavaScript 跳转
方法一:
<script language=”javascript”>
window.location = “http://www.baidu.com”;
</script>
方法二:
<script language=”javascript”>
document.location = “http://www.baidu.com”;
</script>
方法三: (带进度条)
<html>
<head>
<meta http-equiv=”Content-Language” content=”zh-cn”>
<meta HTTP-EQUIV=”Content-Type” CONTENT=”text/html; charset=gb2312″>
<title>跳转到baidu.com</title>
</head>
<body>
<form name=loading>
<P align=center><FONT face=Arial color=#0066ff size=2>loading…</FONT>
<INPUT style=”PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: bolder; PADDING-BOTTOM: 0px; COLOR: #0066ff; BORDER-TOP-style: none; PADDING-TOP: 0px; FONT-FAMILY: Arial; BORDER-RIGHT-style: none; BORDER-LEFT-style: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-style: none”
size=46 name=chart>
<BR>
<INPUT style=”BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; COLOR: #0066ff; BORDER-BOTTOM: medium none; TEXT-ALIGN: center” size=47 name=percent>
<script language=”javascript”>
var bar=0
var line=”||”
var amount=”||”
count()
function count(){
bar=bar+2
amount =amount + line
document.loading.chart.value=amount
document.loading.percent.value=bar+”%”
if (bar<99){
setTimeout(“count()”,100);
}else{
window.location = “http://www.baidu.com/”;
}
}
</script>
</P>
</form>
</body>
</html>
第二篇: 页面跳转
<head>
<meta http-equiv=”refresh” content=”10; url=http://www.baidu.com”>
</head>
第三篇: 动态页面跳转
方法一: PHP 跳转
<?php
header(“location: http://www.baidu.com”);
?>
方法二: ASP 跳转
<%
response.redirect “http://www.baidu.com”
%>
FYI:
<%
Dim ID1
Dim ID2
dim str
ID1 = Request(“forumID”)
ID2 = Request(“threadID”)
str=”/blog/threadview.asp?forumID=”& ID1 &”&threadID=” & ID2
response.redirect str
%>

这年头,真是好记性不如烂笔头。学的快,忘的快。刚才工作中要用到页面跳转,却又记不清楚了。
故特意整理了一下,用做以后参考。
第一篇: JavaScript 跳转
方法一:
<script language=”javascript”>    window.location = “http://www.baidu.com”;</script>
方法二:
<script language=”javascript”>    document.location = “http://www.baidu.com”;</script>
方法三: (带进度条)
<html><head><meta http-equiv=”Content-Language” content=”zh-cn”><meta HTTP-EQUIV=”Content-Type” CONTENT=”text/html; charset=gb2312″><title>跳转到baidu.com</title></head><body><form name=loading><P align=center><FONT face=Arial color=#0066ff size=2>loading…</FONT><INPUT style=”PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-WEIGHT: bolder; PADDING-BOTTOM: 0px; COLOR: #0066ff; BORDER-TOP-style: none; PADDING-TOP: 0px; FONT-FAMILY: Arial; BORDER-RIGHT-style: none; BORDER-LEFT-style: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-style: none”size=46 name=chart><BR><INPUT style=”BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; COLOR: #0066ff; BORDER-BOTTOM: medium none; TEXT-ALIGN: center” size=47 name=percent><script language=”javascript”>var bar=0var line=”||”var amount=”||”count()function count(){    bar=bar+2    amount =amount + line    document.loading.chart.value=amount    document.loading.percent.value=bar+”%”    if (bar<99){        setTimeout(“count()”,100);    }else{        window.location = “http://www.baidu.com/”;    }}</script></P></form></body></html>
第二篇: 页面跳转
<head><meta http-equiv=”refresh” content=”10; url=http://www.baidu.com”></head>
第三篇: 动态页面跳转
方法一: PHP 跳转
<?phpheader(“location: http://www.baidu.com”);?>
方法二: ASP 跳转
<%response.redirect “http://www.baidu.com”%>
FYI:<%Dim ID1Dim ID2dim strID1 = Request(“forumID”)ID2 = Request(“threadID”)str=”/blog/threadview.asp?forumID=”& ID1 &”&threadID=” & ID2response.redirect str%>

简单实用的javascript的windows.confirm()类型的确认对话框

// January 14th, 2010 // No Comments » // javascript and CSS

<a   href=”#”   onclick=”return   confirm(‘删除?’);”>删除</a>

Zend_Db_Table Relationships 翻译和自己的注释

// January 10th, 2010 // No Comments » // Zend Framework 累积

下面是在读Zend手册9.8 Zend_Db_Table Relationships时,对重要的地方的摘录,翻译,还有很多自己的解释。由于时间有限,就不全部翻译了:

介绍:

在RDBMS中,表之间有着各种关系,有一多对应,多多对应等等。
Zend框架提供了一些方法来方便我们实现这些关系。

定义关系:

下面是本文用的例子的关系定义:

<?php
class Accounts extends Zend_Db_Table_Abstract
{
protected $_name            = ‘accounts’;
protected $_dependentTables = array(‘Bugs’);
}

class
Products extends Zend_Db_Table_Abstract
{
protected $_name            = ‘products’;
protected $_dependentTables = array(‘BugsProducts’);
}

class
Bugs extends Zend_Db_Table_Abstract
{
protected $_name            = ‘bugs’;

protected
$_dependentTables = array(‘BugsProducts’);

protected
$_referenceMap    = array(
‘Reporter’ => array(
‘columns’           => ‘reported_by’,
‘refTableClass’     => ‘Accounts’,
‘refColumns’        => ‘account_name’
),
‘Engineer’ => array(
‘columns’           => ‘assigned_to’,
‘refTableClass’     => ‘Accounts’,
‘refColumns’        => ‘account_name’
),
‘Verifier’ => array(
‘columns’           => array(‘verified_by’),
‘refTableClass’     => ‘Accounts’,
‘refColumns’        => array(‘account_name’)
)
);
}

class
BugsProducts extends Zend_Db_Table_Abstract
{
protected $_name = ‘bugs_products’;

protected
$_referenceMap    = array(
‘Bug’ => array(
‘columns’           => array(‘bug_id’),
‘refTableClass’     => ‘Bugs’,
‘refColumns’        => array(‘bug_id’)
),
‘Product’ => array(
‘columns’           => array(‘product_id’),
‘refTableClass’     => ‘Products’,
‘refColumns’        => array(‘product_id’)
)
);

}

我们看到例子中定义了四个类:Accounts,Products,Bugs,BugsProducts。其中Accounts,Products和Bugs是三个实体表,而BugsProducts是关系表。
我们再来分析一下这三个实体,一个Account有多个Bug,他们之间是一对多的关系,而Bug和Product是多对多的关系。
$_dependentTables是一个与该对象关联的对象名,这里注意,要写对象名而不是关联的数据库名。
$_referenceMap 数组用来定义和其他表的关系,在这里可以设置和那些表有关系,有什么样的关系。第一个设置的是Rule Key,也就是上面例子的’Reporter’, ‘Engineer’之类的。Rule Key的作用其实就是一个关系的名字,并不需要和其他数据库表名或者其他对象名的名字一样。只是为了标记的,在后面的时候,我们可以看到这个Rule Key的作用。

每一个Rule下面都有如下的一些定义:(没有特殊说明,都以如上’Reporter’关系进行说明)

* columns=> 设置和别的表关联的字段名,如上的’report_by’就是数据库中表Bugs的report_by字段。这里只有一个字段,也可以设置多个字段。
* refTableClass=>用于设置与这个表发生关系的表。这里要注意,一定使用目标表的对象的名字而不是表名字,例子中就和’Account’对象发生了关联。
* refColumns =>设置发生联系的表的字段。可以写多个,如果和多个字段发生联系的话,这里要和columns对应。这个设置其实是可选的,如果为空,关联字段自动被设置成为关联表的主键。上面例子中并没有使用主键作为关联字段,所以手动设置。
* onDelete=>可选字段,设置当删除是的动作。
* onUpdate=>可选字段,设置当更新表时的动作。

以上定义关系。

从关联表中取数据:

如果我们已经得到了一个查询结果,我们可以通过一下语句去取得这个结果相关联的表的查询结果:

$row->findDependentRowset($table, [$rule]);

这个方法一般使用与一多对应的两个实体表中,在多多对应的两个实体表和一个关系表如何从一个实体表取出另一个实体表的数据,我们会在下面叙述。
第一个字段$table是指和这个表想相联系的表对应的类名。第二个字段是可选的,是我们刚刚说到的rule key,就是这个关系的名字,如果省略,则默认为这个表中的第一个关系。下面是例子:

<?php
$accountsTable      = new Accounts();
$accountsRowset     = $accountsTable->find(1234);
$user1234           = $accountsRowset->current();

$bugsReportedByUser = $user1234->findDependentRowset(‘Bugs’);

例子中,我们先读取了一个编号为1234的用户,然后去查找这个家伙报了什么bug,由于zend默认是第一个关联,所以这里和Account发生关联的第一个就是’Reporter,所以就取出了Reporter的记录。

如果我们想取出其他的记录,比如Engineer,可以按照下面的办法:

<?php
$accountsTable      = new Accounts();
$accountsRowset     = $accountsTable->find(1234);
$user1234           = $accountsRowset->current();

$bugsAssignedToUser = $user1234->findDependentRowset(‘Bugs’, ‘Engineer’);

除了使用findDependentRowset之外,我们还可以使用叫做“魔术方法”(Magic Method)的机制。之所以这么叫,就是因为好像是在变魔术一样。所以方法findDependentRowset(‘<TableClass>’, ‘<Rule>’)就可以等价于如下:
- $row->find<TableClass>()
- $row->find<TableClass>By<Rule>()

注:这个机制是我们最一开始是在Ruby on Rails里面看到的。这里的<TableClass>和<Rule>一定要使用和相关联的类名以及关联名(Rule Key)完全一样的名字,才可以生效。下面是例子:

<?php
$accountsTable    = new Accounts();
$accountsRowset   = $accountsTable->find(1234);
$user1234         = $accountsRowset->current();

// Use the default reference rule
$bugsReportedBy   = $user1234->findBugs();

// Specify the reference rule
$bugsAssignedTo   = $user1234->findBugsByEngineer();

从父表取得字段:

刚刚我们介绍了一多关系中的从一去多的方法,现在我们反过来,从多取一,其实是从多中的一个取他相对应的那个记录。
类似的我们有这样的语句:

$row->findParentRow($table, [$rule]);

类似的,$table为类名,而可选参数$rule填入对应的Rule Key。下面是例子:

<?php
$bugsTable         = new Bugs();
$bugsRowset        = $bugsTable->fetchAll(array(‘bug_status = ?’ => ‘NEW’));
$bug1              = $bugsRowset->current();

$reporter          = $bug1->findParentRow(‘Accounts’);

和上面不太一样的是,上面返回的是一个多个记录的集合,而这次返回的必然是一条记录。下面的例子是设置Rule:

<?php
$bugsTable         = new Bugs();
$bugsRowset        = $bugsTable->fetchAll(‘bug_status = ?’, ‘NEW’);
$bug1              = $bugsRowset->current();

$engineer          = $bug1->findParentRow(‘Accounts’, ‘Engineer’);

只需要吧Rule填入就好了。相似的,这个方法也有“魔术字段”。findParentRow(‘<TableClass>’, ‘<Rule>’)对应:
- $row->findParent<TableClass>()
- $row->findParent<TableClass>By<Rule>()
例子:

<?php
$bugsTable         = new Bugs();
$bugsRowset        = $bugsTable->fetchAll(‘bug_status = ?’, ‘NEW’);
$bug1              = $bugsRowset->current();

// Use the default reference rule
$reporter          = $bug1->findParentAccounts();

// Specify the reference rule
$engineer          = $bug1->findParentAccountsByEngineer();

取得多对多关系表的字段:

上面两个方法讲述了一对多的使用,下面就是多对多了。我们使用如下方法取得多对多关系表的数据:

$row->findManyToManyRowset($table, $intersectionTable, [$rule1, [$rule2]]);

这里参数变成了4个,因为需要增加一个关系表来存储多对多的关系。
$table是与之发生多对多关系的表的类名,$intersectionTable是中间存储关系的关系表的类名。$rule1和$rule2是上面两个数据表的Rule Key。省略Rule Key的例子如下:

<?php
$bugsTable        = new Bugs();
$bugsRowset       = $bugsTable->find(1234);
$bug1234          = $bugsRowset->current();

$productsRowset   = $bug1234->findManyToManyRowset(‘Products’, ‘BugsProducts’);

下面是该方法的全部参数调用例子:

<?php
$bugsTable        = new Bugs();
$bugsRowset       = $bugsTable->find(1234);
$bug1234          = $bugsRowset->current();

$productsRowset   = $bug1234->findManyToManyRowset(‘Products’, ‘BugsProducts’, ‘Bug’);

这次的“魔术方法”是,对应 findManyToManyRowset(‘<TableClass>’, ‘<IntersectionTableClass>’, ‘<Rule1>’, ‘<Rule2>’)
- $row->find<TableClass>Via<IntersectionTableClass>()
- $row->find<TableClass>Via<IntersectionTableClass>By<Rule1>()
- $row->find<TableClass>Via<IntersectionTableClass>By<Rule1>And<Rule2>()

例子:

<?php
$bugsTable        = new Bugs();
$bugsRowset       = $bugsTable->find(1234);
$bug1234          = $bugsRowset->current();

// Use the default reference rule
$products          = $bug1234->findProductsViaBugsProducts();

// Specify the reference rule
$products          = $bug1234->findProductsViaBugsProductsByBug();

如何使用Zend_Form组件来实现表单提交,并且让错误提示信息为中文显示.

// January 6th, 2010 // No Comments » // Zend Framework 累积

今天因为在这里看到一篇帖子, 我也就找了一下怎样实现..没想到还真被我给搞事实上了….同时公司又要开发一个群组功能..我也就想运用一下Zend_Form来实现创建群组的功能.主要还是看中Zend_Form可以在写Form时候.实现服务器端的验证功能..省得我们在把数据提交到数据库的时候再验证一次..所以呢.我就看了一下这方面的手册..通过Zend Framework手册找到了相关的使用说明…最简单的使用方式就是在控制器(Controller)里写一个现成的Action,这样..在这个控制器里就可以直接使用这个Action…代码可以如下:

<?php
public    function   formAction()
{
$form=new Zend_Form();
$form->setName(‘group’)
$title = new Zend_Form_Element_Select(‘title’);
$title ->setLabel(‘性别’)
->setMultiOptions(array(‘mr’=>’Mr’, ‘mrs’=>’Mrs’))
->setRequired(true)
->addValidator(‘NotEmpty’, true);
$yourName = new Zend_Form_Element_Text(‘firstName’);
$yourName->setLabel(‘姓名’)
->setRequired(true)
->addValidator(‘NotEmpty’, true) ;
$email = new Zend_Form_Element_Text(‘email’);
$email->setLabel(‘电子邮件地址’)
->addFilter(‘StringToLower’)
->setRequired(false)
->addValidator(‘NotEmpty’);

$submit = new Zend_Form_Element_Submit(‘submit’);
$submit->setLabel(‘group’);
$form->addElements(array($title, $yourName,$email,$submit));
}
?>

当然..我也可以把这个Form专门写成一个类…存放在一个forms共同的目录下.这样就方便我们管理我们所有的Form表单..我的实现方式就是把它放在和控制器(Controller)的同一级别的目录下…这样管理起来也方便..当然不同的朋友..有不同的想法…另一种方式..就是可以把它写成View Helper…这个方式实现起来,,也很方便..这里我就不想多写了…Zend Framework实现起来很方便…只要你想的到…无论你怎样完成你的任务,,都是可以的..在这里我就不多说其它的…我只想谈一下怎样让 Zend_Form实现中文的提示信息功能…我这里有二种方法..
第一:比较笨的方式就是:如果你的网站不要做成多国语言的网站..同时你的Zend Framework版本不是经常更换的话…你就可以找到相关提示信息的源码…更改成中文的提示.
这个笨方法..实在是没有办法的办法…呵呵…
第二:我也是在英文站…看到的一个比较好的方式,就是通过重写这个提示信息.把它换成我们想要的语言…这样…就算我们会去换语言..或是换Zend Framework的版本..
对我们的影响也不是很大…我们只要更改一下我们的Form的表单就可以搞定了..现在这种方式的代码如下(我这里只写了Email提示信息..其它的不要多写出):

<?php
$email = new Zend_Form_Element_Text(‘email’);
$email->setLabel(‘电子邮件地址’)
->addFilter(‘StringToLower’)
->setRequired(false)
->addValidator(‘NotEmpty’)
->addValidator(‘EmailAddress’,true,array(‘messages’ => array(
‘emailAddressInvalid’ => ‘这不是一个可用的电子邮件!’,
‘emailAddressInvalidHostname’ => ‘这不是一个有效的主机名!’,
‘emailAddressInvalidMxRecord’ => ‘这不是一个有效的电子邮件地址!’,
‘emailAddressDotAtom’ => ‘这不是一个有效的电子邮件地址!’,
‘emailAddressQuotedString’ => ‘这不是一个有效的电子邮件地址!’,
‘emailAddressInvalidLocalPart’ => ‘这不是一个有效的电子邮件地址!’,)));

?>

到这里..Zend_Form这个组件还有一个比较重要的功能..就是Zend_Form_Decorator..手册上称为装饰器,也就是说你可以自己写你想要的装饰器..比如说..你要把你的Form用Table包含起来..我们要怎样实现呢?这个时候..我们就要用到比如说 HtmlTag,Label这些装饰器来达到我们想要的功能…这里是一个比较重要的概念了..有兴趣的朋友可以去去看一下…因为如果你想要用 Zend_Form这个组件..不会装饰器因该用起来会很困难..所以必须要会这个东西..才可以创建你自己想要的表单功能..最后..就是一点装饰器的小运用
我只是实现一个小的功能…如下代码:

<?php
$email = new Zend_Form_Element_Text(‘email’);
$email->setLabel(‘电子邮件地址’)
->addFilter(‘StringToLower’)
->setRequired(false)
//利用装饰器来增加td标签
->addDecorator(‘HtmlTag’, array(‘tag’ => ‘td’))
->addDecorator(‘Label’, array(‘tag’ => ‘td’))
//重复利用HtmlTag装饰器来增加tr标签
->addDecorator(array(‘FooTr’ => ‘HtmlTag’), array(‘tag’ => ‘tr’))
->addValidator(‘NotEmpty’);
?>

哈哈….大致的运用就是这样了…最后..就是验证提交的数据了…看如何验检验用户提交的数据….这里就不多说了…OK…

是快一个星期没有更新我的这个博客了..今天因为在这里看到一篇帖子, 我也就找了一下怎样实现..没想到还真被我给搞事实上了….同时公司又要开发一个群组功能..我也就想运用一下Zend_Form来实现创建群组的功 能.主要还是看中Zend_Form可以在写Form时候.实现服务器端的验证功能..省得我们在把数据提交到数据库的时候再验证一次..所以呢.我就看 了一下这方面的手册..通过Zend Framework手册找到了相关的使用说明…最简单的使用方式就是在控制器(Controller)里写一个现成的Action,这样..在这个控 制器里就可以直接使用这个Action…代码可以如下:

<?php
public	function   formAction()
{
 $form=new Zend_Form();
 $form->setName('group')
 $title = new Zend_Form_Element_Select('title');
 $title ->setLabel('性别')
        ->setMultiOptions(array('mr'=>'Mr', 'mrs'=>'Mrs'))
	->setRequired(true)
        ->addValidator('NotEmpty', true);
 $yourName = new Zend_Form_Element_Text('firstName');
 $yourName->setLabel('姓名')
          ->setRequired(true)
          ->addValidator('NotEmpty', true) ;
 $email = new Zend_Form_Element_Text('email');
 $email->setLabel('电子邮件地址')
       ->addFilter('StringToLower')
       ->setRequired(false)
       ->addValidator('NotEmpty');
 
 $submit = new Zend_Form_Element_Submit('submit');
 $submit->setLabel('group');
 $form->addElements(array($title, $yourName,$email,$submit));
}
?>

当然..我也可以把这个Form专门写成一个类…存放在一个forms共同的目录下.这样就方便我们管理我们所有的Form表单..我的实现方式就是 把它放在和控制器(Controller)的同一级别的目录下…这样管理起来也方便..当然不同的朋友..有不同的想法…另一种方式..就是可以 把它写成View Helper…这个方式实现起来,,也很方便..这里我就不想多写了…Zend Framework实现起来很方便…只要你想的到…无论你怎样完成你的任务,,都是可以的..在这里我就不多说其它的…我只想谈一下怎样让 Zend_Form实现中文的提示信息功能…我这里有二种方法..
第一:比较笨的方式就是:如果你的网站不要做成多国语言的网站..同时你的Zend Framework版本不是经常更换的话…你就可以找到相关提示信息的源码…更改成中文的提示.
这个笨方法..实在是没有办法的办法…呵呵…
第二:我也是在英文站…看到的一个比较好的方式,就是通过重写这个提示信息.把它换成我们想要的语言…这样…就算我们会去换语言..或是换Zend Framework的版本..
对我们的影响也不是很大…我们只要更改一下我们的Form的表单就可以搞定了..现在这种方式的代码如下(我这里只写了Email提示信息..其它的不要多写出):

<?php
$email = new Zend_Form_Element_Text('email');
$email->setLabel('电子邮件地址')
    ->addFilter('StringToLower')
    ->setRequired(false)
    ->addValidator('NotEmpty')
    ->addValidator('EmailAddress',true,array('messages' => array(
       'emailAddressInvalid' => '这不是一个可用的电子邮件!',
       'emailAddressInvalidHostname' => '这不是一个有效的主机名!',
       'emailAddressInvalidMxRecord' => '这不是一个有效的电子邮件地址!',
       'emailAddressDotAtom' => '这不是一个有效的电子邮件地址!',
       'emailAddressQuotedString' => '这不是一个有效的电子邮件地址!',
       'emailAddressInvalidLocalPart' => '这不是一个有效的电子邮件地址!',)));
 
?>

到这里..Zend_Form这个组件还有一个比较重要的功能..就是Zend_Form_Decorator..手册上称为装饰器,也就是说你可以自己 写你想要的装饰器..比如说..你要把你的Form用Table包含起来..我们要怎样实现呢?这个时候..我们就要用到比如说 HtmlTag,Label这些装饰器来达到我们想要的功能…这里是一个比较重要的概念了..有兴趣的朋友可以去去看一下…因为如果你想要用 Zend_Form这个组件..不会装饰器因该用起来会很困难..所以必须要会这个东西..才可以创建你自己想要的表单功能..最后..就是一点装饰器的 小运用
我只是实现一个小的功能…如下代码:

<?php
$email = new Zend_Form_Element_Text('email');
$email->setLabel('电子邮件地址')
   ->addFilter('StringToLower')
   ->setRequired(false)
   //利用装饰器来增加td标签
   ->addDecorator('HtmlTag', array('tag' => 'td'))
   ->addDecorator('Label', array('tag' => 'td'))
   //重复利用HtmlTag装饰器来增加tr标签
   ->addDecorator(array('FooTr' => 'HtmlTag'), array('tag' => 'tr'))
   ->addValidator('NotEmpty');
?>

哈哈….大致的运用就是这样了…最后..就是验证提交的数据了…看如何验检验用户提交的数据….这里就不多说了…OK…

用Zend_Auth实现Session身份持久认证

// January 5th, 2010 // No Comments » // Zend Framework 累积

今天用Zend Framework搞了一下身份持久认证…

手册里头提供了四种认证方式,一个是session,一个是数据库表,一个摘要式,最后一愕是HTTP认证适配器。我在实现session认证的时候(按照手册上的代码),起初发现了一个问题,无法验证…后来仔细看了一下,手册上的代码缺少了点东西…

Zend_Auth结合Zend_Auth_Storage_Session实现session的持久身份认证,主要有一下几点:

1、先做个适配器,也就是自己用来验证用户的类,如:

class AuthAdapter implements Zend_Auth_Adapter_Interface{
var $username;
var $password;
/**
* Sets username andpassword for authentication
* @return void
*/
public function __construct($username=”, $password=”){//
$this->username = $username;
$this->password = $password;
}
/**
* Performs an authentication attempt
* @throws Zend_Auth_Adapter_Exception If authentication cannot be performed
* @return Zend_Auth_Result
* Zend_Auth_Result::SUCCESS
* Zend_Auth_Result::FAILURE
* Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND
* Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS
* Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID
* Zend_Auth_Result::FAILURE_UNCATEGORIZED
*/
public function authenticate(){
$aryInfo;
if (isset($this->username) && (isset($this->password))){
$aryInfo[0] = _e(’验证正确’);
return new Zend_Auth_Result(1,$aryInfo);
}else{
$aryInfo[0] = _e(’验证失败’);
return new Zend_Auth_Result(-1,$aryInfo);
}
}
}

2、在获取一个Zend_Auth的实例

$auth = Zend_Auth::getInstance();
3、创建认证session的命名空间,并放到Zend_Auth的实例的存储器中
$auth->setStorage(new Zend_Auth_Storage_Session('someNamespace'));
4、加入上面的认证适配器实例:

include (’../classes/authadapter.class.php’);
$authAdapter = new AuthAdapter(’usrname’, ‘pwd’);
$result = $this->_auth->authenticate($authAdapter);

5、判断验证结果:

if (!$result->isValid()) {
foreach ($result->getMessages() as $message){
echo “$message\n”;
}
}else{

foreach ($result->getIdentity() as $message){
echo “$message\n”;
}
}

如果在其他页面去验证的时候直接调用一个方法就可以验证了:

$auth = Zend_Auth::getInstance();
$auth->setStorage(new Zend_Auth_Storage_Session(’sessionAuth’));
if ($auth->hasIdentity()){
$identity = $auth->getIdentity();
echo ‘认证’;
}else{
echo ‘未认证’;
foreach ($auth->getIdentity() as $message){
echo “$message\n”;
}

其实按照我的理解,采用什么样的方式去验证,只要在适配器验证方法中去决定就可以了…

对于身份持久,最好与ACL配合好使用才好…否则对于权限和资源的访问控制还是会有很多问题…

还有一个重要的问题,从根本上来讲,无论那种验证方式,还都是和session有很大关系的,除非在每次验证的时候都去调用验证的原始方法,而不是只根据验证session中取出来的值,当然,session中的值会作为验证信息的依据。

另外几种验证方法,再看看,也许会有更好更合适的,到时候再分享。

PS:有个重要需要搞清楚的问题,用这样的认证方式是否能够判断用户在线时长…

PHP 计算时间差 (转)

// December 31st, 2009 // No Comments » // PHP基础知识累积, PHP知识累计

<?php
/**
* 时间差计算
*
* @param Timestamp $time
* @return String Time Elapsed
* @author Shelley Shyan
* @copyright http://phparch.cn (Professional PHP Architecture)
*/
function time2Units ($time)
{
$year   = floor($time / 60 / 60 / 24 / 365);
$time  -= $year * 60 * 60 * 24 * 365;
$month  = floor($time / 60 / 60 / 24 / 30);
$time  -= $month * 60 * 60 * 24 * 30;
$week   = floor($time / 60 / 60 / 24 / 7);
$time  -= $week * 60 * 60 * 24 * 7;
$day    = floor($time / 60 / 60 / 24);
$time  -= $day * 60 * 60 * 24;
$hour   = floor($time / 60 / 60);
$time  -= $hour * 60 * 60;
$minute = floor($time / 60);
$time  -= $minute * 60;
$second = $time;
$elapse = ”;

$unitArr = array(‘年’  =>’year’, ’个月’=>’month’,  ’周’=>’week’, ’天’=>’day’,
‘小时’=>’hour’, ’分钟’=>’minute’, ’秒’=>’second’
);

foreach ( $unitArr as $cn => $u )
{
if ( $$u > 0 )
{
$elapse = $$u . $cn;
break;
}
}

return $elapse;
}

$past = 2052345678; // Some timestamp in the past
$now  = time();     // Current timestamp
$diff = $now - $past;

echo ’发表于’ . time2Units($diff) . ’前’;
?>

网址Excel大全

// December 29th, 2009 // No Comments » // 电脑知识

http://www.excel-jiten.net/database/index.html

Zend Framework之Zend_ACL

// December 24th, 2009 // No Comments » // Zend Framework 累积

在Zend_Acl當中有兩個重要的部份:Resource(資源) 與 Role(角色),其中「角色」存取「資源」,舉個白話的例子,在一個進出受管制的電梯大樓,小明可以進入101樓的辦公室,表示小明這個「角色」,他的 通行證可以刷卡進入101樓的電梯,進入101樓這個「資源」。

比較常見的是網站管理系統的權限實作,例如編輯部的同仁只能用網站的內容編輯系統,廣告部則可以使用廣告刊播系統以及報表系統,但沒有使用內容編輯的權限。那在ZF中,Zend_Acl如何實作這樣的概念呢?

一、建立資源:
Zend_Acl裡有個Zend_Acl_Resource_Interface這個介面可以方便的來建立資源。

實作自這個介面的類別,會有一個getResourceId()這個方法,代表它是一個資源

另外,Zend_Acl_Resource類別中也包含一些Zend_Acl的一些實作,讓開發者可以直接繼承來使用。

Zend_Acl使用樹狀結構的方式來管理資源,透過這個樹狀結構,可以新增新的資源進來,並儲存在結構中。

對樹狀結構上層的修改,亦可影響至下層,不過即使下層不想繼承上層的規則,也可以簡單的加上一些例外規則,在這結構中,Resource只能一次繼承自一個Parent,不過每個Parent都可以有各自的Parent,以此類推。

二、建立角色:
透 過Zend_Acl_Role_Interface的實作,建立角色也是相當容易的。如同資源的建立,角色可透過實作的getRoleId()方法來建 立。同Zend_Acl_Resource,Zend_Acl裡也有個Zend_Acl_Role的類別可以直接繼承來使用。

不過與資源不同的,一個角色可以一次繼承自一個或多個角色。

以上面那個網站管理系統的例子來說,假設eddie可能只是編輯部的同事(單一角色),而joanne是企劃部門的主管,她除了管企劃部門的案子之外,亦可能需要看一下網站的新聞是不是有錯字,則可以說她的角色同時屬於”企劃部”及”編輯部”(多重角色)。

其 實透過角色繼承的方式,可以在設計系統時不用指定特定某個人的使用權限。例如設定”編輯部”的權限是可以用內容管理系統,然後只要讓eddie”屬於”這 個部門,eddie這個帳號也可以有使用的權限了;若同像上面joanne的例子,只要讓她同時”屬於”企劃部跟編輯部即可,在設定上相當簡潔且方便。

我們以上面這個例子來實作一小段程式碼,設定三種角色:編輯部editor、企劃部planner以及網站系統管理員administrator。

<?php
require_once ‘Zend/Acl.php’;
require_once ‘Zend/Acl/Role.php’;
require_once ‘Zend/Acl/Resource.php’;

//建立一個Access Control List(ACL)物件
$acl = new Zend_Acl();

//在ACL中建立三個角色:editor、planner及administrator
$acl->addRole(new Zend_Acl_Role(‘editor’))
->addRole(new Zend_Acl_Role(‘planner’))
->addRole(new Zend_Acl_Role(‘administrator’));

//建立joanne角色,並設定此角色同時屬於editor及planner兩個角色
$group1 = array(‘editor’, ‘planner’);
$acl->addRole(new Zend_Acl_Role(‘joanne’), $group1);

//在ACL中建立三個資源:內容管理系統ContentManager、廣告系統ADManager及系統管理SystemAdmin
$acl->add(new Zend_Acl_Resource(‘ContentManager’))
->add(new Zend_Acl_Resource(‘ADManager’))
->add(new Zend_Acl_Resource(‘SystemAdmin’));

//設定角色與資源之關係
$acl->allow(‘editor’, ‘ContentManager’);     //editor角色允許使用ContentManager資源
$acl->allow(‘planner’, ‘ADManager’);          //planner角色允許使用ADManager資源
$acl->allow(‘administrator’, ‘SystemAdmin’); //administrator角色允許使用SystemAdmin資源

//測試權限
//joanne不屬administrator角色….
echo $acl->isAllowed(‘joanne’, ‘SystemAdmin’)?’allowed’:'denined’;     //得到denined

//joanne屬於editor角色…
echo $acl->isAllowed(‘joanne’, ‘ContentManager’)?’allowed’:'denined’;   //得到allowed

上面這段程式碼中,因為joanne這個角色沒有SystemAdmin資源的使用權限,所以以isAllowed方法測試時會得到false。

Zend_Acl 在判斷isAllowed的時候,除了會去看被查的那個角色本身(上例中則為joanne)對資源的存取權限,也會從該角色所屬的角色群來詢問該角色是否 有足夠權限。上例中,其實只是將joanne繼承了editor角色,並沒有直接的定義joanne與ContentManager之間的關係,但因為 editor是有權限可以使用ContentManager,所以joanne也跟著有相同的權限。

不過要特別注意的是,上面的例子中,$group1的前後順序是有差別的,在某些情況下,可能會造成非預期的答案,舉例如下:


$group2 = array(‘editor’, ‘planner’, ‘administrator’);
$acl->addRole(new Zend_Acl_Role(‘eddie’), $group2);
$acl->allow(‘editor’, ‘ContentManager’);  //設定editor可以使用ContentManager
$acl->deny(‘planner’, ‘ContentManager’);   //設定planner不可以使用ContentManager

//測試結果
echo $acl->isAllowed(‘eddie’, ‘ContentManager’)?’allowed’:'denined’;  //得到denined

但如果改一下$group2的順序則會得到不同的結果:

$group2 = array(‘planner’, ‘editor’, ‘administrator’);
echo $acl->isAllowed(‘eddie’, ‘ContentManager’)?’allowed’:'denined’;  //得到allowed

第 一個例子中,因為eddie並沒有”直接”的被定義規則,所以Zend_Acl往它所繼承的上層角色搜尋,它會先搜尋”administrator”角 色,結果沒符合的規則,它會再往下一個”planner”搜尋,發現了”deny”的規則,搜尋結束,回傳false;而第二個例子中,先搜 尋”administrator”角色,然後再搜尋”editor”,發現”allow”的定義,搜尋結束,回傳true。

Zend_Acl在搜尋角色規則時,會在搜尋到第一個有定義規則時回傳答案。

所以如果直接定義如下:

$acl->allow(“eddie”, “ContentManager”);
echo $acl->isAllowed(‘eddie’, ‘ContentManager’)?’allowed’:'denined’;  //得到allowed

如同上面我們規納出來的規則,它在遇到第一個定義時(就是它本身的角色)就回傳true了。

存取控制清單(Access Control List – ACL)的建立
我們在上一段已經可以設定某個帳號有權限可以使用網站的內容管理系統了,但如果還需要更細部的設定,例如企劃部的同仁帳號只能”檢視”文章,編輯部的帳號可以”檢視”及”編輯”文章,主管則有全部的功能。

我們假設把內容管理系統的權限再細分為三種:view、edit、delete

角色 權限
planner view
editor view, edit
manager view, edit, delete

<?php
require_once ‘Zend/Acl.php’;
require_once ‘Zend/Acl/Role.php’;

//建立ACL
$acl = new Zend_Acl();

//建立三個角色 planner、editor及manager
$acl->addRole(new Zend_Acl_Role(‘planner’));
$acl->addRole(new Zend_Acl_Role(‘editor’));
$acl->addRole(new Zend_Acl_Role(‘manager’));

$acl->allow(‘planner’, null, ‘view’);
$acl->allow(‘editor’, null, array(‘view’,'edit’));
$acl->allow(‘manager’, null , array(‘view’, ‘edit’, ‘delete’));

//測試:企劃部能檢視文章?
echo $acl->isAllowed(‘planner’, null, ‘view’) ? “allowed” : “denied”;  //allowed
//測試:企劃部能編輯文章?
echo $acl->isAllowed(‘planner’, null, ‘edit’) ? “allowed” : “denied”;  //denined
//測試:編輯部能編文章?
echo $acl->isAllowed(‘editor’, null, ‘edit’) ?  “allowed” : “denied”;  //allowed
//測試:編輯部能刪除文章?
echo $acl->isAllowed(‘editor’, null, ‘delete’) ?  “allowed” : “denied”; //denined
//測試:主管可刪除文章?
echo $acl->isAllowed(‘manager’, null, ‘delete’) ?  “allowed” : “denied”; //allowed

上面這段程式碼分別對三個角色(planner、editor及manager)定義了使用的權限。如果仔細觀察權限列表,用角色繼承的方式可以更有彈性的完成實作。


//建立三個角色,manager繼承editor,editor繼承planner
$rolePlanner = $acl->addRole(new Zend_Acl_Role(‘planner’);
$roleEditor = $acl->addRole(new Zend_Acl_Role(‘editor’), $rolePlanner);
$roleManager = $acl->addRole(new Zend_Acl_Role(‘manager’), $roleEditor);

//對各別角色定義權限
$acl->allow($rolePlanner, null, ‘view’);
$acl->allow($roleEditor, null, ‘edit’);
$acl->allow($roleManager, null, ‘delete’);

如此一來,雖然editor只有定義了”edit”的權限,但因為它繼承自planner角色,所以它也有”view”的功能,同理,manager則同時擁有繼承別的角色的”view”、”edit”及自己定義的”delete”權限。

更複雜的權限設定
前 面的章節說明了如何定義角色與資源之間的關係,除了指定某帳號可使用某資源外,也可以定義某帳號可以使用該資源的特定功能,如檢視、修改、刪除等。不過我 們可能會遇到更複雜的例子,例如同樣是編輯部的三個同事:eddie、lindsay及jessica,其中eddie負責的是電子報的工作,還偶爾幫忙 lindsay看一下她的電子報有沒有錯字,lindsay負責的是網站最新消息的發布,jessica則是負責網站一般文章的撰寫,所以接下來我們要來 針對內容管理系統這個資源做更細部的權限設定。

我們將上述的角色及工作列一個簡單的表格:

角色 功能 權限
eddie epaper view, edit, send
news view
lindsay news view, edit, publish
jessica content view, edit, publish

程式碼如下:

<?php
require_once ‘Zend/Acl.php’;
require_once ‘Zend/Acl/Role.php’;
require_once ‘Zend/Acl/Resource.php’;
$acl = new Zend_Acl();

//定義三個角色
$acl->addRole(new Zend_Acl_Role(‘eddie’));
$acl->addRole(new Zend_Acl_Role(‘lindsay’));
$acl->addRole(new Zend_Acl_Role(‘jessica’));

//定義三個資源
$acl->add(new Zend_Acl_Resource(‘epaper’));
$acl->add(new Zend_Acl_Resource(‘news’));
$acl->add(new Zend_Acl_Resource(‘content’));

//定義規則
$acl->allow(‘eddie’, ‘epaper’, array(‘view’, ‘edit’, ‘send’));
$acl->allow(‘eddie’, ‘news’, ‘view’);
$acl->allow(‘lindsay’, ‘news’, array(‘view’, ‘edit’, ‘publish’));
$acl->allow(‘jessica’, ‘content’, array(‘view’, ‘edit’, ‘publish’));

//測試:eddie是否可編輯電子報?
echo $acl->isAllowed(‘eddie’, ‘epaper’, ‘edit’) ? “allowed” : “denied”; // allowed
//測試:lindsay是否可編輯網站文章?
echo $acl->isAllowed(‘lindsay’, ‘content’, ‘edit’) ? “allowed” : “denied”; // denied
//測試:jessica是否可發布網站文章?
echo $acl->isAllowed(‘jessica’, ‘content’, ‘publish’) ? “allowed” : “denied”; // allowed

上面這段,我們是針對各別角色來做資源及權限的設定,不過只要人數一多,這樣的做法顯然不切實際,建議就改用之前提到的角色繼承的方式讓它更有彈性。

移除權限
要移除權限設定也是相當容易的,只要用removeAllow()或removeDeny()這兩個方法就行了。

<?php
//..延用上一章節的程式碼..
//移除eddie對電子報的編輯權限
$acl->removeDeny(‘eddie’, ‘epaper’, ‘edit’);
進階應用
一、以資料庫管理ACL
Zend_Acl在角色及資源的權限設定上相當容易,但如果能配合資料庫系統做管理,則可更方便管理每個角色及資源之間之關係。

二、進階權限設定
除了原本Zend_Acl裡定義的角色、資源、權限的關係外,也可以再結合其它程式功能(例如IP白名單),或是只能在限定時間內使用該權限等等設定,使整個權限管控更加安全。

本文主要是參照Zend Framework的官方文件自己試寫的,新手上路難免有誤,若有謬誤還請指教

官方網站上也有附了一段程式碼,有興趣的可以上去看看 :)
http://framework.zend.com/manual/en/zend.acl.advanced.html

http://blog.eddie.com.tw/2008/04/30/zend-framework-zend-acl