przekazanie zmiennej z PHP do JS

0

Potrzebowałem przekazać zmienną sesyjną do zmiennej w JS. Użyłem takiego kodu:

 <script>let login = <?php echo json_encode($_SESSION['login']); ?>;</script>

Działa, z poziomu konsoli widzę zmienną login. Ale dlaczego poniższy wariant nie działa? Wywala komunikat, że login nie jest zadeklarowane.

 <script>let login = <?php echo $_SESSION['login']; ?>;</script>
4

wejdź na swoją stronę, wybierz z menu "pokaż źródło" i zobacz, co ci się wygenerowało, bo przypuszczalnie generujesz nieprawidłowy kod JS.

<script>let login = <?php echo $_SESSION['login']; ?>;</script>

jak echujesz zmienną $_SESSION['login'] to do pliku JS trafia to bez cudzysłowu, więc JS nie będzie wiedział, że to string.

0

@kosmonauta80: A masz na tym etapie sesję i zmienną login już określoną ?
Zależy jak to jest położone w źródle, to tak lub nie

0

bo nie dodales na poczatku pliku php ze uzywasz sesji

2
kosmonauta80 napisał(a):

Potrzebowałem przekazać zmienną sesyjną do zmiennej w JS. Użyłem takiego kodu:

 <script>let login = <?php echo json_encode($_SESSION['login']); ?>;</script>

Działa, z poziomu konsoli widzę zmienną login. Ale dlaczego poniższy wariant nie działa? Wywala komunikat, że login nie jest zadeklarowane.

 <script>let login = <?php echo $_SESSION['login']; ?>;</script>

Próbowałem doklejać cudzysłów, ale efekt ten sam.

Wiesz, że musiałbyś dodać dwa cudzysłowy? I to takie, których nie ma w $_SESSION['login'].

<script>let login = "<?php echo $_SESSION['login']; ?>";</script>

albo

<script>let login = <?php echo "'" . $_SESSION['login'] . "'"; ?>";</script>

Ale tak serio, czemu nie chcesz użyć json_encode()?

Bo z tego co widzę, to:

  • Piszesz Potrzebowałem przekazać zmienną sesyjną do zmiennej w JS.
  • Nie wiesz, że nie da się przekazywać zmiennych z jednych języków do innych - najwyżej możesz przekazać dane.
  • Szukasz jakiegoś sposobu, żeby przekazać dane z jednego języka do drugiego, myśląc że można przekazać zmienne, więc chicałbyś jakiś "fajny" zapis.
    zmiennaJavaScript = $zmiennaPhp;
    
    ale czegoś takiego nie ma, i być nie może. Możesz próbować przekazać prymitywy (integer oraz string), ale z bardziej zaawansowanymi - zapominj.
  • To co faktycznie zrobiłeś w swoim kodzie, to wyrenderowałeś kod źródłowy jednego języka w drugim, a łączenie języków to nie jest prosta sprawa. Dużo rzeczy może się pomieszać, dużo rzeczy może pójść nie tak. Wrenderowanie danych do JS'a bez json_encode() jest dokładnie tym co może Ci narobić duuużo problemów.
  • Twoje wybory:
    • Jeśli chcesz zostać przy wrenderowaniu danych prosto w kod źródłowy innych języków, to json_encode() to jest najlepsza i najprostsza rzecz jaką możesz zrobić. Nadal to jest okropne rozwiązanie, ale jakieś. Pozbycie się json_encode() tylko Ci zaszkodzi.
    • Jeśli chciałbyś to zrobić, tak jak należy, powinieneś odseparować te języki programowania od siebie jak tylko się da. Trzymać je w osobnych plikach, i wymieniać dane między nimi tak jak się powinno czyli:
      • Jeden język wywołuje drugi (np kod z JS uruchamiający proces php)
      • Jeden język jest serverem drugiego (np Ajax z przeglądarki, przy użyciu fetch())
      • Jest jakiś trzeci język który pośredniczy pomiędzy nimi (np plik bash/cmd)
      • Oba języki korzystają ze wspólnego zasobu (np PHP renderuje tag <div data-name, a JS go odczytuje div.datasset).

Pomiędzy językami nie da się przekazać klas, funkcji, zmiennych ani nic takiego. Da się przekazać jedynie dane.

1

@kosmonauta80: Nie za bardzo rozumiem tego: "szukam argumentu za użyciem json_encode()...". Przykładowo:

$login = $_SESSION['login'];
echo json_encode($login); // zwróci "jakis_login";
echo '<br />';
echo $login;   // zwróci jakis_login

Różnica jest taka, że nie masz cudzysłowów w tym drugim przypadku.

2
kosmonauta80 napisał(a):

Potrzebowałem przekazać zmienną sesyjną do zmiennej w JS. Użyłem takiego kodu:

Czyli json_encode() dodaje za mnie cudzysłowy

leonpro778 napisał(a):

Tak, co jednak nie znaczy, że dla samych cudzysłowów należy go używać :)

Yyy, a skąd.

json_encode() tylko dodaje cudzysłowy, jeśli:

  • Twoja zmienna to jest string
  • Twoja zmienna nie ma w sobie cudzysłowów
  • Twoja zmienna nie ma w sobie żadnego backslasha
  • Twoja zmienna nie zawiera żadnego znaku Unicode
  • Twoja zmienna nie zawiera nowych liń, tabulatorów, i innych dziwnych rzeczy.

Jeśli Twój $_SESSION['login'] spełnia te kryteria, to nigdy byś nie zobaczył jak łączneie stringów może źle pójść ;) A pójść może bardzo źle.

To co na prawdę robi json_encode() to zwraca reprezentację JSON parametru, czyli innymi słowy jego JavaScript-Object Notation - zapis literału obiektu z JavaScript. Wrenderując dane w kod JavaScript, json_encode() jest tak konieczne, jak htmlEntities() dodając dane do HTML, lub mysql_real_escape_string() dodajć coś do SQL'a.

Jeśli chcesz zobaczyć czemu Twój zapis bez json_encode() się tragicznie rozjedzie, sugeruję dodać jakikolwiek "dziwny" znak, np cudzysłów, apostrof albo backslash ;)

To czemu json_encode() jest istotny, to:

  • Możesz wrenderować int, np json_encode(4), zwraca 4.
  • Możesz wrenderować tablicę, np json_encode(['1', '2'])
  • Możesz wrenderować obiekt, np json_encode(['key' => 'value'])
  • Również boolean, json_encode(true).
  • Wrenderują string, upewnisz się, że nie tworzysz jakiegoś frankensteina

Teraz wyobraź sobie, co by było, gdybyś nie korzystał z json_encode(), a jakiś użytkownikowi udałoby się ustawić login na string

"; alert("You have been hacked");

Książkowy XSS, który dodatkowo jest bardzo niebezpieczny.

3
kosmonauta80 napisał(a):

O generowaniu DIVa myślałem. Tylko to będzie wymagało więcej linijek JS

O nie!

Tylko nie poprawnie zaimplementowany front-end, który sam potrafi parsować dane i nie ma zależności z innego języka programowania! :O

A tak, serio, ile by Ci to zajęło? Mi napisanie tego całego kodu zajęło 3 minuty.

<html>
<body>
<?php
$mojeDane = [
    'login'     => 'my secret login',
    'firstName' => 'Maciek',
    'movies'    => [
        'Fight Club',
        'The Dark Knight'
    ],
    'grades'    => [
        'math' => 5,
        'art'  => 3
    ]
];
?>
<div class="main">
  <script type="application/json" id="session"><?= json_encode($mojeDane); ?></script>
</div>
<script>
  const session = JSON.parse(document.querySelector("script#session").innerHTML); // to jest ten Twój cały "więcej linijek JS"

  console.log("login: ", session.login);
  console.log("name: ", session.firstName);

  session.movies.forEach(movie => console.log("I like ", movie));

  console.log("grades (math)", session.grades.math);
  console.log("grades (art)", session.grades.art);
</script>
</body>
</html>
leonpro778 napisał(a):

@kosmonauta80: Nie za bardzo rozumiem tego: "szukam argumentu za użyciem json_encode()...". Przykładowo:

$login = $_SESSION['login'];
echo json_encode($login); // zwróci "jakis_login";
echo '<br />';
echo $login;   // zwróci jakis_login

Różnica jest taka, że nie masz cudzysłowów w tym drugim przypadku.

To spróbuj z login"\ łść ;)

echo 'login"\\ łść';
echo json_encode('login"\\ łść');

Wynik

login"\ łść
"login\"\\ \u0142\u015b\u0107"

Spróbuj oba wsadzić do JS, i zobaczyć który zadziała a który spowoduje syntax error ;)

0

@kosmonauta80: Tak jak @TomRiddle napisał powyżej - json_encode nie używa się do stawiania cudzysłowy dla stringa :) Ja tylko wskazałem Tobie czemu w jednym przypadku działało a w drugim nie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1