免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1644 | 回复: 3
打印 上一主题 下一主题

请教个语法问题,关于一次进行多层调用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-05-24 11:08 |只看该作者 |倒序浏览
PHP 4.3.11下,
    $page_data = $form->get_pager()->get_page_data();
这种写法是错误的,可以写成:
       $pager = $form->get_pager();
       $page_data = $pager->get_page_data();

小弟我孤陋寡闻,请问能把上面两行写成一行吗?

论坛徽章:
0
2 [报告]
发表于 2007-05-24 22:01 |只看该作者
不知道下文能否对你有所帮助,注意那些引用符“&”
由于构建一个指向彼此的对象网络是所有面向对象设计模式的基础,这个改进具有非常重大的意义.当引用允许建立更多强大的面向对象应用程序, PHP4对待对象和其它类型数据相同的做法带给开发者极大的痛苦.就像任何PHP4的程序员将会告诉你的, 应用程序将会遭遇WTMA(Way Too Many Ampersands过多&)综合症. 如果你想构建一个实际应用,你会感到极为痛苦,看看例6.21你就明白.

Listing 6.21 Problems with objects in PHP 4 PHP4中使用对象的问题

class MyFoo

{

function MyFoo()

{

$this->me = &$this;

$this->value = 5;

}

function setValue($val)

{

$this->value = $val;

}

function getValue()

{

return $this->value;

}

function getValueFromMe()

{

return $this->me->value;

}

}

function CreateObject($class_type)

{

switch ($class_type)

{

case "foo":

$obj = new MyFoo();

break;

case "bar":

$obj = new MyBar();

break;

}

return $obj;

}

$global_obj = CreateObject ("foo");

$global_obj->setValue(7);

print "Value is " . $global_obj->getValue() . "n";

print "Value is " . $global_obj->getValueFromMe() . "n";

让我们一步步来讨论. 首先,有一个MyFoo类.在构造函数里,我们给$this->me一个引用,并设定
我们有其它三个成员函数: 一个设定this->value的值;一个返回this->value的值;另一个返回this->value->me的值. 但是--$this不是相同的东西吗? MyFoo::getValue()和MyFoo::getValueFromMe()返回的值不是一样的吗?

首先,我们调用CreateObject("foo"),这会返回一个MyFoo类型的对象. 然后我们调用MyFoo::setValue(7). 最后,我们调用MyFoo::getValue() 和MyFoo::getValueFromMe(), 期望得到返回值7.

当然,如果我们在任何情况下都得到7, 以上这个例子将不是本书中最没有意义的例子. 所以我相信你已经猜到—我们得不到两个7这样的结果.

但是我们将得到什么结果,并且更重要地,为什么呢?

我们将得到的结果分别是7和5. 至于为什么—--有三个很好的理由.

首先,看构造函数. 当在构造函数内部,我们在this和this->me间建立引用. 换句话说,this和this->me是同个东西. 但是我们是在构造函数内. 当构造函数结束,PHP要重新建立对象(new MyFoo的结果,第28行)分配给$obj. 因为对象没有特殊化对待,就像其它任何数据类型一样,赋值X给Y意味着Y是X的一个副本. 也就是说,obj将是new MyFoo的一个副本,而new MyFoo是一个存在于构造函数的对象. Obj->me怎么样呢? 因为它是一个引用,它原封不动仍然指向原来的对象—this. Voila-obj和obj->me不再是同个东西了—改变其中一个另一个不变.

以上是第一条理由. 还有其它类似于第一条的理由. 奇迹般地我们打算克服实例化对象这个问题(第28行). 一旦我们把CreateObject返回的值赋给global_object,我们仍然要撞上相同的问题—global_object将变成返回值的一个副本,并且再次地,global_object和global_object->me将不再相同. 这就是第二条理由.

但是,事实上我们还走不了那么远— 一旦CreateObject返回$obj,我们将破坏引用(第34行) . 这就是第三条理由.

那么,我们如何改正这些? 有两个选择. 一是在所有地方增加&符号,就像例6.22那样(第24, 28, 31, 37行). 二.如果你幸运地使用上了PHP5,你可以忘了以上这一切,PHP5会自动为你考虑这些. 如果你想知道PHP5是如何考虑这些问题的,继续阅读下去.

Listing 6.22 WTMA syndrome in PHP 4 PHP4中的WTMA综合症

class MyFoo

{

function MyFoo()

{

$this->me = &$this;

$this->value = 2;

}

function setValue($val)

{

$this->value = $val;

}

function getValue()

{

return $this->value;

}

function getValueFromMe()

{

return $this->me->value;

}

}

function &CreateObject($class_type)

{

switch ($class_type)

{

case "foo":

$obj =& new MyFoo();

break;

case "bar":

$obj =& new MyBar();

break;

}

return $obj;

}

$global_obj =& CreateObject ("foo");

$global_obj->setValue(7);

print "Value is " . $global_obj->getValue() . "n";

print "Value is " . $global_obj->getValueFromMe() . "n";

PHP5是第一个把对象看成与其它类型数据不同的PHP版本. 从用户的角度看,这证明它非常明白的方式—在PHP5中,对象总是通过引用来传递,而其它类型数据(如integer,string,array)都是通过值来传递. 最显著地,没有必要再用&符号来表示通过引用来传递对象了.

面向对象编程广泛利用了对象网络和对象间的复杂关系,这些都需要用到引用. 在PHP的前些版本中,需要显示地指明引用. 因此, 现在默认用引用来移动对象,并且只有在明确要求复制时才复制对象,这样比以前更好.

它是如何实现的呢?

在PHP5之前,所有值都存在一个名为zval(Zend Value)的特殊结构里. 这些值可以存入简单的值,如数字和字符串,或复杂的值如数组和对象. 当值传给函数或从函数返回时,这些值会被复制,在内存的另一个地址建立一个带有相同内容的结构.

在PHP5中,值仍存为zval结构中,但对象除外. 对象存在一个叫做Object Store的结构里,并且每个对象有一个不同的ID. Zval中,不储存对象本身,而是存着对象的指针. 当复制一个持有对象的zval结构,例如我们把一个对象当成参数传给某个函数,我们不再复制任何数据. 我们仅仅保持相同的对象指针并由另一个zval通知现在这个特定的对象指向的Object Store. 因为对象本身位于Object Store,我们对它所作的任何改变将影响到所有持有该对象指针的zval结构.这种附加的间接作用使PHP对象看起来就像总是通过引用来传递,用透明和有效率的方式.

使用PHP5,我们现在可以回到示例6.21,除去所有的&符号, 一切代码都仍然可以正常工作.当我们在构造函数(第4行)中持有一个引用时一个&符号都不用.

[ 本帖最后由 sunnyfun 于 2007-5-24 22:16 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2007-05-25 09:17 |只看该作者
LS的,你贴那么多一堆东西是准备让版主给你发稿费?

论坛徽章:
0
4 [报告]
发表于 2007-05-25 10:57 |只看该作者
原帖由 kytexzy 于 2007-5-24 11:08 发表
PHP 4.3.11下,
    $page_data = $form->get_pager()->get_page_data();
这种写法是错误的,可以写成:
       $pager = $form->get_pager();
       $page_data = $pager->get_page_data();

...

$page_data = $form->get_pager()->get_page_data();
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP