🔒 Connexion

🔄 Migration de version

Modernisez votre code entre deux versions d'un même langage : PHP 5.6 vers 7.x ou 8.x, Python 2 vers 3, MySQL 5.7 vers 8.0, MySQL et MariaDB dans les deux sens, Oracle 11g vers 19c. Ce qui se corrige sans risque est appliqué ; ce qui demande un arbitrage est signalé, ligne par ligne, sans être touché. Tout se passe dans votre navigateur — votre code ne quitte pas votre machine.

Rapport

Corrigé : réécrit sans risque. À vérifier : réécrit, mais relisez. À reprendre : signalé, votre code n'a pas été modifié. Information : rien à faire, mais bon à savoir.

Aucune analyse pour le moment.

Migrer un fichier ou une archive

Déposez un fichier .php, .py, .sql, ou une archive .zip contenant un projet entier. Chaque fichier est migré selon son extension ; les autres sont recopiés sans être touchés. L'archive est reconstruite à l'identique, arborescence comprise. Rien n'est envoyé sur le réseau : lecture, transformation et réécriture se font dans votre navigateur.

ou glissez-le ici

Pourquoi un migrateur plutôt qu'un traducteur

Passer de PHP 5.6 à PHP 8 n'est pas une traduction : c'est le même langage, dont certaines constructions ont disparu et d'autres ont changé de comportement. La liste des ruptures est publiée, finie et vérifiable — ce qui rend l'opération mécanisable, contrairement à une conversion entre deux langages différents où la moindre ligne suppose un choix de conception.

Le même raisonnement vaut d'une version 3 à une autre. Python ne casse presque jamais la syntaxe, mais retire des modules de sa bibliothèque standard : distutils en 3.12, dix-neuf modules d'un coup en 3.13. Le code reste valide — il ne démarre simplement plus. Ce sont des listes publiées, donc vérifiables.

Cet outil s'en tient donc à ce périmètre. Il ne prétend pas transformer du Python en Java : un tel résultat compile parfois et se comporte autrement, ce qui est le pire des résultats puisqu'il inspire confiance.

Ce qui est réécrit, et ce qui ne l'est pas

Une réécriture n'est appliquée que lorsqu'elle est équivalente : array() en crochets, $s{0} en $s[0], isset($a) ? $a : $b en $a ?? $b, print "x" en print("x"). Ces transformations ne changent ni le résultat ni les cas limites.

Tout le reste est signalé sans être touché. Un appel mysql_query() ne devient pas du PDO par substitution : il faut reprendre la connexion, la gestion des erreurs et l'échappement. Un outil qui produirait ici du code d'apparence correcte rendrait un mauvais service.

MySQL, MariaDB, Oracle : ce que change une version

Le SQL se prête particulièrement bien à cet exercice, parce que ses ruptures sont peu nombreuses et documentées. Passer de MySQL 5.7 à 8.0, c'est surtout une vingtaine de mots devenus réservés — rank, row, groups, system —, la disparition de PASSWORD(), celle du tri implicite du GROUP BY, et le préfixe ST_ devenu obligatoire sur les fonctions spatiales.

Entre MySQL et MariaDB, la difficulté n'est plus la version mais la divergence : les collations utf8mb4_0900_* et JSON_TABLE() n'existent pas côté MariaDB, tandis que les séquences, RETURNING et CREATE OR REPLACE TABLE n'existent pas côté MySQL. Un fichier de sauvegarde restauré dans l'autre moteur échoue le plus souvent sur la collation, dès la première table.

Côté Oracle, les ruptures purement syntaxiques sont rares : l'essentiel des points relevés concerne des constructions devenues inutiles — la pagination par ROWNUM depuis que FETCH FIRST existe, le couple séquence et déclencheur depuis les colonnes IDENTITY — ou dépréciées, comme DBMS_JOB. C'est le jeu de règles le plus mince des quatre, et il faut le savoir.

Le code ne quitte pas votre navigateur

L'analyse s'exécute entièrement en JavaScript, sur votre machine. Aucun envoi, aucun enregistrement, aucune trace côté serveur — ce qui compte quand on colle du code appartenant à un client ou à un employeur.

Cela vaut aussi pour les archives. Une archive ZIP est lue, décompressée, migrée puis reconstruite dans l'onglet, sans qu'un seul octet transite. La décompression s'appuie sur une fonction native du navigateur plutôt que sur une bibliothèque tierce, ce qui évite d'ajouter trois cents kilooctets de code à charger — et un intermédiaire de plus à qui faire confiance.

Traiter un projet entier

Déposez une archive et chaque fichier est migré selon son extension : .php, .phtml, .inc côté PHP, .py côté Python, .sql côté base. Tout le reste — images, feuilles de style, fichiers de configuration — est recopié sans être touché, et l'arborescence est restituée à l'identique.

Les dossiers vendor/, node_modules/, .git/ et wp-admin/ sont ignorés par défaut : ce code appartient à des tiers, le réécrire ferait diverger le projet de sa source sans aucun gain, et la prochaine mise à jour effacerait le travail. La case se décoche si vous savez pourquoi vous le faites.

Un fichier source qui n'est pas en UTF-8 est recopié tel quel plutôt que réécrit : mieux vaut le laisser intact que le corrompre. Le rapport le signale ligne par ligne, fichier par fichier.

Les chaînes et les commentaires sont protégés

Avant toute transformation, le texte est parcouru pour repérer les chaînes, les commentaires et les heredocs, qui sont mis de côté. Un array( écrit dans un commentaire ou une parenthèse à l'intérieur d'une chaîne ne sont donc jamais confondus avec du code — c'est précisément là que se cassent les outils fondés sur de simples expressions régulières.

Le résultat est-il utilisable directement en production ?
Non, et aucun outil de ce type ne devrait le prétendre. Les corrections marquées « corrigé » sont sûres, mais un fichier n'est migré que lorsqu'il a été relu et que les points « à reprendre » ont été traités. Considérez le rapport comme une liste de tâches, pas comme un certificat.
Pourquoi ne pas convertir PHP en Python, ou Python en Java ?
Parce que les différences ne sont pas syntaxiques. Les entiers Python n'ont pas de limite de taille, ceux de Java débordent silencieusement ; le typage dynamique n'a pas de contrepartie dans un langage à typage nominal ; générateurs, décorateurs et héritage multiple demandent des décisions d'architecture. Sans compter les bibliothèques : un script de trente lignes qui importe pandas n'a pas d'équivalent ligne à ligne.
Je suis déjà en Python 3, cet outil me sert-il ?
Oui : choisissez la version visée dans le sélecteur. Passer de 3.9 à 3.12 supprime distutils, de 3.12 à 3.13 retire dix-neuf modules de la bibliothèque standard — cgi, telnetlib, crypt et les autres « piles usagées » du PEP 594. Ce ne sont pas des erreurs de syntaxe : le fichier se lit très bien, il échoue à l'import. Un outil qui parcourt le code les trouve avant la mise en production.
La division Python est-elle vraiment un piège ?
C'est la rupture la plus silencieuse de Python 2 vers 3. 7 / 2 valait 3, il vaut 3.5. Aucune erreur n'est levée, le programme continue — et les résultats sont faux là où l'on attendait une division entière. C'est pourquoi l'outil la signale même sans rien réécrire : le remplacement par // dépend de l'intention, que seul l'auteur connaît.
Que faire des appels mysql_* ?
Ils ont disparu en PHP 7.0 et se reprennent en PDO ou mysqli. Ce n'est pas un renommage : la connexion devient un objet, les erreurs se lèvent en exceptions selon la configuration, et les requêtes doivent être préparées plutôt que concaténées — ce qui est d'ailleurs l'occasion de corriger d'anciennes injections SQL.
Mon code contient des heredocs, est-ce géré ?
Oui, heredocs et nowdocs sont reconnus et protégés. La différence compte : un nowdoc (délimiteur entre apostrophes) n'interpole rien, un heredoc si — donc seul le second peut contenir une écriture ${var} à corriger pour PHP 8.2.
Pourquoi la collation fait-elle échouer une restauration MySQL vers MariaDB ?
Parce que MySQL 8.0 écrit par défaut utf8mb4_0900_ai_ci, une collation fondée sur Unicode 9.0 que MariaDB n'implémente pas. Le fichier de sauvegarde la mentionne à chaque table, et l'import s'arrête sur la première. Le remplacement le plus proche est utf8mb4_general_ci, ou utf8mb4_uca1400_ai_ci sur MariaDB 10.10 et suivants — sachant que l'ordre de tri ne sera pas rigoureusement identique.
Puis-je migrer plusieurs fichiers d'un coup ?
Oui : déposez une archive ZIP de votre projet. Chaque fichier reconnu est migré, les autres sont recopiés, et vous récupérez une archive complète. Sur un dépôt vivant, Rector côté PHP et 2to3 côté Python restent préférables — ils s'intègrent à Git et rejouent la migration à chaque commit, là où le dépôt d'archive est un traitement ponctuel.
Quelle taille d'archive est acceptée ?
Tout se passe en mémoire, dans l'onglet : quelques dizaines de mégaoctets et quelques milliers de fichiers passent sans peine, au-delà l'onglet peut saturer. Décocher l'exclusion de vendor/ sur un projet Composer suffit souvent à faire basculer une archive de raisonnable à lourde. Les archives ZIP64 — au-delà de quatre gigaoctets — sont refusées explicitement.
Mon fichier .php n'est pas reconnu, pourquoi ?
La détection se fait sur l'extension. Sont traités : .php, .phtml, .inc, .module, .install, .theme, .py, .pyw, .sql, .ddl. Un fichier sans extension, ou avec une extension maison, est recopié sans analyse — renommez-le, ou collez son contenu dans le champ ci-dessus.