SlideShare una empresa de Scribd logo
1 de 27
Descargar para leer sin conexión
PHPMORE VOL 5

本期目录
新闻                                                                        2


PHP5 面向对象程序设计之:THIS , SELF 和 PARENT                                       3


PHP5 面向对象程序设计之: STATIC 和 CONST                                            7


PEAR 探奇系列之 PEAR::TEXT_PASSWORD                                            9


PEAR::PEAR 的析构器模拟                                                        16


SMARTY 中 SECTION 的简单使用                                                   18


XMLHTTP 试用手记                                                             23


推荐图书                                                                     26




Editors:
Avenger Binzy Cozo Easy Freeman Happay KnightE RainX Shenkong


Thanks to:



                                                      .


感谢所有关心和支持 PHPMORE 的人,“感谢你们让我们梦想”。




                                                                PHPMORE VOL5
新闻

Zend 和 IBM 合作推出 Zend Core for IBM

PHP 5.0.4 and 4.3.11 Released

PHPMORE.com 改版,推出中文 PHP Blog 聚合服务和 PHP 知识书签服务。欢迎大家到 club.phpe.net 的

PHPMORE 版推荐自己喜爱的 PHP Blog 信息源。

PHPe.net 的论坛已经完成了和 PHP 知识书签的整合,点击帖子中的          图标可以直接将帖子收藏到你的

PHP 知识书签中。




                                                      PHPMORE VOL5 2/26
PHP5 面向对象程序设计之:this , self 和 parent
文/ heiyeluren


PHP5 是一具备了大部分面向对象语言的特性的语言,比 PHP4 有了很多的面向对象的特性,但是有部分概念也比较
绕人,所以今天拿出来说说,说的不好,请高手见谅. (阅读本文,需要了解 PHP5 的面向对象的知识)

首先我们来明白上面三个关键字: this,self,parent,从字面上比较好理解,是指这,自己,父亲,呵呵,比较好玩
了,我们先建立几个概念,这三个关键字分别是用在什么地方呢?我们初步解释一下,this 是指向当前对象的指针
(我们姑且用 C 里面的指针来看吧),self 是指向当前类的指针,parent 是指向父类的指针。我们这里频繁使用指
针来描述,是因为没有更好的语言来表达,呵呵,语文没学好。 -_-#

这么说还不能很了解,那我们就根据实际的例子结合来讲讲。

(1)this

<? Code ?>
1 <?php
2
3 class UserName
4{
5    //定义属性
6    private $name;
7
8    //定义构造函数
9    function __construct( $name )
10     {
11         $this->name = $name; //这里已经使用了 this 指针
12     }
13
14     //析构函数
15     function __destruct(){}
16
17     //打印用户名成员函数
18     function printName()
19     {
20         print( $this->name ); //又使用了 this 指针
21     }
22 }
23
24 //实例化对象
25 $nameObject = new UserName( "heiyeluren" );
                                                    PHPMORE VOL5 3/26
26
27 //执行打印
28 $nameObject->printName(); //输出: heiyeluren
29
30 //第二次实例化对象
31 $nameObject2 = new UserName( "PHP5" );
32
33 //执行打印
34 $nameObject2->printName(); //输出:PHP5
35 ?>


我们看,上面的类分别在 11 行和 20 行使用了 this 指针,那么当时 this 是指向谁呢?其实 this 是在实例化的
时候来确定指向谁,比如第一次实例化对象的时候(25 行),那么当时 this 就是指向$nameObject 对象,那么执
行 18 行的打印的时候就把 print( $this-><name )变成了 print( $nameObject->name ),那么当然就输
出了"heiyeluren"。第二个实例的时候,print( $this->name )变成了 print( $nameObject2->name ),
于是就输出了"PHP5"。所以说,this 就是指向当前对象实例的指针,不指向任何其他对象或类。

(2)self


首先我们要明确一点,self 是指向类本身,也就是 self 是不指向任何已经实例化的对象,一般 self 使用来指向
类中的静态变量。

<? Code ?>
1 <?php
2
3 class Counter
4{
5    //定义属性,包括一个静态变量
6    private static $firstCount = 0;
7    private $lastCount;
8
9    //构造函数
10     function __construct()
11     {
12         $this->lastCount = ++self::$firstCount; //使用 self 来调用静态变量,使
用 self 调用必须使用::(域运算符号)
13     }
14
15     //打印最次数值
16     function printLastCount()
17     {
18         print( $this->lastCount );
19     }
20 }

                                                                         PHPMORE VOL5 4/26
21
22 //实例化对象
23 $countObject = new Counter();
24
25 $countObject->printLastCount(); //输出 1
26
27 ?>


我们这里只要注意两个地方,第 6 行和第 12 行。我们在第二行定义了一个静态变量$firstCount,并且初始值为
0,那么在 12 行的时候调用了这个值得,使用的是 self 来调用,并且中间使用"::"来连接,就是我们所谓的域运
算符,那么这时候我们调用的就是类自己定义的静态变量$frestCount,我们的静态变量与下面对象的实例无关,
它只是跟类有关,那么我调用类本身的的,那么我们就无法使用 this 来引用,可以使用 self 来引用,因为 self
是指向类本身,与任何对象实例无关。换句话说,假如我们的类里面静态的成员,我们也必须使用 self 来调用。

(3)parent


我们知道 parent 是指向父类的指针,一般我们使用 parent 来调用父类的构造函数。
<? Code ?>
1 <?php
2
3 //基类
4 class Animal
5{
6    //基类的属性
7    public $name; //名字
8
9    //基类的构造函数
10     public function __construct( $name )
11     {
12         $this->name = $name;
13     }
14 }
15
16 //派生类
17 class Person extends Animal //Person 类继承了 Animal 类
18 {
19     public $personSex; //性别
20     public $personAge; //年龄
21
22     //继承类的构造函数
23     function __construct( $personSex, $personAge )
24     {
25         parent::__construct( "heiyeluren" ); //使用 parent 调用了父类的
构造函数

                                                                     PHPMORE VOL5 5/26
26         $this->personSex = $personSex;
27         $this->personAge = $personAge;
28     }
29
30     function printPerson()
31     {
32         print( $this->name. " is " .$this->personSex. ",this year
" .$this->personAge );
33     }
34 }
35
36 //实例化 Person 对象
37 $personObject = new Person( "male", "21");
38
39 //执行打印
40 $personObject->printPerson(); //输出:
41
42 ?>


我们注意这么几个细节:成员属性都是 public 的,特别是父类的,是为了供继承类通过 this 来访问。我们注意
关键的地方,第 25 行:parent::__construct( "heiyeluren" ),这时候我们就使用 parent 来调用父类的
构造函数进行对父类的初始化,因为父类的成员都是 public 的,于是我们就能够在继承类中直接使用 this 来调
用。

总结:


this 是指向对象实例的一个指针,self 是对类本身的一个引用,parent 是对父类的引用。




                                                                       PHPMORE VOL5 6/26
PHP5 面向对象程序设计之: static 和 const
文/ heiyeluren


PHP5 中加入了很多面向对象的思想,PHP5 的面向对象比较接近 Java 的面向对象思想。我们这里对 PHP5 中的
static 和 const 关键字作用进行一下描述,希望对学习 PHP5 的朋友有帮助。

(1) static
static 关键字在类中是,描述一个成员是静态的,static 能够限制外部的访问,因为 static 后的成员是属于
类的,是不属于任何对象实例,其他类是无法访问的,只对类的实例共享,能一定程序对该成员尽心保护。类的静
态变量,非常类似全局变量,能够被所有类的实例共享,类的静态方法也是一样的,类似于全局函数。类的静态方
法能访问类的静态的属性。另外说明的是,static 的成员,必须使用 self 来访问,使用 this 会出错。
另外,还有一个比较重要的特点就是,如果一个方法使用了 static,那么这个方法就能够在不需要实例化对象的前
提下直接使用该方法.
(关于 this 和 self 的异同,请参考:
http://blog.csdn.net/heiyeshuwu/archive/2004/11/03/165828.aspx )

(2)const
const 是一个定义常量的关键字,类似于 C 中的#define,能够定义一个常量,如果在程序中改变了它的值,那么
会出现错误。

举例说明上面的代码:(注:以下代码来自 phpe.net)

<? Code ?>
<?php


class Counter
{
    private static $count = 0;//定义一个静态属性
    const VERSION = 2.0;//定义一个常量


    //构造函数
    function __construct()
    {
        self::$count++;
    }


    //析构函数
    function __destruct()
    {
        self::$count--;
                                                    PHPMORE VOL5 7/26
}


     //定义一个静态的方法
     static function getCount()
     {
         return self::$count;
     }
}


//创建一个实例
$c = new Counter();


//执行打印
print( Counter::getCount(). "<br>n" ); //使用直接输入类名来访问静态方
法 Counter::getCount


//打印类的版本
print( "Version useed: " .Counter::VERSION. "<br>n" );


?>




嗯,基本到这里了,心里知道的那点东西就讲清楚了,不过我觉得自己对 static 还有点不理解,等以后慢慢去思

考。




作者信息:

heiyeluren
Email: heiyeluren@163.com
Blog: http://blog.csdn.net/heiyeshuwu




                                                           PHPMORE VOL5 8/26
PEAR 探奇系列之 PEAR::Text_Password
Haohappy/文


上期在介绍 PEAR::Quick_Form 后,收到一些读者来信,希望继续介绍 PEAR 库中的其
它类库。Haohappy 在此作个尝试,在《PHP&More》上开个专栏,今后每一期介绍一个
实用的 PEAR 类,希望大家喜欢。 PEAR 库中目前共有 273 个 package,是全球 PHP 程
序员智慧的结晶,均经过较严格的质量控制,基本上每个 package 都很不错。我选择的原
则主要是两点:1。实用;2。稳定,只选择开发状态为 stable 的版本。如果大家对某个
package 特别感兴趣可以告诉我,将在杂志上优先介绍。
     事实上将来有一些 package 是 Haohappy 也没有在实际开发中使用过的,所以写这
一系列文章的过程将是作者和读者共同学习,                              共同进步的过程,          希望能得到更多同仁的反馈
和鼓励。有任何意见和建议请到超越 PHP 论坛(club.phpe.net)上的《PHP & MORE》杂
志专区提出,或发信至 haohappy@msn.com,我一定会及时回复。
In reality, it is not lazy to want to be able to do things quickly and easily, especially if
they’re things that need to be done often。聪明的人总是懂得利用资源,不会尝试任何工作
都亲自从头做一遍。如果你也和我一样想站在前人的肩膀之上,就跟我来吧。


关于随机密码

系统自动生成随机密码或口令,这是 WEB 程序常见的功能之一。例如这样的注册模式你一定不会感到陌生:当用户
注册时,系统为用户生成一个随机密码并发至其注册邮箱。用户登录自己的邮箱得到系统所给的随机密码后,再登
录系统修改为自己想要的密码。这和直接发送密码到用户邮箱相比,避免了用户密码在网络上的明文传输,大大增
强了系统安全性。随机密码还常用于“忘记密码”功能,用户忘记密码后,系统可以为之自动再生成一个密码。

/*随机字符串的生成还有一个很酷的应用就是验证码,PEAR 中有一个对应的类库 Text_CAPTCHA。目前
Text_CAPTCHA 还只是 Alpha 版本,所以我们暂不讨论,等到 Stable 版本释出后我会向大家介绍。
                                                         Text_CAPTCHA
就基于即将介绍的 Text_Password 开发的。本文中也将会有一个图形验证码的实例,采用 Text_Password+GD
开发。*/

我们在 WEB 开发中生成的密码都是由数字,字母和特殊字符组成的。根据不同的组合方式,密码的类型可以大概分
成纯数字型,纯字母型,纯特殊字符型,数字字母混合型,数字字母特殊字符混合型等。

PEAR::Text_Password 简介
http://pear.php.net/package/Text_Password
   今 天 向 大 家 介 绍 的 PEAR 类 是 PEAR::Text_Password , 可 以 称 之 为 随 机 密 码 生 成 器 。
PEAR::Text_Password 是个比较简单的类,只包含一个 PHP 文件(Password.php),代码连注释在内只有 500
多行。Text_Password 易学易用,功能却相当强大,可以满足 WEB 应用中绝大部份情况下的需求(如果你觉得还
需要定制一些自己的功能,可以将这个类库再开发,相当方便)。

Text_Password 的主要特性如下:
   可创建多种格式的随机密码,如纯字母,纯数字,纯特殊字符及混用型密码;
                                                                                               PHPMORE VOL5 9/26
可自定义密码的长度(字符数);
     可限定密码中只能出现某些字符;
     可一次性创建多个密码;
     创建基于某个字符串的密码(非随机,使用不同算法对字符串进行处理,如翻转)。

   Text_Password 把密码分为 pronounceable(可发音的)和 Unpronounceable(不可发音的)两种类型。
可发音型即纯英文字母型,虽然整个口令不是正常的英文单词,但一般可以划分出音节来发音,有助于记忆,例如
“steagionea”。不可发音型则是混用型,无法发音,如“miC106AIB7”       。显然,可发音型容易记忆而安全性相
对较差,  不可发音型不易记忆但安全性较好。       通常情况下我们不太需要记忆随机密码,         所以选用 Unpronounceable
的情况较常见一些。你可以视实际情况选择。

系统需求:
PHP4.3.* /PHP5
PEAR::Text_Password


使用 Text_Password,实际上我们使用到的只有四个类方法,通过传递不同的参数来生成所需的密码。四个类方
法分别是 create(),createMultiple(),createFromLogin(),createMultipleFromLogin()。下面我们
来举例说明它们的用法。

(1) 创建可发音密码
<? Code - PronounceablePWD.php?>
<?php
require_once "Text/Password.php";


echo "创建 10 个字符的可发音密码....:<BR> ";
echo Text_Password::create(10,'Pronounceable') . "<P>";


echo "创建三个 10 字符的可发音密码...:<BR> ";
print_r(Text_Password::createMultiple(3));
?>




运行结果如图:




在 这 个 程 序 中 , 我 们 使 用 create() 来 创 建 一 个 长 度 为 10 , 类 型 为 pronounceable 的 密 码 ; 使 用
createMultiple()来同时创建三个长度为 10,类型为 pronounceable 的密码密码。


                                                                   PHPMORE VOL5 10/26
(2) 创建不可发音密码

<? Code - UnpronounceablePWD.php?>
<?php
require_once "Text/Password.php";


echo "创建一个 10 字符的不可发音密码....:<BR>";
echo Text_Password::create(10, 'unpronounceable') . "<P>";


echo "创建一个 8 字符且只包含有 a,b,c 的不可发音密码....:<BR>";
echo Text_Password::create(8, 'unpronounceable', 'a,b,c') .
"<P>";


echo "<BR>同时创建 4 个不可发音密码...:n<BR>";
print_r(Text_Password::createMultiple(4,                  10,
'unpronounceable'));
echo "<P>";


echo "创建一个长度为 8 的只含有数字的不可发音密码:<BR>";
echo Text_Password::create(8, 'unpronounceable', 'numeric') .
"<P>";


echo "创建一个长度为 8 的只包含数字或字母的不可发音密码::<BR>";


echo      Text_Password::create(8,         'unpronounceable',
'alphanumeric') . "<P>";
?>




运行结果如图:




                                                                PHPMORE VOL5 11/26
在这个程序中,我们仍然使用的是 create()和 createMultiple()两个类方法,但是在传递参数时使用的是
unpronounceable。

好,看过以上两个例子后,你应该大概知道如何使用 create()和 createMultiple()两个类方法了。create()
有三个参数,分别是密码长度,密码类型和密码组成。

具体用法请参看源代码:
http://cvs.php.net/co.php/pear/Text_Password/Password.php?r=1.12


(2) 创建基于某个字符串的密码
有时候我们希望得到的密码不完全随机,而是有一定规律的。我们希望根据我们所给的字符来获得最终的密码。这
样有个好处就是可以将密码还原成明文,只要我们知道算法。

Text_Password 内建了一些算法来对字符串进行处理。有以下几种算法(或可称操作)
                                            :

     •   xor
     •   rotx
     •   rotx++
     •   rotx--
     •   ascii_rotx
     •   ascii_rotx++
     •   ascii_rotx--
     •   shuffle
     •   reverse

<? Code - GivenStrPWD.php ?>
<?php
require_once "Text/Password.php";


echo "n 密码原文为: 'haohappy', 加密方法为: 'reverse',<BR>加密结果为:
";
echo Text_Password::createFromLogin('haohappy', 'reverse') . "<P>";


echo "n 密码原文为 'haohappy', 加密方法为: 'rot13',<BR>加密结果为:";
echo Text_Password::createFromLogin('haohappy', 'rot13') . "<P>";


echo "n 密码原文为 'haohappy', 加密方法为: 'rotx',<BR>加密结果为:";
echo Text_Password::createFromLogin('haohappy', 'rotx', 13) . "<P>";


echo "n 密码原文为 'haohappy', 加密方法为: 'rotx++',<BR>加密结果为:";
echo Text_Password::createFromLogin('haohappy', 'rotx++', 13) . "<P>";


echo "n 密码原文为 'haohappy', 加密方法为: 'rotx--',<BR>加密结果为:";
echo Text_Password::createFromLogin('haohappy', 'rotx--', 13) . "<P>";
                                                                         PHPMORE VOL5 12/26
echo "n 密码原文为 'haohappy', 加密方法为: 'xor',<BR>加密结果为:";
echo Text_Password::createFromLogin('haohappy', 'xor', 5) . "<P>";
echo "n 密码原文为 'haohappy', 加密方法为: 'ascii_rotx',<BR>加密结果为:
";
echo Text_Password::createFromLogin('haohappy', 'ascii_rotx', 5) . "<P>";
echo "n 密码原文为 'haohappy', 加密方法为: 'ascii_rotx++',<BR>加密结果为:
";
echo Text_Password::createFromLogin('haohappy', 'ascii_rotx++', 5) . "<P>";
echo "n 密码原文为 'haohappy', 加密方法为: 'ascii_rotx--',<BR>加密结果为:
";
echo Text_Password::createFromLogin('haohappy', 'ascii_rotx--', 5) . "<P>";
echo "n 密码原文为 'haohappy', 加密方法为: 'shuffle',<BR>加密结果为:";
echo Text_Password::createFromLogin('haohappy', 'shuffle', 1) . "<P>";
echo "n<b>密码组</b>原文为: 'haohappy', 'martin', 'vanhoucke', 'jansen', 加密
方法为: 'reverse':n";
$logins = array('haohappy', 'martin', 'vanhoucke', 'jansen');
echo "结果如下:<pre>";
print_r(Text_Password::createMultipleFromLogin($logins, 'reverse'));
echo "</pre>";
?>


运行结果如图:
你可以按 F5 刷新几次,会发现除了 Shuffle 操作(打乱)之外,其它结果都是固定不变,也即非随机的。




                                                                              PHPMORE VOL5 13/26
以上即 Text_Password 的三个主要应用,相信你已经初步掌握。
应用实例――图形验证码:

下面 Haohappy 将给出一个应用实例,那就是大家都非常熟悉的图形验证码。虽然只是一个简单的例子,却是一个
完整的验证码程序的核心部份。思路是采用随机的背景图,再用不同的颜色写上随机字符串。

首先,我们准备三个图形背景文件,分别命名为 bg1.png,bg2.png,bg3.png,放在 images 目录下。




代码如下:

<? Code - ImageCode.php?>
<?php
      require_once "Text/Password.php";
     $string = Text_Password::create(10, 'pronounceable');


      $num = rand(1,3);
      header("Content-type: image/png");
    $im = imagecreatefrompng("images/bg$num.png");


     switch ($num) {
     case 1:
       $orange = imagecolorallocate($im, 253, 238, 227);      //字体颜色
       break;
     case 2:
       $orange = imagecolorallocate($im, 255, 204, 51);
       break;
     case 3:
       $orange = imagecolorallocate($im, 255,255,200);
       break;
}


     $px = (imagesx($im) - 7.5 * strlen($string)) / 2; //位置
     imagestring($im, 5, $px-3, 2, $string, $orange);   //写上随机字符串
     imagepng($im);
     imagedestroy($im);
?>

                                                                       PHPMORE VOL5 14/26
运行结果如下:




左图为随机码类型 pronounceable,右图为 unpronounceable
使用 Text_Password 的好处就在这里,可以非常方便地使用你想要的随机码类型。

程序非常简单,只有二十多行,但功能算是相当强大,想使用程序进行边缘识别不那么容易,安全性较高。
至少比腾讯网站上 QQ 免费注册的那个验证码强多了:) 当然你也可以再加入随机杂点,画线,使用随机字体,旋
转等等(如果有必要的话)   。你可以在网页中加入<IMAGE SRC='imagetest2.php'>来引用该验证码,配合
Session,就可以在用户登录时进行图形验证码认证。具体不详述,没什么难度。


如果对几个图像函数不熟悉,请自行查阅 PHP 手册。


参考资料:
End-user Documentation and API documentation of PEAR::Text_Password




                                                                      PHPMORE VOL5 15/26
PEAR::PEAR 的析构器模拟
EasyChen / 文


Pear 是 Pear 的基类,其中提供了 Pear 类的一些基本服务,主要包括

    o    析构器的模拟
    o    错误处理机制

这里我们说析构器的模拟 。虽然 PHP4 中的 class 是没有析构器的,但是所有扩展自 Pear 的 class,都会在程序
结束时调用_classname()函数来析构。很神奇是吧,我们就来看看 pear 是怎么做到的。

首先,我们需要在构造器中调用$this->Pear()方法,实际上运行的是如下代码:

<? Code ?>
$classname = get_class($this);
if ($this->_debug) {
print "PEAR constructor called, class=$classnamen";
}
if ($error_class !== null) { $this->_error_class = $error_class;
}
while ($classname) { $destructor = "_$classname";
if (method_exists($this, $destructor)) {
global                                 $_PEAR_destructor_object_list;
$_PEAR_destructor_object_list[] = &$this;
break;
} else { $classname = get_parent_class($classname);
}
}


可以看到,Pear 取得了当前对象的 class 名,然后开始拼接出析构器的名称_classname,接着调用 method_exists
方法察看当前对象是否存在着方法,如果存在,把这个对以引用方式推入一个数组。从这个数组的名字上我们就可
以知道,析构时 pear 将遍历这个数组中的对象并调用其析构方法。

需要注意的是,这里为什么会使用一个数组。实际上,pear 用 while 语句制造了一个类似递归的效果。当当前对象
没有析构器时,pear 会去找它的父类的析构器,直到找到为止。

现在剩下的就是一个问题了,如何在程序执行完时触发这个析构过程?

要明白这一点,需要先了解一个函数 register_shutdown_function。这个函数可以添加一个函数,使 php 在脚本
运行结束前,调用它。可以注册多个函数,调用的顺序和注册的顺序一致。

pear 的代码里边有这么一句。
                                                                        PHPMORE VOL5 16/26
register_shutdown_function("_PEAR_call_destructors");

显然,_PEAR_call_destructors 就是那个析构过程了,代码和 Pear()有些类似。

<? Code ?>
function _PEAR_call_destructors()
{
global $_PEAR_destructor_object_list;
if (is_array($_PEAR_destructor_object_list) &&
sizeof($_PEAR_destructor_object_list))
{ reset($_PEAR_destructor_object_list);
while (list($k, $objref) = each($_PEAR_destructor_object_list))
{ $classname = get_class($objref);
while ($classname) { $destructor = "_$classname";
if (method_exists($objref, $destructor)) { $objref->$destructor();
break;
} else { $classname = get_parent_class($classname);
}
}
} // Empty the object list to ensure that destructors are
// not called more than once. $_PEAR_destructor_object_list = array();
} // Now call the shutdown functions if
(is_array($GLOBALS['_PEAR_shutdown_funcs'])
AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) {
foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value)
{ call_user_func_array($value[0], $value[1]);
}
}
}


总结一下,Pear 在初始化时建立了需要析构的对象数组,并利用了 register_shutdown_function 触发析构函数,

_PEAR_call_destructors,从而完美的模拟了析构过程。




                                                                         PHPMORE VOL5 17/26
Smarty 中 section 的简单使用

翟翔/文



什么是 section?
就像在 Smarty 官方手册里提到的,模板 section 是用来循环数组里的数据的。所有的 section 标签必须和

/section 标签成对儿使用。必须使用的参数是 name 和 loop。section 的 name 可以随你所好,可以是由字母、

数字和下划线组成的。section 可以嵌套使用,互相嵌套的 section 它们的 name 必须与众不同。变量 loop(通

常是数组的值)决定着 section 将要循环的次数。当用 section 显示一个变量时,section 的 name 必须紧跟

在变量名的后面,并用中括号 [] 括起来。当 loop 变量没有值时,sectionelse 就会运行。

下面就是一个 name 为 left_block,loop 为$LEFT_BLOCK_BODY 的 section,注意到<div

class=”left_block”></div>当中显示变量的方法了么?section 的 name 也就是 left_block 紧跟在

$LEFT_BLOCK_BODY 的后面,并用中括号 [] 括起来了。


<{section name=left_block loop=$LEFT_BLOCK_BODY}>

<div class="left_block"><{$LEFT_BLOCK_BODY[left_block]}></div>

<{/section}>



为什么要使用 section?

就像 phpBB2 的成员列表,如下图,显示的内容
当你设计成员列表时(如图 1 所示)
                 ,你要用到 section。




                                             (图 1)
因为你无法确认有多少个用户注册,即使确认就 100 个限制用户注册,用传统的 table 设计网页你需要作的是牲

口般的工作,所以把这些交给 section 来处理吧。

其实还有很多地方可以用到 section。比如用 div 来作网页布局的时候,左、中、右区域的区块儿和模块儿都是

由后台数据库的 block management 来管理的,网页设计者根本就不知这些动态浮动的区块儿、模块儿在什么地

方、什么时候、什么样式、什么内容出现,或者这些区块儿和模块儿压根儿就不让你看见(管理员控制面板对一般

用户就是隐藏的),section 可以轻松地管理登陆框、导航栏、新闻发布、谁在线、语言选择等区块儿和模块儿。


如何使用 section?

                                                                 PHPMORE VOL5 18/26
Smarty 中的 section 和 PHPLib 中 template 的 block 很相似, section 更为 smart。
                                                  但                 如果你使用过 PHPLib

的 block 很快你就会过渡到 section,如果你以前压根儿就没有听说过这些事儿, 反而更容易掌握 section 的

概念,因为什么都不知道嘛。Just kidding^_^

来个简单的导航栏元素设计的例子。传统的导航栏设计很实诚(如图 2 所示),




                                               (图 2)
有多少个链接就用 dreamweaver 设计几个,有千千万万个怎么办呢?而且还要随时变化怎么办呢?你只用设计一

个链接其他的就让 section 去循环显示好了。 dreamweaver 设计一个名为 navigation.htm 的页面
                         用                                     (只保留
了 table 当中要用到的元素,其余的 html 元素在不影响显示的前提下均以省略)
                                          ,如下面 html 代码。


<table width="100%"   border="0" cellspacing="0" cellpadding="0">

 <tr>

   <td><h2><{$L_TITLE_NAVIGATION}></h2></td>

 </tr>

 <{section name=navigation loop=$l_navigation}>

 <tr>

   <td><img src="<{$IMG_DOT}>" width="12" height="12">

   <a

href="<{$u_navigation[navigation]}>"><{$l_navigation[navigation]}></a></td>

 </tr>

 <{/section}>

</table>



其中<a href="<{$u_navigation[navigation]}>"></a>就定义了超链接变量,

<{$l_navigation[navigation]}>就定义了超链接的名称,用<{section name=navigation

loop=$l_navigation}>和<{/section}>框住要循环显示的部分,一个自动化的导航栏的表现层就设计好了。

(请参看 MVC 模型)

光有皮肤没有骨架是支撑不起导航栏来的,所以让我们看看如何用 PHP 代码控制显示导航栏的。写一个名为

navigation.php 的 PHP 文件,代码如下:
                                                                              PHPMORE VOL5 19/26
$template->assign("l_navigation", array(

     //要在其他地方给$lang[' …… ']负值

     $lang['index'],

     $lang['your_account'],

     $lang['downloads'],

     $lang['submit_news'],

     $lang['topics'],

     $lang['top10']

     )

);



$template->assign("u_navigation",array(

     "./index.php",

     "./modules.php?name=Your_Account",

     "./modules.php?name=Downloads",

     "./modules.php?name=Submint_News",

     "./modules.php?name=Topics",

     "./modules.php?name=Top10"

     )

);



你肯定要惊叹:“really?”真的是这么简单呀^_^

首先,$template->assign 是在调用 Smarty 的 smarty 类当中的 assign 函数,assign 的意思就是赋值、分

配、指派的意思。$template->assign 给 navigation.htm 网页模板中的 l_navigation 变量赋了一个数组,

并提供了 6 个变量型的数组值(你要在其他地方给它们负值,或者直接像给超链接地址负值一样用" …… "的形式)

——用来显示超链接的名称,其中的数组键值用 PHP 默认的 0、1、2……就省略了;还给 u_navigation 变量赋了一

个数组,相对称的也是 6 个但已给出数值的变量——用来定义超链接的去向(其中运用了参数?name 来判断转向哪个

模块儿)。你可能会产生疑问:循环的次数在哪里定义的?loop 变量名仅仅是$l_navigation 数组呀!如果你有

机会查看 Smarty 的代码,你会发现 loop = count($l_navigation),只是这个过程被封装了,你只用调用这

个 section 接口就 OK 了。



然后,利用 smarty 类当中的 display 函数,就可以运行 navigation.php 查看你的导航栏了
                                                          PHPMORE VOL5 20/26
$template->display(“navigation.htm”);



进一步使用 section
就像我前面提到的,section 主要在处理多个重复其不断变化的元素上优势明显。这里由于篇幅有限,就把思想和

大家共享,把未完善的内容留给以后的文章。变化的数据来源于数据库,那么在$template->assign 一个 section

变量的时候可以用到 DB(是 PEAR 提供的对多种数据库操作的集成度很高的类,可以一次编写标准的 SQL 语句在大

多数主流数据库上到处运行)和 section 的综合利用。

在网页中显示居于左侧的区块儿和模块儿


$sql = "SELECT block_value FROM sirtoozee_blocks

     WHERE block_side = 'left' and block_visble = 'true'

     ORDER BY 'weight ";

//用 getCol 这个 API 可以得到一维数组$block = array('','',...)

$block_value = $db->getCol($sql);

$template->assign("LEFT_BLOCK_BODY", $block_value)



你可以 print_r($block_value)看看$block_value 这个数组结构是不是就是 array('' …… '', ... )的

结构一模一样。其中具体的 DB 类的使用和网页 layout 布局我会在以后的文章中详细讲解。



如果大家对调用 Smarty 不熟悉,我在这里也简单介绍安装配置 Smarty 的方法:

到 http://smarty.php.net 下载 stable 版本的 smarty,将压缩包里./libs 文件夹里的所有文件解压缩到

Smarty(需要自己新建)文件夹中,并将你设计的网页模板文件,如 navigation.htm 放在 templates(需要

自己新建)文件夹下,还需要为 Smarty 新建 config、cache、templates_c 文件夹用来编译生成临时文件,

最后形成如下的文件目录结构:

./

./Smarty/internals

./Smarty/plugins

./Smarty/Config_File.class

./Smarty/debug

./Smarty/Smarty.class

./Smarty/Smarty_Compiler.class

./templates

                                                           PHPMORE VOL5 21/26
./templates_c

./config

./cache

用如下代码调用 Smarty 类



//

//模板引擎配置,采用 smarty-2.6.6

//

include("./Smarty/Smarty.class.php");

$template = new Smarty;

//安装并配置 Smarty 模板引擎

$template->template_dir = "./templates/ ";

$template->compile_dir = "./templates_c";

$template->config_dir = "./configs";

$template->cache_dir = "./cache";

//为了和 javascript 标签区别开来

$template->left_delimiter = "<{";

$template->right_delimiter = "}>";



您可以通过如下方式和作者翟翔联系
Email:legendren2008@yahoo.com.cn




                                             PHPMORE VOL5 22/26
XmlHttp 试用手记
EasyChen / 文


什么是 XmlHttp

Xmlhttp 是一种浏览器对象,可用于模拟 http 的 GET 和 POST 请求。配合 JavaScript 可以实现页面数据在无
刷新下的定时数据更新,如果应用在聊天室、文字直播上可以取得较好的视觉效果。

IE 中的 XmlHttp 对象

在 IE 中 XmlHttp 被实现为 ActiveX 对象,通常使用

var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");


来创建一个对象,然后使用该对象的 open 方法来发出一个 Http 请求。

xmlhttp.open("GET", fragment_url);


这时候浏览器已经发出了 Http 请求,我们需要注册一个匿名函数给 XmlHttp 对象的 onreadystatechange 方
法,这样当请求返回时,xmlhttp 就会自动调用我们注册的这个函数,下边是一个实际的例子。

xmlhttp.onreadystatechange = function()
{
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
    {
        element.innerHTML = xmlhttp.responseText;
    }
}


因为我们不需要再发送任何信息,所以用下边的语句结束

xmlhttp.send(null);


我们将上边的过程封装为一个函数,下边是这个函数的完整代码:

function loadFragmentInToElement(fragment_url, element_id)
{
    var element = document.getElementById(element_id);
    var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");


    xmlhttp.open("GET", fragment_url);
                                                             PHPMORE VOL5 23/26
xmlhttp.onreadystatechange = function()
    {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
            {
                element.innerHTML = xmlhttp.responseText;
        }
    }
    xmlhttp.send(null);


}


函数的调用方法如下所示:

loadFragmentInToElement(       'http://domain.com/url.php' , DynamicContent_id );


有了上边的代码,再配合 JavaScript 的定时函数,我们就可以实现定时的无刷新数据更新了,下边这个函数每隔
5 秒对 element_id 的数据进行一次更新。

function refresh( element_id )
{
    loadFragmentInToElement(       'show.php' , '' + element_id );
    setTimeout( "refresh('ts')" , 5000 );
}


在 IE 上使用 XmlHttp 要注意的问题

特别要注意的是由于 IE 的 Cache 的关系,我们看见的 XmlHttp 并不总是最新读取的那一个,为了让 IE 不启用
Cache,我们发送给 IE 一个特殊的 Header,用 PHP 实现如下:

header( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" );
header( "Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . "GMT" );
header( "Cache-Control: no-cache, must-revalidate" );
header( "Pragma: no-cache" );


XmlHttp 对象在 Gecko 上的实现

Gecko 上的 XmlHttp 和 IE 上略有不同,它并不需要通过 ActiveX 来创建。另外回调函数必须在 open 方法之前
注册,而 IE 并不要求,这是一个很需要注意的问题。

使用 JavaScript 实现 XmlHttp 的跨浏览器应用

为了能在多种浏览器上有一个统一的实现,我们可以用 JavaScript 来对不同浏览器的差异进行封装。这里我们采
用 Andrew Gregory 的实现。首先我们要引用 Andrew Gregory 的一个名为 xmlhttprequest.js 的 Js 脚本。

                                                                                    PHPMORE VOL5 24/26
<script type="text/javascript" src="xmlhttprequest.js"></script>


然后在创建 XmlHttp 对象时统一使用 new XMLHttpRequest()就可以了;其它的方法不用改变。这个 Js 脚本允
许 我 们 在 IE 、 Gecko ( Mozilla/FireFox ) 和 Opera 的 特 定 版 本 使 用 XmlHttp 。 下 边 是 调 整 后 的
loadFragmentInToElement 函数,这个函数在 IE6 和 FireFox1.0pre 上运行通过。

<script type="text/javascript" src="xmlhttprequest.js"></script>
<script>
function loadFragmentInToElement(fragment_url, element_id)
{
    var element = document.getElementById(element_id);


    var xmlhttp = new XMLHttpRequest();


    xmlhttp.onreadystatechange = function()
    {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
            {
                element.innerHTML = xmlhttp.responseText;
        }
    }
    xmlhttp.open("GET", fragment_url);
    xmlhttp.send(null);
}
</script>


xmlhttprequest.js 文件和具体的使用例子可以在我写的一个 DEMO 中找到。

XmlHttp 中的中文乱码问题
在默认情况下,   XmlHttp 都是使用 Utf-8 字符集, 而我们使用的多是 GB2312 字符集,      这就要求我们进行 GB2312
到 Utf-8 的转码。PHP 提供了一个可选的专码模块,可以实现多种字符集之间的相互转化。加载这个专码模块的方
法如下:
打开 PHP 配置文件 php.ini,将 ;extension=php_mbstring.dll(*nix 是 php_mbstring.so) 前的分
号去掉。重新启动 Apache 以后,这个模块就可以使用了。如果有错误出现,请检查扩展目录的路径设置是否正确。
加载这个模块以后,我们就可以使用 mb_convert_encoding 函数来转码了:

$utf8_string = mb_convert_encoding(       $gb_string , 'UTF-8' , 'GB2312'   );



将转码后的字符输出就可以看见正确显示的中文了。




                                                                                 PHPMORE VOL5 25/26
推荐图书




 著名的 J2ee 核心模式,最近原书第   李维的新作,对于面向对象的初学者              《程序员修炼之道》同系列的书,深
二版的中文版出来了,书不错,翻译       和 Delphi For dotnet 的用户来说很不   入浅出的讲解了 JUNIT 的使用。
得也不错。                  错,Delphi 也开始 UT 和 TDD 了




                                                            PHPMORE VOL5 26/26

Más contenido relacionado

La actualidad más candente

PHP & MySQL 教學
PHP & MySQL 教學PHP & MySQL 教學
PHP & MySQL 教學Bo-Yi Wu
 
Learning python in the motion picture industry by will zhou
Learning python in the motion picture industry   by will zhouLearning python in the motion picture industry   by will zhou
Learning python in the motion picture industry by will zhouWill Zhou
 
Free Marker中文文档
Free Marker中文文档Free Marker中文文档
Free Marker中文文档yiditushe
 
Python学习笔记
Python学习笔记Python学习笔记
Python学习笔记Lingfei Kong
 
Symfony簡介
Symfony簡介Symfony簡介
Symfony簡介Ricky Su
 
Php设计模式介绍
Php设计模式介绍Php设计模式介绍
Php设计模式介绍cyf5513
 
Groovy简介
Groovy简介Groovy简介
Groovy简介profeter
 
自然语言处理 中文分词程序实验报告%28含源代码%29
自然语言处理 中文分词程序实验报告%28含源代码%29自然语言处理 中文分词程序实验报告%28含源代码%29
自然语言处理 中文分词程序实验报告%28含源代码%29aemoe
 
滲透測試基本技巧與經驗分享
滲透測試基本技巧與經驗分享滲透測試基本技巧與經驗分享
滲透測試基本技巧與經驗分享WEI CHIEH CHAO
 
PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在
PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在
PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在Asika Simon
 
Python 入门
Python 入门Python 入门
Python 入门kuco945
 
Moodle 项目帮助手册:程序编写准则
Moodle 项目帮助手册:程序编写准则Moodle 项目帮助手册:程序编写准则
Moodle 项目帮助手册:程序编写准则YUCHENG HU
 
Swift 程序语言介绍
Swift 程序语言介绍Swift 程序语言介绍
Swift 程序语言介绍明 李
 
第7章预编译命令
第7章预编译命令第7章预编译命令
第7章预编译命令summerfeng
 
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VMCompiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VMLi Hsuan Hung
 
PHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming SkillsPHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming SkillsHo Kim
 
iPhone,ios,Object-C基础入门
iPhone,ios,Object-C基础入门iPhone,ios,Object-C基础入门
iPhone,ios,Object-C基础入门Lucien Li
 

La actualidad más candente (20)

PHP & MySQL 教學
PHP & MySQL 教學PHP & MySQL 教學
PHP & MySQL 教學
 
Learning python in the motion picture industry by will zhou
Learning python in the motion picture industry   by will zhouLearning python in the motion picture industry   by will zhou
Learning python in the motion picture industry by will zhou
 
Free Marker中文文档
Free Marker中文文档Free Marker中文文档
Free Marker中文文档
 
Python学习笔记
Python学习笔记Python学习笔记
Python学习笔记
 
Symfony簡介
Symfony簡介Symfony簡介
Symfony簡介
 
Php设计模式介绍
Php设计模式介绍Php设计模式介绍
Php设计模式介绍
 
Groovy简介
Groovy简介Groovy简介
Groovy简介
 
自然语言处理 中文分词程序实验报告%28含源代码%29
自然语言处理 中文分词程序实验报告%28含源代码%29自然语言处理 中文分词程序实验报告%28含源代码%29
自然语言处理 中文分词程序实验报告%28含源代码%29
 
滲透測試基本技巧與經驗分享
滲透測試基本技巧與經驗分享滲透測試基本技巧與經驗分享
滲透測試基本技巧與經驗分享
 
PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在
PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在
PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在
 
Python 入门
Python 入门Python 入门
Python 入门
 
Moodle 项目帮助手册:程序编写准则
Moodle 项目帮助手册:程序编写准则Moodle 项目帮助手册:程序编写准则
Moodle 项目帮助手册:程序编写准则
 
Swift 程序语言介绍
Swift 程序语言介绍Swift 程序语言介绍
Swift 程序语言介绍
 
第7章预编译命令
第7章预编译命令第7章预编译命令
第7章预编译命令
 
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VMCompiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
Compiler for Dummy 一點都不深入的了解 Compiler, Interpreter 和 VM
 
Vim Hacks
Vim HacksVim Hacks
Vim Hacks
 
PHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming SkillsPHP Coding Standard and 50+ Programming Skills
PHP Coding Standard and 50+ Programming Skills
 
Json知识分享
Json知识分享Json知识分享
Json知识分享
 
iPhone,ios,Object-C基础入门
iPhone,ios,Object-C基础入门iPhone,ios,Object-C基础入门
iPhone,ios,Object-C基础入门
 
ios分享
ios分享ios分享
ios分享
 

Destacado

Paras Multi Location Functionality
Paras Multi Location FunctionalityParas Multi Location Functionality
Paras Multi Location FunctionalityAnshuman Kumar
 
Presentazione Paese Slovacchia
Presentazione Paese SlovacchiaPresentazione Paese Slovacchia
Presentazione Paese SlovacchiaItaloblog
 
Salute e Consumatori Direzione Generale (DG SANCO)
Salute e Consumatori Direzione Generale (DG SANCO)Salute e Consumatori Direzione Generale (DG SANCO)
Salute e Consumatori Direzione Generale (DG SANCO)Italoblog
 
Economia del settore agro-alimentare: eccellenti caratteristiche in Emilia-Ro...
Economia del settore agro-alimentare: eccellenti caratteristiche in Emilia-Ro...Economia del settore agro-alimentare: eccellenti caratteristiche in Emilia-Ro...
Economia del settore agro-alimentare: eccellenti caratteristiche in Emilia-Ro...Italoblog
 
Sv kand eurcrisis_ba_23052012
Sv kand eurcrisis_ba_23052012Sv kand eurcrisis_ba_23052012
Sv kand eurcrisis_ba_23052012Italoblog
 
La isla blanca
La isla blancaLa isla blanca
La isla blancaroshemarie
 
Tsok may 2012 ita
Tsok may 2012 itaTsok may 2012 ita
Tsok may 2012 itaItaloblog
 
Tax seminar 2015 italiano
Tax seminar 2015   italianoTax seminar 2015   italiano
Tax seminar 2015 italianoItaloblog
 
Service Projects
Service ProjectsService Projects
Service ProjectsAnn Gregson
 
Ppt Presentation With Photo
Ppt Presentation With PhotoPpt Presentation With Photo
Ppt Presentation With Photogueste44a64b
 
Echipa Brumm La Inundatii
Echipa Brumm La InundatiiEchipa Brumm La Inundatii
Echipa Brumm La Inundatiiancaradu
 
Open Source Adoption Challenges in the Enterprise
Open Source Adoption Challenges in the EnterpriseOpen Source Adoption Challenges in the Enterprise
Open Source Adoption Challenges in the EnterpriseVenkat Mangudi
 

Destacado (20)

Globalvillage11
Globalvillage11Globalvillage11
Globalvillage11
 
Paras Multi Location Functionality
Paras Multi Location FunctionalityParas Multi Location Functionality
Paras Multi Location Functionality
 
Presentazione Paese Slovacchia
Presentazione Paese SlovacchiaPresentazione Paese Slovacchia
Presentazione Paese Slovacchia
 
Salute e Consumatori Direzione Generale (DG SANCO)
Salute e Consumatori Direzione Generale (DG SANCO)Salute e Consumatori Direzione Generale (DG SANCO)
Salute e Consumatori Direzione Generale (DG SANCO)
 
Economia del settore agro-alimentare: eccellenti caratteristiche in Emilia-Ro...
Economia del settore agro-alimentare: eccellenti caratteristiche in Emilia-Ro...Economia del settore agro-alimentare: eccellenti caratteristiche in Emilia-Ro...
Economia del settore agro-alimentare: eccellenti caratteristiche in Emilia-Ro...
 
Sv kand eurcrisis_ba_23052012
Sv kand eurcrisis_ba_23052012Sv kand eurcrisis_ba_23052012
Sv kand eurcrisis_ba_23052012
 
La isla blanca
La isla blancaLa isla blanca
La isla blanca
 
Amaguestu330
Amaguestu330Amaguestu330
Amaguestu330
 
Tsok may 2012 ita
Tsok may 2012 itaTsok may 2012 ita
Tsok may 2012 ita
 
Paras Healthcare
Paras HealthcareParas Healthcare
Paras Healthcare
 
Tax seminar 2015 italiano
Tax seminar 2015   italianoTax seminar 2015   italiano
Tax seminar 2015 italiano
 
Ti
TiTi
Ti
 
Apuntes urinario
Apuntes urinarioApuntes urinario
Apuntes urinario
 
Me voy ha comprar un coche
Me voy ha comprar un cocheMe voy ha comprar un coche
Me voy ha comprar un coche
 
Service Projects
Service ProjectsService Projects
Service Projects
 
Ppt Presentation With Photo
Ppt Presentation With PhotoPpt Presentation With Photo
Ppt Presentation With Photo
 
Brad birds tips on compositing
Brad birds tips on compositingBrad birds tips on compositing
Brad birds tips on compositing
 
Echipa Brumm La Inundatii
Echipa Brumm La InundatiiEchipa Brumm La Inundatii
Echipa Brumm La Inundatii
 
Open Source Adoption Challenges in the Enterprise
Open Source Adoption Challenges in the EnterpriseOpen Source Adoption Challenges in the Enterprise
Open Source Adoption Challenges in the Enterprise
 
Nativity Story
Nativity StoryNativity Story
Nativity Story
 

Similar a Php More

Python速成指南
Python速成指南Python速成指南
Python速成指南March Liu
 
HITCON CTF 2014 BambooFox 解題心得分享
HITCON CTF 2014 BambooFox 解題心得分享HITCON CTF 2014 BambooFox 解題心得分享
HITCON CTF 2014 BambooFox 解題心得分享Chong-Kuan Chen
 
Py ladies 0928
Py ladies 0928Py ladies 0928
Py ladies 0928Yen_CY
 
PHPUnit + Xdebug 单元测试技术
PHPUnit + Xdebug 单元测试技术PHPUnit + Xdebug 单元测试技术
PHPUnit + Xdebug 单元测试技术hoopchina
 
Java Script 引擎技术
Java Script 引擎技术Java Script 引擎技术
Java Script 引擎技术bigqiang zou
 
Lamp高性能设计
Lamp高性能设计Lamp高性能设计
Lamp高性能设计锐 张
 
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘Liu Allen
 
學好 node.js 不可不知的事
學好 node.js 不可不知的事學好 node.js 不可不知的事
學好 node.js 不可不知的事Ben Lue
 
2006 recycle opensourceprojects
2006 recycle opensourceprojects2006 recycle opensourceprojects
2006 recycle opensourceprojectsGeorge Ang
 
Recycle Open Source Projects
Recycle Open Source ProjectsRecycle Open Source Projects
Recycle Open Source ProjectsGeorge Ang
 
[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來
[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來
[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來Shengyou Fan
 
OpenWebSchool - 02 - PHP Part I
OpenWebSchool - 02 - PHP Part IOpenWebSchool - 02 - PHP Part I
OpenWebSchool - 02 - PHP Part IHung-yu Lin
 
Android C Library: Bionic 成長計畫
Android C Library: Bionic 成長計畫Android C Library: Bionic 成長計畫
Android C Library: Bionic 成長計畫Kito Cheng
 
Talking about exploit writing
Talking about exploit writingTalking about exploit writing
Talking about exploit writingsbha0909
 
Vim hacks
Vim hacksVim hacks
Vim hacksXuYj
 
Phalcon the fastest php framework 阿土伯
Phalcon   the fastest php framework 阿土伯Phalcon   the fastest php framework 阿土伯
Phalcon the fastest php framework 阿土伯Hash Lin
 
Phalcon phpconftw2012
Phalcon phpconftw2012Phalcon phpconftw2012
Phalcon phpconftw2012Rack Lin
 

Similar a Php More (20)

Python速成指南
Python速成指南Python速成指南
Python速成指南
 
HITCON CTF 2014 BambooFox 解題心得分享
HITCON CTF 2014 BambooFox 解題心得分享HITCON CTF 2014 BambooFox 解題心得分享
HITCON CTF 2014 BambooFox 解題心得分享
 
Py ladies 0928
Py ladies 0928Py ladies 0928
Py ladies 0928
 
Py ladies 0928
Py ladies 0928Py ladies 0928
Py ladies 0928
 
PHPUnit + Xdebug 单元测试技术
PHPUnit + Xdebug 单元测试技术PHPUnit + Xdebug 单元测试技术
PHPUnit + Xdebug 单元测试技术
 
Java Script 引擎技术
Java Script 引擎技术Java Script 引擎技术
Java Script 引擎技术
 
Lamp高性能设计
Lamp高性能设计Lamp高性能设计
Lamp高性能设计
 
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘
课题一:PHP5.3、PHP5.4的特性介绍与深度挖掘
 
學好 node.js 不可不知的事
學好 node.js 不可不知的事學好 node.js 不可不知的事
學好 node.js 不可不知的事
 
2006 recycle opensourceprojects
2006 recycle opensourceprojects2006 recycle opensourceprojects
2006 recycle opensourceprojects
 
Recycle Open Source Projects
Recycle Open Source ProjectsRecycle Open Source Projects
Recycle Open Source Projects
 
getPDF.aspx
getPDF.aspxgetPDF.aspx
getPDF.aspx
 
getPDF.aspx
getPDF.aspxgetPDF.aspx
getPDF.aspx
 
[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來
[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來
[Modern Web 2016] 讓你的 PHP 開發流程再次潮起來
 
OpenWebSchool - 02 - PHP Part I
OpenWebSchool - 02 - PHP Part IOpenWebSchool - 02 - PHP Part I
OpenWebSchool - 02 - PHP Part I
 
Android C Library: Bionic 成長計畫
Android C Library: Bionic 成長計畫Android C Library: Bionic 成長計畫
Android C Library: Bionic 成長計畫
 
Talking about exploit writing
Talking about exploit writingTalking about exploit writing
Talking about exploit writing
 
Vim hacks
Vim hacksVim hacks
Vim hacks
 
Phalcon the fastest php framework 阿土伯
Phalcon   the fastest php framework 阿土伯Phalcon   the fastest php framework 阿土伯
Phalcon the fastest php framework 阿土伯
 
Phalcon phpconftw2012
Phalcon phpconftw2012Phalcon phpconftw2012
Phalcon phpconftw2012
 

Php More

  • 1.
  • 2. PHPMORE VOL 5 本期目录 新闻 2 PHP5 面向对象程序设计之:THIS , SELF 和 PARENT 3 PHP5 面向对象程序设计之: STATIC 和 CONST 7 PEAR 探奇系列之 PEAR::TEXT_PASSWORD 9 PEAR::PEAR 的析构器模拟 16 SMARTY 中 SECTION 的简单使用 18 XMLHTTP 试用手记 23 推荐图书 26 Editors: Avenger Binzy Cozo Easy Freeman Happay KnightE RainX Shenkong Thanks to: . 感谢所有关心和支持 PHPMORE 的人,“感谢你们让我们梦想”。 PHPMORE VOL5
  • 3. 新闻 Zend 和 IBM 合作推出 Zend Core for IBM PHP 5.0.4 and 4.3.11 Released PHPMORE.com 改版,推出中文 PHP Blog 聚合服务和 PHP 知识书签服务。欢迎大家到 club.phpe.net 的 PHPMORE 版推荐自己喜爱的 PHP Blog 信息源。 PHPe.net 的论坛已经完成了和 PHP 知识书签的整合,点击帖子中的 图标可以直接将帖子收藏到你的 PHP 知识书签中。 PHPMORE VOL5 2/26
  • 4. PHP5 面向对象程序设计之:this , self 和 parent 文/ heiyeluren PHP5 是一具备了大部分面向对象语言的特性的语言,比 PHP4 有了很多的面向对象的特性,但是有部分概念也比较 绕人,所以今天拿出来说说,说的不好,请高手见谅. (阅读本文,需要了解 PHP5 的面向对象的知识) 首先我们来明白上面三个关键字: this,self,parent,从字面上比较好理解,是指这,自己,父亲,呵呵,比较好玩 了,我们先建立几个概念,这三个关键字分别是用在什么地方呢?我们初步解释一下,this 是指向当前对象的指针 (我们姑且用 C 里面的指针来看吧),self 是指向当前类的指针,parent 是指向父类的指针。我们这里频繁使用指 针来描述,是因为没有更好的语言来表达,呵呵,语文没学好。 -_-# 这么说还不能很了解,那我们就根据实际的例子结合来讲讲。 (1)this <? Code ?> 1 <?php 2 3 class UserName 4{ 5 //定义属性 6 private $name; 7 8 //定义构造函数 9 function __construct( $name ) 10 { 11 $this->name = $name; //这里已经使用了 this 指针 12 } 13 14 //析构函数 15 function __destruct(){} 16 17 //打印用户名成员函数 18 function printName() 19 { 20 print( $this->name ); //又使用了 this 指针 21 } 22 } 23 24 //实例化对象 25 $nameObject = new UserName( "heiyeluren" ); PHPMORE VOL5 3/26
  • 5. 26 27 //执行打印 28 $nameObject->printName(); //输出: heiyeluren 29 30 //第二次实例化对象 31 $nameObject2 = new UserName( "PHP5" ); 32 33 //执行打印 34 $nameObject2->printName(); //输出:PHP5 35 ?> 我们看,上面的类分别在 11 行和 20 行使用了 this 指针,那么当时 this 是指向谁呢?其实 this 是在实例化的 时候来确定指向谁,比如第一次实例化对象的时候(25 行),那么当时 this 就是指向$nameObject 对象,那么执 行 18 行的打印的时候就把 print( $this-><name )变成了 print( $nameObject->name ),那么当然就输 出了"heiyeluren"。第二个实例的时候,print( $this->name )变成了 print( $nameObject2->name ), 于是就输出了"PHP5"。所以说,this 就是指向当前对象实例的指针,不指向任何其他对象或类。 (2)self 首先我们要明确一点,self 是指向类本身,也就是 self 是不指向任何已经实例化的对象,一般 self 使用来指向 类中的静态变量。 <? Code ?> 1 <?php 2 3 class Counter 4{ 5 //定义属性,包括一个静态变量 6 private static $firstCount = 0; 7 private $lastCount; 8 9 //构造函数 10 function __construct() 11 { 12 $this->lastCount = ++self::$firstCount; //使用 self 来调用静态变量,使 用 self 调用必须使用::(域运算符号) 13 } 14 15 //打印最次数值 16 function printLastCount() 17 { 18 print( $this->lastCount ); 19 } 20 } PHPMORE VOL5 4/26
  • 6. 21 22 //实例化对象 23 $countObject = new Counter(); 24 25 $countObject->printLastCount(); //输出 1 26 27 ?> 我们这里只要注意两个地方,第 6 行和第 12 行。我们在第二行定义了一个静态变量$firstCount,并且初始值为 0,那么在 12 行的时候调用了这个值得,使用的是 self 来调用,并且中间使用"::"来连接,就是我们所谓的域运 算符,那么这时候我们调用的就是类自己定义的静态变量$frestCount,我们的静态变量与下面对象的实例无关, 它只是跟类有关,那么我调用类本身的的,那么我们就无法使用 this 来引用,可以使用 self 来引用,因为 self 是指向类本身,与任何对象实例无关。换句话说,假如我们的类里面静态的成员,我们也必须使用 self 来调用。 (3)parent 我们知道 parent 是指向父类的指针,一般我们使用 parent 来调用父类的构造函数。 <? Code ?> 1 <?php 2 3 //基类 4 class Animal 5{ 6 //基类的属性 7 public $name; //名字 8 9 //基类的构造函数 10 public function __construct( $name ) 11 { 12 $this->name = $name; 13 } 14 } 15 16 //派生类 17 class Person extends Animal //Person 类继承了 Animal 类 18 { 19 public $personSex; //性别 20 public $personAge; //年龄 21 22 //继承类的构造函数 23 function __construct( $personSex, $personAge ) 24 { 25 parent::__construct( "heiyeluren" ); //使用 parent 调用了父类的 构造函数 PHPMORE VOL5 5/26
  • 7. 26 $this->personSex = $personSex; 27 $this->personAge = $personAge; 28 } 29 30 function printPerson() 31 { 32 print( $this->name. " is " .$this->personSex. ",this year " .$this->personAge ); 33 } 34 } 35 36 //实例化 Person 对象 37 $personObject = new Person( "male", "21"); 38 39 //执行打印 40 $personObject->printPerson(); //输出: 41 42 ?> 我们注意这么几个细节:成员属性都是 public 的,特别是父类的,是为了供继承类通过 this 来访问。我们注意 关键的地方,第 25 行:parent::__construct( "heiyeluren" ),这时候我们就使用 parent 来调用父类的 构造函数进行对父类的初始化,因为父类的成员都是 public 的,于是我们就能够在继承类中直接使用 this 来调 用。 总结: this 是指向对象实例的一个指针,self 是对类本身的一个引用,parent 是对父类的引用。 PHPMORE VOL5 6/26
  • 8. PHP5 面向对象程序设计之: static 和 const 文/ heiyeluren PHP5 中加入了很多面向对象的思想,PHP5 的面向对象比较接近 Java 的面向对象思想。我们这里对 PHP5 中的 static 和 const 关键字作用进行一下描述,希望对学习 PHP5 的朋友有帮助。 (1) static static 关键字在类中是,描述一个成员是静态的,static 能够限制外部的访问,因为 static 后的成员是属于 类的,是不属于任何对象实例,其他类是无法访问的,只对类的实例共享,能一定程序对该成员尽心保护。类的静 态变量,非常类似全局变量,能够被所有类的实例共享,类的静态方法也是一样的,类似于全局函数。类的静态方 法能访问类的静态的属性。另外说明的是,static 的成员,必须使用 self 来访问,使用 this 会出错。 另外,还有一个比较重要的特点就是,如果一个方法使用了 static,那么这个方法就能够在不需要实例化对象的前 提下直接使用该方法. (关于 this 和 self 的异同,请参考: http://blog.csdn.net/heiyeshuwu/archive/2004/11/03/165828.aspx ) (2)const const 是一个定义常量的关键字,类似于 C 中的#define,能够定义一个常量,如果在程序中改变了它的值,那么 会出现错误。 举例说明上面的代码:(注:以下代码来自 phpe.net) <? Code ?> <?php class Counter { private static $count = 0;//定义一个静态属性 const VERSION = 2.0;//定义一个常量 //构造函数 function __construct() { self::$count++; } //析构函数 function __destruct() { self::$count--; PHPMORE VOL5 7/26
  • 9. } //定义一个静态的方法 static function getCount() { return self::$count; } } //创建一个实例 $c = new Counter(); //执行打印 print( Counter::getCount(). "<br>n" ); //使用直接输入类名来访问静态方 法 Counter::getCount //打印类的版本 print( "Version useed: " .Counter::VERSION. "<br>n" ); ?> 嗯,基本到这里了,心里知道的那点东西就讲清楚了,不过我觉得自己对 static 还有点不理解,等以后慢慢去思 考。 作者信息: heiyeluren Email: heiyeluren@163.com Blog: http://blog.csdn.net/heiyeshuwu PHPMORE VOL5 8/26
  • 10. PEAR 探奇系列之 PEAR::Text_Password Haohappy/文 上期在介绍 PEAR::Quick_Form 后,收到一些读者来信,希望继续介绍 PEAR 库中的其 它类库。Haohappy 在此作个尝试,在《PHP&More》上开个专栏,今后每一期介绍一个 实用的 PEAR 类,希望大家喜欢。 PEAR 库中目前共有 273 个 package,是全球 PHP 程 序员智慧的结晶,均经过较严格的质量控制,基本上每个 package 都很不错。我选择的原 则主要是两点:1。实用;2。稳定,只选择开发状态为 stable 的版本。如果大家对某个 package 特别感兴趣可以告诉我,将在杂志上优先介绍。 事实上将来有一些 package 是 Haohappy 也没有在实际开发中使用过的,所以写这 一系列文章的过程将是作者和读者共同学习, 共同进步的过程, 希望能得到更多同仁的反馈 和鼓励。有任何意见和建议请到超越 PHP 论坛(club.phpe.net)上的《PHP & MORE》杂 志专区提出,或发信至 haohappy@msn.com,我一定会及时回复。 In reality, it is not lazy to want to be able to do things quickly and easily, especially if they’re things that need to be done often。聪明的人总是懂得利用资源,不会尝试任何工作 都亲自从头做一遍。如果你也和我一样想站在前人的肩膀之上,就跟我来吧。 关于随机密码 系统自动生成随机密码或口令,这是 WEB 程序常见的功能之一。例如这样的注册模式你一定不会感到陌生:当用户 注册时,系统为用户生成一个随机密码并发至其注册邮箱。用户登录自己的邮箱得到系统所给的随机密码后,再登 录系统修改为自己想要的密码。这和直接发送密码到用户邮箱相比,避免了用户密码在网络上的明文传输,大大增 强了系统安全性。随机密码还常用于“忘记密码”功能,用户忘记密码后,系统可以为之自动再生成一个密码。 /*随机字符串的生成还有一个很酷的应用就是验证码,PEAR 中有一个对应的类库 Text_CAPTCHA。目前 Text_CAPTCHA 还只是 Alpha 版本,所以我们暂不讨论,等到 Stable 版本释出后我会向大家介绍。 Text_CAPTCHA 就基于即将介绍的 Text_Password 开发的。本文中也将会有一个图形验证码的实例,采用 Text_Password+GD 开发。*/ 我们在 WEB 开发中生成的密码都是由数字,字母和特殊字符组成的。根据不同的组合方式,密码的类型可以大概分 成纯数字型,纯字母型,纯特殊字符型,数字字母混合型,数字字母特殊字符混合型等。 PEAR::Text_Password 简介 http://pear.php.net/package/Text_Password 今 天 向 大 家 介 绍 的 PEAR 类 是 PEAR::Text_Password , 可 以 称 之 为 随 机 密 码 生 成 器 。 PEAR::Text_Password 是个比较简单的类,只包含一个 PHP 文件(Password.php),代码连注释在内只有 500 多行。Text_Password 易学易用,功能却相当强大,可以满足 WEB 应用中绝大部份情况下的需求(如果你觉得还 需要定制一些自己的功能,可以将这个类库再开发,相当方便)。 Text_Password 的主要特性如下: 可创建多种格式的随机密码,如纯字母,纯数字,纯特殊字符及混用型密码; PHPMORE VOL5 9/26
  • 11. 可自定义密码的长度(字符数); 可限定密码中只能出现某些字符; 可一次性创建多个密码; 创建基于某个字符串的密码(非随机,使用不同算法对字符串进行处理,如翻转)。 Text_Password 把密码分为 pronounceable(可发音的)和 Unpronounceable(不可发音的)两种类型。 可发音型即纯英文字母型,虽然整个口令不是正常的英文单词,但一般可以划分出音节来发音,有助于记忆,例如 “steagionea”。不可发音型则是混用型,无法发音,如“miC106AIB7” 。显然,可发音型容易记忆而安全性相 对较差, 不可发音型不易记忆但安全性较好。 通常情况下我们不太需要记忆随机密码, 所以选用 Unpronounceable 的情况较常见一些。你可以视实际情况选择。 系统需求: PHP4.3.* /PHP5 PEAR::Text_Password 使用 Text_Password,实际上我们使用到的只有四个类方法,通过传递不同的参数来生成所需的密码。四个类方 法分别是 create(),createMultiple(),createFromLogin(),createMultipleFromLogin()。下面我们 来举例说明它们的用法。 (1) 创建可发音密码 <? Code - PronounceablePWD.php?> <?php require_once "Text/Password.php"; echo "创建 10 个字符的可发音密码....:<BR> "; echo Text_Password::create(10,'Pronounceable') . "<P>"; echo "创建三个 10 字符的可发音密码...:<BR> "; print_r(Text_Password::createMultiple(3)); ?> 运行结果如图: 在 这 个 程 序 中 , 我 们 使 用 create() 来 创 建 一 个 长 度 为 10 , 类 型 为 pronounceable 的 密 码 ; 使 用 createMultiple()来同时创建三个长度为 10,类型为 pronounceable 的密码密码。 PHPMORE VOL5 10/26
  • 12. (2) 创建不可发音密码 <? Code - UnpronounceablePWD.php?> <?php require_once "Text/Password.php"; echo "创建一个 10 字符的不可发音密码....:<BR>"; echo Text_Password::create(10, 'unpronounceable') . "<P>"; echo "创建一个 8 字符且只包含有 a,b,c 的不可发音密码....:<BR>"; echo Text_Password::create(8, 'unpronounceable', 'a,b,c') . "<P>"; echo "<BR>同时创建 4 个不可发音密码...:n<BR>"; print_r(Text_Password::createMultiple(4, 10, 'unpronounceable')); echo "<P>"; echo "创建一个长度为 8 的只含有数字的不可发音密码:<BR>"; echo Text_Password::create(8, 'unpronounceable', 'numeric') . "<P>"; echo "创建一个长度为 8 的只包含数字或字母的不可发音密码::<BR>"; echo Text_Password::create(8, 'unpronounceable', 'alphanumeric') . "<P>"; ?> 运行结果如图: PHPMORE VOL5 11/26
  • 13. 在这个程序中,我们仍然使用的是 create()和 createMultiple()两个类方法,但是在传递参数时使用的是 unpronounceable。 好,看过以上两个例子后,你应该大概知道如何使用 create()和 createMultiple()两个类方法了。create() 有三个参数,分别是密码长度,密码类型和密码组成。 具体用法请参看源代码: http://cvs.php.net/co.php/pear/Text_Password/Password.php?r=1.12 (2) 创建基于某个字符串的密码 有时候我们希望得到的密码不完全随机,而是有一定规律的。我们希望根据我们所给的字符来获得最终的密码。这 样有个好处就是可以将密码还原成明文,只要我们知道算法。 Text_Password 内建了一些算法来对字符串进行处理。有以下几种算法(或可称操作) : • xor • rotx • rotx++ • rotx-- • ascii_rotx • ascii_rotx++ • ascii_rotx-- • shuffle • reverse <? Code - GivenStrPWD.php ?> <?php require_once "Text/Password.php"; echo "n 密码原文为: 'haohappy', 加密方法为: 'reverse',<BR>加密结果为: "; echo Text_Password::createFromLogin('haohappy', 'reverse') . "<P>"; echo "n 密码原文为 'haohappy', 加密方法为: 'rot13',<BR>加密结果为:"; echo Text_Password::createFromLogin('haohappy', 'rot13') . "<P>"; echo "n 密码原文为 'haohappy', 加密方法为: 'rotx',<BR>加密结果为:"; echo Text_Password::createFromLogin('haohappy', 'rotx', 13) . "<P>"; echo "n 密码原文为 'haohappy', 加密方法为: 'rotx++',<BR>加密结果为:"; echo Text_Password::createFromLogin('haohappy', 'rotx++', 13) . "<P>"; echo "n 密码原文为 'haohappy', 加密方法为: 'rotx--',<BR>加密结果为:"; echo Text_Password::createFromLogin('haohappy', 'rotx--', 13) . "<P>"; PHPMORE VOL5 12/26
  • 14. echo "n 密码原文为 'haohappy', 加密方法为: 'xor',<BR>加密结果为:"; echo Text_Password::createFromLogin('haohappy', 'xor', 5) . "<P>"; echo "n 密码原文为 'haohappy', 加密方法为: 'ascii_rotx',<BR>加密结果为: "; echo Text_Password::createFromLogin('haohappy', 'ascii_rotx', 5) . "<P>"; echo "n 密码原文为 'haohappy', 加密方法为: 'ascii_rotx++',<BR>加密结果为: "; echo Text_Password::createFromLogin('haohappy', 'ascii_rotx++', 5) . "<P>"; echo "n 密码原文为 'haohappy', 加密方法为: 'ascii_rotx--',<BR>加密结果为: "; echo Text_Password::createFromLogin('haohappy', 'ascii_rotx--', 5) . "<P>"; echo "n 密码原文为 'haohappy', 加密方法为: 'shuffle',<BR>加密结果为:"; echo Text_Password::createFromLogin('haohappy', 'shuffle', 1) . "<P>"; echo "n<b>密码组</b>原文为: 'haohappy', 'martin', 'vanhoucke', 'jansen', 加密 方法为: 'reverse':n"; $logins = array('haohappy', 'martin', 'vanhoucke', 'jansen'); echo "结果如下:<pre>"; print_r(Text_Password::createMultipleFromLogin($logins, 'reverse')); echo "</pre>"; ?> 运行结果如图: 你可以按 F5 刷新几次,会发现除了 Shuffle 操作(打乱)之外,其它结果都是固定不变,也即非随机的。 PHPMORE VOL5 13/26
  • 15. 以上即 Text_Password 的三个主要应用,相信你已经初步掌握。 应用实例――图形验证码: 下面 Haohappy 将给出一个应用实例,那就是大家都非常熟悉的图形验证码。虽然只是一个简单的例子,却是一个 完整的验证码程序的核心部份。思路是采用随机的背景图,再用不同的颜色写上随机字符串。 首先,我们准备三个图形背景文件,分别命名为 bg1.png,bg2.png,bg3.png,放在 images 目录下。 代码如下: <? Code - ImageCode.php?> <?php require_once "Text/Password.php"; $string = Text_Password::create(10, 'pronounceable'); $num = rand(1,3); header("Content-type: image/png"); $im = imagecreatefrompng("images/bg$num.png"); switch ($num) { case 1: $orange = imagecolorallocate($im, 253, 238, 227); //字体颜色 break; case 2: $orange = imagecolorallocate($im, 255, 204, 51); break; case 3: $orange = imagecolorallocate($im, 255,255,200); break; } $px = (imagesx($im) - 7.5 * strlen($string)) / 2; //位置 imagestring($im, 5, $px-3, 2, $string, $orange); //写上随机字符串 imagepng($im); imagedestroy($im); ?> PHPMORE VOL5 14/26
  • 16. 运行结果如下: 左图为随机码类型 pronounceable,右图为 unpronounceable 使用 Text_Password 的好处就在这里,可以非常方便地使用你想要的随机码类型。 程序非常简单,只有二十多行,但功能算是相当强大,想使用程序进行边缘识别不那么容易,安全性较高。 至少比腾讯网站上 QQ 免费注册的那个验证码强多了:) 当然你也可以再加入随机杂点,画线,使用随机字体,旋 转等等(如果有必要的话) 。你可以在网页中加入<IMAGE SRC='imagetest2.php'>来引用该验证码,配合 Session,就可以在用户登录时进行图形验证码认证。具体不详述,没什么难度。 如果对几个图像函数不熟悉,请自行查阅 PHP 手册。 参考资料: End-user Documentation and API documentation of PEAR::Text_Password PHPMORE VOL5 15/26
  • 17. PEAR::PEAR 的析构器模拟 EasyChen / 文 Pear 是 Pear 的基类,其中提供了 Pear 类的一些基本服务,主要包括 o 析构器的模拟 o 错误处理机制 这里我们说析构器的模拟 。虽然 PHP4 中的 class 是没有析构器的,但是所有扩展自 Pear 的 class,都会在程序 结束时调用_classname()函数来析构。很神奇是吧,我们就来看看 pear 是怎么做到的。 首先,我们需要在构造器中调用$this->Pear()方法,实际上运行的是如下代码: <? Code ?> $classname = get_class($this); if ($this->_debug) { print "PEAR constructor called, class=$classnamen"; } if ($error_class !== null) { $this->_error_class = $error_class; } while ($classname) { $destructor = "_$classname"; if (method_exists($this, $destructor)) { global $_PEAR_destructor_object_list; $_PEAR_destructor_object_list[] = &$this; break; } else { $classname = get_parent_class($classname); } } 可以看到,Pear 取得了当前对象的 class 名,然后开始拼接出析构器的名称_classname,接着调用 method_exists 方法察看当前对象是否存在着方法,如果存在,把这个对以引用方式推入一个数组。从这个数组的名字上我们就可 以知道,析构时 pear 将遍历这个数组中的对象并调用其析构方法。 需要注意的是,这里为什么会使用一个数组。实际上,pear 用 while 语句制造了一个类似递归的效果。当当前对象 没有析构器时,pear 会去找它的父类的析构器,直到找到为止。 现在剩下的就是一个问题了,如何在程序执行完时触发这个析构过程? 要明白这一点,需要先了解一个函数 register_shutdown_function。这个函数可以添加一个函数,使 php 在脚本 运行结束前,调用它。可以注册多个函数,调用的顺序和注册的顺序一致。 pear 的代码里边有这么一句。 PHPMORE VOL5 16/26
  • 18. register_shutdown_function("_PEAR_call_destructors"); 显然,_PEAR_call_destructors 就是那个析构过程了,代码和 Pear()有些类似。 <? Code ?> function _PEAR_call_destructors() { global $_PEAR_destructor_object_list; if (is_array($_PEAR_destructor_object_list) && sizeof($_PEAR_destructor_object_list)) { reset($_PEAR_destructor_object_list); while (list($k, $objref) = each($_PEAR_destructor_object_list)) { $classname = get_class($objref); while ($classname) { $destructor = "_$classname"; if (method_exists($objref, $destructor)) { $objref->$destructor(); break; } else { $classname = get_parent_class($classname); } } } // Empty the object list to ensure that destructors are // not called more than once. $_PEAR_destructor_object_list = array(); } // Now call the shutdown functions if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { call_user_func_array($value[0], $value[1]); } } } 总结一下,Pear 在初始化时建立了需要析构的对象数组,并利用了 register_shutdown_function 触发析构函数, _PEAR_call_destructors,从而完美的模拟了析构过程。 PHPMORE VOL5 17/26
  • 19. Smarty 中 section 的简单使用 翟翔/文 什么是 section? 就像在 Smarty 官方手册里提到的,模板 section 是用来循环数组里的数据的。所有的 section 标签必须和 /section 标签成对儿使用。必须使用的参数是 name 和 loop。section 的 name 可以随你所好,可以是由字母、 数字和下划线组成的。section 可以嵌套使用,互相嵌套的 section 它们的 name 必须与众不同。变量 loop(通 常是数组的值)决定着 section 将要循环的次数。当用 section 显示一个变量时,section 的 name 必须紧跟 在变量名的后面,并用中括号 [] 括起来。当 loop 变量没有值时,sectionelse 就会运行。 下面就是一个 name 为 left_block,loop 为$LEFT_BLOCK_BODY 的 section,注意到<div class=”left_block”></div>当中显示变量的方法了么?section 的 name 也就是 left_block 紧跟在 $LEFT_BLOCK_BODY 的后面,并用中括号 [] 括起来了。 <{section name=left_block loop=$LEFT_BLOCK_BODY}> <div class="left_block"><{$LEFT_BLOCK_BODY[left_block]}></div> <{/section}> 为什么要使用 section? 就像 phpBB2 的成员列表,如下图,显示的内容 当你设计成员列表时(如图 1 所示) ,你要用到 section。 (图 1) 因为你无法确认有多少个用户注册,即使确认就 100 个限制用户注册,用传统的 table 设计网页你需要作的是牲 口般的工作,所以把这些交给 section 来处理吧。 其实还有很多地方可以用到 section。比如用 div 来作网页布局的时候,左、中、右区域的区块儿和模块儿都是 由后台数据库的 block management 来管理的,网页设计者根本就不知这些动态浮动的区块儿、模块儿在什么地 方、什么时候、什么样式、什么内容出现,或者这些区块儿和模块儿压根儿就不让你看见(管理员控制面板对一般 用户就是隐藏的),section 可以轻松地管理登陆框、导航栏、新闻发布、谁在线、语言选择等区块儿和模块儿。 如何使用 section? PHPMORE VOL5 18/26
  • 20. Smarty 中的 section 和 PHPLib 中 template 的 block 很相似, section 更为 smart。 但 如果你使用过 PHPLib 的 block 很快你就会过渡到 section,如果你以前压根儿就没有听说过这些事儿, 反而更容易掌握 section 的 概念,因为什么都不知道嘛。Just kidding^_^ 来个简单的导航栏元素设计的例子。传统的导航栏设计很实诚(如图 2 所示), (图 2) 有多少个链接就用 dreamweaver 设计几个,有千千万万个怎么办呢?而且还要随时变化怎么办呢?你只用设计一 个链接其他的就让 section 去循环显示好了。 dreamweaver 设计一个名为 navigation.htm 的页面 用 (只保留 了 table 当中要用到的元素,其余的 html 元素在不影响显示的前提下均以省略) ,如下面 html 代码。 <table width="100%" border="0" cellspacing="0" cellpadding="0"> <tr> <td><h2><{$L_TITLE_NAVIGATION}></h2></td> </tr> <{section name=navigation loop=$l_navigation}> <tr> <td><img src="<{$IMG_DOT}>" width="12" height="12"> <a href="<{$u_navigation[navigation]}>"><{$l_navigation[navigation]}></a></td> </tr> <{/section}> </table> 其中<a href="<{$u_navigation[navigation]}>"></a>就定义了超链接变量, <{$l_navigation[navigation]}>就定义了超链接的名称,用<{section name=navigation loop=$l_navigation}>和<{/section}>框住要循环显示的部分,一个自动化的导航栏的表现层就设计好了。 (请参看 MVC 模型) 光有皮肤没有骨架是支撑不起导航栏来的,所以让我们看看如何用 PHP 代码控制显示导航栏的。写一个名为 navigation.php 的 PHP 文件,代码如下: PHPMORE VOL5 19/26
  • 21. $template->assign("l_navigation", array( //要在其他地方给$lang[' …… ']负值 $lang['index'], $lang['your_account'], $lang['downloads'], $lang['submit_news'], $lang['topics'], $lang['top10'] ) ); $template->assign("u_navigation",array( "./index.php", "./modules.php?name=Your_Account", "./modules.php?name=Downloads", "./modules.php?name=Submint_News", "./modules.php?name=Topics", "./modules.php?name=Top10" ) ); 你肯定要惊叹:“really?”真的是这么简单呀^_^ 首先,$template->assign 是在调用 Smarty 的 smarty 类当中的 assign 函数,assign 的意思就是赋值、分 配、指派的意思。$template->assign 给 navigation.htm 网页模板中的 l_navigation 变量赋了一个数组, 并提供了 6 个变量型的数组值(你要在其他地方给它们负值,或者直接像给超链接地址负值一样用" …… "的形式) ——用来显示超链接的名称,其中的数组键值用 PHP 默认的 0、1、2……就省略了;还给 u_navigation 变量赋了一 个数组,相对称的也是 6 个但已给出数值的变量——用来定义超链接的去向(其中运用了参数?name 来判断转向哪个 模块儿)。你可能会产生疑问:循环的次数在哪里定义的?loop 变量名仅仅是$l_navigation 数组呀!如果你有 机会查看 Smarty 的代码,你会发现 loop = count($l_navigation),只是这个过程被封装了,你只用调用这 个 section 接口就 OK 了。 然后,利用 smarty 类当中的 display 函数,就可以运行 navigation.php 查看你的导航栏了 PHPMORE VOL5 20/26
  • 22. $template->display(“navigation.htm”); 进一步使用 section 就像我前面提到的,section 主要在处理多个重复其不断变化的元素上优势明显。这里由于篇幅有限,就把思想和 大家共享,把未完善的内容留给以后的文章。变化的数据来源于数据库,那么在$template->assign 一个 section 变量的时候可以用到 DB(是 PEAR 提供的对多种数据库操作的集成度很高的类,可以一次编写标准的 SQL 语句在大 多数主流数据库上到处运行)和 section 的综合利用。 在网页中显示居于左侧的区块儿和模块儿 $sql = "SELECT block_value FROM sirtoozee_blocks WHERE block_side = 'left' and block_visble = 'true' ORDER BY 'weight "; //用 getCol 这个 API 可以得到一维数组$block = array('','',...) $block_value = $db->getCol($sql); $template->assign("LEFT_BLOCK_BODY", $block_value) 你可以 print_r($block_value)看看$block_value 这个数组结构是不是就是 array('' …… '', ... )的 结构一模一样。其中具体的 DB 类的使用和网页 layout 布局我会在以后的文章中详细讲解。 如果大家对调用 Smarty 不熟悉,我在这里也简单介绍安装配置 Smarty 的方法: 到 http://smarty.php.net 下载 stable 版本的 smarty,将压缩包里./libs 文件夹里的所有文件解压缩到 Smarty(需要自己新建)文件夹中,并将你设计的网页模板文件,如 navigation.htm 放在 templates(需要 自己新建)文件夹下,还需要为 Smarty 新建 config、cache、templates_c 文件夹用来编译生成临时文件, 最后形成如下的文件目录结构: ./ ./Smarty/internals ./Smarty/plugins ./Smarty/Config_File.class ./Smarty/debug ./Smarty/Smarty.class ./Smarty/Smarty_Compiler.class ./templates PHPMORE VOL5 21/26
  • 23. ./templates_c ./config ./cache 用如下代码调用 Smarty 类 // //模板引擎配置,采用 smarty-2.6.6 // include("./Smarty/Smarty.class.php"); $template = new Smarty; //安装并配置 Smarty 模板引擎 $template->template_dir = "./templates/ "; $template->compile_dir = "./templates_c"; $template->config_dir = "./configs"; $template->cache_dir = "./cache"; //为了和 javascript 标签区别开来 $template->left_delimiter = "<{"; $template->right_delimiter = "}>"; 您可以通过如下方式和作者翟翔联系 Email:legendren2008@yahoo.com.cn PHPMORE VOL5 22/26
  • 24. XmlHttp 试用手记 EasyChen / 文 什么是 XmlHttp Xmlhttp 是一种浏览器对象,可用于模拟 http 的 GET 和 POST 请求。配合 JavaScript 可以实现页面数据在无 刷新下的定时数据更新,如果应用在聊天室、文字直播上可以取得较好的视觉效果。 IE 中的 XmlHttp 对象 在 IE 中 XmlHttp 被实现为 ActiveX 对象,通常使用 var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); 来创建一个对象,然后使用该对象的 open 方法来发出一个 Http 请求。 xmlhttp.open("GET", fragment_url); 这时候浏览器已经发出了 Http 请求,我们需要注册一个匿名函数给 XmlHttp 对象的 onreadystatechange 方 法,这样当请求返回时,xmlhttp 就会自动调用我们注册的这个函数,下边是一个实际的例子。 xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { element.innerHTML = xmlhttp.responseText; } } 因为我们不需要再发送任何信息,所以用下边的语句结束 xmlhttp.send(null); 我们将上边的过程封装为一个函数,下边是这个函数的完整代码: function loadFragmentInToElement(fragment_url, element_id) { var element = document.getElementById(element_id); var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); xmlhttp.open("GET", fragment_url); PHPMORE VOL5 23/26
  • 25. xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { element.innerHTML = xmlhttp.responseText; } } xmlhttp.send(null); } 函数的调用方法如下所示: loadFragmentInToElement( 'http://domain.com/url.php' , DynamicContent_id ); 有了上边的代码,再配合 JavaScript 的定时函数,我们就可以实现定时的无刷新数据更新了,下边这个函数每隔 5 秒对 element_id 的数据进行一次更新。 function refresh( element_id ) { loadFragmentInToElement( 'show.php' , '' + element_id ); setTimeout( "refresh('ts')" , 5000 ); } 在 IE 上使用 XmlHttp 要注意的问题 特别要注意的是由于 IE 的 Cache 的关系,我们看见的 XmlHttp 并不总是最新读取的那一个,为了让 IE 不启用 Cache,我们发送给 IE 一个特殊的 Header,用 PHP 实现如下: header( "Expires: Mon, 26 Jul 1997 05:00:00 GMT" ); header( "Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . "GMT" ); header( "Cache-Control: no-cache, must-revalidate" ); header( "Pragma: no-cache" ); XmlHttp 对象在 Gecko 上的实现 Gecko 上的 XmlHttp 和 IE 上略有不同,它并不需要通过 ActiveX 来创建。另外回调函数必须在 open 方法之前 注册,而 IE 并不要求,这是一个很需要注意的问题。 使用 JavaScript 实现 XmlHttp 的跨浏览器应用 为了能在多种浏览器上有一个统一的实现,我们可以用 JavaScript 来对不同浏览器的差异进行封装。这里我们采 用 Andrew Gregory 的实现。首先我们要引用 Andrew Gregory 的一个名为 xmlhttprequest.js 的 Js 脚本。 PHPMORE VOL5 24/26
  • 26. <script type="text/javascript" src="xmlhttprequest.js"></script> 然后在创建 XmlHttp 对象时统一使用 new XMLHttpRequest()就可以了;其它的方法不用改变。这个 Js 脚本允 许 我 们 在 IE 、 Gecko ( Mozilla/FireFox ) 和 Opera 的 特 定 版 本 使 用 XmlHttp 。 下 边 是 调 整 后 的 loadFragmentInToElement 函数,这个函数在 IE6 和 FireFox1.0pre 上运行通过。 <script type="text/javascript" src="xmlhttprequest.js"></script> <script> function loadFragmentInToElement(fragment_url, element_id) { var element = document.getElementById(element_id); var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { element.innerHTML = xmlhttp.responseText; } } xmlhttp.open("GET", fragment_url); xmlhttp.send(null); } </script> xmlhttprequest.js 文件和具体的使用例子可以在我写的一个 DEMO 中找到。 XmlHttp 中的中文乱码问题 在默认情况下, XmlHttp 都是使用 Utf-8 字符集, 而我们使用的多是 GB2312 字符集, 这就要求我们进行 GB2312 到 Utf-8 的转码。PHP 提供了一个可选的专码模块,可以实现多种字符集之间的相互转化。加载这个专码模块的方 法如下: 打开 PHP 配置文件 php.ini,将 ;extension=php_mbstring.dll(*nix 是 php_mbstring.so) 前的分 号去掉。重新启动 Apache 以后,这个模块就可以使用了。如果有错误出现,请检查扩展目录的路径设置是否正确。 加载这个模块以后,我们就可以使用 mb_convert_encoding 函数来转码了: $utf8_string = mb_convert_encoding( $gb_string , 'UTF-8' , 'GB2312' ); 将转码后的字符输出就可以看见正确显示的中文了。 PHPMORE VOL5 25/26
  • 27. 推荐图书 著名的 J2ee 核心模式,最近原书第 李维的新作,对于面向对象的初学者 《程序员修炼之道》同系列的书,深 二版的中文版出来了,书不错,翻译 和 Delphi For dotnet 的用户来说很不 入浅出的讲解了 JUNIT 的使用。 得也不错。 错,Delphi 也开始 UT 和 TDD 了 PHPMORE VOL5 26/26