Solucionado (ver solução)
Solucionado
(ver solução)
12
respostas

Array de objetos e array de arrays no PHP

Oi, eu comecei a refatorar um código e parou de funcionar o código, eu encontrei um tutorial que lista uma playlist do Youtube, mas armazenando as listas em um array, eu não consigo mais acessar:

<?php 
             $api_key = 'chave';
             $idList = ['chave1','chave2'];
             $urlList = [];
                     forEach ($idList as $id) {
              $newUrl = 'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=3&playlistId='. $id . '&key=' . $api_key;
                                  array_push($urlList, $newUrl);
                            }                            
                            //print_r($urlList); 
                  $playlists = [];
                    forEach ($urlList as $url) {
                                  array_push($playlists, json_decode(file_get_contents($url)));
                            }
?>
  <?php 
                foreach($playlists->items AS $item):                                
                  ?>  
                            <li class="video-thumbnail"><a target="_blank" href='<?php echo 'https://www.youtube.com/watch?v='.$item->snippet->resourceId->videoId ?>'><img src="<?php echo $item->snippet->thumbnails->medium->url; ?>"></a></li>
                            <?php endforeach; ?>
                         </ul>                  

Erro:

Warning : Invalid argument supplied for foreach() in

Utilizando o comando print_r($playlists[0]), ele me devolve o exemplo abaixo e pode ver que tem [items] logo no inicio e quando eu tento print_r($playlists[0]->items) ele devolve um Array[0], só que eu não consigo ver mais depois disso print_r($playlists[0]->items->id), retorna um erro :

Fatal error : Uncaught Error: Cannot use object of type stdClass as array in C:\xampp\htdocs\wordpress

stdClass Object ( [kind] => youtube#playlistItemListResponse [etag] => "8jEFfXBrqiSrcF6Ee7MQuz8XuAM/qpJ1i01CgbJ7EDSRUfrWBYkAsi8" [nextPageToken] => CAMQAA [pageInfo] => stdClass Object ( [totalResults] => 414 [resultsPerPage] => 3 ) [items] => Array ( [0] => stdClass Object ( [kind] => youtube#playlistItem [etag] => "8jEFfXBrqiSrcF6Ee7MQuz8XuAM/CYibgFTGHxuRZFDi5mO0QEnI8wg" [id] => UEx4SXEyMUx1c3hYN3BGRzV2TTI0OFp3NEt4dHFtazhvZy5EODk5RTI0RkMzQ0M2NTA0 [snippet] => stdClass Object ( [publishedAt] => 2019-08-28T23:07:29.000Z [channelId] => UC5XG4yYM-_DQ-3HPRuam76Q [title] => Legalidade | Trailer Oficial [description] => Legalidade | Trailer Oficial Confira o trailer de #Legalidade Somos o melhor destino para quem busca trailers assim que eles são lançados. Se você é fã de cinema como a gente, INSCREVA-SE e receba todas as novidades dos seus filmes favoritos!

12 respostas

Coloquei em negrito o que eu acho que seja uma playlist, tem só uma parte, porque é muito texto. No exemplo do site ele coloca uma seta a mais:

 <?php 
         foreach($playlists->items AS $item): 
    ?> 
 print_r($playlists); 

Mostra:

Array ( [0] => stdClass Object ( [kind] => youtube#playlistItemListResponse [etag] => "8jEFfXBrqiSrcF6Ee7MQuz8XuAM/S3KLNzgKuqjpFo24o7jAFhd5Pd8" [nextPageToken] =>CAMQAA [pageInfo] => stdClass Object ( [totalResults] => 415 [resultsPerPage] => 3 )[items] => Array ( [0] => stdClass Object ( [kind] => youtube#playlistItem [etag] => "8jEFfXBrqiSrcF6Ee7MQuz8XuAM/JsTGgyVzZeHHnCsXPRNzir6medw" [id] => UEx4SXEyMUx1c3hYN3BGRzV2TTI0OFp3NEt4dHFtazhvZy5DMDQzQ0Y1OUU5Qjk1NjE1 [snippet] => stdClass Object ( [publishedAt] => 2019-08-30T16:00:56.000Z [channelId] => UC5XG4yYM-DQ-3HPRuam76Q [title] => O Exterminador do Futuro: Destino Sombrio | Trailer EXCLUSIVO Dublado [description] => O Exterminador do Futuro: Destino Sombrio | Trailer EXCLUSIVO Dublado Confira o novo trailer de #OExterminadorDoFuturoDestinoSombrio com #ArnoldSchwarzenegger e #LindaHamilton Somos o melhor destino para quem busca trailers assim que eles são lançados. Se você é fã de cinema como a gente, INSCREVA-SE e receba todas as novidades dos seus filmes favoritos! ► Baixe nossos apps: Android: https://goo.gl/ZOknfm iOS: https://goo.gl/hFbnMY ► Compre Ingressos para as melhores estreias em: https://www.ingresso.com ►Curta a Ingresso no FACEBOOK: https://goo.gl/E7qjwv [thumbnails] => stdClass Object ( [default] => stdClass Object ( [url] => https://i.ytimg.com/vi/rOQagrHWE2A/default.jpg [width] => 120 [height] => 90 ) [medium] => stdClass Object ( [url] => https://i.ytimg.com/vi/rOQagrHWE2A/mqdefault.jpg [width] => 320 [height] => 180 ) [high] => stdClass Object ( [url] => https://i.ytimg.com/vi/rOQagrHWE2A/hqdefault.jpg [width] => 480 [height] => 360 ) [standard] => stdClass Object ( [url] => https://i.ytimg.com/vi/rOQagrHWE2A/sddefault.jpg [width] => 640 [height] => 480 ) ) [channelTitle] => Ingresso.com [playlistId] => PLxIq21LusxX7pFG5vM248Zw4Kxtqmk8og [position] => 0 [resourceId] => stdClass Object ( [kind] => youtube#video [videoId] => rOQagrHWE2A ) ) ) [1] => stdClass Object ( [kind] => youtube#playlistItem [etag] => "8jEFfXBrqiSrcF6Ee7MQuz8XuAM/VLVGwqcBX2tu9e2uJJMWrZTYt8E" [id] => UEx4SXEyMUx1c3hYN3BGRzV2TTI0OFp3NEt4dHFtazhvZy5EODk5RTI0RkMzQ0M2NTA0 [snippet] => stdClass Object ( [publishedAt] => 2019-08-28T23:07:29.000Z [channelId] => UC5XG4yYM-DQ-3HPRuam76Q [title] => Legalidade | Trailer Oficial[description] => Legalidade | Trailer Oficial Confira o trailer de #Legalidade Somos o melhor destino para quem busca trailers assim que eles são lançados. Se você é fã de cinema como a gente, INSCREVA-SE e receba todas as novidades dos seus filmes favoritos! ► Baixe nossos apps: Android: https://goo.gl/ZOknfm iOS: https://goo.gl/hFbnMY ► Compre Ingressos para as melhores estreias em https://www.ingresso.com

Gisele, boa tarde!

Perceba que a array, possui 1 elemento, que está no index 0, isso aqui playlists->items não funcionaria pois na playlist em si não possui um index items, mas no primeiro index dele, ou seja playlist[0], ele sim possui um items podendo ser acessado por playlists[0]->items

Tente fazer um teste fazendo um:

print_r(playlists[0]->items)

Retorna isso:

Array ( [0] => stdClass Object ( [kind] => youtube#playlistItem [etag] => "8jEFfXBrqiSrcF6Ee7MQuz8XuAM/JsTGgyVzZeHHnCsXPRNzir6medw" [id] => UEx4SXEyMUx1c3hYN3BGRzV2TTI0OFp3NEt4dHFtazhvZy5DMDQzQ0Y1OUU5Qjk1NjE1 [snippet] => stdClass Object ( [publishedAt] => 2019-08-30T16:00:56.000Z [channelId] => UC5XG4yYM-_DQ-3HPRuam76Q [title] => O Exterminador do Futuro: Destino Sombrio | Trailer EXCLUSIVO Dublado [description] => O Exterminador do Futuro: Destino Sombrio | Trailer EXCLUSIVO Dublado Confira o novo trailer de #OExterminadorDoFuturoDestinoSombrio com #ArnoldSchwarzenegger e #LindaHamilton Somos o melhor destino para quem busca trailers assim que eles são lançados. Se você é fã de cinema como a gente, INSCREVA-SE e receba todas as novidades dos seus filmes favoritos! ► Baixe nossos apps: Android: https://goo.gl/ZOknfm iOS: https://goo.gl/hFbnMY ► Compre Ingressos para as melhores estreias em: https://www.ingresso.com ►Curta a Ingresso no FACEBOOK: https://goo.gl/E7qjwv [thumbnails] => stdClass Object ( [default] => stdClass Object ( [url] => https://i.ytimg.com/vi/rOQagrHWE2A/default.jpg [width] => 120 [height] => 90 ) [medium] => stdClass Object ( [url] => https://i.ytimg.com/vi/rOQagrHWE2A/mqdefault.jpg [width] => 320 [height] => 180 ) [high] => stdClass Object ( [url] => https://i.ytimg.com/vi/rOQagrHWE2A/hqdefault.jpg [width] => 480 [height] => 360 ) [standard] => stdClass Object ( [url] => https://i.ytimg.com/vi/rOQagrHWE2A/sddefault.jpg [width] => 640 [height] => 480 ) ) [channelTitle] => Ingresso.com [playlistId] => PLxIq21LusxX7pFG5vM248Zw4Kxtqmk8og [position] => 0 [resourceId] => stdClass Object ( [kind] => youtube#video [videoId] => rOQagrHWE2A ) ) ) [1] => stdClass Object ( [kind] => youtube#playlistItem [etag] => "8jEFfXBrqiSrcF6Ee7MQuz8XuAM/VLVGwqcBX2tu9e2uJJMWrZTYt8E" [id] => UEx4SXEyMUx1c3hYN3BGRzV2TTI0OFp3NEt4dHFtazhvZy5EODk5RTI0RkMzQ0M2NTA0 [snippet] => stdClass Object ( [publishedAt] => 2019-08-28T23:07:29.000Z [channelId] => UC5XG4yYM-_DQ-3HPRuam76Q [title] => Legalidade | Trailer Oficial [description] => Legalidade | Trailer Oficial Confira o trailer de #Legalidade Somos o melhor destino para quem busca trailers assim que eles são lançados. Se você é fã de cinema como a gente, INSCREVA-SE e receba todas as novidades dos seus filmes favoritos! ► Baixe nossos apps: Android: https://goo.gl/ZOknfm iOS: https://goo.gl/hFbnMY ► Compre Ingressos para as melhores estreias em https://www.ingresso.com ►Curta a Ingresso no FACEBOOK: https://goo.gl/E7qjwv [thumbnails] => stdClass Object ( [default] => stdClass Object ( [url] => https://i.ytimg.com/vi/H_C6zw5kmiA/default.jpg [width] => 120 [height] => 90 ) [medium] => stdClass Object ( [url] => https://i.ytimg.com/vi/H_C6zw5kmiA/mqdefault.jpg [width] => 320 [height] => 180 ) [high] => stdClass Object ( [url] => https://i.ytimg.com/vi/H_C6zw5kmiA/hqdefault.jpg [width] => 480 [height] => 360 ) [standard] => stdClass Object ( [url] => https://i.ytimg.com/vi/H_C6zw5kmiA/sddefault.jpg [width] => 640 [height] => 480 ) ) [channelTitle] => Ingresso.com [playlistId] => PLxIq21LusxX7pFG5vM248Zw4Kxtqmk8og [position] => 1 [resourceId] => stdClass Object ( [kind] => youtube#video [videoId] => H_C6zw5kmiA ) ) ) [2] => stdClass Object ( [kind] => youtube#playlistItem [etag] => "8jEFfXBrqiSrcF6Ee7MQuz8XuAM/qgeNjnn995tLGzVjbjQRZTzvw9U" [id] => UEx4SXEyMUx1c3hYN3BGRzV2TTI0OFp3NEt4dHFtazhvZy4yMUY5NzI2NUIwRDIyQUM4 [snippet] => stdClass Object ( [publishedAt] => 2019-08-28T21:29:18.000Z [channelId] => UC5XG4yYM-_DQ-3HPRuam76Q [title] => Deleted video

Ótimo! perceba que no retorno você possui uma chave chamada id que possui o valor:

UEx4SXEyMUx1c3hYN3BGRzV2TTI0OFp3NEt4dHFtazhvZy5DMDQzQ0Y1OUU5Qjk1NjE1

Sendo assim é possível acessa-lo com o código:

print_r(playlists[0]->items->id)

A partir disso você só precisa alterar os locais onde você itera sobre a array de forma a acessar esse dados usando o items, ficando o exemplo abaixo

Agora só é necessário passar pra todos os foreachs :D

Então isso que é estranho, não aparece nada na tela com isso:

 print_r($playlists[0]->items->id); 

Até o items aparece aquela lista gigante, senão não aparece nada.

Desse jeito apareceu, como eu faço o loop?

$playlists[0]->items[0]->id

Se fosse Javascript, já teria um [i], mas esse foreach funciona como?

Seria melhor fazer um for ao invés do foreach? Acabei deixando assim:

 <li class="video-thumbnail"><a target="_blank" href='<?php echo 'https://www.youtube.com/watch?v='.$playlists[0]->items[0]->snippet->resourceId->videoId ?>'><img src="<?php echo $playlists[0]->items[0]->snippet->thumbnails->medium->url; ?>"></a></li>
       <li class="video-thumbnail"><a target="_blank" href='<?php echo 'https://www.youtube.com/watch?v='.$playlists[0]->items[1]->snippet->resourceId->videoId ?>'><img src="<?php echo $playlists[0]->items[1]->snippet->thumbnails->medium->url; ?>"></a></li>
              <li class="video-thumbnail"><a target="_blank" href='<?php echo 'https://www.youtube.com/watch?v='.$playlists[0]->items[2]->snippet->resourceId->videoId ?>'><img src="<?php echo $playlists[0]->items[2]->snippet->thumbnails->medium->url; ?>"></a></li>

Gisele, boa tarde!

Agora é necessário iterar sobre essa array para não repetir código, assim a parte que você colocou acima ficaria assim

forEach($playlists as $playlist) {
    $videos = $playlist->items;
    forEach($videos as $video) {
        <li class="video-thumbnail">
            <a target="_blank"
               href="<?php echo 'https://www.youtube.com/watch?v=' . $video->snippet->resourceId->videoId ?>">
                <img src="<?php echo $video->snippet->thumbnails->medium->url; ?>">
            </a>
        </li>
    }
}

Claro que vão ser necessárias algumas alterações baseadas no seu código, mas dessa forma teremos uma boa refatoração!

Obrigada, talvez o foreach não seja a solução, porque eu precisava colocar o título de cada playlist antes da tag li e não deu certo, inseri o titulo depois do primeiro foreach, mas ele pula o primeiro item, porque começa a contar depois do primeiro laço, vou deixar do outro jeito mesmo ou vou tentar adaptar um for.

Ficou, pula o primeiro e não lista o último titulo:

<ul>
<h4>Esse fica vazio</h4>
<li></li>
</ul>
<ul>
<h4>Título video[0]</h4>
<li></li>
</ul>

O código a seguir lista as playlists, mas eu tive que abrir e fechar várias <?php para separar o html e o php.

 <?php forEach($playlists as $playlist) {
               $videos = $playlist->items;?>
               <ul class="youtube-lista">
                /*<h4><?php echo $video->snippet->title ?></h4>*/
                                <?php forEach($videos as $video) {?>                                                           
                                    <li class="video-thumbnail">
                                        <a target="_blank"
                                           href="<?php echo 'https://www.youtube.com/watch?v=' . $video->snippet->resourceId->videoId ?>">
                                            <img src="<?php echo $video->snippet->thumbnails->medium->url; ?>">
                                        </a>
                                    </li>                                   
                               <?php }?>
                               </ul>
                              <?php }?>  

Gisele, boa tarde!

Nossa que estranho! O foreach percorre TODOS os elementos da array, o fato dele "pular" o primeiro elemento não deveria ocorrer. Esse elemento de fato possui um titulo? Ou ele está público na playlist?

Então, o problema também é que eu acho que o titulo tá dentro do video, eu preciso ver se tem um titulo na playlist e não no video. Fica dentro do item e teria que ter um titulo fora do segundo loop, eu acho.

[title] => Bad Boys - Para Sempre | Trailer Dublado

se alguém precisar, olha o código da formatação:

print("<pre>".print_r($playlists,true)."</pre>")

Site: https://coderwall.com/p/ngnecw/pretty-print-array-php

Consegui formatar melhor os resultados do youtube:

Array
(
    [0] => stdClass Object
        (
            [kind] => youtube#playlistItemListResponse
            [etag] => "8jEFfXBrqiSrcF6Ee7MQuz8XuAM/u8Pg5gWB3gRXmI8tWWZ3aEpafFk"
            [nextPageToken] => CAMQAA
            [pageInfo] => stdClass Object
                (
                    [totalResults] => 420
                    [resultsPerPage] => 3
                )

            [items] => Array
                (
                    [0] => stdClass Object
                        (
                            [kind] => youtube#playlistItem
                            [etag] => "8jEFfXBrqiSrcF6Ee7MQuz8XuAM/W_s3rklYXIner1tygj1k1v3qTeo"
                            [id] => UEx4SXEyMUx1c3hYN3BGRzV2TTI0OFp3NEt4dHFtazhvZy5FRjUyQ0E2Mjc1QTg3NENC
                            [snippet] => stdClass Object
                                (
                                    [publishedAt] => 2019-09-04T19:08:09.000Z
                                    [channelId] => UC5XG4yYM-_DQ-3HPRuam76Q
                                    [title] => Bad Boys - Para Sempre |  Trailer Dublado
                                    [description] => Bad Boys - Para Sempre |  Trailer Dublado
solução!

Vou marcar como resolvido, porque acho que o meu problema é com a API do youtube, os resultados que ela passa. Mas o código PHP está correto e me ajudou a resolver meu problema sem o loop.