如何将PHP查询MySQL的股票数据传入Javascript绘制Google K线图
修复步骤与代码实现
1. 基础问题修复
首先你现有代码存在几个隐藏问题需要先处理:
- 表单缺少提交按钮,无法触发POST请求
- 缺少ID为
candlestick的图表容器,JS渲染会报错 - 直接拼接SQL会触发SQL注入漏洞,且
interval是MySQL保留关键字,作为字段名需要用反引号包裹 - 表单提交的参数不能直接用
$ticker/$Interval获取,需要从$_POST超全局变量中读取
2. 参数获取与数据传递逻辑
关于参数读取
POST提交的表单参数通过$_POST['表单元素name属性值']获取,获取后需要做合法性校验,避免恶意请求。
关于PHP数据传递给JS
有两种常用实现方式:
- 方案A(匹配你现有表单提交逻辑):PHP处理请求后直接渲染页面,将查询结果转成JSON格式嵌入到JS代码中,直接赋值给JS变量。如果你的JS是独立外部文件,可以先在PHP页面声明全局变量存储数据,再引入外部JS文件即可。
- 方案B(无刷新体验更好):前端监听表单提交事件,阻止默认跳转,用AJAX异步传递参数给PHP,PHP返回JSON格式数据,前端接收后直接渲染图表。
3. 完整修改代码示例
修改后的HTML代码
<section class="no-padding-top no-padding-bottom"> <div class="container-fluid"> <div class="statistic-block block"> <form name="query" method="post" action="connection.php"> <div class="ticker"> <label for="ticker">Ticker:</label> <input style="background: rgba(255,255,255,0.5);border-radius: 10px; border: none; text-align: center;" type="text" id="ticker" name="ticker" required minlength="4" maxlength="8" size="10" placeholder="TSLA"> </div> <div class="Interval"> <label for="Interval">Period:</label> <select style="background: rgba(255,255,255,0.5);border-radius: 10px; border: none; text-align: center;" name="Interval" id="Interval"> <option value="1d">1 day</option> <option value="1wk">1 week</option> <option value="1mo">1 month</option> </select> </div> <!-- 新增提交按钮 --> <button type="submit" style="margin-left:10px;padding:5px 15px;border-radius:10px;border:none;">查询</button> </form> <!-- 新增图表容器 --> <div id="candlestick" style="height: 500px; margin-top: 20px;"></div> </div> </div> </section>
修改后的PHP代码(connection.php,采用方案A实现)
<?php $servername = "..."; $username = "..."; $password = "..."; $dbname = "..."; $conn = mysqli_connect($servername, $username, $password, $dbname); if (!$conn) { die("Connection failed: " . mysqli_connect_error()); } // 获取并校验参数 $ticker = trim($_POST['ticker'] ?? ''); $interval = trim($_POST['Interval'] ?? ''); $allow_interval = ['1d', '1wk', '1mo']; if (empty($ticker) || !in_array($interval, $allow_interval)) { die("参数非法"); } // 预处理查询防SQL注入,interval关键字加反引号包裹 $stmt = mysqli_prepare($conn, "SELECT Date, Open, High, Low, Close FROM symbols WHERE ticker=? AND `interval`=?"); mysqli_stmt_bind_param($stmt, "ss", $ticker, $interval); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $rows = []; if (mysqli_num_rows($result) > 0) { while($row = mysqli_fetch_assoc($result)) { $rows[] = [ $row['Date'], floatval($row['Open']), floatval($row['High']), floatval($row['Low']), floatval($row['Close']) ]; } } mysqli_close($conn); // 把PHP数组转成JSON格式 $chart_data = json_encode($rows); ?> <!-- 引入Google Charts依赖 --> <script src="https://www.gstatic.com/charts/loader.js"></script> <script> // 如果是独立JS文件,可把下一行单独放在PHP页面,作为全局变量供外部JS调用 const rows = <?php echo $chart_data; ?>; google.charts .load("current", { packages: ["corechart"], }) .then(function drawChart() { if(rows.length === 0) { alert("暂无对应数据"); return; } var data = google.visualization.arrayToDataTable( rows.map(function (row) { var date = row[0]; var low = row[3]; var open = row[1]; var close = row[4]; var high = row[2]; return [date, low, open, close, high]; }), true ); var options = { legend: "none", candlestick: { fallingColor: { strokeWidth: 0, fill: "#a52714" }, risingColor: { strokeWidth: 0, fill: "#0f9d58" }, }, }; var chart = new google.visualization.CandlestickChart( document.getElementById("candlestick") ); chart.draw(data, options); }); </script>
内容的提问来源于stack exchange,提问作者user16845627
相关产品推荐
相关产品推荐

