假设我有这样一个简单的对象:
class User
{
public id;
public name;
public surname;
public gender;
public age;
}
在我的代码中,我想根据设置的属性为这样一个对象创建动态UPDATE语句。因此,我希望我的UPDATE(转移到数据库(只更改已更改的列。如果用户的某个属性未设置,则不应将该属性作为数据库列包含在UPDATE语句中。
例如,如果我创建User
对象并仅设置id
、name
和surname
(age
和gender
未设置(
$User=new User();
$User->id=1;
$User->name='Bob';
$User->surname='Geldof';
我的代码应该从这个对象创建UPDATE语句,如下所示:
UPDATE users SET name='Bob',surname='Geldof' WHERE id=1
问题是数据库中的列可能具有NULL值(例如age
(。在这种情况下,我应该能够在数据库中为该列设置null。在那里,我应该检查User对象属性是否明确设置为NULL。如果它被设置为NULL,那么UPDATE语句的结果应该是:
UPDATE users SET name='Bob',age=NULL WHERE id=1
但是没有办法测试属性是否设置为NULL值!
在这种情况下,我将属性设置为"NULL"字符串,并在代码中对其进行解析,以便在创建UPDATE语句时将"NULL"串转换为NULL值。
是否可以区分对象属性是否显式设置为NULL值(而不是"NULL"字符串(?
isset((不会有区别。
试试PHP的函数property_exists($user,'age')
请参阅:https://www.php.net/manual/en/function.property-exists.php
我不知道这里是否遗漏了什么,但你想要的答案似乎很简单。
- 如果任何变量显式设置为
NULL
,则可以使用is_null((: 您还可以使用property_exists(obj,property(检查属性是否存在
class User { public $id = 1; public $name = NULL; public $age; } $user = new User(); $isset = [ 'id' => isset($user->id), 'name' => isset($user->name), 'age' => isset($user->age), 'other' => isset($user->other)]; $isnul = [ 'id' => is_null($user->id), 'name' => is_null($user->name), 'age' => is_null($user->age), 'other' => is_null($user->other)]; $isprp = [ 'id' => property_exists($user, 'id'), 'name' => property_exists($user, 'name'), 'age' => property_exists($user, 'age'), 'other' => property_exists($user, 'other')]; var_dump($isset); /* array(3) { ["id"]=> bool(true) ["name"]=> bool(false) ["age"]=> bool(false) ["other"]=> bool(false) } */ var_dump($isnul); /* array(3) { ["id"]=> bool(false) ["name"]=> bool(true) ["age"]=> bool(true) ["other"]=> bool(true) // Also throws: "Notice: Undefined property: User::$other" } */ var_dump($isprp); /* array(3) { ["id"]=> bool(true) ["name"]=> bool(true) ["age"]=> bool(true) ["other"]=> bool(false) } */
然而,对于您文章的其余部分,这似乎毫无意义,因为您可能只需要省略您没有的值,并使用数据库的默认null选项(除非您的特定数据库出于某种原因不支持(。
您正在处理由类声明的属性,因此答案是"否";。
当您声明类属性而没有像这里所做的那样使用默认值初始化它们时,PHP在类的任何对象上都会将它们视为使用值NULL
声明的。没有办法区分。
最简单的解决方案是在SQLUPDATE
语句中包含所有属性,包括未更改的null。无论它通过省略它们为您节省了多少性能,每次都不值得像这样手动构建查询。