我有这个对象从mongodb查询
object(stdClass)#22 (9) {
["_id"]=>
object(MongoDB\BSON\ObjectID)#19 (1) {
["oid"]=>
string(24) "56639b2aa18994f5398b4567"
}
["Title"]=>
string(76) "Example movie ..."
["ID"]=>
string(10) "abc12345"
["Code"]=>
string(8) "123456"
["Released"]=>
string(10) "2015-11-27"
["Length"]=>
string(10) "300 min(s)"
["Poster"]=>
string(64) "http://example.net/84orea005pl.jpg"
["Episodes"]=>
object(stdClass)#21 (1) {
[1]=>
object(stdClass)#20 (1) {
["URL"]=>
string(38) "http://example.net/movie.e1.m3u8"
}
}
["View"]=>
int(31)
}
通过树枝渲染
twig->render('movie.html',array('movie' => $movie));
我可以通过{{movie.Title}},{{movie.ID}}轻松访问标题,ID ... 然而,当我使用for循环遍历movie.Episodes时,我似乎无法从中获取任何东西。
{{ dump(movie.Episodes) }}
返回
object(stdClass)#21 (1) {
[1]=>
object(stdClass)#20 (1) {
["URL"]=>
string(38) "http://example.net/movie.e1.m3u8"
}
}
但
{% for episode in movie.Episodes %}
testing
{{ dump(episode) }}
{% endfor %}
返回空,它甚至不循环。 所以,我的问题是如何使用twig获取电影剧集的URL?
答案 0 :(得分:0)
看起来Twig不知道如何处理StdClass,尤其是在嵌套时。我之前遇到过嵌套StdClass的问题(使用SoapClient)。我使用以下函数将嵌套的StdClass转换为嵌套数组,这些数组更容易处理,Twig会理解......
function objectToArray($data) {
if (is_object($data))
$data = get_object_vars($data);
if (is_array($data))
return array_map(__FUNCTION__, $data);
return $data;
}
在将数据传递给Twig之前,您需要在数据(StdClass)上调用它。
(注意这个函数在array_map
中递归调用自己以获得所有嵌套的StdClass)
答案 1 :(得分:0)
虽然PHP中的每个对象都是“可迭代的”,但并非所有对象都使用for循环“遍历”(参见http://php.net/manual/en/class.traversable.php)。
根据定义,数组是可遍历的,但不是stdClass
对象。
var_dump(new stdClass() instanceof Traversable);
将产生:
bool(false)
我只能建议您将已转换的$movie
var传递给TWIG,其Episodes
密钥为array
而不是stdClass
。
这可以通过@BareNakedCoder
或者,如果您想更好地操作对象以获得更多功能,最好使用Movie
中的参数传递的stdClass
电影对象构建一个新的__construct()
类
class Movie
{
public $id;
public $oid;
public $code;
public $title;
public $released;
public $length;
public $poster;
public $views;
/** @var Episode[] $episodes */
protected $episodes = [];
function __construct(stdClass $object = null)
{
if (!is_null($object)) {
$this->oid = $object->_id->oid;
$this->id = $object->ID;
$this->code = $object->Code;
$this->title = $object->Title;
$this->released = $object->Released;
$this->length = $object->Length;
$this->poster = $object->Poster;
$this->views = $object->View;
foreach(get_object_vars($object->Episodes) as $ep)
$this->episodes[] = new Episode($ep);
}
}
public function getEpisodes()
{
return $this->episodes;
}
}
class Episode
{
public $url;
function __construct(stdClass $object = null)
{
if (!is_null($object))
$this->url = $object->URL;
}
}
您的渲染线将是:
twig->render('movie.html', ['movie' => new Movie($movie)]);
以下是您在TWIG环境中的对象:
object(Movie)#5 (9) {
["id"]=>
string(8) "abc12345"
["oid"]=>
string(24) "56639b2aa18994f5398b4567"
["code"]=>
string(6) "123456"
["title"]=>
string(17) "Example movie ..."
["released"]=>
string(10) "2015-11-27"
["length"]=>
string(10) "300 min(s)"
["poster"]=>
string(34) "http://example.net/84orea005pl.jpg"
["views"]=>
int(31)
["episodes":protected]=>
array(1) {
[0]=>
object(Episode)#6 (1) {
["url"]=>
string(32) "http://example.net/movie.e1.m3u8"
}
}
}
循环剧集没问题
{% for episode in movie.getEpisodes() %}
<br>{{ episode.url }}
{% endfor %}
这个新的Movie
/ Episode
类在此示例中非常简单,但您现在可以添加新函数来操作数据,这些方法也可以从TWIG模板中调用。
答案 2 :(得分:0)
在将数据传递到树枝之前,请尝试以下操作:
$data_to_twig = json_encode($your_data);
$data_to_twig = json decode($data_to_twig, true); // the parameter "true" will convert all child objects including stdClass objects to array