其实对于博主这样的初学者,这个话题是有点超纲的,但如果从零开始想做一个主题。观摩一些成熟的主题是必不可少的,这个时候就有可能遇到这种单例模式的写法,所以即便我们暂时用不到,但了解一下结构,多少能看明白这个类究竟在做些什么事情。单例模式是一种常用的软件设计模式,确保一个类只有一个实例,并提供一个全局访问点。在PHP中,单例模式通常用于数据库连接、日志记录等资源共享和控制场景。
单例模式关键
单例模式的实现依赖于以下几个关键点:
私有构造函数:防止使用 new 关键字在外部创建类的实例。
私有静态属性:用于存储类的唯一实例。
私有克隆方法:防止对象被复制或克隆。
公共静态方法:通常命名为 getInstance,用于访问和创建类的唯一实例。
单例模式的基本模板
class Singleton {
private static $instance;
// 私有构造函数防止外部创建实例
private function __construct() {}
// 私有克隆方法防止实例被复制
private function __clone() {}
// 公共静态方法获取唯一实例
public static function getInstance() {
if (!self::$instance instanceof self) {
self::$instance = new self();
}
return self::$instance;
}
// 示例方法
public function someFunction() {
// 功能实现
}
}
// 使用单例模式
$instance = Singleton::getInstance();
优点:
减少内存开支,特别是频繁创建和销毁对象时。
减少系统性能开销,提高资源利用率。
避免对资源的多重占用,如文件写操作。
缺点:
扩展困难,不易维护。
如果单例对象持有 Context,可能引发内存泄漏。
应用场景
单例模式适用于以下场景:
资源共享,如日志文件、应用配置。
控制资源,如数据库连接池、线程池。
zakra主题里的一个实例
博主删掉了一部分以凸显单例结果,对全文感兴趣的可以去主题官网下载学习。
<?php
/**
* Additional setup After theme setup.
*
* @package zakra
*
* TODO: @since.
*/
defined( 'ABSPATH' ) || exit;
if ( ! class_exists( 'Zakra_After_Setup_Theme' ) ) {
class Zakra_After_Setup_Theme {
private static $instance;
public static function get_instance() {
if ( ! isset( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->setup_hooks();
}
public function setup_hooks() {
add_action( 'after_setup_theme', array( $this, 'setup_theme' ) );
}
public function setup_theme() {
// Make theme available for translation.
load_theme_textdomain( 'zakra', get_template_directory() . '/languages' );
// Add default posts and comments RSS feed links to head.
add_theme_support( 'automatic-feed-links' );
// Let WordPress manage the document title.
add_theme_support( 'title-tag' );
// Enable support for Post Thumbnails on posts and pages.
add_theme_support( 'post-thumbnails' );
// Register menu.
$menus = array(
'menu-primary' => esc_html__( 'Primary Menu', 'zakra' ),
);
$enable_builder = get_theme_mod( 'zakra_enable_builder', false );
if ( $enable_builder || zakra_maybe_enable_builder() ) {
$menus['menu-secondary'] = esc_html__( 'Secondary Menu', 'zakra' );
$menus['menu-mobile'] = esc_html__( 'Mobile Menu', 'zakra' );
}
register_nav_menus( $menus );
/*
* Switch default core markup for search form, comment form, and comments
* to output valid HTML5.
*/
add_theme_support(
'html5',
array(
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption',
)
);
// Add theme support for selective refresh for widgets.
add_theme_support( 'customize-selective-refresh-widgets' );
/**
* Add support for core custom logo.
*
* @link https://codex.wordpress.org/Theme_Logo
*/
add_theme_support(
'custom-logo',
array(
'width' => 170,
'height' => 60,
'flex-width' => true,
'flex-height' => true,
)
);
// Custom background support.
add_theme_support( 'custom-background' );
// Gutenberg Wide/fullwidth support.
add_theme_support( 'align-wide' );
// Add support for Block Styles.
add_theme_support( 'wp-block-styles' );
}
}
}
Zakra_After_Setup_Theme::get_instance();
以上这个类被写成了一个单独的文件,然后在functions.php中,用如下语句引入:
//这里的 ZAKRA_PARENT_INC_DIR 是主题定义的本地路径常量
require ZAKRA_PARENT_INC_DIR . '/core/class-zakra-after-setup-theme.php';