Is there a way to replace img tag with div tag like below?
Original html:
<div class="article">
<img src="/images/img-1.jpg" alt="alt for image">
</div>
Replaced html:
<div class="article">
<div style="background: transparent url(/images/img-1.jpg) no-repeat;
background-position: center center; background-size: cover; width: 566px;
height: 576px;">alt for image</div>
</div>
(Optional) Also is it possible to use the width and height from the parent div ie article class in my example instead of defining fixed width: 566px; height: 576px;
width: 566px; height: 576px;
?
If it's possible, I want to use the str_replace
function.
str_replace('?????', '?????', $article);
Edit:
There may be multiple elements with class article and there may be other elements inside article class div and from which I need to change img to div.
Edit2:
I was meaning as if I may have any content inside article div and just want to replace the img with div.
I may have:
<div class="article">
<h1>heading</h1>
<p>paragraph</p>
<img src="/images/img-1.jpg" alt="alt for image">
</div>
Or I may have:
<div class="article">
<h3>heading</h3>
<p><img src="/images/img-1.jpg" alt="alt for image"> some paragraph </p>
</div>
So, I may have anything inside .article
div and from which I wanted to replace img to div like
From:
<img src="/images/img-1.jpg" alt="alt for image" here-may-be-another-attribute-too>
To:
<div style="background: transparent url(/images/img-1.jpg) no-repeat;">alt for image</div>
use the php-class simplehtmldom ( http://simplehtmldom.sourceforge.net/ ) you can find and modify the HTML-Dom with CSS-like selectors.
<?php
require_once('simple_html_dom.php');
// Create DOM from string
$html = str_get_html('<div class="article">
<img src="/images/img-1.jpg" alt="alt for image">
</div>');
$html->find('div.article', 0)->innertext = '<div style="background: transparent url(/images/img-1.jpg) no-repeat;
background-position: center center; background-size: cover; width: 566px;
height: 576px;">alt for image</div>';
/**
* Output: <div id="article"><div style="background: transparent url(/images/img-1.jpg) no-repeat;
* background-position: center center; background-size: cover; width: 566px;
* height: 576px;">alt for image</div></div>
*/
echo $html;
?>
You can use PHP's native DOM library to found and replace html. I wrote some example, you adapt for your case. Hope help.
Updated code:
$html_str = '<div class="article newclass" id="some_id">
<h1>heading</h1>
<p>paragraph</p>
<img src="images/image.png" alt="alt for image">
<br>
<h3>
<p>paragraph</p>
<img src="images/image2.png" alt="alt for image3">
</h3>
</div>';
$dom = new DOMDocument();
$dom->loadHTML($html_str);
$xpath = new DOMXpath($dom);
foreach ($xpath->query('//div[contains(@class, "article")]//img') as $img) {
$new_img = replace($img, $width = '566', $height = '576');
$replacement = $dom->createDocumentFragment();
$replacement->appendXML($new_img);
$img->parentNode->replaceChild($replacement, $img);
}
$new_html = $dom->saveXml();
echo $new_html;
function replace($img, $width, $height) {
$href = $img->getAttribute('src');
$alt = $img->getAttribute('alt');
$new_img = '<div style="background: transparent url('.$href.') no-repeat;
background-position: center center; background-size: cover; width: '.$width.'px;
height: '.$height.'px;">'.$alt.'</div>';
return $new_img;
}
replace function stay the same only change part where manage with DOM
Here you go. A tested and working solution. The error reporting is there in case PHP throws any errors. The child div also inherits the width and height of the parent div.
<?php
error_reporting(E_ALL);
ini_set("log_errors", 1);
/**
* Display of all other errors
*/
ini_set("display_errors", 1);
/**
* Display of all startup errors
*/
ini_set("display_startup_errors", 1);
$content = '
<div class="article">
<h1>heading</h1>
<p>paragraph</p>
<img src="/images/img-1.jpg" alt="alt for image">
</div>
';
$domDocument = new DOMDocument();
$domDocument->loadHTML($content);
$domElemsToRemove = [];
$domXpath = new DOMXpath($domDocument);
$nodes = $domXpath->query('//div[@class="article"]/img');
$newNode ="<div style='background: transparent url(/images/img-1.jpg) no-repeat; width: inherit; height: inherit; background-position: center center; background-size: cover; width: 566px; height: 576px;'>alt for new image</div>";
$newDom = $domDocument->createDocumentFragment();
$newDom->appendXML($newNode);
foreach ($nodes as $node) {
$node->parentNode->appendChild($newDom);
$node->parentNode->removeChild($node);
}
echo $domDocument->saveHTML();
?>
Is there a way to replace img tag with div tag like below?
YES
a). DOM (prefered way)
b). REGEX
both methods are already implemented in other answers, use one you like
Note: if the html is generated dynamically by php, i would advise you to extract alt
and src
attributes value with preg_match_all
regex here and then create a string from that, that would give you more flexibility, for eg:
$str ='<div class="article"><img src="/images/img-1.jpg" alt="alt for image"></div>';
preg_match_all('`src=(?:[\'"])(.*)[\'"].*alt=(?:[\'"])(.*)[\'"].*`U', $str, $matches);
$desiredHTML = <<<HTML
<div class="article">
<div style="background: transparent url({$matches[1][0]}) no-repeat;
background-position: center center; background-size: cover; width: 566px;
height: 576px;">{$matches[2][0]}</div>
</div>
HTML;
is it possible to use the width and height from the parent div?
YES by using following js code you can do that, since you can't find out the height of article
div without rendering, and you want them in pixels, you have to use javascript
var cl = document.getElementsByClassName('article');
for (var i = 0; i <= cl.length; i++)
{
var width = cl[i].style.width;
var height = cl[i].style.height;
cl[i].firstElementChild.style.width = width;
cl[i].firstElementChild.style.height = height;
};
If it's possible, I want to use the str_replace function?
NO , it's not possible with str_replace function.
For your Problem try this:
$string = ' <div class="article">
<img src="/images/img-1.jpg" alt="alt for image">
</div>';
preg_match('@<div class="article">(.*?)</div>@is', $string, $replace);
preg_match('/<img src="(.*?)" alt="(.*?)">/', $string, $matches);
$string = str_replace($replace[1], '<div style="background: transparent url('.$matches[1].') no-repeat; background-position: center center; background-size: cover; width: inherit; height: inherit;">'.$matches[2].'</div>', $string);
To go from the old html to the new html we need to know two things:
src
attribute alt
attribute Once we know these two values we can easily create the new html format. I do that as follows:
<?php
$orig_html = <<<HERE
<div class="article">
<img src="http://lorempixel.com/400/200" alt="alt for image">
</div>
HERE;
echo new_html($orig_html);
/* helper function to get the value of an attribute:
$attribute: the attribute you want to check (e.g. src)
$source: The html you want it to parse */
function get_attribute($attribute, $source) {
$query = '/' . $attribute . '="([^"]*)"/i';
$result = array();
preg_match($query, $source, $result);
return $result[1];
}
/* helper function to return new html from the old html
$source: the old html */
function new_html($source) {
$src = get_attribute('src', $source);
$alt = get_attribute('alt', $source);
return <<<HERE
<div class="article">
<div style="background: transparent url($src) no-repeat;
background-position: center center; background-size: cover;">$alt</div>
</div>
HERE;
}
?>
We can't use php to read the width and height of the parent (the article class), unless the width and height is defined in the markup. From your example it doesn't seem like these values are in the markup, so I'm assuming these dimensions are provided by css?
Instead you can always style the image with the following css: .article > div {width: 100%; height: 100%;}
.article > div {width: 100%; height: 100%;}
.
You can try something like this:
$content = "this is something with an <img src=\"test.png\"/> in it.";
$replaceWith = '<div style="background:url($1)"></div>';
$content = preg_replace('/<img\s+src="([^"]+)"[^>]+>/i', $replaceWith, $content);
echo $content;
Change $replaceWith
according to your markup.
YES.
But str_replace can not do this alone.
$article =<<<'EOT'
<div class="article">
<img src="/images/img-1.jpg" alt="alt for image">
</div>
EOT;
// img -> div
$res = str_replace('<img', '<div', $article);
// src -> style
$res = preg_replace('/src="([^"]+)"/i', 'style="background: transparent url($1) no-repeat; background-position: center center; background-size: cover; width: 566px; height: 576px;"', $res);
// alt -> innerHTML
$res = preg_replace('/ alt="(.*)">/i', '>$1</div>', $res);
echo $res;
using preg_replace :
//your html code in a variable
$source = '<div class="article">
<img src="/images/img-1.jpg" alt="alt for image1">
</div>
<div class="article">
<img src="/images/img-5.jpg" alt="alt for image5">
</div>';
//class
class PregReplace{
private static $instance;
private $source;
public $css = array('width'=>'600','height'=>'800','background-size'=>'cover','background-position'=>'center center','background'=>'transparent url($1) no-repeat');
private $replace;
private $result;
private $pattern = '/\<div\s?class="article">\n?\r?\n?.*img\s?src="(.*?)"\salt="(.*?)".*\n?\r?\n?\<\/div\>/m';
public function __construct(){
}
public function loadreplace(){
$this->replace='<div class="article">
<div style="background:'.$this->css['background'].'; background-position:'.$this->css['background-position'].'; background-size:'.$this->css['background-size'].'; width:'.$this->css['width'].'px;
height: '.$this->css['height'].'px;">$2</div>
</div>';
}
public function setcss($array){
$this->css = $array;
}
public function setsource($value){
$this->source = $value;
return $this;
}
public function setreplace($value){
$this->replace = $value;
}
public function replacing(){
$this->loadreplace();
$this->result = preg_replace($this->pattern,$this->replace,$this->source);
return $this;
}
public function result(){
return $this->result;
}
}
//process with preg_replace
$result = new PregReplace();
//you can set your css
$result->css['width'] = '566';
$result->css['height'] = '576';
//
var_dump($result->setsource($source)->replacing()->result());
Here is my approach, call normal Java Script from php:
<div class="article">
<img src="../images/img-1.jpg" alt="alt for image">
</div>
<?php
$removeOldContent = '<script>document.getElementsByClassName("article")[0].remove();</script>';
$newContent = '<div class="article"><div style="background: transparent url(../images/img-1.jpg) no-repeat;
background-position: center center; background-size: cover; width: 566px;
height: 576px;">alt for image</div></div>';
$content = $removeOldContent . $newContent;
// this could be you replacing condition
// false will keep old content
// true will remove old content and view new content
if (false)
echo $content;
You could read the file into a string, replace to your needs, then write back to either a new file or overwrite the original. Anyway, I'd probably just add a class for the div. Inline css is a pain.
You can use replaceWith
method :
The
.replaceWith()
method, like most jQuery methods, returns the jQuery object so that other methods can be chained onto it. However, it must be noted that the original jQuery object is returned. This object refers to the element that has been removed from the DOM, not the new element that has replaced it.The
.replaceWith()
method removes all data and event handlers associated with the removed nodes.
$('.article img').replaceWith(function(i, v){
return $('<div/>', {
style: 'background-image: url('+this.src+')',
html: '<div style="background: transparent url(/images/img-1.jpg)no-repeat;background-position: center center; background-size: cover; width: 566px; height: 576px;">alt for image</div>'
})
})
OR
echo "$('.article img').replaceWith(function(i, v){
return $('<div/>', {
style: 'background-image: url('+this.src+')',
html: '<div style=\"background: transparent url(/images/img-1.jpg)no-repeat;background-position: center center; background-size: cover; width: 566px; height: 576px;\">alt for image</div>'
})
})";
This will accomplish what you are trying to do. Hope this helps.
$prev_str = '<div class="article"><img src="pics/flower.jpg" alt="alt for image"></div>';
preg_match('/'.preg_quote("<div class=\"").'(.*?)'.preg_quote("\"><img").'/is', $prev_str, $class);
$class_name=$class[1];//article
preg_match('/'.preg_quote("<img src=\"").'(.*?)'.preg_quote("\" alt=\"").'/is', $prev_str, $image);
$image_path=$image[1];//pics/flower.jpg
preg_match('/'.preg_quote("alt=\"").'(.*?)'.preg_quote("\"><").'/is', $prev_str, $alt);
$alt=$alt[1];//alt for image
//size that we are going to use in the div as well image div
$width="200px";
$height="200px";
echo '
<style>
div.article{
min-height:'.$height.';
width:'.$width.';
}
</style>';
/** additional hints in css formatting
div.article div{
//display: inline-block;
//width:inherit;
//height:inherit;
//width:100%;
//height:100%;
}
**/
echo '<div class="'.$class_name.'">';
echo '<div style="background: transparent url('.$image_path.') no-repeat;
background-position: center center; background-size: cover;width:'.$height.';
height: '.$width.';">'.$alt.'</div>
</div>';
This method is almost entirely preg_replace
; it does have a few nice additions:
wxh
are added as part of the replacement. class
, href
, and alt
) are dynamically replaced. It basically uses two patterns, the first parses the CSS
and the second replaces the <div>
.
Code :
<?php
$str = '<div class="article"><img src="/images/image.png" alt="alt for image"></div>';
$css = '<style> .article { font-size:16px; font-weight:bold; width:566px; height:576px; } </style>
';
function replace($str, $css) {
preg_match( '@>\s\.(.+)\s{\s(.*)\s}@', $css, $res);
$style['class'] = $res[1];
$attrs = explode("; ", $res[2]);
foreach ($attrs as $attr) {
if (strlen(trim($attr)) > 0) {
$kv = explode(":", trim($attr));
$style[trim($kv[0])] = trim($kv[1]);
}
}
$rep = '<div class="$1">
<div style="background: transparent url($2) no-repeat;
background-position: center center; background-size: cover; width: '.$style['width'].';
height: '.$style['height'].'">$3</div>
</div>
';
return preg_replace( '@.+class="(.+)"><.*="(.+)"\\salt="(.+)".+@', $rep, $str );
}
$str = replace($str, $css);
?>
<html>
<head>
<?php echo $css; ?>
</head>
<body>
<?php echo $str; ?>
</body>
</html>
Example :
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.