.load oublie les variable PHP

Par AminMe, il y a 11 ans


Hello

Contexte :

Voilà j'ai un projet web, avec un chat, le but est d'avoir accès à certaines fonctionnalités tel que son profil, des produits en vente etc ...

Objectif :

j'ai plusieurs pages product.php, profile.php, chat.php pour faire simple. J'ai souhaité migré tout dans une page index.php
Pourquoi ? Pour garder le chat en live (socket) je dois eviter à tout prix les refresh de page :).

Avec les includes en php pas de problèmes à vue d'oeil quand je passe par le .load en JQuery ça me fait des erreurs des php genre

Class Not Found $user undeclared

Solution essayés :

1 - Display none

Alors j'ai déjà pensé à faire dans mon index.php des

<!-- Dans index.php --> <?php <div id = "page"> include('product.php'); include('chat.php'); include('profile.php'); ?> </div>

et de passer 2 en display none et jouer avec le css pour afficher/ cacher les différentes pages.
Mais cette solution de ne me va pas car j'ai des parties de ma pages web que j'ai besoin de rafraichir à certains moment et si le load ne marche pas :/

2 - Jquery .load ou $.ajax

Comme je l'ai signalé au dessus je me retrouve avec des erreurs php, des includes qui sont fait dans mon index.php ne sont pas répercuté dans les sous pages.
Quand je fait $('#pages').load('product.php'); ça ne charge pas les includes et les script inclus dans index.php.

Y a t-il une solution à ce problème (sans passer par les GET & POST pour passer les variables) ?

Je tiens à remercier d'avance ceux qui participeront au sujet.

24 réponses

betaWeb, il y a 11 ans

Yop !

Alors déjà commence par corriger ton code dans "index.php":

<!-- Dans index.php --> <div id = "page"> // Cette balise était était l'ouverture de PHP, pas bon <?php include('product.php'); include('chat.php'); include('profile.php'); ?> </div>

Et sinon, lorsque tu es sur ta page de chat, tu es sur index.php ou non ? Ce n'est pas très clair ton histoire.

AminMe, il y a 11 ans

Oups effectivement mais c'était un exemple :)

Alors je suis en continue sur index.php et je charge dynamiquement le contenu de chat.php, profile.php et product.php. Mon url est toujours site/index.php

betaWeb, il y a 11 ans

Montres voir le contenu de ton JS ?

AminMe, il y a 11 ans

Mon app.js

function refresh(link) { $('#pages').load(link); }

Mon index.php (preview)

<?php include ("classes/classes.php"); //contient classe Database session_start(); $user = $_SESSION['user']; ?> ... <li class="mt"> <a class="active" onclick=refresh('product.php')> <span>Produits</span> </a> </li>

Quand je clique sur le lien Produits ça me dit

Class Database Not Found $user undeclared
betaWeb, il y a 11 ans

Bah voilà tu as ta réponse, il te faut chercher de ce côté là.
Google est ton ami !

AminMe, il y a 11 ans

C'est ce que j'ai déjà fait, après avoir parcouru 10 conversation de stackeoverflow et des tutoriels je n'ai pas eu ma réponse d'ou mon arrivé ici.
J'ai appris que php était chargé bien avant tout et donc les variables php était inconnu par la suite par le js.

Surement je n'ai pas tapé les bon mots-clés :D

betaWeb, il y a 11 ans

Beh en chargeant index.php il te faut déjà avoir déclaré yes variables et instancié les classes dont tu as besoin oui.
Tu fais ça où normalement ?

AminMe, il y a 11 ans

Alors je me suis mal exprimé toutes mes variables sont instanciés dans index.php tout en haut du code. Au dessus de tout.
les sous fichiers product.php chat.php profile.php font appel à ces variables.

lors de l'appel d'un include ('profile.php'); dans l'index.php pas de probleme car il va absorbé le code dans profile.php et l'injecter dans index.php et du coup dans profile.php si je fait echo $user;tout se passe bien. avec le load en JQuery non ça va me dire user not declared

betaWeb, il y a 11 ans

Alors ce qu'il te faut faire, c'est au lieu d'un $.load() utiliser un $.ajax(). De cette manière tu vas pouvoir injecter ton contenu HTML généré par le script PHP (produits.php par exmple) dans ta page courante. Alors attention il y a une petite spécificité, il faut "echo" ton contenu en fin de script PHP afin que ton ajax puisse le récupérer et l'afficher. Tu me suis ?

AminMe, il y a 11 ans

Alors j'avais utilisé un $.ajax() : mais pas de la bonne manière.

function refresh(link) { //$('#pages').load(link); $.ajax({ url: link, success: function(html) { $("#pages").html(html); } }); }

Il faut que je echo ou en fait dans chaque sous pages (product, chat, profile) ou dans index.php ?

betaWeb, il y a 11 ans

Pour la partie JS:

function refresh(link, target) { // target correspond au bloc dans lequel tu vas injecter le contenu HTML //$('#pages').load(link); $.ajax({ url: link, data: { 'ajax': '1' }, // On envoie une variable histoire de vérifier si le script PHP est appelé en AJAX method: 'post', dataType: 'html', success: function(response) { if (0 === response.length) { alert('Erreur lors du chargement du contenu'); return false; } $(target).empty().prepend(response); // OU (c'est pareil) $(target).html(response); } }); // Ou tu peux aussi utiliser la mixin $.post() qui fait la même chose $.post(link, { 'ajax': '1' }, function(response){ if (0 === response.length) { alert('Erreur lors du chargement du contenu'); return false; $(target).empty().prepend(response); // OU (c'est pareil) $(target).html(response); }); }

En fin de script PHP:

/* Traitements PHP + Génération de ton HTML (pour lequel je te conseille d'utiliser les fonctions ob_start() et ob_get_clean() ) */ // Fin du script si appelé via ajax if (isset($_POST['ajax']) && 1 == $_POST['ajax']) { die($html); // On coupe l'execution ici en affichant le contenu de la variable $html, en l'occurrence ton contenu } return $html; // Fin du script si non appelé via ajax

Si tu as des questions n'hésites pas ;)

AminMe, il y a 11 ans

Si j'ai bien compris si je transforme toutes ma page php en une string il n'y aura plus de problème.

J'ai cherché sur le net mais faire des echo avec plein de concaténations, à toutes les lignes c'est la seul solution ?

j'ai essayer de faire

$html = <<<EOD

mais je n'ai pas l'impression que ça marche très bien


De plus quand je fait un test à la main du style :

$("#pages").empty().prepend('<p>test</p><?php echo "aie"; echo "hello : ".$user; ?>');

sur la page ça ne m'affiche que test, le php est mis en commentaire

betaWeb, il y a 11 ans

En même temps si tu mets du PHP dans un JS ça ne risque pas de fonctionner !
De plus, il y a la concaténation oui, mais ce n'est pas très propre si le HTML généré est conséquent. Il vaut mieux utiliser ob_start() et on_get_clean():

<?php // Début du script php $html = ""; ob_start(); ?> // Génération de ton contenu HTML (SANS echo justement) // Exemple: <h1><?= $titre ?></h1> <?php if (!empty($nom)) : ?> <p><?= $nom ?></p> <?php endif; ?> <p><?= $contenu ?></p> <ul> <?php foreach ($liste as $entry) : ?> <li><?= $entry ?></li> <?php endforeach; ?> </ul> // !Exemple (ce n'est qu'un exemple) <?php $html = ob_get_clean(); // Traitements PHP éventuels // Fin du script si appelé via ajax if (isset($_POST['ajax']) && 1 == $_POST['ajax']) { echo $html; return false; } return $html; ?>

Comme tu peux le voir, on met le HTML en "dur" entre les balises ob_start() & ob_get_clean().

AminMe, il y a 11 ans

Ah d'accord.

Néamoins j'ai toujours la même erreur Notice: Undefined variable: user in Project/test.php on line 7 je dois m'y prendre mal :

Avant tout j'ai une question <h1><?= $user ?></h1> c'est normal que la balise commence par <?= ? j'ai essayé avec la balise d'ouverture php ça ne fonctionne pas non plus.

<?php // Début du script php $html = ""; ob_start(); ?> <h1><?= $user ?></h1> <?php $html = ob_get_clean(); // Traitements PHP éventuels // Fin du script si appelé via ajax if (isset($_POST['ajax']) && 1 == $_POST['ajax']) { echo $html; return false; } return $html; ?>

Je suis assez sur que la variable $user est défini :) dans index.php

<?php include ("classes/classes.php"); session_start(); //$user = $_SESSION['user']; if(!array_key_exists('user',$_SESSION)){ header("Location:login.php"); exit; } else { $user = $_SESSION['user']; // affichage de index.php ?>
betaWeb, il y a 11 ans

Bien sûr que c'est normal, "<?=" c'est le raccourci pour echo ;)

Eh beh fais un petit var_dump() de $_SESSION voir ce qu'il contient. Peut être que ta fonction login ne rempli pas correctement l'array $_SESSION ?

AminMe, il y a 11 ans

var_dump() me donne

array (size=1) 'user' => string 'test@test.fr' (length=XX)

j'ai juste caché la length. mais sinon ça marche très bien ma session est bien rempli.

On récapitule pour voir si on n'est pas parti sur un quiproco

index.php Déclaration des variables $user etc ...+ appel de la fonction ajax refresh() pour injecter les pages product, chat, profile dans la page index.php app.js contient la fonction refresh pour appeler les sous fichiers product, chat, profile product.php, chat.php, profile.php appel la variable $user déclaré dans index.php + ob_start() et ob_get_clean()
betaWeb, il y a 11 ans

Tu as un session_start(); au début de chaque script PHP ?

AminMe, il y a 11 ans

non j'ai rien mis pour le moment

on retrouve ces 2 lignes

include ("classes/classes.php"); session_start();

seulement dans index.php

betaWeb, il y a 11 ans

alors remets ces deux lignes au début de tous tes scripts PHP et ré-essaye.

AminMe, il y a 11 ans

J'ai essayé mais ça ne change rien :/

on va faire un cas de figure simple (oublions les includes + session_start). c'est censé marcher ?
moi je veux que cette chose marche xD

index.php

<?php $user = 'toto'; ?> <div id="pages"> <a class="active" onclick=refresh('chat.php')>chat</a> </div>

chat.php

<?php ob_start(); ?> <?= $user ?> <?php $html = ob_get_clean(); // Traitements PHP éventuels // Fin du script si appelé via ajax if (isset($_POST['ajax']) && 1 == $_POST['ajax']) { echo $html; return false; } return $html; ?>

app.js

function refresh(link) { $.ajax({ url: 'test.php', data: { 'ajax': '1' }, // On envoie une variable histoire de vérifier si le script PHP est appelé en AJAX method: 'POST', type : 'POST', dataType: 'html', success: function(html) { if (0 === html.length) { alert('Erreur lors du chargement du contenu'); return false; } $("#pages").empty().prepend(html); // OU (c'est pareil) //$("#product-part").html(html); } });
betaWeb, il y a 11 ans

Le soucis c'est que ta variable $user est déclarée dans ton index.php, mais non dans chat.php, donc tu ne peux potentiellement pas l'utiliser dans ce script.
Deuxièmement, pourquoi veux-tu injecter le contenu dans ta balise ayant l'id #pages alors que vraisemblablement celle-ci contien les liens permettant l'appel des pages (donc en gros ton menu) ??

index.php

<?php $infos = ['user' => 'toto']; ?> <div id="menu"> <a class="active" class="pages" data-page="chat" data-infos="<?= json_encode($infos) ?>">chat</a> </div> <div id="pages"></div>

app.js

function refresh(pagename, infos) { $.ajax({ url: pagename + '.php', data: { 'ajax': '1', 'infos': infos }, // On envoie une variable histoire de vérifier si le script PHP est appelé en AJAX method: 'POST', type : 'POST', dataType: 'html', success: function(html) { if (0 === html.length) { alert('Erreur lors du chargement du contenu'); return false; } $("#pages").empty().prepend(html); // OU (c'est pareil) // $("#pages").html(html); } }); } $('#menu').on('click', 'a', function(e){ e.preventDefault(); var self = $(this), page = self.data('page') || self.attr('data-page'), infos = self.data('infos') || self.attr('data-infos'); refresh(page, infos); return false; });

chat.php

<?php $infos = json_decode($_POST['infos'], true); ob_start(); ?> <?php $html = ob_get_clean(); <p><?= $infos['user']; ?></p> <?php $html = ob_get_clean(); // Fin du script si appelé via ajax if (isset($_POST['ajax']) && 1 == $_POST['ajax']) { echo $html; return false; } return $html; ?>

Ca devrait NORMALEMENT fonctionner.

AminMe, il y a 11 ans

C'était un exemple. Je n'ai pas mis de menu à proprement dit dans l'exemple. Mais effectivement tu as raison.

Petit problème ma page chat.php utilise app.js pour d'autres raisons. Quand je fait donc un clique sur ma page chat tout s'affiche correctement mais les boutons ne répondent plus au app.js.

Alors qu'avant si, une action était enclenché.

AminMe, il y a 11 ans

Bon je reviens sur le sujet

Au final j'ai changé de stratégie, je ne savais pas que je pouvais sérialiser en JSON les sockets et les faire passer dans le sessionStorage (ou localStorage) du coup ça m'aide à garder une variable de socket en continu.

Merci de m'avoir aidé tout de même :D !

betaWeb, il y a 11 ans

Oh je t'en prie, content que tu aies solutionné ton problème. Effectivement le sessionStorage est une solution (que j'utilise régulièrement dans mes apps JS), mais il ne faut pas en abuser et faire attention à la sécurité car tu vas stocker des infos user côté client et non côté serveur.