面向对象编程(OOP)是现代PHP开发的核心技能。掌握面向对象编程,能让我们写出更规范、更易维护、更易扩展的代码。今天就来分享PHP面向对象编程的进阶知识。

1. 类与对象

类是对象的模板,对象是类的实例。

class User {
    public $name;
    public $email;
    
    public function __construct($name, $email) {
        $this->name = $name;
        $this->email = $email;
    }
    
    public function getInfo() {
        return "姓名:{$this->name},邮箱:{$this->email}";
    }
}

$user = new User('张三', 'zhangsan@example.com');
echo $user->getInfo();

2. 访问控制

PHP支持三种访问控制修饰符:public(公有)、protected(受保护)、private(私有)。

class User {
    public $name;      // 公有,外部可访问
    protected $email;  // 受保护,子类可访问
    private $password; // 私有,只有本类可访问
}

3. 继承

继承让子类可以复用父类的属性和方法。

class Person {
    public $name;
    public function __construct($name) {
        $this->name = $name;
    }
    public function sayHello() {
        return "你好,我是{$this->name}";
    }
}

class Student extends Person {
    public $school;
    public function __construct($name, $school) {
        parent::__construct($name);
        $this->school = $school;
    }
    public function study() {
        return "{$this->name}在{$this->school}学习";
    }
}

4. 多态

多态让不同对象对同一消息有不同响应。

interface Shape {
    public function area();
}

class Circle implements Shape {
    private $radius;
    public function __construct($radius) {
        $this->radius = $radius;
    }
    public function area() {
        return pi() * $this->radius * $this->radius;
    }
}

class Rectangle implements Shape {
    private $width, $height;
    public function __construct($width, $height) {
        $this->width = $width;
        $this->height = $height;
    }
    public function area() {
        return $this->width * $this->height;
    }
}

function printArea(Shape $shape) {
    echo "面积:" . $shape->area();
}

5. 抽象类与接口

抽象类不能实例化,用于定义子类的共同接口。接口定义类必须实现的方法契约。

abstract class Animal {
    abstract public function makeSound();
    public function sleep() {
        return "睡觉中...";
    }
}

interface Flyable {
    public function fly();
}

class Bird extends Animal implements Flyable {
    public function makeSound() {
        return "叽叽喳喳";
    }
    public function fly() {
        return "飞翔中...";
    }
}

6. 魔术方法

PHP提供了一系列魔术方法,在特定时机自动调用。

class User {
    private $data = [];
    
    // 访问不存在的属性时调用
    public function __get($name) {
        return $this->data[$name] ?? null;
    }
    
    // 设置不存在的属性时调用
    public function __set($name, $value) {
        $this->data[$name] = $value;
    }
    
    // 对象被当作字符串时调用
    public function __toString() {
        return json_encode($this->data);
    }
    
    // 对象被当作函数调用时调用
    public function __invoke($arg) {
        return "调用参数:$arg";
    }
}

7. 命名空间

命名空间解决了类名冲突问题。

namespace App\Models;

class User {
    // ...
}

// 使用
use App\Models\User;
$user = new User();

8. 自动加载

splautoloadregister实现类的自动加载。

spl_autoload_register(function ($class) {
    $file = __DIR__ . '/' . str_replace('\\', '/', $class) . '.php';
    if (file_exists($file)) {
        require $file;
    }
});

9. Trait

Trait解决了PHP单继承限制,实现代码复用。

trait Loggable {
    public function log($message) {
        echo date('Y-m-d H:i:s') . " - " . $message;
    }
}

class User {
    use Loggable;
    
    public function save() {
        $this->log('用户保存成功');
    }
}

10. 设计原则

  • 单一职责原则:一个类只做一件事
  • 开闭原则:对扩展开放,对修改关闭
  • 里氏替换原则:子类可以替换父类
  • 接口隔离原则:接口要小而专
  • 依赖倒置原则:依赖抽象而非具体

掌握这些面向对象知识,能让你的PHP代码更加规范、易维护、易扩展。