分类目录归档:未分类

php测试之phpt文件

phpt文件用于PHP的自动化测试,这是PHP用自己来测试自己的测试数据用例文件。 测试脚本通过执行PHP源码根目录下的run-tests.php,读取phpt文件执行测试。

phpt文件包含 TEST,FILE,EXPECT 等多个段落的文件。在各个段落中,TEST、FILE、EXPECT是基本的段落, 每个测试脚本都必须至少包括这三个段落。其中:

  • TEST段可以用来填写测试用例的名字。
  • FILE段是一个 PHP 脚本实现的测试用例。
  • EXPECT段则是测试用例的期待值。

在这三个基本段落之外,还有多个段落,如作为用例输入的GET、POST、COOKIE等,此类字段最终会赋值给$env变量。 比如,cookie存放在$env[‘HTTP_COOKIE’],$env变量将作为用例中脚本的执行环境。一些主要段落说明如下表所示:

PHP测试脚本中的段落说明

段落名 填充内容 备注
TEST 测试用例名称 必填段落
FILE 测试脚本语句 必填段落。用PHP语言书写的脚本语句。其执行的结果将与 EXPECT* 段的期待结果做对比。
ARGS FILE 段的输入参数 选填段落
SKIPIF 跳过这个测试的条件 选填段落
POST 传入测试脚本的 POST 变量 选填段落。如果使用POST段,建议配合使用SKIPIF段
GET 传入测试脚本的 GET 变量 选填段落。如果使用GET段,建议配合使用SKIPIF段。
POST_RAW 传入测试脚本的POST内容的原生值 选填段落。比如在做文件上传测试时就需要使用此字段来模拟HTTP的POST请求。
COOKIE 传入测试脚本的COOKIE的值 选填段落。最常见的是将PHPSESSID的值传入。
INI 应用于测试脚本的 ini 设置 选填段落。例如 foo=bar 。其值可通过函数 ini_get(string name_entry) 获得。
ENV 应用于测试脚本的环境设置 选填段落。例如做gzip测试,则需要设置环境HTTP_ACCEPT_ENCODING=gzip。
EXPECT 测试脚本的预期结果 相当于测试文件的结果 必填段落
EXPECTF 测试脚本的预期结果 选填段落。可用函数 sscanf() 中的格式表达预期结果 EXPECT 段的变体
EXPECTREGEX 测试脚本的正则预期结果 选填段落。以正则的方式包含多个预期结果,是预期结果EXPECT段的一种变体。
EXPECTHEADERS 测试脚本的预期头部内容 选填段落.测试脚本期待HTTP头部返回,是预期结果EXPECT段的另一种格式。验证过程中会按头部的字段一一比对测试,比如zlib扩展中,如果开启zlib.output_compression, 则在EXPECTHEADERS中包含Content-Encoding: gzip作为预期结果。

phpt文件只是用例文件,它还需要一个控制器来调用这些文件,以实现整个测试过程。 PHP的测试控制器文件是源码根目录下的run-tests.php文件。此文件的作用是根据传入的参数,分析用例相关数据,执行测试过程。 其大概过程如下:

  1. 分析输入的命令行,根据参数配置相关参数,初始化各种信息。
  2. 分析用例输入参数,获取需要执行的用例文件列表。PHP支持指定单文件用例执行,支持多文件用例执行, 支持* .phpt多用例执行,支持* .phpt简化版本多用例执行(相当于.phpt)。
  3. 遍历用例文件列表,执行每一个用例。对于每个用例,PHP会具体解析测试脚本中各个段落的含义, 清除所有上次测试的记录与设置将准备此次的测试环境,并把各种中间文件和日志文件准备好, 然后用环境变量 TEST_PHP_EXECUTABLE 指定的 PHP 可执行对象运行实际的测试语句。 最后将运行后的结果和测试脚本中的预期结果(EXPECT*段)进行比较,如果比较结果一致,则测试通过;如果不一致,则测试失败, 最后将结果信息一一记录到用户设置的日志文件中。
  4. 生成测试结果。

这仅仅是执行的过程,除此之外,还有若干准备和清理工作,如,对上次测试遗留下的环境的清理, 本次测试所必须的环境变量的读取与设置,对测试参数的解析,测试脚本名的解析,各种输出文件的准备等等

以测试脚本/tests/basic/001.phpt为例:

--TEST--
Trivial "Hello World" test
--FILE--
<?php echo "Hello World"?>
--EXPECT--
Hello World

这个用例脚本只包含必填的三项。测试控制器会执行–FILE–下面的PHP文件, 如果最终的输出是–EXPECT–所期望的结果则表示这个测试通过,如果不一致,则测试不通过, 最终这个用例的测试结果会汇总会所有的测试结果集中。

原文:https://github.com/reeze/tipi/blob/248c0ab7f966f10db5bc300c2ae82214cb2010b3/book/E-phpt-file.markdown

多台WEB服务器session共享之NFS配置

session.save_path string

    session.save_path 定义了传递给存储处理器的参数。如果选择了默认的 files 文件处理器,则此值是创建文件的路径。默认为 /tmp。参见 session_save_path()。

    此指令还有一个可选的 N 参数来决定会话文件分布的目录深度。例如,设定为 ‘5;/tmp’ 将使创建的会话文件和路径类似于 /tmp/4/b/1/e/3/sess_4b1e384ad74619bd212e236e52a5a174If。要使用 N 参数,必须在使用前先创建好这些目录。在 ext/session 目录下有个小的 shell 脚本名叫 mod_files.sh,windows 版本是 mod_files.bat 可以用来做这件事。此外注意如果使用了 N 参数并且大于 0,那么将不会执行自动垃圾回收,更多信息见 php.ini。另外如果用了 N 参数,要确保将 session.save_path 的值用双引号 “quotes” 括起来,因为分隔符分号( ;)在 php.ini 中也是注释符号。

    文件储存模块默认使用 mode 600 创建文件。通过 修改可选参数 MODE 来改变这种默认行为: N;MODE;/path ,其中 MODE 是 mode 的八进制表示。 MODE 设置不影响进程的掩码(umask)。

    Warning
        如果将此设定为一个全局可读的目录,例如 /tmp(默认值),服务器上的其他用户有可能通过该目录的文件列表破解会话。
    Caution
        使用以上描述的可选目录层级参数 N 时请注意,对于绝大多数站点,大于1或者2的值会不太合适——因为这需要创建大量的目录:例如,值设置为 3 需要在文件系统上创建 64^3 个目录,将浪费很多空间和 inode。
        仅仅在绝对肯定站点足够大时,才可以设置 N 大于2。

 mod_files.sh

#! /bin/sh

if [[ "$2" = "" ]] || [[ "$3" = "" ]]; then
       echo "Usage: $0 BASE_DIRECTORY DEPTH HASH_BITS"
       echo "BASE_DIRECTORY will be created if it doesn't exist"
       echo "DEPTH must be an integer number >0"
       echo "HASH_BITS(session.hash_bits_per_charactor) should be one of 4, 5, or 6"
       exit 1
fi

if [[ "$2" = "0" ]] && [[ ! "$4" = "recurse" ]]; then
       echo "Can't create a directory tree with depth of 0, exiting."
fi

if [[ "$2" = "0" ]]; then
       exit 0
fi

directory="$1"
depth="$2"
hashbits="$3"

hash_chars="0 1 2 3 4 5 6 7 8 9 a b c d e f"

if [[ "$hashbits" -ge "5" ]]; then
       hash_chars="$hash_chars g h i j k l m n o p q r s t u v"
fi

if [[ "$hashbits" -ge "6" ]]; then
       hash_chars="$hash_chars w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z - ,"
fi

while [[ -d $directory ]] && [[ $( ls $directory ) ]]; do
       echo "Directory $directory is not empty! What would you like to do?"

       options="\"Delete directory contents\" \"Choose another directory\" \"Quit\""
       eval set $options
       select opt in "[email protected]"; do

              if [[ $opt = "Delete directory contents" ]]; then
                     echo "Deleting $directory contents... "
                     rm -rf $directory/*
              elif [[ $opt = "Choose another directory" ]]; then
                     echo "Which directory would you like to choose?"
                     read directory
              elif [[ $opt = "Quit" ]]; then
                     exit 0
              fi

              break;
       done
done

if [[ ! -d $directory ]]; then
       mkdir -p $directory
fi


echo "Creating session path in $directory with a depth of $depth for session.hash_bits_per_character = $hashbits"

for i in $hash_chars; do
       newpath="$directory/$i"
       mkdir $newpath || exit 1
       sh $0 $newpath `expr $depth - 1` $hashbits recurse
done

垃圾回收

; NOTE: If you are using the subdirectory option for storing session files
;       (see session.save_path above), then garbage collection does *not*
;       happen automatically.  You will need to do your own garbage
;       collection through a shell script, cron entry, or some other method.
;       For example, the following script would is the equivalent of
;       setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
;          find /path/to/sessions -cmin +24 | xargs rm

;          find /tmp/php_sess -mmin +30 | xargs rm -fr   

;        crontab, every 30 minutes

;       */30 * * * *  find /path/to/sessions -cmin +24 | xargs rm

;        

NFS的配置详见:http://www.lookafar.net/?p=640

nfs共享session慢的原因

1.nfslock
    使用unlock方式挂载
    mount -o nolock -t nfs 192.168.1.2:/tmp/session/ /tmp/session/
2.open_basedir 的设置问题。
    单机环境去掉即可。或:     ../:./:/tmp:../../

 

NFS常用配置

——————————-
        NFS配置说明
——————————-
//主服务器配置
1.vi /etc/exports
    /opt/test 10.1.1.52(rw)
2.启动服务
    service portmap start
    service nfs start
3.自启动配置
    chkconfig –level 35 portmap on
    chkconfig –level 35 nfs on
    
//从服务器配置
1.启动服务
    service portmap start
    service nfs start
2.自启动配置
    chkconfig –level 35 portmap on
    chkconfig –level 35 nfs on
2.手动挂载
    mount -t nfs -o nolock 10.1.1.52:/opt/test/    /opt/test/
3.自启动挂载
    vi /etc/fstab
        10.1.1.52:/opt/test/    /opt/test/    nfs    defaults 0 0
    vi /etc/rc.local
        mount -t nfs -o nolock 10.1.1.52:/opt/test/    /opt/test/

 

服务器代码部署常用命令

+—————————————-

|   文件上传

+—————————————-

1.sftp
Secure Ftp 是一个基于SSH安全协议的文件传输管理工具。由于它是基于SSH的,会在传输过程中对用户的密码、数据等敏感信息进行加密,因此可以有效的防止用户信息在传输的过程中被窃取,比FTP有更高的安全性。在功能方面与FTP很类似,不仅可以传输文件数据,而且可以进行远程的文件管理(如建立,删除,查看文件列表等操作)。Sftp与ftp虽然只有一字之差,但基于的传输协议却是不同的。因此不能用sftp client去连接ftp server 也不能用 ftp client 去连接 sftp server。

建立连接:sftp [email protected]

从本地上传文件:put localpath

下载文件:get remotepath

与远程相对应的本地操作,只需要在命令前加上”l” 即可,方便好记。

例如:lcd lpwd lmkdir


2.scp
SCP :secure copy (remote file copy program) 也是一个基于SSH安全协议的文件传输命令。与sftp不同的是,它只提供主机间的文件传输功能,没有文件管理的功能。

复制local_file 到远程目录remote_folder下

scp local_file [email protected]:remote_folder

复制local_folder 到远程remote_folder(需要加参数 -r 递归)

scp –r local_folder [email protected]:remote_folder

以上命令反过来写就是远程复制到本地


3.sz/rz
sz/rz 是基于ZModem传输协议的命令。对传输的数据会进行核查,并且有很好的传输性能。使用起来更是非常方便,但前提是window端需要有能够支持ZModem的telnet或者SSH客户端,例如secureCRT。

首先需要在secureCRT中可以配置相关的本地下载和上传目录,然后用rz、sz命令即可方便的传输文件数据。

下载数据到本地下载目录:sz filename1 filename2 …

上传数据到远程:执行rz –be 命令,客户端会弹出上传窗口,用户自行选择(可多选)要上传的文件即可。

php编译相关

1.从5.3开始mysql使用如下参数编译

   –with-mysql=mysqlnd
   –with-mysqli=mysqlnd
   –with-pdo-mysql=mysqlnd

2.完全编译

    
–prefix=/usr/local/php #指定 php 安装目录 

–with-apxs2=/usr/local/apache/bin/apxs #整合apache,apxs功能是使用mod_so中的LoadModule指令,加载指定模块到 apache,要求 apache 要打开SO模块

–with-config-file-path=/usr/local/php/etc #用来指定 php3.ini 或 php4.ini 的路径

–with-MySQL=/usr/local/mysql #mysql安装目录,对mysql的支持

–with-mysqli=/usr/local/mysql/bin/mysql_config #mysqli扩展技术不仅可以调用MySQL的存储过程、处理MySQL事务,而且还可以使访问数据库工作变得更加稳定。 

–with-mysql-sock=/tmp/mysql.sock #指定mysql套接字文件位置

–enable-safe-mode #打开安全模式,默认值是打开的

–disable-short-tags  #配置本选项后,PHP 的程序就不能使用短的标记,一定要用的长标记

–with-exec-dir=DIR  #PHP 执行路径(有时为了系统的安全性考虑,会指定 PHP 程序一定要在哪个目录执行)

–enable-ftp #打开ftp的支持 

–enable-zip #打开对zip的支持 

–with-bz2 #打开对bz2文件的支持 

–with-jpeg-dir #打开对jpeg图片的支持 

–with-png-dir #打开对png图片的支持 

–with-freetype-dir #打开对freetype字体库的支持 

–without-iconv #关闭iconv函数,各种字符集间的转换 

–with-libXML-dir #打开libxml2库的支持 

–with-XMLrpc #打开xml-rpc的c语言 

–with-zlib-dir #打开zlib库的支持 

–with-gd #打开gd库的支持 

–enable-gd-native-ttf #支持TrueType字符串函数库 

–with-curl #打开curl浏览工具的支持 

–with-curlwrappers #运用curl工具打开url流 

–with-ttf #打开freetype1.*的支持,可以不加了 

–with-xsl #打开XSLT 文件支持,扩展了libXML2库 ,需要libxslt软件 

–with-gettext #打开gnu 的gettext 支持,编码库用到 

–with-pear #打开pear命令的支持,PHP扩展用的 

–enable-calendar #打开日历扩展功能 

–enable-mbstring #多字节,字符串的支持

–enable-sqlite-utf8  #使sqllite支持utf-8

–enable-bcmath #打开图片大小调整,用到zabbix监控的时候用到了这个模块

–enable-sockets #打开 sockets 支持

–enable-exif #图片的元数据支持 

–enable-magic-quotes #魔术引用的支持 

–disable-rpath #关闭额外的运行库文件 

–disable-debug #关闭调试模式

–enable-debug  #本选项一般不会使用,除非在开发 PHP 程序时比较有用。它可以显示额外的错误信息 

–with-ldap=DIR  #若要使用目录协议 (Lightweight Directory Access Protocol, LDAP) 则必须要打开本选项。有关 LDAP 的细节,可以参考 RFC 文件的 RFC1777 及 RFC1778

–with-mime-magic=/usr/share/file/magic.mime #魔术头文件位置

–with-apache=DIR   #用本选项可以让 PHP 以apache的模块方式使用,DIR 的字符串可以是 /usr/local/apache 或其它安装apache的目录

–with-custom-odbc=DIR   #使用自订的 ODBC 函数库。当然,在使用本方式时要指定 CUSTOM_ODBC_LIBS 及 CFLAGS 变量。例如在 QNX 机器上使用 Sybase SQL Anywhere 时可能要配置系统环境变量 CFLAGS=-DODBC_QNX、LDFLAGS=-lunix 及 CUSTOM_ODBC_LIBS="-ldblib -lodbc",并要在 PHP 配置加入 –with-custom-odbc=/usr/lib/sqlany50

–with-oracle=DIR    #使用 Oracle 数据库。Oracle 的版本要在 7.3 版以上。您也可以在 PHP 程序中使用环境变量 ORACLE_HOME 来指定 Oracle 的路径。更多有关 Oracle 的信息请参考 Oracle 的网站 http://www.oracle.com

–with-sybase=DIR   #使用 Sybase 数据库。更多有关 Sybase 的信息请参考 Sybase 的网站 http://www.sybase.com

–with-sybase-ct=DIR  #使用 Sybase-CT 数据库

CGI方式安装常用的参数:

–enable-fpm #打上PHP-fpm 补丁后才有这个参数,CGI方式安装的启动程序

–enable-fastCGI #支持fastcgi方式启动PHP

–enable-force-CGI-redirect #重定向方式启动PHP

–with-ncurses #支持ncurses 屏幕绘制以及基于文本终端的图形互动功能的动态库

–enable-pcntl #freeTDS需要用到的,可能是链接mssql 才用到

–with-mcrypt #mcrypt算法的扩展

–with-mhash #mhash算法的扩展

以上函数库需要安装

–with-gmp #应该是支持一种规范

–enable-inline-optimization #优化线程

–with-openssl #openssl的支持,加密传输时用到的

–enable-dbase #建立DBA 作为共享模块

–with-pcre-dir=/usr/local/bin/pcre-config #perl的正则库案安装位置

–disable-dmalloc

–with-gdbm #dba的gdbm支持

–enable-sigchild

–enable-sysvsem

–enable-sysvshm

–enable-zend-multibyte #支持zend的多字节

–enable-mbregex

–enable-wddx

–enable-shmop

–enable-soap

备注:需要单独安装的扩展
1. gd库。
2. ming的扩展。
3. mhash和mcrypt的扩展
1>指定了–with-apxs2=/usr/local/apache/bin/apxs以后,就不要再激活–enable-fpm和–enable-fastCGI,apxs是以php module的模式加载PHP的。
2>Mysql在编译了Mysql开发library以后,可以不用指定mysql的路径。
3>PHP编译存在基础的依赖的关系,编译PHP首先需要安装XML扩展,因为php5核心默认打开了XML的支持,其他的基础库,相应需要:
4>GD -> zlib, Png, Jpg, 如果需要支持其他,仍需要根据实际情况编译扩展库,ttf库需要freetype库的支持。
5>–enable-magic-quotes,是一个极其不推荐的参数,当然,如果你需要PHP为你做这些底下的工作,实际上他也没有很彻底的解决问题。
6>-with-openssl,需要openssl库。
mysqli是MySQL团队提供的MySQL驱动,具有很多实用的功能和典型特征。不过他不是MySQL于PHP平台最好的选择,PDO被证实,是一个简易、高并发性,而且易于创建和回收的标准接口。不过PDO也经历了5.3以前的内存溢出的问题,在5.3以后,在读取Oracle的LOB资源时,若不对内存进行限制,仍会内存溢出。
如果是产品模式,好像pear、shmop、ftp等,都不推荐使用,他们要做的事情,用C/C++,用Java,甚至其他脚本语言,都有很好很快速的选择,无需局限于使用PHP去实现。不熟悉的类库和不常用的库,也不推荐使用。magic-quote、session.auto_start、PHP服务器信息、PHP报错信息等在编译完成后,应该第一时间关闭,避免暴露服务器信息。
PHP对应的Web Server模式,Module、fastcgi、fpm只需要一种即可,服务器不是你的试验田。fastcgi可以选择Nginx和lighttpd,其实Nginx也是使用lighttpd的spwan-fcgi进行fcgi进程管理的。fpm是使用PHP自身去管理多进程,有点类似一个后端代理。无论什么模式,在发布产品服务器,都应该做进程和线程调优,做足够多的性能及压力方面的测试,找出最好的进程数组合。
选好一种PHP OPCode cache的扩展,这个也是很重要的,linux 2.6核心下,fcgi下,xcache有较好的实践经验,其他的在并发数增加以后,性能衰减严重。如果真的想体验,宁可编译多几个PHP版本,也不要针对一个版本的PHP集合各种扩展,适应各种环境,这会让把你自己逼进窘境的。

3.使用phpize编译某一个扩展