Vous êtes ici FAQ - Foire aux questions de phpSources

 

FAQ - Foire aux questions sur le PHP et MySQL

Consultez la FAQ à partir des questions les plus fréquement posées. Avec des solutions rapides qui répondrons à vos problèmes pour réaliser vos scripts PHP/MySQL.
 
 
Sommaire de la FAQ
 

Généralités

Architecture client-serveur

Nous allons étudier ici l'architecture client-serveur et les relations entre divers languages de programmation web (PHP/MySQL, (X)HTML/CSS, JavaScript). Garder en tête cette architecture permet d'éviter de ce poser quelques question ou de se lancer des scripts ne pouvant fonctionner.

Lorsqu'un navigateur web, le client, demande une page web, il envoie une requête au serveur hébergeant la page concernée. On peut ici distinguer deux cas.
Si le serveur ne possède pas de language serveur de type PHP ou ASP : il se contente d'envoyer la page au navigateur qui l'a demandée sans autres manipulations.
Si, au contraire, un language, par exemple le PHP, est implémenté sur le serveur, celui-ci va commencer par interprêter la page, c'est-à-dire rechercher et exécuter les instructions PHP. Si des accès à des fichiers ou à une base de donnée sont nécessaires, c'est durant cette étape qu'ils seront faits. L'etape finale consiste en l'envoi de la page au navigateur. Ce qui est important c'est que le navigateur ne reçoit que des informations de mise en forme -(X)HTML, CSS- et du JavaScript: il ne reçoit en aucun cas du PHP puisque l'exécution de celui-ci est loin en arrière... Si l'on veut à nouveau exécuter du PHP, on est obligé de recharger la page -ce qui fait appel au serveur.

On voit souvent, sur des forums, un début de code dans le genre:
// un bouton, en HTML
<input type="button" name="bouton" onClick="fonction_php();" />

<?php
function fonction_php()
{
    
// code PHP ici
}
?>
Avec la question associée: "pourquoi le bloc de PHP ne s'exécute pas lors du clic sur le bouton?"
Si l'on a à l'esprit l'architecture client-serveur, il est clair qu'un bloc de PHP (language serveur), ne peut pas s'exécuter lors d'un clic sur un bouton (JavaScript, language client). Si l'on veut une exécution du code PHP, il faut recharger la page!
Les sessions

Erreurs et problèmes fréquents
Cannot send session cookie
Message d'erreur:
Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at www\index.php:2) in www\index.php on line XX

Explication:
Cette erreur se produit lorsque les headers ont déjà été envoyés et que la session ne peut démarrer.
Pour plus d'informations reportez vous aux erreurs liées aux headers

Résolution:
Assurez vous que l'appel à la fonction session_start() se trouve avant toute sortie.


No such file or directory
Message d'erreur:
Warning: session_start() [function.session-start]: open(/mnt/103/free.fr/0/6/membre/sessions/sess_145bc68e6e1e1bbb486595133b28e106, O_RDWR) failed: No such file or directory (2) in /mnt/103/free.fr/0/6/membre/index.php on line XX

Explication:
Cette erreur se produit lorsque le repertoire contenant les sessions ne peut être trouvé.

Résolution:
  • Si vous développez sur votre serveur:
    - Vérifiez, dans le php.ini, que le chemin correspondant à session.save_path est valide
    - Vérifiez que ce dossier possède les droits en écriture

  • Si vous ne développez pas sur votre propre serveur:
    Quelques hébergeurs demandent la création d'un répertoire qui contiendra les sessions, consultez la FAQ de votre hébergeur.
    Remarque: pour les hébergeurs Free et online.net, il s'agit de créer un répertoire sessions dans le dossier principal de votre compte

Les données sont perdues
Dans le cas où vous enregistrez des données dans une session et que, malheureusement, à la page suivante, elles n'existent plus, vous pouvez vérifier les points suivants:
- L'appel à la fonction session_start() doit se faire sur chaque page (sur la page principale, pas dans les pages incluses) et avant toute sortie vers le navigateur
- Dans la plupart des cas, l'identifiant de session -qui permet à PHP de savoir si une nouvelle session doit être démarrée ou si l'on utilise une ancienne, et ensuite à qui il faut envoyer les données- est transmis par un cookie. Si vous n'acceptez pas les cookies, la session peut se ré-initialiser sur chaque page.


Les données sont modifiées
Si la valeur de l'une de vos variables de session change de manière inexpliquée, pensez à vérifier si vous utiliser une variable du même nom. En effet, sur certains serveurs ayant la directive de configuration register_globals à ON, l'emploi de la variable $variable peut changer le contenu de $_SESSION['variable']:
Ainsi ce code affichera, lors de sa deuxième exécution: 'bbb', au lieu de 'aaa':
<?php
session_start
();

$_SESSION['variable'] = 'aaa';
$variable 'bbb';

echo 
$_SESSION['variable'];
?>

Bases de données

Erreurs fréquentes
supplied argument is not a valid MySQL result resource Message d'erreur: Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in www\index.php on line XX

Explication: Cette erreur se produit lorsque une fonction de traitement MySQL (mysql_fetch_array, mysql_fetch_row, mysql_fetch_assoc, mysql_num_rows, ...), qui prend normalement en paramètre une ressource MySQL, a été appelée avec un paramètre n'étant pas une ressource MySQL.

Cette erreur se produit notamment lorsqu'une requête SELECT contient une erreur ; ainsi la fonction mysql_query renvoie false (et non une resource MySQL comme elle le devrait).

Résolution:
Vérifiez que l'exécution de la requête s'est bien déroulée avant la suite du script:
En cas de redirection et d'arrêt du script:
<?php
// exécution de la requête
$result = @mysql_query'SELECT champ FROM table' );

// si erreur
if( !$result )
{
    
// traitement de l'erreur
}
else
{
    
$row mysql_fetch_array$result );
}
?>
Plus simplement, die affiche un message d'erreur et stoppe l'exécution du script (l'instruction ne sera exécutée qu'en cas d'erreur, grâce à or):
<?php
// exécution de la requête
$result = @mysql_query'SELECT champ FROM table' )
    or die( 
'Erreur MySQL' );
?>

Optimisations

Guillemets simples ' ou doubles "

Différence entre les deux:
Le texte entre guillemets simples n'est pas interprêté, contrairement à celui qui se trouve entre guillemets doubles.
Par exemple:
<?php
$nom 
'Toto';

echo 
'Il se prénomme $nom<br />'// Affiche: Il se prénomme $nom
echo "Il se prénomme $nom<br />"// Affiche: Il se prénomme Toto
?>
Avantages, inconvénients et utilisations:
L'utilisation de l'une ou de l'autre sorte de guillemets dépend des situations.

Sans contrainte particulière, il est préférable d'utiliser les guillemets simples qui sont plus rapides que les guillemets doubles (puisque le texte entre ' ' n'est pas interprêté).
L'exemple précédent s'écrira donc comme suit:
<?php
$nom 
'Toto';

echo 
'Il se prénomme ' $nom '<br />'// Affiche: Il se prénomme $nom
?>
Dans le cas où une chaîne comporte un grand nombre de variables, notamment pour des requêtes MySQL, l'utilisation de guillemets doubles permet une syntaxe plus légère.
Pour une requête qui pourrait servir à l'insertion d'une news, il est clair que la syntaxe utilisant " " est plus légère que l'autre:
<?php
mysql_query
"INSERT INTO news (membre_id, membre_pseudo, date, titre, texte) VALUES
 ($membre_id, '$membre_pseudo', " 
time(). ", '$titre', '$texte')" );

mysql_query'INSERT INTO news (membre_id, membre_pseudo, date, titre, texte) VALUES
 ($membre_id, \'' 
$membre_pseudo '\', " . time(). ", \'' $titre '\', \'' $texte '\')' );
?>
Lorsqu'il s'agit d'écrire du HTML, les attributs des balises étant délimitées par des guillemets doubles, il est plus lisible d'utiliser des guillemets simples:
<?php
echo '<img src="image.jpg" alt="texte" border="0" />';

echo 
"<img src=\"image.jpg\" alt=\"texte\" border=\"0\" />";
?>
Pour résumer: les guillemets simples sont plus rapides mais le gain de temps est peu significatif dans bien des cas par rapport à d'autres optimisations et la lisibilité du code source est aussi un facteur à prendre en compte.
Print ou echo

Différence entre les deux:
La première différence réside en le fait que la fonction print renvoie un entier (apparement, toujours 1), au contraire de la fonction echo qui ne renvoie rien.
La fonction echo est ensuite un tout petit peu plus rapide (sur un script courant, le gain est tout à fait négligeable).

Lequel utiliser?
Dans la mesure ou print n'apporte rien de plus, autant utiliser echo même si, comme nous l'avons dit, le gain de temps est minime.

Formulaires

Retours à la ligne

Problème:
Vous utilisez un champ de texte multilignes (textarea) dans lequel vous entrez un texte sur plusieurs lignes mais il n'apparaît que sur une seule ligne.

Raison:
Les marqueurs de fin de lignes sont les caractères \r\n, qui sont utilisés aussi dans les fichiers, qui n'ont pas d'effet en HTML.

Résolution:
Utiliser la fonction nl2br() qui ajoutera, pour chaque \r\n, un <br />:
<?php
$texte 
nl2br$texte );
?>
Remarques:
- La fonction nl2br ne supprime pas les \r\n qui servent de retours chariot dans les zones de textes.
- L'utilisation de \r\n permet de faire un retour chariot au niveau du source HTML (amélioration de la lisibilité du code source de la page)

Combinaison avec requêtes MySQL

Les données entrées dans les formulaires sont bien souvent utilisées dans des requêtes MySQL (sélection, insertion et modification de données).
Afin d'éviter tous problèmes de sécurité, il convient de faire attention à quelques points.

Guillemets
Le premier problème concerne les guillemets simples, ', utilisés bien souvent comme délémiteurs dans les requêtes MySQL.

Résolution:
La fonction addslashes() échappe les guillemets (et quelques autres caractères qui peuvent poser problème) en ajoutant une barre oblique inverse ( \ ) devant ceux-ci.
<?php
$texte 
addslashes$texte );
?>
La fonction stripslashes(), qui s'utilise de la même façon, effectue l'opération inverse: elle enlève les barres obliques inverses qui sont gênantes pour l'affichage.

Remarque:
La fonction mysql_real_escape_string() effectue le même traitement mais en tenant compte du jeu de caractères et traîte quelques caractères supplémentaires.

Exemple:
Ce qui suit est un exemple d'attaque MySQL dans le cas d'un code non-protégé, afin que tout ceci reste moins théorique.

Imaginons que vous possédiez une table contenant des membres, elle possède, notamment, les champs suivants:
- id ( entier )
- pseudo (chaîne des caractères)
- password (chaîne des caractères)
Pour loger la personne, après avoir récupéré le mot-de-passe dans $pass et le pseudo dans $pseudo, vous construisez la requêtes comme ceci:
<?php
$result 
mysql_query("SELECT id FROM membres WHERE pseudo='$pseudo'
                       AND password='$pass'"
)
    or die( 
'Erreur MySQL: ' mysql_error() );
?>
Tout fonctionne jusqu'au moment ou quelqu'un rentre les informations suivantes:
pseudo: admin
pass: ' OR '1'='1
La requêtes générée sera alors celle ci:
SELECT id FROM membres WHERE pseudo='admin' AND pass='' OR '1'='1'
Ainsi, s'il existe un compte admin, la requête retournera sont identifiant puisque '1' est toujours égal à '1'! Si l'authentification se base sur la récupération de l'id, n'importe qui peut se faire passer pour l'admin!
Caractères spéciaux

Une autre chose à laquelle il faut faire attention si les données que vous enregistrez sont destinées à l'affichage est les caractères HTML. Un utilisateur peu en effet intégrer sa propre mise en page ou bien, plus embêtant, en ne fermant pas une balise, perturber toute la mise en page de votre site. Il peu de plus tenter d'intégrer du JavaScript, ce qui peut provoquer des failles de sécurité.
Afin d'éciter ceci, il convient d'utiliser la fonction htmlentities qui remplacera certains caractères par leur entité:
$texte htmlentities$texte );
Deux paramètres optionnels de htmlentities permettent de définir la gestion des guillemets, simples et doubles, ainsi que le jeu de caractères utilisé.

Fichiers

Erreurs fréquentes
supplied argument is not a valid stream resource
Message d'erreur:
Warning: fread(): supplied argument is not a valid stream resource in www\index.php on line XX

Explication:
Cette erreur est semblable à celle expliquée pour MySQL: la fonction fread (ainsi que fputs, fgets, ... ) attend comme premier paramètre un pointeur sur un fichier. Le problème se présente lorsqu'une erreur se produit lors de l'ouverture du fichier: ainsi fopen renvoie false au lieu d'un identifiant de fichier ; la fonction fread n'aime pas qu'on lui donne false en paramètre.

Résolution:
Ajouter un contrôle d'erreur:
<?php
$fp 
= @fopen'fichier.txt''r' );

if( !
$fp )
    die( 
'Erreur lors de l\'ouverture du fichier' );

$texte fread$fp4096 );

fclose$fp );
?>

failed to open stream: Permission denied

Message d'erreur:
Warning: fopen(fichier.txt): failed to open stream: Permission denied in /www/index.php on line XX

Explication:
Cette erreur peut se produire lors de l'ouverture en écriture d'un fichier (si la fichier n'existe pas et que la fonction fopen doit le créer) et que le répertoire dans lequel le fichier doit être créé ne dispose pas des droits suffisants.

Résolution:
Assurez-vous que le groupe 'tous' dispose des droits en écriture sur le répertoire concerné. En général, le chmod 0767 convient.

Connexion

 
 

Explications

 
 

Ressources

 
 
 
Partenaire officiel
Partenaire officiel
 
  Statistiques...
Stats du réseau:
visiteurs en ligne : 36
basées sur les utilisateurs actifs des 5 dernières minutes
membres : 19872
 
Stats du site phpsources:
Dernière mise à jour des stats
aujourd'hui à 13:19:12

codes sources : 595
scripts : 972
articles - actualités : 101
tutoriel : 34
sites sur le langage PHP : 231
commentaires : 2 064
total des scripts téléchargés: 1 554 888
total hits codes sources: 7 100 123