PHP类相关函数
2015-11-14 21:51
645 查看
虽然PHP不是一开始就是面向对象的语言,而且基因上也不是面向对象友好的但是,随着PHP版本的发展,PHP的面向对象特性还是渐渐的向Java靠拢了。自从PHP有了面向对象特性后,基本所有的框架,库,网站都是使用了面向对象来写的。所以了解PHP的类还是很重要的。
PHP提供了很多函数来操作类,这也是面向对象不干净的地方。。。但是这些函数的确可以很方便的操作类。
这个函数也体现了PHP怎么方便怎么简单怎么来的设计思想。。。在Java中,你用一个类就得乖乖import没啥取巧的。
没有定义类直接实例化:
报错:
可以定义
这样就可以找到
不会。第一次调用
可以存在多个
不能。而且如果定义多个
因为
使用一个类的别名:
定义了别名,两个类还是一个类,记住这个就行了。
如果原本的类无法加载,则会报错:
这个时候,有两个解决方法。一个是直接include/require,一个是autoload。如果使用autoload,第三个参数就起作用了。
输出:
可以看到,虽然定义了My为MyClass的别名,因为
需要注意的就是
1. xxx_name大小写不敏感
2. autoload指定是否在找不到时使用autoloader
类定义如下:
获取类的所有方法:
输出:
可以看出,
所以如果在类的成员函数中调用
注意两点:
class_name只能是string,如果你手上只有类的实例,可以使用
该函数只能获得当前作用域可以访问的属性,所以类外部调用只能获得public属性,类内部调用可以获得所有属性。
这个函数很直接了当了,不过还是需要注意:
并且返回
返回调用
输出:
总结:
1. 类外部只能获得public的属性,类内部可以获得所有属性。
2. PHP类的属性是可以随时扩展的,类的内部和外部都可以对属性进行扩展。
输出:
如果参数对应的类没有父类,则返回false。
参考前面的
需要注意的就是,
和
注意:
判断类中是否存在字符串
注意:
输出:
PHP提供了很多函数来操作类,这也是面向对象不干净的地方。。。但是这些函数的确可以很方便的操作类。
__autoload - 自动加载未定义的类
这个函数不是供我们调用,而是需要我们实现的一个函数。如果PHP找不到一个类的定义,就会调用__autoload函数,并把类名作为字符串参数传入。
这个函数也体现了PHP怎么方便怎么简单怎么来的设计思想。。。在Java中,你用一个类就得乖乖import没啥取巧的。
没有定义类直接实例化:
$obj = new MyClass();
报错:
Fatal error: Class 'MyClass' not found in /Users/mazhibin/project/learn/learn-php/class-function/__autoload.php on line 7
可以定义
__autoload函数:
function __autoload($class){ if($class == 'MyClass'){ require("../common/MyClass.php"); } }
这样就可以找到
MyClass这个类了。
关于__autoload的问题
多次new MyClass()会多次调用
__autoload么?
不会。第一次调用
__autoload后,
MyClass已被加载,所以就不需要再调用
__autoload了。
可以存在多个
__autoload函数么?
不能。而且如果定义多个
__autoload函数会报错:
Fatal error: Cannot redeclare __autoload() (previously declared in /Users/mazhibin/project/learn/learn-php/class-function/__autoload.php:3) in /Users/mazhibin/project/learn/learn-php/class-function/__autoload.php on line 13
因为
__autoload函数只能定义一个,所以一般使用的是
spl_autoload_register()。
class_alias - 定义类别名
这个函数就和shell中的alias一样,shell的alias命令定义命令的别名,PHP中的class_alias定义的是类的别名。bool class_alias ( string $original , string $alias [, bool $autoload = TRUE ] )
使用一个类的别名:
class_alias('MyClass','My'); $my = new My(); $myclass = new MyClass(); var_dump($my == $myclass); //true var_dump($my === $myclass); //false var_dump($my instanceof $myclass); //true var_dump($my instanceof My); //true var_dump($my instanceof MyClass); //true var_dump($myclass instanceof My); //true var_dump($myclass instanceof MyClass); //true
定义了别名,两个类还是一个类,记住这个就行了。
如果原本的类无法加载,则会报错:
Warning: Class 'MyClass' not found in /Users/mazhibin/project/learn/learn-php/class-function/class_alias.php on line 3 Fatal error: Class 'My' not found in /Users/mazhibin/project/learn/learn-php/class-function/class_alias.php on line 5
这个时候,有两个解决方法。一个是直接include/require,一个是autoload。如果使用autoload,第三个参数就起作用了。
class_alias的autoload参数的效果
默认,$autoload参数为
true,如果原本的类不存在,就会使用自动加载。如果
$autoload参数设置为
false,则如果原本的类不存在,就去找别名字符串指定的类。见例子:
function __autoload($class){ echo "__autoload $class\n"; if($class == 'MyClass'){ require("../common/MyClass.php"); }else if($class == 'My'){ require("../common/My.php"); } } class_alias('MyClass','My',false); $my = new My(); $myclass = new MyClass(); var_dump($my == $myclass); var_dump($my === $myclass); var_dump($my instanceof $myclass); var_dump($my instanceof My); var_dump($my instanceof MyClass); var_dump($myclass instanceof My); var_dump($myclass instanceof MyClass);
输出:
Warning: Class 'MyClass' not found in /Users/mazhibin/project/learn/learn-php/class-function/class_alias2.php on line 13 __autoload My My::__construct __autoload MyClass MyClass::__construct bool(false) bool(false) bool(false) bool(true) bool(false) bool(false) bool(true)
可以看到,虽然定义了My为MyClass的别名,因为
$autoload=false,所以在找不到My类时,不会自动加载”MyClass”指定的类,而是尝试加载”My”类。所以此时别名效果就失效了。不过PHP会先爆出Warning。
可以定义和别名同名的类么?
function __autoload($class){ echo "__autoload $class\n"; if($class == 'MyClass'){ require("../common/MyClass.php"); }else if($class == 'My'){ require("../common/My.php"); } } class My{ function __construct(){ echo "this My::__construct\n"; } } class_alias('MyClass','My',true); $my = new My();
$autoload=true时,
new My()先尝试读取MyClass,这时发现,代码中已经定义了My类(此时两者已经等价了,所以认为是重定义),和普通重定义不一样(普通重定义报Fatal),这次报的是Warning,并且使用的是My这个定义而不是MyClass这个定义。
__autoload MyClass Warning: Cannot redeclare class My in /Users/mazhibin/project/learn/learn-php/class-function/class_alias3.php on line 22 this My::__construct
$autoload=true时,PHP先报MyClass找不到的Warning,然后淡定地使用本文件定义的My类。
Warning: Class 'MyClass' not found in /Users/mazhibin/project/learn/learn-php/class-function/class_alias3.php on line 20 this My::__construct
class_exists/interface_exists/trait_exists - 判断一个类/接口/traits是否定义
bool class_exists ( string $class_name [, bool $autoload = true ] ) bool interface_exists ( string $interface_name [, bool $autoload = true ] ) bool trait_exists ( string $traitname [, bool $autoload ] )
需要注意的就是
1. xxx_name大小写不敏感
2. autoload指定是否在找不到时使用autoloader
get_class_methods - 获取类的方法名组成的数组
array get_class_methods ( mixed $class_name )
类定义如下:
class MyClass{ function __construct(){} function public_func(){} private function private_func(){} protected function protected_function(){} }
获取类的所有方法:
$obj = new MyClass();var_dump(get_class_methods($obj));
//or
var_dump(get_class_methods("MyClass"));
输出:
array(2) { [0]=> string(11) "__construct" [1]=> string(11) "public_func" }
可以看出,
get_class_methods可以获得构造函数,但是无法获得无法访问的函数。
所以如果在类的成员函数中调用
get_class_methods可以获得所有方法。
get_class_vars - 获得类的默认属性组成的键值数组
array get_class_vars ( string $class_name )
注意两点:
class_name只能是string,如果你手上只有类的实例,可以使用
get_class函数
该函数只能获得当前作用域可以访问的属性,所以类外部调用只能获得public属性,类内部调用可以获得所有属性。
get_class - 返回对象的类名
string get_class ([ object $obj ] )
这个函数很直接了当了,不过还是需要注意:
obj参数可以不传,这时返回调用这个函数的类的名字,如果在一个函数外调用无参数的get_class,则会报Warning:
Warning: get_class() called without object from outside a class in /Users/mazhibin/project/learn/learn-php/class-function/get_class.php on line 11
并且返回
flase。
get_declared_classes/get_declared_interfaces/get_declared_traits
array get_declared_classes ( void ) array get_declared_interfaces ( void ) array get_declared_traits ( void )
返回调用
get_declared_xxx时,作用域中可以使用的类/接口/traits。
get_object_vars — 返回由对象属性组成的关联数组
array get_object_vars ( object $obj )
get_object_vars获得对象在目前作用域可以获取的属性的关联数组。
class A{ public $public_var; private $private_var; protected $protected_var; function setUp(){ $this->public_var = 1; $this->private_var = 2; $this->protected_var = 3; $this->extra = true; } function get_object_vars(){ return get_object_vars($this); } } $obj = new A(); var_dump(get_object_vars($obj)); var_dump($obj->get_object_vars()); $obj->setUp(); $obj->extraOut = true; var_dump(get_object_vars($obj)); var_dump($obj->get_object_vars());
输出:
array(1) { ["public_var"]=> NULL } array(3) { ["public_var"]=> NULL ["private_var"]=> NULL ["protected_var"]=> NULL } array(3) { ["public_var"]=> int(1) ["extra"]=> bool(true) ["extraOut"]=> bool(true) } array(5) { ["public_var"]=> int(1) ["private_var"]=> int(2) ["protected_var"]=> int(3) ["extra"]=> bool(true) ["extraOut"]=> bool(true) }
总结:
1. 类外部只能获得public的属性,类内部可以获得所有属性。
2. PHP类的属性是可以随时扩展的,类的内部和外部都可以对属性进行扩展。
get_object_vars可以获得当前这个对象的所有属性,包括运行时添加的属性。
get_parent_class — 返回对象或类的父类名
string get_parent_class ([ mixed $obj ] )
class ParentClass{} class Child extends ParentClass{} var_dump(get_parent_class('ParentClass')); var_dump(get_parent_class('Child'));
输出:
bool(false) string(11) "ParentClass"
如果参数对应的类没有父类,则返回false。
参考前面的
class_exists。
is_a — 判断是否是类/子类的实例
bool is_a ( object $object , string $class_name [, bool $allow_string = FALSE ] )
$allow_string函数指定
$object是否可以是字符串。如果指定为false,则在传入字符串时,总返回false。
class ParentClass{} class Child extends ParentClass{} $parentObj = new ParentClass(); $childObj = new Child(); var_dump(is_a($childObj,'Child')); //true var_dump(is_a($childObj,'ParentClass')); //true var_dump(is_a($parentObj,'Child')); //false var_dump(is_a($parentObj,'ParentClass')); //true var_dump(is_a('Child','Child')); //false var_dump(is_a('Child','ParentClass')); //false var_dump(is_a('Child','Child',true)); //true var_dump(is_a('Child','ParentClass',true)); //true
需要注意的就是,
is_a传入子类对象和父类时,返回true。
is_subclass_of — 如果此对象是该类的子类,则返回 TRUE
bool is_subclass_of ( mixed $object , string $class_name [, bool $allow_string = TRUE ] )
和
is_a不同,
is_subclass_of只会是在子类的时候返回true。
$allow_string函数指定
$object是否可以是字符串。如果指定为false,则在传入字符串时,总返回false。
class ParentClass{} class Child extends ParentClass{} $childObj = new Child(); var_dump(is_subclass_of($childObj,'Child')); //false var_dump(is_subclass_of($childObj,'ParentClass')); //true var_dump(is_subclass_of('Child','ParentClass')); //true var_dump(is_subclass_of($childObj,'Child',false)); //false var_dump(is_subclass_of($childObj,'ParentClass',false)); //true var_dump(is_subclass_of('Child','ParentClass',false)); //false
method_exists — 判断方法是否存在
bool method_exists ( mixed $object , string $method_name )
注意:
method_exists不会考虑属性的访问修饰符(
public/protected/private)。
property_exists - 判断类属性是否存在
bool property_exists ( mixed $class , string $property )
判断类中是否存在字符串
$property指定的属性。
注意:
property_exists不会考虑属性的访问修饰符(
public/protected/private)。
<?php class A{ public $public_var; protected $protected_var; private $private_var; static public $static_public_var; static protected $static_protected_var; static private $static_private_var; public function public_fuck(){ var_dump(property_exists($this, 'private_var')); } static public function static_public_func(){ var_dump(property_exists('A', 'private_var')); } } var_dump(property_exists('A','public_var')); //true var_dump(property_exists('A','protected_var')); //true var_dump(property_exists('A','private_var')); //true var_dump(property_exists('A','static_public_var')); //true var_dump(property_exists('A','static_protected_var')); //true var_dump(property_exists('A','static_private_var')); //true var_dump(property_exists('A','public_fuck')); //false var_dump(property_exists('A','static_public_func')); //false var_dump(property_exists(new A(),'public_var')); //true var_dump(property_exists(new A(),'protected_var')); //true var_dump(property_exists(new A(),'private_var')); //true (new A())->public_fuck(); //true A::static_public_func(); //true
get_called_class — 获得后期静态绑定(”Late Static Binding”)类的名称
string get_called_class ( void )
class A{ static function func(){ var_dump(get_called_class()); } } class B extends A{} A::func(); B::func(); var_dump(get_called_class());
输出:
string(1) "A" string(1) "B" Warning: get_called_class() called from outside a class in /Users/mazhibin/project/learn/learn-php/class-function/get_called_class.php on line 15 bool(false)
对应版本
参考文章
PHP: Classes/Object Functions - Manual相关文章推荐
- 一个关于if else容易迷惑的问题
- Android Native 绘图方法
- PHP5.2.*防止Hash冲突拒绝服务攻击的Patch
- 深入理解PHP之匿名函数
- JSP/PHP基于Ajax的分页功能实现
- 关于PHP通过PDO用中文条件查询MySQL的问题。
- 什么是设计模式
- PHP数据库长连接mysql_pconnect的细节
- Php Installing An Expansion
- Mootools 1.2教程 函数
- autoit InputBox 函数
- 文件遍历排序函数
- Oracle 函数大全[字符串函数,数学函数,日期函数]第1/4页
- Lua编程示例(二):面向对象、metatable对表进行扩展
- ASP下经常用的字符串等函数参考资料
- PostgreSQL教程(五):函数和操作符详解(1)
- C#中面向对象编程机制之多态学习笔记
- C#中struct和class的区别详解
- DOS批处理 函数定义与用法