WP Super Cache 插件好不好(一:架构篇)

188

目录结构

项目的可维护性和易读性与项目的目录结构有着正相关关系。以下为 WP Super Cache(简称:WSC)插件的总体目录结构,去除重复部分并做了一些注释说明。

├── advanced-cache.php // 主要缓存作用文件
├── languages // 多国语言目录
│   ├── wp-super-cache-zh_TW.mo // 正体中文语言文件
│   ├── wp-super-cache-zh_TW.po // 正体中文语言模板
│   └── ... // 更多其他语言文件
├── ossdl-cdn.php // oss cdn 作用文件
├── partials // “部分”文件,后台设置相关
│   ├── advanced.php
│   ├── debug.php
│   ├── easy.php
│   ├── lockdown.php
│   ├── preload.php
│   ├── rejected_user_agents.php
│   ├── restore.php
│   └── tracking_parameters.php
├── plugins // 特定兼容插件部分
│   ├── awaitingmoderation.php
│   ├── badbehaviour.php
│   ├── domain-mapping.php
│   ├── dynamic-cache-test.php
│   ├── jetpack.php
│   ├── multisite.php
│   └── wptouch.php
├── readme.txt // 读我文件
├── rest // 接口
│   ├── class.wp-super-cache-rest-delete-cache.php
│   ├── ...
│   └── load.php // 入口文件
├── wp-cache-base.php // 作用文件
├── wp-cache-config-sample.php // 配置示例
├── wp-cache-phase1.php // 阶段(片段)1文件
├── wp-cache-phase2.php // 阶段(片段)2文件
├── wp-cache.php // 后台插件执行主体文件
└── wp-super-cache.pot // 多国语言模板文件

语义化

在插件目录中可以看到,里面有不少语义不明的文件,如果不看源代码,十分难理解该文件有何作用。

例如 partials 这个目录,可理解为“部分”,但究竟是哪部分让人无从得知,查看里面的文件源码才大概知道是后台设置的“部分”。

再如 wp-cache-phase1.phpwp-cache-phase2.php 这两个文件就彼有意思。阶段(片段)1阶段(片段)2 这样的文件命名,笔者曾在很多编程新手的项目中见到,往往是 a1.phpa2.php 这样的命名。为什么会出现这样的命名呢,很大概率是因为文件代码量过大需要分割显得易读,或下任接手人员无法理解代码意图从而新建 a2.php 接着编码。让人想起以下的一个表情图。

面向现代

在编程项目中,我们往往都要考虑到一个要点:现代化。所谓现代化,即语法现代化逻辑现代化性能现代化。在该插件中,笔者并无法看到任何具有现代化的表现(性能现代化以后篇章再述)。

从语法上看,该插件没有用到任意处于生命周期的 PHP 版本语法,所有代码均停留在 PHP 4~5.2 时代,无语法现代化一说。

从逻辑上说,该插件在目录结构上语义不明、逻辑不清。代码上也有同样情况。以 advanced-cache.php 缓存主体文件来说,笔者以注释的形式进行说明:

// 缺少命名空间
// 不应定义全局函数
function wpcache_broken_message() {
    global $wp_cache_config_file;
        // isset 结构语句本身就是返回布尔值,没任何必要加上布尔假判断,就算加上也应该使用全等
    if ( isset( $wp_cache_config_file ) == false ) {
        return '';
    }

    $doing_ajax     = defined( 'DOING_AJAX' ) && DOING_AJAX;
    $xmlrpc_request = defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST;
    $rest_request   = defined( 'REST_REQUEST' ) && REST_REQUEST;
        // 应使用全等,否则位置 0 也是 false
    $robots_request = strpos( $_SERVER['REQUEST_URI'], 'robots.txt' ) != false;
        // 这个括号蛇舌舔足
    $skip_output = ( $doing_ajax || $xmlrpc_request || $rest_request || $robots_request );
        // 应使用全等,逻辑不严谨
    if ( false == strpos( $_SERVER['REQUEST_URI'], 'wp-admin' ) && ! $skip_output ) {
        echo '<!-- WP Super Cache is installed but broken. The constant WPCACHEHOME must be set in the file wp-config.php and point at the WP Super Cache plugin directory. -->';
    }
}
// 同样全等问题,而且 defined 本身只能返回布尔值,加上布尔判断多此一举
if ( false == defined( 'WPCACHEHOME' ) ) {
        // 常量命名不应不带下划线
    define( 'ADVANCEDCACHEPROBLEM', 1 );
// 判断语句中加 include,远古时代残留的写法
} elseif ( ! include_once WPCACHEHOME . 'wp-cache-phase1.php' ) {
        // 不应开关屏蔽错误修饰符,应先判断文件存在再操作
    if ( ! @is_file( WPCACHEHOME . 'wp-cache-phase1.php' ) ) {
        define( 'ADVANCEDCACHEPROBLEM', 1 );
    }
}
if ( defined( 'ADVANCEDCACHEPROBLEM' ) ) {
        // 退出函数容易因异常中断无法执行,不应使用
    register_shutdown_function( 'wpcache_broken_message' );
}

从上述代码与注释可见,WSC 该插件没有一处称得上现代化,各种寒武纪写法,无任何OOP,混乱的判断逻辑,自卑的代码风格一应俱全。

历史包袱

可能很多人认为,WSC 因为使用者众多,所以无法调整结构和面向现代。在这里笔者恰想说相反,正式因为使用者众多,所以更加要优化结构和面向现代。

即使大船转身可能需要抛下许多乘客,但也比撞冰山全员沉没来得强。