Charger plusieurs page php une apres l'autre...

WRInaute discret
Hello a Tous.

Je me demandais si vous auriez une suggestion pour moi.

Je dois de temps en temps transferrer plusieur donnee d'une base a une autre et certaine info d'une table a l'autre dans cette meme base et donc un gros et tres long script php fait le travail.

Le seul probleme, est que le script etait tellement lourd que en plus de changer set_time_limit, j'ai duseparer le script en plusieurs morceaux car c'etait trop gros et ca plantait tout le temps..
Et donc je me retrouve avec 6 page PHP que je dois appeler une apres l'autre lorqu'elle on fini de "loader".
Et donc certaine d'entre elle prennent 2 minutes et d'autre 5 a 6 min...et donc de rester en face de l'ordi pour attendre que les pages finissent .

Je me demandais si ca serrait possible pour de creer une page qui les l'ancerrait une apres l'autre, mais seulement quand le scrit est fini...de plus quelques fois une des 6 parties du script gele et donc il faudrait pour bien faire que je sache ou j'en etait rendu...

Avez vous une suggestion?
Merci a tous!
 
Nouveau WRInaute
Voir du côté de PHP CLI (php en ligne de commande). Bien entendu ça sous entend que tu as accès en ssh (pour un serveur sous linux)
 
WRInaute impliqué
Surement faisable avec exec().

J'ai été confronté à un problème similaire sinon et l'ai résolu en décomposant en deux phases:
- générer les requêtes SQL à faire et les mettre dans un fichier texte ou plusieurs
- les éxécuter dans un ordre précis, en effaçant le fichier texte une fois utilisé

En pratique le timeout survient lors de l'envoi à la bdd, pas à cause du PHP.
Puis je supposer que tu as d'énormes requêtes étendues avec des milliers d'enregistrements?
Je suis sûr qu'on peut décomposer un peu pour alléger le travail du serveur :)
 
WRInaute discret
Dr DLP a dit:
Surement faisable avec exec().

J'ai été confronté à un problème similaire sinon et l'ai résolu en décomposant en deux phases:
- générer les requêtes SQL à faire et les mettre dans un fichier texte ou plusieurs
- les éxécuter dans un ordre précis, en effaçant le fichier texte une fois utilisé

En pratique le timeout survient lors de l'envoi à la bdd, pas à cause du PHP.
Puis je supposer que tu as d'énormes requêtes étendues avec des milliers d'enregistrements?
Je suis sûr qu'on peut décomposer un peu pour alléger le travail du serveur :)

Oui et j'ai surtout beaucoup while a l'interieur d'un autre while...c'est ce qui fait que c'est tres lourd...
Donc toi tu est cappable de tout faire marcher en mettant ton script dans un fichier texte et tu lance le fichier et ca fonctionne? Meme si c'est tres lourd?
 
WRInaute impliqué
Dépend ce que tu entends pas "lourd".
Ni le PHP ni le nombre de requêtes n'est un problème, c'est la taille des requêtes qui provoque le timeout généralement.

Dans ton cas ça simplifierait tout de même: tu transfères de local en réel c'est ça?
Le "truc" est de différer la requête SQL; au lieu de l'exécuter tu la stockes dans un fichier texte, cela permet de séparer le PHP et le SQL.
Une fois le travail du script PHP terminé, tu exécutes tes requêtes en les effaçant au fur et à mesure.
Du coup si ça plante tu peux relancer au même point sans repasser par le PHP.

Je ne sais pas si c'est très clair :lol:

Pour ma part en tout cas la mise à jour de mon site et ces 500.000 enregistrements est passé de plus de trois heures en moyenne à une dizaine de minutes :D
 
WRInaute discret
Dr DLP a dit:
Pour ma part en tout cas la mise à jour de mon site et ces 500.000 enregistrements est passé de plus de trois heures en moyenne à une dizaine de minutes :D

Wow... ca commence a m'interesser :D

En fait le logiciel d'inventaire de mon entreprise a une fonction qui permettait d'exporter automatiquement les information client et items a une base de donne mysql. Cette information etait avant utilisé dans un petit site web (shopping cart) tres simple. Mais Dernierement (4mois) j'ai changé refait le site et les mis sous Oscommerce.

J'ai donc écrit un script que prenait mon information de l'encienne db et la mettrait dans la base OScommerce au bon endroit, puisque la structure n'etait pas parreil. Donc a chaque fois que je fais un update par le logiciel d'inventaire, je lance par la suite le ''transfert de base''.

Mon code ressemble a pres de 25 mini code comme celui ci.

Code:
$queryz  = "SELECT * FROM kvd.style";
$resultz = mysql_query($queryz);
while($row = mysql_fetch_array($resultz)){

$count= 0;
$num_style = $row['num_style'];
$descrip = $row['descrip'];
$descrip_e = $row['descrip_e'];
$prix = $row['prix'];
$vraiimage = "$num_style-01_L.gif";
$date = date("Y-m-d");
$heure = date("H:i:s");
$heuredate = "$date $heure";


$sqqql="SELECT * FROM kvd.products";  
$answer = mysql_query($sqqql);
while ($answer_data = mysql_fetch_array($answer) ) 
{ 
if ($num_style!=$answer_data['products_model'])
echo"";
else
$count=$count+1; 
} 

if($count != 0){
echo "$num_style existe<br>";
mysql_query("UPDATE kvd.products SET products_price='$prix' WHERE products_model = '$num_style'");
}else{
echo "$num_style existe pas et donc ajouter<br>";
mysql_query("INSERT INTO kvd.products (products_model, products_image, products_price, products_date_added, products_status, products_tax_class_id ) VALUES ('$num_style', '$vraiimage', '$prix', '$heuredate', '1', '1')");
}
}

Aillant plusieurs milliers d'item et de clients cela prends beaucoup de temps...et cela ne me derange pas trop, mais c'est surtout que le fait que je dois separer mon script en plusieurs page, je dois rester a coter de l'ordi et lancer une page apres l'autre...pas pratique.

Je ne suis pas trop sur si je comprends bien, mais toi tu ferrait ecrire par le script php tous les mysql_query dans un fichier text et par la suite ferrait executer le fichier txt?
 
WRInaute impliqué
willpower a dit:
Je ne suis pas trop sur si je comprends bien, mais toi tu ferrait ecrire par le script php tous les mysql_query dans un fichier text et par la suite ferrait executer le fichier txt?
Seulement les UPDATE, INSERT et DELETE, pas les SELECT :p

A vue de nez ton problème est plutôt le codage PHP en fait.
Balancer un SELECT ALL dans la boucle doit causer "quelques" lenteurs en effet: je ne vois aucune possibilité pour que ce soit obligatoire.
Cette requête est trop gourmande: soit tu mets les résultats en tableau, soit tu ne sélectionne que le champ qui t'intéresse et le recherche avec $num_style.
Pour cette deuxième solution:
Code:
$sqqql="SELECT * FROM kvd.products"; 
$answer = mysql_query($sqqql);
while ($answer_data = mysql_fetch_array($answer) )
{
if ($num_style!=$answer_data['products_model'])
echo"";
else
$count=$count+1;
}
devient
Code:
$sqqql="SELECT products_model FROM kvd.products WHERE products_model = " . $num_style; 
$answer = mysql_query($sqqql);
if (mysql_num_rows($answer) > 0)
{
$count= 1;
}
C'est monstrueusement moins gourmand en ressources.

Ceci dit j'opte pour l'option tableau qui supprime complètement la requête de la boucle.
A la place de
Code:
$sqqql="SELECT * FROM kvd.products"; 
$answer = mysql_query($sqqql);
while ($answer_data = mysql_fetch_array($answer) )
{
if ($num_style!=$answer_data['products_model'])
echo"";
else
$count=$count+1;
}
Fais:
Code:
$products_model_array = array(); 
$sqqql="SELECT products_model FROM kvd.products"; 
$answer = mysql_query($sqqql);
while ($answer_data = mysql_fetch_array($answer) )
{
 $products_model_array[] = $answer_data['products_model'];
}
Et mets le avant la boucle.

Ensuite remplace
Code:
if($count != 0){
echo "$num_style existe<br>";
mysql_query("UPDATE kvd.products SET products_price='$prix' WHERE products_model = '$num_style'");
}else{
echo "$num_style existe pas et donc ajouter<br>";
mysql_query("INSERT INTO kvd.products (products_model, products_image, products_price, products_date_added, products_status, products_tax_class_id ) VALUES ('$num_style', '$vraiimage', '$prix', '$heuredate', '1', '1')");
}
par
Code:
if(in_array($num_style, $products_model_array))  // IE si le produit est déjà existant
{
	echo "$num_style existe<br>";
	$mon_sql = "UPDATE kvd.products SET products_price='$prix' WHERE products_model = '$num_style'";
}
else
{
	echo "$num_style existe pas et donc ajouter<br>";
	$mon_sql = "INSERT INTO kvd.products (products_model, products_image, products_price, products_date_added, products_status, products_tax_class_id ) VALUES ('$num_style', '$vraiimage', '$prix', '$heuredate', '1', '1')";
}
mysql_query($mon_sql);

Là si tu le veux, à la place de déclencher la requête par mysql_query($mon_sql) c'est le moment de la stocker dans ton fichier texte.

Mon avis sans avoir vu la suite: optimise les appels à la BDD et pour chaque script crée un fichier texte contenant toutes les requêtes à lancer.
Si le script merde tu n'auras qu'à le relancer, ça n'aura pas touché ta base de données.
Néanmoins ça devrait mieux se passer avec les modifications indiquées: les requêtes en elles mêmes sont petites.

Par ailleurs pourquoi 25 scripts? Une table clients, une produits, une produits/clients non?
Je mise mes 15 centimes Adsense quotidiens que l'on peut tout regrouper dans la joie à petit prix :D
 
WRInaute discret
Oui...tu a en effet bien remarqué que j'étais débutant en PHP et donc je réussi a faire ce que je veus faire la plus part du temps, mais souvent pas de la methode idéal...Un gros Merci pour ton aide et le temps que t'a pris pour les exemples c'est très apprécié! Je me mets au boullot! :D
 
WRInaute impliqué
Pas tellement débutant que ça pour avoir réussi à monter un site d'e-commerce :)
Fais signe si tu penses avoir besoin d'aide pour tes autres scripts.
 
Discussions similaires
Haut