我有一些HTML内容,我需要解析它,得到所有的图像。然后打印出整个内容,但是在每次出现image
时运行一个PHP类实例This is the content
<?php $content = 'Some text
<p>A paragraph</p>
<img src="image1.jpg" width="200" height="200">
More text
<img src="image2.jpg" width="200" height="200">'; ?>
我需要能够获得图像并运行一个类方法的输出。
那么结果会是类似于
<?php echo 'Some text
<p>A paragraph</p>';
$this->Image('image1.jpg', PDF_MARGIN_LEFT, $y_offset, 116, 85);
echo 'More text';
$this->Image('image2.jpg', PDF_MARGIN_LEFT, $y_offset, 116, 85);
但是显然我认为它必须是一个循环或者其他自动完成的东西
如您在评论中提到的那样,要将整个HTML代码段转换为TcPDF,您需要使用DOMDocument
解析代码段,并遍历每个子节点,决定如何适当地处理它们。
上面提供的代码片段的问题是它不是一个完整的HTML文档,因此DOMDocument
在解析它时会将其包装在<html>
和<body>
标记中,在内部加载以下结构:
<html>
<body>
Some text
<p>A paragraph</p>
<img src="image1.jpg" width="200" height="200">
More text
<img src="image2.jpg" width="200" height="200">
</body>
</html>
这个警告很容易解决,然而,通过建立@hakre的回答在我链接到下面的线程。我的建议大致如下:
// Load the snipped into a DOMDocument
$doc = new DOMDocument();
$doc->loadHTML($content);
// Use DOMXPath to retrieve the body content of the snippet
$xpath = new DOMXPath($doc);
$data = $xpath->evaluate('//html/body');
// <body> is now $data[0], so for readability we do this
$body = $data[0];
// Now we loop through the elements in your original snippet
foreach ($body->childNodes as $node) {
switch ($node->nodeName) {
case 'img':
// Get the value of the src attribute from the img element
$src = $node->attributes->getNamedItem('src')->nodeValue;
$this->Image($src, PDF_MARGIN_LEFT, $y_offset, 116, 85);
break;
default:
// Pass the line to TcPDF as a normal paragraph
break;
}
}
这样,您可以轻松地添加额外的case 'blah':
块来处理可能出现在$content
片段中的其他元素并适当地处理它们,并且内容将以正确的顺序处理,而不会破坏文本的原始流程。:)
——原始答案。将工作,如果你只是想提取图像源和处理他们在其他地方独立的其余内容。
您可以使用正则表达式匹配$content
字符串中的所有<img>
标记:
/<img(?:['s'w="]+)src="([^"]+)"(?:['s'w="]*)'/?>/i
regex的实时分解,你可以在这里玩,看看它是如何工作的:http://regex101.com/r/tS5xY9
您可以对preg_match_all()
使用这个正则表达式从$content
变量中检索所有图像标记,如下所示:
$matches = array();
$num = preg_match_all('/<img(?:['s'w="]+)src="([^"]+)"(?:['s'w="]*)'/?>/i', $content, $matches, PREG_SET_ORDER);
PREG_SET_ORDER
常量告诉preg_match_all()
以一种更容易在产生输出时循环的方式存储其结果,因为数组上的第一个索引(即$matches[0]
, $matches[1]
等)将包含来自正则表达式的完整匹配集。在上述正则表达式的情况下,$matches[0]
将包含以下内容:
array(
0 => '<img src="image1.jpg" width="200" height="200">',
1 => 'image1.jpg',
)
你现在可以循环通过$matches
作为$key => $match
,并将$match[1]
传递给你的$this->Image()
方法。
或者,如果您不想循环,您可以直接从$matches
访问每个src
属性,如$matches[0][1]
, $matches[1][1]
等。
如果您需要能够访问标签中的其他属性,那么我建议使用@hakre在PHP Get img src上提供的DOMDocument
方法。如果您只需要访问src
属性,那么使用preg_match_all()
会更快更有效,因为它不需要将代码片段的整个DOM作为对象加载到内存中,从而为您提供所需的数据。
您可以构建一个词法分析器或解析器来查找图像的位置。
您正在开始寻找两个令牌:<img
和各自的结束>
。起始点可以是这样的:
$text = "hello <img src='//first.jpg'> there <img src='//second.jpg'>";
$pos = 0;
while (($opening = strpos($text, '<img', $pos)) !== FALSE) {
// Find the next closing bracket's location
$closing = strpos($text, '>', $opening);
$length = ($closing - $opening) + 1; // Add one for the closing '>'
$img_tag = substr($text, $opening, $length);
var_dump($img_tag);
// Update the loop position with our closing tag to advance the lexer
$pos = $closing;
}
您将不得不构建方法来扫描img标签。您还可以在循环中添加PDF方法。
另一种更易于管理的方法是构建一个遍历每个字符的类。它首先查找开头的'<'字符,然后检查接下来的三个字符是否为'img',如果是,则分别扫描src、height、width属性。这是更多的工作,但更灵活的方式-你将能够扫描更多的不仅仅是你的图像标签。