【问题标题】:Echoing Array from MySQL PDO来自 MySQL PDO 的回显数组
【发布时间】:2020-01-28 05:04:28
【问题描述】:

我编写了一些功能完美的 MySQL 代码:

<?php
include 'dbconfig.php';

$startdate = date("Y-m-d", strtotime($_GET['startdate']));
$class = ($_GET['class']);
$city = ($_GET['city']);
$coverage = ($_GET['coverage']);

$sql="SELECT day, week, month FROM pricing 
  WHERE '" . $startdate . "' between start_date AND end_date and class='" . $class . "' and city='" . $city . "' and coverage='" . $coverage . "'";
$result = mysqli_query($conn,$sql);


while($row = mysqli_fetch_array($result)) {

    $date_ranges = array(
        'day'   => $row['day'],
        'week'     => $row['week'],
        'month'     => $row['month']
    );

    mysqli_close($conn);

} 

$json = json_encode($date_ranges);
echo $json;
?>

但是,我被告知使用 PDO 更安全,所以我将代码转换为 PDO,并且我做到了这一点:

<?php
include 'dbconfig.php';

$startdate = date("Y-m-d", strtotime($_GET['startdate']));
$class = ($_GET['class']);
$city = ($_GET['city']);
$coverage = ($_GET['coverage']);

try {
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $stmt = $conn->prepare("SELECT day, week, month FROM pricing 
  WHERE :startdate between start_date AND end_date and class=:class and city=:city and coverage=:coverage"); 

    $stmt->bindParam(':startdate', $startdate);
    $stmt->bindParam(':class', $class);
    $stmt->bindParam(':city', $city);
    $stmt->bindParam(':coverage', $coverage);

    $stmt->execute();

    $result = $stmt->setFetchMode(PDO::FETCH_ASSOC); 
    foreach(new TableRows(new RecursiveArrayIterator($stmt->fetchAll())) as $k=>$v) { 
        echo $v;

    }
}
catch(PDOException $e) {
    echo "Error: " . $e->getMessage();
}
$conn = null;
?>

问题肯定是这样的:

$result = $stmt->setFetchMode(PDO::FETCH_ASSOC); 
    foreach(new TableRows(new RecursiveArrayIterator($stmt->fetchAll())) as $k=>$v) { 
        echo $v;

我试图让输出看起来像这样(与第一个相同):

{"day":"35","week":"150","month":"650"}

有人可以告诉我如何完成这个吗?谢谢!

【问题讨论】:

  • 什么是TableRows?你为什么使用RecursiveArrayIterator
  • 没什么——我只是不太了解 PDO,我正在使用我找到的教程来学习它,这是默认示例。
  • 啊,我明白了。我认为您在这里所做的事情可能过于复杂。
  • 什么意思?
  • 无论你在网上找到什么教程,请放弃它。您展示的两个代码示例都充满了可疑的代码。试试phpdelusions.net/pdo

标签: php mysql arrays pdo


【解决方案1】:

如果您只是想以 JSON 格式输出查询结果,

echo json_encode($stmt->fetchAll(PDO::FETCH_ASSOC));

应该可以正常工作。不需要额外的类或循环。


顺便说一句,您使用 mysqli 的方式可能实际上存在问题,即使它看起来工作正常。看起来查询可能返回不止一行,但每次循环运行时都会覆盖 $date_ranges,因此您最终只会输出最后一行。


如果真的应该只有一个结果,您应该使用fetch() 而不是fetchAll(),这样您在 JSON 输出中只会得到一个对象,而不是一组对象。

echo json_encode($stmt->fetch(PDO::FETCH_ASSOC));

【讨论】:

  • 输出:[{"day":"35","0":"35","week":"150","1":"150","month":" 650","2":"650"}] 而不是 {"day":"35","week":"150","month":"650"}
  • 您没有将获取模式设置为 FETCH_ASSOC 吗?这看起来像默认的 FETCH_BOTH。
【解决方案2】:

无论你找到什么教程,你都需要放弃它。您正在编写的代码仍然容易受到 SQL 注入的影响,而且您并没有太大的改进。您只是对本教程感到困惑。请查看https://phpdelusions.net/pdo 以获得良好的 PDO 教程。

至于您编写的代码,您应该考虑一些更改:

  1. 设置正确的字符集,最好禁用模拟语句(默认启用,但您不需要它们)。

  2. 使用 PHP 的 DateTime 类而不是 strtotime()date()。它更健壮,更可靠。

  3. 不要使用TableRows 类,无论它应该是什么。你不需要它!请阅读这篇文章:Fatal error: Class 'TableRows' not found in

  4. 不要为了显示异常而捕获异常。它们将由 PHP 为您显示。只有在你知道如何处理它们的情况下才应该抓住它们。

<?php

include 'dbconfig.php';

$options = [
    \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
    \PDO::ATTR_EMULATE_PREPARES => false,
];
$conn = new \PDO("mysql:host=$servername;dbname=$dbname;charset=utf8mb4", $username, $password, $options);

$stmt = $conn->prepare("SELECT day, week, month FROM pricing 
    WHERE :startdate BETWEEN start_date AND end_date 
        AND class=:class 
        AND city=:city 
        AND coverage=:coverage");

// bind in execute with an array. 
$values = [
    'startdate' => (new \DateTime($_GET['startdate']))->format('Y-m-d'),
    'class' => $_GET['class'],
    'city' => $_GET['city'],
    'coverage' => $_GET['coverage']
];
$stmt->execute($values);

// echo all results in JSON format
echo json_encode($stmt->fetchAll());

【讨论】:

  • 谢谢,仅供参考 - 我必须删除 'fetchAll' 中的 'All' 才能以正确的格式输出数组。
  • 如果这是一个新问题,您可以发布一个新问题,我很乐意查看它,但我不能保证我能够回答。无论哪种方式,如果原始问题已解决,请保持此问题不变。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-07
  • 2016-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-12
相关资源
最近更新 更多