<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>潘锦的空间 &#187; 思考PHP语言</title>
	<atom:link href="https://www.phppan.com/tag/%e6%80%9d%e8%80%83php%e8%af%ad%e8%a8%80/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.phppan.com</link>
	<description>SaaS SaaS架构 团队管理 技术管理 技术架构 PHP 内核 扩展 项目管理</description>
	<lastBuildDate>Sat, 25 Apr 2026 00:56:17 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=3.9.40</generator>
	<item>
		<title>思考PHP之五：访问控制</title>
		<link>https://www.phppan.com/2011/05/thinkinphp-5-visibility/</link>
		<comments>https://www.phppan.com/2011/05/thinkinphp-5-visibility/#comments</comments>
		<pubDate>Mon, 23 May 2011 01:11:20 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[PHP语言]]></category>
		<category><![CDATA[思考PHP语言]]></category>
		<category><![CDATA[访问控制]]></category>
		<category><![CDATA[面向对象]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1377</guid>
		<description><![CDATA[面向对象三大特性：封装性、继承性和多态性。 封装隐藏了对象内部的细节和实现， 使对象能够集中而完整的描述并对应 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="text-indent: 2em;">面向对象三大特性：封装性、继承性和多态性。 封装隐藏了对象内部的细节和实现， 使对象能够集中而完整的描述并对应一个具体的事物。 它使对象只提供对外的访问接口，这样可以在不改变接口的前提下改变实现细节，而且能使对象自我完备。 除此之外，封装还可以增强安全性和简化编程。 继承的目的是为了实现代码复用，它是一种一般化与特殊化的关系，其中子类是父类的细化。 在实现继承时最需要考虑的问题是子类和父类是不是&#8221;IS-A&#8221;的关系。</p>
<p style="text-indent: 2em;">PHP（其它面向对象的语言也类似）对于封装和继承的一些特性是通过访问控制实现。访问控制的作用是控制成员变量，成员方法和基类。 曾经一直以为访问控制的作用仅仅是控制一个类的成员方法和成员变量，这把自己的思维局限于一类一对象了， 这两个方面的控制是PHP对面向对象中封装特性的支持。 把思维拉升到面向对象的体系之上，访问控制也控制了基类（或父类）的行为，或者说控制了继承特性的某些方面。</p>
<p style="text-indent: 2em;">PHP中关于访问控制的关键字和Java等其它面向对象语言一样，如下：</p>
<ul>
<li>public 所定义的类成员可以在任何地方被访问</li>
<li>protected 所定义的类成员则可以被其所在类、其所在类的子类和父类访问</li>
<li>private 定义的类成员则只能被其所在类访问。</li>
</ul>
<p style="text-indent: 2em;">以上的类成员包括成员变量和成员函数。不管是成员变量还是成员方法，PHP默认都是public。 在Java中访问控制默认为包可见，在C++中访问控制默认为私有(private)，而PHP则是公有的(public)，这比Java还要open。 笔者认为这是PHP的一个历史遗留问题。如果可以重新设计PHP，可能是另一个结果，并且这也是语言的对于访问的态度问题。</p>
<p style="text-indent: 2em;">前面介绍的各个访问控制是针对封装性，对于继承性，如下：</p>
<ul>
<li>public/protected 可以被继承</li>
<li>private 没有被继承</li>
</ul>
<blockquote style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-left: 60px; padding-right: 20px; background-image: url(http://localhost/git/blog/web/images/note.png); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: #dfdfdf; border-top-width: 1px; border-bottom-width: 1px; border-top-style: solid; border-bottom-style: solid; border-top-color: #aaaaaa; border-bottom-color: #aaaaaa; border-left-width: 0px; border-left-style: initial; border-left-color: initial; border-right-width: 0px; border-right-style: initial; border-right-color: initial; background-position: 15px 8px; background-repeat: no-repeat no-repeat;">
<p style="text-indent: 0px;">实际上，在PHP中，私有方法也会被继承下来，只是其上下文没有改变（还是父类），从而在调用的时候出错。</p>
</blockquote>
<p style="text-indent: 2em;">一般来说，private定义的成员只能被内部调用，仅供当前类使用，这在PHP的源码中检查访问权限控制时， 以private的成员会检查是否属于当前类体现。public定义的成员则属于类或对象的外部接口， 声明的public成员最好是定义好后就不要再变更，这会影响到调用了类的这些方法的相关客户。 好的public和private的设计对于对象本身的自我完备的实际有重大的意义。</p>
<p style="text-indent: 2em;">但是public关键字有一些二义性。对于封装性，它是公有的，任何地方都可以访问的成员；对于继承性， 它允许子类继承此成员。同时兼顾这两个特性，当我们把它作为一个接口提供给外部使用时就会有一些歧义： 子类可以覆盖该成员方法，同时也可以调用访方法，如果子类覆盖了该成员方法并调用了该方法， 则它的实现就和你当初作为接口提供给外部时的含义有一些不同了。和public一样，protected也有类似的问题。 可以思考一下：各语言这样实现的目的是什么？是否有更好的方案？</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2011/05/thinkinphp-5-visibility/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>思考PHP语言四：接口和抽象类</title>
		<link>https://www.phppan.com/2010/12/thinkinphp-4-interface-abstract-class/</link>
		<comments>https://www.phppan.com/2010/12/thinkinphp-4-interface-abstract-class/#comments</comments>
		<pubDate>Fri, 24 Dec 2010 02:35:50 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[思考PHP语言]]></category>
		<category><![CDATA[抽象类]]></category>
		<category><![CDATA[接口]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1197</guid>
		<description><![CDATA[思考PHP语言四：接口和抽象类 【概述】 在写PHP的日子里，我们多是按照需求完成相关功能，对于一些设计的工作 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>思考PHP语言四：接口和抽象类<br />
<strong>【概述】</strong><br />
在写PHP的日子里，我们多是按照需求完成相关功能，对于一些设计的工作较少的接触，也许是PHP的历史遗留问题或者其它，对于PHP的接口与抽象类使用得较少，但是对于一个支持面向对象的语言，接口与抽象是两个非常重要的内容。这里我们介绍接口与抽象类的一些基础知识，思考一些关于面向对象的东西。<br />
<strong>【接口】</strong><br />
接口是一些方法特征的集合，这里的方法没有实现，只有声明。如果一个类继承了某个接口，则需要实现这个接口的所有方法。接口除了声明方法外，还可以定义常量。如下所示：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">interface</span> IFoo <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">const</span> CONST_VAR <span style="color: #339933;">=</span> <span style="color: #0000ff;">'martin'</span><span style="color: #339933;">;</span>
	<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> method<span style="color: #009900;">&#40;</span><span style="color: #000088;">$str</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>接口中方法的声明需要包含方法的名称，参数。不用包含参数类型和返还类型（PHP的函数本来就不用定义参数类型和返还类型）。<br />
接口的方法只能是public，这说明接口本身包含的对外开放的意义在访问控制中体现出来了，并且当我们实现接口的方法时，也不能修改方法的访问控制权限。</p>
<p>接口是可以继承的，接口可以继承接口(和类继承一样，使用extends关键字)，类可以继承接口（我们称之为接口继承，用implements关键字）</p>
<p>实现同一个接口的两个类可能功能完全不同，但是他们有相同的方法以及方法参数，并且都是公开的，从而他们可以提供相类似的服务，从而具有相同的接口。</p>
<p><strong>接口的可插入性</strong><br />
在一个拥有多个层次结构的类组织中，如果要给某个处于中间位置的类添加父类，如果我们没有接口，则我们需要修改这个类的所有父类，打乱整个类的层次结构。当有了接口后，任何一个类都可以实现一个接口，此时，接口不会影响父类，但是会影响所有的子类，此类将必须实现这个接口的所有方法（抽象类可以不用实现所有方法，只是将实现下移到子类），子类则可以自动从此类继承实现后的方法。这就是接口的可插入性。</p>
<p>接口通常被用来声明一个新的类型，并且会作为一个类组织结构的起点，特别是当某个实体属于多个类型时，此时接口的作用就体现出来了。另外，理想情况下（现实中没发现过）一个类只应该实现接口或抽象类所声明的方法，纯理想呵。</p>
<p><strong>【抽象类】</strong><br />
抽象类是类的一种，通过在类定义前添加abstract关键字实现。如下示例：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> AbstarctFoo <span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> method<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>抽象类不能实例化，一般作为类组织结构中枝节点或根节点存在。<br />
抽象类提供一个类型的部分实现，抽象类可以有实例变量，可以有构造方法，可以有抽象方法，同时也可以有具体的方法实现。抽象类的构造方法可以被子类调用，只是需要显式调用。<br />
我们在做设计时需要注意的是一般不要从具体类继承，具体类是用来实例化的。<br />
在类的组织结构中，一般抽象类是枝节点，具体类是叶节点，在设计结构时应该尽量将公共代码放到作为父类的抽象类中，这样可以提高代码的复用性，与公共代码的移动相反，数据应该尽量放到具体类。<br />
在继承过程中，子类的责任是扩展父类，而不是置换或取消掉父类的职责，当有取消或置换父类的职责的情况发生时，此时可能你的设计有问题了，需要考虑他们是否是is-a的关系？<br />
<strong>抽象类和接口有相同的方法时</strong><br />
在PHP中，如果一个类继承了一个抽象类并且实现了一个接口，如果此时这个抽象类和接口中有相同名称的方法，则此时对于接口的实现会报错。与此相同，当一个抽象类实现一个接口时，如果接口已经声明了方法A，则在抽象方法中将不能再次声明此方法。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2010/12/thinkinphp-4-interface-abstract-class/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>思考PHP语言三：异常处理</title>
		<link>https://www.phppan.com/2010/12/thinkinphp-3-exception/</link>
		<comments>https://www.phppan.com/2010/12/thinkinphp-3-exception/#comments</comments>
		<pubDate>Wed, 22 Dec 2010 01:28:03 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[异常处理]]></category>
		<category><![CDATA[思考PHP语言]]></category>
		<category><![CDATA[断言]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1192</guid>
		<description><![CDATA[思考PHP语言三：异常处理 【概述】 异常处理是指在语言中能够使程序按照一种标准的方法对于某些运行时错误和其他 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>思考PHP语言三：异常处理<br />
<strong>【概述】</strong><br />
异常处理是指在语言中能够使程序按照一种标准的方法对于某些运行时错误和其他程序所检测到的异常事件做出反应。异常发生的时间是不可以确定的，如果一种语言不包括异常处理机制，这就会给语言带来额外的复杂性。<br />
一般来说，对于异常的处理有三种方案：<br />
1、将一个额外的参数作为状态变量，通过标记这个状态值判断是否发生了异常。在C的标准库中许多函数使用返回值作为出错的状态变量。<br />
2、将一个标号参数传给子程序，当异常发生时，通过标号将程序调用跳转到程序中的不同位置<br />
3、将一个异常处理独立出来，作为专门的子程序或类存在。</p>
<p>在基于C的语言中，将异常出现称之为thrown，而不是raise，是因为在标准的C程序库中已经存在一个叫做raise的函数。<br />
在PHP5中使用第3种方式。<br />
<strong>【PHP中的异常处理】</strong><br />
在PHP5以后，PHP添加了异常处理模块。PHP的异常处理模块与java有一些类似，异常可被 throw 语句抛出并被 catch 语句捕获。需要进行异常处理的代码都必须放入 try 代码块内，以便捕获可能存在的异常。每一个 try 至少要有一个与之对应的 catch。使用多个 catch 可以捕获不同的类所产生的异常(嗯，这里没有throws子句)。当 try 代码块不再抛出异常或者找不到 catch 能匹配所抛出的异常时，PHP 代码就会在跳转到最后一个 catch 的后面继续执行。所以在安排catch的顺序时，需要将详细或子类的异常类放到前面。在有一些情况下，不管try子句是否抛出异常，也不管是否捕获了异常，程序都要执行一个过程，此时我们就需要finally子句，只是在PHP中并没有finally子句（HOHO）。<br />
一个异常的简单示例：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="php" style="font-family:monospace;">try <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;error msg&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>catch<span style="color: #009900;">&#40;</span>Exception <span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	 <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Caught exception: '</span><span style="color: #339933;">,</span>  <span style="color: #000088;">$e</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>PHP提供了Exception类，以及在SPL中提供了一些内置的异常类，我们可以通过继承Exception类而实现属于自己的异常类。在一个面向对象系统的设计中我们需要考虑关于错误的处理情况，是以PHP的内部错误报告，还是以异常的方式给出，此时我们需要规划一套专属于我们系统的异常子系统。并且对于PHP的内部错误报告我们可以使用ErrorException进行转换，如下所示帮助文档中的代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> exception_error_handler<span style="color: #009900;">&#40;</span><span style="color: #000088;">$errno</span><span style="color: #339933;">,</span> <span style="color: #000088;">$errstr</span><span style="color: #339933;">,</span> <span style="color: #000088;">$errfile</span><span style="color: #339933;">,</span> <span style="color: #000088;">$errline</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> ErrorException<span style="color: #009900;">&#40;</span><span style="color: #000088;">$errstr</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000088;">$errno</span><span style="color: #339933;">,</span> <span style="color: #000088;">$errfile</span><span style="color: #339933;">,</span> <span style="color: #000088;">$errline</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #990000;">set_error_handler</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;exception_error_handler&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Trigger exception */</span>
<span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>【断言】</strong><br />
断言常常被用于防错性的程序设计。在一个程序中可以有多条断言，以便确保程序计算的正确性。<br />
PHP提供了assert函数，当执行到此函数时，如果条件为真，则什么都不执行，如果条件为假，则警告并中断程序： Warning: assert() [function.assert]: Assertion failed<br />
经常我们会用echo或die来调试我们的程序，在调试完后我们需要删除相关调试代码。使用assert语句可以在出现问题时将程序调用，而不需要在后面将这些断言删除，这样可以节省删除操作并且在以后的维护过程中也可以重用这些语句，这里就有点测试的感觉了。<br />
当然，我们也可以将断言和异常一起使用，如下所示代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * 断言回调函数，抛出异常
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> assert_callcack<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> Exception<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;msg&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Set our assert options</span>
<span style="color: #990000;">assert_options</span><span style="color: #009900;">&#40;</span>ASSERT_ACTIVE<span style="color: #339933;">,</span>   <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">assert_options</span><span style="color: #009900;">&#40;</span>ASSERT_BAIL<span style="color: #339933;">,</span>     <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">assert_options</span><span style="color: #009900;">&#40;</span>ASSERT_WARNING<span style="color: #339933;">,</span>  <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// 必须为true</span>
<span style="color: #990000;">assert_options</span><span style="color: #009900;">&#40;</span>ASSERT_CALLBACK<span style="color: #339933;">,</span> <span style="color: #0000ff;">'assert_callcack'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* 触发一个断言*/</span>
<span style="color: #990000;">assert</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Never reached'</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>断言和异常的结合处在于断言的回调函数，只是需要注意的是：assert_options(ASSERT_WARNING,  true);<br />
因为断言的错误级别为warning。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2010/12/thinkinphp-3-exception/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>思考PHP语言二：面向对象</title>
		<link>https://www.phppan.com/2010/12/thinkinphp-2-oop/</link>
		<comments>https://www.phppan.com/2010/12/thinkinphp-2-oop/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 01:00:32 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[思考PHP语言]]></category>
		<category><![CDATA[面向对象]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1190</guid>
		<description><![CDATA[思考PHP语言二：面向对象 【概述】 PHP是一门支持面向过程，也支持面向对象的动态语言。从PHP5开始，PH [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>思考PHP语言二：面向对象<br />
<strong>【概述】</strong><br />
PHP是一门支持面向过程，也支持面向对象的动态语言。从PHP5开始，PHP对于面向对象的支持好了很多。<br />
面向对象程序设计是抽象数据类型的抽象原理的一种应用。当我们使用类时，我们应该了解这是一种抽象数据类型，对象是属于所对应类的类型的。<br />
面向对象的三个特征：封装，继承，多态。这三个特征也可以用：抽象数据类型，继承和方法调用与方法间的动态绑定来说明。抽象是我们与程序复杂性抗争的一种方式，通过这种方式，我们可以关注并且仅关注主要的属性而忽略次要的属性。从语法的角度来说，抽象数据类型是一种封装，它不仅仅包括对于数据的封装，也包括其提供方法的封装。通过访问控制，从而实现数据或方法的隐藏和暴露，这就是我们经常所说的类，它的实例我们称之为对象。</p>
<p><strong>【PHP的抽象数据类型】</strong><br />
PHP以类的形式实现封装，类中所定义的数据称为成员变量；而类中所定义的函数称为成员函数或成员方法。成员函数和成员变量又分别有类属性和实例属性。<br />
<strong>类属性的成员函数和成员变量</strong><br />
PHP中的类属性成员都以静态的方式存在，为所有的实例共享（包括成员函数和成员变量），可以通过类名直接调用。但是其仅在一个PHP的生命周期内有效，这与java等有较大的差别。<br />
<strong>实例属性的成员函数和成员变量</strong><br />
对于实例属性的成员函数和成员变量，一个类的所有实例共享一套成员函数，而每个实例都有属于自己的一套成员变量，这也是我们在做面向对象的程序结构设计时将数据尽量向下移，将共用的方法尽量向上移的原因。<br />
<strong>信息隐藏</strong><br />
PHP中的信息隐藏通过访问控制实现，对于需要隐藏的数据将其以私有成员定义，在其声明前添加private关键字，对于需要公开的数据将其以公有成员定义，在其定义前添加public关键字，也可以不加任何关键字，因为PHP默认情况下是public。PHP的私有和公有访问权限与java相同，</p>
<p><strong>命名封装</strong><br />
在构建大型系统时，为解决不同团队对于函数或类等的命名冲突，我们需要引入命名封装，命名封装是一些逻辑上的封装。在PHP中使用命名空间实现，只是这在PHP５.3版本后才有相关支持。<br />
在PHP中，类，函数和常量这三种类型受命名空间的影响，命名空间通过关键字namespace 来声明，对于层次化的命名空间以反斜杠隔开，如：namespace com\toll\level;</p>
<p><strong>【PHP的继承】</strong><br />
继承是软件复用的一种形式，它不仅可以让程序人员以一个已有类为基础，设计一个修改了的后代类型，还可以定义相关的程序结构和关系。这种结构和关系在一定程度上反映了这些实体的上下代关系。从这里就产生了父类，子类等概念，并且在访问控制中也产生了protected，使用protected时，它的最大访问范围为其派生类。在子类中我们可以定义新的成员变量和新的成员函数，并且可以重载父类的成员函数，但是无法重载父类的构造函数，如果在实例化时需要调用父类的构造函数，我们需要手动调用父类的构造函数，PHP本身不会自动调用。<br />
另外，关于PHP的构造函数的一个历史遗留问题：以类名为构造函数和以__construct为构造函数，在之前写过一篇文章介绍二者在调用时的选择方式。<a href="http://www.phppan.com/2010/11/php-source-27-construct/">PHP源码阅读笔记二十七：PHP对构造方法的识别</a><br />
PHP没有多继承，只支持单继承，但是他拥有接口，它提供了一种多继承的方式。这点和java一样。<br />
接口的定义与类的定义类似，只是关键字变成了interface，接口可以包含常量和方法声明。它的作用仅仅是定义类的说明。类可以实现多个接口，但是类也必须实现接口中的所有方法。接口可以模拟实现多继承，也提供了另一种形式的多态，但是这对于PHP来说没有多大的意义，因为PHP的变量本身就是多态的。</p>
<p>继承是作为增加复用可能性的一种手段，但是它在继承层次中产生的类之间的相互依赖性，产生了一些强耦合。而这与之前的封装的优点刚好相反，封装就是为了保持类之间的相互独立性。所以在作设计时，我们如果使用继承就需要考虑是否真的需要，是否真的是is-a的关系。更多的时候我们会选择使用委托来实现。<br />
<strong>【PHP的动态绑定】</strong><br />
PHP本身就是动态绑定的。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2010/12/thinkinphp-2-oop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>思考PHP语言一：控制结构</title>
		<link>https://www.phppan.com/2010/12/thinkinphp-1-control-structures/</link>
		<comments>https://www.phppan.com/2010/12/thinkinphp-1-control-structures/#comments</comments>
		<pubDate>Wed, 15 Dec 2010 03:10:02 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[思考PHP语言]]></category>

		<guid isPermaLink="false">http://www.phppan.com/?p=1181</guid>
		<description><![CDATA[思考PHP语言一：控制结构 【概述】 命令式程序设计语言的实质是赋值语句占主导地位。 赋值语句的目的是改变变量 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>思考PHP语言一：控制结构<br />
<strong>【概述】</strong><br />
命令式程序设计语言的实质是赋值语句占主导地位。 赋值语句的目的是改变变量的值，因此在所有的命令式程序设计语言中，其共同部分就是不停的变幻变量的值，最后达到我们的目的。<br />
然而我们的程序并不是仅仅是由赋值语句组成的。至少还需要两种额外的语言机制：<br />
1、控制路径选择的方法。<br />
2、控制某些语句重复执行的方法。<br />
这些方法或语言机制我们称之为控制语句。<br />
大量的控制语句可以提高程序语言的可写性，但是同时又会降低程序语言的可读性，为此，经常需要在这二者之间进行权衡。<br />
</strong>【PHP中的选择语句】</strong><br />
<strong>1、双向选择语句</strong><br />
示例：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>expr<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	statement
<span style="color: #009900;">&#125;</span><span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span>
	statement
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>PHP选择语句中的逻辑表达式可以是布尔表达式，也可以是结果为数字的表达式，但是在PHP内部只有一种变量zval，于是这些表达式结果类型对于PHP来说没有多大的意义</p>
<p>在PHP中，then子句和else子句可以是简单语句也可以是复合语句，如果是复合语句需要使用大括号将所有的复合语句括起来。</p>
<p>关于else的归属问题，以就近原则为准，如果需要在一个then子句中包含一个if语句，建议将其以复合语句处理，使用大括号将if语句括起来。如下所示代码：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>expr<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>expr2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		statement
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #b1b100;">else</span><span style="color: #009900;">&#123;</span>
	statement
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p><strong>2、多向选择语句</strong><br />
多向选择语句允许在任意数目的语句或语句组中进行一种选择。多向选择器与双向选择器可以互相构造，都可以实现对方的功能。<br />
示例：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">switch</span><span style="color: #009900;">&#40;</span>expr<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #b1b100;">case</span> 常量表达式<span style="color: #cc66cc;">1</span>：
	statement <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
<span style="color: #339933;">......</span>
&nbsp;
<span style="color: #b1b100;">case</span> 常量表达式n：
	statement n<span style="color: #339933;">;</span>
	<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#91;</span><span style="color: #b1b100;">default</span><span style="color: #339933;">:</span> statement n <span style="color: #339933;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span><span style="color: #009900;">&#93;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>PHP的switch语句使用了C的switch语句的语法，但是却有一些差别，PHP的case 表达式可以是数字，字符串或浮点数这些简单类型。<br />
与双向选择语句一样，多向选择语句在选择的路径上可以是简单语句，也可以是复合语句，只是这里我们不需要使用大括号，此时我们可以叫它语句序列。<br />
当所有的情况都不满足时，执行default路径，如果没有所谓的default情况，请将default子句也写上，并且报错吧。<br />
但是，当出现了switch选择语句时，此时可以想想我们的代码是否可以重构了。<br />
当某个case下没有 break语句时，请写下注释说明原因。</p>
<p></strong>【PHP中的循环语句】</strong><br />
循环语句的作用是将一条或一组语句执行n(n>=0)的一种语句<br />
在函数式程序设计语言中一般是通过递归完成循环语句的功能<br />
<strong>1、计数器循环控制语句</strong><br />
这种形式的循环控制语句一般包括初始值，终值，步长，这些统称为循环参数<br />
PHP的计数器循环控制语句是类似于C语言的。<br />
示例如下：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span>表达式<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> 表达式<span style="color: #cc66cc;">2</span>；表达式<span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	循环体
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>这就是我们所说的for语句，只是在PHP中，for语句的使用较少，用得最多的还是在后面会提到的基于数据结构的循环&#8212;foreach<br />
for语句中的三个表达式都是可选的，如果缺少第二个表达式，则认为其结果为真，如果在循环体中没有退出操作的话，这将是一个死循环。并且每个表达式都是可以由多条语句组成，语句与语句之间用逗号隔开，此时表达式的值为最后一条语句的值。<br />
虽然for语句属于计数器循环控制语句，但是它并没有明显的循环变量或循环参数，可以在循环体中改变所有的所有变量，这就导致了for语句的灵活性，同时，如果用得不好也将导致程序逻辑的混乱<br />
<strong>2、逻辑控制循环语句</strong><br />
逻辑控制循环语句是基于布尔表达式的，所有的计数循环都可以使用逻辑循环来实现，反过来则不一定。<br />
示例：</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>控制表达式<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    循环体
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">do</span> <span style="color: #009900;">&#123;</span>
   循环体
<span style="color: #009900;">&#125;</span><span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span>控制表达式<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>逻辑控制语句分为先测试和后测试两种情况，这个在上面的示例中有所体现。与for语句一样，PHP的逻辑循环控制语句也是类似于C语言的实现。<br />
对于while语句，当控制表达式的条件为真时执行循环体，对于do-while语句，先执行循环体，再判断控制表达式是否为真。while语句总会比do-while语句少执行一次。<br />
<strong>3、基于数据的循环语句</strong><br />
顾名思义，基于数据的循环语句的循环是由数据结构中的元素的数目来控制的。一般来说，基于数据的循环语句会使用一种称之为迭代器的函数来实现元素的遍历。<br />
PHP中可以使用预定义的一些函数来实现对数组的迭代访问，如current,next,reset等等。<br />
然而我们使用得最多的还是foreach语句，foreach可以直接迭代访问数组，如果用户自己定义的对象需要使用此语句进行迭代访问，必须实现SPL的迭代器。<br />
之前写过两篇关于迭代器的文章：<br />
<a href="http://www.phppan.com/2010/04/php-iterator-and-yii-cmapiterator/">PHP中迭代器的简单实现及Yii框架中的迭代器实现</a><br />
<a href="http://www.phppan.com/2010/04/php-source-24-iterator-false-value/">PHP源码阅读笔记二十四 ：iterator实现中当值为false时无法完成迭代的原因分析</a></p>
]]></content:encoded>
			<wfw:commentRss>https://www.phppan.com/2010/12/thinkinphp-1-control-structures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
