从准备语句的结果分配对象属性
Assign object attributes from the result of prepared statement
我想为我的 Class 创建一个新实例,并为其属性分配 return 编辑的值。这样做的原因是我正在创建一系列继承自调用 class 的方法,而不是使用我已经在使用的静态方法。
我目前使用的示例:
public static function findById($id) {
$id = self::escapeParam($id);
$idVal = is_int($id) ? "i" : "s";
$sql = "SELECT * FROM ".static::$db_table." WHERE id = ? LIMIT 1";
return static::findByQuery($sql,$idVal,$id);
}
public static function findByQuery($sql,$bindChar = '',$bindVal = '') {
try {
$callingClass = get_called_class();
$object = new $callingClass;
$statement = Database::$connection->prepare($sql);
if(!empty($bindChar)) :
$statement->bind_param($bindChar, $bindVal);
endif;
if($statement->execute()) :
$result = $statement->get_result();
$object = $result->fetch_object();
endif;
$statement->close();
if(!empty($object)) :
return $object;
endif;
} catch(Exception $e) {
}
}
我尝试编写一个实例化方法来创建我的 class 的新实例,然后从教程 I 中的数组中为对象的每个属性分配值 returns做过。但是,该教程相当过时并且没有使用任何新的语法或绑定,所以我试图重新编写它。
下面教程中的示例:
public static function find_by_id($id) {
global $database;
$the_result_array = static::find_by_query("SELECT * FROM " . static::$db_table . " WHERE id = $id LIMIT 1");
return !empty($the_result_array) ? array_shift($the_result_array) : false;
}
public static function find_by_query($sql) {
global $database;
$result_set = $database->query($sql);
$the_object_array = array();
while($row = mysqli_fetch_array($result_set)) {
$the_object_array[] = static::instantation($row);
}
return $the_object_array;
}
public static function instantation($the_record){
$calling_class = get_called_class();
$the_object = new $calling_class;
foreach ($the_record as $the_attribute => $value) {
if($the_object->has_the_attribute($the_attribute)) {
$the_object->$the_attribute = $value;
}
}
return $the_object;
}
private function has_the_attribute($the_attribute) {
return property_exists($this, $the_attribute);
}
我在本教程中尝试做的是 return 我的结果作为一个数组使用一段时间,然后通过将构建的数组传递给 static::instantation()
方法来分配一个变量,但它似乎永远无法正常工作,因为我在调用 class(例如管理员)中创建的任何 public 函数都不会被调用,因为它们不存在,因为 Class 没有被实例化。
我现在已经开始工作了,虽然我觉得这可能不是最好的方法。
我主要是前端,所以如果有改进或最佳实践,请发表评论。
public static function findByQuery($sql,$bindChar = '',$bindVal = '') {
try {
$statement = Database::$connection->prepare($sql);
if(!empty($bindChar)) :
$statement->bind_param("$bindChar", $bindVal);
endif;
if($statement->execute()) :
$result = $statement->get_result();
$output = $result->fetch_object();
endif;
$statement->close();
if(!empty($output)) :
$class = get_called_class();
$object = new $class;
foreach(get_object_vars($output) as $key => $value) :
$object->$key = $value;
endforeach;
endif;
if(!empty($object)) :
return $object;
endif;
} catch(Exception $e) {
}
}
我最初的想法是声明一个对象,然后我认为 PHP fetch_object 调用会在启动 Class 之后为我的对象分配它的属性,但事实并非如此案.
所以我所做的是,如果语句成功并创建了一个结果对象,然后我使用 get_object_vars() 命令获取对象属性和值,然后循环遍历这些作为一个键值对,为每个属性分配它的返回值。
我现在可以确认这有效 运行 $admin->remove() 从我的删除脚本中,而不是我之前必须做的 Admin::remove($编号);
mysqli_result::fetch_object()
接受 class 名称作为第一个参数。您可以将 class 名称作为参数传递给该方法并获取模型的实例。我不确定你为什么有那么多代码,但请考虑我根据你自己的代码编写的示例:
<?php
class Model
{
public static function findByQuery(string $sql, ?string $bindChar = null, ?string $bindVal = null): ?static
{
$statement = Database::$connection->prepare($sql);
if ($bindChar) :
$statement->bind_param($bindChar, $bindVal);
endif;
$statement->execute();
$result = $statement->get_result();
return $result->fetch_object(static::class);
}
}
class User extends Model
{
private $id;
}
class Database
{
public static mysqli $connection;
}
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
Database::$connection = new mysqli('localhost', 'user', 'password', 'test');
$user = User::findByQuery('SELECT ? as id', 's', 'Dharman');
var_dump($user);
该示例的输出是:
object(User)#4 (1) {
["id":"User":private]=>
string(7) "Dharman"
}
如您所见,代码使用后期静态绑定创建了 class 的实例,并且还将值分配给私有 属性,否则您无法这样做。
P.S。我的例子有点整洁。我添加了参数类型并删除了很多不必要的代码。特别是,我删除了空的 try-catch,这是一种糟糕的做法。
我想为我的 Class 创建一个新实例,并为其属性分配 return 编辑的值。这样做的原因是我正在创建一系列继承自调用 class 的方法,而不是使用我已经在使用的静态方法。
我目前使用的示例:
public static function findById($id) {
$id = self::escapeParam($id);
$idVal = is_int($id) ? "i" : "s";
$sql = "SELECT * FROM ".static::$db_table." WHERE id = ? LIMIT 1";
return static::findByQuery($sql,$idVal,$id);
}
public static function findByQuery($sql,$bindChar = '',$bindVal = '') {
try {
$callingClass = get_called_class();
$object = new $callingClass;
$statement = Database::$connection->prepare($sql);
if(!empty($bindChar)) :
$statement->bind_param($bindChar, $bindVal);
endif;
if($statement->execute()) :
$result = $statement->get_result();
$object = $result->fetch_object();
endif;
$statement->close();
if(!empty($object)) :
return $object;
endif;
} catch(Exception $e) {
}
}
我尝试编写一个实例化方法来创建我的 class 的新实例,然后从教程 I 中的数组中为对象的每个属性分配值 returns做过。但是,该教程相当过时并且没有使用任何新的语法或绑定,所以我试图重新编写它。
下面教程中的示例:
public static function find_by_id($id) {
global $database;
$the_result_array = static::find_by_query("SELECT * FROM " . static::$db_table . " WHERE id = $id LIMIT 1");
return !empty($the_result_array) ? array_shift($the_result_array) : false;
}
public static function find_by_query($sql) {
global $database;
$result_set = $database->query($sql);
$the_object_array = array();
while($row = mysqli_fetch_array($result_set)) {
$the_object_array[] = static::instantation($row);
}
return $the_object_array;
}
public static function instantation($the_record){
$calling_class = get_called_class();
$the_object = new $calling_class;
foreach ($the_record as $the_attribute => $value) {
if($the_object->has_the_attribute($the_attribute)) {
$the_object->$the_attribute = $value;
}
}
return $the_object;
}
private function has_the_attribute($the_attribute) {
return property_exists($this, $the_attribute);
}
我在本教程中尝试做的是 return 我的结果作为一个数组使用一段时间,然后通过将构建的数组传递给 static::instantation()
方法来分配一个变量,但它似乎永远无法正常工作,因为我在调用 class(例如管理员)中创建的任何 public 函数都不会被调用,因为它们不存在,因为 Class 没有被实例化。
我现在已经开始工作了,虽然我觉得这可能不是最好的方法。
我主要是前端,所以如果有改进或最佳实践,请发表评论。
public static function findByQuery($sql,$bindChar = '',$bindVal = '') {
try {
$statement = Database::$connection->prepare($sql);
if(!empty($bindChar)) :
$statement->bind_param("$bindChar", $bindVal);
endif;
if($statement->execute()) :
$result = $statement->get_result();
$output = $result->fetch_object();
endif;
$statement->close();
if(!empty($output)) :
$class = get_called_class();
$object = new $class;
foreach(get_object_vars($output) as $key => $value) :
$object->$key = $value;
endforeach;
endif;
if(!empty($object)) :
return $object;
endif;
} catch(Exception $e) {
}
}
我最初的想法是声明一个对象,然后我认为 PHP fetch_object 调用会在启动 Class 之后为我的对象分配它的属性,但事实并非如此案.
所以我所做的是,如果语句成功并创建了一个结果对象,然后我使用 get_object_vars() 命令获取对象属性和值,然后循环遍历这些作为一个键值对,为每个属性分配它的返回值。
我现在可以确认这有效 运行 $admin->remove() 从我的删除脚本中,而不是我之前必须做的 Admin::remove($编号);
mysqli_result::fetch_object()
接受 class 名称作为第一个参数。您可以将 class 名称作为参数传递给该方法并获取模型的实例。我不确定你为什么有那么多代码,但请考虑我根据你自己的代码编写的示例:
<?php
class Model
{
public static function findByQuery(string $sql, ?string $bindChar = null, ?string $bindVal = null): ?static
{
$statement = Database::$connection->prepare($sql);
if ($bindChar) :
$statement->bind_param($bindChar, $bindVal);
endif;
$statement->execute();
$result = $statement->get_result();
return $result->fetch_object(static::class);
}
}
class User extends Model
{
private $id;
}
class Database
{
public static mysqli $connection;
}
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
Database::$connection = new mysqli('localhost', 'user', 'password', 'test');
$user = User::findByQuery('SELECT ? as id', 's', 'Dharman');
var_dump($user);
该示例的输出是:
object(User)#4 (1) {
["id":"User":private]=>
string(7) "Dharman"
}
如您所见,代码使用后期静态绑定创建了 class 的实例,并且还将值分配给私有 属性,否则您无法这样做。
P.S。我的例子有点整洁。我添加了参数类型并删除了很多不必要的代码。特别是,我删除了空的 try-catch,这是一种糟糕的做法。