php面向对象 自动加载类 对象串行化 多态的应用
自动加载类
很多开发者写面向对象的应用程序时,对每个类的定义建立一个 PHP 源文件。一个很大的烦恼是不得不在每个脚本(每个类一个文件)开头写一个长长的包含文件的列表。
在软件开发的系统中,不可能把所有的类都写在一个PHP文件中,当在一个PHP文件中需要调用另一个文件中声明的类时,就需要通过include把这个文件引入。不过有的时候,在文件众多的项目中,要一一将所需类的文件都include进来,是一个很让人头疼的事,所以我们能不能在用到什么类的时候,再把这个类所在的php文件导入呢?这就是我们这里我们要讲的自动加载类。
在 PHP 5 中,可以定义一个 __autoload()函数,它会在试图使用尚未被定义的类时自动调用,通过调用此函数,脚本引擎在 PHP 出错失败前有了最后一个机会加载所需的类, __autoload()函数接收的一个参数,就是你想加载的类的类名,所以你做项目时,在组织定义类的文件名时,需要按照一定的规则,最好以类名为中心,也可以加上统一的前缀或后缀形成文件名,比如xxx_classname.php、classname_xxx.php以及就是classname.php等等.
本例尝试分别从 MyClass1.php 和 MyClass2.php 文件中加载 MyClass1 和 MyClass2 类
代码如下 | 复制代码 |
function __autoload($classname) //MyClass1类不存在自动调用__autoload()函数,传入参数”MyClass1” //MyClass2类不存在自动调用__autoload()函数,传入参数”MyClass2” |
对象串行化
有时候需要把一个对象在网络上传输,为了方便传输,可以把整个对象转化为二进制串,等到达另一端时,再还原为原来的对象,这个过程称之为串行化, 就像我们现在想把一辆汽车通过轮船运到美国去,因为汽车的体积比较大,我们可以把汽车拆开成小的部件,然后我们把这些部件通过轮般运到美国去,到了美国再把这些部件组装回汽车。
有两种情况我们必须把对象串行化,第一种情况就是把一个对象在网络中传输的时候要将对象串行化,第二种情况就是把对象写入文件或是数据库的时候用到串行化。
串行化有两个过程,一个是串行化,就是把对象转化为二进制的字符串,我们使用serialize()函数来串行化一个对象,另一个是反串行化,就是把对象转化的二进制字符串再转化为对象, 我们使用unserialize()函数来反串行化一个对象.
PHP中serialize()函数的参数为对象名,返回值为一个字符串,Serialize()返回的字符串含义模糊,一般我们不会解析这个串来得到对象的信息,我们只要把返回来的这个字符串传到网络另一端或是保存到方件中即可。
PHP中unserialize()函数来反串行化对象,这个函数的参数即为serialize()函数的返回值,输出当然是重新组织好的对象.
代码如下 | 复制代码 |
class Person //定义一个构造方法参数为属性姓名$name、性别$sex和年龄$age进行赋值 //这个人可以说话的方法, 说出自己的属性 $p1=new Person("张三", "男", 20); $p1_string=serialize($p1); //把一个对象串行化,返一个字符串 echo $p1_string.""; //串行化的字符串我们通常不去解析 $p2=unserialize($p1_string); //把一个串行化的字符串反串行化形成对象$p2 $p2->say(); |
多态的应用
多态是除封装和继承之外的另一个面象对象的三大特性之一,我个人看来PHP中虽然可以实现多态,但和c++还有Java这些面向对象的语言相比,多态性并不是那么突出,因为PHP本身就是一种弱类型的语言,不存在父类对象转化为子类对象或者是子类对象转化为父类对象的问题,所以多态的应用并不是那么的明显;所谓多态性是指一段程序能够处理多种类型对象的能力,比如说在公司上班,每个月财务发放工资,同一个发工资的方法,在公司内不同的员工或是不同职位的员工,都是通过这个方法发放的,但是所发的工资都是不相同的。所以同一个发工资的方法就出现了多种形态。对于面向对象的程序来说,多态就是把子类对象赋值给父类引用,然后调用父类的方法,去执行子类覆盖父类的那个方法,但在PHP里是弱类型的,对象引用都是一样的不分父类引用,还是子类引用。
我们现在来看一个例子,首先还是要使用多态就要有父类对象和子类对象的关系。做一个形状的接口或是抽象类做为父类,里面有两个抽象方法,一个求周长的方法,另一个是求面积的方法;这接口的子类是多种不同的形状,每个形状又都有周长和面积,又因为父类是一个接口,所以子类里面就必须要实现父类的这两个周长和面积的抽象方法,这样做的目的是每种不同形状的子类都遵守父类接口的规范,都要有求周长和求面积的方法。
代码如下 | 复制代码 |
//定义了一个形状的接口,里面有两个抽象方法让子类去实现 //定义了一个矩形子类实现了形状接口中的周长和面积 function __construct($width, $height) function area() function perimeter() //定义了一个圆形子类实现了形状接口中的周长和面积 function __construct($radius) function area() function perimeter() //把子类矩形对象赋给形状的一个引用 echo $shape->area()." //把子类圆形对象赋给形状的一个引用 echo $shape->area()." 上例执行结果: |
好了关于它们三个我们有详细的介绍了,大家不懂还可以百度一下哦。
上传类使用ORG类库包中的Net.UpdateFile类,最新版本的上传类包含的功能如下(有些功能需要结合ThinkPHP系统其他类库):
1.基本上传功能
2.支持批量上传
3.支持生成图片缩略图
4. 自定义参数上传
5.上传检测(包括大小、后缀和类型)
6.支持上传类型、附件大小、上传路径定义
7.支持哈希或者日期子目录保存上传文件
8.上传图片的安全性检测
9.支持上传文件命名规则
10. 支持对上传文件的Hash验证
在ThinkPHP中使用上传功能无需进行特别处理。例如,下面是一个带有附件上传的表单提交:
代码如下 | 复制代码 |
<form METHOD=POST action=“/Manual/upload” enctype=“multipart/form-data” > <input type=“text” NAME=“name” > <input type=“text” NAME=“email” > <input type=“file” name=“photo” > <input type=“submit” value=“保 存” > </form> |
注意表单的Form标签中一定要添加 enctype=”multipart/form-data” 文件才能上传。因为表单提交到当前模块的upload操作方法,所以我们在模块类里面添加下面的upload方法即可:
代码如下 | 复制代码 |
Public function upload(){ import(“ORG.Net.UploadFile”); $upload = new UploadFile(); // 实例化上传类 $upload->maxSize = 3145728 ; // 设置附件上传大小 $upload->allowExts = array(‘jpg’, ‘gif’, ‘png’, ‘jpeg’); // 设置附件上传类型 $upload->savePath = ‘./Public/Uploads/’; // 设置附件上传目录 if(!$upload->upload()) { // 上传错误 提示错误信息 $this->error($upload->getErrorMsg()); }else{ // 上传成功 获取上传文件信息 $info = $upload->getUploadFileInfo(); } // 保存表单数据 包括附件数据 $User = M(“User”); // 实例化User对象 $User->create(); // 创建数据对象 $User->photo = $info[0]["savename"]; // 保存上传的照片 根据需要自行组装 $User->add(); // 写入用户数据到数据库 $this->success(“数据保存成功!”); } |
首先是实例化上传类
代码如下 | 复制代码 |
import(“ORG.Net.UploadFile”); $upload = new UploadFile(); // 实例化上传类 |
实例化上传类之后,就可以设置一些上传的属性(参数),支持的属性有:
maxSize: 文件上传的最大文件大小(以字节为单位)默认为-1 不限大小
savePath:文件保存路径,如果留空会取UPLOAD_PATH常量定义的路径
saveRule:上传文件的保存规则,必须是一个无需任何参数的函数名,例如可以是 time、 uniqid com_create_guid 等,但必须能保证生成的文件名是唯一的,默认是uniqid
hashType:上传文件的哈希验证方法,默认是md5_file
autoCheck:是否自动检测附件,默认为自动检测
uploadReplace:存在同名文件是否是覆盖
allowExts:允许上传的文件后缀(留空为不限制),使用数组设置,默认为空数组
allowTypes:允许上传的文件类型(留空为不限制),使用数组设置,默认为空数组
thumb:是否需要对图片文件进行缩略图处理,默认为false
thumbMaxWidth:缩略图的最大宽度,多个使用逗号分隔
thumbMaxHeight:缩略图的最大高度,多个使用逗号分隔
thumbPrefix:缩略图的文件前缀,默认为thumb_ (如果你设置了多个缩略图大小的话,请在此设置多个前缀 )
thumbSuffix:缩略图的文件后缀,默认为空 (如果你设置了多个缩略图大小的话,请在此设置多个后缀 )
thumbPath:缩略图的保存路径,留空的话取文件上传目录本身
thumbFile:指定缩略图的文件名
thumbRemoveOrigin:生成缩略图后是否删除原图
autoSub:是否使用子目录保存上传文件
subType:子目录创建方式,默认为hash,可以设置为hash或者date
dateFormat:子目录方式为date的时候指定日期格式
hashLevel:子目录保存的层次,默认为一层
以上属性都可以直接设置,例如:
代码如下 | 复制代码 |
$upload->thumb = true $upload->thumbMaxWidth = “50,200″ $upload->thumbMaxHeight = “50,200″ |
其中生成缩略图功能需要Image类的支持。
设置好上传的参数后,就可以调用 UploadFile类的upload方法进行附件上传,如果失败,返回false,并且用getErrorMsg方法获取错误提示信息;如果上传成功, 可以通过调用getUploadFileInfo方法获取成功上传的附件信息列表。因此getUploadFileInfo方法的返回值是一个数组,其中 的每个元素就是上传的附件信息。每个附件信息又是一个记录了下面信息的数组,包括:
key:附件上传的表单名称
savepath:上传文件的保存路径
name:上传文件的原始名称
savename:上传文件的保存名称
size:上传文件的大小
type:上传文件的MIME类型
extension:上传文件的后缀类型
hash:上传文件的哈希验证字符串
文件上传成功后,就可以通过这些附件信息来进行其他的数据存取操作,例如保存到当前数据表或者单独的附件数据表都可以。
如果需要使用多个文件上传,只需要修改表单,把
XML/HTML代码
代码如下 | 复制代码 |
<input type=“file” name=“photo”> |
改为
XML/HTML代码
代码如下 | 复制代码 |
<input type=“file” name=“photo1″> 或者 PHP代码 |
两种方式的多附件上传系统的文件上传类都可以自动识别。
$_POST 变量用于收集来自 method=\"post\" 的表单中的值。从带有 POST 方法的表单发送的信息,对任何人都是不可见的(不会显示在浏览器的地址栏),并且对发送信息的量也没有限制。先来看个最简单的实例
代码如下 | 复制代码 |
<form action ="post.php" method ="post"> |
如我输入 你好,
post.php文件代码如下
代码如下 | 复制代码 |
You are <?php echo $_POST["username"]?>. |
输出结果就是
You are 你好
那么post如何获取像单选按钮呢,实例如下
代码如下 | 复制代码 |
<form action = "radiopost.php" method = "post"> |
radiopost.php文件
代码如下 | 复制代码 |
<?php echo $_POST["abcde"]?> |
这样你选择那个就全出输那个的值,对于checkbox会有所不同,这个大家可以注意一下
代码如下 | 复制代码 |
<form action = "checkboxpost.php" method = "post"> |
checkboxpost.php文件
代码如下 | 复制代码 |
print_r($_POST['abcde']); |
输出的是个数组形式了
注:
通过 HTTP POST 发送的变量不会显示在 URL 中。
变量没有长度限制。
$_POST 与 php://input可以取到值,$HTTP_RAW_POST_DATA 为空
$_POST 以关联数组方式组织提交的数据,并对此进行编码处理,如urldecode,甚至编码转换。
php://input 可通过输入流以文件读取方式取得未经处理的POST原始数据
php://input 允许读取 POST 的原始数据。和 $HTTP_RAW_POST_DATA 比起来,它给内存带来的压力较小,并且不需要任何特殊的 php.ini 设置。php://input 不能用于 enctype="multipart/form-data"。
这里拓展一下post模拟方法
代码如下 | 复制代码 |
<?PHP |
1. 创建对象$object = new Class(),然后使用”->”调用:$object->attribute/function,前提是该变量/方法可访问。
2. 直接调用类方法/变量:class::attribute/function,无论是静态/非静态都可以。但是有前提条件:
A. 如果是变量,需要该变量可访问。
B. 如果是方法,除了该方法可访问外,还需要满足:
b1) 如果是静态方法,没有特殊条件;
b2) 如果是非静态方法,需要改方法中没有使用$this,即没有调用非静态的变量/方法,当然,调用静态的变量/方法没有问题。
然后我们再看一下使用$object->… 和使用class::… 都有什么区别:
1. 使用$object->… ,需要执行构造函数创建对象;
2. 使用class::… 调用静态方法/变量,不需要执行构造函数创建对象;
3. 使用class::… 调用非静态方法/变量,也不需要执行构造函数创建对象。
然后奇怪的地方就出来了,既然2和3都一样,那静态方法/变量存在还有什么意义呢?
静态 static
声明类成员或方法为 static ,就可以不实例化类而直接访问,不能通过一个对象来访问其中的静态成员(静态方法除外)。静态成员属于类,不属于任何对象实例,但类的对象实例都能共享。
例子:
代码如下 | 复制代码 |
<?php // 子类中输出成员属性值 |
运行该例子,输出:
中国
我是中国人
我是中国人
中国
我是中国人
小结
在类内部访问静态成员属性或者方法,使用 self::(注意不是 $slef),如:
代码如下 | 复制代码 |
slef:: $country slef:: myCountry() |
在子类访问父类静态成员属性或方法,使用 parent::(注意不是 $parent),如:
代码如下 | 复制代码 |
parent:: $country parent:: myCountry() |
外部访问静态成员属性和方法为 类名/子类名:: ,如:
代码如下 | 复制代码 |
Person::$country Person::myCountry() Student::$country |
但静态方法也可以通过普通对象的方式访问。
例子 声明静态变量
代码如下 | 复制代码 |
<?PHP |
例子 使用静态变量的例子
代码如下 | 复制代码 |
<?PHP function Test() { static $w3sky = 0; echo $w3sky; $w3sky++; } ?> |
现在,每次调用 Test() 函数都会输出 $w3sky 的值并加一。
静态变量也提供了一种处理递归函数的方法。递归函数是一种调用自己的函数。写递归函数时要小心,因为可能会无穷递归下去。必须确保有充分的方法来中止递归。一下这个简单的函数递归计数到 10,使用静态变量 $count 来判断何时停止:
例子 静态变量与递归函数
代码如下 | 复制代码 |
<?PHP |
注: 静态变量可以按照上面的例子声明。如果在声明中用表达式的结果对其赋值会导致解析错误。
更多关于php静态变量用法
网站开发少不了有网站后台,有了后台自然要对用户有同角色来分配一下,特别是多用户系统的情况下,如我一个系统要有多个管理员,那么我这些管理要分成,编辑,友情连接,管理员等,那我们要有权限和角色分配,今天我们就来看我以前做的一个系统吧。先介绍一下文件,
adminconfig.php 这是后台系统中所有文件权限配置。
fun.php 这是一个功能函数
left.php 网站后台根据用户登录的ID来加载相对应的功能菜单
op.php 调用adminconfig.php 默认权限文件
opsava.php 保存用户权限成一个php文件
好了我们先来看看 fun.php文件吧。
代码如下 | 复制代码 |
<? //下面为生成用户的php权限文件 //数组转换成字串 //写入文件 ?> |
adminconfig.php 后台权限配置文件,以一个数组形式保存
代码如下 | 复制代码 |
<? |
left.php文件很简单就是根据用户登录后ID读出权限
代码如下 | 复制代码 |
<? foreach($bb as $key=>$submenu) |
如图
op.php这个文件就是要调用我们的adminconfig.php文件,然后利用fun.php文件中函数把提供过来的数据保存成数组如图
点击保存我们调用了opsava.php 文件,代码如下
代码如下 | 复制代码 |
<? } |
保存成功后文件内容如
代码如下 | 复制代码 |
<?php |
这样的话我们的left只要加载 7.php文件就只会显示这里在的文件,这样一个基本的后台权限就完成了。
原站原创教程转载注明来源:http://www.111cn.net/phper/php.html
相关文章
- 这篇文章主要介绍了JS实现简单面向对象的颜色选择器,以完整实例形式分析了JavaScript基于面向对象实现颜色选择器的具体步骤与实现技巧,需要的朋友可以参考下...2016-04-23
- 用面向对象的思维去理解Vue组件,可以将所有的事物都抽象为对象,而类或者说是组件,都具有属性和操作。这篇文章主要介绍了尝试用面向对象思维理解Vue组件,需要的朋友可以参考下...2021-07-11
- 这篇文章主要介绍了个人对c# 面向对象的理解,算是一个入门篇吧,给需要的小伙伴参考下,抛砖引玉。...2020-06-25
- 这篇文章主要介绍了php面向对象之反射功能与用法,结合实例形式简单分析了php5面向对象反射的概念及具体用法,需要的朋友可以参考下...2017-04-03
- 当你尝试使用一个未定义的类时,PHP会报告一个致命错误. 解决方法就是添加一个类,可以用include包含一个文件. 究竟你知道要用到哪个类. 但是,PHP提供了类的自动加载功...2016-11-25
- 今天小编就为大家分享一篇关于C#面向对象编程基础概念汇总的文章,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧...2020-06-25
- 本篇文章主要介绍了Javascript的面向对象,小编觉得这篇文章内容很不错,需要的朋友可以看下,希望能够给你带来帮助...2021-09-27
PHP面向对象开发之类中接口的应用(interface、implements)
php类中接口的应用关键字是interface、implements了,接口是一种成员属性全部为抽象或常量的特殊抽象类,下面我们看几个实例。 类中接口的应用 1.关键字:interface...2016-11-25- 这篇文章主要介绍了C#中面向对象编程机制之继承学习笔记,本文给出一个简单子实例讲解C#中的继承,并讲解了一些C#继承的知识技巧,需要的朋友可以参考下...2020-06-25
PHP的面向对象编程:开发大型PHP项目的方法(三)(转载)
PHP的面向对象编程:开发大型PHP项目的方法(三) 作者:Luis Argerich 译者:limodou 重载(与覆盖不同)在PHP中不支持。在OOP中,你可以重载一个方法来实现两个或重多的方法...2016-11-25- 在php中不支持多重继承,如果我们向使用多个类的方法而实现代码重用有什么办法么?那就是组合。在一个类中去将另外一个类设置成属性。 下面的例子,模拟了多重继承。 view s...2016-11-25
- 这篇文章主要介绍了Java面向对象基础,类,变量,方法,需要的朋友可以参考下...2020-10-03
- 这篇文章主要介绍了JavaScript基于面向对象之继承...2015-12-14
- 大多数类都有一种称为构造函数的特殊方法。当创建一个对象时,它将自动调用构造函 数,也就是使用new 这个关键字来实例化对象的时候自动调用构造方法。 构造函数的声...2016-11-25
- 这篇文章主要为大家介绍了js面向对象编程,感兴趣的小伙伴们可以参考一下...2016-01-25
- PHP 语言从诞生起,就具有了很好的面向过程编程的特性。只是在其进化过程中才逐渐加强了面向对象的特性,直到 PHP5.0,也才接近完善。一般来说,PHP 的初学者和...2016-11-25
- 下面小编就为大家带来一篇老生常谈PHP面向对象之命令模式(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2017-05-26
- 串行化可以把变量包括对象,转化成连续bytes数据,你可以将串行化后的变量存在一个文件里或在网络上传输,然后再反串行化还原为原来的数据。你在反串行化类的对象之前定义的...2016-11-25
- 这篇文章主要介绍了Python面向对象封装操作,结合具体案例形式详细分析了Python面向对象的封装、扩展等操作技巧与相关注意事项,需要的朋友可以参考下...2020-05-06
- 这篇文章主要介绍了Python面向对象之继承原理与用法,结合具体案例形式分析了Python面向对象程序设计中继承的原理、使用方法及相关操作注意事项,需要的朋友可以参考下...2020-05-06