Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

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.