php文档更新

php.net最近更新了php文档,比较有用的是新增的pman工具。pman是一个命令行小工具,方便查看php函数的本地帮助文档,但是不包含php.net的评论数据。简单的试用心得如下:

安装pman

使用传说中的pear来安装pman

sudo pear install doc.php.net/pman

如果pear版本比较老,需要先升级pear才可以继续

sudo pear upgrade pear

pman使用方法

pman的使用方法很傻瓜,比如我们想查看strlen的帮助信息:

pman strlen

帮助文本的内容是彩色的,能和chm版本的php帮助文档媲美。pman的详细使用帮助如下

#pman --help
man, version 1.6c

usage: man [-adfhktwW] [section] [-M path] [-P pager] [-S list]
	[-m system] [-p string] name ...

  a : find all matching entries
  c : do not use cat file
  d : print gobs of debugging information
  D : as for -d, but also display the pages
  f : same as whatis(1)
  h : print this help message
  k : same as apropos(1)
  K : search for a string in all pages
  t : use troff to format pages for printing
  w : print location of man page(s) that would be displayed
      (if no name given: print directories that would be searched)
  W : as for -w, but display filenames only

  C file   : use `file' as configuration file
  M path   : set search path for manual pages to `path'
  P pager  : use program `pager' to display pages
  S list   : colon separated section list
  m system : search for alternate system's man pages
  p string : string tells which preprocessors to run
               e - [n]eqn(1)   p - pic(1)    t - tbl(1)
               g - grap(1)     r - refer(1)  v - vgrind(1)

还有一个好处是在vim里查看php帮助信息更方便了,结合完美

:!pman strlen

PHP Namespaces FAQ

PHP Namespaces FAQ,适合没耐心仔细阅读完整README.namespaces的人来看.

Q. Why PHP needs namespaces?
A. Because long names like PEAR_Form_Loader_Validate_Table_Element_Validator_Exception are really tiresome.

Q. What is the main goal of the namespace implementation?
A. To solve the problem above.

Q. What “namespace X::Y::Z” means?
A: 1. All class/function/method names are prefixed with X::Y::Z.
2. All class/function/method names are resolved first against X::Y::Z.

Q. What “import X::Y::Z as Foo” means?
A. Every time there’s Foo as a class/function name or prefix to the name, it really means X::Y::Z

Q. What “import X::Y::Z” means?
A. “import X::Y::Z as Z”, then see above.

Q. What “import Foo” means?
A. Nothing.

Q. What is the scope of namespace and import?
A. Current file.

Q. Can same namespace be used in multiple files?
A. Yes.

Q. Is there any relation between namespaces X::Y::Z and X::Y?
A. Only in programmer’s mind.

Q. How do I import all classes from namespace X::Y::Z into global space?
A. You don’t, since it brings back the global space pollution problem.
Instead, you import X::Y::Z and then prefix your classes with Z::.

Q. But doesn’t it mean I will still have long names?
A. Not longer then three elements: Namespace::Class::Element.

Q. Why it is not implemented like in <insert your favorite language here>?
A. Because PHP is not <insert your favorite language here>

php是否需要namespace,我想第一条理由已经显得很充分了。用过PEAR的可能会对其中超长的class命名印象深刻,所以在PEAR2的Code standing中,也隐约提到可能会利用namespaces以及__autoload来缩短class名。

原文:Namespaces FAQ

关于PEAR的DB和MDB2方法对比

在从前的php4时代,我很喜欢使用pear的DB库,使用非常方便。但是现在pear官方站已经建议我们采用MDB2来代替它,虽然MDB2的前身可能有一些DB的影子,但是使用方法还是有一些不同,这些天一边使用,一边做些笔记。

MDB2 DB
queryAll getAll
queryRow getRow
queryCol getCol
queryOne getOne
autoExecute autoExecute(需要载入extended module)
autoPrepare autoPrepare(需要载入extended module)

其它方法貌似一致。

创建本地的pear

在某些主机上,你可能没有修改系统缺省安装pear的权限,但是又希望安装自己的pear包。这种情况下也有简单的办法实现:

首先在自己的home下创建一份pear的配置文件.pearrc:

$ pear config-create $HOME .pearrc

如果一切顺利的话,直接进行下一步,否则运行一下下列命令:

$ pear config-set download_dir /home/(username)/tmp/pear/cache
$ pear config-set cache_dir /home/(username)/tmp/pear/cache
$ pear config-set temp_dir /home/(username)/tmp/pear/temp

接着就可以开始安装pear了,这会连着pear的依赖文件一块安装:

$ pear install -o PEAR

经过这一步,pear已经安装完成,如果你还希望安装其它的package,那么:

$ pear install pear/PackageName

这样你就有了一份自己定制的pear包,为了在程序中调用到这些pear,你需要多谢写一些额外的代码,毕竟这些代码还不在你的include_path中。

php4

ini_set( 
  'include_path', 
  ini_get( 'include_path' ) . PATH_SEPARATOR . "/home/(youruser)/pear/php"
);    

php5

set_include_path(
	get_include_path() . 
	PATH_SEPARATOR . '/home/(youruser)/pear/php'
);

Pear的PHP_Compat包

Pear的PHP_Compat是个比较有趣的包,它提供了一些php4下也能使用的php5专有函数,比如file_put_contents,array_combine,str_split……….这样即使是在php4的主机上,也能提前享受一点php5函数的便利.

用法

<?php
require_once 'PHP/Compat.php';

// load file_put_contents
PHP_Compat::loadFunction('file_put_contents');

// load str_split, array_chunk and file_get_contents
PHP_Compat::loadFunction(array('str_split', 'array_chunk', 'file_get_contents'));
?>

上面的例子说明,可以一次载入n个php5特有函数

Package Information: PHP_Compat

http://pear.php.net/package/PHP_Compat

Pear::Pager和AJAX的整合应用

作为一个PHP开发人员来说,大概很让人受用的一个东东就是Pear的类库了。我们知道,Pear::Pager是专门处理分页的,而Pear::HTML_AJAX则是Ajax应用的一些类库。但是Pager也不仅仅是只能用于html的分页链接,它已经为比超女还红的Ajax做好了准备,下面看看这两个包如何整合应用。

Pager and Javascript

现在走出第一步,Pager已经能够构建出javascript的链接了,和Ajax整合,理论上应该也是能够实现的,下面是Pager和javascript分页的一个例子:

require_once 'Pager/Pager.php';
$data = range(1, 100); //an array of data to paginate
$pager_params = array(
    'mode'     => 'Sliding',
    'append'   => false,  //don't append the GET parameters to the url
    'path'     => '',
    'fileName' => 'javascript:revealDiv(%d)',  //Pager replaces "%d" with the page number...
    'perPage'  => 10, //show 10 items per page
    'delta'    => 5,
    'itemData' => $data,
);
$pager = & Pager::factory($pager_params);
$n_pages = $pager->numPages();
$links = $pager->getLinks();
?>


    
    


PEAR::Pager example with JavaScript

<?php echo $links['pages']; ?>
<?php for ($i=1; $i < = $n_pages; ++$i) { echo '
'; echo '

Page '.$i.'

'; foreach ($pager->getPageData($i) as $item) { echo 'Item '.$item.'
'; } echo ''; } ?>

例子中把分页的所有数据放入一个div标签,定义了两个比较重要的参数就是path(为空)和fileName,fileName原本应该是链接的文件名,但是这里用javascript替换了。

Ajax上阵

这个例子包括三个文件page.html,server.php,testdata.php
Continue reading “Pear::Pager和AJAX的整合应用”

Pear::Pager分页类简介

PearPager分页类是一个很好用的php分页类,扩展性很强,能够适应各种分页情况的需求,至少我在几年间大大小小的项目里,基本上没有为分页额外写过代码,全部都是用的Pager,足见Pager的可用性之强.下面用代码来看看它的使用范例:

例子1

<?php
require_once 'Pager/Pager.php';
$params = array(
    'mode'       => 'Jumping',
    'perPage'    => 3,
    'delta'      => 2,
    'itemData'   => array('a','b','c','d','e',[...omissis...],'z')
);
$pager = & Pager::factory($params);
$data  = $pager->getPageData();
$links = $pager->getLinks();
//$links is an ordered+associative array with 'back'/'pages'/'next'/'first'/'last'/'all' links
//NB: $links['all'] is the same as $pager->links;

//echo links to other pages:
echo $links['all'];

//Pager can also generate  tags
echo $pager->linkTags;

//Show data for current page:
echo 'PAGED DATA: ' ; print_r($data);

//Results from methods:
echo 'getCurrentPageID()...: '; var_dump($pager->getCurrentPageID());
echo 'getNextPageID()......: '; var_dump($pager->getNextPageID());
echo 'getPreviousPageID()..: '; var_dump($pager->getPreviousPageID());
echo 'numItems()...........: '; var_dump($pager->numItems());
echo 'numPages()...........: '; var_dump($pager->numPages());
echo 'isFirstPage()........: '; var_dump($pager->isFirstPage());
echo 'isLastPage().........: '; var_dump($pager->isLastPage());
echo 'isLastPageComplete().: '; var_dump($pager->isLastPageComplete());
echo '$pager->range........: '; var_dump($pager->range);
?>

Pager的使用,只要调整$param数组的参数,就可以应付很多种分页情况了.代码中的$links数组包含了一些链接,如上一页/页码/下一页/第一页/末页/全部.

例2

如今许多网站为了SEO,把动态页使用rewrite规则伪造成静态页的形式,例如下面这个.htaccess配置:

RewriteEngine on
#Options FollowSymlinks

RewriteBase /
RewriteRule ^articles/([a-z]{1,12})/art([0-9]{1,4})\.html$ /article.php?num=$2&month=$1 [L]

即使在这种情况下,Pager分页仍然有办法工作,见下面的code

<?php
require_once 'Pager/Pager.php';

//first pager
$params1 = array(
    'perPage'    => 3,
    'urlVar'     => pageID_articles,  //1st identifier
    'itemData'   => $someArray
);
$pager1 = & Pager::factory($params1);
$data1  = $pager1->getPageData();
$links1 = $pager1->getLinks();

//second pager
$params2 = array(
    'perPage'    => 8,
    'urlVar'     => pageID_news,      //2nd identifier
    'itemData'   => $someOtherArray
);
$pager2 = & Pager::factory($params2);
$data2  = $pager2->getPageData();
$links2 = $pager2->getLinks();
?>

通过配置$param,就能够把链接 “/articles/march/art15.html”对应到链接”/article.php?num=15&month=march” ,比较灵活的表现

扩展性

Pager类的扩展性,平心而论,也是不错的.比如以前写的path方式的分页类 – Pager::Pathing(),这个方法就是从Pager上扩展而来,满足了当时的需求.

在虚拟主机上复制安装本机Pear

在国内租来的虚拟主机上,有部分主机本身就提供了pear类库,但是不用指望它们会给你升级或安装需要的pear包.在这种情况下,可以尝试在自己的虚拟主机下安装一份pear.

通过ssh安装pear

国内绝大部分虚拟主机都不提供ssh,但若是朋友的服务器,可能会比较放宽一点给你权限.下面看看通过ssh在虚拟主机上安装pear的步骤:

  • PEAR 1.3.5或以下:
    $ pear -s -c ~/.pearrc -d doc_dir=~/pear/docs \
        -d ext_dir=~/pear/ext -d php_dir=~/pear/lib \
        -d data_dir=~/pear/data -d test_dir=~/pear/tests \
        -d cache_dir=~/pear/cache -d bin_dir=~/pear/bin

    PEAR 1.4以上:

    $ pear config-create /home/user/pear .pearrc

    这样就在用户的home下建立了一个.pearrc文件

  • 在.bashrc文件中加入
    PEAR 1.3.2 或以下:

    $ pear -c ~/.pearrc install Archive_Tar PEAR Console_Getopt XML_RPC

    PEAR 1.3.3以上

    $ pear install -o PEAR

    这样就在用户的home目录下新增了一个pear目录,这份pear是完全复制主机上的pear的.

  • 为了使用刚装上的这份pear包,需要在php代码中指定include_path
    <?php
    ini_set('include_path', '~/pear/lib' . PATH_SEPARATOR
            . ini_get('include_path'));
    
    // From PHP 4.3.0 onward, you can use the following,
    // which especially useful on shared hosts:
    set_include_path('~/pear/lib' . PATH_SEPARATOR
                     . get_include_path());
    ?>

通过ftp/ftps/sftp安装pear

通过ftp之类的向远程虚拟主机上安装pear,这无疑是个好主意.主要通过pear的程序包PEAR_RemoteInstaller来完成这功能.有几点要确定:

  • 本机是php 5.0以上
  • 如果需要用ftps安装,那么本机的php需要增加openssl extension
  • 如果需要用ssh安装,那么本机的php需要增加ssh2 extension
  • php目录的pear命令行可执行
  • ftp有写权限

因为时间关系,暂时不写具体步骤了,有需要的朋友可以参考下面的链接.

参考文档:

pear manual

No handlers for package.xml version 2.0

尝试在某主机安装PearDB_Table

pear install -o DB_Table

下载…………………………等了半晌,在下载完之后,本应安装成功的时候,丢出来一句:

No handlers for package.xml version 2.0

这实在是很奇怪的事情,php的xml extension没少装,依赖包也不曾短缺了它的,它怎么就能这样呢?搜索了一把,在Pear的Faq上面找到了答案.

Why do I get “No handlers for package.xml version 2.0” when I try to install a package?

You are using a PEAR version lower than 1.4.0.

To install the package, you have to update PEAR via:

$ pear upgrade PEAR

This will install the latest available version of PEAR which is capable of installing packages that have only a package.xml version 2.0.

在升级Pear为1.4.11之后,问题解决.

Pear::HTTP_Upload简介

Pear的HTTP_Upload类库提供了一个封装好的html表单文件上传处理程序,使用Pear的error系统。

特点

  • 能一次处理多个文件的上传
  • 容易校验文件的上传状态,限制不期望的文件上传
  • 多语种的报错提示信息(还没有中文,不过可以扩展)

单个文件上传的例子

index.htm

File 1:

files.php

<?php
require 'HTTP/Upload.php';
$upload = new HTTP_Upload('es');
// Language for error messages
$file = $upload->getFiles('userfile');
// return a file object or error
if (PEAR::isError($file)) {
	die ($file->getMessage());
}
// Check if the file is a valid upload
if ($file->isValid()) {    // this method will return the name of the file you moved,    
	// useful for example to save the name in a database    
	$file_name = $file->moveTo('./uploads_dir/');
	if (PEAR::isError($file_name)) {  
		die ($file_name->getMessage());
	}
}
?>

多文件上传的例子

Continue reading “Pear::HTTP_Upload简介”