php - 查询数据到json响应

时间:2017-12-02 20:51:57

标签: php mysql json ajax pdo

我正在尝试通过PDO从php获取数据,然后接收一个JSON对象(json_encode),以便在前端处理。尽我所能,我从MySQL查询中收到的唯一数据是添加消息的用户的用户名(推文),见下文: enter image description here

推文课程:

class Tweet extends User {

private $id;
private $userId;
private $text;
private $creationDate;

public function __construct() {
    $this->id = -1;
    $this->userId = null;
    $this->text = null;
    $this->creationDate = null;
}

function getId() {
    return $this->id;
}

function getUserId() {
    return $this->userId;
}

function getText() {
    return $this->text;
}

function getCreationDate() {
    return $this->creationDate;
}

function setUserId($userId) {
    $this->userId = $userId;
}

function setText($text) {
    $this->text = $text;
}

function setCreationDate($creationDate) {
    $this->creationDate = $creationDate;
}

static public function loadTweetById(PDO $pdo, $id) {
    $stmt = $pdo->prepare("SELECT * FROM Messages WHERE message_id=:id");
    $result = $stmt->execute([
        'id' => $id
    ]);

    if ($result === true && $stmt->rowCount() > 0) {
        $row = $stmt->fetch(PDO::FETCH_ASSOC);

        $loadedTweet = new Tweet();
        $loadedTweet->id = $row['message_id'];
        $loadedTweet->userId = $row['user_id'];
        $loadedTweet->text = $row['message_text'];
        $loadedTweet->creationDate = $row['message_datetime'];

        return $loadedTweet;
    }

    return null;
}

static public function loadAllTweetsByUserId(PDO $pdo, $id) {
    //$stmt = $pdo->prepare("SELECT * FROM Messages WHERE user_id=:id");
    $stmt = $pdo->prepare("SELECT "
            . "Users.username, "
            . "Messages.message_text, "
            . "Messages.message_datetime "
            . "FROM "
            . "Messages "
            . "JOIN "
            . "Users "
            . "ON Users.id=Messages.user_id "
            . "WHERE `user_id`=:id "
            . "ORDER BY Messages.message_datetime DESC");
    $result = $stmt->execute([
        'id' => $id
    ]);

    //var_dump($stmt->rowCount());


    if ($result === true && $stmt->rowCount() > 0) {
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {

            $loadedTweet = new Tweet();
            //echo $loadedTweet->id = $row['message_id'] . '<br>';
            echo $loadedTweet->userId = $row['username'] . '<br>';
            echo $loadedTweet->text = $row['message_text'] . '<br>';
            echo $loadedTweet->creationDate = $row['message_datetime'] . '<br>';
            echo "<br>";


            //return $loadedTweet;
        }

        return null;
    }
}

static public function loadAllTweets(PDO $pdo) {

    $sql = "SELECT * FROM Messages JOIN Users ON Users.id=Messages.user_id ORDER BY Messages.message_datetime DESC";

    $stmt = $pdo->prepare($sql);
    $stmt->execute();

    $tweets = $stmt->fetchAll(PDO::FETCH_OBJ);
    $tweetsList = [];

    if ($stmt !== false && $stmt->rowCount() > 0) {
        foreach ($tweets as $dbTweet) {
            $tweet = new Tweet($pdo);
            $tweet->id = $dbTweet->message_id;
            $tweet->userId = $dbTweet->user_id;
            $tweet->text = $dbTweet->message_text;
            $tweet->creationDate = $dbTweet->message_datetime;
            $tweet->getUsername = $dbTweet->username;


            $tweetsList[] = $tweet;
        }
        return $tweetsList;
    } else {
        return null;
    }

}

public function saveToDB(PDO $pdo) {
    //sprawdza czy robimy insert czy update
    if ($this->id == -1) { // if -1, robimy insert
        //przygotowanie zapytania
        //$userId = $_SESSION['userId'];
        $sql = "INSERT INTO `Messages`(`user_id`, `message_text`) VALUES (:user_id, :message_text)";
        $prepare = $pdo->prepare($sql);

        //wyslanie zapytania do bazy z kluczami i wartosciami do podmienienia
        $result = $prepare->execute([
            //uzywa userId zapisanego w sesji
            'user_id' => $this->userId,
            'message_text' => $this->text
        ]);

        // pobranie ostatniego ID dodanego rekordu i przypisanie do ID w tabeli Users
        //$this->id = $pdo->lastInsertId();


        return (bool) $result;
    }
}

函数loadAllTweets来自Tweet类(返回一个Tweet对象数组):

    static public function loadAllTweets(PDO $pdo) {

    $sql = "SELECT * FROM Messages JOIN Users ON Users.id=Messages.user_id ORDER BY Messages.message_datetime DESC";

    $stmt = $pdo->prepare($sql);
    $stmt->execute();

    $tweets = $stmt->fetchAll(PDO::FETCH_OBJ);
    $tweetsList = [];

    if ($stmt !== false && $stmt->rowCount() > 0) {
        foreach ($tweets as $dbTweet) {
            $tweet = new Tweet();
            $tweet->id = $dbTweet->message_id;
            $tweet->userId = $dbTweet->user_id;
            $tweet->text = $dbTweet->message_text;
            $tweet->creationDate = $dbTweet->message_datetime;
            $tweet->getUsername = $dbTweet->username;


            $tweetsList[] = $tweet;
        }
        return $tweetsList;
    } else {
        return null;
    }

}

mainpage.php

<?php
include_once '../../bootstrap.php';
header('Content-Type: application/json');//return json header

    $username = $_SESSION['username'];
    $tweets = Tweet::loadAllTweets($connection);
    $jsonTweets = [];


foreach ($tweets as $tweet) {
    $jsonTweets[] = json_decode(json_encode($tweet), true);
}

$response = ["tweets" => $jsonTweets,
            "success" => $username];

echo json_encode($response);

AJAX

$.ajax({
        url: "../admin/ajax/mainpage.php",
        dataType: 'json'
    })
        .done(function (response) {
            console.log(response.tweets);
        })
        .fail(function (response) {
            console.log(response);
        });

非常感谢任何有关我所做错事的见解。

1 个答案:

答案 0 :(得分:2)

Tweet类的私有属性对json_encode不可见,因此不包含在json中。使用自定义jsonSerialize实现将它们公开为实现\JsonSerializable,例如

class Tweet implements \JsonSerializable
{
  // ...

        public function jsonSerialize()
        {
            return [
                'foo' => $this->foo,
                'bar' => $this->bar
            ];
        }
}

有关可见性的更多信息:http://docs.php.net/language.oop5.visibility 不太明显的是,静态方法loadTweetData确实可以访问私有道具,因为对象属于同一类。

注意主题:让你的推文模型扩展用户有点尴尬,因为推文不是用户(违反Liskov substitution principle)。