
new
关键字创建实例
class Singleton {
// 存储唯一实例的静态变量
private static $instance = null;
// 私有构造方法,防止外部实例化
private function __construct() {
// 初始化代码
}
// 私有克隆方法,防止克隆
private function __clone() {
// 可以抛出异常或直接忽略
}
// 防止反序列化创建新实例
private function __wakeup() {
// 可以抛出异常
}
// 静态方法,提供全局访问点
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
// 类的其他方法
public function doSomething() {
// 业务逻辑
}
}
getInstance()
时才会创建实例,避免不必要的资源消耗
public static function getInstance() {
if (self::$instance === null) {
// 加锁防止多线程同时创建实例
synchronized(self::class, function() {
if (self::$instance === null) {
self::$instance = new self();
}
});
}
return self::$instance;
}
unserialize()
时,PHP 会创建新实例,__wakeup()
方法可以阻止这种行为:
private function __wakeup() {
throw new Exception("Cannot unserialize singleton");
}
class Database {
private static $instance = null;
private $connection;
// 数据库配置
private $host = 'localhost';
private $db = 'my_database';
private $user = 'username';
private $pass = 'password';
private $charset = 'utf8mb4';
private function __construct() {
$dsn = "mysql:host=$this->host;dbname=$this->db;charset=$this->charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$this->connection = new PDO($dsn, $this->user, $this->pass, $options);
} catch (\PDOException $e) {
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
}
private function __clone() {}
private function __wakeup() {}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
// 获取数据库连接
public function getConnection() {
return $this->connection;
}
// 封装常用查询方法
public function query($sql, $params = []) {
$stmt = $this->connection->prepare($sql);
$stmt->execute($params);
return $stmt;
}
}
// 使用方式
$db = Database::getInstance();
$users = $db->query("SELECT * FROM users WHERE status = ?", [1])->fetchAll();
class Config {
private static $instance = null;
private $config = [];
private function __construct() {
// 加载配置文件
$this->loadConfig();
}
private function __clone() {}
private function __wakeup() {}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
private function loadConfig() {
// 加载主配置文件
$mainConfig = require __DIR__ . '/config/main.php';
// 加载环境配置文件(开发/生产)
$env = getenv('APP_ENV') ?: 'development';
$envConfig = require __DIR__ . "/config/{$env}.php";
// 合并配置
$this->config = array_merge($mainConfig, $envConfig);
}
// 获取配置项
public function get($key, $default = null) {
$keys = explode('.', $key);
$value = $this->config;
foreach ($keys as $k) {
if (!isset($value[$k])) {
return $default;
}
$value = $value[$k];
}
return $value;
}
// 设置配置项
public function set($key, $value) {
$keys = explode('.', $key);
$config = &$this->config;
foreach ($keys as $i => $k) {
if ($i === count($keys) - 1) {
$config[$k] = $value;
break;
}
if (!isset($config[$k])) {
$config[$k] = [];
}
$config = &$config[$k];
}
return $this;
}
}
// 使用方式
$config = Config::getInstance();
$apiKey = $config->get('services.payment.api_key');
$timeout = $config->get('app.timeout', 30);
class Logger {
private static $instance = null;
private $logFile;
private function __construct() {
$this->logFile = __DIR__ . '/logs/app.log';
// 确保日志目录存在
$this->ensureLogDirectory();
}
private function __clone() {}
private function __wakeup() {}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
private function ensureLogDirectory() {
$dir = dirname($this->logFile);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
}
public function log($message, $level = 'info') {
$timestamp = date('Y-m-d H:i:s');
$logLine = "[$timestamp] [$level] $message" . PHP_EOL;
file_put_contents($this->logFile, $logLine, FILE_APPEND);
}
public function info($message) {
$this->log($message, 'info');
}
public function error($message) {
$this->log($message, 'error');
}
public function warning($message) {
$this->log($message, 'warning');
}
}
// 使用方式
$logger = Logger::getInstance();
$logger->info('User login successful');
$logger->error('Database connection failed');
public static function resetInstance() {
// 仅在测试环境下启用
if (getenv('APP_ENV') === 'testing') {
self::$instance = null;
}
}