|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
不断巩固,摸透大部分PHP常用函数,并可理解OOP,MYSQL优化,以及模板编程|对象 这篇文章引见在PHP的面向对象编程(OOP)。我将演示若何用面向对象的概念编出较少的代码但更好的法式。祝人人好运。
面向对象编程的概念对每个作者来讲都有分歧的意见,我提示一下一个面向对象言语应有的器材:
- 数据笼统和信息埋没
- 承继
- 多态性
在PHP中利用类停止封装的举措:
class Something {
// In OOP classes are usually named starting with a cap letter.
var $x;
function setX($v) {
// Methods start in lowercase then use lowercase to seprate
// words in the method name example getValueOfArea()
$this->x=$v;
}
function getX() {
return $this->x;
}
}
?>
固然你可以用你本人的举措,但有一个尺度老是好的。
PHP中类的数据成员利用 "var" 界说,数据成员是没有类型直到被赋值。一个数据成员多是一个 integer、数组、结合数组(associative array)或乃至对象(object). 办法在类里界说成函数,在办法里存取数据成员,你必需利用$this->name 如许的举措,不然对办法来讲是一个函数的部分变量。
利用 new 来创立一个对象
$obj = new Something;
然后利用成员函数
$obj->setX(5);
$see = $obj->getX();
setX 成员函数将 5 赋给对象(而不是类)obj 中成员变量, 然后 getX 前往值 5.
你也能够用对象援用来存取成员变量,例如:$obj->x=6; 但是,这纷歧种好的面向对象编程的办法。我保持你应利用成员函数来设置成员变量的值和经由过程成员函数来读取成员变量。假如你以为成员变量是不成存取的除利用成员函数的举措,你将成为一个好的面向对象法式员。 但不幸的是PHP自己没有举措声明一个变量是公有的,所以答应糟的代码存在。
在 PHP 中承继利用 extend 来声明。
class Another extends Something {
var $y;
function setY($v) {
// Methods start in lowercase then use lowercase to seperate
// words in the method name example getValueOfArea()
$this->y=$v;
}
function getY() {
return $this->y;
}
}
?>
如许类 "Another" 的对象具有父类的所用成员变量及办法函数,再加上本人的成员变量及成员函数。如:
$obj2=new Another;
$obj2->setX(6);
$obj2->setY(7);
多重承继不被撑持,所以你不克不及让一个类承继多个类。
在承继类中你可以从头界说来重界说办法,假如咱们在 "Another" 从头界说 getX,那末咱们不再能存取 "Something" 中的成员函数 getX. 一样,假如咱们在承继类中声明一个和父类同名的成员变量,那末承继类的变量将埋没父类的同名变量。
你可以界说一个类的机关函数, 机关函数是和类同名的成员函数,在你创立类的对象时被挪用。
class Something {
var $x;
function Something($y) {
$this->x=$y;
}
function setX($v) {
$this->x=$v;
}
function getX() {
return $this->x;
}
}
?>
所以可以用以下办法创立对象:
$obj=new Something(6);
机关函数主动赋值 5 给成员变量 x, 机关函数和成员函数都是通俗的PHP函数,所以你可使用缺省参数。
function Something($x="3",$y="5")
然后:
$obj=new Something(); // x=3 and y=5
$obj=new Something(8); // x=8 and y=5
$obj=new Something(8,9); // x=8 and y=9
缺省参数的界说办法和 C++ 一样,因而你不克不及传一个值给 Y 但让 X 取缺省值,实参的传递是从左到右,当没有更多的实参时函数将利用缺省参数。
只要当承继类的机关函数被挪用后,承继类的对象才被创立,父类的机关函数没有被挪用,这是PHP分歧其他面向对象言语的特色,由于机关函数挪用链是面向对象编程的特色。假如你想挪用基类的机关函数,你不能不在承继类的机关函数中显式挪用它。如许它能任务是由于在承继类中父类的办法全体可用。
function Another() {
$this->y=5;
$this->Something(); //explicit call to base class constructor.
}
?>
在面向对象编程中一种好的机制是利用笼统类,笼统类是一种不克不及实例化而是用来给承继类界说界面的类。设计师常常利用笼统类来强迫法式员只能从特定的基类来承继,所以就可以肯定新类有所需的功效,但在PHP中没有尺度的举措做到这一点,不外:
假如你在界说基类是需求这个特色,可以经由过程在机关函数中挪用 "die",如许你就能够确保它不克不及实例化,如今界说笼统类的函数并在每一个函数中挪用 "die",假如在承继类中法式员不想重界说而直接挪用基类的函数,将会发生一个毛病。
另外,你需求确信由于PHP没有类型,有些对象是从基类承继而来的承继类创立的,因而增添一个办法在基类来分辨类(前往 "一些标识")并验证这一点,当你收到一个对象作为参数派上用处。 但关于一个无赖法式没用举措,由于他可以在承继类中重界说此函数,凡是这类举措只对怠惰的法式员见效。固然,最好的举措是避免法式接触到基类的代码只供应界面。
重载在PHP中不被撑持。在面向对象编程中你可以经由过程界说分歧参数品种和几何来重载一个同名成员函数。PHP是一种松懈的类型言语,所以参数类型重载是没有效的,一样参数个数分歧的举措重载也不克不及任务。
有时分,在面向对象编程中重载机关函数很有效,所以你能以分歧的体例创立分歧的对象(经由过程传递分歧的参数个数)。一个玲珑门可以做到这一点:
class Myclass {
function Myclass() {
$name="Myclass".func_num_args();
$this->$name();
//Note that $this->$name() is usually wrong but here
//$name is a string with the name of the method to call.
}
function Myclass1($x) {
code;
}
function Myclass2($x,$y) {
code;
}
}
?>
经由过程这类举措可以局部到达重载的目标。
$obj1=new Myclass(1); //Will call Myclass1
$obj2=new Myclass(1,2); //Will call Myclass2
多态性
多态性被界说为当在运转时辰一个对象作为参数传递时,对象能决意挪用谁人办法的才能。例如,用一个类界说了办法 "draw",承继类重界说 "draw" 的行动来画圆或正方形,如许你就有一个参数为 x 的函数,在函数里可以挪用$x->draw(). 假如撑持多态性,那末 "draw" 办法的挪用就取决于对象 x 的类型。多态性在PHP中很天然被撑持(想想这类情形在C++编译器中假如编译,那一个办法被挪用?但是你不晓得对象的类型是甚么,固然如今不是这类情形)。
幸亏PHP撑持多态性。
function niceDrawing($x) {
//Supose this is a method of the class Board.
$x->draw();
}
$obj=new Circle(3,187);
$obj2=new Rectangle(4,5);
$board->niceDrawing($obj); //will call the draw method of Circle.
$board->niceDrawing($obj2); //will call the draw method of Rectangle.
?>
PHP的面向对象编程
纯对象论者以为PHP不是真实的面向对象言语,这是对的。PHP是一种夹杂言语,你可以用面向对象或传统布局编程的办法来利用它。关于大型工程,但是你能够或需求利用纯面向对象办法来界说类,并在你的工程中只利用对象和类。愈来愈大的工程经由过程利用面向对象的办法会取得好处,面向对象工程十分轻易保持,轻易了解而且重用。这是软件工程的根基。利用这些概念在网站设计中是将来胜利的关头。
PHP中的初级面向对象手艺
在回忆面向对象的根基概念以后,我将引见一些更初级的手艺。
串行化
PHP其实不撑持耐久性对象,在面向对象言语中耐久性对象是一些经由使用法式屡次挪用依然坚持其形态和功效的对象,这意味着有一种能保留对象到文件或数据库中然后从头装载对象。这类机制称之为串行化。PHP 有一个串行化函数,可以在对象中挪用,串行化函数前往一个字符串代表这个对象。然后串行化函数保留的是成员数据而不是成员函数。
在PHP4中,假如你串行化一个对象到字符串 $s, 然后删除此对象,再反串行化对象到 $obj, 你依然可以挪用对象的办法函数。但我不保举这类办法,这由于(a)这类功效在未来纷歧定撑持(b)这招致一种幻象,假如你保留串行化对象到磁盘并加入法式。未来从头运转此剧本时你不克不及反串行化此对象并但愿对象的办法函数仍无效,由于串行化出来的字符串并没有暗示任何成员函数。最初,串行化保留对象的成员变量在PHP中十分有效,仅仅如斯. (你可以串行化结合数组和数组到磁盘里)。
例子:
$obj=new Classfoo();
$str=serialize($obj);
// Save $str to disk
//...some months later
//Load str from disk
$obj2=unserialize($str)
?>
上例中,你可以恢复成员变量而没有成员函数(依据文档)。这招致 $obj2->x 是独一的办法来存取成员变量(由于没有成员函数)。
这里还有一些办法处理这个成绩,但我留下给你由于它会弄脏这个洁净的文档。
我但愿PHP未来能周全撑持串行化。
利用类来把持保留的数据
PHP和面向对象编程中一个对照好的中央是你很轻易界说类来把持某些器材,而且当需求时挪用适合的类。假定有一个HTML文件,你需求经由过程选择产物的ID号来选择一个产物,你的数据保留在数据库中,而你想显示产物的信息,如价钱等等。你有分歧品种的产物,一样的举措对分歧的产物有分歧的寄义。
例如,显示一个声响意味着播放它,而对其他产物来讲多是显示一个存储在数据库的图片。你可以用面向对象编程和PHP来到达,代码少但更好。
界说一个类,界说类应当有的办法,然后经由过程承继来界说每种产物的类(SoundItem类, ViewableItem类,等等),重界说每一个产物类的办法,使它们如你所需。依据你保留在数据库中的表的产物类型字段来给每种产物类型界说一个类,一个典范的产物表应有字段(id, 类型, 价钱, 描写,等等)。
在剧本中你从数据库的表中获得类型信息,然后实例化响应类的对象:
$obj=new $type();
$obj->action();
?>
这是PHP对照的特征,你可以挪用 $obj 的显示办法或其他办法而不必去管对象的类型。经由过程这类手艺,当你增添一种新类型的对象时,你不需求去修正剧本。这个办法有点威力,就是界说一切对象应有的办法而不论它的类型,然后在分歧的类中以分歧的体例来完成,如许就能够在剧本中对分歧的类型对象利用他们,再没有 if, 没有两个法式员在统一个文件里,永久康乐。你信任编程是如许康乐不?保护价值小而且可重用?
假如你率领一组法式员,最好的办法是划分义务,每人可以对某品种和对象担任。国际化可以用一样的手艺处理,使适合的类对应利用者选择的分歧的言语等等。
复制和克隆
当你创立一个对象 $obj, 你可使用 $obj2 = $obj 来拷贝一个对象,新的对象是 $obj 的一个拷贝(不是援用),所以在赋值完新对象有 $obj 同新的形态。有时分你不想如许,只想创立和 obj 一样的新对象,挪用新对象的机关函数好像你曾利用过 new 号令。这可以经由过程PHP的串行化和利用基类而且其他类必需从基类承继来到达。
停止风险的地带
当你串行化一个对象,你失掉一个有特定格局的字符串,假如你有猎奇心,能够你会探访个中的奥密,字符串中有一个器材就是类的名字,你可以解开它:
$herring=serialize($obj);
$vec=explode(:,$herring);
$nam=str_replace("\"",\,$vec[2]);
?>
假定你创立一个类 "Universe" 而且使一切类都从 "Universe" 承继而来,你可以在 "Universe" 界说一个克隆的办法:
class Universe {
function clone() {
$herring=serialize($this);
$vec=explode(:,$herring);
$nam=str_replace("\"",\,$vec[2]);
$ret=new $nam;
return $ret;
}
}
//Then:
$obj=new Something();
//Something extends Universe !!
$other=$obj->clone();
?>
你所得的是类 Something 的新对象好像利用 new 一样,而且机关函数被挪用等等。我不晓得这对你是否是有效,这是一个很好的理论,Universe 类晓得它的承继类的名字。对你来讲,独一的限制是你的想象力!!!
注重:我利用的是PHP4, 文章里有些器材能够不合适PHP3。
看看西,人家这个编论坛,那个CMS,还有那啥CRM,我啥时候写一个呢? |
|