一尘不染

前端上的Ajax和WordPress-数据库未更新

ajax

因此,我正在使用WordPress网站。我在获取用户输入以更新数据库方面有些困难。

JS:

var ID = $(this).attr('id');
var name = $("#name_input_"+ID).val();
var createDate = $("#created_input_"+ID).val();
var stats = $("#status_input_"+ID).val();
var dateExpire = $("#disbanded_input_"+ID).val();
var dataString = 'id=' + ID + '&name=' + name + 
'&createDate=' + createDate + '&stats=' + stats + '&dateExpire=' + dateExpire;

// can place loading image here

if (name.length > 0 || createDate.length > 0 || 
stats.length > 0 || dateExpire.length > 0) {
  $.ajax({
    type: "POST",
    url: "../edit-items.php",
    data: dataString,
    cache: false,
    error: function(xhr, status, error) {
      var err = eval("(" + xhr.responseText + ")");
      alert(err.Message);
    },
    success: function (html) {
      $("#name_"+ID).html(name);
      $("#createDate_"+ID).html(createDate);
      $("#stats_"+ID).html(stats);
      $("#dateExpire_"+ID).html(dateExpire);
    }
  });
} else {
  alert("Enter text to make an edit.");
}
});

PHP(edit-items.php)

global $wpdb;

if($_POST['id']) {
    $id = esc_sql($_POST['id']);
    $name = esc_sql($_POST['name']);
    $created = esc_sql($_POST['createDate']);
    $stats = esc_sql($_POST['stats']);
    $dateExpire = esc_sql($_POST['dateExpire']);

    $query = "UPDATE items SET itemName='$name', createDate='$created', itemStats='$stats', dateExpire='$dateExpire' WHERE committee_id='$id';"

    $wpdb->query($wpdb->prepare($query));
  }

每当我尝试更新表时,我都能在前端成功完成此操作,但是在刷新时,数据更改不会停止。检查数据库进一步验证数据是否没有更改…似乎“成功”正在AJAX中传递,但是由于某种原因,它没有更新数据库。

对此有任何见识会有所帮助!

*决定 *编辑 以开始使用该admin-ajax.php方法。一切都一样,除了我将JS中的url更改为,url: "/wp- admin/admin-ajax.php",并且来自的代码edit-items.php现在functions.php像这样:

 function editCommittee() {  
  global $wpdb;

if($_POST['id']) {
    $id = esc_sql($_POST['id']);
    $name = esc_sql($_POST['name']);
    $created = esc_sql($_POST['createDate']);
    $stats = esc_sql($_POST['stats']);
    $dateExpire = esc_sql($_POST['dateExpire']);

    $wpdb->update('itemsTable',
                array(
                    'name' => $name
                ),
                array(
                    'committee_id' => $id
                ),

                array(
                  '%s'
                )
  );
  echo $id;
  exit();
  }
}
add_action('wp_ajax_editItems', 'editItems');

阅读 250

收藏
2020-07-26

共1个答案

一尘不染

好的,所以首先定位您的ajaxurl对象

add_action( 'wp_enqueue_scripts', 'frontend_enqueued_scripts' );

/**
 * Localization object
 *
 * @since 1.0.0
 */
function frontend_enqueued_scripts() {

    wp_enqueue_script( 'script', get_template_directory_uri() . '/js/custom.js', array( 'jquery' ), '', true );
    wp_localize_script( 'script', 'ajax_object', array(
        'ajaxurl' => admin_url( 'admin-ajax.php' ),
    ));
}

如果有的话,请functions.php在要排队前端脚本的地方放置,wp_enqueue_script然后wp_localize_script在其中放置part。另外,如果要将调用Ajax的javascript放在未调用的文件内,请custom.js更改名称以指向该文件。我始终custom.js将所有与主题相关的javascript用作存储文件。

上面的代码将ajax_object在您的前端创建一个对象,该对象可用于内的代码custom.js,因为您已将其附加到该脚本。入队文件和本地化脚本(在我们的例子中script)中的句柄必须相同才能起作用。

然后,您可以在functions.php文件中或放置了ajax函数的任何包含文件中创建回调函数

/**
 * Front and back end ajax hooks.
 */
add_action( 'wp_ajax_edit_committee', 'edit_committee' );
add_action( 'wp_ajax_nopriv_edit_committee', 'edit_committee' );

/**
 * Ajax callback function
 *
 * @since 1.0.0
 */
function edit_committee() {
    global $wpdb;

    if ( isset( $_POST['id'], $_POST['committee_nonce'] ) && wp_verify_nonce( sanitize_key( $_POST['committee_nonce'] ), 'committee_nonce_action' ) && '' !== $_POST['id'] ) { // Input var okay.
        $id          = ( isset( $_POST['id'] ) && '' !== $_POST['id'] ) ? sanitize_text_field( wp_unslash( $_POST['id'] ) ); : ''; // Input var okay.
        $name        = ( isset( $_POST['name'] ) && '' !== $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ); : ''; // Input var okay.
        $created     = ( isset( $_POST['create_date'] ) && '' !== $_POST['create_date'] ) ? sanitize_text_field( wp_unslash( $_POST['create_date'] ) ); : ''; // Input var okay.
        $stats       = ( isset( $_POST['stats'] ) && '' !== $_POST['stats'] ) ? sanitize_text_field( wp_unslash( $_POST['stats'] ) ); : ''; // Input var okay.
        $date_expire = ( isset( $_POST['date_expire'] ) && '' !== $_POST['date_expire'] ) ? sanitize_text_field( wp_unslash( $_POST['date_expire'] ) ); : ''; // Input var okay.

        $updated = $wpdb->update( 'itemsTable', array(  'name' => $name ), array( 'committee_id' => $id ), array( '%s' ) );
        if( false !== $updated ) {
            wp_die( 'success' );
        } else {
            wp_die( 'fail' );
        }

    }
}

我添加了消毒检查。至关重要的是,在表单中包括一个用于提交数据的随机数。

您可以通过放置

wp_nonce_field( 'committee_nonce_action', 'committee_nonce' );

<form>前端的元素中。这将生成一个nonce,这是一个很好的安全措施,尤其是在您写入数据库时​​。

回调函数将检查是否设置了随机数,是否设置了$_POST['id']变量且不为空,并且将首先验证随机数。

然后,您可以继续执行该功能。

$POST即使您没有使用它们,我也将所有变量留在那里,但也许您以后想使用它们。我还对它们进行了消毒并毫不费力。

// Input var okay.评论是phpcs的目的,你可以忽略。

然后您执行更新。如果itemsTable数据库中有,则应使用您提供的数据对其进行更新。

最后但并非最不重要的是javascript代码。我假设您正在通过某种按钮单击来执行ajax调用。需要对其进行更改以使其起作用(我用过#update_button,您将放置正确的ID或按钮的类)

jQuery(document).ready(function($) {
    'use strict';

    $('#update_button').on('click', function(e){
        e.preventDefault();

        var ID = $(this).attr('id'); // Button that is clicked is in $(this) object
        var name = $('#name_input_'+ID).val();
        var create_date = $('#created_input_'+ID).val();
        var stats = $('#status_input_'+ID).val();
        var date_expire = $('#disbanded_input_'+ID).val();

        // Can place loading image here
        if ( name.length > 0 || create_date.length > 0 || stats.length > 0 || date_expire.length > 0 ) {
            $.ajax({
                type: 'POST',
                url: ajax_object.ajaxurl,
                data: {
                    'action' : 'edit_committee',
                    'id' : ID,
                    'name' : name,
                    'create_date' : create_date,
                    'stats' : stats,
                    'date_expire' : date_expire,
                    'committee_nonce' : $( '#committee_nonce' ).val()
                },
                cache: false,
                error: function( jqXHR, textStatus, errorThrown ) {
                    console.log( jqXHR + ' :: ' + textStatus + ' :: ' + errorThrown );
                },
                success: function (html) {
                    if ( html == 'success' ) {
                        $('#name_'+ID).html(name);
                        $('#createDate_'+ID).html(create_date);
                        $('#stats_'+ID).html(stats);
                        $('#dateExpire_'+ID).html(date_expire);
                    }
                }
            });
        } else {
            alert('Enter text to make an edit.');
        }

    });

});

我还更改了变量名的short_name格式,而不是shortName。我觉得更整洁。

请注意,对于url,我们使用了ajax_object.ajaxurl- ajax_object从一开始就是本地化的,它指向admin- ajax.php文件的正确路径。数据只是您的字符串,而是作为对象写入的。

因此,当您单击按钮时,ajax调用会将所有数据放入一个全局$_POST变量中。

您可以通过运行检查器并单击网络> XHR选项卡来进行检查。

在此处输入图片说明

另外,如果不确定$_POST变量的含义,请输入

error_log(print_r($_POST, true));

在您的edit_committee()函数中,就在验证检查之前(如果条件)。如果您已启用调试wp-config.php

define('WP_DEBUG', true);
ini_set('log_errors',TRUE);
ini_set('error_reporting', E_ALL);
ini_set('error_log', dirname(__FILE__) . '/error_log.txt');

您将拥有error_log.txtWordPress安装的根目录,并且可以检查$_POST变量的内容。

希望这可以帮助 ;)

2020-07-26