关于数据库操作的PHP 7.4 typeError

问题描述 投票:-1回答:1

我想将一些数据从数据库编码为JSON。

此类将打开与我的数据库的连接。

<?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);
    }
}

此类查询数据库中是否有任何项目

<?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();

此类遍历所有提取的数据,将其存储在数组中并将其编码为JSON。错误发生在while循环的第41行上。错误返回此

致命错误:未捕获的TypeError:键入的属性Read \ Read :: $ row_count必须为数组,在C:\ laragon \ www \ WBS \ php \ api \ task \ Read.php中使用布尔在第41行。

检查fetch方法的文档

此函数成功返回的值取决于获取类型。在所有情况下,失败均返回FALSE。

这对为什么会发生typeError很有道理,我只是对应该使我的字段row_count感到困惑,我尝试将其强制转换为没有成功的数组,并且有人认为PDO::FETCH_ASSOC会返回数组一个布尔值。

我对PHP如何使用这些类型化的属性以及如何在数据库操作中正确使用它们感到非常困惑。

php pdo php-7
1个回答
0
投票

您无需在方法中使用属性。您应该使用局部变量,但是甚至不需要。请不惜一切代价避免使用extract()。这是非常混乱的解决方案。

您已经将单行代码变成了包含很多不必要内容的完整方法。这样做就足够了:

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

但是,整个班级变得毫无意义。您没有以OOP方式使用它。您创建的类只是您的代码中的噪音。您可以删除Read类,而直接在Task上直接调用该方法。

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

您的Task类也有问题。您应该遵循依赖项注入设计,并将连接作为参数传递给__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;
    }
}

然后在创建对象时,将连接传入。

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

无关的注释:从不显示错误消息!。如果您唯一想做的就是回显错误,请不要捕获异常。放开例外。如果要实现错误处理程序,则应将其记录到文件中。

© www.soinside.com 2019 - 2024. All rights reserved.