如何撰写pod

简介

pod(Plain Old Documentation), 是一种简单而易用的标记型语言(置标语言),它经常用于在perl程序和模块中的文档书写。

在pod中,用段类型可分为三种,普通段落,字面段落(Verbatim Paragraph)和命令段落。

三者的区分非常简单,以=pod|head1|cut|over等指示字开始的段落为命令段落,以空格或制表符(\t)等缩进字符开始的段落为字面段落,其余的就是普通段落。

pod中有其独特的格式代码来表现粗体,斜体,超链接等。

在pod中,对于字面段落的文本,是从来都不进行格式代码转义的。pod2html时用<pre >将其包围。所以字面段落非常适合在引用语言与代码块时运用。

当然,值得注意的是,对于pod2xxx脚本来说,段落意味着前后各有一个空行

下面我们要介绍的pod,都是用于pod2html这项功能的。

命令指示字

=head1

=head2

=head3

=head4

上面的四个指示字产生指定级别的标题。在pod2html时,用他们各自对应的

..

来包围此段落,并且自动生成a的命名/name和索引/index.

一个简单的例子:

pod2html后NAME的标签为h1, 而后面的那段为p。

=pod

=cut

=pod 只告诉编译器pod文档开始了,而=cut则是pod文档的结束。

一个简单的例子:

=over NUMBER

=item SYMBOL

=back

上面三个标签是连在一起的。=over后面必须要跟一个=back,而这两者之间最少要有一个=item,同时不能有=head1至head4。

pod2html时依据item后面的SYMBOL不同将其转化为<dl><ol><ul>中的一种。

当SYMBOL为数字时使用ol, SYBMOL为*时使用ul, 其余的使用dl.

而=over后面的NUMBER只是用来确定缩进中的空格。不同的格式器(pod2xxxx)对于NUMBER有着不同地处理,另外有些格式器对此则进行忽略。默认的NUMBER为4。

=item 能自动生成a的命名,但不参加索引/index(与head不同)。

一个简单的例子:

此例子摘自perlcn.pod

=for format text =begin format =end format 此指示字的作用是对此段落使用特殊的格式/format(如html, text等)。 =for与=begin+=end作用相同。区别在于=for只处理一个段落,而=begin+=end却能处理它们中间的多个段落。 format为html时,可以用于增加“命令指示字和格式代码”都不能实现的特殊格式。如<img或其它html标签。

一个简单的例子:

pod2html时会原文拷贝此段代码。

=encoding

用于制定文档的编码,默认为不指定。

格式代码

格式代码可以用于除字面段落外的所有段落,包括命令段落。

        

  • I<text> 用斜体表示text, 效果如text
  •     

  • B<text> 用粗体表示text, 效果如text
  •     

  • C<code> pod2html时用<code>包围。
  •     

  • L<text|name/sec> 超链接。 其中name可以为模块名,也可以为一个网址。pod2html时,当name为模块名时,转化为module/name.html.name为a里href参数的内容其中text为连接所显示的内容,若没有text,name为模块名时,显示 the module::name manpage;name为网址时,不允许存在text。pod2html时转化为<a>和</a>之间的东西。    

    sec参数当name为模块名时指向该模块名的sec部分,没有name时指向当前页的sec部分。这些sec部分一般被=head或=item所定义。pod2html时转化为href里的#部分。

        

        

  •     

  • E<escape> 字符转义。    
              

    • E<lt> – <
    •         

    • E<gt> – >
    •         

    • E<verbar> – |
    •         

    • E<sol> – /
    •         

    • 更多的请参考perldoc perlpod
    •     

        

  •     

  • 更多的如F<filename>, S<text>等请参考perldoc perlpod

实例

最后给出一个简单的例子,用以使大家加深对pod的印象。

perldoc & pod2html

pod可以转化为n多种格式。在bin目录下以pod2开头的工具有很多,也有2pod的工具。但最常用的是perldoc和pod2html.

perldoc用于在命令控制台下查看pod文档,而pod2html则把pod转化为html格式。

pod2html

你可以通过pod2html—help来查看pod2html的所有参数。因为所有的参数都是很容易看懂的,也就不多加解释了。

将上面的例子保存为examples.pod, 然后进入控制台/console:

All is Done.

参考

🙂 have fun.

 

相关链接:http://search.cpan.org/~rgarcia/perl-5.10.0/pod/perlpodspec.pod

libmemcache  与 libmemcached

libmemcache 是C语言的操作memcached的客户端的库

libmemcached 好像应该是服务器端需要的库,实际上不是,ldd memcached :发现和libmemcached并没有关系,下面是libmemcached的README:

Hi!

So what is this? It is a library in C for connectinng to memcached servers
(
http://danga.com/memcached/). It is also a collection of utilities designed
to work with memcached.

memcat – Copy the value of a key to standard output
memflush – Flush the contents of your servers.
memrm – Remove a key(s) from the server.
memstat – Dump the stats of your servers to standard output
memslap – Load generation utility (benchmark!)

The utilities are beta quality at this point. The library is in production
in many locations (upwards to 600 nodes). For networks of more then 512
hosts using consistent hashing, you must update the target WHEEL size for
number of hosts * 4 in libmemcached/memcached_constants.h.

Want to contribute? If you write more then three good patches, then I will
just ask you to commit directly to the tree. I am happy to have additional
people work on this project. Please checkout README.FIRST.

You will need a C99 compiler in order to compile this library. Currently we
actively support Linux, MacOSX, FreeBSD, and Solaris. A Windows port is
currently not supported.

If you are looking for answers to your questions please check out the
mailing list at:
http://lists.tangent.org/ 

Subscribe to the libmemcached mailing list found there.

Cheers,
  -Brian Aker
   Seattle, WA.

另外,PHP还有一个自己的操作memcache的模块,它是自己实现的,并不依赖C的那个客户端模块

PHP实现多个异步的http请求

摘自: PHP手册

以前感觉PHP里没法同时执行多个http请求,这次看手册不小心发现了这种用法,就是通过设置非阻塞模式来实现异步的http请求,对于单个脚本中要尽快执行完大量的http请求的应用来讲是非常适合的。

<?php
function multiHTTP ($urlArr) {
    
$sockets = Array(); // socket array!
    
$urlInfo = Array(); // info arr
    
$sumDone 0;
    
$ret = Array();
    
$errno  = Array();
    
$errstr  = Array();
    foreach (
$urlArr as $key=>$url) {
        
$urlInfo[$key] = parse_url($urlArr[$key]);
        
$urlInfo[$key][port] = ($urlInfo[$key][port]) ? $urlInfo[$key][port] : 80;
        
$urlInfo[$key][path] = ($urlInfo[$key][path]) ? $urlInfo[$key][path] : "/";
        
$sockets[$key] = @fsockopen($urlInfo[$key][host], $urlInfo[$key][port], $errno[$key], $errstr[$key], 30);
        if(!
$sockets[$key]){
            
$ret[$key][‘result’] = false;
            
$ret[$key][‘error’]  = $errstr[$key];
            
$ret[$key][‘done’] = 1;
            
$sumDone++;
            continue;
        }
        
$ret[$key][‘result’] = true;
        
socket_set_blocking($sockets[$key],false);
        
$query = ($urlInfo[$key][query]) ? "?" $urlInfo[$key][query] : "";
        
fputs($sockets[$key],"GET " $urlInfo[$key][path] . "$query HTTP/1.0\r\nHost: " .
                        
$urlInfo[$key][host] . "\r\n\r\n");
    }
    
// ok read the data from each one
    
$done false;
    while (!
$done) {
        foreach (
$urlArr as $key=>$url) {
            if(
$ret[$key][‘done’] == 1) continue;
            if (!
feof($sockets[$key])) {
                if (
$ret[$key][‘data’]) {
                        
$ret[$key][‘data’] .= fgets($sockets[$key],1024);
                } else {
                        
$ret[$key][‘data’] = fgets($sockets[$key],1024);
                }
            } else {
                
$ret[$key][‘done’] = 1;
                
$sumDone++;
                
fclose($sockets[$key]);
            }
        }
        
$done = ($sumDone == count($urlArr));
    }
    foreach(
$ret as $key=>$item){
        
$ret[$key][‘data’] = substr($item[‘data’],strpos($item[‘data’],"\r\n\r\n") + 4);
    }
    return 
$ret;
}
?>

PHP 小知识 [ int floor round]

对于正数来讲,(int) 和floor()没有太大区别,都取不大于输入的整数,但是int的正数是强制类型转换出来的,返回值的类型是整型,floor是取整出来的,如果输入是float型,你们返回值还是float型。我们还发现round(1.1) == (int)1.1==floor(1.1);但是round四舍五入的,对于负数来讲,int还是取整数部分,而floor则是小于输入的那个整数;

PHP 加速器eaccelerator 之control.php

PHP 加速器Eaccelerator有一些管理自己的函数,源码中也给我们提供了一个简单的管理脚本control.php,下面就该文件做一下说明:

eAccelerator 0.9.5 control panel

Information

    

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

        

            

            

        

    

Caching enabled yes // 启用了cache
Optimizer enabled yes //启用了优化
Memory usage 0.28% (0.09MB/ 32.00MB) // 显示已用内存的大小(0.09MB)及总大小(32MB)
Free memory 31.91MB // 可用内存的大小
Cached scripts 4 // 已cache的脚本数量
Removed scripts 0 // ?????
Cached keys 0 // ?????

Actions // eAccelerator 的选项不是只能在php.ini中设置的,还可以通过函数来控制,下面就是通过提供的api来动态控制的

    

        

            

                

                

            

            

                

                

            

            

                

                

            

            

                

                

            

            

                

                

            

        

    

Caching // 可以在这里禁用cache
Optimizer // 可以在这里禁用优化
Clear cache // 清掉所有的cache
Clean cache // 清理cache,清理那些已经过期或已被删除但还被cache的脚本
Purge cache // ?????

Cached scripts // 这是已cache的所有脚本

    

        

            

            

            

            

            

        

        

            

            

            

            

            

        

        

            

            

            

            

            

        

        

            

            

            

            

            

        

        

            

            

            

            

            

        

    

Filename MTime Size Reloads Hits
/data1/apache/newbsso/htdocs/junjie2/functions.php 2008-10-12 18:50 8.32 KB 1 (0) 0
/data1/apache/newbsso/htdocs/junjie2/mc.php 2008-10-12 18:49 6.37 KB 1 (0) 0
/data1/apache/newbsso/htdocs/tools/control.php 2008-10-12 20:16 43.62 KB 1 (0) 0
/usr/home/junjie2/smalltools/mc_img.php 2008-10-12 19:15 30.16 KB 1 (0) 0

Removed scripts // ?????

    

        

            

            

            

            

            

        

    

Filename MTime Size Reloads Hits

下面说一下该脚本的使用,下面这个变量需要在php.ini 里设置:

eaccelerator.allowed_admin_path = "/data1/apache/newbsso/htdocs/tools/"

如果control.php 不是在该目录被访问,你们一些api函数不允许被调用,至于设置好了,还需要用户名和密码,最简单的办法是把control.php 的下面代码注释掉:

if (!isset($_SERVER[‘PHP_AUTH_USER’]) || !isset($_SERVER[‘PHP_AUTH_USER’]) ||
$_SERVER[‘PHP_AUTH_USER’] != $user || $_SERVER[‘PHP_AUTH_PW’] != $pw
) {
header(‘WWW-Authenticate: Basic realm="eAccelerator control panel"’
);
header(‘HTTP/1.0 401 Unauthorized’
);
exit;
}

或者在control.php 中把user 和pw设置成自己的用户名、密码就行了

PHP 中memcache连接

php memcache模块版本:

php –re memcache
Extension [ <persistent> extension #28 memcache version <no_version> ] {

今天使用memcache时,发现这么一个问题,使用同一个mc_client对象,依次连接多个memcached,第二个memcached确实进行了连接,但是getStats()时仍然使用的是第一个memcached的连接,如果要依次连接不同的memcached则需要重新new Memcache();
下面是测试脚本

<?php
$arrHosts
= array(‘10.10.10.11’=>‘11211’,‘10.10.10.12’=>‘11211’);

$mc = new Memcache();
echo
serialize($mc)."\n";
foreach(
$arrHosts as $host=>$port) {
echo
‘start ‘.$host."\n";
$mc->connect($host,$port);
echo
serialize($mc)."\n";
$stats = $mc->getStats();
echo
$stats[‘pid’]."\n";
sleep(10);
}
?>

面是strace的部分调用:观察发现两次connect使用的是不同的fd,而send却使用的是同一个fd

1054 fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1),}) = 0
1055 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 1, 0) = 0xb7de9000
1056 write(1, "start 10.10.10.11\n", 18) = 18
1057 socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 3
1058 close(3) = 0
1059 gettimeofday({1223351084, 844527}, NULL) = 0
1060 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3
1061 fcntl64(3, F_GETFL) = 0x2 (flags O_RDWR)
1062 fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
1063 connect(3, {sa_family=AF_INET, sin_port=htons(11211), sin_addr=inet_addr("10.10.10.11")}, 16) = -1 EINPROGRESS (Operation now in progress)
1064 poll([{fd=3, events=POLLIN|POLLOUT|POLLERR|POLLHUP, revents=POLLOUT}], 1, 1000) = 1
1065 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
1066 fcntl64(3, F_SETFL, O_RDWR) = 0
1067 send(3, "stats\r\n", 7, 0) = 7
1068 poll([{fd=3, events=POLLIN|POLLERR|POLLHUP, revents=POLLIN}], 1, 1000) = 1
1069 recv(3, "STAT pid 15727\r\nSTAT uptime 1293", 8192, 0) = 555
1070 write(1, "15727\n", 6) = 6
1071 write(1, "start 10.10.10.12\n", 18) = 18
1072 gettimeofday({1223351084, 845984}, NULL) = 0
1073 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 4
1074 fcntl64(4, F_GETFL) = 0x2 (flags O_RDWR)
1075 fcntl64(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
1076 connect(4, {sa_family=AF_INET, sin_port=htons(11211), sin_addr=inet_addr("10.10.10.12")}, 16) = -1 EINPROGRESS (Operation now in progress)
1077 poll([{fd=4, events=POLLIN|POLLOUT|POLLERR|POLLHUP, revents=POLLOUT}], 1, 1000) = 1
1078 getsockopt(4, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
1079 fcntl64(4, F_SETFL, O_RDWR) = 0
1080 send(3, "stats\r\n", 7, 0) = 7
1081 poll([{fd=3, events=POLLIN|POLLERR|POLLHUP, revents=POLLIN}], 1, 1000) = 1
1082 recv(3, "STAT pid 15727\r\nSTAT uptime 1293", 8192, 0) = 555
1083 write(1, "15727\n", 6) = 6
1084 close(3) = 0
1085 close(4) = 0
1086 close(0
) = 0

下面的php memcache模块是没有问题的

Extension [ <persistent> extension #26 memcache version 2.2.4 ] {

所以,使用php memcache模块时注意版本号哦,

关于代理

代理ip

Variable              Value         
DOCUMENT_ROOT         /data1/apache/sso/htdocs/          
HTTP_ACCEPT             */*          
HTTP_ACCEPT_ENCODING    gzip, deflate          
HTTP_ACCEPT_LANGUAGE    zh-cn          
HTTP_CONNECTION         close          
HTTP_HOST               123.103.65.99          
HTTP_MAX_FORWARDS       10          
HTTP_UA_CPU             x86          
HTTP_USER_AGENT               Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; TencentTraveler )          
HTTP_X_FORWARDED_FOR               10.218.19.130 // 最终的客户端ip         
HTTP_X_FORWARDED_HOST               ljj.com          
HTTP_X_FORWARDED_SERVER               ljj.com          
HTTP_X_REAL_IP               10.218.19.94 // 代理的ip         
PATH   /usr/kerberos/sbin:/usr/kerberos/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/home/junjie2/bin          
REMOTE_ADDR               61.135.152.194 // 代理的出口ip         
REMOTE_PORT               43217                    
SERVER_ADDR               123.103.65.99 // 最终访问的apache服务器的ip          
                 
SERVER_PORT               80          
SERVER_SIGNATURE               <ADDRESS>Apache/1.3.33 Server at login.sina.com.cn:80 Port 80</ADDRESS>          
SERVER_SOFTWARE               Apache/1.3.33 (Unix) PHP/5.1.5 mod_ssl/2.8.24 OpenSSL/0.9.8d          
GATEWAY_INTERFACE               CGI/1.1          
SERVER_PROTOCOL               HTTP/1.0          
REQUEST_METHOD               GET          
QUERY_STRING               no value          
REQUEST_URI               /sso/phpinfo.php          
SCRIPT_NAME               /sso/phpinfo.php 

下面解释一下上面ip的含义:

10.218.19.130 -> 10.218.19.94 -> 123.103.65.99

10.218.19.120 通过代理服务器10.218.19.94访问123.103.65.99 ,服务器正真做tcp连接的server是61.135.152.194,是代理服务器的出口ip,也只有这一个ip是无法伪造的,其它的以HTTP开头的ip都是从http协议头里取的,都是可以伪造的。客户端到服务器中间经过了两次代理 访问的是 10.218.19.94:80 -> 10.218.94.80:81 -> 123.103.65.99

PHP模块mcrypt模块安装

今天想了解一下PHP的加密函数,但是需要mcrypt模块,就自己编译一遍,没想到如此复杂,所以记录下来,也好和大家分享

PHP模块mcrypt安装步骤:

1. 确认是否已安装libmcrypt
ldconfig -p | grep libmcrypt

如果没有安装:
下载地址:http://sourceforge.net/projects/mcrypt
可以同时下载libmcrypt 和 mcrypt
先安装libmcrypt, 默认安装目录为 /usr/local , PHP 手册建议–disable-posix-threads ,不知何故
./configure && make && make install
ldconfig

再安装mcrypt, 默认安装目录为 /usr/local
./configure –with-libmcrypt-prefix=/usr/local

2. 确认是否已安装mhash
ldconfig -p | grep mhash

如果没有安装:
下载地址:http://mhash.sourceforge.net/
./configure && make && make install
ldconfig

3. 现在可以安装mcrypt模块了
cd php-x.x.x/ext/mcrypt
./configure –with-mcrypt=/usr/local/ && make && make install

4. 修改php.ini 就可以了

测试一下:

<?php
// Designate string to be encrypted 
$string "Applied Cryptography, by Bruce Schneier, is a wonderful cryptography reference."

$key "Four score and twenty years ago"
// Encryption/decryption key
$cipher_alg MCRYPT_TWOFISH

$iv=mcrypt_create_iv(mcrypt_get_iv_size($cipher_alg,MCRYPT_MODE_ECB), MCRYPT_RAND
); 
echo 
"Original string: $string \n"
;  
$encrypted_string mcrypt_encrypt($cipher_alg$key$stringMCRYPT_MODE_CBC$iv
); 
echo 
"Encrypted string: ".bin2hex($encrypted_string)."\n"
;
$decrypted_string mcrypt_decrypt($cipher_alg$key

$encrypted_stringMCRYPT_MODE_CBC$iv
); 
echo 
"Decrypted string: $decrypted_string\n"

?>