PHP 7.4 数据库操作的类型错误
PHP 7.4 typeError on database operations
我想将一些数据从数据库编码到 JSON。
这 class 打开一个到我的数据库的连接。
<?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);
}
}
这 class 查询数据库中的任何项目
<?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();
这个class循环遍历所有获取的数据,将其存储在一个数组中并将其编码为JSON。
错误发生在第 41 行,即 while
循环。错误 return 是这个
Fatal error: Uncaught TypeError: Typed property Read\Read::$row_count
must be array, bool used in C:\laragon\www\WBS\php\api\task\Read.php
on line 41.
查看有关 fetch
方法的文档
The return value of this function on success depends on the fetch
type. In all cases, FALSE is returned on failure.
为什么会发生 typeError 是有道理的,我只是对我应该如何设置我的字段感到困惑 row_count
我尝试将它转换为一个数组但没有成功,人们会认为 PDO::FETCH_ASSOC
会 return 一个数组而不是布尔值。
我只是对 PHP 如何使用这些类型化属性以及如何在数据库操作中正确使用它们感到非常困惑。
您不需要在您的方法中使用属性。您应该使用局部变量,但即使它们也不是必需的。请不惜一切代价避免extract()
。这是非常混乱的解决方案。
您已经将应该是单行代码的内容变成了包含很多不必要内容的完整方法。这样做就足够了:
public function EncodeToJson(): string
{
return json_encode(['records' => $this->task->SqlQuery()->fetchAll(PDO::FETCH_ASSOC)]);
}
然而,整个class变得毫无意义。您没有以 OOP 方式使用它。您创建的 class 只是代码中的噪音。您可以删除 Read
class 并直接调用 Task
上的方法。
echo json_encode(['records' => (new Task())->SqlQuery()->fetchAll(PDO::FETCH_ASSOC)]);
你的Task
class也有问题。您应该遵循依赖注入设计并将连接作为参数传递给 __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);
一条不相关的注释:从不显示错误消息!。如果您只想回显错误,请不要捕获异常。别理会例外。如果你想实现错误处理程序,它应该记录到一个文件中。
我想将一些数据从数据库编码到 JSON。
这 class 打开一个到我的数据库的连接。
<?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);
}
}
这 class 查询数据库中的任何项目
<?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();
这个class循环遍历所有获取的数据,将其存储在一个数组中并将其编码为JSON。
错误发生在第 41 行,即 while
循环。错误 return 是这个
Fatal error: Uncaught TypeError: Typed property Read\Read::$row_count must be array, bool used in C:\laragon\www\WBS\php\api\task\Read.php on line 41.
查看有关 fetch
方法的文档
The return value of this function on success depends on the fetch type. In all cases, FALSE is returned on failure.
为什么会发生 typeError 是有道理的,我只是对我应该如何设置我的字段感到困惑 row_count
我尝试将它转换为一个数组但没有成功,人们会认为 PDO::FETCH_ASSOC
会 return 一个数组而不是布尔值。
我只是对 PHP 如何使用这些类型化属性以及如何在数据库操作中正确使用它们感到非常困惑。
您不需要在您的方法中使用属性。您应该使用局部变量,但即使它们也不是必需的。请不惜一切代价避免extract()
。这是非常混乱的解决方案。
您已经将应该是单行代码的内容变成了包含很多不必要内容的完整方法。这样做就足够了:
public function EncodeToJson(): string
{
return json_encode(['records' => $this->task->SqlQuery()->fetchAll(PDO::FETCH_ASSOC)]);
}
然而,整个class变得毫无意义。您没有以 OOP 方式使用它。您创建的 class 只是代码中的噪音。您可以删除 Read
class 并直接调用 Task
上的方法。
echo json_encode(['records' => (new Task())->SqlQuery()->fetchAll(PDO::FETCH_ASSOC)]);
你的Task
class也有问题。您应该遵循依赖注入设计并将连接作为参数传递给 __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);
一条不相关的注释:从不显示错误消息!。如果您只想回显错误,请不要捕获异常。别理会例外。如果你想实现错误处理程序,它应该记录到一个文件中。