WordPress主题函数的实现原理?

查看:92
本文介绍了WordPress主题函数的实现原理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

求解:WordPress主题中函数的实现原理是什么?

比如主题目录wp-content/themes/twentyfifteen/下的index.php

<?php get_header(); ?>

问题1:其中的get_header()函数哪来?
问题2:get_header()函数为什么会调用header.php?

解决方案

这个机制要说起来,可以复杂,可以简单。

程序语言是一个逻辑体现的工具,有顺序,判断的过程,绕来绕去绕来绕去,并没有啥神奇的地方,神奇的是人的脑洞。

我来点化你。虽然,我已经不用PHP四年多了。。。

是外层的php文件调用wp-content/themes/twentyfifteen中的index.phpget_header()是在外层定义的。

建议一层一层往里分析。

如最外层index.php是入口

define('WP_USE_THEMES', true);

/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wp-blog-header.php' );

加载了wp-blog-header.php

我们在看wp-blog-header.php

if ( !isset($wp_did_header) ) {

    $wp_did_header = true;

    // Load the WordPress library.
    require_once( dirname(__FILE__) . '/wp-load.php' );

    // Set up the WordPress query.
    wp();

    // Load the theme template.
    require_once( ABSPATH . WPINC . '/template-loader.php' );

}

检测头部是否加载!isset($wp_did_header),没加载则先将wp的库给加进来:require_once( dirname(__FILE__) . '/wp-load.php' );

wp-load.php中的文件内容是:

// #############定义绝对路径,如果没有的话
if ( ! defined( 'ABSPATH' ) ) {
    define( 'ABSPATH', dirname( __FILE__ ) . '/' );
}

// php内置函数
error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING | E_RECOVERABLE_ERROR );


// 下面英文说得很清楚
/*
 * If wp-config.php exists in the WordPress root, or if it exists in the root and wp-settings.php
 * doesn't, load wp-config.php. The secondary check for wp-settings.php has the added benefit
 * of avoiding cases where the current directory is a nested installation, e.g. / is WordPress(a)
 * and /blog/ is WordPress(b).
 *
 * If neither set of conditions is true, initiate loading the setup process.
 */
// 存在配置文件,加载一次!
if ( file_exists( ABSPATH . 'wp-config.php') ) {

    /** The config file resides in ABSPATH */
    require_once( ABSPATH . 'wp-config.php' );

} elseif ( @file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! @file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) {

    /** The config file resides one level above ABSPATH but is not part of another install */
    require_once( dirname( ABSPATH ) . '/wp-config.php' );


// 不存在配置,就复杂了
} else {

    // A config file doesn't exist

    define( 'WPINC', 'wp-includes' );
    require_once( ABSPATH . WPINC . '/load.php' );

    // Standardize $_SERVER variables across setups.
    wp_fix_server_vars();

    require_once( ABSPATH . WPINC . '/functions.php' );

    $path = wp_guess_url() . '/wp-admin/setup-config.php';

    /*
     * We're going to redirect to setup-config.php. While this shouldn't result
     * in an infinite loop, that's a silly thing to assume, don't you think? If
     * we're traveling in circles, our last-ditch effort is "Need more help?"
     */
    if ( false === strpos( $_SERVER['REQUEST_URI'], 'setup-config' ) ) {
        header( 'Location: ' . $path );
        exit;
    }

    define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' );
    require_once( ABSPATH . WPINC . '/version.php' );

    wp_check_php_mysql_versions();
    wp_load_translations_early();

    // Die with an error message
    $die  = sprintf(
        /* translators: %s: wp-config.php */
        __( "There doesn't seem to be a %s file. I need this before we can get started." ),
        '<code>wp-config.php</code>'
    ) . '</p>';
    $die .= '<p>' . sprintf(
        /* translators: %s: Codex URL */
        __( "Need more help? <a href='%s'>We got it</a>." ),
        __( 'https://codex.wordpress.org/Editing_wp-config.php' )
    ) . '</p>';
    $die .= '<p>' . sprintf(
        /* translators: %s: wp-config.php */
        __( "You can create a %s file through a web interface, but this doesn't work for all server setups. The safest way is to manually create the file." ),
        '<code>wp-config.php</code>'
    ) . '</p>';
    $die .= '<p><a href="' . $path . '" class="button button-large">' . __( "Create a Configuration File" ) . '</a>';

    wp_die( $die, __( 'Word

我们一层层往下看,最后发现:

原来get_header大兄弟在wp-includes/general-template.php

我们看看定义

/**
 * Load header template.
 *
 * Includes the header template for a theme or if a name is specified then a
 * specialised header will be included.
 *
 * For the parameter, if the file is called "header-special.php" then specify
 * "special".
 *
 * @since 1.5.0
 *
 * @param string $name The name of the specialised header.
 */
function get_header( $name = null ) {
    /**
     * Fires before the header template file is loaded.
     *
     * The hook allows a specific header template file to be used in place of the
     * default header template file. If your file is called header-new.php,
     * you would specify the filename in the hook as get_header( 'new' ).
     *
     * @since 2.1.0
     * @since 2.8.0 $name parameter added.
     *
     * @param string|null $name Name of the specific header file to use. null for the default header.
     */
    do_action( 'get_header', $name );

    $templates = array();
    $name = (string) $name;
    if ( '' !== $name ) {
        $templates[] = "header-{$name}.php";
    }

    $templates[] = 'header.php';

    locate_template( $templates, true );
}

需传入$name,但一般没有传,有两个函数搞清楚,你就清楚了。

这个$templates[]你没传入name就是header.php了,所以会调用主题下的这个文件,

怎么调用呢?

我们要看:

do_action( 'get_header', $name );  // 这个做些hook过滤,有某些函数被绑在get_header这个操作上,我建议好好看,学PHP好好理解
locate_template( $templates, true ); // 这个是重点

我们来看看wp-includes/template.php下的

/**
 * Retrieve the name of the highest priority template file that exists.
 *
 * Searches in the STYLESHEETPATH before TEMPLATEPATH and wp-includes/theme-compat
 * so that themes which inherit from a parent theme can just overload one file.
 *
 * @since 2.7.0
 *
 * @param string|array $template_names Template file(s) to search for, in order.
 * @param bool         $load           If true the template file will be loaded if it is found.
 * @param bool         $require_once   Whether to require_once or require. Default true. Has no effect if $load is false.
 * @return string The template filename if one is located.
 */
function locate_template($template_names, $load = false, $require_once = true ) {
    $located = '';
    foreach ( (array) $template_names as $template_name ) {
        if ( !$template_name )
            continue;
        if ( file_exists(STYLESHEETPATH . '/' . $template_name)) {
            $located = STYLESHEETPATH . '/' . $template_name;
            break;
        } elseif ( file_exists(TEMPLATEPATH . '/' . $template_name) ) {
            $located = TEMPLATEPATH . '/' . $template_name;
            break;
        } elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) {
            $located = ABSPATH . WPINC . '/theme-compat/' . $template_name;
            break;
        }
    }

    if ( $load && '' != $located )
        load_template( $located, $require_once );

    return $located;
}

定位模板位置有四个判断!关键在于这些STYLESHEETPATH,恩 。。。

那么,位置到底在哪里,请看wp-includes/default-constants.php:

/**
 * Defines templating related WordPress constants
 *
 * @since 3.0.0
 */
function wp_templating_constants() {
    /**
     * Filesystem path to the current active template directory
     * @since 1.5.0
     */
    define('TEMPLATEPATH', get_template_directory());

    /**
     * Filesystem path to the current active template stylesheet directory
     * @since 2.1.0
     */
    define('STYLESHEETPATH', get_stylesheet_directory());

    /**
     * Slug of the default theme for this install.
     * Used as the default theme when installing new sites.
     * It will be used as the fallback if the current theme doesn't exist.
     *
     * @since 3.0.0
     * @see WP_Theme::get_core_default_theme()
     */
    if ( !defined('WP_DEFAULT_THEME') )
        define( 'WP_DEFAULT_THEME', 'twentyseventeen' );

}

少年,我只能帮你这么多。

WP还是挺简单的,直接原生的,也没有啥类机制,很古老。

程序加载是从一个入口进去,然后所有 包含的函数,变量都会加载在内存。你进根目录的index.php,会最后加载到主题下的index.php

PHP is The best langauge in the world!

这篇关于WordPress主题函数的实现原理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆