أفضل طريقة لإزالة التعليقات تلقائيًا من كود PHP

StackOverflow https://stackoverflow.com/questions/503871

  •  20-08-2019
  •  | 
  •  

سؤال

ما هي أفضل طريقة لإزالة التعليقات من ملف 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.

هل كانت مفيدة؟

المحلول

وكنت تستخدم tokenizer . وهنا قال لي الحل. يجب أن تعمل على كلا PHP 4 و 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;

نصائح أخرى

وماذا عن استخدام فب -w لإنشاء ملف تجريده من التعليقات وبيضاء، ثم استخدام المجمل مثل PHP_Beautifier لإعادة لهذين؟

$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;

يحررأدركت إيونوت ج.لقد اقترح ستان هذا بالفعل، لكنني سأترك المثال هنا

إليك وظيفة نشرت أعلاه، تعديل لإزالة متكرر كل التعليقات من جميع ملفات 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");

ونسخة أكثر قوة: إزالة جميع التعليقات في المجلد

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

إذا كنت تستخدم بالفعل محررًا مثل تحرير فائق, ، يمكنك فتح ملف/ملفات PHP واحدة أو متعددة ثم استخدام ملف بحث واستبدال بسيط (CTRL+R) مع بيرل التالية regexp

(?s)/\*.*\*/

احذر من أن التعبير العادي أعلاه يزيل أيضًا التعليقات داخل السلسلة، على سبيل المثال.في echo "hello/*babe*/"; ال /*babe*/ ستتم إزالتها أيضًا.ومن ثم، يمكن أن يكون حلاً إذا كان لديك عدد قليل من الملفات لإزالة التعليقات، للتأكد تمامًا من أنه لا يستبدل بشكل خاطئ شيئًا ليس تعليقًا، فيجب عليك تشغيل أمر البحث والاستبدال والموافقة في كل مرة على ما يتم استبداله.

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

لردود اياكس / سلمان، يمكنني استخدام التعليمات البرمجية التالية PHP، لإزالة التعليقات من التعليمات البرمجية HTML / جافا سكريبت، لذلك سيكون أصغر (ربح حوالي 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
);

وقصيرة وفعالة، ولكن يمكن أن تعطي نتائج غير متوقعة، إذا كان رمز لديه $ جملة itty.

حل باش:إذا كنت تريد إزالة التعليقات بشكل متكرر من جميع ملفات 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, temp2 )

وتشغيل php --strip file.php الأمر في موجه الأوامر (أي CMD.EXE )، ثم استعرض إلى <م> <وأ href = "http://www.writephponline.com/phpbeautifier" يختلط = "نوفولو noreferrer"> http://www.writephponline.com/phpbeautifier .

وهنا، <م> file.php هو ملف خاص بك.

والصيد هو أن خوارزمية أقل قوة مطابقة (رجإكس بسيط، على سبيل المثال) سيبدأ تجريد هنا عندما لا ينبغي بوضوح:

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

قد لا تؤثر على الشفرة الخاصة بك، ولكن في النهاية شخص سوف تحصل شيئا السيناريو الخاص بك. لذلك سوف تضطر إلى استخدام الأداة التي تدرك أكثر من لغة مما قد تتوقع غير ذلك.

و-Adam

في عام 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 النصي الخاص بك ..فهو يقوم بتحميل نفسه ويزيل جميع التعليقات وعلامات التبويب أيضًا.أفضل هذا الحل أيضًا لأنني أستخدمه لتسريع محرك ملف واحد لإطار العمل الخاص بي "m.php" وبعد php_strip_whitespace كل المصدر بدون هذا البرنامج النصي الذي ألاحظه هو الأبطأ: لقد أجريت 10 معايير ثم قمت بحساب متوسط ​​الرياضيات (أعتقد php) 7 هو استعادة العناصر المفقودة cr_lf عند التحليل أو يستغرق بعض الوقت عندما تكون مفقودة)

وphp -w أو php_strip_whitespace($filename);

الوثائق

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top