0

I'm working on a software in which models can have custom fields. This means using a user interface, customers can add and remove fields.

Now, I have a Customer class and I want to fill object values from associative array or JSON. Normally I would do is:

$customer = new Customer();

$customer->first_name = $firstName;
$customer->last_name = $lastName;
.....

What I want is to be able to do like this:

$data = array(
  "first_name" => $firstName,
  "last_name" => $lastName,
  ....
);

$customer = getCustomer($data);

and the getCustomer() method should not be dependent on number of entries in the array.

Is this doable in PHP?

I found something like this on searching:

$customer = (object)$data;

Is it correct?

Thanks

2 Answers 2

3

You can use __set and __get magic methods of PHP.

class Customer{

  private $data = [];

  function __construct($property=[]){
    if(!empty($property)){
      foreach($property as $key=>$value){
        $this->__set($key,$value);
      }
    }
  }  

  public function __set($name, $value){ // set key and value in data property       
      $this->data[$name] = $value;
  }

  public function __get($name){  // get propery value  
    if(isset($this->data[$name])) {
        return $this->data[$name];
    }
  }

  public function getData(){
    return $this->data;
  }

}

$customer = new Customer();
$customer->first_name = 'A';
$customer->last_name = 'B';

// OR

$data = array(
  "first_name" => 'A',
  "last_name" => 'B',  
);

$customer = new Customer($data);
echo '<pre>'; print_r($customer->getData());
$res = (object)$customer->getData();
echo '<pre>'; print_r($res);

Hope it will help you :)

Sign up to request clarification or add additional context in comments.

Comments

2

If getCustomer() function is intended as a global function for generating objects of Customer class, use the following approach:

  • encapsulate all passed customer's data within Customer class. Mark the "main" properties as private
  • declare setCustomerData() method which will be responsible for setting all customer's attributes
  • use privileged methods to "get" those attributes from client code

    function getCustomer(array $data) {
        $customer = new Customer();    
        $customer->setCustomerData($data);
    
        return $customer;
    }
    
    class Customer
    {
        private $first_name;
        private $last_name;
        // other crucial attributes
    
        public function setCustomerData(array $data) 
        {
            foreach ($data as $prop => $value) {
                $this->{$prop} = $value;
            }
        }
    
        public function getFirstName() 
        {
            return $this->first_name;
        }
    
        // ... other privileged methods
    
    }
    
    $data = array(
      "first_name" => "John",
      "last_name" => $lastName,
      ....
    );
    
    $customer = getCustomer($data);
    echo $customer->getFirstName();  // "John" 
    

3 Comments

Why wouldn't you just pass the data in the constructor? Also should check the values passed in to make sure they're allowed to be set by a user.
@miken32, Of course, in "real" production scheme the solution should be complemented and adjusted. I consider that no one should pass an "arbitrary" array into the object's constructor. We should pass into constructor the crucial and required object's attributes and dependent(service) objects. Imagine that someone is passing an array with 1000 elements into constructor in such case ... but the requied attributes list is comprised of 20 properties (e. g.)
So, there should be such considerations: "what the required attributes of my customer object ?" , "what is the allowable size of passed arbitrary array?", "should I create some PersonFactory class for generating such objects?"

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.