前几天百度知道中有人问如何在Wordpress中使用自己的表,我看他已采纳的答案,能用,但是可能会报错,可能报的错是:头部已发送之类的,这篇文章就我为某个客户写过的一个插件聊一下如何在Wordpress数据库中使用自己的表而不出错:2个知识点分别是数据库的创建、查询、更新、删除,另外一个是正确处理文件头的输出,不让浏览器报错。
提示:插件的常量和全局变量定义、i18n、业务部分等细节,这里就不提供了,仅提供与数据库操作相关的代码和经验。
1.在插件被启用后创建表,这个不需要后台选项,直接上代码:
//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升级,所以,这个插件就没考虑,上代码:
//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):
编辑按钮:
<?php if(current_user_can( 'manage_options' )): ?> <input type="submit" name="alp_edit" value="确定" class="button-primary" /> | <?php endif; ?>
4.进行编辑操作,因为此文件开头已经拒绝了来自来自别处的请求,所以就不用再次考虑安全性的问题了,但是,变量是一定要过滤的:
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');
:
/** *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查看官方文档。
不成功了就抛出错误:
//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'); }
上面的函数都是直接的输出函数,就不用浪费版面上代码了。
补充:数据库的查询:
由于下面的查询语句被使用的比较多,所以我就专门写了个函数
/** *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() ......
之类的,如何解决这个问题,我会在下一篇文章中介绍。
继续说数据库的查询:
下面的函数用于返回用户收到的消息的条数,比较简单:
/** *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良好的发展并获得所用产品良好的支持和版本更新。
祝愉快!