【问题标题】:Ajax & WordPress on Front End - Database not updating前端的 Ajax 和 WordPress - 数据库未更新
【发布时间】:2016-11-07 19:28:58
【问题描述】:

所以我正在开发一个 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');

【问题讨论】:

  • 您传递的是字符串格式,您无法访问 $_post['id'],而不是像 Tomsaz 建议的那样传递 json 并在 json 中添加另一个键,操作:'editCommittee' 和 echo 'success ';然后死去;在 php 函数的末尾 editCommittee @sleepy_daze
  • 我在我的 JS 文件中设置了以下内容:data: dataString, dataType: 'json', action: 'editCommittee'。还在editCommittee() 函数的末尾添加了or die();。我发现如果我从 functions.php 中删除查询,我不会收到 500 Internal Server Error。也许我的查询有问题?
  • 尝试回显查询并在 mysql 中运行,我看到的一个错误是你是 @sleepy_daze 中的字符串形式的委员会 ID
  • 感谢您的收获,@parthmahida!我已经走得更远了,请查看我上面的代码编辑。不再出现 500 个内部错误,并且我能够看到 HTTP 响应标头。似乎数据正在通过admin-ajax.php 很好。但是,每当我在前端编辑数据时,它都会以GET 请求而不是POST 的形式成功通过...有什么想法吗?

标签: php jquery ajax wordpress


【解决方案1】:

这是问题所在,对于 ajax 请求,我们使用 http://example.com/wp-admin/admin-ajax.php
此外,您的数据字符串应包含 &action=editItems(与您在 wp_ajax_editItems 中使用的相同)

你的 ajax 请求代码应该看起来像...

  $.ajax({
    type: "POST",
    url: "/wp-admin/admin-ajax.php",
    data: dataString + '&action=editItems',
    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);
    }
  });

更多详情请查看https://codex.wordpress.org/AJAX_in_Plugins

希望有帮助:)

【讨论】:

  • 永远不要直接拨打admin-ajax.php。你应该先本地化它,然后通过一个对象来引用它。
  • 是的@dingo_d,建议不要使用硬编码的网址。
【解决方案2】:

好的,首先本地化您的 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_scriptwp_localize_script 部分在那里。此外,如果您将调用 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' );
        }

    }
}

我添加了消毒检查。在表单中包含用于提交数据的 nonce 至关重要。

你可以通过放置添加它

wp_nonce_field( 'committee_nonce_action', 'committee_nonce' );

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

回调函数会检查nonce是否设置,$_POST['id']变量是否设置且不为空,会先验证nonce。

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

我将所有$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 变量中。

您可以通过运行检查器并单击 Network > XHR 选项卡来检查它

此外,如果您不确定您的 $_POST 变量包含什么,请输入

error_log(print_r($_POST, true));

在您的 edit_committee() 函数中,在验证检查(if 条件)之前。如果您在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');

您将在 WordPress 安装的根目录中拥有 error_log.txt,您可以检查 $_POST 变量的内容。

希望这会有所帮助;)

【讨论】:

  • 没问题,乐于助人;)
  • 您是否有任何想法关于如何实现类似的东西,但对于插入语句?
  • 一切都是一样的,除了在 ajax 回调函数中你会使用 $wpdb->prepare 和 insert 方法。我敢肯定 wpdb 的法典中有关于此的内容。
【解决方案3】:

我很确定您没有将 POST 数据发送到 PHP 文件 - 检查一下。在php中输入var_dump($_POST),在ajax成功部分添加console.log(html)

尝试将 JS 中的 dataString 变量更改为:

var dataString = {
 id:ID,
 name:name,
 createDate:createDate,
 stats:stats,
 dateExpire:dateExpire
};

【讨论】:

  • 似乎没有任何东西被打印到控制台。但是,我收到了这个错误:jquery.js?ver=1.12.4:4 POST http://url.com/~directory/committee_edit_ajax.php 500 (Internal Server Error) 有趣的是,每当我将 AJAX url 设置为"../wp-admin/admin-ajax.php" 时,只要前端的输入更新(尽管仍然没有更新到数据库),它就会在控制台打印 0
  • 如果你想使用 admin-ajax.php 检查示例表单文档:codex.wordpress.org/Plugin_API/Action_Reference/…
  • 对 POST 500 内部服务器错误有任何想法吗?如果这不起作用,我可能会使用 admin-ajax.php 方法。老实说,我不确定该方法是否仅限于在 Admin Dashboard 端使用 Ajax...
  • 检查 php 错误日志,找出它为什么会出现内部服务器错误。您是否在edit-items.php 中加载了 wp 核心?
  • 不,edit-items.php 仅包含我原始帖子中的 PHP。回家后会检查 PHP 错误日志
【解决方案4】:
$wpdb->update( 'table',
array( 'column' => $name),
array( 'ID' => 1 ),
array( '%s'), 
array( '%d' )
);

【讨论】:

  • 请解释为什么您发布的代码会回答这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-05
  • 1970-01-01
  • 2015-10-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 2020-09-22
相关资源
最近更新 更多