webdeb
Messages postés488Date d'inscriptionsamedi 5 avril 2003StatutMembreDernière intervention31 mars 2009
-
19 déc. 2008 à 00:51
zroxx
Messages postés1Date d'inscriptionjeudi 13 novembre 2008StatutMembreDernière intervention30 avril 2009
-
30 avril 2009 à 04:03
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
zroxx
Messages postés1Date d'inscriptionjeudi 13 novembre 2008StatutMembreDernière intervention30 avril 2009 30 avril 2009 à 04:03
Bonjour,
j'ai utilisé ce script il marche très bien, mais lorsque les table sont copiés il semble que l'auto incrémentation ne se copie pas. Ça ajoute également la valeur "0" par défault...
qqun a-t-il une solution ? c'est une variable de mysql qui n'est pas correcte ?
merci !
pouyelayese
Messages postés7Date d'inscriptionvendredi 9 mai 2008StatutMembreDernière intervention28 avril 2014 11 janv. 2009 à 17:28
slt je m'adresse à fmarie s'il peut mettre des commentaires dans son code car pour les débutants comme nous c'est un peu difficile de comprendre.
webdeb
Messages postés488Date d'inscriptionsamedi 5 avril 2003StatutMembreDernière intervention31 mars 20094 21 déc. 2008 à 00:04
>> Sinon, pourquoi ne pas utiliser l'extension mysqli plutôt que mysql ?
Ou même PDO tant qu'à faire :)
neigedhiver
Messages postés2480Date d'inscriptionjeudi 30 novembre 2006StatutMembreDernière intervention14 janvier 201119 20 déc. 2008 à 22:15
Salut,
Concernant l'exécution d'un script shell par l'utilisateur, il est vivement recommandé, à moins d'apporter un soin extrême à la configuration de PHP et du serveur (ce qui n'est pas une mince affaire), de ne pas le faire directement par PHP.
Le mieux est, comme le disait WebDeb, d'utiliser une tâche auto avec cron, exécutée sous root.
Il n'est pas nécessaire que la tâche soit exécutée 1 fois par jour... On peut imaginer que le script de backup cherche un fichier précis à un endroit précis (lequel aura été créé par PHP dans un répertoire de l'utilisateur qui ne se trouve pas dans l'arborescence de publication http). Si le fichier est trouvé (il peut d'ailleurs contenir le(s) nom(s) de la / des base(s) à sauvegarder), alors le dump est effectué. Sinon, non.
Cette tâche peut très bien être exécutée toutes les 5/10 minutes par exemple.
Dans le même ordre d'idée, pour la restauration, on peut imaginer l'inverse... L'utilisateur doit placer son fichier .sql à un endroit précis. La tâche de restauration cherche les fichiers SQL dans ce répertoire précis et les exécute. Idem, elle peut tourner toutes les 5/10 minutes.
C'est à mon avis une des solutions les plus simples à mettre en place sans sacrifier la sécurité (plutôt que d'avoir un script PHP qui exécute un script shell contenant le mot de passe MySQL de root) et, puisque tu t'adresses à des personnes qui ont un serveur dédié, bien plus adaptées qu'un script PHP.
Pour revenir sur le point 2 évoqué par WebDeb : pourquoi utiliser MySQL connect sur chaque page avec des variables définies dans un autre fichier ? Pourquoi ne pas simplement inclure un fichier qui contient la fonction mysql_connect() avec les arguments ? Bon c'est du détail, hein...
Sinon, pourquoi ne pas utiliser l'extension mysqli plutôt que mysql ?
coucou747
Messages postés12303Date d'inscriptionmardi 10 février 2004StatutMembreDernière intervention30 juillet 201244 19 déc. 2008 à 19:26
# mysql_query($SQL);
# if (!$SQL) {
<=>
# $truc = mysql_query($SQL);
# if (!$truc) {
fmarie
Messages postés6Date d'inscriptiondimanche 20 avril 2003StatutMembreDernière intervention19 décembre 2008 19 déc. 2008 à 14:27
Ok ! Merci de l'information !
Mes bases sont en effet en MyISAM.
Et si tu as encore 5 minutes à me consacrer pour les questions de mon message de 01:14:52 ;)
webdeb
Messages postés488Date d'inscriptionsamedi 5 avril 2003StatutMembreDernière intervention31 mars 20094 19 déc. 2008 à 13:23
Les transactions ne fonctionnent que si tes bases de données utilisent le moteur de stockage InnoDB. Si tu es en MyISAM, ça ne fera rien, bien que les requêtes BEGIN, COMMIT et ROLLBACK s'exécutent bien.
fmarie
Messages postés6Date d'inscriptiondimanche 20 avril 2003StatutMembreDernière intervention19 décembre 2008 19 déc. 2008 à 12:14
J'ai oublié de mettre la ligne :
begin();
entre :
$SQL="CREATE TABLE $dbdest.$enr[0] SELECT * FROM $db.$enr[0];";
et
$result=@mysql_query($SQL);
fmarie
Messages postés6Date d'inscriptiondimanche 20 avril 2003StatutMembreDernière intervention19 décembre 2008 19 déc. 2008 à 12:12
A l'attention de Webdeb !
J'ai cherché un peu sur le point 7 et les transactions.
Si je fais quelque chose de ce type :
<?
$db="base"; // Base a sauvegarder
$dbdest=$db."_".date("Ymd_Hi"); // Cela créera la base avec le nom de la base intiale + date et heure ex : base_20001231_2359
function begin()
{
@mysql_query("BEGIN");
}
function commit()
{
@mysql_query("COMMIT");
}
function rollback()
{
@mysql_query("ROLLBACK");
}
$connexion=mysql_connect("localhost","root","pass"); //on effectue la connexion
if (!$connexion) {
die('Connexion impossible : ' . mysql_error());
exit;
}
echo "Lancement de la sauvegarde
\n";
//Création de la base de données de sauvegarde
$SQL="CREATE DATABASE `$dbdest` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"; // Si besoin modifier les character
mysql_query($SQL);
if (!$SQL) {
die('Erreur sur la creation de la base $dbdest : ' . mysql_error());
exit;
}
echo "Base $dbdest créée.
\n";
//Création et copie des tables
$tables = mysql_list_tables($db, $connexion);
while ($enr = mysql_fetch_row($tables)) {
$SQL="CREATE TABLE $dbdest.$enr[0] SELECT * FROM $db.$enr[0];";
$result=@mysql_query($SQL);
if (!$result) {
rollback();
die('Requête invalide sur la table $enr[0] : ' . mysql_error());
exit;
}else{
commit();
echo "TABLE ".$enr[0]." sauvegardée.
\n";
}
}
echo "
Sauvegarde terminée. La base de sauvegarde est $dbdest.
\n\n";
mysql_close($connexion);
?>
fmarie
Messages postés6Date d'inscriptiondimanche 20 avril 2003StatutMembreDernière intervention19 décembre 2008 19 déc. 2008 à 01:14
Je passerai sur les différents points où tu as raison et que je modifierai plus tard en effet, à savoir les points 1,3,4,6,8.
Point 2, je fais un include logiquement pour n'avoir qu'un fichier de connexion et j'ai simplement fait la copie des variables.
Point 5, à vrai dire, je n'ai pas trouver la solution et je n'ai pas non plus cherché beaucoup en effet. Si tu as la réponse, je suis preneur.
Point 7, qu'appelle-tu transaction ? Un lien d'explication me suffira.
En ce qui concerne le dump, je suis évidement d'accord avec toi mais je ne sais pas comment faire pour que sur une page d'administration d'un site internet, les utilisateurs puissent lancer cet utilitaire à tout moment.
Pour moi, l'important est que les utilisateurs puissent faire une sauvegarde avant de modifier de façon significative une base de données.
Merci de tes éventuelles réponses.
coucou747
Messages postés12303Date d'inscriptionmardi 10 février 2004StatutMembreDernière intervention30 juillet 201244 19 déc. 2008 à 01:04
que beaucoup de gens pensent que php est un langage de merde.
c'est pas du bash la... c'est du php !
webdeb
Messages postés488Date d'inscriptionsamedi 5 avril 2003StatutMembreDernière intervention31 mars 20094 19 déc. 2008 à 00:51
Ca ne sert strictement à rien comme code. Tu t'exposes à de gros problèmes de pertes de cohérence des données au moment de la sauvegarde en procédant de cette manière. De plus ton code est complètement mal écrit pour de multiples raisons :
1/ Le bon tag PHP d'ouverture de script est <?php et non <? qui peut-être désactivés sur les serveurs dignes de ce nom,
2/ Quel est l'intérêt de faire des variables pour stocker les identifiants de connexion plutôt que de les écrire directement en dur dans le mysql_connect() ?
3/ Que se passe-t-il si la connexion au serveur SQL ne se fait pas ? Pourquoi le script continue-t-il ?
4/ Pourquoi mettre des apostrophes inutiles autour des variables ?
5/ Et si je n'utilise pas l'UTF-8 comme encodage de chaque table ?
6/ Que se passe-t-il si un mysql_query() échoue ? Pourquoi continuer le script ?
7/ Malheureusement, il n'y a aucune transaction (donc pas de moteur de stockage InnoDB) pour assurer que toutes les données ont bien été copiées et que l'intégrité référentielle entre les tables a été respectée.
8/ Pas de mysql_close() ?
9/ ...
Bref tout ça pour dire que tu peux jeter ton code à la poubelle ! On ne fait jamais de backups d'une base de données comme ça sur un site en production, c'est complètement fou. Un backup doit être réalisé par une tâche automatique qui lance périodiquement un script shell qui appelle par exemple l'utilitaire mysqldump. C'est beaucoup beaucoup beaucoup beaucoup plus performant et beaucoup beaucoup beaucoup moins dangereux pour la base de données car mysqldump est un utilitaire qui maîtrise les sauvegardes et qui est conçu pour ça.
Pour rappel :
mysqldump -u root -p MaDatabase > MaDatabase.sql
permet en 1 ligne de commande de dumper proprement MaDatabase dans le fichier MaDatabase.sql.
30 avril 2009 à 04:03
j'ai utilisé ce script il marche très bien, mais lorsque les table sont copiés il semble que l'auto incrémentation ne se copie pas. Ça ajoute également la valeur "0" par défault...
qqun a-t-il une solution ? c'est une variable de mysql qui n'est pas correcte ?
merci !
11 janv. 2009 à 17:28
21 déc. 2008 à 00:04
Ou même PDO tant qu'à faire :)
20 déc. 2008 à 22:15
Concernant l'exécution d'un script shell par l'utilisateur, il est vivement recommandé, à moins d'apporter un soin extrême à la configuration de PHP et du serveur (ce qui n'est pas une mince affaire), de ne pas le faire directement par PHP.
Le mieux est, comme le disait WebDeb, d'utiliser une tâche auto avec cron, exécutée sous root.
Il n'est pas nécessaire que la tâche soit exécutée 1 fois par jour... On peut imaginer que le script de backup cherche un fichier précis à un endroit précis (lequel aura été créé par PHP dans un répertoire de l'utilisateur qui ne se trouve pas dans l'arborescence de publication http). Si le fichier est trouvé (il peut d'ailleurs contenir le(s) nom(s) de la / des base(s) à sauvegarder), alors le dump est effectué. Sinon, non.
Cette tâche peut très bien être exécutée toutes les 5/10 minutes par exemple.
Dans le même ordre d'idée, pour la restauration, on peut imaginer l'inverse... L'utilisateur doit placer son fichier .sql à un endroit précis. La tâche de restauration cherche les fichiers SQL dans ce répertoire précis et les exécute. Idem, elle peut tourner toutes les 5/10 minutes.
C'est à mon avis une des solutions les plus simples à mettre en place sans sacrifier la sécurité (plutôt que d'avoir un script PHP qui exécute un script shell contenant le mot de passe MySQL de root) et, puisque tu t'adresses à des personnes qui ont un serveur dédié, bien plus adaptées qu'un script PHP.
Pour revenir sur le point 2 évoqué par WebDeb : pourquoi utiliser MySQL connect sur chaque page avec des variables définies dans un autre fichier ? Pourquoi ne pas simplement inclure un fichier qui contient la fonction mysql_connect() avec les arguments ? Bon c'est du détail, hein...
Sinon, pourquoi ne pas utiliser l'extension mysqli plutôt que mysql ?
19 déc. 2008 à 19:26
# if (!$SQL) {
<=>
# $truc = mysql_query($SQL);
# if (!$truc) {
19 déc. 2008 à 14:27
Mes bases sont en effet en MyISAM.
Et si tu as encore 5 minutes à me consacrer pour les questions de mon message de 01:14:52 ;)
19 déc. 2008 à 13:23
19 déc. 2008 à 12:14
begin();
entre :
$SQL="CREATE TABLE $dbdest.$enr[0] SELECT * FROM $db.$enr[0];";
et
$result=@mysql_query($SQL);
19 déc. 2008 à 12:12
J'ai cherché un peu sur le point 7 et les transactions.
Si je fais quelque chose de ce type :
<?
$db="base"; // Base a sauvegarder
$dbdest=$db."_".date("Ymd_Hi"); // Cela créera la base avec le nom de la base intiale + date et heure ex : base_20001231_2359
function begin()
{
@mysql_query("BEGIN");
}
function commit()
{
@mysql_query("COMMIT");
}
function rollback()
{
@mysql_query("ROLLBACK");
}
$connexion=mysql_connect("localhost","root","pass"); //on effectue la connexion
if (!$connexion) {
die('Connexion impossible : ' . mysql_error());
exit;
}
echo "Lancement de la sauvegarde
\n";
//Création de la base de données de sauvegarde
$SQL="CREATE DATABASE `$dbdest` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;"; // Si besoin modifier les character
mysql_query($SQL);
if (!$SQL) {
die('Erreur sur la creation de la base $dbdest : ' . mysql_error());
exit;
}
echo "Base $dbdest créée.
\n";
//Création et copie des tables
$tables = mysql_list_tables($db, $connexion);
while ($enr = mysql_fetch_row($tables)) {
$SQL="CREATE TABLE $dbdest.$enr[0] SELECT * FROM $db.$enr[0];";
$result=@mysql_query($SQL);
if (!$result) {
rollback();
die('Requête invalide sur la table $enr[0] : ' . mysql_error());
exit;
}else{
commit();
echo "TABLE ".$enr[0]." sauvegardée.
\n";
}
}
echo "
Sauvegarde terminée. La base de sauvegarde est $dbdest.
\n\n";
mysql_close($connexion);
?>
Est-ce que cela parait correct ?
J'ai lu cet article et repris les fonctions de départ :
http://www.devarticles.com/c/a/MySQL/Using-Transactions-with-MySQL-4.0-and-PHP/
19 déc. 2008 à 01:14
Point 2, je fais un include logiquement pour n'avoir qu'un fichier de connexion et j'ai simplement fait la copie des variables.
Point 5, à vrai dire, je n'ai pas trouver la solution et je n'ai pas non plus cherché beaucoup en effet. Si tu as la réponse, je suis preneur.
Point 7, qu'appelle-tu transaction ? Un lien d'explication me suffira.
En ce qui concerne le dump, je suis évidement d'accord avec toi mais je ne sais pas comment faire pour que sur une page d'administration d'un site internet, les utilisateurs puissent lancer cet utilitaire à tout moment.
Pour moi, l'important est que les utilisateurs puissent faire une sauvegarde avant de modifier de façon significative une base de données.
Merci de tes éventuelles réponses.
19 déc. 2008 à 01:04
$connexion=mysql_connect("$host","$user","$password");
que beaucoup de gens pensent que php est un langage de merde.
c'est pas du bash la... c'est du php !
19 déc. 2008 à 00:51
1/ Le bon tag PHP d'ouverture de script est <?php et non <? qui peut-être désactivés sur les serveurs dignes de ce nom,
2/ Quel est l'intérêt de faire des variables pour stocker les identifiants de connexion plutôt que de les écrire directement en dur dans le mysql_connect() ?
3/ Que se passe-t-il si la connexion au serveur SQL ne se fait pas ? Pourquoi le script continue-t-il ?
4/ Pourquoi mettre des apostrophes inutiles autour des variables ?
5/ Et si je n'utilise pas l'UTF-8 comme encodage de chaque table ?
6/ Que se passe-t-il si un mysql_query() échoue ? Pourquoi continuer le script ?
7/ Malheureusement, il n'y a aucune transaction (donc pas de moteur de stockage InnoDB) pour assurer que toutes les données ont bien été copiées et que l'intégrité référentielle entre les tables a été respectée.
8/ Pas de mysql_close() ?
9/ ...
Bref tout ça pour dire que tu peux jeter ton code à la poubelle ! On ne fait jamais de backups d'une base de données comme ça sur un site en production, c'est complètement fou. Un backup doit être réalisé par une tâche automatique qui lance périodiquement un script shell qui appelle par exemple l'utilitaire mysqldump. C'est beaucoup beaucoup beaucoup beaucoup plus performant et beaucoup beaucoup beaucoup moins dangereux pour la base de données car mysqldump est un utilitaire qui maîtrise les sauvegardes et qui est conçu pour ça.
Pour rappel :
mysqldump -u root -p MaDatabase > MaDatabase.sql
permet en 1 ligne de commande de dumper proprement MaDatabase dans le fichier MaDatabase.sql.