0

Example of mustache template:

{{#entites}}
  <a href="{{url}}">{{title}}</a>
{{/entities}}

Rendered by:

$m = new Mustache_Engine(
  ['loader' => new Mustache_Loader_FilesystemLoader('../views')]
);

echo $m->render('index', $data);

Basic nested array.

$data = [
   'entities' => [
       [
         'title' => 'title value',
         'url' => 'url value',
       ] 
    ]
];

This is rendered properly in template.

Array of objects of class:

class Entity 
{
  private $title;

  private $url;

  //setter & getters

  public function __get($name)
  {
      return $this->$name;
  }
}

Mustache argument:

$data = [
   'entities' => [
       $instance1
    ]
];

In this case not working - output is empty (no values from properties)

Codium
  • 3,200
  • 6
  • 34
  • 60
  • it is not clear what you are trying to do here, however, what is the error you are getting from your attempt? – hassan Sep 23 '18 at 14:37
  • @hassan no errors, just rendered properties are empty - {{url}} & {{title}} – Codium Sep 23 '18 at 14:41

2 Answers2

1

Instead of magic methods, why don't you use a function like this in the class

public function toArray()
{
    $vars = [];
    foreach($this as $varName => $varValue) {
        $vars[$varName] = $varValue;
    }

    return $vars;
}

then call that function to grab the variables as array

$data = [
   'entities' => $instance1->toArray()
];
  • `private` variables are available inside class instance only, So you either do as @Salvatore says or make your properties as `public`. Third option is to implement `JsonSerializable` interface which is simiar to this answer. – u_mulder Sep 23 '18 at 14:48
  • @u_mulder so no chance that __get($name) will work in this case? By implementing __get method I made them available outside. I've also getters. – Codium Sep 23 '18 at 14:49
  • 2
    `__get` will work when you __explicitly__ access a property. This means that you should write code similar to `'entities' => [['title' => $instance1->title, 'url' => $instance1->url]`. – u_mulder Sep 23 '18 at 14:50
  • @u_mulder ok, I thought that mustache can do it for me. Thanks – Codium Sep 23 '18 at 14:51
  • @u_mulder what about implementing ArrayAccess ? – hassan Sep 23 '18 at 14:59
  • @hassan not really sure how it helps here, I suppose it's just another variant of `__get()`. OP still has to write explicit access to properties to activate `ArrayAccess`. – u_mulder Sep 23 '18 at 15:02
  • @u_mulder I don't think that it need an explicit access to these properties to get it's values https://3v4l.org/HMi4g , however this is still need to be tested in the context of the Mustache – hassan Sep 23 '18 at 15:03
  • See updated fiddle - https://3v4l.org/GPu3l. OP passes instance to data array. I don't think that Mustache does anythin with this data, it just passes it to js as is, probably `json_encode`d. – u_mulder Sep 23 '18 at 15:08
  • Anyway I've switched to Twig, working out of the box – Codium Sep 23 '18 at 15:17
0

You can make a use of ArrayAccess Interface, to be able to access your private properties as follow:

class Foo implements ArrayAccess {
    private $x = 'hello';

    public $y = 'world';

    public function offsetExists ($offset) {}

    public function offsetGet ($offset) {
        return $this->$offset;
    }
    public function offsetSet ($offset, $value) {}
    public function offsetUnset ($offset) {}
}

$a = new Foo;

print_r($a); // Print: hello

Of course this is a trivial example, you need to add more business logic for the rest of the inherited methods.

hassan
  • 7,812
  • 2
  • 25
  • 36