étendre la portée de la variable de connexion

Eléphanteau du PHP | 10 Messages

22 mars 2015, 21:02

Bonjour,

pour éviter des messages d'erreur du style "Call to a member function prepare() on a non-object" ou "Cannot redeclare class MyPdo", mon idée est de me connecter une seule fois à MySQL dans le fichier principal et de déclarer la variable comme globale :
<?php
error_reporting(E_ALL ^ (E_NOTICE|E_WARNING|E_DEPRECATED));
global $bdd;

include dirname(__DIR__)."\pdo\connect_mysql.php";
if ((!isset($bdd)))
	$bdd=connect_mysql();
...
?>
Mon problème est que dans un fichier inclus dans un autre fichier que le fichier principal, je déclare aussi $bdd en global, mais si j'y fais un var_dump($bdd), la variable est nulle...Comment ça se fait ?

Mammouth du PHP | 688 Messages

22 mars 2015, 21:34

c'est pareil sans le
global $bdd;
présent dans le code présenté ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

22 mars 2015, 22:30

Le mot clé global s'utilise au sein d'une fonction afin d'indiquer que les variables concernées font références aux variables correspondantes de portée globale. En gros, il permet d'utiliser des variables externes à la fonction comme si celles-ci étaient à l'intérieur.

A priori, dans ton cas, le fait de déclarer la variable $bdd a pour effet de la définir avec une valeur null. La fonction isSet() retourne alors vrai puisque la variable est trouvée. Tu peux utiliser empty() qui a pour effet de tester non seulement la présence de la variable (isSet) mais va également vérifier que celle-ci contient une valeur non nulle, non vide, non false et différente de 0.
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 10 Messages

22 mars 2015, 22:51

Si j'enlève partout la déclaration "global", pareil, et j'ai aussi remplacé !isset par empty et pareil aussi... :(

Mammouth du PHP | 2278 Messages

23 mars 2015, 08:48

Voici, par exemple, index.php
<?PHP
	include ("connect.php");
	$bdd = connect();
	var_dump ($bdd);
print "<a href = 'chose.php'>aaaa</a>";
?>
et conect.php
<?PHP
function connect()
{
	$bidule = $mysqli = mysqli_init();
	if (!$bidule)
	{ 
		return False;
	}
	else
	{
		$truc = mysqli_real_connect($bidule, 'localhost', 'root', '', 'lexique');
		if (!$truc)
		{		
			return FALSE;
		}
		else
		{
			return $truc;
		}
	}
}
?>
Effectivement chose.PHP NE CONNAIT PAS $bdd. Passer par Session ou par Post ou GET?
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Eléphanteau du PHP | 10 Messages

23 mars 2015, 08:58

les "grands" esprits se rencontrent :wink: car j'avais justement l'idée de passer par une session (et comptais essayer ce matin) ; mais pourquoi déclarer $bdd en variable globale ne marche pas ?

Mammouth du PHP | 2278 Messages

23 mars 2015, 10:42

Ca marche d'un fichier inclus à un autre qui l'inclut; plus exactement entre une fonction et le script qui l'appelle (cf http://php.net/manual/fr/language.variables.scope.php) puisque les variables des fonctions sont par défaut locales et que les variables déclarées en-dehors de la fonction lui sont inconnues
<?PHP
	include ("connect.php");
	$bdd= NULL;//peut être supprimé
	connect();
	var_dump ($bdd);
print "<a href = 'chose.php'>aaaa</a>";
?>
<?PHP
function connect()
{
global $bdd;
	$bidule = $mysqli = mysqli_init();
	if (!$bidule)
	{ 
		return False;
	}
	else
	{
		$bdd = mysqli_real_connect($bidule, 'localhost', 'root', '', 'lexique');
		if (!$bdd)
		{		
			return FALSE;
		}
		else
		{
			print "ok";
		}
	}
}
?>
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Eléphanteau du PHP | 10 Messages

23 mars 2015, 12:04

Je ne comprends pas pourquoi déclarer en global ne marche pas, vu que ce que tu expliques porte sur les variables locales...

Je viens d'essayer de passer par une variable de session mais ça ne marche pas :(

Voici ce que j'ai fait :

indexpage.php (fichier principal) :
<?php
session_start();
error_reporting(E_ALL ^ (E_NOTICE|E_WARNING|E_DEPRECATED));
//global $bdd;

include dirname(__DIR__)."\pdo\connect_mysql.php";
if ((empty($bdd))) {
	$bdd=connect_mysql();
	}
...
connect_mysql.php :
<?php
session_start();
//global $bdd;
header('Content-type: text/html; charset=UTF-8');
//// connexion
function connect_mysql() {
include_once (dirname(__DIR__).'\pdo\new\MyPdo.php');

try{
				$bdd = new MyPdo();
				$_SESSION['bdd']=$bdd;
				return($bdd);
			}
catch(PDOException $e){
				echo "argggggggggggggg".$e->getMessage();
				return(FALSE);
			}
}
		
?>
MyPdo.php :
<?php
error_reporting(E_ALL ^ E_DEPRECATED ^ E_NOTICE);
ini_set('display_errors','1'); 
// MyPDO
 // ls : la classe MyPdo hérite de la classe PDO (extends)
class MyPdo extends PDO {

	static public $DB_NAME = "su_dev_eis"; // ls : static public, je sais + pourquoi...

	static public $HOST = "localhost";
	
	static public $USER ="root";

	static public $PASS ="root";
	
// ls : le constructeur de MyPdo appelle le constructeur de PDO en lui passant ses paramètres	
	function __construct() {
	/* ls : la variable $pdo_options, ça date de ma formation de 2012 */ 
	$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
	$pdo_options[PDO::ATTR_EMULATE_PREPARES] = false;//important sur les configs récentes
	$pdo_options[PDO::ATTR_DEFAULT_FETCH_MODE] = PDO::FETCH_OBJ;//pour le mode objet
	$pdo_options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES utf8";//pour l'utf-8
 
	parent::__construct('mysql:host=' . MyPdo::$HOST . ';dbname=' . MyPdo::$DB_NAME, MyPdo::$USER,MyPdo::$PASS, $pdo_options);
//MyPdo::$USER
	}

}
// fin MyPDO
?>
un fichier autre que indexpage.php :
<?php
session_start();
...
include dirname(__DIR__)."\header.inc.php";
...
header.inc.php :
<?php
session_start();
...
$bdd=$_SESSION['bdd'];
...
var_dump($bdd);
$query1="SELECT * from users WHERE user='".$_SESSION['user']."'";
$qid = $bdd->prepare($query1);
$qid->execute();
...
Le var_dump ci-dessus affiche NULL :(

Mammouth du PHP | 2278 Messages

23 mars 2015, 13:26

De toute façon, les connexions sont closes à la fin de chaque script et ça ne coute pas cher de rouvrir chaque fois que nécessaire (close est exécuté implicitement)
Pour local et global un exemple
<?PHP
function local ()
{
	print "<br>dump entrée de local  : ";
	var_dump($a);
	$a = 2;
	print "<br>dans fonction local $a";
}
function globale ()
{
	global $a;
	print "<br>dump entrée de globale : ";
	var_dump($a);
	$a = 2;
	print "<br>dans fonction globale $a";
}
function utile()
{
	return 31;
}
function parametre($a)
{
	return $a*10;
}
function paradresse (&$a, $b)
{
	$a = $a*$b;
	
}
function globalisant ($a,$b)
{
	global $texte;
	$div = $a /$b;
	print "<br>$texte : $div";
}
$a = 4;
print "principal avant $a";
local();
print "<br>après local $a";
globale ();
print "<br>après globale $a";
$a = utile();
print "<br>après utile $a";
$b = parametre($a);
print "<br>b après parametre $b";
print "<br>a après parametre $a";
paradresse($a, $b);
print "<br>b après paradrese $b";
print "<br>a après paradresse $a";
include ("barratin");
globalisant ($a, $b);
?>
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Eléphanteau du PHP | 10 Messages

23 mars 2015, 15:31

Je te remercie de ton message ; je connaissais déjà le principe mais ça fait une bonne révision, mais ça n'explique pas pourquoi mon var_dump retourne 0 !! Y aurait pas trop de session_start() ? (à ne pas mettre dans les fichiers inclus)

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

23 mars 2015, 16:29

$bdd étant un objet, il me semble qu'il faut le sérialiser pour le passer en session (et le déserialiser pour pouvoir le lire, après avoir inclus la classe de laquelle il est instancié)

La fonction session_register() permettait de gérer de façon transparente la sérialisation, mais celle-ci est dépréciée depuis php 5.4. Je ne sais pas si le traitement est encore réalisé sur les variables passées et lues dans $_SESSION
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 10 Messages

23 mars 2015, 16:40

Je viens de tenter une sérialisation donc connect_mysql.php est devenu :
<?php
//global $bdd;
header('Content-type: text/html; charset=UTF-8');
//// connexion
function connect_mysql() {
include_once (dirname(__DIR__).'\pdo\new\MyPdo.php');

try{
				$bdd = new MyPdo();
				$_SESSION["bdd"]=serialize($bdd);
				return($bdd);
			}
catch(PDOException $e){
				echo "argggggggggggggg".$e->getMessage();
				return(FALSE);
			}
}
		
?>
mais le message d'erreur est :
You cannot serialize or unserialize PDO instances
:cry:

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

23 mars 2015, 17:05

Ah flute, pas de chance :)

Mais par contre je ne comprends pas bien au final ce que tu veux faire... c'est juste ouvrir une connexion dans un fichier include que tu appelles au début de chacun de tes scripts de façon à pouvoir l'exploiter ?

Du coup il suffit d'un include_once() de ton fichier de connexion qui fera la connexion $bdd=connect_mysql(); en dehors d'une fonction de façon à se que sa portée soit globale. Tu pourras ainsi l'utiliser dans tous tes scripts inclus à la suite, et via le mot clé global si tu veux l'utiliser à l'intérieur d'une fonction...
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 10 Messages

23 mars 2015, 17:36

Je ne suis pas tout à fait dans le cas que tu décris : il y a certes un fichier principal (indexpage.php) dans lequel d'autres fichiers sont inclus, donc là, ta proposition va, mais il y a un deuxième fichier (indexcal.php) (qu'on peut attendre depuis indexpage.php via un lien) et dans indexcal.php sont inclus les mêmes fichiers que dans indexpage.php (des menus, en-têtes, pieds de page...) et tous ces fichiers doivent pouvoir se connecter à la même bdd...