0

In PHP, I have a product object that contains a collection of attributes. json_encode produces this:

{"id":"123","name":"abc","attributes":{"attributes":[{"key":"sku","value":"xyz"}]}}

"attributes" listed twice is redundant. What's the best way of structuring object collections so that the json is clean?

class Product {

    public $id;
    public $name;
    public $attributes;

    public function __construct()
    {
        $this->attributes = new Attributes();
    }

    public function get($id)
    {
        $this->id = "123";
        $this->name = "abc";
        $attribute = new Attribute("sku", "xyz");
        $this->attributes->add($attribute);
    }
}

class Attributes
{
    public $attributes;

    public function __construct()
    {
        $this->attributes = array();
    }

    public function add($attribute)
    {
        array_push($this->attributes, $attribute);
    }
}

class Attribute
{
    public $key;
    public $value;

    public function __construct($key, $value)
    {
        $this->set($key, $value);
    }
}

2 Answers 2

1

I would just use an associative array.

class Product {
...
    public $attributes=array();
    ...
    public function get($id)
    {
        ...
        $this->attributes["sku"]="xyz";
        $this->attributes["foo"]="bar";
    }
}

json_encode() should produce something like this:

{"id":"123","name":"abc","attributes":{"sku":"xyz","foo":"bar"}}

OR using variable variables:

class Attributes
{
    public function add($key,$value)
    {
        $this->{$key}=$value;
    }
    public function drop($key)
    {
        unset($this->{$key});
    }
}

$a=new Attributes();
$a->add('sku','xyz');
$a->add('foo','bar');
echo json_encode($a).'<br>';
$a->drop('sku');
echo json_encode($a).'<br>';

Output:

{"sku":"xyz","foo":"bar"}
{"foo":"bar"}
Sign up to request clarification or add additional context in comments.

3 Comments

This would work in this specific case. However, this is a simplified version of a bigger picture. Better for us to stay with objects/collections and figure out a custom json output.
It's hard to say without knowing your specific requirements. I've added a way to implement the Attributes class using variable variables. It isn't completely compatible with your Attributes class in that it won't allow multiple attributes with the same key.
Digging deeper. The way json_encode encodes objects/collections by default is good. Attributes is our exception and this is a good solution until we upgrade to PHP 9.4.
1

You can give your classes a custom json encoding format by implementing JsonSerializable.

In your case you'll just need to have Attributes implement that and give it a jsonSerialize method which returns $this->attributes.

1 Comment

Good solution. However, only available on PHP 5.4 and we're on 5.3.

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.