wordpress插件开发入门(一):基本构成
在上高中时,我就一直想开发一个wordpress插件,但奈何水平有限,网上教程一大堆,却硬是一个也看不懂。
上了大学后,还专门去请教过老师,但也没有了下文…
本文,我将会从零开始,手把手教你怎么创建一个属于自己的插件。
阶段一:徒有其表
首先,你需要创建一个php文件,将名字设置为demo.php
,文件的内容如下:
<?php
/*
Plugin Name: 示例插件
Description: 没有什么卵用的插件
Author: 高小调
Version: 1.0.0
Author URI: http://gaoxiaodiao.com/
*/
然后,把这个文件压缩成一个zip文件,得到一个:demo.php.zip
接下来,来到Wordpress后台页面,点击插件->安装插件->上传插件->立即安装:
稍等片刻后,就可以在插件列表里看到出现了一个新插件:
由于,demo.php文件里没有任何可以执行的php代码,所以即使你启用示例插件
也不会产生任何的效果。
阶段二:了解action与filter
我想开发一个wordpress的插件,必然是要通过它实现某个功能,wordpress提供了两个函数add_action
和add_filter
来供我们在某个特定的时间点来做一些事情。
在介绍进一步内容之前,我先来简述一下action
和filter
的区别:
- action: 在某个特定的时间点,去做特定的事情。
- filter: 在某个特定的时间点,修改特定的内容。
那么问题来了:这个“特定的时间点”是什么时候呢?
这里有一篇官方文档,里面包含了所有action
和filter
可以进行hook
的hookname
:
接下来,我们通过使用add_action
函数,来做一个简单的小练习。
阶段三: 实战之使用action
我们可以从Plugin API/Action Reference这篇文档中,可以找到一个为admin_head
的hook name。
从其介绍中,我们可以了解到,admin_head
会在后台页面的head标签中被调用,经常用于包含CSS或者JS。
那我们的demo.php
就可以扩充为以下代码:
<?php
/*
Plugin Name: 示例插件
Description: add_action初体验
Author: 高小调
Version: 1.0.1
Author URI: http://gaoxiaodiao.com/
*/
function add_custom_js_script_code(){
echo "<script>alert(\"I'm in!\");</script>";
}
add_action( 'admin_head', 'add_custom_js_script_code' );
其中,add_custom_js_script_code
函数功能非常简单,打印出一个script标签,执行alert("I'm in!")
。
那add_custom_js_script_code
函数什么时候执行呢?
没错,就是在后台页面的<head></head>
标签里会执行add_custom_js_script_code
函数,有点类似于以下逻辑:
<html>
<head>
<?php add_custom_js_script_code(); ?>
</head>
...
</html>
接下来,将demo.php
压缩为demo.php.zip
文件,重新上传,启用。
启用后,无论你访问哪个后台页面,都会弹出一个弹窗I'm in
,并且能在源码中找到<script>alert("I'm in!");</script>
。
阶段四: 实战之使用filter
上述的例子,太过于偏向于Demo,可能会有读者心想:哦,那样做有什么用呢?
所以,接下来,我来以一个模拟场景举例,来示范filter的用法。
在前文开发Wordpress蜜罐(一):项目概述中,我想留下黑客入侵后的所有痕迹,其中一种实现方案就是通过Wordpress的插件来实现。蜜罐的功能之一是要:记录黑客的弱口令字典。
所以,本小节目标就是让插件实现记录登录失败的功能,做法很简单,找到登录验证的hookname,然后是否判断登录失败,登录失败后,将失败的用户名/密码记录下来。
步骤一:找hookname
我们可以从Plugin API/Filter Reference这篇文档中,可以找到一个为authenticate的hook name,它的解释是“过滤用户登录的凭证是否有效”。
步骤二:调用add_filter函数
我们在demo.php中,就可以调用add_filter
函数,来对其进行Hook,其中:
-
第一个参数,代表hook的名称。
-
第二个参数,代表hook的优先级,0代表最高,99代表最低。
-
第三个参数,代表hook名所对应的参数个数。
add_filter( 'authenticate', 'gxd_login_check', 30 ,3 );
注意:在这里,针对
authenticate
hook的优先级必须设置为21及其以上,否则会和Wordpress Core的源码里的hook冲突
步骤三:记录用户名密码
因为,Wordpress Core源码里也是通过authenticate
来进行真正的登录验证的,如下所示:
// /wp-includes/default-filters.php
add_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
add_filter( 'authenticate', 'wp_authenticate_email_password', 20, 3 );
add_filter( 'authenticate', 'wp_authenticate_spam_check', 99 );
所以,我们可以借鉴它源码内的实现并加以改动。
function gxd_login_check($user,$username, $password){
if ( $user instanceof WP_User ) {
return $user;
}
if ( is_wp_error( $user ) ) {
if( $username != "" && $password!= "" ){
$ip = "";
if( isset($_SERVER['HTTP_CLIENT_IP']) ){
$ip = $_SERVER['HTTP_CLIENT_IP'];
}else if( isset($_SERVER['HTTP_X_FORWARDED_FOR']) ){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
$ip = $_SERVER['REMOTE_ADDR'];
}
$myfile = fopen("login_history.txt", "a+") or die("Unable to open file!");
fwrite($myfile,"[$ip] $username --- $password\r\n");
fclose($myfile);
}
return $user;
}
}
最终效果,你可以:访问此处。