56 votes

Le meilleur moyen de supprimer automatiquement les commentaires du code PHP

Quel est le meilleur moyen de supprimer les commentaires à partir d'un fichier PHP?

Je veux faire quelque chose de similaire à la bande-espace (), mais il ne doit pas supprimer les sauts de ligne ainsi.

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();
?>

pour devenir:

<?PHP
if ($whatsit) {
    do_something();
    echo '<html>Some embedded HTML</html>';
}
some_more_code();
?>

(Bien que si les lignes vides restent où les commentaires sont supprimés, ce ne serait pas ok).

Il peut ne pas être possible à cause de l'exigence de préserver embedded html - thats whats trébucher les choses qui viennent sur google.

69voto

Ionuț G. Stan Points 62482

J'utiliserais tokenizer . Voici ma solution. Cela devrait fonctionner sur 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;
 

45voto

Paul Dixon Points 122033

Pourquoi ne pas utiliser php -w pour générer un fichier dépourvu de commentaires et d’espaces, puis utiliser un beautifier tel que PHP_Beautifier pour reformater afin d’en améliorer la lisibilité?

9voto

Tom Haigh Points 32314
 $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;
 

modifier J'ai réalisé que Ionut G. Stan avait déjà suggéré cela, mais je vais laisser l'exemple ici

9voto

John Tyler Points 21

Voici la fonction publiée ci-dessus, modifiée pour supprimer de manière récursive 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");
 

2voto

Steely Wing Points 1857
/*
* 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);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X