Quelle est la meilleure façon de supprimer les commentaires d'un fichier PHP?
Je veux faire quelque chose de similaire à strip-whitespace () - mais cela ne devrait pas aussi supprimer les sauts de ligne.
PAR EXEMPLE:
Je veux ceci:
<?PHP
// something
if ($whatsit) {
do_something(); # we do something here
echo '<html>Some embedded HTML</html>';
}
/* another long
comment
*/
some_more_code();
?>
devenir:
<?PHP
if ($whatsit) {
do_something();
echo '<html>Some embedded HTML</html>';
}
some_more_code();
?>
(Bien que si les lignes vides restent là où les commentaires sont supprimés, ce ne serait pas correct).
Cela peut ne pas être possible, en raison de l'exigence de préserver le HTML intégré - c'est ce qui a déclenché les choses qui ont été trouvées sur Google.
J'utiliserais tokenizer . Voici ma solution. Il devrait fonctionner sur les deux PHP 4 et 5:
$fileStr = file_get_contents('path/to/file');
$newStr = '';
$commentTokens = array(T_COMMENT);
if (defined('T_DOC_COMMENT'))
$commentTokens[] = T_DOC_COMMENT; // PHP 5
if (defined('T_ML_COMMENT'))
$commentTokens[] = T_ML_COMMENT; // PHP 4
$tokens = token_get_all($fileStr);
foreach ($tokens as $token) {
if (is_array($token)) {
if (in_array($token[0], $commentTokens))
continue;
$token = $token[1];
}
$newStr .= $token;
}
echo $newStr;
Que diriez-vous d'utiliser php -w pour générer un fichier dépourvu de commentaires et d'espaces, puis d'utiliser un embellisseur comme PHP_Beautifier pour reformater la lisibilité?
$fileStr = file_get_contents('file.php');
foreach (token_get_all($fileStr) as $token ) {
if ($token[0] != T_COMMENT) {
continue;
}
$fileStr = str_replace($token[1], '', $fileStr);
}
echo $fileStr;
edit J'ai réalisé que Ionut G. Stan l'a déjà suggéré, mais je vais laisser l'exemple ici
Voici la fonction publiée ci-dessus, modifiée pour supprimer récursivement tous les commentaires de tous les fichiers php d'un répertoire et de tous ses sous-répertoires:
function rmcomments($id) {
if (file_exists($id)) {
if (is_dir($id)) {
$handle = opendir($id);
while($file = readdir($handle)) {
if (($file != ".") && ($file != "..")) {
rmcomments($id."/".$file); }}
closedir($handle); }
else if ((is_file($id)) && (end(explode('.', $id)) == "php")) {
if (!is_writable($id)) { chmod($id,0777); }
if (is_writable($id)) {
$fileStr = file_get_contents($id);
$newStr = '';
$commentTokens = array(T_COMMENT);
if (defined('T_DOC_COMMENT')) { $commentTokens[] = T_DOC_COMMENT; }
if (defined('T_ML_COMMENT')) { $commentTokens[] = T_ML_COMMENT; }
$tokens = token_get_all($fileStr);
foreach ($tokens as $token) {
if (is_array($token)) {
if (in_array($token[0], $commentTokens)) { continue; }
$token = $token[1]; }
$newStr .= $token; }
if (!file_put_contents($id,$newStr)) {
$open = fopen($id,"w");
fwrite($open,$newStr);
fclose($open); }}}}}
rmcomments("path/to/directory");
une version plus puissante: supprimez tous les commentaires du dossier
<?php
$di = new RecursiveDirectoryIterator(__DIR__,RecursiveDirectoryIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($di);
$fileArr = [];
foreach($it as $file){
if(pathinfo($file,PATHINFO_EXTENSION) == "php"){
ob_start();
echo $file;
$file = ob_get_clean();
$fileArr[] = $file;
}
}
$arr = [T_COMMENT,T_DOC_COMMENT];
$count = count($fileArr);
for($i=1;$i < $count;$i++){
$fileStr = file_get_contents($fileArr[$i]);
foreach(token_get_all($fileStr) as $token){
if(in_array($token[0],$arr)){
$fileStr = str_replace($token[1],'',$fileStr);
}
}
file_put_contents($fileArr[$i],$fileStr);
}
Si vous utilisez déjà un éditeur comme UltraEdit , vous pouvez ouvrir un ou plusieurs PHP fichier/s, puis utiliser un Recherche et remplacement simples (CTRL + R) avec l'expression rationnelle Perl suivante
(?s)/\*.*\*/
Attention, l'expression rationnelle ci-dessus supprime également les commentaires à l'intérieur d'une chaîne, c'est-à-dire dans echo "hello/*babe*/";
les /*babe*/
serait également supprimé. Par conséquent, cela pourrait être une solution si vous avez peu de fichiers pour supprimer les commentaires, afin d'être absolument sûr qu'il ne remplace pas à tort quelque chose qui n'est pas un commentaire, vous devrez exécuter la commande Rechercher et remplacer et approuver chaque fois ce qui est remplacé.
/*
* T_ML_COMMENT does not exist in PHP 5.
* The following three lines define it in order to
* preserve backwards compatibility.
*
* The next two lines define the PHP 5 only T_DOC_COMMENT,
* which we will mask as T_ML_COMMENT for PHP 4.
*/
if (! defined('T_ML_COMMENT')) {
define('T_ML_COMMENT', T_COMMENT);
} else {
define('T_DOC_COMMENT', T_ML_COMMENT);
}
/*
* Remove all comment in $file
*/
function remove_comment($file) {
$comment_token = array(T_COMMENT, T_ML_COMMENT, T_DOC_COMMENT);
$input = file_get_contents($file);
$tokens = token_get_all($input);
$output = '';
foreach ($tokens as $token) {
if (is_string($token)) {
$output .= $token;
} else {
list($id, $text) = $token;
if (in_array($id, $comment_token)) {
$output .= $text;
}
}
}
file_put_contents($file, $output);
}
/*
* Glob recursive
* @return ['dir/filename', ...]
*/
function glob_recursive($pattern, $flags = 0) {
$file_list = glob($pattern, $flags);
$sub_dir = glob(dirname($pattern) . '/*', GLOB_ONLYDIR);
// If sub directory exist
if (count($sub_dir) > 0) {
$file_list = array_merge(
glob_recursive(dirname($pattern) . '/*/' . basename($pattern), $flags),
$file_list
);
}
return $file_list;
}
// Remove all comment of '*.php', include sub directory
foreach (glob_recursive('*.php') as $file) {
remove_comment($file);
}
Exécutez la commande php --strip file.php
dans une invite de commande (ie cmd.exe ), puis accédez à http://www.writephponline.com/phpbeautifier.
Ici, file.php est votre propre fichier.
Solution bash: Si vous souhaitez supprimer récursivement les commentaires de tous les fichiers PHP à partir du répertoire courant, vous pouvez écrire dans le terminal ce one-liner. (Il utilise temp1
fichier à stocker PHP contenu pour le traitement) Notez que cela supprimera tous les espaces blancs avec des commentaires.
find . -type f -name '*.php' | while read VAR; do php -wq $VAR > temp1 ; cat temp1 > $VAR; done
Vous devez ensuite supprimer temp1
fichier après.
si PHP_BEAUTIFER est installé alors vous pouvez obtenir du code bien formaté sans commentaires avec
find . -type f -name '*.php' | while read VAR; do php -wq $VAR > temp1; php_beautifier temp1 > temp2; cat temp2 > $VAR; done;
puis supprimez deux fichiers (temp1
, temp2
)
Pour les réponses ajax/json, j'utilise le code PHP code, pour supprimer les commentaires du code HTML/JavaScript, il serait donc plus petit (gain d'environ 15% pour mon code).
// Replace doubled spaces with single ones (ignored in HTML any way)
$html = preg_replace('@(\s){2,}@', '\1', $html);
// Remove single and multiline comments, tabs and newline chars
$html = preg_replace(
'@(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|((?<!:)//.*)|[\t\r\n]@i',
'',
$html
);
Court et efficace, mais peut produire des résultats inattendus si votre code a la syntaxe $ itty.
en 2019 pourrait fonctionner comme ça
<?php
/* hi there !!!
here are the comments */
//another try
echo removecomments('index.php');
/* hi there !!!
here are the comments */
//another try
function removecomments($f){
$w=Array(';','{','}');
$ts = token_get_all(php_strip_whitespace($f));
$s='';
foreach($ts as $t){
if(is_array($t)){
$s .=$t[1];
}else{
$s .=$t;
if( in_array($t,$w) ) $s.=chr(13).chr(10);
}
}
return $s;
}
?>
si vous voulez voir les résultats, exécutons-le d'abord dans xampp, puis vous obtenez une page vierge, mais si vous faites un clic droit et cliquez sur voir la source, vous obtenez votre script php .. il se charge et supprime tous les commentaires et aussi les onglets. je préfère aussi cette solution car je l'utilise pour accélérer mon framework un moteur de fichiers "m.php" et après php_strip_whitespace toutes les sources sans ce script que j'observe est le plus lent: j'ai fait 10 benchmarks puis je calcule la moyenne mathématique (je pense php 7 rétablit les manquements cr_lf lors de l'analyse ou prend un certain temps lorsque ceux-ci sont manquants)
Le hic, c'est qu'un algorithme de correspondance moins robuste (regex simple, par exemple) commencera à se déshabiller ici alors qu'il ne devrait clairement pas:
if (preg_match('#^/*' . $this->index . '#', $this->permalink_structure)) {
Cela n'affectera peut-être pas votre code, mais finalement, quelqu'un sera mordu par votre script. Vous devrez donc utiliser un utilitaire qui comprend plus la langue que vous ne le pensez.
-Adam
php -w
Ou php_strip_whitespace($filename);