如何检测结束 php 标签?

How to detect closing php tag?

使用 bash 或 php,我如何检测文件中 php 的最后一个块是否有结束标记,而不考虑尾随换行符或空格?

这是我目前所知道的,但我不知道如何确定结束标记之后的内容是否更多 php。

#!/bin/bash
FILENAME=""
closed=false

# just checking the last 10 lines
# should be good enough for this example
for line in $(tail $FILENAME); do
  if [ "$line" == "?>" ]; then
    closed=true
  else
    closed=false
  fi
done

if $closed; then
  exit 1
else
  exit 0
fi

我用测试运行器脚本编写了一些测试。

#!/bin/bash
for testfile in $(ls tests); do
  ./closed-php.bash tests/$testfile
  closed=$?
  if [ $closed -eq 1 -a "true"  == ${testfile##*.} ] || 
     [ $closed -eq 0 -a "false" == ${testfile##*.} ]; then
    echo "[X] $testfile"
  else
    echo "[ ] $testfile"
  fi
done

你可以 clone these files,但这就是我目前所知道的。

.
├── closed-php.bash
├── test.bash
└── tests
    ├── 1.false
    ├── 2.true
    ├── 3.true
    ├── 4.true
    ├── 5.false
    └── 6.false
  1. 错误:

    <?php
    $var = 'value';
    
  2. 正确:

    <?php
    $var = 'value';
    ?>
    
  3. 正确:

    <?php
    $var = 'value';
    ?><!DOCTYPE>
    
  4. 正确:

    <?php
    $var = 'value';
    ?>
    <!DOCTYPE>
    
  5. 错误:

    <?php
    $var = 'value';
    ?>
    <!DOCTYPE>
    <?php
    $var = 'something';
    
  6. 错误:

    <?php
    $var = 'value';
    ?><?php
    $var = 'something';
    

我没有通过 3 和 4,因为我不知道结束标记之后的内容是否更多 php。

[X] 1.false
[X] 2.true
[ ] 3.true
[ ] 4.true
[X] 5.false
[X] 6.false

感谢Ryan Vincent's comment, this was pretty easy when using token_get_all

<?php
$tokens = token_get_all(file_get_contents($argv[1]));
$return = 0;
foreach ($tokens as $token) {
  if (is_array($token)) {
    if (token_name($token[0]) === 'T_CLOSE_TAG')
      $return = 0;
    elseif (token_name($token[0]) === 'T_OPEN_TAG')
      $return = 1;
  }
}
exit ($return);

我什至添加了几个测试,你可以see the full solution here