javascript - 从 jQuery Ajax 访问 JSON 结果

标签 javascript php jquery mysql json

我正在开发一个网络应用程序来维护餐厅类型的管理。这个想法是发出新订单,将订单项目放入其中,检查财务概览等...

我还有一个功能可以查看列表中的所有订单,当您选择其中一个订单时,订单数据(例如客户的姓名、电子邮件地址、位置)显示在列表中的另一个元素中文档。

我用这个函数来做到这一点,其中的每个 tr 都被赋予了一个自定义属性; order_id。选择该选项时,会给出一个名为 selectedRow 的类。

function select_order(order) {
    var item = $(order);
    if (!item.hasClass("selectedRow")) {
        if (!selectedOrderInformation.is(":visible")) {
            switchScreen(selectedOrderInformation, financeOverview);
        }
        item.parent().find(".selectedRow").removeClass("selectedRow");
        item.addClass("selectedRow");
        selectedOrderInformation.html("loading......");
        $.ajax({
            url: "includes/functions/select-order.php",
            type: "get",
            data: {order_id: item.attr("data-order-index")},
            success: function (data) {
                selectedOrderInformation.html(data);
                $("#delete-order-btn").prop("disabled", false);
            }
        });
    } else {
        console.log("DEBUG: Row is already selected");
    }
}

该函数的用法是这样的:

$("#list tbody tr").click(function () {
    select_order(this);
});

首先,我通过 PHP 部署所有 HTML 数据。这花费了相当长的时间,可能需要 500 毫秒到大约 1 秒。我认为这很长。

我是这样做的(select-order.php):

if (!empty($_GET['order_id'])) {
    $order_id = $_GET['order_id'];

    $order_data = Database::getInstance()->get_all_data_by_order_id($order_id);
    $order_items = Database::getInstance()->get_order_items_by_order_id($order_id);

    while ($row = mysqli_fetch_array($order_data)) {
        echo "<h1>Klant informatie</h1>";
        echo "<p>Voornaam: " . $row['first_name'] . "</p>";
        echo "<p>Achternaam: " . $row['last_name'] . "</p>";
        echo "<p>Emailadres: " . $row['email_adress'] . "</p>";
        echo "<p>Klant informatie: " . $row['customer_info'] . "</p>";
        echo "<br>";
        echo "<h1>Bestellingsinformatie</h1>";
        echo "<p>Order informatie: " . $row['order_info'] . "</p>";
        echo "<p>Locatie: " . $row['location'] . "</p>";
        echo "<p>Gemaakt op: " . $row['created'] . "</p>";
    }

    echo "<br>";
    echo "<table>";
    echo "<thead>";
    echo "<tr>";
    echo "<th>Product naam</th>";
    echo "<th>Hoeveelheid</th>";

    echo "</tr>";
    echo "</thead>";
    while ($row = mysqli_fetch_array($order_items)) {
        echo "<tr>";
        echo "<td>" . $row['name'] . "</td>";
        echo "<td>" . $row['quantity'] . "</td>";
        echo "</tr>";
    }
    echo "</table>";
    exit;
}

这与具有所有功能的数据库类一起使用:

class Database extends mysqli
{

    // single instance of self shared among all instances
    private static $instance = null;

    private $databaseHost = "";
    private $databaseUser = "";
    private $databasePassword = "";
    private $databaseName = "";

    public static function getInstance() {
        if (!self::$instance instanceof self) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    public function __clone() {
        trigger_error('Clone is not allowed.', E_USER_ERROR);
    }

    public function __wakeup() {
        trigger_error('Deserializing is not allowed.', E_USER_ERROR);
    }

    function __construct() {
        parent::__construct($this->databaseHost, $this->databaseUser, $this->databasePassword, $this->databaseName);
        if (mysqli_connect_error()) {
            exit('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
        }
        parent::set_charset('utf-8');
    }


    function get_all_data_by_order_id($order_id) {
        $query = "SELECT customers.first_name,
                         customers.last_name,
                         customers.email_adress,
                         customers.customer_info,

                         orders.order_info,
                         orders.total_price,
                         orders.location,
                         orders.created

                         FROM customers
                 INNER JOIN orders ON customers.id = orders.customer_id

                 WHERE orders.id = {$order_id}";

        return $this->query($query);
    }

    function get_order_items_by_order_id($order_id) {
        $query = "SELECT `products`.`name`, `orders-items`.`quantity` FROM `orders-items`\n" . "INNER JOIN `products`ON `orders-items`.`products_id` = `products`.`id`\n" . "WHERE order_id=" . $order_id;

        return $this->query($query);
    }
}

现在有人告诉我我可以更好地将数据转换为 json 并返回,所以我这样做了:

if (!empty($_GET['order_id'])) {
    $order_id = $_GET['order_id'];

    $order_data = Database::getInstance()->get_all_data_by_order_id($order_id);
    $order_items = Database::getInstance()->get_order_items_by_order_id($order_id);

    $rows = array();
    while ($row = mysqli_fetch_array($order_data)) {
        $rows[] = $row;
    }
    return json_encode($rows);
    exit;
}

但正如所料,什么都没有发生。所以我尝试将 javascript 更改为此(尝试将其作为数组,因为我以这种方式返回它?),以部署一份数据:

$.ajax({
    url: "includes/functions/select-order.php",
    type: "get",
    data: {order_id: item.attr("data-order-index")},
    success: function (data) {
        selectedOrderInformation.html(data['first_name']);
    }
});

但这并没有奏效。

问题

  • 以前的 PHP 代码速度很慢,所以我必须寻找另一种方法。
  • 当尝试将 HTML 部署到另一个屏幕时,它不会执行任何操作。它停留在“正在加载...”屏幕上,因此未达到成功功能。

问题

如何更改我的代码片段,使其能够实际部署 mysql 数据库中的部分数据?

最佳答案

在您的 $.ajax() 中调用时,您应该通过将以下参数添加到调用中来定义响应数据的预期类型:

dataType: 'json'

另外,你应该尝试echo json_encode($rows);您的数据而不是 return正在学习它。

**编辑:您正在接收一个数组数组,因此您在 success 中的原始引用回调是不够的。再看一下 MySQL 部分,如果您只希望查询返回一行,那么您可以将 PHP 更改为:

$row = mysqli_fetch_array($order_data);
echo json_encode($row); // instead of $rows

而不是 while环形。这样你的selectedOrderInformation.html(data['first_name']);很可能会起作用。

稍微清理一下你的查询:

$query = "SELECT p.name, ot.quantity FROM orders-items AS ot
    LEFT JOIN products AS p ON ot.products_id = p.id
    WHERE ot.order_id = " . $order_id;

您还可以切换您的INNER JOINLEFT JOIN在您的“获取订单数据”功能中。内部联接在这里绝对没有用,因为无论如何您都将根据外键对所有数据进行配对。

我会尝试隔离一些代码库:尝试注释掉 Database::getInstance()调用,并将一些测试数据补充到流程中。简而言之,通过声明 $row = array('first_name' => 'Joe', 'order_date' => '2014-08-29 11:11:52', ...); 来伪造返回的响应。并返回该值。如果速度更快,那么您的数据库服务器可能是瓶颈。如果它仍然很慢,那么 500ms - 1000ms 实际上可以说与代码相关,可能是其他硬件方面导致了问题。或者例如,您的 jQuery 库是从 CDN 还是本地加载的?

**编辑:正如@Debflav指出的那样(我也谈到了这个问题),您的查询可以受益于不作为简单查询执行,而是将它们转换为准备好的语句。要了解完整的故事,您可以开始查看 PHP.net : Prepared Statements ,或者保持简短:

准备好的语句看起来几乎就像您的日常查询一样,但是变量不仅仅是连接到查询字符串中,而是使用了绑定(bind)。 您使用数据库处理程序的 prepare函数而不是 query - 使用此方法,您请求 MySQL 服务器检查您的查询并优化它以供以后使用(如果您一遍又一遍地执行相同的查询,只是使用一些不同的值,这会很方便)。

有关准备好的语句的机制以及如何掌握它以在项目中有效地利用它的更详细的见解,我建议您稍微研究一下该主题,但作为手头示例的快速转换,它会看起来像这样:

function get_all_data_by_order_id($order_id) {
    $query = "SELECT c.first_name, c.last_name, c.email_adress, c.customer_info, 
                  o.order_info, o.total_price, o.location, o.created
                  FROM customers AS c
                  LEFT JOIN orders AS o ON c.id = o.customer_id
                  WHERE o.id = :order_id";
    $query_params = array( 
        ':order_id' => $order_id 
    ); 

    $preparedStatement = $this->prepare($query);
    return $preparedStatement->execute($query_params);

}

function get_order_items_by_order_id($order_id) {
    $query = "SELECT p.name, ot.quantity FROM orders-items AS ot
                  LEFT JOIN products AS p ON ot.products_id = p.id
                   WHERE ot.order_id = :order_id;";
    $query_params = array( 
        ':order_id' => $order_id 
    ); 

    $preparedStatement = $this->prepare($query);
    return $preparedStatement->execute($query_params);
}

并反射(reflection)如何使用包括订单 header 和连接的订单项目在内的数据构建 JSON 响应:

if (!empty($_GET['order_id'])) {
    $order_id = $_GET['order_id'];

    $order_data = Database::getInstance()->get_all_data_by_order_id($order_id);
    $order_items = Database::getInstance()->get_order_items_by_order_id($order_id);

    $orderObject = array();
    $orderObject['header'] = mysqli_fetch_array($order_data);
    $orderObject['items'] = array();    
    while ($orderedItem = mysqli_fetch_array($order_items)){
        $orderObject['items'][] = $orderedItem;
    }

    echo json_encode($orderObject);
}

这样你的 jQuery 可能看起来如下:

....
success: function (data) {
    selectedOrderInformation.html('<h3>' + data['header']['first_name'] + '</h3><ul>');
    $.each(data['items'], function(i, item) {
        selectedOrderInformation.append('<li>' + item['name'] + ' x ' + item['quantity'] + '</li>');
    });
    selectedOrderInformation.append('</ul>');
}
....

关于javascript - 从 jQuery Ajax 访问 JSON 结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25565113/

相关文章:

php - MySQL "in-where"很慢?

php - MySQL 数据透视表子字符串列名称

javascript - 单击其他 div 时切换脚本

javascript - javascript 的变量作用域问题

javascript - 将动态创建的元素中的文本翻译为不同的格式

javascript - 理解 classie.js 中的 js 代码

php - 如何将参数从 bash 传递到 php 脚本?

javascript - Jquery keydown 只能工作一次

javascript - javascript 中的销毁函数

javascript - 按钮点击问题