PHP网页编程之PHP4之真OO
终于理解了数据库的概念,而且让你兴奋不已的是你终于可以通过PHP来连接数据库了,这期间你是怎么学会的,我们不去考证了,但是事实证明,你已经可以了。 本文的作者Johan Persson是PHP中有名的JpGraph图表类库的开辟者. 本文是作者关于在PHP4中停止面向对象开辟时需求注重的几个小成绩的总结.翻译: Binzy Wu , 程度无限, 接待切磋. 2004-2-4
简介
本文的对象是那些曾利用加倍成熟的OO 言语, 如Eiffel, Java, C# or C++(), 停止开辟的伴侣(如我本人). 在利用PHP4停止完整的OO开辟时有着很多的语义 (semantic)
上的圈套.
希本文内容可助人避我曾犯之错.
援用 VS 拷贝语义
这根基上是毛病的次要来历(最少关于我来讲).即便在PHP的文档中你可以读到PHP4较之援用更多利用拷贝语义(如其他我所知的面向对象言语), 但这仍将使你最初在一些渺小的地方困扰.
接上去的两局部用于论述二个小的例子, 在这二个例子中拷贝语义或许会令你惊奇.
要时辰切记主要的是一个类的变量不是一个指向类的指针而是实践的类本人自己. 大多半成绩激发自关于赋值操作符(=)的曲解, 即觉得是给一个对象一一般名, 而实践上倒是一个新的拷贝. 例如假定$myObj是某个类的实例, 而且它有一个Set()办法. 那末上面的代码或许不会像一个C++(或Java)法式员所希冀的那样任务.
function SomeFunction($aObj) { $aObj->Set(10); }
…
SomeFunction ($myObj);
…
那末如今, 很轻易便会以为该函数所挪用的Set()办法会感化于$myObj. 但这是错的!
其实产生的是$myObj被拷贝为一个新的, 与原对象一样的拷贝----参数$aObj. 然后当Set()办法被挪用时, 它仅仅感化于当地拷贝而非原参数----$myObj.
在包括直接或直接(如上)赋值操作的中央就会产生各类各样的上述成绩.
为了函数能像你所希冀的那样举动(或许是), 那末你不能不经由过程修正办法声名来告知PHP利用援用来传递对象, 如:
Function SomeFunction(&$aObj)
假如你再一次测验考试下面的代码, 那末你会发明Set()办法将感化于本来的参数上, 由于如今咱们在感化中创立了一个$myObj的别号----$aObj.
然而你不能不当心, 由于即便是&操作符也不是在任什么时候候都能救你, 以下面的举例.
从一个援用来取得援用
假定有以下代码:
$myObject = new SomeClass();$myRefToObject = &$myObject;
假如咱们如今想要一个援用的拷贝(因某些来由), 那末咱们要做甚么呢? 你能够会因为$myRefToObject已是援用而试图那末写:
$myCopyRefToObject = $myRefToObject;
准确么? 不! PHP会创立$myRefToObject所援用对象的新拷贝. 假如你想拷贝一个对象的援用, 你不能不这么写:
$myCopyRefToObject = &$myRefToObject;
在与前所述例子相当的C++的例子中, 便会创立一个援用的援用. 与其在PHP中分歧. 这是一个经历丰厚的C++法式员常会作的直觉假定相反的, 而这会是你的PHP法式中小BUG的来历.
请当心由此所发生的直接(传递参数)或直接的成绩.
我团体所告竣的结论, 即最好的防止这些语义圈套的办法是老是用援用来传递对象或对象赋值. 这不单单改善了运转速度(更少的数据拷贝), 并且可以对像我如许的老狗而言使语义加倍可展望.
在机关函数中对$this利用援用
在一个对象的机关函数里初始化作为其他对象发明者(Observer)的对象是一个罕见的形式. 上面几行代码即是一个示例:
class Bettery
{
function Bettery() {…};
function AddObserver($method, &$obj)
{
$this->obs[] = array($obj, &$method)
}
function Notify(){…}
}
class Display
{
function Display(&$batt)
{
$batt->AddObserver("BatteryNotify",$this);
}
function BatteryNotify() {…}
}
然而, 这其实不会正常任务, 假如你是这么实例化对象的:
$myBattery = new Battery();$myDisplay = new Display($myBattery);
这么做的毛病在于new时在机关函数中利用$this其实不会前往统一个对象. 反而会前往比来创立对象的一个拷贝. 即在挪用AddObserver()时所传送的对象于原对象不是统一个. 然后当Battery类测验考试告诉一切它的察看者(Observer)(经由过程挪用他们的Notify办法)时, 它其实不会挪用咱们所创立的Display类而是$this所代表的类(即咱们所创立的Display类的拷贝). 因而假如Notify()办法更新了一些实例变量, 其实不像咱们所假想原Display类会被更新, 由于更新的实际上是个拷贝. 为了让它任务, 你必需使机关函数前往统一个对象, 正如与最后$this所意味的那样. 可以经由过程添加&符号于Display的机关, 如$myDisplay = & new Display($myBattery);
一个直接的了局是任何Display类的Client必需懂得Display的完成细节. 现实上, 这会发生一个能够引发争辩的成绩: 一切对象的构建必需利用额定的&符号. 就我所说的根基上是平安的, 但疏忽它能够会在某些时分失掉不想要的如上述示例般的感化.
在JpGraph中利用了另外一种办法来处理. 即需求利用经由过程添加一个能平安的利用&$this援用的”Init()”办法的所谓二阶段机关来”new”一个对象(仅仅是由于在机关函数中的$this援用前往对象的一个拷贝而不如所希冀的那样履行). 因而下面的例子会以下完成:
$myBattery = new Battery();
$myDisplay = new Display();
$myDisplay->Init($myBattery);
如JPGraph.php中的”LinearScale”类.
利用foreach
别的一个类似代码却分歧了局的成绩是”foreach”布局的成绩. 研讨一下上面的二个轮回布局的分歧版本.
// Version 1
foreach( $this->plots as $p )
{
$p->Update();
}
…
// Version 2
for( $i=0; $i<count($this->plots); ++$i )
{
$this->plots[$i]->Update();
}
如今是一个价值10美元的成绩: version1==version2么?
使人惊奇的谜底是:No! 这是渺小倒是关头的分歧. 在Version 1中, Update()办法将感化于”plots[]”数组中对象的正本. 因而数组华夏来的对象其实不会被更新.
在Version 2中Update()办法将如预期的感化于”plots[]”数组中的对象.
正如第一局部所陈说的, 这是PHP将对象实例作为对象自己来处置而非作为对象援用的了局.
译注:
. OO: Object-Oriented, 面向对象.
. 原文并没有C#, 全因Binzy的团体喜好.
. Semantic在本文中被译为”语义”, 若有任何建议请和Binzy接洽.
. C++中有一本有名的”C++ Gotchas”.
. 这里的类应当是指Instance, 即实例.
. 可拜见””, 即”Design Patterns”.
. 有个挺风趣的关于买卖的小故事:
有人用60美元买了一匹马, 又以70美元的代价卖了出去;然后, 他又用80美元把它买回来, 最初以90美元的代价卖出.在这桩马的买卖中, 他? (A)赔了10美元; (B)出入均衡; 遇到出错的时候,我经常把错误信息直接复制到 google的搜索栏,一般情况都是能搜到结果的,不过有时候会搜出来一大片英文的出来,这时候就得过滤一下,吧中文的弄出来,挨着式方法。 当然这种网站的会员费就几十块钱。 说php的话,首先得提一下数组,开始的时候我是最烦数组的,总是被弄的晕头转向,不过后来呢,我觉得数组里php里最强大的存储方法,所以建议新手们要学好数组。 有位前辈曾经跟我说过,phper 至少要掌握200个函数 编起程序来才能顺畅点,那些不熟悉的函数记不住也要一拿手册就能找到。所以建议新手们没事就看看php的手册(至少array函数和string函数是要记牢的)。 如果你已经到这种程度了,那么你已经可以做我的老师了。其实php也分很多的区域, 最后祝愿,php会给你带来快乐的同时 你也会给他带来快乐。 首先我是坚决反对新手上来就用框架的,因为对底层的东西一点都不了解,造成知识上的真空,会对以后的发展不利。我的观点上手了解下框架就好,代码还是手写。当然啦如果是位别的编程语言的高手的话,这个就另当别论啦。 对于初学者来说不推荐去拿钱买的。当然如果一个网站你经常去用,而且里面的资料也比较有用,最好还是买个会员比较好,毕竟那些也是别人的工作成果。 学习php的目的往往是为了开发动态网站,phper就业的要求也涵盖了很多。我大致总结为:精通php和mysql 做为1门年轻的语言,php一直很努力。 爱上php,他也会爱上你。 ,熟悉html,能用div+css,还有javascript,优先考虑linux。我在开始学习的时候,就想把这些知识一起学习,我天真的认为同时学习能够互相呼应,因为知识是相通的。 为了以后维护的方便最好是代码上都加上注释,“予人方便,自己方便”。此外开发文档什么的最好都弄齐全。我觉得这是程序员必备的素质。虽然会消耗点很多的时间。但是确实是非常有必要的。 有时候汉字的空格也能导致页面出错,所以在写代码的时候,要输入空格最好用引文模式。 使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。 再就是混迹于论坛啦,咱们的phpchina的论坛就很强大,提出的问题一般都是有达人去解答的,以前的帖子也要多看看也能学到不少前辈们的经验。别的不错的论坛例如php100,javaeye也是很不错的。 多看优秀程序员编写的代码,仔细理解他们解决问题的方法,对自身有很大的帮助。 装在C盘下面可以利用windows的ghost功能可以还原回来(顺便当做是重转啦),当然啦我的编译目录要放在别的盘下,不然自己的劳动成果就悲剧啦。 兴趣是最好的老师,百度是最好的词典。
页:
[1]