分页: 114/120 第一页 上页 109 110 111 112 113 114 115 116 117 118 下页 最后页 [ 显示模式: 摘要 | 列表 ]
Oct 29

1:打开Editplus,选择"工具->配置用户工具..."菜单。
2:
在弹出的窗口中选择"添加工具->应用程序",给新程序起一个好记的名字,比如这里我们用"Debug
PHP",在"菜单文本"中输入"Debug
PHP"。点击"命令行"右边的按钮,找到你的php.exe所在的路径,例如这里是"c:\php\php.exe"。再点击"参数"右边的下拉按钮选
择"文件路径",最后再把"捕获输出"前面的复选框选上。
3:现在测试一下,新建一个php文件,按快捷键Ctrl+1可以激活刚才我们设置的工
具(如果你设置了多个工具,快捷键可能会有所不同),现在你可以看到它已经能正常工作了。但是还有一点不太理想:如果你的PHP程序出错,在输出窗口会提
示你第几行出错 ,单击这一行提示,Editplus老是提示你找不到某某文件,是否新建。接下下我们要修正这个功能。
4:打开刚才用户工具设置
窗口,找到刚才设置的"Debug
PHP"工具。点击"捕获输出"复选框旁边的"输出模式"按钮,会弹出一个定义输出模式的窗体,把"使用默认输出模式"前面的复选框去掉,
在"正则表达式"这一项的文本框中输入" ^.+ in (.+) line ([0-9]+)
"(不包括引号),细心的朋友可能会发现,这里使用的也正则表达式的语法。然后,在下面的"文件名"下拉菜单中选择"预设表达式
1",即上边正则表达式中的第一个参数,"行"下拉菜单项选择"预设表达式 2","列"下拉项保持为空。然后保存设置。
5:好了,现在再来试一下吧,双击出错的行数,Editplus就会自动激活出错文件,并把光标定位到出错行,是不是特别方便呢?!
如果不能切换错误行号,请尝试作如下修改:
1.php.ini 中html_errors = Off打开
//如果你不打开,3.中的表达式要修改
2.参数改成:-q -f "$(FilePath)"
//不加"符号的话文件名有空格的文件调试失败。。
//-q不输出html头信息,你去掉也行,不过调试时候你一般用不到那些header信息
3." ^.+ in (.+) line ([0-9]+) " 改成 "^.+ in (.+) on line ([0-9]+)$"
//如果还是不行,请注意调试结果,自己修改表达式来取出文件名和行号


6: 把剪辑库定位在 PHP4 Functions 上就可以在编辑时, 利用[插入]->[匹配剪辑]命令,就可以自动完成末输入完整的 PHP 函数(或直接按 F2 键)
7: 类似上面,在选择部分文字后,同样可以自动完成。(同 F2)
8: 在[参数选择]->[设置和语法]->PHP->自动完成, 选择目录下的 php.acp 文件,你可以定制自己的自动完成方式.
9: 想要即时预览文件,可在[参数选择]->[工具]->WEB 服务器中添加本地目录,(注意不要加 http:// , 应是一个有效的站点)。
    如: 主机->localhost/php &line; 根目录->D:\php
主机->localhost/asp &line; 根目录->D:\asp
主机->localhost/cgi &line; 根目录->D:\cgi
完成设置后只要脚本文件位于这些目录下(子目录也没问题), 就能够正确解释.
10: 各种语法和模板文件可以在
http://editplus.com/files.html 获得,可根据需要选用和编辑。
11: Ctrl+F11 可显示当前文件中的函数列表.
12: 添加各种用户工具.如:
启动MYSQL服务器管理工具->C:\mysql\bin\winmysqladmin.exe
启动Apache服务器->C:\Apache\bin\Apache.exe -k start
启动Apache服务器->C:\Apache\bin\Apache.exe -k stop (shutdown)
13: DBG 附带有一个 prof_results.php 文件,可剖析 PHP 程序的性能.
虽不是真正的调试器,但已经够了.
OK! 经过改造后,是不是有点象一个 IDE 什么?还差点,没有即时帮助...看我的,再来:
14 把 php_manual_en.chm (最好是扩展帮助手册)加入到用户工具中, 当遇到需要参考的关键字时, 把光标定位其上, 按下快捷键 Ctrl+1, 看到了吗.
在输入时有想不起来的函数名时, 先按照第 1 条的方法调出函数, 然后...怎么样?


以上有的是对于调试工具的设置,由于此类工具比较多,大家设置时参考以上的基本就差不多了,所以就不过多的列举了。
本文转自www.csdn.net


Oct 28
个人理解
类是函数的函数
把工具和数据都放在同一个函数里。
要用什么从那里用就是

类最难理解的不是什么只是比喻用错了。或者说,没有一个很好的比喻

要理解类,就要先理解函数的变量(如果什么是变量都不知道的请先理解了再说)
有的人称函数为工具,
就是能实现某些功能的
function show($str)
{
echo $str;
}
基本上很多人都能理解吧
把输入的参数$str输出
然后来一个复杂一点的程序
<?
$s='Hello Word';
$g='baby';
show($s);//调用
function show($str)//定义函数
{
$g=' bar';
echo $s.$g."\n";
}
echo"\$g=".$g;
?>
会输出
Hello Word bar
$g=baby
这下可明白了函数的作用吧
函数的内部变量与外部变量的不同吧

理解函数内部变量与外部变量的不同后你和能很好的理解类
所以你要先把前面的理解好了才看下面的

关于类 的一个名词就叫数据封装
数据封装就是把一些数据放在一个不能很容易就得到的地方
这是简单的理解
一切从简单开始好

类跟函数一样,能有自己的变量而且还能有自己的工具(函数)
也就是方法了
<?
class myclass
{
    var $s;
    var $g=' baby';
    function myclass()
    {
        $this->$s='Hello Word';
        $this->$g=' baby';
    }
    function show($str='')
    {
       $g=' bar ';
        echo $this->$s.$g.$str."<BR>";
    }
}
$new=new myclass();
$new->show('myclass');
$new->show('');

?>

这个就比函数的功能要多很多了
应该说是包含了函数
最后说一句:不明白的不要紧,自已去尝试一下就明白了!

Oct 26

   1. 什么是grub

  grub 是一个多重启动管理器。grub是GRand Unified Bootloader的缩写,它可以在

多个操作系统共存时选择引导哪个系统。它可以引导的操作系统包括Linux,FreeBSD,So

laris,NetBSD,BeOSi,OS/2,Windows95/98,Windows NT,Windows2000。它可以载入操作系

统的内核和初始化操作系统(如Linux,FreeBSD),或者把引导权交给操作系统(如Win

dows 98)来完成引导。

2. grub的特点

  grub可以代替lilo来完成对Linux的引导,特别适用于linux与其它操作系统共存情

况,与lilo相比,它有以下特点:

支持大硬盘

  现在大多数Linux发行版本的lilo都有同样的一个问题:根分区(/boot分区)不能分

在超过1024柱面的地方,一般是在8.4G左右的地方,否则lilo不能安装,或者安装后不

能正确引导系统。而grub就不会出现这种情况,只要安装时你的大硬盘是在LBA模式下,

grub就可以引导根分区在8G以外的操作系统。

支持开机画面

  grub支持在引导开机的同时显示一个开机画面。对于玩家来说,这样可以制作自己

的个性化开机画面;对于PC厂商,这样可以在开机时显示电脑的一些信息和厂商的标志

等。grub支持640x480,800x600,1024x768各种模式的开机画面,而且可以自动侦测选择

最佳模式,与Windows那320x400的开机画面不可同日而语。

两种执行模式

  grub不但可以通过配置文件进行例行的引导,还可以在选择引导前动态改变引导时

的参数,还可以动态加载各种设备。例如你在Linux下编译了一个新的核心,但不能确定

它能不能工作,你就可以在引导时动态改变grub的参数,尝试装载这个新的核心进行使

用。Grub的命令行有非常强大的功能,而且支持如bash或doskey一样的历史功能,你可

以用上下键来寻找以前的命令。

菜单式选择

  在lilo下,你需要手工输入操作系统的名字来引导不同的操作系统。而grub使用一

个菜单来选择不同的系统进行引导。你还可以自己配置各种参数,如延迟时间,默认操

作系统等。

分区位置改变后不必重新配置

  lilo是通过读取硬盘上的绝对扇区来装入操作系统,因此每次分区改变都必须重新

配置lilo,例如你用PQ magic调整了分区的大小,那lilo在你重新配置好之前就不能引

导这个分区的操作系统了。而grub是通过文件系统直接把核心读取到内存,因此只要操

作系统核心的路径没有改变,grub就可以引导系统。 除此之外,Grub还有许多非常强大

的功能。例如支持多种外部设备,动态装载操作系统内核,甚至可以通过网络装载操作

系统核心。Grub支持多种文件系统,支持多种可执行文件格式,支持自动解压,可以引

导不支持多重引导的操作系统等。

3. grub的使用

安装grub

  如果已经安装了蓝点Linux2.0则grub是默认安装的。要把grub重新安装到主引导扇

区上,只需要简单打入makebootable命令就可以了。

制作grub启动盘

  首先确定grub已经安装,然后进入grub的目录,键入:

  #cd /boot/grub

  放入一张软盘,然后敲入命令:

  #dd if=stage1 of=/dev/fd0 bs=512 count=1

  #dd if=/stage2 of=/dev/fd0 bs512 seek=1

  这样就可以做好一张启动盘了。

开机

  安装了grub开机后会出现一个菜单,列出所有的启动选项。如果设置了启动画面则

会显示启动画面,按Esc键则可以取消启动画面显示菜单选项。蓝点Linux所带的grub的

命令提示是全中文的,在菜单下面详细列出如按e是编辑启动命令,按c是使用命令行等

。用上下键可以选择菜单项,按回车启动所选项。按e键可以编辑所选项的启动命令,你

可以用这个功能临时改变你的系统的启动参数,参见配置grub一节。按c键则进入命令行

模式。   

  在命令行模式下可以打入命令直接执行,例如你可以敲入poweroff关闭计算机。按

Tab键可以列出所有支持的命令。蓝点Linux已经把grub汉化了,其中一部分命令敲入名

字后会给出中文提示,显示命令的用法和参数。

4. 配置grub

  grub启动时会在/boot/grub/中寻找一个名字为menu.lst的配置文件,如果找不到此

文件则不进入菜单模式而直接进入命令行模式。

  menu.lst 是一个文本文件,你可以用任何一个文本编辑器来打开它。每一行代表一

个配置命令,如果一行的第一个字符为井号"#"则这一行为注释,你可以简单地用增加或

减少注释行来改变配置。

编辑menu.lst,一般会有以下各行

timeout second

设定在second秒之后引导默认的操作系统。

蓝点Linux默认是timeout 5,就是5秒没有其他指令就引导系统,如果设成-1,则grub会

一直等待直到用户选择一个选项为止。

default num

默认启动第num+1行选项,也就说default=0则默认启动菜单第一行的操作系统,defaul

t=1则启动第2行的系统,如此类推。

splash pathname/filename

指出开机画面的文件所存放的路径和文件名,如 splash /boot/logo/800x600x8.img 是

指用在/boot/logo路径下的800x600.img文件作为开机画面

title OSname title

后面的字符就是你在菜单项上所看见的选项,你可以写上操作系统的名字和描述,如用

title BluePoint Linux, Single Mode 代表这一选项是引导蓝点Linux的单用户模式。

下面结合两个系统引导描述来解释几个引导选项的意义

title BluePoint Linux, Default Mode

root (hd0,1)

kernel /boot/vmlinuz vga=auto root=/dev/hda2

hd0是指第一个硬盘(主硬盘) (hd0,1)是指第一个硬盘的第二个分区。 kernel /boot/v

mlinuz 是指出Linux核心的路径在/boot/vmlinuz中。vga=auto 是设定显示模式,root

=/dev/hda2是指把第一个硬盘的第二个分区作为根挂载点("/")。

title Microsoft Windows

root (hd1,0)

chainloader (hd1,0)+1

root (hd1,0)这是指第二个硬盘(从硬盘)上第一个分区

chainloader (hd1,0)+1 装入一个扇区的数据然后把引导权交给它。

5. 从软盘启动grub

  制作启动盘后可以用软盘启动引导硬盘上的操作系统 插入制作好的启动软盘,进入

BIOS设定软盘启动。软盘启动成功后就会进入grub的命令行模式

grub>

  要启动一个操作系统,首先指定引导哪个分区上的系统,例如要引导指第一个硬盘

上的第一个分区的操作系统,先键入

grub>root (hd0,0)

  接着如果要启动的是Windows系统,键入

grub>chainloader (hd0,0)+1

  注意(hd0,0)要随着硬盘和分区的不同而改变数字。 如果要引导Linux或其他系统,

应键入

grub>kernel (hd0,0)/boot/vmlinuz root=/dev/hda1

  注意hda1参数也要随着硬盘和分区的不同而改变,如从第二个硬盘的第一个分区引

导则用hdb1。

  最后敲入boot就可以启动系统了。

  在任何时候不能确定命令或者命令的参数都可以按Tab获得相关的帮助。用上下键可

以获得命令的历史记录。 其实这些命令就是menu.lst的启动描述,您也可以根据那些描

述来自己键入启动命令,最后敲入boot就可以引导系统了。
Oct 26

   (一)安装linux时安装grub.

安装redhat linux时会提示安装引导程序,如果选择grub为引导程序,建议把grub安装到硬盘的引导扇区MBR.grub
还可以引导其它操作系统,如 FreeBSD、NetBSD、OpenBSD、GNU HURD 和 DOS,以及 Windows
95、98、NT、2000、XP。

(二)grub的配置

一旦选择了grub为引导程序,下面我们来了解一下它的配置.

/boot/grub/grub.conf是grub产生一个引导选择菜单以及设置一些选项.下面是我的grub.conf:

#==========例子开始==========

# grub.conf generated by anaconda

#

# Note that you do not have to rerun grub after making changes to this file

# NOTICE: You have a /boot partition. This means that

# all kernel and initrd paths are relative to /boot/, eg.

# root (hd0,6)

# kernel /vmlinuz-version ro root=/dev/hda10

# initrd /initrd-version.img

#boot=/dev/hda

default=0

timeout=10

splashimage=(hd0,6)/grub/splash.xpm.gz

# --> Redhat linux 8.0 <--

title Red Hat linux (2.4.18-14)

root (hd0,6)

kernel /vmlinuz-2.4.18-14 ro root=LABEL=/

initrd /initrd-2.4.18-14.img

# --> Microsoft Windows XP <--

title Microsoft Windows XP

rootnoverify (hd0,0)

chainloader +1

#===========例子结束==========

配置选项解释:

以"#"开头的是注释行.

我这里有两个操作系统,分别是Red Hat linux和Microsoft Windows XP.

其中 timeout标识默认等待时间,我这设置为10秒,超过10秒用户还没作出选择的话,将自动选择默认的操作系统(我这里默认的是Redhat linux 8.0)

默认的操作系统是由default一项来控制的,default后的数字表明第几个是默认的,这里0表示第一个,1表示第二个.所以如果你想修改默认的操作系统,就修改default后的数字.

title一项是设置操作系统的名称,grub不支持中文(有点遗憾).

splashimage一项指定grub界面的背景图片,有兴趣的朋友可以修改grub的背景哦!

root
(hd0,6)标识从第一个硬盘,第7个分区来启动搜索引导内核.注意这儿的root与linux的root分区不同,此root非彼root也!
grub的硬盘标识方法与linux的有点不同.在linux中第一个主分区为hda1,第二个主分区为hda1,第一个逻辑分区为hda5,而在
grub中是以(hdx,y)来标识的,如第一个主分区为(hd0,0)第一个逻辑分区为(hd0,1)依此类推.所以这儿root后面的是你的
/boot所在分区标识.

知道了内核在哪儿,还要具体指出哪个文件是内核文件,这就是kernel的工作。

kernel /vmlinuz-2.2.18-14 ro root=LABEL=/.说明/boot/vmlinuz-2.2.18-14
就是要载入的内核。后面的都是传递给内核的参数。ro是以readonly的意思。注意我这里内核前面的路径是"/",因为我的boot单独分了一个区,
如果你没有为boot单独分区,那么内核前面的路径就是"/boot".

initrd用来初始的linux image,并设置相应的参数

再来看一看windows的定义段吧。

这里,我添加了一项来引导 WindowsXP。要完成此操作,GRUB 使用了"链式装入器"(chainloader)。链式装入器从分区
(hd0,0) 的引导记录中装入 winXP 自己的引导装入器,然后引导它。这就是这种技术叫做链式装入的原因 --
它创建了一个从引导装入器到另一个的链。这种链式装入技术可以用于引导任何版本的 DOS 或
Windows。如果你在计算机中装有win98,winme,win2k,winxp的话,chainloader会把引导权交与win的
NTLoader来引导.

(三)Grub启动盘的制作

要制作引导盘,需执行一些简单的步骤。首先,在新的软盘上创建 ext2 文件系统。然后,将其安装,并将一些 GRUB 文件复制到该文件系统,最后运行 "grub" 程序,它将负责设置软盘的引导扇区。

将一张空盘插入 1.44MB 软驱,输入:

# mke2fs /dev/fd0

创建了 ext2 文件系统后,需要安装该文件系统:

# mount /dev/fd0 /mnt/floppy

现在,需要创建一些目录,并将一些关键文件(原先安装 GRUB 时已安装了这些文件)复制到软盘:

# mkdir /mnt/floppy/boot

# mkdir /mnt/floppy/boot/grub

# cp /boot/grub/stage1 /mnt/floppy/boot/grub

# cp /boot/grub/stage2 /mnt/floppy/boot/grub

再有一个步骤,就能得到可用的引导盘。

在linux bash中,从 root 用户运行"grub",该程序非常有趣并值得注意,因为它实际上是 GRUB
引导装入器的半功能性版本。尽管 linux 已经启动并正在运行,您仍可以运行 GRUB 并执行某些任务,而且其界面与使用 GRUB 引导盘或将
GRUB 安装到硬盘 MBR 时看到的界面(即GRUB控制台)完全相同。

在 grub> 提示符处,输入:

grub> root (fd0)

grub> setup (fd0)

grub> quit

现在,引导盘完成了。

(四).恢复被windows破坏的grub.

如果你用grub来引导linux和windows,当windows出毛病重新安装后,会破坏MBR中的grub,这时需要恢复grub.

1.把linux安装光盘的第一张放到光驱,然后重新启动机器,在BOIS中把系统用光驱来引导。

2.等安装界面出来后,按[F4]键,也就是linux rescue模式。

3.一系列键盘以及几项简单的配制,过后就[继续]了。。。这个过程,我不说了,比较简单。

4.然后会出现这样的提示符:

sh#

5.我们就可以操作GRUB了.输入grub:

sh#grub

会出现这样的提示符:

grub>

我们就可以在这样的字符后面,输入:

grub>root (hdX,Y)

grub>setup (hd0)

如果成功会有一个successful......

这里的X,如果是一个盘,就是0,如果你所安装的linux的根分区在第二个硬盘上,那X就是1了;Y,就是装有linux系统所在的根分区。 setup (hd0)就是把GRUB写到硬盘的MBR上。

(五).用NTLoader来引导linux.

如果你在安装linux时没有选择安装grub,不必着急,现在我们来看看如何在安装linux后安装grub.并用windows的NTLoader来引导linux.

1. 安装grub

我用的grub是Redhat8.0带的grub安装包: grub-0.92-7.rpm

安装: rpm -ivh grub-0.92-7.rpm

其他安装方式也一样,只要你安装上grub就行了.RH8缺省用的grub, 1,2步骤可以省了.

2. 建立grub的环境

cp /usr/share/grub/i386-pc/* /boot/grub

3. 生成grub的配置文件/boot/grub/menu.conf

按照上面所讲的grub.conf来生成一个配置文件.

注意了, 这里我的linux在/dev/hda4,所以menu.conf那些分区位置为(hd0,3),

你的可能不一样了,不能完全照着"画瓢"噢! 下面第3步install的中的分区位置也应该和你的系统一致.

3. 安装grub至linux分区boot

将grub的stage1安装到/dev/hda4的boot扇区(hd0,3). 过程如下:

/sbin/grub (运行grub)

grub> install (hd0,3)/boot/grub/stage1 d (hd0,3) (hd0,3)/boot/grub/stage2 p (hd0,3)/boot/grub/menu.conf

(注意,上面"grub>"为grub的提示符,其后内容写在一行上.)

4. 取得grub的boot信息

过程如下:

dd if=/dev/hda4 of=/grub.lnx bs=512 count=1

这样得到grub的引导信息,只要用NT Loader来加载它就行了.

5. 将上面得到的grub.lnx弄到Windows的C盘根目录下

可以先把grub.lnx弄得软盘上,然后启动windows,拷贝到C:; 情况允许也可以直接在linux下拷贝到C:了. 我的C盘(即设备/dev/hda1)为FAT32, 可以直接从Linux下弄过去了. 如下:

mount -t vfat /dev/hda1 /mnt/c

cp /grub.lnx /mnt/c

umount /mnt/c

6. 修改NT Loader的boot.ini

在其中加入一行: C:grub.lnx="Redhat linux - GRUB"

加入后boot.ini的内容如下:

[boot loader]

timeout=15

default=C:oot.lnx

[operating systems]

multi(0)disk(0)rdisk(0)partition(1)WINDOWS="Microsoft Windows XP Professional" /fastdetect

[VGA mode]" /basevideo /sos

C:grub.lnx="Redhat linux - GRUB"

OK. 可以用NT Loader加载linux了, 其实上面过程基本上和用NT Loader加载LILO一样.其基本思想就是用NT Loader来加载LILO或grub的引导区(grub.lnx), 其中的关键就是LILO或grub的引导区的获取.

(六)活用grub的交互功能

grub具有强大的交互功能.学会了将会使你受益非浅!

1.grub没有显示菜单怎么办?

当开机后进入grub界面但没了菜单,只剩下一个grub>提示符,怎么启动呢?别急,看下面:

grub>cat (hd0,6)/boot/grub/grub.conf (为了看参数)

grub>root (hd0,6)

grub>kernel (hd0,6)/vmlinuz-2.4.18-14 ro root=LABEL=/

grub>initrd (hd0,6)/initrd-2.4.18-14.img

grub>boot

OK!启动了吧!以上有些数字要根据你的实际情况更改.

以上这个方法也可以用于测试新编译的内核.

2.进入单用户模式.

有时不小心把root用户密码忘了,只能进入单用户模式来重新设置root密码.方法如下:

开机进入grub界面,按C进入命令行模式,然后按照上面的方法进行,只是在第三步要在后面加入single参数
Oct 26

  这里介绍了在PHP中的面向对象编程(OOP,Object Oriented Programming)。将向你演示如何通过使用一些OOP的概念和PHP的技巧来减少编码和提高质量。祝你好运!



面向对象编程的概念:

不同的作者之间说法可能不一样,但是一个OOP语言必须有以下几方面:



抽象数据类型和信息封装

继承

多态



在PHP中是通过类来完成封装的:



[code:1:430ff1d506]


class Something {

// 在OOP类中,通常第一个字符为大写

var $x;

function setX($v) {

// 方法开始为小写单词,然后使用大写字母来分隔单词,例如getValueOfArea()

$this->x=$v;

}

function getX() {

return $this->x;

}

}

?>

[/code:1:430ff1d506]



  当然你可以按自已的喜好进行定义,但最好保持一种标准,这样会更有效。



  数据成员在类中使用"var"声明来定义,在给数据成员赋值之前,它们是没有类型的。一个数据成员可以是一个整数,一个数组,一个相关数组(associative array)或者是一个对象。



  方法在类中被定义成函数形式,在方法中访问类成员变量时,你应该使用$this->name,否则对一个方法来说,它只能是局部变量。



  使用new操作符来创建一个对象:



  $obj=new Something;



  然后你可以使用成员函数通过:



  $obj->setX(5);

  $see=$obj->getX();



  在这个例子中,setX成员函数将5赋值给对象的成员变量x(不是类的),然后getX返回它的值5。



  你可以象:$obj->x=6那样通过类引用方式来存取数据成员,这不是一个很好的OOP习惯。我强烈建议通过方法来存取成员变量。如果你把成
员变量看成是不可处理的,并且只通过对象句柄来使用方法,你将是一
个好的OOP程序员。不幸的是,PHP不支持声明私有成员变量,所以不良代码在PHP中也是允许的。



  继承在PHP中很容易实现,只要使用extend关键字。



[code:1:430ff1d506]


class Another extends Something {

var $y;

function setY($v) {

$this->y=$v;

}

function getY() {

return $this->y;

}

}

?>

[/code:1:430ff1d506]



  "Another"类的对象现在拥有了父类(Something)的全部的数据成员及方法,而且还加上了自已的数据成 员和方法。



你可以使用



[code:1:430ff1d506]

$obj2=new Something;

$obj2->setX(6);

$obj2->setY(7);

[/code:1:430ff1d506]



PHP现在还不支持多重继承,所以你不能从两个或两个以上类派生出新的类来。



你可以在派生类中重定义一个方法,如果我们在"Another"类中重定义了getX方法,我们就不能使 用"Something"中的getX方法了。如果你在派生类中声明了一个与基派同名的数据成员,那么当你处理它时, 它将“隐藏”基类的数据成员。



你可以在你的类中定义构造函数。构造函数是一个与类名同名的方法,当你创建一个类的对象时会被调 用,例如:



[code:1:430ff1d506]


class Something {

var $x;

function Something($y) {

$this->x=$y;

}

function setX($v) {

$this->x=$v;

}

function getX() {

return $this->x;

}

}

?>

[/code:1:430ff1d506]



  所以你可以创建一个对象,通过:



  $obj=new Something(6);



  构造函数会自动地把6赋值给数据变量x。构造函数和方法都是普通的PHP函数,所以你可以使用缺省参数。



  function Something($x="3",$y="5")



  接着:



  $obj=new Something(); // x=3 and y=5

  $obj=new Something(; // x=8 and y=5

  $obj=new Something(8,9); // x=8 and y=9



  缺省参数使用C++的方式,所以你不能忽略Y的值,而给X一个缺省参数,参数是从左到右赋值的,如果传入的参数少于要求的参数时,其作的将使用缺省参数。



  当一个派生类的对象被创建时,只有它的构造函数被调用,父类的构造函数没被调用,如果你想调用基类的构造函数,你必须要在派生类的构造函数中显示调用。可以这样做是因为在派生类中所有父类的方法都是可用的。



[code:1:430ff1d506]


function Another() {

$this->y=5;

$this->Something();

//显示调用基类构造函数

}

?>

[/code:1:430ff1d506]



  OOP的一个很好的机制是使用抽象类。抽象类是不能实例化,只能提供给派生类一个接口。设计者通常使用抽象类来强迫程序员从基类派生,这样可以确保新的类包含一些期待的功能。在PHP中没有标准的方法,但是:



  如果你需要这个特性,可以通过定义基类,并在它的构造函数后加上"die" 的调用,这样就可以保证基类是不可实例化的,现在在每一个方法
(接口)后面加上"die" 语句,所以,如果一个程序员在派生类中没有覆盖方法,将引发一个错误。而且因为PHP
是无类型的,你可能需要确认一个对象是来自于你的基类的派生类,那么在基类中增加一个方法来实义类的身份(返回某种标识id),并且在你接收到一个对象参
数时校验这个值。当然,如果一个邪恶不好的程序员在派生类中覆盖了这个方法,这种方法就不起作用了,不过一般问题多发现在懒惰的程序员身上,而不是邪恶的
程序员。



  当然,能够让基类对程序员无法看到是很好的,只要将接口打印出来做他们的工作就可以了。



  在PHP中没有析构函数。



  重载(与覆盖不同)在PHP中不支持。在OOP中,你可以重载一个方法来实现两个或重多的方法具有相同的名字,但是有不同数量或类型的参数(这要看语言)。PHP 是一种松散类型的语言,所以通过类型重载不起作用,然而通过参数的个数不同来重载也不起作用。



  有时在OOP中重载构造函数非常好,这样你可以通过不同的方法创建对象(传递不同数量的参数)。在PHP

中实现它的技巧是:



[code:1:430ff1d506]


class Myclass {

function Myclass() {

$name="Myclass".func_num_args();

$this->$name();

//注意$this->name()一般是错误的,但是在这里$name是一个将被调用方法的名字

}

function Myclass1($x) {

code;

}

function Myclass2($x,$y) {

code;

}

}

?>

[/code:1:430ff1d506]



  通过在类中的额外的处理,使用这个类对用户是透明的:



  $obj1=new Myclass('1'); //将调用Myclass1



  $obj2=new Myclass('1','2'); //将调用Myclass2



  有时这个非常好用。



多态

  多态是对象的一种能力,它可以在运行时刻根据传递的对象参数,决定调用哪一个对象的方法。例如,如果你有一个figure的类,它定义了一个
draw的方法。并且派生了circle和rectangle
类,在派生类中你覆盖了draw方法,你可能还有一个函数,它希望使用一个参数x,并且可以调用$x->draw()
。如果你有多态性,调用哪个draw方法就依赖于你传递给这个函数的对象类型。



  多态性在象PHP这样的解释语言(想象一下一个C++编译器生成这样的代码,你应该调用哪一个方法?你也不知道你拥有的对象是什么类型的,好,这不是重点)是非常容易和自然的。所以PHP当然支持多态性。



[code:1:430ff1d506]


function niceDrawing($x) {

//假设这是Board类的一个方法

$x->draw();

}

$obj=new Circle(3,187);

$obj2=new Rectangle(4,5);

$board->niceDrawing($obj);

//将调用Circle的draw方法

$board->niceDrawing($obj2);

//将调用Rectangle的draw方法

?>

[/code:1:430ff1d506]



用PHP进行面向对象编程

  一些"纯化论者(purists)"可能会说PHP不是一个真正的面向对象的语言,这是事实。PHP
是一个混合型语言,你可以使用OOP,也可以使用传统的过程化编程。然而,对于大型项目,你可能想/需要在PHP
中使用纯的OOP去声明类,而且在你的项目只用对象和类。



  随着项目越来越大,使用OOP可能会有帮助,OOP代码很容易维护,容易理解和重用。这些就是软件工程

的基础。在基于web的项目中应用这些概念就成为将来网站成功的关键。



  PHP的高级OOP技术

  在看过基本的OOP概念后,我就可以向你展示更高级的技术:



序列化(Serializing)

  PHP不支持永久对象,在OOP中永久对象是可以在多个应用的引用中保持状态和功能的对象,这意味着拥有将对象保存到一个文件或数据库中的能力,而且
可以在以后装入对象。这就是所谓的序列化机制。PHP
拥有序列化方法,它可以通过对象进行调用,序列化方法可以返回对象的字符串表示。然而,序列化只保存了对象的成员数据而不包话方法。



  在PHP4中,如果你将对象序列化到字符串$s中,然后释放对象,接着反序列化对象到$obj,你可以继续使用对象的方法!我不建议这样去做,因为
(a)文档中没有保证这种行为在以后的版本中仍然可以使用。(b)这个可能导致一种误解,在你把一个序列化后的版本保存到磁盘并退出脚本时。当以后运行这
个脚本时,你不能期待着在反序列化一个对象时,对象的方法也会在那里,因为字符串表示根本就不包括方法。



  总而言之,PHP 进行序列化对于保存对象的成员变量非常有用。(你也可以将相关数组和数组序列化到一个文件中)。



例子 :



[code:1:430ff1d506]


$obj=new Classfoo();

$str=serialize($obj);

//保存$str到磁盘上

//几个月以后

//从磁盘中装入str

$obj2=unserialize($str)

?>

[/code:1:430ff1d506]



  你恢复了成员数据,但是不包括方法(根据文档所说)。这导致了只能通过类似于使用$obj2->x来存取成员变量(你没有别的方法!)的唯一办法,所以不要在家里试它。



  有一些办法可以解决这个问题,我把它留着,因为对这篇简洁的文章来说,他们太不好。



  使用类进行数据存储

  对于PHP和OOP一件非常好的事情就是,你可以很容易地定义一个类来操作某件事情,并且无论何时你想用的时候都可以调用相应的类。假设你有一个
HTML表单,用户可以通过选择产品ID号来选择一个产品。在数据库中有产品的信息,你想把产品显示出来,显示它的价格等等。你拥有不同类型的产品,并且
同一个动作可能对不同的产品具有不同的意思。例如,显示一个声音可能意味着播放它,但是对于其它种类的产品可能意味着显示一个存在数据库中的图片。你可以
使用OOP或PHP来减少编码并提高质量:



  定义一个产品的类,定义它应该有的方法(例如:显示),然后定义对每一种类型的产品的类,从产品类派后出来(SoundItem类,ViewableItem类,等等),覆盖在产品类中的方法,使它们按你的想法动作。



  根据数据库中每一种产品的类型(type)字段给类命名,一个典型的产品表可能有(id, type, price, description, 等等字段)...然后在处理脚本中,你可以从数据库中取出type值,然后实例化一个名为type的对象:





[code:1:430ff1d506]


$obj=new $type();

$obj->action();

?>

[/code:1:430ff1d506]



  这是PHP的一个非常好的特性,你可以不用考虑对象的类型,调用$obj的显示方法或其它的方法。使用这个技术,你不需要修改脚本去增加一个新类型的对象,只是增加一个处理它的类。



  这个功能很强大,只要定义方法,而不去考虑所有对象的类型,在不同的类中按不同的方法实现它们,然后在主脚本中对任意对象使用它们,没有if...else,也不需要两个程序员,只有高兴。



  现在你同意编程是容易的,维护是便宜的,可重用是真的吗?



  如果你管理一组程序员,分配工作就是很简单的了,每个人可能负责一个类型的对象和处理它的类。



  可以通过这个技术实现国际化,根据用户所选的语言字段应用相应的类就可以了,等等。





拷贝和克隆

  当你创建一个$obj的对象时,你可以通过$obj2=$obj来拷贝对象,新的对象是$obj的一个拷贝(不是一个引用),所以它具有$
obj在当时的状态。有时候,你不想这样,你只是想生成一个象obj类一样的一个新的对象,可以通过使用new语句来调用类的构造函数。在PHP中也可以
通过序列化,和一个基类来实现,但所有的其它类都要从基类派生出来。





进入危险区域

  当你序列化一个对象,你会得到某种格式的字符串,如果你感兴趣,你可以调究它,其中,字符串中有类的名字(太好了!),你可以把它取出来,象:



[code:1:430ff1d506]


$herring=serialize($obj);

$vec=explode(':',$herring);

$nam=str_replace("\"",'',$vec[2]);

?>

[/code:1:430ff1d506]



  所以假设你创建了一个"Universe"的类,并且强制所有的类都必须从universe扩展,你可以在universe中定义一个clone的方法,如下:



[code:1:430ff1d506]


class Universe {

function clone() {

$herring=serialize($this);

$vec=explode(':',$herring);

$nam=str_replace("\"",'',$vec[2]);

$ret=new $nam;

return $ret;

}

}

//然后

$obj=new Something();

//从Universe扩展

$other=$obj->clone();

?>

[/code:1:430ff1d506]



  你所得到的是一个新的Something类的对象,它同使用new方法,调用构造函数创建出的对象一样。我不知道这个对你是否有用,但是Universe类可以知道派生类的名字是一个好的经验。想象是唯一的限制。
分页: 114/120 第一页 上页 109 110 111 112 113 114 115 116 117 118 下页 最后页 [ 显示模式: 摘要 | 列表 ]