Saya ingin menyandikan beberapa data dari database ke JSON.

Kelas ini membuka koneksi ke database saya.

<?php

namespace Database;

use PDO;
use PDOException;

class Connection
{
    private string $server = "mysql:host=localhost;dbname=wbs";
    private string $user = "root";
    private string $pass = "";
    private array $options = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,);
    protected PDO $con;

    public function openConnection()
    {
        try {
            $this->con = new PDO($this->server, $this->user, $this->pass, $this->options);
        } catch (PDOException $e) {
            echo "Something went wrong with the database connection: " . $e->getMessage();
        }
        return $this->con;
    }

    public function closeConnection()
    {
        unset($this->con);
    }
}

Kelas ini menanyakan database untuk item apa pun

<?php

namespace Task;

use PDO;
use PDOStatement;
use Database\Connection;

class Task
{
    private Connection $conn;
    private PDO $pdo;
    private PDOStatement $PDOStatement;


    public function __construct()
    {
       $this->conn = new Connection();
    }
    public function SqlQuery(): PDOStatement
    {
       $this->pdo = $this->conn->openConnection();

       $this->PDOStatement = $this->pdo->prepare("SELECT * FROM `tasks` 
       LEFT JOIN `projects` ON 'projects.projectid' = 'tasks.projectid' 
       LEFT JOIN `moscow` ON 'moscow.moscowid' = 'tasks.moscowid'");

       $this->PDOStatement->execute();

       return $this->PDOStatement;
    }
}

<?php

namespace Read;

use PDO;
use PDOStatement;
use Task\Task;


require_once("../config/Connection.php");
require_once("../object/Task.php");

class Read
{
    private PDOStatement $PDOStatement;
    private Task $task;
    private int $items;
    private array $task_array;
    private array $task_item;
    private array $row_count;
    private array $row_items;

    public function __construct()
    {
        $this->task = new Task();
    }

    public function EncodeToJson(): string
    {
        $this->PDOStatement = $this->task->SqlQuery();
        $this->items = $this->PDOStatement->rowCount();

        if ($this->items > 0) {

            $this->task_array = array();
            $this->task_array["records"] = array();

            while ( $this->row_count = $this->PDOStatement->fetch(PDO::FETCH_ASSOC)) {
                $this->row_items = $this->row_count;
                extract($this->row_items);

                $this->task_item = array(
                    "id" => $id,
                    "task_name" => $task_name,
                    "task_owner" => $task_owner,
                    "developer" => $developer,
                );

                array_push($this->task_array["records"], $this->task_item);
            }

            http_response_code(200);

            return json_encode($this->task_array);
        }
    }
}

$Read = new Read();

echo $Read->EncodeToJson();

Kelas ini mengulang semua data yang diambil, menyimpannya dalam array dan mengkodekannya ke JSON. Kesalahan terjadi pada baris 41 yang merupakan loop while. kesalahan mengembalikan ini

Kesalahan fatal: TypeError Tidak Tertangkap: Properti yang diketik Read\Read::$row_count harus berupa array, bool digunakan di C:\laragon\www\WBS\php\api\task\Read.php pada baris 41.

Memeriksa dokumen tentang metode fetch

Nilai kembalian fungsi ini pada keberhasilan tergantung pada jenis pengambilan. Dalam semua kasus, FALSE dikembalikan pada kegagalan.

Masuk akal mengapa typeError terjadi, saya hanya bingung dengan apa yang harus saya buat bidang saya row_count Saya mencoba mentransmisikannya ke array tanpa hasil dan orang akan menganggap PDO::FETCH_ASSOC akan mengembalikan array bukan boolean.

Saya sangat bingung bagaimana PHP menggunakan properti yang diketik ini dan bagaimana menggunakannya dengan benar dengan operasi database.

-2
niels van hoof 9 April 2020, 14:12

1 menjawab

Jawaban Terbaik

Anda tidak perlu menggunakan properti dalam metode Anda. Anda harus menggunakan variabel lokal, tetapi bahkan mereka tidak diperlukan. Harap hindari extract() dengan cara apa pun. Ini adalah solusi yang sangat berantakan.

Anda telah mengubah apa yang seharusnya menjadi satu baris kode menjadi metode lengkap dengan banyak hal yang tidak perlu. Cukup lakukan ini saja:

public function EncodeToJson(): string
{
    return json_encode(['records' => $this->task->SqlQuery()->fetchAll(PDO::FETCH_ASSOC)]);
}

Namun, seluruh kelas menjadi sia-sia. Anda tidak menggunakannya dengan cara OOP. Kelas yang Anda buat hanyalah noise dalam kode Anda. Anda dapat menghapus kelas Read dan cukup memanggil metode di Task secara langsung.

echo json_encode(['records' => (new Task())->SqlQuery()->fetchAll(PDO::FETCH_ASSOC)]);

Kelas Task Anda juga bermasalah. Anda harus mengikuti desain injeksi ketergantungan dan meneruskan koneksi sebagai parameter ke __construct.

<?php

namespace Task;

use PDO;
use PDOStatement;

class Task {
    private PDO $pdo;

    public function __construct(PDO $conn) {
        $this->conn = $conn;
    }

    public function read(): PDOStatement {
        $PDOStatement = $this->pdo->prepare("SELECT * FROM `tasks` 
            LEFT JOIN `projects` ON 'projects.projectid' = 'tasks.projectid' 
            LEFT JOIN `moscow` ON 'moscow.moscowid' = 'tasks.moscowid'");

        $PDOStatement->execute();

        return $PDOStatement;
    }
}

Dan kemudian saat Anda membuat objek, berikan koneksi.

$pdo = $connection->openConnection();
$task = new Task($pdo);

Pada catatan yang tidak terkait: Jangan pernah tampilkan pesan kesalahan!. Jangan menangkap pengecualian jika satu-satunya hal yang ingin Anda lakukan adalah mengulangi kesalahan. Biarkan pengecualian saja. Jika Anda ingin menerapkan penangan kesalahan, itu harus masuk ke file.

2
Dharman 9 April 2020, 15:11