面向对象编程(OOP)是一种编程范式,使用"对象"来组织代码。PHP完全支持OOP,包括类、继承、接口等特性。
<?php
// 定义类
class User {
// 属性(成员变量)
public $name;
public $email;
private $password;
protected $age;
// 构造函数
public function __construct($name, $email) {
$this->name = $name;
$this->email = $email;
}
// 方法(成员函数)
public function sayHello() {
return "你好,我是 {$this->name}";
}
// Getter方法
public function getEmail() {
return $this->email;
}
// Setter方法
public function setPassword($password) {
$this->password = password_hash($password, PASSWORD_DEFAULT);
}
}
// 创建对象
$user = new User("张三", "zhang@example.com");
echo $user->name; // 访问公共属性
echo $user->sayHello(); // 调用方法
$user->setPassword("123456"); // 设置密码
?>
<?php
class Example {
public $publicVar = "公共"; // 任何地方都可访问
private $privateVar = "私有"; // 仅类内部可访问
protected $protectedVar = "保护"; // 类和子类可访问
public function publicMethod() {
// 可以访问所有属性
echo $this->publicVar;
echo $this->privateVar;
echo $this->protectedVar;
}
private function privateMethod() {
echo "私有方法";
}
protected function protectedMethod() {
echo "保护方法";
}
}
$obj = new Example();
echo $obj->publicVar; // 正常
// echo $obj->privateVar; // 错误:无法访问
$obj->publicMethod(); // 正常
// $obj->privateMethod(); // 错误:无法访问
?>
<?php
class Database {
private $connection;
// 构造函数:创建对象时自动调用
public function __construct($host, $user, $pass, $db) {
$this->connection = new mysqli($host, $user, $pass, $db);
echo "数据库连接已建立\n";
}
// 析构函数:对象销毁时自动调用
public function __destruct() {
if ($this->connection) {
$this->connection->close();
echo "数据库连接已关闭\n";
}
}
public function query($sql) {
return $this->connection->query($sql);
}
}
$db = new Database("localhost", "user", "pass", "mydb");
// 使用数据库...
// 脚本结束时自动调用析构函数
?>
<?php
// 父类(基类)
class Animal {
protected $name;
protected $age;
public function __construct($name, $age) {
$this->name = $name;
$this->age = $age;
}
public function eat() {
echo "{$this->name} 正在吃东西\n";
}
public function sleep() {
echo "{$this->name} 正在睡觉\n";
}
}
// 子类(派生类)
class Dog extends Animal {
private $breed;
public function __construct($name, $age, $breed) {
parent::__construct($name, $age); // 调用父类构造函数
$this->breed = $breed;
}
// 新增方法
public function bark() {
echo "{$this->name} 汪汪叫\n";
}
// 重写父类方法
public function eat() {
echo "{$this->name} 正在吃狗粮\n";
}
}
$dog = new Dog("旺财", 3, "金毛");
$dog->eat(); // 调用重写的方法
$dog->bark(); // 调用新方法
$dog->sleep(); // 调用继承的方法
?>
<?php
// 抽象类不能被实例化
abstract class Shape {
protected $color;
public function __construct($color) {
$this->color = $color;
}
// 抽象方法:子类必须实现
abstract public function calculateArea();
abstract public function calculatePerimeter();
// 普通方法:子类可以继承
public function getColor() {
return $this->color;
}
}
class Circle extends Shape {
private $radius;
public function __construct($color, $radius) {
parent::__construct($color);
$this->radius = $radius;
}
public function calculateArea() {
return pi() * $this->radius ** 2;
}
public function calculatePerimeter() {
return 2 * pi() * $this->radius;
}
}
class Rectangle extends Shape {
private $width;
private $height;
public function __construct($color, $width, $height) {
parent::__construct($color);
$this->width = $width;
$this->height = $height;
}
public function calculateArea() {
return $this->width * $this->height;
}
public function calculatePerimeter() {
return 2 * ($this->width + $this->height);
}
}
$circle = new Circle("红色", 5);
echo "圆形面积: " . $circle->calculateArea();
$rect = new Rectangle("蓝色", 4, 6);
echo "矩形面积: " . $rect->calculateArea();
?>
<?php
// 接口定义契约
interface Drawable {
public function draw();
}
interface Resizable {
public function resize($scale);
}
// 类可以实现多个接口
class Image implements Drawable, Resizable {
private $path;
private $width;
private $height;
public function __construct($path, $width, $height) {
$this->path = $path;
$this->width = $width;
$this->height = $height;
}
public function draw() {
echo "绘制图片: {$this->path}\n";
}
public function resize($scale) {
$this->width *= $scale;
$this->height *= $scale;
echo "调整大小为: {$this->width}x{$this->height}\n";
}
}
$img = new Image("photo.jpg", 800, 600);
$img->draw();
$img->resize(0.5);
?>
<?php
class Math {
// 静态属性
public static $pi = 3.14159;
private static $count = 0;
// 静态方法
public static function square($n) {
return $n * $n;
}
public static function cube($n) {
return $n * $n * $n;
}
public static function incrementCount() {
self::$count++;
}
public static function getCount() {
return self::$count;
}
}
// 访问静态成员(不需要创建对象)
echo Math::$pi;
echo Math::square(5);
Math::incrementCount();
echo Math::getCount();
// 也可以通过对象访问
$math = new Math();
echo $math::square(3);
?>
<?php
class Config {
// 类常量
const VERSION = "1.0.0";
const MAX_SIZE = 1024;
public const DEBUG = true; // PHP 7.1+
private const SECRET = "key"; // PHP 7.1+
public static function getVersion() {
return self::VERSION;
}
}
// 访问公共常量
echo Config::VERSION;
echo Config::MAX_SIZE;
// 通过类访问
echo Config::getVersion();
?>
<?php
class MagicExample {
private $data = [];
// __get: 访问不存在的属性时调用
public function __get($name) {
echo "获取属性: $name\n";
return $this->data[$name] ?? null;
}
// __set: 设置不存在的属性时调用
public function __set($name, $value) {
echo "设置属性: $name = $value\n";
$this->data[$name] = $value;
}
// __isset: 检查不存在的属性时调用
public function __isset($name) {
return isset($this->data[$name]);
}
// __unset: 删除不存在的属性时调用
public function __unset($name) {
unset($this->data[$name]);
}
// __call: 调用不存在的方法时调用
public function __call($name, $arguments) {
echo "调用方法: $name\n";
echo "参数: " . implode(", ", $arguments) . "\n";
}
// __toString: 对象转字符串时调用
public function __toString() {
return "MagicExample对象";
}
// __invoke: 对象当作函数调用时
public function __invoke($x) {
echo "对象被调用,参数: $x\n";
}
}
$obj = new MagicExample();
$obj->name = "张三"; // 触发__set
echo $obj->name; // 触发__get
echo $obj; // 触发__toString
$obj(100); // 触发__invoke
?>
<?php
// 定义命名空间
namespace App\Models;
class User {
public $name;
}
namespace App\Controllers;
class UserController {
public function index() {
// 使用完全限定名称
$user = new \App\Models\User();
// 或使用use导入
// use App\Models\User;
// $user = new User();
}
}
// 使用命名空间
namespace App;
use App\Models\User;
use App\Controllers\UserController as Controller;
$user = new User();
$controller = new Controller();
?>
<?php
// Trait用于代码复用
trait Timestampable {
private $createdAt;
private $updatedAt;
public function setCreatedAt() {
$this->createdAt = date('Y-m-d H:i:s');
}
public function setUpdatedAt() {
$this->updatedAt = date('Y-m-d H:i:s');
}
public function getCreatedAt() {
return $this->createdAt;
}
}
trait Loggable {
public function log($message) {
echo "[" . date('Y-m-d H:i:s') . "] $message\n";
}
}
// 使用多个Trait
class Article {
use Timestampable, Loggable;
private $title;
private $content;
public function __construct($title, $content) {
$this->title = $title;
$this->content = $content;
$this->setCreatedAt();
$this->log("文章创建: $title");
}
}
$article = new Article("PHP教程", "这是内容");
echo $article->getCreatedAt();
?>
<?php
class Calculator {
// 参数类型声明和返回类型声明
public function add(int $a, int $b): int {
return $a + $b;
}
public function divide(float $a, float $b): float {
if ($b == 0) {
throw new Exception("除数不能为0");
}
return $a / $b;
}
// 可空类型(PHP 7.1+)
public function greet(?string $name): string {
return $name ? "Hello, $name" : "Hello, Guest";
}
// void返回类型(PHP 7.1+)
public function log(string $message): void {
echo $message . "\n";
}
}
$calc = new Calculator();
echo $calc->add(5, 3); // 8
echo $calc->divide(10, 2); // 5.0
echo $calc->greet("张三"); // Hello, 张三
$calc->log("日志信息");
?>
<?php
// 用户管理系统
class User {
private $id;
private $username;
private $email;
private $password;
public function __construct($username, $email) {
$this->username = $username;
$this->email = $email;
}
public function setPassword($password) {
$this->password = password_hash($password, PASSWORD_DEFAULT);
}
public function verifyPassword($password) {
return password_verify($password, $this->password);
}
public function getUsername() {
return $this->username;
}
public function getEmail() {
return $this->email;
}
}
class UserRepository {
private $db;
public function __construct($db) {
$this->db = $db;
}
public function save(User $user) {
// 保存用户到数据库
$stmt = $this->db->prepare(
"INSERT INTO users (username, email) VALUES (?, ?)"
);
$stmt->execute([$user->getUsername(), $user->getEmail()]);
}
public function findByUsername($username) {
$stmt = $this->db->prepare(
"SELECT * FROM users WHERE username = ?"
);
$stmt->execute([$username]);
return $stmt->fetch();
}
}
// 使用
$user = new User("zhangsan", "zhang@example.com");
$user->setPassword("123456");
$repo = new UserRepository($db);
$repo->save($user);
?>
设计模式是解决软件设计中常见问题的可重用方案。以下是PHP中常用的设计模式:
<?php
// 单例模式确保一个类只有一个实例
class Database {
private static $instance = null;
private $connection;
// 私有构造函数防止外部实例化
private function __construct() {
$this->connection = new mysqli('localhost', 'user', 'pass', 'db');
}
// 私有克隆方法防止克隆
private function __clone() {}
// 静态方法获取实例
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function getConnection() {
return $this->connection;
}
}
// 使用
$db = Database::getInstance();
$connection = $db->getConnection();
?>
<?php
// 工厂模式用于创建对象,隐藏创建逻辑
interface Logger {
public function log($message);
}
class FileLogger implements Logger {
public function log($message) {
file_put_contents('log.txt', "[File] $message\n", FILE_APPEND);
}
}
class DatabaseLogger implements Logger {
public function log($message) {
// 写入数据库
echo "[Database] $message\n";
}
}
class LoggerFactory {
public static function getLogger($type): Logger {
switch ($type) {
case 'file':
return new FileLogger();
case 'database':
return new DatabaseLogger();
default:
throw new Exception("Unknown logger type: $type");
}
}
}
// 使用
$logger = LoggerFactory::getLogger('file');
$logger->log('Application started');
?>
<?php
// 依赖注入提高代码的可测试性和可维护性
class UserService {
private $userRepository;
private $logger;
// 通过构造函数注入依赖
public function __construct(UserRepository $userRepository, Logger $logger) {
$this->userRepository = $userRepository;
$this->logger = $logger;
}
public function createUser($username, $email) {
$user = new User($username, $email);
$this->userRepository->save($user);
$this->logger->log("User created: $username");
return $user;
}
}
// 使用
$logger = LoggerFactory::getLogger('file');
$userRepository = new UserRepository($db);
$userService = new UserService($userRepository, $logger);
$userService->createUser('zhangsan', 'zhang@example.com');
?>
<?php
// 观察者模式实现对象间的一对多依赖
interface Observer {
public function update($subject);
}
class Subject {
private $observers = [];
public function attach(Observer $observer) {
$this->observers[] = $observer;
}
public function detach(Observer $observer) {
$this->observers = array_filter($this->observers, function($o) use ($observer) {
return $o !== $observer;
});
}
public function notify() {
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
}
class UserSubject extends Subject {
public $user;
public function createUser($user) {
$this->user = $user;
$this->notify();
}
}
class EmailObserver implements Observer {
public function update($subject) {
echo "发送邮件给: {$subject->user->getEmail()}\n";
}
}
class LogObserver implements Observer {
public function update($subject) {
echo "记录用户创建: {$subject->user->getUsername()}\n";
}
}
// 使用
$userSubject = new UserSubject();
$userSubject->attach(new EmailObserver());
$userSubject->attach(new LogObserver());
$user = new User('lisi', 'li@example.com');
$userSubject->createUser($user);
?>
<?php
class User {
private $passwordHash;
public function setPassword($password) {
// 验证密码强度
if (strlen($password) < 8) {
throw new Exception('密码长度至少8位');
}
// 使用bcrypt加密
$this->passwordHash = password_hash($password, PASSWORD_DEFAULT);
}
public function verifyPassword($password) {
return password_verify($password, $this->passwordHash);
}
}
// 使用
$user = new User();
$user->setPassword('MySecurePassword123!');
if ($user->verifyPassword('MySecurePassword123!')) {
echo '密码正确';
}
?>
<?php
class UserRepository {
private $db;
public function __construct($db) {
$this->db = $db;
}
// 使用参数化查询防止SQL注入
public function findByUsername($username) {
$stmt = $this->db->prepare(
"SELECT * FROM users WHERE username = ?"
);
$stmt->execute([$username]);
return $stmt->fetch();
}
// 批量插入时也使用参数化查询
public function batchInsert($users) {
$stmt = $this->db->prepare(
"INSERT INTO users (username, email) VALUES (?, ?)"
);
foreach ($users as $user) {
$stmt->execute([$user->getUsername(), $user->getEmail()]);
}
}
}
?>