仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 1714|回复: 20
打印 上一主题 下一主题

[学习教程] PHP教程之探秘PHP 5的对象重载手艺

[复制链接]
愤怒的大鸟 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-2-3 23:30:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
基础这个东西,有人问学php需要任何基础不?    PHP 5中引入了对象重载手艺,本文将切磋关于办法__call(),__set()和__get()停止重载的能够性。在对重载实际作复杂引见后,咱们将经由过程两个例子直奔主题:第一例,完成延续存储类;第二例,找到一种完成静态的getter/setter的办法。
   
  1、甚么是对象重载?
  在PHP中谈到对象重载时,咱们要区分两品种型:
  ◆办法重载
  ◆属性重载
  在办法重载的情形下,咱们要界说一个魔术般的办法__call(),它将完成一个在响应类中对不决义办法的笼统挪用。只要当你想存取类中不决义的办法时,这类笼统办法才会被挪用。在没无方法重载的情形下,上面的例子将招致PHP显示一条致命毛病信息:Call to undefined method ThisWillFail::bar() in/some/directory/example.php on line 9并流产法式的履行:
复制代码

    1. <?php  
    复制代码

  •  class ThisWillFail {   
  • public function foo() {   
  •  return "Hello World!";   
  • }   
  •  }   
  •  $class = new ThisWillFail;   
  •  $class->bar();   
  • ?>   
  借助办法重载的匡助,代码可以捕捉到这类挪用且可以面子地赐与处置。属性重载与办法重载差不多。这类情形下,类把读/写操作重定向(亦可称代办署理)到类的属性,这些属性在类中没有显式界说。这里的专门办法是__set()和__get()。依附于毛病呈报品级,PHP翻译器凡是在存取一个不决义的属性时,或收回一个告诉,或推延一下并潜伏地界说这个变量。
  而假如利用属性重载,翻译器却可以在设置一个不决义的属性时挪用__set(),而在存取一个不决义的属性值时挪用__get()。综上所述,使用重载手艺可以完成在象用PHP如许的静态言语停止时软件开辟工夫的大大延长。
  2、延续性存储类举例
  以下代码,经由过程利用属性重载手艺,用少于50行的PHP代码完成了下面所提到的延续性存储类。术语persistable意味着类可以从一个数据布局中描写一个元素,并坚持与底端存储体系的同步。用编码的注释就是,内部代码可使用类来完成从一个数据库表当选定一行。
  如许,在法式运转时,可以直接存取类的属性来把持该行中的元素(读/取)。在剧本停止时,PHP将担任把更新的行数据回送到数据库中去。精心研读上面代码将有助于你了解甚么是属性重载。
复制代码

    1. <?php  
    复制代码

  •  //装入PEAR的 <a href="http://pear.php.net/package/DB/">DB package</a>   
  •  require_once "DB.php";   
  •  class Persistable {   
  • private $data = array();   
  • private $table = "users";   
  • public function __construct($user) {   
  •  $this->dbh = DB::Connect("mysql://user:password@localhost/database");   
  •  $query = "SELECT id, name, email, country FROM " .   
  •  $this->table . " WHERE name = ?";   
  •  $this->data = $this->dbh->getRow($query, array($user),   
  •  DB_FETCHMODE_ASSOC);   
  • }   
  • public function __get($member) {   
  •  if (isset($this->data[$member])) {   
  • return $this->data[$member];   
  •  }   
  • }   
  •    
  • public function __set($member, $value) {   
  •  // dataset的ID是只读的   
  •  if ($member == "id") {   
  • return;   
  •  }   
  •  if (isset($this->data[$member])) {   
  • $this->data[$member] = $value;   
  •  }   
  • }   
  • public function __destruct() {   
  •  $query = "UPDATE " . $this->table . " SET name = ?,   
  •  email = ?, country = ? WHERE id = ?";   
  •  $this->dbh->query($query, $this->name, $this->email,   
  •  $this->country, $this->id);   
  • }   
  •  }   
  •  $class = new Persistable("Martin Jansen");   
  •  $class->name = "John Doe";   
  •  $class->country = "United States";   
  •  $class->email = "john@example.com";   
  • ?>   
  你碰到的第一个成绩多是__construct(),这是PHP 5中引入的新的机关器办法。在PHP 4时期,机关器老是与它们的类名相婚配。在PHP 5中已不再是如许。你不需求对机关器办法有过量的懂得,除挪用它可以创立一个类的实破例;并注重到,这里利用了一个参数 - 履行一个基于此参数的数据库。此机关器把查询了局赋值给类属性$data。
  接上去,法式界说了两个出格的办法__get()和__set()。你应当对它们早已熟习:__get()用于读取不决义的属性值,__set()用于修正不决义的属性值。
  这意味着不管甚么时分从延续性存储类中读取/写入一个不决义的属性,由这些专门办法来担任办理在属性数组变量$data中的信息,而不是直接改动类的属性(切记:变量$data包括着来自于数据库中的一行!)。
  类中的最初一个办法是__construct()的对峙者- 析构器__destruct()。PHP在"剧本封闭阶段"挪用析构器,典范地这是在PHP剧本履行将近停止的时分。析构器把来自于$data属性的信息写回到数据库中去。这恰是后面同步(synchronization )术语的寄义。
  你能够早已注重到,这里的代码利用了PEAR的数据库笼统层包(database abstraction layer package)。其实这无所谓,经由过程其余体例与数据库通信也一样能申明本文的主题。
  假如你仔细察看,会发明该延续性存储类的描写对照复杂。例子中仅触及了一个数据库表,而没有思索更庞杂的数据模子,如利用LEFT JOIN和其它庞杂的数据库操作手艺。但是你不用受此束缚,借助于属性重载,你可使用你本人幻想的数据库模子。只需求到场少量代码,你便可以在该延续性存储类中应用庞杂的数据库特征。
  还存在一个小成绩 - 当在析构器中查询掉败时并没有引入毛病处置机制。是析构器的天分招致在这类情形下不成能显示响应的毛病信息,由于构建HTML标记经常在PHP挪用构析器之前就已停止了。
  为处理这个成绩,你可以把__destruct()重定名为象saveData()如许的名字并在挪用剧本的某处手工履行这一办法。这关于类的延续性存储的概念并没有任何改动;仅是多写几行代码罢了。作为选择,你还可以在析构器中利用函数error_log()来纪录上司于体系局限的毛病纪录文件中的毛病信息。属性重载的任务机制就是如许。上面咱们会商一下办法重载。
   3、办法重载举例
  1. 静态的Getter/Setter办法
  以下代码完成了"静态"getter/setter办法以借助于办法重载的匡助来掌握类。上面咱们联合源代码停止剖析:
复制代码

    1. <?php  
    复制代码

  •  class DynamicGetterSetter {   
  • private $name = "Martin Jansen";   
  • private $starbucksdrink = "Caramel Cappuccino Swirl";   
  • func   
复制代码

    1. tion __call($method, $arguments) {  
    复制代码

  •  $prefix = strtolower(substr($method, 0, 3));   
  •  $property = strtolower(substr($method, 3));   
  •  if (empty($prefix)  empty($property)) {   
  • return;   
  •  }   
  •  if ($prefix == "get" && isset($this->$property)) {   
  • return $this->$property;   
  •  }   
  •  if ($prefix == "set") {   
  • $this->$property = $arguments[0];   
  •  }   
  • }   
  •  }   
  •  $class = new DynamicGetterSetter;   
  •  echo "Name: " . $class->getName() . "\n";   
  •  echo "Favourite Starbucks flavour: " . $class->getStarbucksDrink() . "\n\n";   
  •  $class->setName("John Doe");   
  •  $class->setStarbucksDrink("Classic Coffee");   
  •  echo "Name: " . $class->getName() . "\n";   
  •  echo "Favourite Starbucks flavour: " . $class->getStarbucksDrink() . "\n\n";   
  • ?>   
  很分明,这里的两个属性$name和$starbucksdrink都是公有的,就是说从类的内部是不克不及够存取这些属性的。在面向对象的编程中,完成公共的getter/setter办法来存取或修正非公共属性的值是很常常的工作。完成这些是单调的工作,且相当消耗工夫和精神。
  借助于办法重载可以轻易得处理这个成绩。不是为每一个属性完成getter/setter办法,下面只完成了一个通用的__call()办法。这意味着当挪用一个不决义的getter/setter办法如setName()或getStarbucksdrink()时,PHP不会发生一个致命毛病而流产,而是履行(或代办署理到)魔术般的__call()办法。这是些复杂引见,上面咱们对__call()作一下深切剖析。
  2. 具体剖析__call()办法
  __call()的第一个参数是原始的且还没有肯定的办法(如setName),第二个参数是一个数字索引的一维数组,它包括了原始办法的一切参数。用两个参数("Martin"和42)挪用一个不决义的办法将发生上面数组:
复制代码

    1. $class->thisMethodDoesNotExist("Martin", 42);  
    复制代码

  • /导向__call()的第二个参数   
  • Array   
  • (   
  • [0] => Martin   
  • [1] => 42   
  • )   
  在办法__call()外部,假如原始办法以get或set开首,则要停止某种盘算以肯定是不是代码挪用的是一个getter/setter办法。并且,这类办法还要进一步剖析办法名的别的一构成局部(除去入手下手的三个字符),由于前面这局部字符串正代表getter/setter参照的属性的名字。
  假如办法名中唆使有一个getter/setter,那末该办法或前往响应的属性值,或设置原始办法的第一个参数的值。假如没有的话,它不做任何工作,持续履行法式,好象没有工作产生。
  3. 完成方针
  本色上,响应于恣意的属性,存在一种办法答应代码静态地挪用恣意的getter/setter办法,这类算法是存在的。这在短时间内开辟一个法式原型的情形下是很便利的:不是消费大批工夫来完成getters/setters,开辟人员可以专注于建模API并包管使用法式的基本准确。把__call()办法归入到一个笼统类中乃至有能够使你在未来的PHP工程开辟中完成代码的重用!
  4. 缺乏以外
  有长处就出缺点。以上办法也有几个缺乏:较大些的项目可以会利用象phpDocumentor如许的东西来跟踪API布局。用下面引见的静态办法,一切的getter/setter办法固然不会呈现在主动生成的文档中,这是无需多作注释的。
  别的一个缺乏是,类里面的代码可以存取类内的每个公有属性。当利用真实的getter/setter办法时,有能够区分开内部代码可以存取的公有属性和对类内部不成见的"真实的"公有属性 - 由于咱们无方法重载,并且有虚拟的getter和setter办法可以使用。
  结论
  本文经由过程两个例仔细致剖析了PHP 5中对象重载的两种情况。很但愿本文的办法匡助你进步PHP编程的任务效力!同时,你也应苏醒地看到这类办法的缺乏。
刚开始因为习惯于ASP格式的写法,总是在这些方面出现问题,自己还总是找不到问题所在,这就提醒了自己,在写代码的时候一定要认真,不能粗心地老是少个“;”或者字母大小写不分,要不然很可能找半天都找不到错误。
金色的骷髅 该用户已被删除
沙发
发表于 2015-2-3 23:51:18 | 只看该作者
开发工具也会慢慢的更专业,每个公司的可能不一样,但是zend studio是个大伙都会用的。
老尸 该用户已被删除
板凳
发表于 2015-2-9 07:35:36 | 只看该作者
如果你可以写完像留言板这样的程序,那么你可以去一些别人的代码了,
冷月葬花魂 该用户已被删除
地板
发表于 2015-2-27 04:31:08 | 只看该作者
我还是强烈建议自己搭建php环境。因为在搭建的过程中你会遇到一些问题,通过搜索或是看php手册解决问题后,你会更加深刻的理解它们的工作原理,了解到php配置文件中的一些选项设置。
爱飞 该用户已被删除
5#
发表于 2015-3-6 15:22:06 | 只看该作者
实践是检验自己会不会的真理。
愤怒的大鸟 该用户已被删除
6#
 楼主| 发表于 2015-3-13 03:09:43 | 只看该作者
没接触过框架的人,也不用害怕,其实框架就是一种命名规范及插件,学会一个框架其余的框架都很好上手的。
变相怪杰 该用户已被删除
7#
发表于 2015-3-20 07:22:33 | 只看该作者
你很难利用原理去编写自己的代码。对于php来说,系统的学习我认为还是很重要的,当你有一定理解后,你可你针对某种效果研究,我想那时你不会只是复制代码的水平了。
第二个灵魂 该用户已被删除
8#
发表于 2015-3-24 18:05:19 | 只看该作者
个人呢觉得,配wamp 最容易漏的一步就是忘了把$PHP$目录下的libmysql.dll拷贝到windows系统目录的system32目录下,还有重启apache。
若天明 该用户已被删除
9#
发表于 2015-3-27 16:40:21 | 只看该作者
因为blog这样的可以让你接触更多要学的知识,可以接触用到类,模板,js ,ajax
精灵巫婆 该用户已被删除
10#
发表于 2015-4-1 00:12:00 | 只看该作者
当留言板完成的时候,下步可以把做1个单人的blog程序,做为目标,
兰色精灵 该用户已被删除
11#
发表于 2015-4-10 00:49:00 | 只看该作者
为了以后维护的方便最好是代码上都加上注释,“予人方便,自己方便”。此外开发文档什么的最好都弄齐全。我觉得这是程序员必备的素质。虽然会消耗点很多的时间。但是确实是非常有必要的。
莫相离 该用户已被删除
12#
发表于 2015-4-11 01:11:03 | 只看该作者
其实没啥难的,多练习,练习写程序,真正的实践比看100遍都有用。不过要熟悉引擎
小女巫 该用户已被删除
13#
发表于 2015-4-16 20:51:33 | 只看该作者
我要在声明一下:我是个菜鸟!!我对php这门优秀的语言也是知之甚少。但是我要在这里说一下php在网站开发中最常用的几个功能:
再现理想 该用户已被删除
14#
发表于 2015-4-26 15:10:48 | 只看该作者
因为blog这样的可以让你接触更多要学的知识,可以接触用到类,模板,js ,ajax
谁可相欹 该用户已被删除
15#
发表于 2015-4-29 16:56:18 | 只看该作者
刚开始安装php的时候,我图了个省事,把php的扩展全都打开啦(就是把php.ini 那一片 extension 前面的冒号全去掉啦),这样自然有好处,以后不用再需要什么功能再来打开。
不帅 该用户已被删除
16#
发表于 2015-4-29 22:55:48 | 只看该作者
最后介绍一个代码出错,但是老找不到错误方法,就是 go to wc (囧),出去换换气没准回来就找到错误啦。
简单生活 该用户已被删除
17#
发表于 2015-5-2 00:48:24 | 只看该作者
先学习php和mysql,还有css(html语言很简单)我认为现在的效果比以前的方法好。
灵魂腐蚀 该用户已被删除
18#
发表于 2015-6-19 21:06:54 | 只看该作者
我学习了一段时间后,我发现效果并不好(估计是我自身的问题)。因为一个人的精力总是有限的,同时学习这么多,会导致每个的学习时间都得不到保证。
山那边是海 该用户已被删除
19#
发表于 2015-7-1 16:49:11 | 只看该作者
学好程序语言,多些才是王道,写两个小时代码的作用绝对超过看一天书,这个我是深有体会(顺便还能练打字速度)。
分手快乐 该用户已被删除
20#
发表于 2015-7-4 01:21:05 | 只看该作者
使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-5-3 12:06

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表