如何从字符串中删除 php 代码?

发布于 2024-09-10 12:43:17 字数 284 浏览 8 评论 0原文

我有一个包含 php 代码的字符串,我需要从字符串中删除 php 代码,例如:

<?php $db1 = new ps_DB() ?><p>Dummy</p>

Should return

Dummy

和一个没有 php 的字符串例如

Dummy

应返回相同的字符串。

我知道这可以用正则表达式来完成,但 4 小时后我还没有找到解决方案。

I have a string that has php code in it, I need to remove the php code from the string, for example:

<?php $db1 = new ps_DB() ?><p>Dummy</p>

Should return <p>Dummy</p>

And a string with no php for example <p>Dummy</p> should return the same string.

I know this can be done with a regular expression, but after 4h I haven't found a solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

反目相谮 2024-09-17 12:43:17
 <?php
 function filter_html_tokens($a){
    return is_array($a) && $a[0] == T_INLINE_HTML ?
      $a[1]:
      '';
 }
 $htmlphpstring = '<a>foo</a> something <?php $db1 = new ps_DB() ?><p>Dummy</p>';
 echo implode('',array_map('filter_html_tokens',token_get_all($htmlphpstring)));
 ?>

正如 ircmaxell 指出的:这需要有效的 PHP!

正则表达式路由将是(允许没有带短标签的“php”。字符串/文件中没有结尾?>(出于某种原因Zend推荐这样做?),当然还有UNgreedy & DOTALL模式:

preg_replace('/<\\?.*(\\?>|$)/Us', '',$htmlphpstring);
 <?php
 function filter_html_tokens($a){
    return is_array($a) && $a[0] == T_INLINE_HTML ?
      $a[1]:
      '';
 }
 $htmlphpstring = '<a>foo</a> something <?php $db1 = new ps_DB() ?><p>Dummy</p>';
 echo implode('',array_map('filter_html_tokens',token_get_all($htmlphpstring)));
 ?>

As ircmaxell pointed out: this would require valid PHP!

A regex route would be (allowing for no 'php' with short tags. no ending ?> in the string / file (for some reason Zend recommends this?) and of course an UNgreedy & DOTALL pattern:

preg_replace('/<\\?.*(\\?>|$)/Us', '',$htmlphpstring);
这个俗人 2024-09-17 12:43:17

好吧,你可以使用 DomDocument 来做到这一点...

function stripPHPFromHTML($html) {
    $dom = new DomDocument();
    $dom->loadHtml($html);
    removeProcessingInstructions($dom);
    $simple = simplexml_import_dom($d->getElementsByTagName('body')->item(0));
    return $simple->children()->asXml();
}

function removeProcessingInstructions(DomNode &$node) {
    foreach ($node->childNodes as $child) {
        if ($child instanceof DOMProcessingInstruction) {
            $node->removeChild($child);
        } else {
            removeProcessingInstructions($child);
        }
    }
}

这两个函数将变成

$str = '<?php echo "foo"; ?><b>Bar</b>';
$clean = stripPHPFromHTML($str);
$html = '<b>Bar</b>';

编辑: 实际上,在查看 Wrikken 的答案后,我意识到这两种方法都有一个缺点...我的方法需要一些有效的 HTML标记(Dom 很不错,但它不会解析 foo)。 Wrikken 需要有效的 PHP(任何语法错误都会失败)。所以也许是两者的结合(先尝试一个。如果失败,再尝试另一个。如果两者都失败,那么如果不尝试找出它们失败的确切原因,你真的无能为力)......

Well, you can use DomDocument to do it...

function stripPHPFromHTML($html) {
    $dom = new DomDocument();
    $dom->loadHtml($html);
    removeProcessingInstructions($dom);
    $simple = simplexml_import_dom($d->getElementsByTagName('body')->item(0));
    return $simple->children()->asXml();
}

function removeProcessingInstructions(DomNode &$node) {
    foreach ($node->childNodes as $child) {
        if ($child instanceof DOMProcessingInstruction) {
            $node->removeChild($child);
        } else {
            removeProcessingInstructions($child);
        }
    }
}

Those two functions will turn

$str = '<?php echo "foo"; ?><b>Bar</b>';
$clean = stripPHPFromHTML($str);
$html = '<b>Bar</b>';

Edit: Actually, after looking at Wrikken's answer, I realized that both methods have a disadvantage... Mine requires somewhat valid HTML markup (Dom is decent, but it won't parse <b>foo</b><?php echo $bar). Wrikken's requires valid PHP (any syntax errors and it'll fail). So perhaps a combination of the two (try one first. If it fails, try the other. If both fail, there's really not much you can do without trying to figure out the exact reason they failed)...

小姐丶请自重 2024-09-17 12:43:17

一个简单的解决方案是使用 php 标签分解为数组,删除数组之间的任何内容,然后分解回字符串。

function strip_php($str) {

  $newstr = '';

  //split on opening tag
  $parts = explode('<?',$str);

  if(!empty($parts)) {
      foreach($parts as $part) {

          //split on closing tag
          $partlings =  explode('?>',$part);
          if(!empty($partlings)) {

              //remove content before closing tag
              $partlings[0] = '';
          }

          //append to string
          $newstr .= implode('',$partlings);
      }
  }
  return $newstr;
}

这比正则表达式慢,但不需要有效的 html 或 php;它只需要关闭所有 php 标签。

对于并不总是包含最终结束标签的文件以及一般错误检查,您可以对标签进行计数,并在缺少结束标签时附加结束标签,或者在开始标签和结束标签未按预期添加时发出通知,例如添加代码下面在函数的开头。不过,这会减慢速度:)

  $tag_diff = (substr_count($str,'<?') - (substr_count($str,'?>');

  //Append if there's one less closing tag
  if($tag_diff == 1) $str .= '?>';

  //Parse error if the tags don't add up
  if($tag_diff < 0 || $tag_diff > 1) die('Error: Tag mismatch. 
  (Opening minus closing tags = '.$tag_diff.')<br><br>
  Dumping content:<br><hr><br>'.htmlentities($str));

A simple solution is to explode into arrays using the php tags to remove any content between and implode back to a string.

function strip_php($str) {

  $newstr = '';

  //split on opening tag
  $parts = explode('<?',$str);

  if(!empty($parts)) {
      foreach($parts as $part) {

          //split on closing tag
          $partlings =  explode('?>',$part);
          if(!empty($partlings)) {

              //remove content before closing tag
              $partlings[0] = '';
          }

          //append to string
          $newstr .= implode('',$partlings);
      }
  }
  return $newstr;
}

This is slower than regex but doesn't require valid html or php; it only requires all php tags to be closed.

For files which don't always include a final closing tag and for general error checking you could count the tags and append a closing tag if it's missing or notify if the opening and closing tags don't add up as expected, e.g. add the code below at the start of the function. This would slow it down a bit more though :)

  $tag_diff = (substr_count($str,'<?') - (substr_count($str,'?>');

  //Append if there's one less closing tag
  if($tag_diff == 1) $str .= '?>';

  //Parse error if the tags don't add up
  if($tag_diff < 0 || $tag_diff > 1) die('Error: Tag mismatch. 
  (Opening minus closing tags = '.$tag_diff.')<br><br>
  Dumping content:<br><hr><br>'.htmlentities($str));
久而酒知 2024-09-17 12:43:17

这是 @jon 建议的 strip_php 的增强版本,它能够用另一个字符串替换代码的 php 部分:

/**
 * Remove PHP code part from a string.
 *
 * @param   string  $str            String to clean
 * @param   string  $replacewith    String to use as replacement
 * @return  string                  Result string without php code
 */
function dolStripPhpCode($str, $replacewith='')
{
    $newstr = '';

    //split on each opening tag
    $parts = explode('<?php',$str);
    if (!empty($parts))
    {
        $i=0;
        foreach($parts as $part)
        {
            if ($i == 0)    // The first part is never php code
            {
                $i++;
                $newstr .= $part;
                continue;
            }
            //split on closing tag
            $partlings = explode('?>', $part);
            if (!empty($partlings))
            {
                //remove content before closing tag
                if (count($partlings) > 1) $partlings[0] = '';
                //append to out string
                $newstr .= $replacewith.implode('',$partlings);
            }
        }
    }
    return $newstr;
}

This is an enhanced version of strip_php suggested by @jon that is able to replace php part of code with another string:

/**
 * Remove PHP code part from a string.
 *
 * @param   string  $str            String to clean
 * @param   string  $replacewith    String to use as replacement
 * @return  string                  Result string without php code
 */
function dolStripPhpCode($str, $replacewith='')
{
    $newstr = '';

    //split on each opening tag
    $parts = explode('<?php',$str);
    if (!empty($parts))
    {
        $i=0;
        foreach($parts as $part)
        {
            if ($i == 0)    // The first part is never php code
            {
                $i++;
                $newstr .= $part;
                continue;
            }
            //split on closing tag
            $partlings = explode('?>', $part);
            if (!empty($partlings))
            {
                //remove content before closing tag
                if (count($partlings) > 1) $partlings[0] = '';
                //append to out string
                $newstr .= $replacewith.implode('',$partlings);
            }
        }
    }
    return $newstr;
}
忆离笙 2024-09-17 12:43:17

如果您使用 PHP,则只需使用正则表达式来替换与 PHP 代码匹配的任何内容。

以下语句将删除 PHP 标记:

preg_replace('/^<\?php.*\?\>/', '', '<?php $db1 = new ps_DB() ?><p>Dummy</p>');

如果没有找到任何匹配项,则不会替换任何内容。

If you are using PHP, you just need to use a regular expression to replace anything that matches PHP code.

The following statement will remove the PHP tag:

preg_replace('/^<\?php.*\?\>/', '', '<?php $db1 = new ps_DB() ?><p>Dummy</p>');

If it doesn't find any match, it won't replace anything.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文