Discussion:
Enchainer des fichiers .php
(trop ancien pour répondre)
Denis Beauregard
2009-11-24 22:44:50 UTC
Permalink
Bonjour,

Mon hébergeur a bloqué la fonction mysql LOAD INFILE et je
dois la remplacer par une série d'énoncés SQL.

Le hic, c'est que j'ai 2,5 millions d'énoncés à insérer...


Y a-t-il une méthode simple pour qu'une page en PHP soit
exécutée, puis après un temps arbitraire (au retour de la
fonction mysql_query par exemple) appeler une autre page ?

Comme alternative, je pourrais lire les énoncés SQL dans un
fichier et les envoyer à mysql_query un après l'autre mais
j'aurais encore le problème de l'enchaînement des pages PHP.

J'avais pensé à un énoncé <img src="page412.php">
à la fin de la page, mais cela ne me semble pas très élégant.


Denis
CrazyCat
2009-11-25 14:48:35 UTC
Permalink
Post by Denis Beauregard
Mon hébergeur a bloqué la fonction mysql LOAD INFILE et je
dois la remplacer par une série d'énoncés SQL.
Est-ce que par hasard tu ne pourrais pas utiliser la commande MySQL
"SOURCE" ?
Post by Denis Beauregard
Y a-t-il une méthode simple pour qu'une page en PHP soit
exécutée, puis après un temps arbitraire (au retour de la
fonction mysql_query par exemple) appeler une autre page ?
Rien ne t'empèche, si ta page n'affiche rien (n'envoie pas de headers),
de faire en fin de script quelque chose comme:
<?php
sleep(100);
header("Location: page.php?num=1");
?>
--
Réseau IRC Francophone: http://www.zeolia.net
Aide et astuces : http://www.g33k-zone.org
Communauté Francophone sur les Eggdrops: http://www.eggdrop.fr
Olivier Miakinen
2009-11-25 14:48:35 UTC
Permalink
Post by Denis Beauregard
Y a-t-il une méthode simple pour qu'une page en PHP soit
exécutée, puis après un temps arbitraire (au retour de la
fonction mysql_query par exemple) appeler une autre page ?
<meta http-equiv="refresh" content="60; URL=http://truc/page2"> ?
--
Olivier Miakinen
Pascal
2009-11-25 14:48:35 UTC
Permalink
Post by Denis Beauregard
Bonjour,
Bonjour,
Post by Denis Beauregard
Mon hébergeur a bloqué la fonction mysql LOAD INFILE et je
dois la remplacer par une série d'énoncés SQL.
Le hic, c'est que j'ai 2,5 millions d'énoncés à insérer...
Je pense à une solution intermédiaire, qui consisterait à utiliser LOAD
INFILE sur une installation locale où serait dupliquée la structure de
la table, puis un export en SQL des données vers un fichier, toujours
local, qu'il suffira de passer en import au serveur via l'interface
d'administration MySQL de l'hébergeur (phpMyAdmin, je suppose).

Faut juste faire attention au volume (en MB) et, peut-être, faire un
import par lot.

Cordialement,
Pascal
Jean-Francois Ortolo
2009-11-25 14:48:35 UTC
Permalink
Post by Denis Beauregard
Bonjour,
Mon hébergeur a bloqué la fonction mysql LOAD INFILE et je
dois la remplacer par une série d'énoncés SQL.
Le hic, c'est que j'ai 2,5 millions d'énoncés à insérer...
Y a-t-il une méthode simple pour qu'une page en PHP soit
exécutée, puis après un temps arbitraire (au retour de la
fonction mysql_query par exemple) appeler une autre page ?
Comme alternative, je pourrais lire les énoncés SQL dans un
fichier et les envoyer à mysql_query un après l'autre mais
j'aurais encore le problème de l'enchaînement des pages PHP.
J'avais pensé à un énoncé<img src="page412.php">
à la fin de la page, mais cela ne me semble pas très élégant.
Denis
Bonjour Monsieur

A supposer au pire qu'il y ait au moins une table SQL qui ne puisse
pas être lue d'une traite, vous avez certainement des index dans vos
tables, tels qu'il soit possible de lire vos tables de manière
fractionnée, en spécifiant des sélection du genre

"SELECT * FROM table WHERE index LIKE <expression> ORDER BY index;"

A ce moment-là, vous alimentez une variable indicée du type :

$table[0] = "table_1";
$table[1] = "table_2";
$table[2] = "table_3";
... etc ...

En début de votre script, et puis éventuellement une autre variable
indicée à deux indices :

$critere[0][0] = "critere_1_1";
$critere[0][1] = "critere_1_2";
... etc ...
$critere[1][0] = "critere_2_1";
$critere[1][1] = "critere_2_2;
... etc ...


Vous avez donc un simple script comportant au début toutes ces
affectations. Pour chaques tables, vous voulez les sauver chacune dans
un fichier ASCII avec tous leurs champs, séparés mettons par un
caractère "\t" ( tout autre caractère sera correct, pourvu qu'il soit
discriminant ). Le nom du fichier sera indexé pareil ( n'importe quel
préfixe fait l'affaire ) :

$fichier[0] = "fichier_1";
$fichier[1] = "fichier_2";
... etc ...

Après toutes ces affectations, vous avez donc le script, qui doit
être lancé plusieurs fois, pour fractionner les écritures dans chaque
fichiers.

Vous devez donc avoir deux paramètres : Mettons $i et $j

Le script sera lancé sur votre navigateur, avec les paramètres $i=0
et $j=0, et s'exécutera tant que :

- Soit la table courante sera entièrement lue et écrite dans le
fichier correspondant,

- Soit la durée d'exécution du script mesurée après chaque
incrémentation du paramètre $j à l'intérieur du script, du script excède
un délai qui dépend du délai maximum d'exécution du script.

Je vous conseille de fixer cette limite à 1/3 ou 1/4 de ce délai
maximum d'exécution, pour laisser, si limite non atteinte, le temps à
l'itération suivante de $j, de s'effectuer.

- Soit, après incrémentation de $j à l'intérieur du script, $j
devient supérieur à $j_max[$i] ( $j_max[$i] est la valeur maximale de $j
telle que $critere[$i][$j] a été alimentée en début de script ).


Si l'une des conditions ci-dessus n'est pas vérifiée, vous devz
fermer le fichier en cours, puis vous avez deux solution :

- Soit la table courante a été entièrement lue et écrite dans le
fichier correspondant. Dans ce cas, vous incrémentez $i, vous fixez $j =
0, puis vous vérifiez si $table[$i] est alimentée, dans ce cas, vous
faites une instruction de relocation 302 avec header, du type :

header("Location: votre_script.php?i=$i&j=0");
exit;

Ces deux instructions vous permettent de relancer facilement le même
script, avec les paramètres ajustés.


- Soit la table courante n'a pas été entièrement lue et écrite dans
le fichier correspondant, auquel cas vous avez encore deux solutions :

- La durée d'exécution mesurée après chaque incrémentation du
paramètre $j dans le script, excède le délai fixé. Vous devez fermer le
fihcier courant avec fclose($fp); A ce moment-là, vous avez incrémenté
$j, si $criter[$i][$j] est alimenté, même chose : Il faut faire une
redirection 302 avec ces deux paramètres :

header("Location: votre_script.php?i=$i&j=$j");
exit;

- Enfin, deuxième solution de la deuxième solution ;) $j après
incrémentation devien supérieur à $j_max[$i]. En fait celà revient à
dire que la table courante a été entièrement lue et écrite dans le fichier.

Donc vous incrémentez $i, puis si $table[$i] est alimentée, vous
faites une relocation pareil, avec $j = 0:

header("Location: votre_script.php?i=$i&j=0");
exit;


Voilà. Tout le problème est de fixer les critères $critere[$i][$j]
suivant les dimensions et le contenu des tables, pour qu'un lecture
d'une table sur ce critère, puisse être faite en un seul lancement de
script.

C'est à vous à examiner le contenu des tables, faires des SELECT sur
critères ( probablement avec PhpMyAdmin ), pour trouver des critères pas
trop sélectifs, mais pas trop gourmands en quantité d'enregistrements.

Une choses encore: Vous devez ouvrir en début de script ( après
affectation des variables indicées ), le fichier en append, et non pas
en écriture simple.

Voici donc l'instruction :

$fp = @fopen($fichier[$i][$j], "a");
if(!$fp)
{
echo "Erreur a l'ouverture du fichier $fichier[$i][$j] en append<br>\n";
exit;
}


En ce qui me concerne, mon hébergeur me fournit la possibilité de
faire des sauvegardes avec une interface web déclenchant l'utilitaire
mysql_dump.

Bien à vous.

Amicalement.

Jean-François Ortolo
Jean-Francois Ortolo
2009-11-25 22:50:42 UTC
Permalink
Rebonjour

Je me suis trompé dans les requêtes sur critères.

Sachant qu'il y a un certain nombre de critères :

$critere[0][0] = "...";
$critere[0][1] = "...";
$critere[0][2] = "...";

...etc...

$critere[1][0] = "...";

...etc...

Et surtout ( j'avais oublié celà : )

$index[0] = "...";
$index[1] = "...";

... etc...


Les ordres SQL sont les suivants :

$sql = "SELECT * from $table[$i] WHERE $index[$i]>=$critere[$i][$j]
AND index[$i]<$critere[$i][$j + 1] ORDER BY index";

Ceci éatant entre quotes doubles, les variables sont interprétées.

Pour $index[$i] , vous prenez de préférence une PRIMARY KEY de la
table $table[$i] , ce n'est théoriquement pas strictement nécessaire,
pourvu que ce soit un index, quel que soit son type ( alphabétique ou
numérique ), peut importe.

Donc, pour chaque $i vous avez une liste de limites des select, puis
vous terminez la liste ( pour chaque $i ) par un critère correspondant à
$critere[$i][$j_max[$i]] plus grand que la plus grande valeur de index
dans la table $table[$i]

Evidemment, pour chaque $i vous affectez $j_max[$i] en début de script.

Cette méthode de sélection assure, qu'il n'y aura pas
d'enregistrements copiés plusieurs fois dans le fichier correspondant.

Pour le problème du traitement en fin de SELECT : mesure du temps
écoulé depuis le début du script, vérification que le délai est
inférieur à la limite fixée ( en fonction du délai maximum d'exécution
d'un script, fixé par votre hébergeur ), puis traitement en fonction des
conditions non remplies, vous incrémentez si besoin $j, puis si
$j>=$j_max[$i] , sortie de la boucle, fermeture du fichier ( fclose($fp
); ), puis incrémentation de $i, vérification que $table[$i] existe.

Si $table[$i] existe, lancement du même script avec les paramètre
i=$i et j=0 , sinon le traitement est terminé.

Simple n'est-ce pas ?

Bien à vous.

Amicalement.

Jean-François Ortolo

Denis Beauregard
2009-11-25 22:50:43 UTC
Permalink
Le 24 Nov 2009 22:44:50 GMT, Denis Beauregard
Post by Denis Beauregard
Bonjour,
Mon hébergeur a bloqué la fonction mysql LOAD INFILE et je
dois la remplacer par une série d'énoncés SQL.
Le hic, c'est que j'ai 2,5 millions d'énoncés à insérer...
Y a-t-il une méthode simple pour qu'une page en PHP soit
exécutée, puis après un temps arbitraire (au retour de la
fonction mysql_query par exemple) appeler une autre page ?
Merci à tous pour les idées.

Voici ce que je suis en train de faire.

- un petit logiciel en C++ qui va transformer la BDD en énoncés
SQL, sans doute par blocs de 10 ou 100 insertions (il y a en
moyenne 240 caractères par ligne et 23 champs). Le résultat
sera quelque chose comme 25 fichiers de 100000 insertions.
- un script en PHP qui va lire chaque ligne, faire l'insertion
et noter ce qu'il a fait, via une session. Un premier essai
pour évaluer combien d'insertions avant le time out, puis on
fera le 1/3 de ce nombre, avec un header() pour enchaîner au
suivant.

25 fichiers, c'est parce qu'il faudra sauter un certain nombre
de lignes. 25, cela donne autour de 24 Mo par fichier, ce qui
n'est pas trop élevé je pense, mais je verrai à l'usage.


Denis
Continuer la lecture sur narkive:
Loading...