另外,如果从类的内部访问const或者static变量或者方法,那么就必须使用自引用的self,反之如果从类的内部访问不为const或者static变量或者方法,那么就必须使用自引用的$this。
$this实例
代码如下 | 复制代码 |
<?php // this是指向当前对象的指针 class test_this{ $test=new test_this('北京欢迎你!'); //实例化对象 |
::使用方法
代码如下 | 复制代码 |
//parent是指向父类的指针 class test_parent{ //基类 $nostop=new test_son('女性','22');//实例化test_son对象 |
使用self::$name的形式。注意的是const属性的申明格式,const PI=3.14,而不是const $PI=3.14
代码如下 | 复制代码 |
class clss_a { |
还要注意的一点是如果类的方法是static的,他所访问的属性也必须是static的。
在类的内部方法访问未声明为const及static的属性时,使用$this->value ='class_a';的形式。
原因分析
出现这种问题一般是变量未定义造成的
例
代码如下 | 复制代码 |
if($a) } |
//提示:Notice: Undefined variable: a in E:/www/test.php on line 5
代码如下 | 复制代码 |
$a=1; } //输出1 error_reporting(0); if($a) } |
解决方法总结
1、如果是变量未申请直接申名变量如 $a=1; 这样。
2、在文章头部加error_reporting(0); 所有错误都不提示
3、isset($_GET["page"]) 或 :@$page=$_GET["page"]
4、用php.ini中error_reporting = E_ALL & ~E_NOTICE 可以关闭notice的显示,屏蔽掉此类警告好,
(OOP)来开发。面向对象开发相对于面向过程有很多优点:
维护简单 模块化是面向对象编程中的一个特征。实体被表示为类和同一名字空间中具有相同功能的类,我们可以在名字空间中添加一个类而不会影响该名字空间的其他成员。
可扩充性 面向对象编程从本质上支持扩充性。如果有一个具有某种功能的类,就可以很快地扩充这个类,创建一个具有扩充的功能的类。
代码重用 由于功能是被封装在类中的,并且类是作为一个独立实体而存在的,提供一个类库就非常简单了。
它比较适合多人合作来开发项目,所以现在很多大中型网站都选择了用OOP来开发。
下面我来来介绍面向对象编程
类与属性和方法
PHP中定义类语法格式:
代码如下 | 复制代码 |
class classname [可选属性]{ public $property [=value];… //用public声明一个公共标识 然后给予一个变量 变量也可以赋值 function functionname ( args ){ //类的方法里的成员函数 代码} … //类的方法(成员函数) } |
生成对象(类的实例化): $对象名=new classname( );
使用对象的属性
在一个类中,可以访问一个特殊指针$this当在该类中通过一个操作设置或访问该变量时,使用$this->name来引用.
代码如下 | 复制代码 |
class person{ |
1.final
final:php5新增一个final关键字。如果父类中的方法被声明为final,则子类无法覆盖该方法;如果一个类被声明final,则不能被继承。
代码如下 | 复制代码 |
class BaseClass{ public function test(){ ehco "test"; } final public function moreTest(){ echo "moretest"; } } class ChildClass extends BaseClass{ public function moreTest(){ echo "moretest"; } } // 产生 Fatal error: Cannot override final method BaseClass::moretest() |
2.__toString(建议用PHP5.2或者更高版本)
代码如下 | 复制代码 |
class Person{ protected $name; protected $email; public function setName($name){ $this->name = $name; } public function setEmail($email){ $this->email = $email; } public function __toString(){ return "$this->name <$this->email>"; } } $rasums = new Person; $rasums->setName('test'); $rasums->setEmail('test@qq.com'); print $rasums; |
3.接口和抽象类
接口的作用:你想要保证一个类按照特定的名称、可见性和原型实现一个或多个方法。
接口的要求:
类中全部为抽象方法
抽象方法钱不用加abstract
接口抽象方法属性为public
成员属性必须为常量
例:
代码如下 | 复制代码 |
interface ChildTest{ public function childTest(); } class FathTest implements ChildTest1,ChildTest2{ public function childTest(){ echo 1; } ………… } |
抽象的作用: 其实抽象类和接口类有一部分很像,记得在哪里看见这样一句话,抽象类就把类像的部分抽出来,这句看上去很搞笑,其实它说出了抽象类的真理,抽象类的作用 是,当你发现你的很多类里面用很多方法你不断的在重复写,那你就可以考虑使用抽象类了,你可能会说“我不是可以重写一个类每个公共类我个实例化一个这个公 共类,调用相同的方法就可以了”,这里是可以,实际上抽象类做的工作也就是这个,不过他省去了你实例化的这个步骤,让你就像直接调用本类方法一样方便,而 且你还可以重载这个方法。
抽象的要求:
类中至少有一个抽象方法
抽象方法钱必须加abstract
例:
代码如下 | 复制代码 |
abstract class Database{ abstract public function connect(); abstract public function query(); abstract public function fetch(); abstract public function close(); } |
注:抽象方法不能定义为私有方法、不能定义为最终方法,因为它们需要被继承。
4.传递对象引用
php4:所有“=”都是创建一个副本
php5:除了对象外,其他“=”进行赋值时,都是创建一个副本;而对象则是引用
5.克隆对象
一、
聚合类:
__call方法简介:
当客户端代码用类中未定义的方法时,__call会被调用。
__call()接受两个参数,一个是方法名称,另一个是传递给要调用方法的所有参数(包括数组)
__call()方法返回的任何值都会返回给客户,将好像调用方式真实存在一样
例:
代码如下 | 复制代码 |
class Address{ public function setCity($city){$this->city = $city;} class Person{ public function setName($name){ public function __call($method,$arguments){ $test1 = new Person; $test1->setName('testname1'); echo $test1->getName().'-'.$test1->getCity()."n"; |
6.重要属性访问(__set __get __isset __unset) __isset __unset5.1之后才有用
作用:拦截对属性的需求,为了提高分离的程度,还要实现__isset()和__unset(),以便当我们用isset来检测属性或者unset()来删除属性,来保证类的行为正确
例:
代码如下 | 复制代码 |
class Person{ public function __get($property){ public function __set($property,$value){ $test = new Person; |
注意:
这两个方法只会捕捉缺少的属性,如果你为你的类定义了一个属性,那么当访问这个属性时php不会调用__get()和__set();
这两个方法完全破坏了任何属性继承的想法。如果父对象中有个 __get()方法,而你在子类中又实现了自己的__get()方法,那么你的对象不会正确的执行,因为父类的__get()方法永远不会被调用,当然可以用parent::__get()解决
缺点:
速度相对较慢
使用魔术访问器方法就不可能在使用反射类,如phpdocumentor这类的工具将代码自动文档化
不能将其用于静态属性
字符串;判断字符串是否为空;输出判断;你可以在修饰一下
代码如下 | 复制代码 |
if (empty($C_char)) return false; //是否已设定 if ($C_char=='') return false; //是否为空 |
利用==""
例
代码如下 | 复制代码 |
<?php if($str==='') {//''==null ''==false ''!==false |
empty判断是否为空
代码如下 | 复制代码 |
<?php |
从表面上看,很容易误解empty()函数是判断字符串是否为空的函数,其实并不是,我也因此吃了很多亏。
empty()函数是用来测试变量是否已经配置。若变量已存在、非空字符串或者非零,则返回 false 值;反之返回
true值。所以,当字符串的值为0时,也返回true,就是执行empty内部的语句。这就是陷阱。
如: 假设 $value = 0; 则empty($value)=false。
判断字符串是否为空,可以这么判断: if ($value=="") ...
* 格式:bool empty ( mixed var )
* 功能:检查一个变量是否为空
* 返回值:
* 若变量不存在则返回 TRUE
* 若变量存在且其值为""、0、"0"、NULL、、FALSE、 array()、var $var; 以及没有任何属性的对象,则返回
TURE
* 若变量存在且值不为""、0、"0"、NULL、、FALSE、 array()、var $var; 以及没有任何属性的对象,则返回
FALSE
isset()和empty()判断方法:
代码如下 | 复制代码 |
function demo(){ |
代码如下 | 复制代码 |
<?php // 定义提示函数 function alert($msg){ return '<script type="text/javascript">alert("'.$msg.'");window.history.back(-1);</script>'; }
$allowType = array('image/jpeg','image/gif','image/jpg');
$filePath = './uploadFileDir/';
// 接收表单信息 其中里边写的 file 值是 静态页form表单里的name值 $file = $_FILES['file'];
// 第一步,判断上传的文件是否有错误 if( $file['error'] !== 0 ){ exit(alert('文件上传错误')); }
// 第二步,判断文件大小,这里的102400是字节,换算为kb就是100kb if( $file['size'] > 102400 ){ exit(alert('文件过大')); }
// 第三步,判断文件类型 if( !in_array(mime_content_type($file['tmp_name']),$allowType) ){ exit(alert('文件类型错误')); }
// 第四步,判断路径是否存在,如果不存在则创建 if( !file_exists($filePath) && !mkdir($filePath,0777,true) ){ exit(alert('创建目录错误')); }
// 第五步,定义上传后的名字及路径 $filename = time().'_'.$file['name'];
// 第六步,复制文件 if( !copy($file['tmp_name'],$filePath.$filename) ){ exit(alert('上传文件出错,请稍候重试')); }
// 第七步,删除临时文件 unlink($file['tmp_name']);
// 提示上传成功 echo alert('恭喜,上传文件['.$filename.']成功!'); |