函数文档

_get_plugin_from_callback()

💡 云策文档标注

概述

_get_plugin_from_callback() 是一个内部辅助函数,用于从元框回调中查找所属的插件。它通过反射机制分析回调函数,并检查其文件路径是否位于插件目录内,以返回插件信息或 null。

关键要点

  • 函数接受一个 callable 参数 $callback,用于检查回调函数。
  • 使用 ReflectionMethod 或 ReflectionFunction 进行反射分析,处理数组、字符串或函数类型的回调。
  • 如果回调不是内部 PHP 函数且文件路径在 WP_PLUGIN_DIR 内,则通过 get_plugins() 匹配插件并返回插件数据。
  • 在反射异常或非插件回调时返回 null。

代码示例

function _get_plugin_from_callback( $callback ) {
    try {
        if ( is_array( $callback ) ) {
            $reflection = new ReflectionMethod( $callback[0], $callback[1] );
        } elseif ( is_string( $callback ) && str_contains( $callback, '::' ) ) {
            $reflection = new ReflectionMethod( $callback );
        } else {
            $reflection = new ReflectionFunction( $callback );
        }
    } catch ( ReflectionException $exception ) {
        return null;
    }

    if ( ! $reflection->isInternal() ) {
        $filename   = wp_normalize_path( $reflection->getFileName() );
        $plugin_dir = wp_normalize_path( WP_PLUGIN_DIR );

        if ( str_starts_with( $filename, $plugin_dir ) ) {
            $filename = str_replace( $plugin_dir, '', $filename );
            $filename = preg_replace( '|^/([^/]*/).*$|', '1', $filename );

            $plugins = get_plugins();

            foreach ( $plugins as $name => $plugin ) {
                if ( str_starts_with( $name, $filename ) ) {
                    return $plugin;
                }
            }
        }
    }

    return null;
}

注意事项

  • 此函数为内部辅助函数,主要用于 WordPress 核心功能如 do_block_editor_incompatible_meta_box() 和 do_meta_boxes()。
  • 依赖 get_plugins() 和 wp_normalize_path() 等函数,需确保相关文件已加载。
  • 自 WordPress 5.0.0 版本引入。

📄 原文内容

Internal helper function to find the plugin from a meta box callback.

Parameters

$callbackcallablerequired
The callback function to check.

Return

array|null The plugin that the callback belongs to, or null if it doesn’t belong to a plugin.

Source

function _get_plugin_from_callback( $callback ) {
	try {
		if ( is_array( $callback ) ) {
			$reflection = new ReflectionMethod( $callback[0], $callback[1] );
		} elseif ( is_string( $callback ) && str_contains( $callback, '::' ) ) {
			$reflection = new ReflectionMethod( $callback );
		} else {
			$reflection = new ReflectionFunction( $callback );
		}
	} catch ( ReflectionException $exception ) {
		// We could not properly reflect on the callable, so we abort here.
		return null;
	}

	// Don't show an error if it's an internal PHP function.
	if ( ! $reflection->isInternal() ) {

		// Only show errors if the meta box was registered by a plugin.
		$filename   = wp_normalize_path( $reflection->getFileName() );
		$plugin_dir = wp_normalize_path( WP_PLUGIN_DIR );

		if ( str_starts_with( $filename, $plugin_dir ) ) {
			$filename = str_replace( $plugin_dir, '', $filename );
			$filename = preg_replace( '|^/([^/]*/).*$|', '\1', $filename );

			$plugins = get_plugins();

			foreach ( $plugins as $name => $plugin ) {
				if ( str_starts_with( $name, $filename ) ) {
					return $plugin;
				}
			}
		}
	}

	return null;
}

Changelog

Version Description
5.0.0 Introduced.