54

PHPファイルからコメントを削除する最良の方法は何ですか?

strip-whitespace() と同様のことをしたいのですが、改行も削除しないでください。

例えば、

これ欲しい:

<?PHP
// something
if ($whatsit) {
    do_something(); # we do something here
    echo '<html>Some embedded HTML</html>';
}
/* another long
comment
*/
some_more_code();
?>

なる:

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

(ただし、コメントを削除したところに空行が残っていても問題ありません。)

埋め込まれた HTML を保持する必要があるため、それは不可能かもしれません。これが、Google で出てきたものをつまずかせた原因です。

4

14 に答える 14

64

トークナイザーを使用します。これが私の解決策です。PHP4と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;
于 2009-02-02T16:53:54.293 に答える
45

php -w <sourcefile>コメントと空白を取り除いたファイルを生成するために使用し、次にPHP_Beautifierなどのビューティファイアを使用して読みやすくするために再フォーマットします。

于 2009-02-02T17:02:22.247 に答える
9
$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;
于 2009-02-02T17:06:17.467 に答える
9

上記の関数は、ディレクトリとそのすべてのサブディレクトリ内のすべての PHP ファイルからすべてのコメントを再帰的に削除するように変更されています。

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");
于 2011-11-15T10:49:31.503 に答える
4

より強力なバージョン: フォルダー内のすべてのコメントを削除します

<?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);
    }
于 2016-01-03T14:47:15.073 に答える
2

Bash ソリューション: 現在のディレクトリから始まるすべての PHP ファイルから再帰的にコメントを削除する場合は、ターミナルでこのワンライナーを記述できます。(temp1ファイルを使用して、処理用の PHP コンテンツを保存します。)

これにより、コメントですべての空白が削除されることに注意してください。

 find . -type f -name '*.php' | while read VAR; do php -wq $VAR > temp1  ;  cat temp1 > $VAR; done

temp1その後、ファイルを削除する必要があります。

PHP_BEAUTIFERがインストールされている場合、コメントなしで適切にフォーマットされたコードを取得できます

 find . -type f -name '*.php' | while read VAR; do php -wq $VAR > temp1; php_beautifier temp1 > temp2;  cat temp2 > $VAR; done;

temp1次に、2 つのファイル (と)を削除しますtemp2

于 2016-08-13T03:53:48.073 に答える
1

Ajax および JSON 応答の場合、次の PHP コードを使用して HTML/JavaScript コードからコメントを削除し、サイズを小さくします (私のコードでは約 15% の向上)。

// 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
);

短くて効果的ですが、コードの構文が不適切な場合、予期しない結果が生じる可能性があります。

于 2013-06-18T17:39:02.813 に答える
1

2019年には、次のように機能する可能性があります。

<?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;
}

?>

結果を確認したい場合は、最初にXAMPPで実行してみましょう。空白のページが表示されますが、右クリックしてソースの表示をクリックすると、PHP スクリプトが取得されます...それ自体が読み込まれ、すべてが削除されますコメントとタブ。

フレームワークの 1 つのファイル エンジン "m.php" を高速化するために使用し、php_strip_whitespaceの後、このスクリプトを使用しないすべてのソースが最も遅くなるため、私もこのソリューションを好みます。10 個のベンチマークを実行してから、数学の平均 ( PHP 7 は、解析中に欠落している cr_lf を復元しているか、欠落しているときに時間がかかっていると思います)。

于 2019-05-20T10:52:45.537 に答える
1
/*
* 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);
}
于 2013-04-08T14:39:20.933 に答える
0

問題は、堅牢性の低いマッチング アルゴリズム (単純な正規表現など) が、明らかにすべきではない場合に、ここで削除を開始することです。

if (preg_match('#^/*' . $this->index . '#', $this->permalink_structure)) {  

あなたのコードには影響しないかもしれませんが、最終的に誰かがあなたのスクリプトに噛み付くでしょう。そのため、予想以上に言語を理解できるユーティリティを使用する必要があります。

于 2009-02-02T16:51:14.563 に答える
0

php -wまたphp_strip_whitespace($filename);

ドキュメンテーション

于 2019-07-11T10:33:57.533 に答える