0

0

前端学PHP之面向对象系列第二篇魔术方法

php中文网

php中文网

发布时间:2016-11-16 10:24:05

|

1482人浏览过

|

来源于php中文网

原创

×
目录
[1]构造方法 [2]析构方法 [3]不可访问属性[4]对象复制[5]字符串[6]对象不存在[7]自动加载类[8]串行化[9]函数调用

前面的话

  php在面向对象部分有很多相关的魔术方法,这些方法为面向对象实现提供了便利,本文将详细介绍魔术方法

 

构造方法

  大多数类都有一种称为构造函数的特殊方法。当创建一个对象时,它将自动调用构造函数,通常用它执行一些有用的初始化任务

  构造函数的声明与其它操作的声明一样,只是其名称必须是两个下划线__construct( )。这是PHP5中的变化;PHP4的版本中,构造函数的名称必须与类名相同。为了向下兼容,如果一个类中没有名为__construct( )的方法,PHP将搜索一个与类名相同的方法

void __construct ([ mixed $args [, $... ]] )

  如果子类中定义了构造函数则不会隐式调用其父类的构造函数。要执行父类的构造函数,需要在子类的构造函数中调用 parent::__construct()。如果子类没有定义构造函数则会如同一个普通的类方法一样从父类继承(假如没有被定义为 private 的话)

立即学习PHP免费学习笔记(深入)”;

php
class BaseClass {
   function __construct() {
       print "In BaseClass constructor\n";
   }
}
class SubClass extends BaseClass {
   function __construct() {
       parent::__construct();
       print "In SubClass constructor\n";
   }
}
class OtherSubClass extends BaseClass {
}
// In BaseClass constructor
$obj = new BaseClass();

// In BaseClass constructor
// In SubClass constructor
$obj = new SubClass();

// In BaseClass constructor
$obj = new OtherSubClass();
?>

 

析构方法

  与构造方法相对的就是析构方法。析构方法是PHP5新添加的内容,在PHP4中没有析构方法。析构方法是在对象被销毁之前自动调用的方法,主要执行一些特定的操作,例如关闭文件,释放结果集等

  与构造方法类似,一个类的析构方法名称必须是两个下划线 _ _destruct( )。析构函数不能带有任何参数

php
class MyDestructableClass {
   function __construct() {
       print "In constructor\n";
       $this->name = "MyDestructableClass";
   }
   function __destruct() {
       print "Destroying " . $this->name . "\n";
   }
}
//In constructor Destroying MyDestructableClass
$obj = new MyDestructableClass();
?>

 

不可访问属性

get()

  读取不可访问属性(protected、private)时,__get()会被调用,并将属性名以第一个参数(string)传进此方法中

public mixed __get ( string $name )
php
class demo{
    protected $protected = 1;
    public $public = 2;
    private $private = 3;
    function __get($name){
        echo "111{$name}111
"; } } $d1 = new demo; $d1->protected;//111protected111 $d1->public; $d1->private;//111private111 ?>

set()

  在给不可访问属性(protected、private)赋值时,__set() 会被调用,并将属性名以第一个参数(string),值作为第二参数(mixed)传进此方法中

public void __set ( string $name , mixed $value )
php
class demo{
    protected $protected = 1;
    public $public = 2;
    private $private = 3;
    function __set($name,$value){
        echo "0{$name}0{$value}
"; } } $d1 = new demo; $d1->protected = '1';//0protected01 $d1->public = '2'; $d1->private = '3';//0private03 ?>

isset()

  当对不可访问属性(protected、private)调用 isset() 或 empty() 时,__isset() 会被调用

public bool __isset ( string $name )
php
class demo{
    protected $protected = 1;
    public $public = 2;
    private $private = 3;
    function __isset($name){
        echo "0{$name}0
"; } } $d1 = new demo; empty($d1->protected);//0protected0 empty($d1->public); empty($d1->private);//0private0 ?>

unset()

  当对不可访问属性(protected、private)调用unset()时,__unset()会被调用

public void __unset ( string $name )
php
class demo{
    protected $protected = 1;
    public $public = 2;
    private $private = 3;
    function __unset($name){
        echo "0{$name}0
"; } } $d1 = new demo; unset($d1->protected);//0protected0 unset($d1->public); unset($d1->private);//0private0 ?>

 

对象复制

clone()

  在对象克隆时会自动调用clone()方法,这方法不需要任何参数,可以通过该方法对克隆后的副本重新初始化

  clone()方法会自动包含this和that两个对象的引用,this是副本对象的引用,that是原本对象的引用

php
    class Person{
        private $name;
        private $sex;
        private $age;
        function __construct($name="",$sex="",$age=1){
            $this->name= $name;
            $this->sex = $sex;
            $this->age = $age;
        }
        function __clone(){
            $this->name = $this->name."的副本";
        }
        function say(){
            echo "我的名字:" .$this->name.",性别:".$this->sex.",年龄:".$this->age."
"; } } $p1 = new Person('张三','男','20'); $p2 = clone $p1; $p1->say();//我的名字:张三,性别:男,年龄:20 $p2->say();//我的名字:张三的副本,性别:男,年龄:20 ?>

 

字符串

toString()

  __toString()方法用于一个类被当成字符串时应怎样回应,它是快速获取对象的字符串表示的最便捷的方式,是直接输出对象引用时自动调用的方法

Kite
Kite

代码检测和自动完成工具

下载
php
class TestClass
{
    public $foo;
    public function __construct($foo) 
    {
        $this->foo = $foo;
    }
    public function __toString() {
        return $this->foo;
    }
}
$class = new TestClass('Hello');
echo $class;//Hello
?>

 

对象不存在

call()

  在对象中调用一个不可访问方法时,__call()会被调用

callStatic()

  在静态上下文中调用一个不可访问方法时,__callStatic()会被调用

php
class MethodTest 
{
    public function __call($name, $arguments) 
    {
        echo "Calling object method '$name' "
             . implode(', ', $arguments). "\n";
    }
    public static function __callStatic($name, $arguments) 
    {
        echo "Calling static method '$name' "
             . implode(', ', $arguments). "\n";
    }
}
$obj = new MethodTest;
//Calling object method 'runTest' in object context
$obj->runTest('in object context');
//Calling static method 'runTest' in static context
MethodTest::runTest('in static context');  
?>

 

自动加载类

autoload()

  在PHP5中,可以定义一个__autoload()函数,它会在试图使用尚未被定义的类时自动调用。通过调用此函数,脚本引擎在PHP出错失败前有了最后一个机会加载所需的类

php
function __autoload($class_name) {
    require_once $class_name . '.php';
}

$obj  = new MyClass1();
$obj2 = new MyClass2();
?>

 

串行化

sleep()

  在调用serialize()函数将对象串行化时,检查类中是否存在一个魔术方法 __sleep()。如果存在,该方法会先被调用,然后才执行序列化操作。此功能可以用于清理对象,并返回一个包含对象中所有应被序列化的变量名称的数组。如果该方法未返回任何内容,则 NULL 被序列化,并产生一个 E_NOTICE 级别的错误

  __sleep()函数不需要接受任何参数,但需要返回一个数组,在数组中包含需要串行化的属性。未被包含在数组中的属性将在串行化时被忽略。如果没有在类中声明__sleep()方法,对象中的所有属性都将被串行化

wakeup()

  在调用unserialize()函数将对象反串行化对象时,则会自动调用对象中的__wakeup()方法,用来在二进制串重新组成一个对象时,为新对象中的成员属性重新初始化

  wakeup()经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作

php
class Connection 
{
    protected $link;
    private $server, $username, $password, $db;  
    public function __construct($server, $username, $password, $db)
    {
        $this->server = $server;
        $this->username = $username;
        $this->password = $password;
        $this->db = $db;
        $this->connect();
    }
    private function connect()
    {
        $this->link = mysql_connect($this->server, $this->username, $this->password);
        mysql_select_db($this->db, $this->link);
    }
    public function __sleep()
    {
        return array('server', 'username', 'password', 'db');
    }
    public function __wakeup()
    {
        $this->connect();
    }
}
?>

 

函数调用

invoke()

  当尝试以调用函数的方式调用一个对象时,__invoke()方法会被自动调用

php
class CallableClass 
{
    function __invoke($x) {
        var_dump($x);
    }
}
$obj = new CallableClass;
$obj(5);//int(5)
var_dump(is_callable($obj));//bool(true)
?>

【补充】

set_state()

  当调用var_export()导出类时,set_state()方法会被调用,本方法的唯一参数是一个数组,其中包含按 array('property' => value, ...) 格式排列的类属性

  [注意]var_export()返回关于传递给该函数的变量的结构信息,它和var_dump()类似,不同的是其返回的表示是合法的PHP代码,也就是说,var_export返回的代码,可以直接当作php代码赋给一个变量。 而这个变量就会取得和被var_export一样的类型的值

php
class A
{
    public $var1;
    public $var2;
    public static function __set_state($an_array) 
    {
        $obj = new A;
        $obj->var1 = $an_array['var1'];
        $obj->var2 = $an_array['var2'];
        return $obj;
    }
}
$a = new A;
$a->var1 = 5;
$a->var2 = 'foo';
eval('$b = ' . var_export($a, true) . ';'); 
/*
object(A)[2]
  public 'var1' => int 5
  public 'var2' => string 'foo' (length=3)
 */
var_dump($b);
?>
PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
C++ 高级模板编程与元编程
C++ 高级模板编程与元编程

本专题深入讲解 C++ 中的高级模板编程与元编程技术,涵盖模板特化、SFINAE、模板递归、类型萃取、编译时常量与计算、C++17 的折叠表达式与变长模板参数等。通过多个实际示例,帮助开发者掌握 如何利用 C++ 模板机制编写高效、可扩展的通用代码,并提升代码的灵活性与性能。

10

2026.01.23

php远程文件教程合集
php远程文件教程合集

本专题整合了php远程文件相关教程,阅读专题下面的文章了解更多详细内容。

29

2026.01.22

PHP后端开发相关内容汇总
PHP后端开发相关内容汇总

本专题整合了PHP后端开发相关内容,阅读专题下面的文章了解更多详细内容。

21

2026.01.22

php会话教程合集
php会话教程合集

本专题整合了php会话教程相关合集,阅读专题下面的文章了解更多详细内容。

21

2026.01.22

宝塔PHP8.4相关教程汇总
宝塔PHP8.4相关教程汇总

本专题整合了宝塔PHP8.4相关教程,阅读专题下面的文章了解更多详细内容。

13

2026.01.22

PHP特殊符号教程合集
PHP特殊符号教程合集

本专题整合了PHP特殊符号相关处理方法,阅读专题下面的文章了解更多详细内容。

11

2026.01.22

PHP探针相关教程合集
PHP探针相关教程合集

本专题整合了PHP探针相关教程,阅读专题下面的文章了解更多详细内容。

8

2026.01.22

菜鸟裹裹入口以及教程汇总
菜鸟裹裹入口以及教程汇总

本专题整合了菜鸟裹裹入口地址及教程分享,阅读专题下面的文章了解更多详细内容。

55

2026.01.22

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

9

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号