functions.php 常用代码大合集 无需插件提升WP功能界面

你是不是看过很多帖子,说插件装太多会增加服务器负担,降低网页访问速度。

那么这篇文章会尽可能为你解决这些烦恼。

什么是functions.php 文件

它是WordPress 主题或插件中常见的一个文件名,用于包含各种函数或自定义代码。
该文件通常位于主题或插件的根目录中,用于执行一些功能或操作。

在 WordPress 主题中,functions.php 文件通常用于定义主题的自定义功能,例如添加新的小工具、自定义菜单、自定义文章类型、添加新的页面模板等等。在 WordPress 插件中,functions.php 文件通常用于定义插件的自定义功能,例如添加新的小工具、自定义短代码、添加新的功能等等。

修改 functions.php 文件之前,建议备份该文件以防止意外错误。

由于 functions.php 文件包含的代码可以直接影响 WordPress 网站的功能和性能,因此需要谨慎编辑和使用。

functions.php文件在什么位置

如果您正在使用的是自定义主题,functions.php 位于您的主题文件夹中, wp-content/themes/your-theme-name/functions.php 路径下,其中 your-theme-name 为您正在使用的主题名称(如果你使用的是子主题,那就修改子主题,这样不会影响主题升级而导致需要从新编辑functions.php文件)。

查看 functions.php 路径

  • 方法一:某些主题会单独把一些常用的文件给用户快速查看,在Wordpress后台界面-外观-主题文件编辑器中你可以找到。
  • 方法二:如果你的服务器有配备面板,这里我们用宝塔面板进行演示。
  • 方法三:使用文件管理插件,找到刚才提到的对应路径,编辑好后直接上传覆盖。不会的可以参考这篇文章:

禁止一个IP注册多个账号

PHP
//禁止用户多次注册账号
function prevent_multiple_registrations_by_ip( $errors, $sanitized_user_login, $user_email ) {
    $ip = $_SERVER['REMOTE_ADDR'];
    $users = get_users( array( 'meta_key' => 'ip_address', 'meta_value' => $ip ) );
    if ( count( $users ) > 0 ) {
        $errors->add( 'registered_error', '你已经注册过一个账户,请不要重复注册。' );
    }
    update_user_meta( get_current_user_id(), 'ip_address', $ip );
    return $errors;
}
add_filter( 'registration_errors', 'prevent_multiple_registrations_by_ip', 10, 3 );

上面的代码使用 WordPress 的 registration_errors 过滤器来检查是否有与当前 IP 地址相同的已注册用户。如果存在,则添加一个自定义错误消息并返回。

另外,代码还使用 update_user_meta 函数将当前用户的 IP 地址存储为其元数据,以便在以后检查使用。

禁止一个IP注册多个账号(控制在30天内)

PHP
//禁止用户30天内多次注册账号
function prevent_multiple_registrations_by_ip( $errors, $sanitized_user_login, $user_email ) {
    $ip = $_SERVER['REMOTE_ADDR'];
    $users = get_users( array( 'meta_key' => 'ip_address', 'meta_value' => $ip ) );
    if ( count( $users ) > 0 ) {
        $last_registered = get_user_meta( $users[0]->ID, 'last_registered', true );
        if ( $last_registered && strtotime( $last_registered ) > strtotime( '-30 days' ) ) {
            $errors->add( 'registered_error', '你已经注册过一个账户,请不要重复注册。' );
        } else {
            update_user_meta( $users[0]->ID, 'last_registered', date( 'Y-m-d H:i:s' ) );
        }
    } else {
        update_user_meta( get_current_user_id(), 'ip_address', $ip );
    }
    return $errors;
}
add_filter( 'registration_errors', 'prevent_multiple_registrations_by_ip', 10, 3 );

上面的代码使用 WordPress 的 registration_errors 过滤器来检查是否有与当前 IP 地址相同的已注册用户,并检查最后一次注册时间是否超过30天。如果用户在30天内已经注册过,则添加一个自定义错误消息并返回,否则将最后一次注册时间存储为其元数据。

在文章列表上方,新增「标签」+「用户」筛选器下拉菜单

Before
After
PHP
/* 文章列表筛选用 */
// 在文章列表上方添加“标签”筛选器
function custmuize_restrict_manage_posts_exsample(){
  global $post_type, $tag;
  if ( is_object_in_taxonomy( $post_type, 'post_tag' ) ) {
    $dropdown_options = array(
      'show_option_all' => get_taxonomy( 'post_tag' )->labels->all_items,
      'hide_empty' => 0,
      'hierarchical' => 1,
      'show_count' => 0,
      'orderby' => 'name',
      'selected' => $tag,
      'name' => 'tag',
      'taxonomy' => 'post_tag',
      'value_field' => 'slug'
    );
    wp_dropdown_categories( $dropdown_options );
  }
	
// 在文章列表上方添加“用户”筛选器
    wp_dropdown_users(
        array(
            'show_option_all' => '全部用户',
            'name' => 'author'
            )
        );
}
add_action('restrict_manage_posts', 'custmuize_restrict_manage_posts_exsample');

// 当在文章列表中选择“所有标签”时,不设置$_GET ['tag']。
function custmuize_load_edit_php_exsample(){
  if (isset($_GET['tag']) && '0' === $_GET['tag']) {
    unset ($_GET['tag']);
  }
}
add_action('load-edit.php', 'custmuize_load_edit_php_exsample');

【拆分】仅增加「标签」筛选器下拉菜单

PHP
/* 文章列表筛选用 */
// 在文章列表上方添加标签筛选器
function custmuize_restrict_manage_posts_exsample(){
  global $post_type, $tag;
  if ( is_object_in_taxonomy( $post_type, 'post_tag' ) ) {
    $dropdown_options = array(
      'show_option_all' => get_taxonomy( 'post_tag' )->labels->all_items,
      'hide_empty' => 0,
      'hierarchical' => 1,
      'show_count' => 0,
      'orderby' => 'name',
      'selected' => $tag,
      'name' => 'tag',
      'taxonomy' => 'post_tag',
      'value_field' => 'slug'
    );
    wp_dropdown_categories( $dropdown_options );
  }

}
add_action('restrict_manage_posts', 'custmuize_restrict_manage_posts_exsample');

// 当在文章列表中选择“所有标签”时,不设置$_GET ['tag']。
function custmuize_load_edit_php_exsample(){
  if (isset($_GET['tag']) && '0' === $_GET['tag']) {
    unset ($_GET['tag']);
  }
}
add_action('load-edit.php', 'custmuize_load_edit_php_exsample');

代码中首先判断当前文章类型是否属于标签分类(post_tag),如果是,则定义了一个下拉菜单选项数组 $dropdown_options,并将其传递给 WordPress 的 wp_dropdown_categories 函数进行渲染。
这个函数会根据 $dropdown_options 数组的设置,显示符合条件的标签,并提供筛选文章的功能。

在文章列表上方,新增「缩略图」「ID」「URL」「文字数」4个菜单同时增加

Before
After
PHP
// 在文章列表上方添加【缩略图】【ID】【URL】【文字数】4个显示项目
function add_posts_columns( $columns ) {
  $columns['thumbnail'] = '缩略图';
  $columns['postid'] = 'ID';
  $columns['slug'] = 'URL';
  $columns['count'] = '文字数';

  echo '<style type="text/css">
  .fixed .column-thumbnail {width: 120px;} // 间隙可以调整
  .fixed .column-postid {width: 2%;} // 间隙可以调整
  .fixed .column-slug, .fixed .column-count {width: 5%;} // 间隙可以调整
  </style>';

  return $columns;
}
function custom_posts_column( $column_name, $post_id ) {
  if ( $column_name == 'thumbnail' ) {
    $thumb = get_the_post_thumbnail( $post_id, array( 100, 100 ), 'thumbnail' );
    echo ( $thumb ) ? $thumb : '-';
  } elseif ( $column_name == 'postid' ) {
    echo $post_id;
  } elseif ( $column_name == 'slug' ) {
    $slug = get_post( $post_id ) -> post_name;
    echo $slug;
  } elseif ( $column_name == 'count' ) {
    $count = mb_strlen( strip_tags( get_post_field( 'post_content', $post_id ) ) );
    echo $count;
  }
}
add_filter( 'manage_posts_columns', 'add_posts_columns' );
add_action( 'manage_posts_custom_column', 'custom_posts_column', 10, 2 );

执行此代码后,您可以在投稿一览画面上确认四个新的项目(”缩略图”、”ID”、”链接后缀名URL”、”文字数”)已添加。样例代码中指定的 .fixed .column-thumbnail 等 CSS 是为了美化而简单编写的,如果不需要可以删除。

另外,尽管在此处介绍了投稿列表,但是只要更改 manage_posts_columns 和 manage_posts_custom_column 中的 “posts” 部分,就可以在页面列表或自定义文章类型列表等任何地方使用。

【拆分】仅增加「缩略图」菜单显示

PHP
// 在文章列表上方显示选项添加缩略图菜单
function add_posts_columns_thumbnail( $columns ) {
  $columns['thumbnail'] = '缩略图';
  return $columns;
}
function custom_posts_column_thumbnail( $column_name, $post_id ) {
  if ( $column_name == 'thumbnail' ) {
    $thumb = get_the_post_thumbnail( $post_id, array( 100, 100 ), 'thumbnail' );
    echo ( $thumb ) ? $thumb : '-';
  }
}
add_filter( 'manage_posts_columns', 'add_posts_columns_thumbnail' );
add_action( 'manage_posts_custom_column', 'custom_posts_column_thumbnail', 10, 2 );

如果想要更改要显示的缩略图的大小,请更改 get_the_post_thumbnailarray(100,100) 部分为所需大小。

此外,在上面的示例代码中,如果没有缩略图,则显示“-”。如果您想要更改它以显示其他内容,则可以自由更改它。

【拆分】仅增加「ID」菜单显示

PHP
// 在文章列表上方显示选项添加ID菜单
function add_posts_columns_postid( $columns ) {
  $columns['postid'] = 'ID';
  return $columns;
}
function custom_posts_column_postid( $column_name, $post_id ) {
  if ( $column_name == 'postid' ) {
    echo $post_id;
  }
}
add_filter( 'manage_posts_columns', 'add_posts_columns_postid' );
add_action( 'manage_posts_custom_column', 'custom_posts_column_postid', 10, 2 );

add_posts_columns_postid 函数中,将自定义列的名称和标题(’ID’)添加到 $columns 数组中,并将该数组返回。

【拆分】仅增加「URL」菜单显示

PHP
// 在文章列表上方显示选项添加链接后缀名菜单
function add_posts_columns_slug( $columns ) {
  $columns['slug'] = 'URL';
  return $columns;
}
function custom_posts_column_slug( $column_name, $post_id ) {
  if ( $column_name == 'slug' ) {
    $slug = get_post( $post_id ) -> post_name;
    echo $slug;
  }
}
add_filter( 'manage_posts_columns', 'add_posts_columns_slug' );
add_action( 'manage_posts_custom_column', 'custom_posts_column_slug', 10, 2 );

显示该文章的URL链接后缀名

【拆分】仅增加「文字数」统计显示

PHP
// 在文章列表上方显示选项添加文章文字数统计
function add_posts_columns_count( $columns ) {
  $columns['count'] = '文字数';
  return $columns;
}
function custom_posts_column_count( $column_name, $post_id ) {
  if ( $column_name == 'count' ) {
    $count = mb_strlen( strip_tags( get_post_field( 'post_content', $post_id ) ) );
    echo $count;
  }
}
add_filter( 'manage_posts_columns', 'add_posts_columns_count' );
add_action( 'manage_posts_custom_column', 'custom_posts_column_count', 10, 2 );

直接计算统计当前文章中还该的文字数量

WordPress Popular Posts插件扩展PV统计显示

After
PHP
// 在文章列表上方显示区分详细PV数据(必须先安装有插件才可趋势)
if(function_exists('wpp_get_views')){

    add_filter('manage_posts_columns', function($columns){
            $columns['view'] = "View";
            return $columns;
    });

    add_action('manage_posts_custom_column',function($column_name, $post_id){
        if($column_name == 'view'){
        echo '日:', wpp_get_views ( get_the_ID(), 'daily' );
        echo "<br />";
        echo '周:', wpp_get_views ( get_the_ID(), 'weekly' );
        echo "<br />";
        echo '月:', wpp_get_views ( get_the_ID(), 'monthly' );
        echo "<br />";
        echo '全:', wpp_get_views ( get_the_ID(), 'all' );
        }
    },10,2);

}

这是一段在统计访问量插件WordPress Popular Posts的扩展代码,

修改文章和页面的排序,按照最后更新时间进行排序

PHP
//在文章和页面列表上,按照最后更新的时间进行排序
function my_sort_order_by_modifired ( $query ) {
if ( $query->is_main_query() ) {
$query->set( 'orderby', 'modified' );
  }
}
add_action( 'pre_get_posts', 'my_sort_order_by_modifired' );

WordPress默认提供了按照文章创建日期进行排序的。

但是很多博主会进行文章重写,有些文章可能会经历大量修改。

这时候,即使是新文章,如果按照创建日期排序,也不容易被注意到。

这段代码可以帮助你修改为按照更新时间排序。

【附加项】在文章列表中显示文章的创建日期和更新日期

PHP
// 在文章列表中显示文章的创建日期和更新日期
function add_post_date_columns($columns) {
    $columns['post_created'] = __('Created');
    $columns['post_updated'] = __('Updated');
    return $columns;
}

function display_post_date_columns($column_name, $post_id) {
    if ($column_name == 'post_created') {
        $post_created = get_the_date('', $post_id);
        echo $post_created;
    }
    if ($column_name == 'post_updated') {
        $post_updated = get_the_modified_date('', $post_id);
        echo $post_updated;
    }
}

add_filter('manage_post_posts_columns', 'add_post_date_columns');
add_action('manage_post_posts_custom_column', 'display_post_date_columns', 10, 2);

这段代码将在文章列表中添加两列:创建日期和更新日期,并显示对应的日期文本。
请注意,如果您使用的是自定义文章类型,则您需要将 manage_post_posts_columns 和 manage_post_posts_custom_column 中的 “post” 更改为您的自定义文章类型名称。

【附加项】快速编辑&批量编辑-保存后 不列入更新对象

PHP
//多文章选择批量编辑或快速编辑时,文章更新日期保持不变
function my_insert_post_data( $data, $postarr ){
if ( isset( $_POST['action'] ) && $_POST['action'] == 'inline-save' ) {
if ( $data['post_status'] == 'publish' ) {
unset( $data['post_date'] );
unset( $data['post_date_gmt'] );
unset( $data['post_modified'] );
unset( $data['post_modified_gmt'] );
}
}
return $data;
}
add_filter( 'wp_insert_post_data', 'my_insert_post_data', 10, 2 );

简单说就是,在文章被通过批量编辑或快速编辑,保存后的文章,将不会按照更新顺序进行排列。

对空格,或什么也没输入进行搜索的结果不进行显示

PHP
// 搜索空格和空字段的结果不给与显示(结果不显示)
function mycus_empty_and_blank_search_invalid_func( $search, \WP_Query $q ) {
    if ( $q->is_search() && $q->is_main_query() && ! $q->is_admin() ) {
        $s = $q->get( 's' );
        $s = trim( $s );
        if ( empty( $s ) ) {
            $search .=" AND 0=1 ";
        }
    }
    return $search;
}
add_filter( 'posts_search', 'mycus_empty_and_blank_search_invalid_func', 10, 2 );

在WordPress的搜索结果页面中,如果搜索关键词为空格或者为空,那么不会显示任何结果。

该函数会对搜索的SQL查询语句进行修改,通过添加 AND 0=1 条件来达到不显示任何搜索结果的目的。

同时,这个函数只会对前台主查询进行操作,不会影响后台管理界面的搜索功能。

禁止Wordpress自动生成缩略图

PHP
//移除默认的图片尺寸自动生成
function remove_default_img_sizes($sizes){
unset($sizes['thumbnail']);
unset($sizes['medium']);
unset($sizes['medium_large']);// 768px禁止图片生成
unset($sizes['large']);
unset($sizes['1536x1536']); // 1536px禁止图片生成
unset($sizes['2048x2048']); // 2048px禁止图片生成
return $sizes;
}
add_filter('intermediate_image_sizes_advanced', 'remove_default_img_sizes');

禁用网页中鼠标右键的功能

PHP
//禁止鼠标右键
function disable_right_click() {
    echo '<script>
        document.oncontextmenu = function() {
            return false;
        }
        </script>';
}
add_action('wp_head', 'disable_right_click');

禁用网页中鼠标拖动图片

PHP
//禁止拖动图片
function disable_dragging_images() {
    echo '<script>
        document.ondragstart = function() {
            return false;
        }
        </script>';
}
add_action('wp_head', 'disable_dragging_images');

禁止WordPress自动更新

PHP
// 禁止WordPress自动更新
add_filter( 'automatic_updater_disabled', '__return_true' );

删除文章 同时删除内容中所有图片媒体附件

PHP
// 监听文章删除事件
add_action('before_delete_post', 'delete_post_attachments');

function delete_post_attachments($post_id) {
    // 获取被删除的文章对象
    $post = get_post($post_id);
    
    // 确保文章对象存在且为正常文章类型
    if($post && $post->post_type == 'post') {
        // 获取文章内容
        $content = $post->post_content;
        
        // 找到文章内容中所有的图片链接
        preg_match_all('/<img.+?src=[\'"]([^\'"]+)[\'"].*?>/i', $content, $matches);
        
        // 删除所有图片链接对应的媒体附件
        if(!empty($matches[1])) {
            foreach($matches[1] as $image_url) {
                $attachment_id = attachment_url_to_postid($image_url);
                if($attachment_id) {
                    wp_delete_attachment($attachment_id, true); // 将 true 参数设为 true 可以同时删除媒体文件
                }
            }
        }
    }
}