从远程Web服务器到HTML Web表单无JSON响应

时间:2019-07-03 07:39:16

标签: javascript php html sql forms

我是一名业余程序员,所以请保持友好:-)

我一直在尝试(一个小时又几个小时!)来开发一个Web表单,该表单在提交一个表单项(例如员工编号)时会从远程SQL Web服务器检索数据并填充网页中的其他字段(例如姓名,地址,电话号码等)。所有常见的东西,我一直在尝试采用和改编StackOverflow中的许多示例。

方法是使用HTML表单来收集EmployeeID,使用JavaScript getJSON通过远程服务器php脚本来请求数据,该脚本连接到SQL数据库,查询数据库以创建返回数组,然后json_encode将其返回到Web表单。 / p>

一致的问题似乎是数据没有传递回Web窗体,因此没有填充其他字段。

因此,我搜索并找到了一个教程,其中包含可下载的“有效”示例代码(确认https://www.electrictoolbox.com/json-data-jquery-php-mysql/)。此示例在选择水果时填充“品种选择”选项,并且其编码方法非常简单。我正在使用它来使基本功能正常工作,但是即使这个简单的代码也不能很好地发挥作用:-)我确定这很简单,但是似乎找不到问题。

我确实将与SQL数据库的连接从PDO更改为Mysqli,因为我完全无法使PDO与SQL Server一起工作。

我希望表单将显示从数据库中提取的“品种”下拉框下方的项目,以匹配水果的类型。

这是带有Javascript的fruit.html文件:

<!doctype html>
<html>

<head>
<title>Untitled 1</title>
</head>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script type="text/javascript">

function populateFruitVariety() {

    $.getJSON('https://mysite.com.au/Secure/fruit-varieties.php', {fruitName:$('#fruitName').val()}, function(data) {
        var select = $('#fruitVariety');
        var options = select.prop('options');
        $('option', select).remove();

        $.each(data, function(index, array) {
            options[options.length] = new Option(array['variety']);
        });

    });
}

$(document).ready(function() {
    populateFruitVariety();
    $('#fruitName').change(function() {
        populateFruitVariety();
    });
});

</script>

<body>

    <form name="testfruit" onsubmit="populateFruitVariety();">

    Fruit: <select id="fruitName" name="name">
    <option>Apple</option>
    <option>Banana</option>
    <option>Orange</option>
    <option>Pear</option>
    </select> Variety: <select id="fruitVariety" name="variety"></select>
    <input type="submit" name="submit" value="Search">
</form>


</body>

</html>

这是在远程SQL Server上运行的fruit-varieties.php:

<?php


    // Connect using SQL Server Authentication.   
    $con = mysqli_connect($serverName, $username, $password); 
        if (!$con) { 
            echo 'Unable to connect to SQL server: ' . mysqli_error();
            die('Unable to connect to SQL server: ' . mysqli_error()); 
        } 

    // Select database
    mysqli_select_db($con,$databaseName);
        if (!$con) { 
            echo 'Unable to open database: ' . mysqli_error(); 
            die('Unable to open database: ' . mysqli_error()); 
        } 

    $fruitName = $_GET['fruitName'];
    echo $fruitName.'|';
    $rows = array();

    if(isset($_GET['fruitName'])) {
        $sql= "SELECT variety FROM fruit WHERE name = '$fruitName' ORDER BY variety";

        $rows = mysqli_fetch_assoc(mysqli_query($con, $sql));
        if (!$con) { 
            echo 'Query failed: ' . mysqli_error(); 
            die('Query failed: ' . mysqli_error()); 
        } 
    }
    echo json_encode($rows);

?>

最后,这是SQL数据库构造和示例数据:

SQL to create the table and populate with example data

CREATE TABLE IF NOT EXISTS `fruit` (
  `fruit_id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  `variety` varchar(50) NOT NULL,
  PRIMARY KEY  (`fruit_id`)
);

INSERT INTO `fruit` (`fruit_id`, `name`, `variety`) VALUES
(1, 'Apple', 'Red Delicious'),
(2, 'Pear', 'Comice'),
(3, 'Orange', 'Navel'),
(4, 'Pear', 'Bartlett'),
(5, 'Orange', 'Blood'),
(6, 'Apple', 'Cox''s Orange Pippin'),
(7, 'Apple', 'Granny Smith'),
(8, 'Pear', 'Anjou'),
(9, 'Orange', 'Valencia'),
(10, 'Banana', 'Plantain'),
(11, 'Banana', 'Burro'),
(12, 'Banana', 'Cavendish');

谢谢大家-非常感谢您能给我的任何帮助!

欢呼 ...史蒂夫

1 个答案:

答案 0 :(得分:1)

清洁编辑: 我完全错过了您要发送自定义正文的jQuery部分。无论如何,您的问题是echo $fruitName.'|';部分。一旦回声,它就会作为响应发送出去,这意味着它永远不会到达数据库查询部分。

这里的工作代码带有mysqli方式的准备好的语句:

<?php

$host = HOST;
$username = USERNAME;
$password = PASSWORD;
$databaseName = DB;

// Connect using SQL Server Authentication.   
$con = new mysqli($host, $username, $password, $databaseName);
if ($con->connect_errno) {
    die('Unable to connect to SQL server: ' . $con->connect_error);
}

$fruitName = $_GET['fruitName'];
$rows = [];

if (!empty($fruitName)) {
    $sql = "SELECT variety FROM fruit WHERE name = ? ORDER BY variety";
    $stmt = $con->prepare($sql);

    if (!$stmt) {
        die("Failed to prepare statement: {$con->error}");
    }

    // since you're passing a string, the first argument is "s"
    $stmt->bind_param("s", $fruitName);

    if (!$stmt->execute()) {
        die("Failed to execute statement: {$stmt->errorInfo()}");
    }

    // bind the result to $result which equals a new row each fetch
    $stmt->bind_result($result);
    while ($stmt->fetch()) {
        $rows[] = $result;
    }

    echo json_encode($rows);
}

$con->close();

PDO方式:

<?php

$host = HOST;
$username = USERNAME;
$password = PASSWORD;
$databaseName = DB;

$options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION];
$con = new PDO("mysql:host=$host;dbname=$databaseName", $username, $password, $options);

$fruitName = $_GET['fruitName'];
$rows = [];

if (!empty($fruitName)) {
    $sql = "SELECT variety FROM fruit WHERE name = :name ORDER BY variety";
    $stmt = $con->prepare($sql);

    // bind $fruitName directly in the execute
    // note that you can, but don't have to, use : in here
    try { $stmt->execute(["name" => $fruitName]); }
    catch(PDOException $e) {
        die("Failed to execute statement: {$e->getMessage()}");
    }

    while (($row = $stmt->fetch(PDO::FETCH_COLUMN))) {
        $rows[] = $row;
    }

    echo json_encode($rows);
}

$con = null;

请注意,在生产环境中,您永远不会向用户直接吐出错误-尤其是涉及数据库的东西时。对于引发异常的内容,您需要捕获它们,发送50x状态代码并记录错误。这样做之后,您还需要配置服务器以将用户发送到适当的页面。 PDO例外的示例:

try {
    $stmt->execute(["name" => $fruitName]);
} catch (PDOException $e) {
    http_response_code(500);
    error_log($e->getMessage());
    die();
}

对于不抛出异常的东西,您可以创建一个自定义的异常处理程序,该处理程序执行与上面类似的操作,然后将其抛出。

最后,将$.each()部分更改为:

$.each(data, function(index, item) {
    options[options.length] = new Option(item);
});

一切都会正常工作。

另一件事:通过删除文件前面的分号,确保已在 php.ini 文件中启用了要使用的扩展名。您还必须重新启动PHP,PHP-FPM,Apache或之后执行的所有操作。