1

Let's say that I have the simple object like this:

class User
{
  public id;
  public name;
  public surname;
  public gender;
  public age;
}

In my code I want to create dynamical UPDATE statement for such an object according to properties that were set. So I want my UPDATE to (transfer to the database) and change only columns that were changed. If one of user's properties is unset, this property should not be included as db column in UPDATE statement.

For example, if I create User object and set only id, name and surname (age and gender leave unset)

$User=new User();
$User->id=1;
$User->name='Bob';
$User->surname='Geldof';

from this object my code should create UPDATE statement like this:

UPDATE users SET name='Bob',surname='Geldof' WHERE id=1

The problem is when a column in database can have NULL values (like age for example). In this case I should be able to null this column in database. There I should check if User object property is explicitly set to NULL. If it is set to NULL then UPDATE statement should result with:

UPDATE users SET name='Bob',age=NULL WHERE id=1

But there's no way to test if the property is set but set to NULL value!

At the moment in such a case I set property to 'NULL' string and parse it in my code to translate 'NULL' string into NULL value in creating UPDATE statement.

Is it possible to distinguish if object property is explicitly set to NULL value (not 'NULL' string)?

4 Answers 4

1

Use ReflectionProperty and its isInitialized() method

$object = new A;
$rp = new ReflectionProperty($object, 'property_name');
$rp->isInitialized($object); // returns true if initialized, even if null
Sign up to request clarification or add additional context in comments.

Comments

0

I don't know if I'm missing something here but it seems that the answer you're looking for is pretty straightforward.

  • You can check any variable if it's explicitly set to NULL by using is_null():
  • You can also check if a property exists at all by using 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)
    }
    */
    

However regarding the rest of your post, it seems pretty pointless, as you probably can just omit values that you don't have and use database's default null option (unless your particular db doesn't support that for some reason).

5 Comments

That's not what I want. If I only wanted to change the name your code would null age of my user!!! The age should stay intact.
@sbrbot No, it would not. Please update your post with information what it is that you want then. Right now it answers your question: "How to check if object's property is explicitly set to NULL". I'm not a mind reader, and my code is just an example of how you can check if object's property is set to null as per your request.
Try $user = new User(1,'John'); and $user = new User(1, 'John',NULL); and you'll get the same result - isset will not detect whether you set your property to null or not!
@sbrbot And as I can clearly see it doesn't mean much. Look, I'm trying to help you out, you don't need to be rude. By doing $user = new User() you're creating an instance of a class. That instance is now an object that inherits given class properties and methods. If you update that object's property it will not tinker with any other properties, you're confusing object creation with updating it. Furthermore isset() will return true if property is set but not NULL, false otherwise; is_null() will return true if property is NULL, false otherwise (and that's the answer to your question).
@sbrbot If you could present some kind of a real input - output pipeline of your particular case, then maybe I can provide you with some better solution to the actual problem you're facing, right now I don't understand what you really trying to achieve here, but I answered your question and the answer is correct. If you're facing possible non-existing properties you can also use property_exist(obj, prop) which is similar to isset() but returns true even if property is NULL.
0

You are dealing with properties declared by your class, so the answer is "No".

When you declare class properties without initialising them with default values as you've done here, PHP treats them, on any object of the class, exactly as though they were declared with value NULL. There is no way to tell the difference.

The simplest solution is just to include all the properties in your SQL UPDATE statement, including the unchanged nulls. Whatever tiny sliver of performance it saves you by omitting them, it's not worth the faff of manually building your query like this each time.

Comments

-1

isset() does not differ if property is set to NULL or it is unset.

Try PHP's function property_exists($user,'age')

See: https://www.php.net/manual/en/function.property-exists.php

1 Comment

This is incorrect. Because age is declared as a property in the User class definition, then property_exists($user,'age') will always return true - even if you've manually done unset($user->age).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.