从零开始攻略PHP(8)——面向对象(下)

8.编写代码类

  每个分离的函数可以执行一个明确的任务。任务越简单,编写与测试这个函数就越简单,当然也不要将这个函数分得太小——若将程序分成太多的小个体,读起来就会很困难。

  使用继承可以重载操作。我们可以替换成一个大的Display()函数,但是改变整个页面的显示方式几乎是不可能的。将显示功能分成几个独立的任务则更好,这样我们可以只需重载需要改变的部分。

  如下所示的page类提供了简单灵活的方法来创建页面:

<?php
class Page
{// class Page's attributespublic $content;  //页面的主要内容public $title = "TLA Consulting Pty Ltd";   //页面的标题public $keywords = "TLA Consulting, Three Letter Abbreviation, some of my best friends are search engines";   //metatags便于搜索引擎对其检索public $buttons = array("Home"   => "home.php", "Contact"  => "contact.php", "Services" => "services.php", "Site Map" => "map.php");    //使用一个数组来保存按钮的文本标签以及该按钮指向的URL// class Page's operationspublic function __set($name, $value){$this->$name = $value;}   //可以从定义访问函数来设置和获得已定义的变量值开始public function Display(){echo "<html>\n<head>\n";$this -> DisplayTitle();$this -> DisplayKeywords();$this -> DisplayStyles();echo "</head>\n<body>\n";$this -> DisplayHeader();$this -> DisplayMenu($this->buttons);echo $this->content;$this -> DisplayFooter();echo "</body>\n</html>\n";}public function DisplayTitle(){echo "<title>".$this->title."</title>";}public function DisplayKeywords(){echo "<meta name=\"keywords\" content=\"".$this->keywords."\"/>";}public function DisplayStyles(){ 
?>   <style>h1 {color:white; font-size:24pt; text-align:center; font-family:arial,sans-serif}.menu {color:white; font-size:12pt; text-align:center; font-family:arial,sans-serif; font-weight:bold}td {    background:black}p {color:black; font-size:12pt; text-align:justify; font-family:arial,sans-serif}p.foot {color:white; font-size:9pt; text-align:center; font-family:arial,sans-serif; font-weight:bold}a:link,a:visited,a:active {color:white}</style>
<?php}public function DisplayHeader(){ 
?>   <table width="100%" cellpadding="12" cellspacing="0" border="0"><tr bgcolor ="black"><td align ="left"><img src = "logo.gif" /></td><td><h1>TLA Consulting Pty Ltd</h1></td><td align ="right"><img src = "logo.gif" /></td></tr></table>
<?php}public function DisplayMenu($buttons){echo "<table width=\"100%\" bgcolor=\"white\" cellpadding=\"4\" cellspacing=\"4\">\n";echo "<tr>\n";//calculate button size$width = 100/count($buttons);while (list($name, $url) = each($buttons)) {$this -> DisplayButton($width, $name, $url, !$this->IsURLCurrentPage($url));}echo "</tr>\n";echo "</table>\n";}public function IsURLCurrentPage($url){if(strpos($_SERVER['PHP_SELF'], $url )==false){return false;}else{return true;}}public function DisplayButton($width,$name,$url,$active = true){if ($active) {echo "<td width = \"".$width."%\"><a href=\"".$url."\"><img src=\"s-logo.gif\" alt=\"".$name."\" border=\"0\" /></a><a href=\"".$url."\"><span class=\"menu\">".$name."</span></a></td>";} else {echo "<td width=\"".$width."%\"><img src=\"side-logo.gif\"><span class=\"menu\">".$name."</span></td>";}  }public function DisplayFooter(){
?>
<table width="100%" bgcolor="black" cellpadding="12" border="0">
<tr>
<td><p class="foot">&copy; TLA Consulting Pty Ltd.</p><p class="foot">Please see our <a href ="">legal information page</a></p>
</td>
</tr>
</table>
<?php}
}
?>

  请注意函数DisplayStyles()、DisplayHeader()和DisplayFooter()需要显示没有经过PHP处理的大量静态HTML。因此,我们简单地使用了PHP结束标记(?>)、输入HTML,然后再在函数体内部使用一个PHP打开标记(<?php)。

操作IsURLCurrentPage()将判断按钮URL是否指向当前页。

  这里,我们使用了字符串函数strpos(),它可以查看给定的URL是否包含在服务器设置的变量中。strpos($__SERVER[‘PHP_SELF’], $url)语句将返回一个数字(如果$url中的字符串包含在全局变量$_SERVER[‘PHP_SELF’])或者false(如果没有包含在全局变量中)。

  首页使用page类完成生成页面内容的大部分工作:

<?phprequire("page.inc");$homepage = new Page();$homepage->content ="<p>Welcome to the home of TLA Consulting.Please take some time to get to know us.</p><p>We specialize in serving your business needsand hope to hear from you soon.</p>";$homepage->Display();
?>

  在以上的程序清单中可以看出,如果使用Page类,我们在创建新页面的时候只要做少量工作。通过这种方法使用类意味着所有页面都必须很相似。

  如果希望网站的一些地方使用不同的标准页,只要将page.inc复制到名为page2.inc的新文件里,并做一些改变就可以了。这意味着每一次更新或修改page.inc时,要记得对page2.inc进行同样的修改。

  一个更好的方法是用继承来创建新类,新类从Page类里继承大多数功能,但是必须重载需要修改的部分。

  Services页面继承了Page类,但是重载了Display()操作,从而改变了其输出结果:

<?phprequire ("page.inc");class ServicesPage extends Page{private $row2buttons = array("Re-engineering" => "reengineering.php","Standards Compliance" => "standards.php","Buzzword Compliance" => "buzzword.php","Mission Statements" => "mission.php");public function Display(){echo "<html>\n<head>\n";$this -> DisplayTitle();$this -> DisplayKeywords();$this -> DisplayStyles();echo "</head>\n<body>\n";$this -> DisplayHeader();$this -> DisplayMenu($this->buttons);$this -> DisplayMenu($this->row2buttons);echo $this->content;$this -> DisplayFooter();echo "</body>\n</html>\n";}}$services = new ServicesPage();$services -> content ="<p>At TLA Consulting, we offer a numberof services.  Perhaps the productivity of your employees wouldimprove if we re-engineered your business. Maybe all your businessneeds is a fresh mission statement, or a new batch ofbuzzwords.</p>";$services -> Display();
?>

  通过PHP类创建页面的好处是显而易见的,通过用类完成了大部分工作,在创建页面的时候,我们就可以做更少的工作。在更新页面的时候,只要简单地更新类即可。通过继承,我们还可从最初的类派生出不同版本的类而不会破坏这些优势。

  不过,用脚本创建网页要求更多计算机处理器的处理操作,应该尽量使用静态HTML网页,或者尽可能缓存脚本输出,从而减少在服务器上的载入操作。

 

9.PHP面向对象的高级功能

  9.1 使用Pre-Class常量

  可以在不需要初始化该类的情况下使用该类中的常量

class Math {const pi = 3.14159; //定义常量

}echo Math::pi;

  可以通过使用::操作符指定常量所属的类来访问Per-Class常量。

  9.2 实现静态方法

  和Pre-Class常量的思想一样,可以在未初始化类的情况下直接调用这个方法,不过,在这个静态方法中,不允许使用 this 关键字,因为可能会没有可以引用的对象。

class Math {static function squared($input) {return $input * $input;}}echo Math::squared(8);

  9.3 检查类的类型和类型提示

  instanceof 关键字允许检查一个对象的类型。可以检查一个对象是否是特定类的实例,是否是从某个类继承过来或者是否实现了某个接口。

  另外,类型检查等价于 instanceof 的作用。

function check_hint(B $someclass){// ...

}

  以上示例将要求$someclass必须是类B的实例。如果按如下方式传入了类A的一个实例:

check_hint($a);

  将产生如下所示的致命错误:

Fatal error: Argument 1 must be an instance of B

  9.4 延迟静态绑定

  PHP 5.3版本引入了延迟静态绑定(late static binding)的概念,该特性允许在一个静态继承的上下文对一个被调用类的引用。父类可以使用子类重载的静态方法。如下所示的是PHP手册提供的延迟静态绑定示例:

<?phpclass A{public static function who(){echo __CLASS__;}public static function test(){static::who(); // Here comes Late Static Bindings
}}class B extends A{public static function who(){echo __CLASS__;}}B::test();?>

  通俗的说,就是B通过继承走的A里的test(),然后通过静态延迟走的B里重载的who()。

  无论类是否被重载,允许在运行时调用类的引用将为你的类提供更多的功能。

  9.5 克隆对象

  PHP提供了 clone 关键字,该关键字允许复制一个已有的对象。

$c = clone $b;

  将创建与对象 $b 具有相同类的副本,而且具有相同的属性值。

  当然,可以自己在类中重新定义 __clone 函数,来控制克隆的过程。

  9.6 使用抽象类

  PHP提供了抽象类。这些类不能被实例化,同样类方法也没有实现,只是提供类方法的声明,没有具体实现。

abstract operationX($param1, $param2);

  包含抽象方法的任何类自身必须是抽象的。

  抽象方法和抽象类主要用于复杂的类层次关系中,该层次关系需要确保每一个子类都包含并重载了某些特性的方法,这也可以通过接口来实现。

  9.7 使用__call()重载方法

  在PHP中,__call()方法用来实现方法的重载。

<?phpclass overload {public function displayArray($array) {foreach($array as $print) {echo $print;echo "<br />";}}public function displayScalar($scalar) {echo $scalar;echo "<br />";}public function __call($method, $p) {if ($method == "display") {if (is_object($p[0])) {$this->displayObject($p[0]);} else if (is_array($p[0])) {$this->displayArray($p[0]);} else {$this->displayScalar($p[0]);}}}}$ov = new overload;$ov->display(array(1, 2, 3));$ov->display('cat');?>

  __call()方法必须带有两个参数。第一个包含了被调用的方法名称,而第二个参数包含了传递给该方法的参数数组。

  使用 __call 方法,不需要实现任何 display() 方法。

  9.8 使用__autoload()方法

  __autoload()函数将在实例化一个还没有被声明的类时自动调用。

  __autoload()方法的主要用途是尝试包含或请求任何用来初始化所需类的文件。

  9.9 实现迭代器和迭代

  可以使用foreach()方法通过循环方式取出一个对象的所有属性,就像数组方式一样。

<?phpclass myClass{public $a = "5";public $b = "7";public $c = "9";}$x = new myClass;foreach($x as $attribute){echo $attribute."<br />";}?>

  如果需要一些更加复杂的行为,可以实现一个iterator(迭代器)。要实现一个迭代器,必须将要迭代的类实现IteratorAggregare接口,并且定义一个能够返回该迭代类实例的getIterator方法。这个类必须实现Iterator接口,该接口提供了一系列必须实现的方法。

  迭代器和迭代的示例基类:

 

<?php
class ObjectIterator implements Iterator {  //迭代器 这个类实现了interator接口private $obj;private $count;private $currentIndex;function __construct($obj){$this->obj = $obj;$this->count = count($this->obj->data);}function rewind(){$this->currentIndex = 0;}function valid(){return $this->currentIndex < $this->count;}function key(){return $this->currentIndex;}function current(){return $this->obj->data[$this->currentIndex];}function next(){$this->currentIndex++;}
}class Object implements IteratorAggregate   //接口
{public $data = array();function __construct($in){$this->data = $in;}function getIterator(){return new ObjectIterator($this);   //返回迭代示例的方法
  }
}$myObject = new Object(array(2, 4, 6, 8, 10));$myIterator = $myObject->getIterator();
for($myIterator->rewind(); $myIterator->valid(); $myIterator->next())
{$key = $myIterator->key();$value = $myIterator->current();echo $key." => ".$value."<br />";
}?>

  ObjectIterator类具有Iterator接口所要求的一系列函数:

    · 构造函数并不是必需的,但是很明显,它是设置将要迭代的项数和当前数据项链接的地方。

    · rewind()函数将内部数据指针设置回数据开始处。

    · valid()函数将判断数据指针的当前位置是否还存在更多数据。

    · key()函数将返回数据指针的值。

    · value()函数将返回保存在当前数据指针的值。

    · next()函数在数据中移动数据指针的位置。

  像这样使用Iterator类的原因就是即使潜在的实现发生了变化,数据的接口还是不会发生变化。

  9.10 将类转换成字符串

  __toString()函数的所有返回内容都将被echo语句打印。

<?php$p = new Printable;echo $p;class Printable{public $testone;public $testtwo;public function __toString(){return(var_export($this, TRUE));}}?>

  var_export()函数打印出了类中的所有属性值。

  9.11 使用Reflection(反射)API

  PHP的面向对象引擎还包括反射API。反射是通过访问已有类和对象来找到类和对象的结构和内容的能力。

  显示关于Page类的信息:

<?phprequire_once("page.inc");$class = new ReflectionClass("Page");echo "<pre>".$class."</pre>";?>

  这里使用了Reflection类的__toString()方法来打印这个数据。注意,<pre>标记位于不同的行上,不要与__toString()方法混淆。

 

整理自《PHP和MySQL Web开发》

 

 

 

转载于:https://www.cnblogs.com/xulei1992/p/5806422.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/271044.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vb treeview 展开子节点_C# / VB.NET 在PPT中创建、编辑PPT SmartArt图形

本文介绍通过C#和http://VB.NET程序代码来创建和编辑PPT文档中的SmartArt图形。文中将分两个操作示例来演示创建和编辑结果。使用工具&#xff1a;Spire.Presentation for .NET hotfix 5.9.5dll文件引用&#xff1a;方式1&#xff1a;下载包&#xff1b;Spire.Presentation for…

mysql安装教程8.0.21安装,Windows系统下MySQL8.0.21安装教程(图文详解)

安装建议&#xff1a;尽量不要用.exe进行安装&#xff0c;用压缩包安装&#xff0c;对日后的卸载/版本升级更为方便下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/1、点击上面的下载地址得到zip压缩包2、解压到要安装的目录我这里是E:\database\mysql8\mysql-8.0…

Java中 a+=b和a=a+b有什么区别?

一&#xff1a;性能方面 aab是加法运算 需要两次寻找地址而ab是增量运算有寄存器优先时 只有一次地址查找。效率方面后者略高于前者 基于现在计算机的发展可忽略不计。 二&#xff1a;对于不同类型的a,b来说 1:不同类型的两个变量在进行运算的时候&#xff0c;我们经常说到的…

事务管理:事务的状态相关知识笔记

1、事务的几个概念中止事务&#xff1a;事务在执行过程中发生故障&#xff0c;不能执行完成的事务。可以进行事务回滚&#xff0c;保持数据库的一致性。事务回滚&#xff1a;将中止事务对数据库的更新操作撤销称为事务回滚。已提交事务&#xff1a;成功执行完成的事务称为已提交…

mysql符合安可要求吗,安可是什么意思?演唱太过精彩,粉丝要求返场(再唱一个)...

解答&#xff1a;安可是指再唱一个的意思&#xff0c;最早是源自英语“Encore”&#xff0c;常被用在演唱会上&#xff0c;当最后一轮表演或演唱结束之后&#xff0c;粉丝就会开始大喊“安可”&#xff0c;就是想要再听一场&#xff0c;这时歌手也会应粉丝的要求返场。安可是什…

事务管理基础:数据库的并发控制相关知识笔记

1、并发操作的概念介绍并发操作主要是指在多用户共享的系统当中&#xff0c;可能存在很多用户同时对同一个数据进行操作。并发操作会造成丢失更新、不可重复读、读脏数据。主要原因是事务的并发操作破坏了事务的隔离性。2、事务调度相关知识事务调度主要有串行调度、并发调度、…

Spring的AOP理解

Spring的AOP理解&#xff1a; OOP面向对象&#xff0c;允许开发者定义纵向的关系&#xff0c;但并适用于定义横向的关系&#xff0c;导致了大量代码的重复&#xff0c;而不利于各个模块的重用。 AOP&#xff0c;一般称为面向切面&#xff0c;作为面向对象的一种补充&#xff…

wpf 如何设置弹出窗口必须关闭才能打开其他软件_5招教你如何清除C盘除系统外的所有垃圾!都学会了吗?...

老毛桃winpe 2019-04-24 12:22:54 对于C盘&#xff0c;最让我们头疼的问题就是空间不足了&#xff01;虽然知道C盘会存有很多垃圾&#xff0c;但由于C盘也是系统盘&#xff0c;我们只能可望不可及。那么&#xff0c;有什么办法清除C盘除系统外的所有垃圾吗&#xff1f;答案是…

事务管理基础:排它锁和共享锁相关知识笔记

1、排它锁、共享锁出现的意义数据库的并发事务对数据库进行读写&#xff0c;可能会破坏事务的隔离性和数据一致性。为了保持事务的隔离性&#xff0c;系统必须对事务之间的相互作用加以控制。最典型的做法就是当一个事务访问某个数据对象时&#xff0c;其他事务都不能更新该数据…

php对象底层结构,PHP 底层原理之类和对象

对于PHPer来说&#xff0c;OOP是不可或缺的开发思维&#xff0c;但是你对php类和对象的底层实现又了解多少呢&#xff1f;本着知其然且知其所以然的思想&#xff0c;让我们一起来寻找答案~类的底层实现可看作是之前我们讲过的变量、函数等的知识集合。所以想要理解更深入的同学…

程序默认在副屏显示_聊一款性价比极高的电竞显示器

小米在6月17日开启了小米显示器27寸165Hz版本的众筹&#xff0c;这台显示器的分辨率为2560x1440&#xff0c;也就是大家熟悉的小金刚&#xff0c;它与大金刚的最大区别也只是省去了G-Sync功能&#xff0c;而其他方面的参数几乎是一致的。那么我们今天就来聊聊这款真香的显示器。…

事务管理基础:两段锁协议、活锁、死锁相关知识整理

1、两段锁协议&#xff08;Two-phase Locking Protocol&#xff09; 两段锁协议是指对任何数据进行读写之前必须对数据进行加锁&#xff1b;在释放一个封锁之后&#xff0c;事务不再申请和获得任何其他封锁。两段锁协议中两段的含义&#xff1a;事务分为两个阶段&#xff0c;第…

php 空函数,PHP 中函数 isset(), empty(), is_null() 的区别

PHP 中函数 isset(), empty(), is_null() 的区别,使用 PHP 进行开发的时候&#xff0c;经常会用到 isset(), empty(), is_null() 这几个函数对数据进行判断&#xff0c;但是这是哪个函数的具体区别其实没有很好的掌握。下面我们详细讲解一下&#xff1a;NULL什么是 NULL&#x…

UVa11021

11021 TribblesGRAVITATION, n.“The tendency of all bodies to approach one another with a strengthproportion to the quantity of matter they contain – the quantity ofmatter they contain being ascertained by the strength of their tendencyto approach one anot…

数据库系统故障相关知识笔记

数据库系统中可能发生的故障主要包括事务故障、系统故障、介质故障、计算机病毒等。下面给大家简单整理一下相关的故障知识笔记。1、事务故障事务故障是因为程序执行错误而引起的非预期、异常终止的故障。主要有逻辑错误、系统错误导致事务的执行失败。逻辑错误&#xff1a;比如…

dede php分页代码,DEDECMS系统分页标签自定义二次开发

以前有给大家写过一篇自定义dedecms留言板的分页,下面我再来给大家分享一篇自定义常见的分页标签例子,希望文章对大家会有所帮助.自定搜索结果页面文章分页,在/plus文件夹中新建一个search.php文件,代码如下:require_once(dirname(__FILE__)."/../include/common.inc.php&…

数据库系备份相关知识笔记

1、数据库备份的知识介绍在互联网时代&#xff0c;最珍贵的财产不是计算机应用软件&#xff0c;更不是计算机硬件&#xff0c;而是企业在业务长期发展过程中积累下来的业务数据。建立网络最根本的用途是更加方便的传递、使用数据&#xff0c;人为原因、硬盘损坏、计算机病毒、断…

操作系统:分享6 个“吓人”的 Linux 命令

目录 1、crypt 2、kill 3、shred 5、at midnight 6、daemons 1、crypt 好吧&#xff0c;我们一直都有crypt。顾名思义&#xff0c;crypt不是存放垃圾文件的地宫或墓坑&#xff0c;而是加密文件内容的命令。 如今&#xff0c;“crypt”通常作为一个脚本而实现&#xff1a;通过调…