Skocz do zawartości
Pecetowicz Forum komputerowe

Undefined przy próbie odczytania klucza JSON


Rekomendowane odpowiedzi

Witam. Tworzę sobie taki "auto-downloader" dla mojego skryptu no i mam niemały problem. Wymyśliłem sobie, aby zrobić wyświetlanie ile z ilu MB zostało już pobrane.

Prawie się udało. Tzn. część kodu cURL w PHP, która odpowiada za przesyłanie tego typu informacji działa. Gorzej jest już z wyświetleniem tego na stronie. I to przez JS, ponieważ korzystam z Vue i Axios

Pobieranie danych nt. ilości MB

$curl = curl_init();
curl_setopt_array($curl, [
  CURLOPT_URL => $fileServer,
  CURLOPT_VERBOSE => 1,
  CURLOPT_RETURNTRANSFER => 1,
  CURLOPT_AUTOREFERER => FALSE,
  CURLOPT_PROGRESSFUNCTION => 'progress', //informacje o ilosci MB
  CURLOPT_NOPROGRESS => FALSE,
  CURLOPT_HEADER => 0
]);
$downloadResult = curl_exec($curl);
curl_close($curl);

Funkcja do zwracania ilości MB

function progress($resource, $download_size, $downloaded, $upload_size, $uploaded) {
    if($download_size > 0) {
        $progress = [
            'download_size' => $download_size,
            'downloaded' => $downloaded
        ];
        echo json_encode($progress);
        ob_flush();
        flush();
    }
}

Niby wszystko działa, ale nie do końca. W JS w momencie kiedy chcę odczytać np. "download_size"

console.log(resp.data.download_size)

zwraca undefined, ale kiedy usunę ten "klucz" - download_size

console.log(resp.data)

zwraca JSONa

obraz.thumb.png.55a372fccc9bc7d5a5d374642c144559.png

Tak wygląda w JS

obraz.png.7db16944119c2ecce9cf3d482c6a9e61.png

Nie wiem czy wszystko co jest potrzebne zamieściłem. Jak coś to mogę podesłać, ale proszę o pomoc, bo psycha siada 😄 Z góry dziękuję za wszystkie odpowiedzi ❤️

P.S. Odkryłem jeszcze, że jeśli nie będzie tego "klucza", czyli np. download_size, a po data dam jakiś numerek, np. [0] to zwraca pojedyncze znaki (ale nie wiem czy to normalne xD)

I nie wiem czy umieściłem to w dobrej kategorii, jeśli nie - prosiłbym o przeniesienie do odpowiedniej

Odnośnik do odpowiedzi
Udostępnij na innych stronach
  • Administrator

Jeśli dobrze widzę to w PHP zwracasz stringa, potem ten string jest przekazywany do funkcji JS i z niego próbujesz wyciągnąć obiekt - tylko że odpowiedź jaką dostajesz masz w stringu a nie obiekcie więc musisz sparsować odpowiedź i dopiero na niej działać.

Czyli finalnie powinno wyglądać to tak:

this.axios
.post('http://localhost/downloader/download.php', form),
.then(resp => {
  	resp = JSON.parse(resp);
	console.log(resp.data.download_size);
});

 

  • Lubię to! 2
Odnośnik do odpowiedzi
Udostępnij na innych stronach
  • Ekspert

W twoim przypadku resp.data to jest tablica. Jeżeli chcesz wyświetlić wszystkie dane to musisz zmapować tą tablice:

resp.data.map(el => {
  console.log(el.download_size);
});

 

16 minutes ago, ravenekse said:

P.S. Odkryłem jeszcze, że jeśli nie będzie tego "klucza", czyli np. download_size, a po data dam jakiś numerek, np. [0] to zwraca pojedyncze znaki (ale nie wiem czy to normalne xD)

To normalne, tak jak wyżej napisałem to jest tablica i jak dodasz [0] to zwróci Ci tylko pierwszą wartość tej tablicy.

  • Lubię to! 2
Odnośnik do odpowiedzi
Udostępnij na innych stronach

Niestety, ale nie działa 😞 Zwraca błąd w konsoli
obraz.thumb.png.85aa9fab63013fc9e5916fbd4ac9ae68.png

A w VSCode podkreśla resp: obraz.png.c0edb9d6d3fef5ba4c458b634c1722fd.png

21 godzin temu, aXenDev napisał:

W twoim przypadku resp.data to jest tablica. Jeżeli chcesz wyświetlić wszystkie dane to musisz zmapować tą tablice:

To niestety też nie działa. Zwraca błąd że resp.data.map nie jest funkcją

obraz.thumb.png.35dd3f2004497bc6b2b7954168b78979.png

Czy da się to jakoś inaczej rozwiązać w PHP aby od razu zwracało obiekt bez kombinacji w JS czy tak średnio?

Odnośnik do odpowiedzi
Udostępnij na innych stronach
  • Ekspert

A co się stanie, jeżeli zrobisz tak?

this.axios
  .post('http://localhost/downloader/download.php', form)
  .then(response => {
    let data = JSON.parse(response.data);

    data.map(element => {
      console.log(element.download_size || 0);
    });
  });
  • Lubię to! 1
Odnośnik do odpowiedzi
Udostępnij na innych stronach
  • Ekspert

Czyli nieprawidłowy JSON 😉 to co masz w zwrotce z PHP musisz opakować w array - bo to zbiór obiektów. I wtedy ten mój kod powinien ruszyć.

PS. W sumie pokaż ten kod tutaj, bo pewnie i tak podwalony z jakiegoś Open Source'a 😄 

  • Lubię to! 2
Odnośnik do odpowiedzi
Udostępnij na innych stronach
20 godzin temu, -n3veR napisał:

PS. W sumie pokaż ten kod tutaj, bo pewnie i tak podwalony z jakiegoś Open Source'a 😄 

Ze stacka xD https://stackoverflow.com/questions/13958303/curl-download-progress-in-php

Głównie to właśnie ta funkcja za to odpowiada:

function progress($resource, $download_size, $downloaded, $upload_size, $uploaded) {
    if($download_size > 0) {
        $progress = [
            'download_size' => $download_size,
            'downloaded' => $downloaded
        ];
        echo json_encode($progress);
        ob_flush();
        flush();
    }
}

 

Odnośnik do odpowiedzi
Udostępnij na innych stronach
  • Ekspert

Tak to się kończy jak się kopiuje coś bez zrozumienia, jak małpa... xD

Sprawdź co masz pod zmienną `$downloadResult`. Jak to nie jest to co myślę, to trzeba poprawić całego cURLa 😉 

Odnośnik do odpowiedzi
Udostępnij na innych stronach
  • Administrator

Problemem jest chyba to, że zwracasz co jakiś czas sam string z JSONem przez co finalnie masz kilka obiektów ale nie w tablicy więc w efekcie masz coś takiego:
 

{download_size:3653,downloaded:0}{download_size:3653,downloaded:0}{download_size:3653,downloaded:0}{download_size:3653,downloaded:0}

A poprawną wartością powinno być

[{download_size:3653,downloaded:0},{download_size:3653,downloaded:0},{download_size:3653,downloaded:0},{download_size:3653,downloaded:0}]

Czyli musisz wybrać:

- albo zwracasz jedną wartość będącą {download_size:3653,downloaded:0}

- albo przypisujesz wszystko co zwracasz w zmiennej $progress do tablicy przez co będzie to wyglądać tak:

[{download_size:3653,downloaded:0},{download_size:3653,downloaded:0},{download_size:3653,downloaded:0},{download_size:3653,downloaded:0}]

i dopiero encodować do JSONa i echo'wać

Odnośnik do odpowiedzi
Udostępnij na innych stronach
  • Ekspert

@Mativve nie chyba, a na pewno 😉 tylko jak skopiował bezmyślnie, to teraz niech się pomęczy z rozwiązaniem 😄 

Odnośnik do odpowiedzi
Udostępnij na innych stronach
  • Administrator

@-n3veR Od tego tutaj jesteśmy na forum, żeby pomóc - nawet jeśli ktoś wziął rozwiązanie z neta 😉

  • Przykro mi 1
Odnośnik do odpowiedzi
Udostępnij na innych stronach
14 minut temu, -n3veR napisał:

tylko jak skopiował bezmyślnie, to teraz niech się pomęczy z rozwiązaniem 😄

Tak, męczę się... Jakoś od rana 😉

 

W każdym razie, dziękuję za wszystkie odpowiedzi 🙂

Odnośnik do odpowiedzi
Udostępnij na innych stronach
  • Ekspert

Problem wciąż nierozwiązany? Dodaj swoją odpowiedź

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto. Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
×
×
  • Dodaj nową pozycję...