【问题标题】:Wrap all <img>'s in <div>, take the alt attribute and add it into a <p> inside把所有的<img>都包裹在<div>中,取alt属性并添加到一个<p>里面
【发布时间】:2010-10-26 17:15:42
【问题描述】:

尝试用一些 php 服务器端的魔法替换 this jquery code

$(document).ready(function() {
    $('#text img').each(function(){ 
        source = $(this).attr('src');
        $(this).wrap($('<div class="caption '+ $(this).attr('class') + '"></div>')).removeAttr('class').removeAttr('height').removeAttr('width');
        $(this).after('<p>' + $(this).attr('alt') + '</p>');
        $(this).attr('src', '/system/tools/phpthumb/phpThumb.php?src=' + source + '&wl=200&hp=200&q=85&f=jpg');
    });
});

它所做的就是这样做:

<img class="right" src="blah.jpg" alt="My caption" width="100" height="200" />

并将其替换为:

<div class="caption right">
    <img src="/system/tools/phpthumb/phpThumb.php?src=blah.jpg&wl=200&hp=200&q=85&f=jpg" alt="My caption" />
    <p>My caption</p>
</div>

图像分散在&lt;p&gt; 之间的一块纺织格式的 html 中。像这样的:

<p>My paragraph text</p>
<img src="image.jpg" />
<p>Another paragraph text <img src="another_image.jpg" /> with more text</p>
<p>And so on</p>

它使用户能够将图像向左、向右或居中浮动,并且缩略图是使用 phpthumb 自动创建的。我假设我需要使用正则表达式。我是 php 新手,只知道前端编码。你会如何攻击它?

【问题讨论】:

  • 这不是您问题的答案,但它仍然很重要。您尝试输出的结果标记无效,因为它具有嵌套在内联元素中的块元素。 标签不应该包含 标签,也不应该包含

    标签。

  • 替换的语法仍然无效,因为

    节点被

    关闭。
  • img 元素是内联的。它在像 span 或 a 这样的内联元素中完全有效。

标签: php regex replace


【解决方案1】:

最终使用了这个:

<?php
$string = '{body}';
$documentSource = mb_substr($string,3,-4);

$doc = new DOMDocument();
$doc->loadHTML($documentSource);
$xpath = new DOMXPath($doc);
foreach ($xpath->query('//html/body/img') as $node) {
    $node->removeAttribute('height');
    $node->removeAttribute('width');
    $source = $node->getAttribute('src');

    $node->setAttribute('src', '/system/tools/phpthumb/phpThumb.php?src=' . $source . '&wl=200&hp=200&q=85&f=jpg');

    $pElem = $doc->createElement('p', $node->getAttribute('alt'));

    $divElem = $doc->createElement('div');
    $divElem->setAttribute('class', 'caption '.$node->getAttribute('class'));
    $node->removeAttribute('class');

    $divElem->appendChild($node->cloneNode(true));
    $divElem->appendChild($pElem);
    $node->parentNode->replaceChild($divElem, $node);

}
?>

【讨论】:

    【解决方案2】:

    我建议您使用解析器,例如DOMDocument。除了DOMXPath,你几乎可以一一翻译jQuery代码:

    $documentSource = '<div id="text"><img class="right" src="blah.jpg" alt="My caption" width="100" height="200" /></div>';
    $doc = new DOMDocument();
    $doc->loadHTML($documentSource);
    $xpath = new DOMXPath($doc);
    foreach ($xpath->query('//html/body/*[@id="text"]/img') as $node) {
        // source = $(this).attr('src');
        $source = $node->getAttribute('src');
    
        // $(this).after('<p>' + $(this).attr('alt') + '</p>');
        $pElem = $doc->createElement('p', $node->getAttribute('alt'));
    
        // $('<div class="caption '+ $(this).attr('class') + '"></div>')
        $divElem = $doc->createElement('div');
        $divElem->setAttribute('class', 'caption '.$node->getAttribute('class'));
    
        // $(this).wrap( … );
        $divElem->appendChild($node->cloneNode(true));
        $divElem->appendChild($pElem);
        $node->parentNode->replaceChild($divElem, $node);
    
        // $(this).removeAttr('class').removeAttr('height').removeAttr('width');
        $node->removeAttribute('class');
        $node->removeAttribute('height');
        $node->removeAttribute('width');
    
        // $(this).attr('src', '/system/tools/phpthumb/phpThumb.php?src=' + source + '&wl=200&hp=200&q=85&f=jpg');
        $node->setAttribute('src', '/system/tools/phpthumb/phpThumb.php?src=' . $source . '&wl=200&hp=200&q=85&f=jpg');
    }
    echo $doc->saveXML();
    

    【讨论】:

    • 这样容易多了,谢谢!
      包裹并显示标题。不过还有一些问题 - * $documentSource 不包含
      (它在 html 的前面出现),只有

      的 & 的。我应该将 $xpath->query 更改为什么? * 没有从 中删除任何属性 * src 上的 setAttribute 似乎不起作用。 src 和以前一样。

    【解决方案3】:

    我认为您可能对使用其 DOM 扩展在 PHP 中本机模仿 jQuerys 功能的 PHP 库感兴趣。

    项目名为PHPQuery - http://code.google.com/p/phpquery/

    可以通过PEAR轻松安装,用法类似于jQuery语法

    【讨论】:

      【解决方案4】:

      一些完全未经测试的代码:

      preg_match('|<img class="([a-z\ ]+)" src="([a-z\ ]+)" alt="([a-z\ ]+)" />|i', 'PUT THE EXISTING HTML HERE', $matches);
      
      echo <<<EOT
      <span class="{$matches[0]}">
        <img src="{$matches[1]}" />
      <p>{$matches[2]}</p>
      </span>
      EOT; #this should be at the start of line
      

      感兴趣的是,为什么一开始就不能输出正确的 html?加载正则表达式引擎并非没有开销!

      【讨论】:

      • Alzo 你不应该使用正则表达式解析 HTML/XML。但是在这个例子中,只要你确定它总是以相同的方式呈现,它就可以非常安全。
      猜你喜欢
      • 2016-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 2015-03-15
      相关资源
      最近更新 更多