将 AJAX 实现到具有多个选择的 PHP 页面

Implementing AJAX into a PHP page with multiple selections

这里是非常新的编码器。

我有一个包含四个 select 输入的页面,每个输入都有两个可能的选项,当所有 selection 都有一个值并单击提交按钮时,某首歌曲(16 首中的第 1 首)基于制造的select离子)将回声到音频播放器中。

在当前状态下,我已经能够连接到我的数据库,该数据库回显了音轨的链接和标题。

我的问题是,我希望所有 select 离子在单击提交按钮后在视觉上保留其选项值,以便用户可以看到他们为当前 select 编辑了哪些选项正在播放的歌曲。

我在网上找到了很多将 AJAX 实现到页面中的示例,其中 one selection 通过诸如此类的 onchange 事件激活一个来自 W3 Schools http://www.w3schools.com/php/php_ajax_database.asp,但没有多个 selection 和一个提交按钮。

这个社区的某个人前几天帮助了我,因此 W3 学校示例的代码可以容纳提交按钮的 onclick 事件,而不是 select 输入上的 onchange,但我缺乏很多流利 PHP/Javascript 我真的不知道如何包含多个 select 离子。

我希望有人可以看看我在页面中有多远 selection 但没有实施 AJAX 并以非常简单的方式向我解释我该如何去做包括 AJAX 以便在单击提交按钮后可以看到 select 选项。如果有人甚至可以向我展示我的页面的一个版本,其中 AJAX 放置了评论来解释该过程,那将是绝对的黄金。

这是我的页面...

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="styles.css">
<link rel="shortcut icon" href="favicon.ico"/>
<title>MoodTunes -- Tunes for your mood</title>
<script src="prefixfree.min.js"></script>
</head>

<body>
<?php

$myDatabase = mysql_connect("localhost","root","root");
if (!myDatabase) die ('Oh dear.' . mysql_error());

if(isset($_GET['submit'])){
mysql_select_db("tunes",$myDatabase);
$volume = $_GET['volume'];
$tempo = $_GET['tempo'];
$complexity = $_GET['complexity'];
$key = $_GET['key'];
$query = "SELECT * FROM music WHERE volumeOption='".$volume."' AND tempoOption='".$tempo."' AND complexityOption='".$complexity."' AND keySignatureOption='".$key."'";
$mydata = mysql_query($query, $myDatabase) or die(mysql_error());
while($row = mysql_fetch_array($mydata)){

echo "<div id='submitContent'>";
echo "<h3><span>Now Playing:</span> " . $row['title'] . "</h3>";
echo "<figure id='audioplayer' style='display:inline-block;'>";
echo "<audio id='audiotrack' controls loop>";
echo "<source src='" . $row['link'] . "'type='audio/mpeg'>";
echo "</audio>";
echo "</figure>";

}
mysql_close($myDatabase);
}

?>

</div>

<header>
    <div>
        <h1>
            <img src="assets/images/logo.png" alt="">
        </h1>
        <h2>Tunes for <span>your</span> mood</h2>
    </div>
</header>

<main>
    <h4>Choose your tune criteria</h4>
    <form>

        <label for="volume"></label>
            <select name="volume" id="volume">
            <option>Select One</option>
            <option value="0" id="loud">heavy</option>
            <option value="1" id="quiet">soft</option>
            </select>
        </label>

        <label for="tempo"></label>
        <select name="tempo" id="tempo">
        <option>Select One</option>
        <option value="0" id="fast">fast</option>
        <option value="1" id="slow">slow</option>
        </select>
        </label>

        <label for="complexity"></label>
        <select name="complexity" id="complexity">
        <option>Select One</option>
        <option value="0" id="complex">complex</option>
        <option value="1" id="simple">simple</option>
        </select>
        </label>

        <label for="key"></label>
        <select name="key" id="key">
        <option>Select One</option>
        <option value="0" id="minor">minor key</option>
        <option value="1" id="major">major key</option>
        </select>
        </label>   
<div id="submitDiv">

<input type="submit" name="submit" id="submit" value="Get My Tune!">
</div>

</form>

</main>

</body>
</html>

如有任何帮助,我们将不胜感激。就像我说的,我对很多编码还是很陌生,所以如果你能帮助我,请简单地回答。谢谢

免责声明 sessionStorage 对象仅在 browser is OPEN 期间可用。如果您希望在浏览器关闭时保留信息,请改用 localStorage 对象。


Here's your working jsFiddle example

无需使用服务器端语言即可保留表单输入信息的最简单快捷的方法之一是使用 sessionStorage 函数。

我们可以捕获表单元素上的所有更改事件并将它们的值推送到 sessionStorage 中。然后,我们可以用非常少的代码检索并将它们应用于页面重新加载时的每个相应输入。

//First, we need to make sure our users support the Storage object.

if(typeof(Storage) !== "undefined") {
    /**
    | -----------------------
    | All of your elements can be selected by the :input selector in jQuery
    | We will bind to the change function and push to the sessionStorage whenever they are altered.
    | -----------------------
    */
    $(':input').change(function(){
        sessionStorage.setItem($(this).prop('name'), $(this).val());
    });
}

基本上,如果存储可用,我们会创建一个事件处理程序,它绑定到我们所有表单元素的更改事件。现在,当它们发生变化时,我们将拥有一组可以从 sessionStorage 元素中检索的键。

现在,我们需要在页面加载时将这些值应用到我们的元素。

//make sure we still have Storage available.
if (typeof (Storage) !== "undefined") {
   /**
    | -----------------------
    | We capture each of the input elements below and then check if
    | we previously had values saved for them.
    | If not, the default is left selected.
    | -----------------------
    */
   $('form *').filter(':input').each(function () {
       if(sessionStorage.getItem($(this).prop('name'))){
           $(this).val(sessionStorage.getItem($(this).prop('name')));    
       }

   });
}

现在,在上面的代码中,我们只是简单地遍历所有表单元素,并将存储在 sessionStorage 中的值应用于这些元素。

另外

让我们远离 mysql_ 库,因为它已被弃用,并将在 PHP 的未来版本中完全删除。让我们也专注于清理用户输入,因此您没有 SQL 可能产生灾难性副作用的注入漏洞。

$myDatabase = new mysqli('localhost', 'username', 'password', 'database');

用户仍然可以绕过 if(isset($_GET['submit'])){ 条件,所以让我们添加更多的健全性检查。

$volume = isset($_GET['volume']) ? $_GET['volume']: null;
$tempo = isset($_GET['tempo']) ? $_GET['tempo'] : null;
$complexity = isset($_GET['complexity']) ? $_GET['complexity'] : null;
$key = isset($_GET['key']) ? $_GET['key'] : null;

现在我们应该检查所有这些是否同时设置。

if(isset($volume, $tempo, $complexity, $key)){

}

在这个条件下,我们可以使用 mysqli 的面向对象方法来应用我们的数据库逻辑。我们还将使用准备好的语句来避免 SQL 注入。

$stmt = $mysqli->prepare('SELECT * FROM music WHERE volumeOption=? AND tempoOption=? AND complexityOption=? AND keySignatureOption=?');
$stmt->bind_param('ssss', $volume, $tempo, $complexity, $key);
if($stmt->execute()){
    while($row = $stmt->fetch()){ ?>
        <div id="submitContent">
            <h3><span>Now Playing:</span> <?php echo $row['title']; ?> </h3>
            <figure id="audioplayer" style='display:inline-block;'>
                <audio id="audiotrack" controls loop>
                    <source src="<?php echo $row['link']?>" type="audio/mpeg"/>
                </audio>
            </figure>
    <?php }
}

我建议分成 2 个文件:一个 HTML 文件和一个 PHP 文件。将 PHP 分开并使用 XHR 对象 (Ajax) 调用它。

music.html

<!-- skipped top stuff -->

<body>

<!-- replace your PHP code with straight HTML -->
<div id='submitContent'>
  <h3><span>Now Playing:</span> <span id="musictitle"></span></h3>
  <figure id='audioplayer' style='display:inline-block;'>
    <audio id='audiotrack' controls loop>
      <source id="musiclink" src='' type='audio/mpeg'>
    </audio>
  </figure>
</div>

<!-- skipped middle stuff -->

<form id="musicform"> <!-- give your form an id -->
  <!-- skipped form stuff -->
</form>

<!-- add script tag to bottom of body -->
<script>

// function to handle music selection
function get_selection () {

    // instantiate music url
    var url = 'music.php'

    // get form values or defaults
    var musicform = document.getElementById('musicform')
    url += ('Select One' == musicform.volume.value)?     '?volume=1':     '?volume='     + musicform.volume.value
    url += ('Select One' == musicform.tempo.value)?      '&tempo=1':      '&tempo='      + musicform.tempo.value
    url += ('Select One' == musicform.complexity.value)? '&complexity=1': '&complexity=' + musicform.complexity.value
    url += ('Select One' == musicform.key.value)?        '&key=1':        '&key='        + musicform.key.value

    // set up XHR object
    var xhr = new XMLHttpRequest()
    xhr.open('GET', url, true)
    xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
    // handle response
    xhr.onload = function () {
        //console.log(this.responseText)
        var music = JSON.parse(this.responseText)
        document.getElementById('musictitle').innerHTML = music.title
        var audio = document.getElementById('audiotrack')
        document.getElementById('musiclink').src = music.link
        audio.load()
        audio.play()
    }
    xhr.send()
}

// hook up music selection function to form submit
document.getElementById('musicform').addEventListener('submit', function(evt){
    evt.preventDefault()
    get_selection()
})

// execute music selection function at least once
get_selection()

</script>

</body>
</html>

music.php

<?php

$myDatabase = mysqli_connect("localhost","root", "root", "tunes");

$stmt = mysqli_prepare($myDatabase
  , "SELECT title, link FROM music WHERE volumeOption = ? AND tempoOption = ? AND complexityOption = ? AND keySignatureOption = ?"
) or die(mysqli_error($myDatabase));
mysqli_stmt_bind_param($stmt, 'ssss', $_GET['volume'], $_GET['tempo'], $_GET['complexity'], $_GET['key']);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $title, $link);

mysqli_stmt_fetch($stmt); // assuming only one result
echo '{"title": "' . $title . '", "link": "' . $link . '"}';

mysqli_close($myDatabase);

?>

我正在使用 PHP MySQL我为安全性数据库访问准备的语句,事实上普通的旧 PHP MySQL 函数已被弃用。