【问题标题】:How can i optimize this php function that is called using ajax?如何优化这个使用 ajax 调用的 php 函数?
【发布时间】:2020-10-22 21:02:00
【问题描述】:

我目前有一个功能,您可以使用 ajax 请求搜索此 php 文件。问题是这个文件很重,导致搜索结果延迟和滞后。例如,如果我搜索 John doe,在搜索框中会显示:正在搜索 John,然后延迟 2 秒,然后添加 Doe。 ajax请求在key up时调用,php文件如下:

如何优化函数以使其在返回数据时更快?

请看这个 gif 中的演示,我在那里写你好

<?php
session_start();
include_once("../inc/main.class.php");
$main = new Main();

if(isset($_POST["token"])) {
    if($_SESSION["sess_id"] == $_POST["token"]) {
        $checkKlarnaApiOrder      = $main->checkKlarnaApiOrder($_POST["term"], $_SESSION["sess_id"]);
        $checkWooCommerceApiOrder = $main->checkWooCommerceApiOrder($_POST["term"], $_SESSION["sess_id"]);
        
        if ($checkKlarnaApiOrder["error"] == 1) {
            echo '
            <div class="alert alert-danger text-center">
                <i class="fa fa-info-circle"></i> '. $getKlarnaApiOrder["message"] .'
            </div>
            ';
        } else if(isset($checkKlarnaApiOrder["order_id"])) {
            $getKlarnaApiOrder        = $main->getKlarnaApiOrder($_POST["term"], $_SESSION["sess_id"]);
            $main->insertSearchTermToHistory("$_POST[term]", "Klarna Order", "$_SESSION[sess_id]", "found");
            echo '
            <div class="alert alert-success text-center mb-0 mt-2">
                <i class="fa fa-check-circle"></i> We found a order with ID '.strip_tags($_POST["term"]).'
            </div>
            <div class="alert bg-light mt-0">
                <div class="row">
                    <div class="col-md-4">
                        <b>Client</b> <br>
                        '.$getKlarnaApiOrder["billing_address"]->given_name. ' ' . $getKlarnaApiOrder["billing_address"]->family_name . ' <br>
                        Address 1: ' . $getKlarnaApiOrder["billing_address"]->street_address . ' <br>
                        Address 2: ' . $getKlarnaApiOrder["billing_address"]->street_address2 . ' <br>
                        ' . $getKlarnaApiOrder["billing_address"]->postal_code . ', ' . $getKlarnaApiOrder["billing_address"]->city . ', ' . $getKlarnaApiOrder["billing_address"]->country . ' <br>
                        ' . $getKlarnaApiOrder["billing_address"]->email . ' <br>
                        ' . $getKlarnaApiOrder["billing_address"]->phone . '
                    </div>
                    <div class="col-md-4">
                        <b>Delivery</b> <br>
                        ' . $getKlarnaApiOrder["shipping_address"]->given_name . ' ' . $getKlarnaApiOrder["billing_address"]->family_name . ' <br>
                        Address 1: ' . $getKlarnaApiOrder["shipping_address"]->street_address . ' <br>
                        Address 2: ' . $getKlarnaApiOrder["shipping_address"]->street_address2 . ' <br>
                        ' . $getKlarnaApiOrder["shipping_address"]->postal_code . ', ' . $getKlarnaApiOrder["billing_address"]->city . ', ' . $getKlarnaApiOrder["billing_address"]->country . ' <br>
                        ' . $getKlarnaApiOrder["shipping_address"]->email . ' <br>
                        ' . $getKlarnaApiOrder["shipping_address"]->phone . '
                    </div>
                    <div class="col-md-4">
                        <b>Method:</b> '. $getKlarnaApiOrder["initial_payment_method"]->type .' / '. $getKlarnaApiOrder["initial_payment_method"]->description . ' <br>
                        <b>Status:</b> ' . $getKlarnaApiOrder["status"] . ' <br>
                        <b>Total:</b> ' . number_format($getKlarnaApiOrder["order_amount"] / 100, 2) . ' <br>
                        <b>Paid:</b> ' . number_format($getKlarnaApiOrder["captured_amount"] / 100, 2) . ' <br>
                        <b>Refunded:</b> ' . number_format($getKlarnaApiOrder["refunded_amount"] / 100, 2) . ' <br>
                        <b>Currency:</b> ' . $getKlarnaApiOrder["purchase_currency"] . ' <br>
                        <b>Handle:</b> <a href="'.$main->baseUrl().'/klarna/cmd/view/order/'.$_POST["term"].'" class="">Show order</a>
                    </div>
                </div>
            </div>
            ';
        } else if($checkWooCommerceApiOrder == 1) {
            $getWooCommerceApiOrder = $main->getWooCommerceApiOrder($_POST["term"], $_SESSION["sess_id"]);
            $main->insertSearchTermToHistory("$_POST[term]", "WooCommerce Order", "$_SESSION[sess_id]", "found");
            if($getWooCommerceApiOrder["payment_method_title"]=="Klarna") {
                $getKlarnaApiOrder = $main->getKlarnaApiOrder($getWooCommerceApiOrder["transaction_id"], $_SESSION["sess_id"]);
                echo '
                <div class="alert alert-success text-center mb-0 mt-2">
                    <i class="fa fa-check-circle"></i> We found a WooCommerce order with id  ' . strip_tags($_POST["term"]) . ' (Klarna Id: '.$getWooCommerceApiOrder["transaction_id"].')
                </div>
                <div class="alert bg-light mt-0">
                    <div class="row">
                        <div class="col-md-4">
                            <b>Client</b> <br>
                            ' . $getKlarnaApiOrder["billing_address"]->given_name . ' ' . $getKlarnaApiOrder["billing_address"]->family_name . ' <br>
                            Address 1: ' . $getKlarnaApiOrder["billing_address"]->street_address . ' <br>
                            Address 2: ' . $getKlarnaApiOrder["billing_address"]->street_address2 . ' <br>
                            ' . $getKlarnaApiOrder["billing_address"]->postal_code . ', ' . $getKlarnaApiOrder["billing_address"]->city . ', ' . $getKlarnaApiOrder["billing_address"]->country . ' <br>
                            ' . $getKlarnaApiOrder["billing_address"]->email . ' <br>
                            ' . $getKlarnaApiOrder["billing_address"]->phone . '
                        </div>
                        <div class="col-md-4">
                            <b>Delivery</b> <br>
                            ' . $getKlarnaApiOrder["shipping_address"]->given_name . ' ' . $getKlarnaApiOrder["billing_address"]->family_name . ' <br>
                            Address 1: ' . $getKlarnaApiOrder["shipping_address"]->street_address . ' <br>
                            Address 2: ' . $getKlarnaApiOrder["shipping_address"]->street_address2 . ' <br>
                            ' . $getKlarnaApiOrder["shipping_address"]->postal_code . ', ' . $getKlarnaApiOrder["billing_address"]->city . ', ' . $getKlarnaApiOrder["billing_address"]->country . ' <br>
                            ' . $getKlarnaApiOrder["shipping_address"]->email . ' <br>
                            ' . $getKlarnaApiOrder["shipping_address"]->phone . '
                        </div>
                        <div class="col-md-4">
                            <b>Method:</b> ' . $getKlarnaApiOrder["initial_payment_method"]->type . ' / ' . $getKlarnaApiOrder["initial_payment_method"]->description . ' <br>
                            <b>Status:</b> ' . $getKlarnaApiOrder["status"] . ' <br>
                            <b>Total:</b> ' . number_format($getKlarnaApiOrder["order_amount"] / 100, 2) . ' <br>
                            <b>Paid:</b> ' . number_format($getKlarnaApiOrder["captured_amount"] / 100, 2) . ' <br>
                            <b>Refunded:</b> ' . number_format($getKlarnaApiOrder["refunded_amount"] / 100, 2) . ' <br>
                            <b>Currency:</b> ' . $getKlarnaApiOrder["purchase_currency"] . ' <br>
                            <b>Handle:</b> <a href="' . $main->baseUrl() . '/klarna/cmd/view/order/' . $getWooCommerceApiOrder["transaction_id"] . '" class="">Show order</a>
                        </div>
                    </div>
                </div>
                ';
            } else {
                echo '
                <div class="alert alert-warning text-center mb-0 mt-2">
                    <i class="fa fa-info-circle"></i> This seem to be a WooCommerce order without a Klarna Id.
                </div>';
                
            }

            
        } else {
            echo '
            <div class="alert alert-light bg-light text-center mt-3">
                <i class="fa fa-info-circle"></i> We could not find any data for <b>'.strip_tags($_POST["term"]).'</b>
            </div>
            ';
        }
    } else {
        echo '
        <div class="alert alert-danger text-center">
            <i class="fa fa-info-circle"></i> Du dont have any access.
        </div>
        ';
    }
} else {
    echo 'Error';
}

ajax 代码如下所示:

function searchAjaxTicket(str) {
        // Declare variables
        var input, filter, table, tr, td, i, txtValue, response;
        input = document.getElementById("ajaxTicket");
        filter = input.value;
        if (filter === '') {
            $('.ajaxTicketSocket').hide();
        } else {
            $('.ajaxTicketSocket').show();
        }

        if (!filter.trim()) {
            $(".ajaxTicketSocket").html('');
        } else {
            $(".ajaxTicketSocket").html('<div class="col-md-12 mt-2 searchAjaxTicketLabel">Söker efter <b>' + stripHTML(
                filter) + '</b> <i class="fas fa-spinner fa-spin" style="font-size: 0.7em;"></i></div>').fadeIn();
            // $(".ajaxTicketSocketResponse")
            var form = $(this);
            var url = '<?= $main->baseUrl(); ?>/cgi/search.php';
            var delay = 20000;
            $.ajax({
                type: "POST",
                url: url,
                data: {
                    term: filter,
                    token: "<?= $_SESSION['sess_id']; ?>"
                }, // serializes the form's elements.
                success: function(data) {
                    $(".ajaxTicketSocket").html(data);
                },
                error: function(data) {
                    $(".ajaxTicketSocket").html(data);
                }
            }, delay);

        }
    }

而html形式如下:

<input type="text" onkeyup="searchAjaxTicket(this.value)" class="form-control font-weight-light ajaxTicket" id="ajaxTicket" placeholder="Search ticket or order..." autocomplete="FALSE">

【问题讨论】:

  • 您应该在按键时添加例如 600 毫秒的超时,并在每次按下键以“缓冲”请求时重置超时,然后当用户停止输入 600 毫秒时,超时执行并将请求发送到搜索。

标签: php ajax


【解决方案1】:

var 延迟 = 20000;

你看 - 你打了多个电话,只是一一延迟。因此,您会收到多个 AJAX 调用,每个调用都在 20000 之后,得到 race condition。检查20000后value是否有变化,如果没有变化,则调用API,否则直接中断函数。

编辑: 在伪代码中是:

var delay = 20000;
await new Promise(r => setTimeout(r, delay));
if (oldTextInput == currTextInput){
        $.ajax({
            type: "POST",
            url: url,
            data: {
                term: filter,
                token: "<?= $_SESSION['sess_id']; ?>"
            }, // serializes the form's elements.
            success: function(data) {
                $(".ajaxTicketSocket").html(data);
            },
            error: function(data) {
                $(".ajaxTicketSocket").html(data);
            }
        }, 100); 
}

【讨论】:

  • 我也尝试过没有延迟,我仍然得到与上面的 gif 相同的延迟和结果,当输入一个长单词时:/
  • 检查我的编辑。只需使用 document.GetElementById 从您的输入中获取值,保存延迟前的旧值,然后将其与延迟后的值进行比较。
猜你喜欢
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 2011-09-30
  • 2016-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多