此代码已编辑but comes from this site.
如果我想使用URL链接中的最后一个函数使用远程网站插入数据,我该怎么做?
我的代码是:
<?php
/**
* Plugin Name: Parts Locator My Parts
* Plugin URI: http://www.m1creative.org/
* Description: Plugin to save and display the Parts Locator My Parts Listings
* Version: 1.0
* Author: Eldred Curwen
* Author URI: http://www.m1creative.org
* License: GPL2
*/
/* Copyright 2014 Eldred Curwen (email : [email protected])
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2, as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* Store our table name in $wpdb with correct prefix
* Prefix will vary between sites so hook onto switch_blog too
* @since 1.0
*/
function PL_register_my_parts_table(){
global $wpdb;
$wpdb->PL_my_parts = "{$wpdb->prefix}PL_my_parts";
}
add_action( \'init\', \'PL_register_my_parts_table\',1);
add_action( \'switch_blog\', \'PL_register_my_parts_table\');
/**
* Creates our table
* Hooked onto activate_[plugin] (via register_activation_hook)
* @since 1.0
*/
function PL_create_my_parts_table(){
global $wpdb;
global $charset_collate;
require_once(ABSPATH . \'wp-admin/includes/upgrade.php\');
//Call this manually as we may have missed the init hook
PL_register_my_parts_table();
$sql_create_table = "CREATE TABLE {$wpdb->PL_my_parts} (
my_part_ID bigint(20) unsigned NOT NULL auto_increment,
user_ID bigint(20) unsigned NOT NULL default \'0\',
PL_part_ID bigint(20) NOT NULL default \'0\',
part_save_date datetime NOT NULL default \'0000-00-00 00:00:00\',
PRIMARY KEY (my_part_ID),
KEY abc (user_ID)
) $charset_collate; ";
dbDelta($sql_create_table);
}
register_activation_hook(__FILE__,\'PL_create_my_parts_table\');
function PL_get_log_table_columns(){
return array(
\'my_part_ID\'=> \'%d\',
\'user_ID\'=> \'%d\',
\'activity\'=>\'%s\',
\'part_save_date\'=>\'%s\',
);
}
/**
* Inserts a log into the database
*
*@param $data array An array of key => value pairs to be inserted
*@return int The log ID of the created activity log. Or WP_Error or false on failure.
*/
function PL_insert_log( $data=array() ){
global $wpdb;
//Set default values
$data = wp_parse_args($data, array(
\'user_ID\'=> get_current_user_ID(),
\'date\'=> current_time(\'timestamp\'),
));
//Check date validity
if( !is_float($data[\'date\']) || $data[\'date\'] <= 0 )
return 0;
//Convert activity date from local timestamp to GMT mysql format
$data[\'part_save_date\'] = date_i18n( \'Y-m-d H:i:s\', $data[\'date\'], true );
//Initialise column format array
$column_formats = PL_get_log_table_columns();
//Force fields to lower case
$data = array_change_key_case ( $data );
//White list columns
$data = array_intersect_key($data, $column_formats);
//Reorder $column_formats to match the order of columns given in $data
$data_keys = array_keys($data);
$column_formats = array_merge(array_flip($data_keys), $column_formats);
$wpdb->insert($wpdb->PL_my_parts, $data, $column_formats);
return $wpdb->insert_id;
}
/**
* Updates an activity log with supplied data
*
*@param $my_part_ID int ID of the activity log to be updated
*@param $data array An array of column=>value pairs to be updated
*@return bool Whether the log was successfully updated.
*/
function PL_update_log( $my_part_ID, $data=array() ){
global $wpdb;
//Log ID must be positive integer
$my_part_ID = absint($my_part_ID);
if( empty($my_part_ID) )
return false;
//Convert activity date from local timestamp to GMT mysql format
if( isset($data[\'part_save_date\']) )
$data[\'part_save_date\'] = date_i18n( \'Y-m-d H:i:s\', $data[\'date\'], true );
//Initialise column format array
$column_formats = PL_get_log_table_columns();
//Force fields to lower case
$data = array_change_key_case ( $data );
//White list columns
$data = array_intersect_key($data, $column_formats);
//Reorder $column_formats to match the order of columns given in $data
$data_keys = array_keys($data);
$column_formats = array_merge(array_flip($data_keys), $column_formats);
if ( false === $wpdb->update($wpdb->PL_my_parts, $data, array(\'my_part_ID\'=>$my_part_ID), $column_formats) ) {
return false;
}
return true;
}
/**
* Retrieves activity logs from the database matching $query.
* $query is an array which can contain the following keys:
*
* \'fields\' - an array of columns to include in returned roles. Or \'count\' to count rows. Default: empty (all fields).
* \'orderby\' - datetime, user_ID or my_part_ID. Default: datetime.
* \'order\' - asc or desc
* \'user_ID\' - user ID to match, or an array of user IDs
* \'since\' - timestamp. Return only activities after this date. Default false, no restriction.
* \'until\' - timestamp. Return only activities up to this date. Default false, no restriction.
*
*@param $query Query array
*@return array Array of matching logs. False on error.
*/
function PL_get_logs( $query=array() ){
global $wpdb;
/* Parse defaults */
$defaults = array(
\'fields\'=>array(),\'orderby\'=>\'datetime\',\'order\'=>\'desc\', \'user_ID\'=>false,
\'since\'=>false,\'until\'=>false,\'number\'=>10,\'offset\'=>0
);
$query = wp_parse_args($query, $defaults);
/* Form a cache key from the query */
$cache_key = \'PL_logs:\'.md5( serialize($query));
$cache = wp_cache_get( $cache_key );
if ( false !== $cache ) {
$cache = apply_filters(\'PL_get_logs\', $cache, $query);
return $cache;
}
extract($query);
/* SQL Select */
//Whitelist of allowed fields
$allowed_fields = PL_get_log_table_columns();
if( is_array($fields) ){
//Convert fields to lowercase (as our column names are all lower case - see part 1)
$fields = array_map(\'strtolower\',$fields);
//Sanitize by white listing
$fields = array_intersect($fields, $allowed_fields);
}else{
$fields = strtolower($fields);
}
//Return only selected fields. Empty is interpreted as all
if( empty($fields) ){
$select_sql = "SELECT* FROM {$wpdb->PL_my_parts}";
}elseif( \'count\' == $fields ) {
$select_sql = "SELECT COUNT(*) FROM {$wpdb->PL_my_parts}";
}else{
$select_sql = "SELECT ".implode(\',\',$fields)." FROM {$wpdb->PL_my_parts}";
}
/*SQL Join */
//We don\'t need this, but we\'ll allow it be filtered (see \'PL_logs_clauses\' )
$join_sql=\'\';
/* SQL Where */
//Initialise WHERE
$where_sql = \'WHERE 1=1\';
if( !empty($my_part_ID) )
$where_sql .= $wpdb->prepare(\' AND my_part_ID=%d\', $my_part_ID);
if( !empty($user_ID) ){
//Force $user_ID to be an array
if( !is_array( $user_ID) )
$user_ID = array($user_ID);
$user_ID = array_map(\'absint\',$user_ID); //Cast as positive integers
$user_ID__in = implode(\',\',$user_ID);
$where_sql .= " AND user_ID IN($user_ID__in)";
}
$since = absint($since);
$until = absint($until);
if( !empty($since) )
$where_sql .= $wpdb->prepare(\' AND part_save_date >= %s\', date_i18n( \'Y-m-d H:i:s\', $since,true));
if( !empty($until) )
$where_sql .= $wpdb->prepare(\' AND part_save_date <= %s\', date_i18n( \'Y-m-d H:i:s\', $until,true));
/* SQL Order */
//Whitelist order
$order = strtoupper($order);
$order = ( \'ASC\' == $order ? \'ASC\' : \'DESC\' );
switch( $orderby ){
case \'my_part_ID\':
$order_sql = "ORDER BY my_part_ID $order";
break;
case \'user_ID\':
$order_sql = "ORDER BY user_ID $order";
break;
case \'datetime\':
$order_sql = "ORDER BY part_save_date $order";
default:
break;
}
/* SQL Limit */
$offset = absint($offset); //Positive integer
if( $number == -1 ){
$limit_sql = "";
}else{
$number = absint($number); //Positive integer
$limit_sql = "LIMIT $offset, $number";
}
/* Filter SQL */
$pieces = array( \'select_sql\', \'join_sql\', \'where_sql\', \'order_sql\', \'limit_sql\' );
$clauses = apply_filters( \'PL_logs_clauses\', compact( $pieces ), $query );
foreach ( $pieces as $piece )
$$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : \'\';
/* Form SQL statement */
$sql = "$select_sql $where_sql $order_sql $limit_sql";
if( \'count\' == $fields ){
return $wpdb->get_var($sql);
}
/* Perform query */
$logs = $wpdb->get_results($sql);
/* Add to cache and filter */
wp_cache_add( $cache_key, $logs, 24*60*60 );
$logs = apply_filters(\'PL_get_logs\', $logs, $query);
return $logs;
}
/**
* Deletes an activity log from the database
*
*@param $my_part_ID int ID of the activity log to be deleted
*@return bool Whether the log was successfully deleted.
*/
function PL_delete_log( $my_part_ID ){
global $wpdb;
//Log ID must be positive integer
$my_part_ID = absint($my_part_ID);
if( empty($my_part_ID) )
return false;
do_action(\'PL_delete_log\',$my_part_ID);
$sql = $wpdb->prepare("DELETE from {$wpdb->PL_my_parts} WHERE my_part_ID = %d", $my_part_ID);
if( !$wpdb->query( $sql ) )
return false;
do_action(\'PL_deleted_log\',$my_part_ID);
return true;
}
if ( isset( $_GET[\'action\'] ) && $_GET[\'action\'] == \'insert\') {
$user_ID = get_current_user_id();
$PL_part_ID = $_GET["partID"];
PL_insert_log ( array(
\'user_ID\'=> $user_ID,
\'PL_part_ID\'=> $PL_part_ID,
));
}
?>
如果我想使用URL链接中的最后一个函数使用远程网站插入数据,我该怎么做?
我现在已经把我的插入代码做成了这个,它位于一个页面模板中,这样我就可以从另一个站点链接并插入数据,不过我想尝试让它更安全。
if (isset($wp_query->query_vars[\'action\']) )
{
if ($wp_query->query_vars[\'action\'] == \'insert\')
{
$user_ID = get_current_user_id();
$PL_part_ID = $wp_query->query_vars[\'partID\'];
$part_save_date = date(\'d.m.y h:i:s\');
global $wpdb;
$wpdb->insert( \'wp_pl_my_parts\', array( \'user_ID\' => $user_ID, \'PL_part_ID\' => $PL_part_ID, \'part_save_date\' => $part_save_date ), array( \'%d\', \'%d\', \'%s\' ) );
}
}
SO网友:Adam
好的,首先,让我们(暂时)忽略wptuts-user-log 以避免首先将该代码与基本目标混淆。
然而,作为记录,该代码是由我们自己编写的Stephen Harris, 这个社区和WordPress社区的升级成员。特定链接问题是tutorial series 在…上Creating Custom Database Tables.
所以
正如我在之前的评论中提到的,there are many ways to insert data from a remote site, 我将介绍实现这一目标的基本方法。
我将给出合理的警告,以下示例代码没有对安全性、数据验证和清理做出任何假设,除了使用$wpdb->prepare
, 最终的责任在于确保应用程序的安全。
整齐for us to help you more precisely 在实现远程插入请求时,我们需要一些上下文来了解您的实现是如何工作的。例如,允许什么样的人提出此类请求,您希望对这些请求施加什么限制,以及与问题相关的任何其他信息。
除此之外,我强烈建议不要将示例代码包含在主题模板文件中,当然不要包含在页面模板文件中。如果该页面可以在你的网站前端访问(我假设是这样),那么任何人都有可能访问该URL并向你的数据库发起插入请求,更不用说可能会对你造成攻击。
我建议创建一个插件,而不是在主题中处理此功能。
<?php
/*
Plugin Name: Plugin Name
Plugin URI: http://www.yoursite.com/
Description: Remote Insert
Author: Your Name
Version: 1.0
Author URI: http://yoursite.com
*/
add_action( \'plugins_loaded\', array( RemoteRequest::instance(), \'setup\' ));
class RemoteRequest {
public function __construct() {}
public function setup() {
add_filter( \'init\', array($this, \'rewrite_rules\'));
add_filter( \'query_vars\', array($this, \'add_query_vars\'), 10, 1);
add_action( \'parse_request\', array($this, \'parse_request\') );
}
public static function instance() {
NULL === self::$instance and self::$instance = new self;
return self::$instance;
}
public function rewrite_rules() {
//http://www.yoursite.com/remote/insert
//http://www.yoursite.com/remote/update
//http://www.yoursite.com/remote/delete
//etc...
add_rewrite_rule(
\'^remote/(insert|update|delete)/?$\',
\'index.php?remote_request=true&remote_action=$matches[1]\',
\'top\'
);
}
public function add_query_vars($query_vars) {
$query_vars[] = \'remote_request\';
$query_vars[] = \'remote_action\';
return $query_vars;
}
public function parse_request($wp) {
$query = $wp->query_vars;
if( array_key_exists( \'remote_insert\', $query ) && isset($query[\'remote_action\']) ) {
//it would be very wise to check the origin of the
//request at this point in addition to the existence
//of a valid API key prior to continuing execution.
if ( $query[\'remote_action\'] === \'insert\' ) {
if ( $this->insert_data($_POST) ) {
//on success redirect user to success link
wp_redirect($success_link);
exit;
} else {
//on success redirect user to success link
wp_redirect($failed_link);
exit;
}
} elseif ( $query[\'remote_action\'] === \'update\' ) {
//your update code...
} elseif ( $query[\'remote_action\'] === \'delete\' ) {
//your delete code...
} else {
//handle other condtions...
}
}
}
public function insert_data($data) {
global $wpdb;
$result = $wpdb->query( $wpdb->prepare(
"
INSERT INTO $wpdb->yourcustomtable
( user_ID, PL_part_ID, part_save_date )
VALUES ( %d, %d, %s )
",
$data[\'user_id\'],
$data[\'pl_part_id\'],
$data[\'part_save_date \']
)
);
return $result;
}
}
。。。以上只是一个粗略的例子,不一定是最好的。
将远程API请求外推到自己的插件中,将使您的代码和实现更易于维护,并可与站点更改(尤其是更改主题,因为您不会失去远程功能)进行互操作。