为Wordpress主题或插件创建和如何使用自己的表

夕阳渐渐迫近地平线,霞光从地平线晕染开来,将天边的云朵渲染得一片通红。山岗上,我静静地望着那轮夕阳。霞光将我的身影剪裁的冗长。暖暖的阳光将我投射成透明,仿佛随时都会蒸发。

前几天百度知道中有人问如何在Wordpress中使用自己的表,我看他已采纳的答案,能用,但是可能会报错,可能报的错是:头部已发送之类的,这篇文章就我为某个客户写过的一个插件聊一下如何在Wordpress数据库中使用自己的表而不出错:2个知识点分别是数据库的创建、查询、更新、删除,另外一个是正确处理文件头的输出,不让浏览器报错。

提示:插件的常量和全局变量定义、i18n、业务部分等细节,这里就不提供了,仅提供与数据库操作相关的代码和经验。

1.在插件被启用后创建表,这个不需要后台选项,直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//Active
register_activation_hook(__FILE__,'coolwp_message_active');
/**
*return:Creat my table when my plugin be activated.
*parameter:none
*@author:Suifengtec suoling.net
*/
function coolwp_message_active() {
	global $wpdb;
	$table_name = CWP_PLUGIN_PM_TABLE;
	if($wpdb->get_var("show tables like '$table_name'") != $table_name){
		$sql = 'CREATE TABLE IF NOT EXISTS `'.$table_name.'` (
			`id` int(11) NOT NULL auto_increment,
			`from_id` text default NULL,
			`from_time` datetime default NULL,
			`to_id` varchar(200) default NULL,
			`viewed` varchar(10) default NULL,
			`subject` varchar(200) default NULL,
			`content` text,
			UNIQUE KEY `id` (`id`)
			) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;';
require_once(ABSPATH . 'wp-admin/upgrade-functions.php');
dbDelta($sql);
}
}

//Active register_activation_hook(__FILE__,'coolwp_message_active'); /** *return:Creat my table when my plugin be activated. *parameter:none *@author:Suifengtec suoling.net */ function coolwp_message_active() { global $wpdb; $table_name = CWP_PLUGIN_PM_TABLE; if($wpdb->get_var("show tables like '$table_name'") != $table_name){ $sql = 'CREATE TABLE IF NOT EXISTS `'.$table_name.'` ( `id` int(11) NOT NULL auto_increment, `from_id` text default NULL, `from_time` datetime default NULL, `to_id` varchar(200) default NULL, `viewed` varchar(10) default NULL, `subject` varchar(200) default NULL, `content` text, UNIQUE KEY `id` (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;'; require_once(ABSPATH . 'wp-admin/upgrade-functions.php'); dbDelta($sql); } }

2.在禁用插件时,删除自用数据库的表,建议加上后台选项,因为我提供的是FTP升级,所以,这个插件就没考虑,上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Deactive
register_deactivation_hook( __FILE__, 'coolwp_message_deactive' );
/**
*return:Delete my table when my plugin be deactivated.
*parameter:none
*@author:Suifengtec suoling.net
*/
function coolwp_message_deactive() {
	global $wpdb;
	$table_name = CWP_PLUGIN_PM_TABLE;
	if($wpdb->get_var("show tables like '$table_name'")== $table_name){
		$sql = 'DROP TABLE  `'.$table_name.'`';
		$wpdb->query($sql);
	}
}

//Deactive register_deactivation_hook( __FILE__, 'coolwp_message_deactive' ); /** *return:Delete my table when my plugin be deactivated. *parameter:none *@author:Suifengtec suoling.net */ function coolwp_message_deactive() { global $wpdb; $table_name = CWP_PLUGIN_PM_TABLE; if($wpdb->get_var("show tables like '$table_name'")== $table_name){ $sql = 'DROP TABLE `'.$table_name.'`'; $wpdb->query($sql); } }

3.此部分代码为表单中为具有相应权限的用户显示的的按钮(这不是重点,但是下面要用,此部分代码中的常量CWP_PLUGIN_PM_SLUG已经被定义,是用于插件本地化的slug):

编辑按钮:

1
2
3
<?php if(current_user_can( 'manage_options' )): ?>
<input type="submit" name="alp_edit" value="确定" class="button-primary" /> |
<?php endif; ?>

<?php if(current_user_can( 'manage_options' )): ?> <input type="submit" name="alp_edit" value="确定" class="button-primary" /> | <?php endif; ?>

4.进行编辑操作,因为此文件开头已经拒绝了来自来自别处的请求,所以就不用再次考虑安全性的问题了,但是,变量是一定要过滤的:

1
2
3
4
5
6
7
8
if($_POST['cwp_pm_edit']){
	$sql = 'update '.$table_name.' set  content="'.$data['content'].'" ,subject = "'.$data['subject'].'" where id = '.$data['id'];
	if($wpdb->query($sql)){
		coolwp_alp_message_LastUrl('update');
	}else{
		cwp_alp_message_sql_error('update');
	};
}//edit

if($_POST['cwp_pm_edit']){ $sql = 'update '.$table_name.' set content="'.$data['content'].'" ,subject = "'.$data['subject'].'" where id = '.$data['id']; if($wpdb->query($sql)){ coolwp_alp_message_LastUrl('update'); }else{ cwp_alp_message_sql_error('update'); }; }//edit

上面的$sql中的变量已经经过过滤。上面这个判断的意思是:如果那个编辑按钮被点击,就修改数据库中的值,修改后的值来自于被过滤后的表单输入,当然了,如果你想来点儿高级的,你可以用ajax判断下被修改的值与新值是否一致,如果全部一致,那就返回并提示不用修改,我的处理简单而粗暴:成功了就重定向,不成功了就抛出一个错误。

重点来了:重定向函数coolwp_alp_message_LastUrl('update');

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**  
*return: Redirect.  
*parameter:the action name.  
*@author:Suifengtec suoling.net  
*/  
function coolwp_alp_message_LastUrl($str){
/*
php.ini中有一段话:  
; Output buffering allows you to send header lines (including cookies) even  
; after you send body content, at the price of slowing PHP's output layer a  
; bit.  You can enable output buffering during runtime by calling the output  
; buffering functions.  You can also enable output buffering for all files by  
; setting this directive to On.  If you wish to limit the size of the buffer  
; to a certain size - you can use a maximum number of bytes instead of 'On', as  
; a value for this directive (e.g., output_buffering=4096).  
output_buffering = Off  
,我调试用的php环境的output_buffering是关闭的,output_buffering的作用是缓冲输出,如果是output_buffering=XXXX(比如是4096,那么,缓冲区大小是4096b,),那么就需要ob_end_clean();这一句了。  
ob_end_flush()或者ob_end_clean()的作用是终止缓冲;  
ob_flush()的作用是将缓冲输出出去,但是不会终止缓冲,所以在flush()之前使用;  
如不想使用ob_end_clean()、ob_end_flush()、ob_flush(),就需要把php.ini里的output_buffering设得足够小,例如0,也可以关闭了,也就是output_buffering = Off。  
注意:  
ob_flush()和flush()是有区别的:前者是把数据从PHP的缓冲中释放出来,后者是把不在缓冲中的或者说是被释放出来的数据发送到浏览器。所以当缓冲存在的时候,我们必须ob_flush()和flush()同时使用。  
当然flush()也并不是不可或缺的,你如果决定在有数据输出时,马上输出到浏览器的话,可以上去flush();  
当你把output_buffering设为0或者Off的时候,连ob_flush()和ob_end_clean()都不需要了.  
OVER  
by Suifengtec 2014.02.23 Suoling.net  
*/  
	ob_end_clean();   //清空(擦除)缓冲区并关闭输出缓冲。此函数丢弃最顶层输出缓冲区的内容并关闭这个缓冲区。如果想要进一步处理缓冲区的内容,必须在ob_end_clean()之前调用ob_get_contents(),因为当调用ob_end_clean()时缓冲区内容将被丢弃。
	if('save'==$str){   
		header("Location:".$_SERVER ['HTTP_REFERER' ].'#send');   
	}elseif('delete'==$str||'update'==$str){   
		header("Location:".$_SERVER ['HTTP_REFERER' ].'#list');   
	}
	//正确下面两个函数的顺序是: 先ob_flush, 然后flush
	ob_flush();   //取出PHP buffering中的数据,放入server buffering
	flush();   // 取出Server buffering的数据,放入browser buffering,简单说,就是刷新输出缓冲
}

/** *return: Redirect. *parameter:the action name. *@author:Suifengtec suoling.net */ function coolwp_alp_message_LastUrl($str){ /* php.ini中有一段话: ; Output buffering allows you to send header lines (including cookies) even ; after you send body content, at the price of slowing PHP's output layer a ; bit. You can enable output buffering during runtime by calling the output ; buffering functions. You can also enable output buffering for all files by ; setting this directive to On. If you wish to limit the size of the buffer ; to a certain size - you can use a maximum number of bytes instead of 'On', as ; a value for this directive (e.g., output_buffering=4096). output_buffering = Off ,我调试用的php环境的output_buffering是关闭的,output_buffering的作用是缓冲输出,如果是output_buffering=XXXX(比如是4096,那么,缓冲区大小是4096b,),那么就需要ob_end_clean();这一句了。 ob_end_flush()或者ob_end_clean()的作用是终止缓冲; ob_flush()的作用是将缓冲输出出去,但是不会终止缓冲,所以在flush()之前使用; 如不想使用ob_end_clean()、ob_end_flush()、ob_flush(),就需要把php.ini里的output_buffering设得足够小,例如0,也可以关闭了,也就是output_buffering = Off。 注意: ob_flush()和flush()是有区别的:前者是把数据从PHP的缓冲中释放出来,后者是把不在缓冲中的或者说是被释放出来的数据发送到浏览器。所以当缓冲存在的时候,我们必须ob_flush()和flush()同时使用。 当然flush()也并不是不可或缺的,你如果决定在有数据输出时,马上输出到浏览器的话,可以上去flush(); 当你把output_buffering设为0或者Off的时候,连ob_flush()和ob_end_clean()都不需要了. OVER by Suifengtec 2014.02.23 Suoling.net */ ob_end_clean(); //清空(擦除)缓冲区并关闭输出缓冲。此函数丢弃最顶层输出缓冲区的内容并关闭这个缓冲区。如果想要进一步处理缓冲区的内容,必须在ob_end_clean()之前调用ob_get_contents(),因为当调用ob_end_clean()时缓冲区内容将被丢弃。 if('save'==$str){ header("Location:".$_SERVER ['HTTP_REFERER' ].'#send'); }elseif('delete'==$str||'update'==$str){ header("Location:".$_SERVER ['HTTP_REFERER' ].'#list'); } //正确下面两个函数的顺序是: 先ob_flush, 然后flush ob_flush(); //取出PHP buffering中的数据,放入server buffering flush(); // 取出Server buffering的数据,放入browser buffering,简单说,就是刷新输出缓冲 }

上面的注释应该已经很清楚了吧?如果没看明白,请自行到php.net查看官方文档。

不成功了就抛出错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Throw a sql error info.
function cwp_alp_message_sql_error($str){
if('save'==$str)
add_action( 'admin_notices', 'cwp_alp_message_sql_save_error');

if('update'==$str)
add_action( 'admin_notices', 'cwp_alp_message_sql_update_error');

if('view'==$str)
add_action( 'admin_notices', 'cwp_alp_message_sql_view_error');

if('delete'==$str)
add_action( 'admin_notices', 'cwp_alp_message_sql_delete_error');
}

//Throw a sql error info. function cwp_alp_message_sql_error($str){ if('save'==$str) add_action( 'admin_notices', 'cwp_alp_message_sql_save_error'); if('update'==$str) add_action( 'admin_notices', 'cwp_alp_message_sql_update_error'); if('view'==$str) add_action( 'admin_notices', 'cwp_alp_message_sql_view_error'); if('delete'==$str) add_action( 'admin_notices', 'cwp_alp_message_sql_delete_error'); }

上面的函数都是直接的输出函数,就不用浪费版面上代码了。
补充:数据库的查询:
由于下面的查询语句被使用的比较多,所以我就专门写了个函数

1
2
3
4
5
6
7
8
9
10
/**
*return: Correct sql query
*parameter:none
*@author:Suifengtec suoling.net
*/
function cwp_alp_message_received(){
	$table_name =CWP_PLUGIN_PM_TABLE;//已被定义的表名常量:define('CWP_PLUGIN_PM_TABLE',$table_prefix .'cwp_XXX');
	$usr_name=cwp_get_current_user();
	return 'select * from  '.$table_name.' '.'where to_id = "'.$usr_name.'"'.' AND viewed = "0"';
}

/** *return: Correct sql query *parameter:none *@author:Suifengtec suoling.net */ function cwp_alp_message_received(){ $table_name =CWP_PLUGIN_PM_TABLE;//已被定义的表名常量:define('CWP_PLUGIN_PM_TABLE',$table_prefix .'cwp_XXX'); $usr_name=cwp_get_current_user(); return 'select * from '.$table_name.' '.'where to_id = "'.$usr_name.'"'.' AND viewed = "0"'; }

上面的函数cwp_get_current_user()返回的是当前用户的user_login(登录名称,因为在WP中,这个是不可以修改的,所以用这个,当然,如果你想麻烦些,你可以用用户ID)。
Tips:如果你在插件中使用 is_user_logged_in() 或者get_currentuserinfo()之类与当前用户相关的函数,你会发现WP会抛出一个致命错误:
Fatal error: Call to undefined function is_user_logged_in() ...
或者
Fatal error:Call to undefined function wp_get_current_user() ......
之类的,如何解决这个问题,我会在下一篇文章中介绍。
继续说数据库的查询:
下面的函数用于返回用户收到的消息的条数,比较简单:

1
2
3
4
5
6
7
8
9
10
11
12
/**
*return: The amount of message I received
*parameter:none
*@author:Suifengtec suoling.net
*/
function cwp_alp_num_of_message_i_has_received(){
	global $wpdb;
	$table_name =CWP_PLUGIN_PM_TABLE;//还是表
	$sql=cwp_alp_message_received();//就是上面定义的查询语句
	$info = $wpdb->get_results($sql);
	return count($info);
}

/** *return: The amount of message I received *parameter:none *@author:Suifengtec suoling.net */ function cwp_alp_num_of_message_i_has_received(){ global $wpdb; $table_name =CWP_PLUGIN_PM_TABLE;//还是表 $sql=cwp_alp_message_received();//就是上面定义的查询语句 $info = $wpdb->get_results($sql); return count($info); }

也就是说:数据库的查询需要构建一个查询语句,然后用WP内置的$wpdb去查询,具体使用如上面函数所示。

希望各位高手不吝赐教!如果你是真正的WP爱好者,请不要使用盗版的WP产品,特别是国产的WP作品,以促进WP良好的发展并获得所用产品良好的支持和版本更新。

祝愉快!

以上就是为Wordpress主题或插件创建和如何使用自己的表。要想走出平凡,就要先走入孤独。更多关于为Wordpress主题或插件创建和如何使用自己的表请关注haodaima.com其它相关文章!

标签: 自己的