str_replace bug with foreach loop - php

I've got a problem with my little text to smiley/emoji function in php, which is based on str_replace. This is my code.
$smileys = array( ":inlove:" => "/smileys/smiley2.png",
":cool:" => "/smileys/smiley3.png",
":tongue:" => "/smileys/smiley4.png",
":wow:" => "/smileys/smiley5.png",
":smile:" => "/smileys/smiley15.png",
":happy:" => "/smileys/smiley6.png",
":funny:" => "/smileys/smiley7.png",
":wink:" => "/smileys/smiley8.png",
":worried:" => "/smileys/smiley10.png",
":pokerface:" => "/smileys/smiley9.png",
":poop:" => "/smileys/smiley12.png",
":thinking:" => "/smileys/35_thinking.png",
":triumph:" => "/smileys/49_triumph.png",
":vulcan:" => "/smileys/109_vulcan.png",
":pointup:" => "/smileys/102_point_up_2.png",
":santa:" => "/smileys/135_santa.png",
":spy:" => "/smileys/134_spy.png");
if(isset($_POST['message'])) {
$messagePlain = $_POST['message'];
$messageSmileys = $messagePlain;
foreach($smileys as $key => $img) {
$messageSmileys = str_replace($key, '<img src="' . $img . '" />', $messageSmileys);
}
$connection->query(// Message to db);
}
It works fine. But the problem is, when the user inputs more than ~14 emojis in a row, the HTML gets destroyed and it looks like this:
And the HTML source like this:
<div class="media-body">
<h4 class="media-heading">test <small>07. August. 2017 01:34</small></h4>
<img src="/smileys/smiley2.png" /> <img src="/smileys/smiley3.png" /> <img src="/smileys/smiley5.png" /> <img src="/smileys/smiley4.png" /> <img src="/smileys/smiley15.png" /> <img src="/smileys/smiley6.png" /> <img src="/smileys/smiley7.png" /> <img src="/smileys/smiley8.png" /> <img src="/smileys/smiley10.png" /> <img src="/smileys/smiley9.png" /> <img src="/smileys/smiley12.png" /> <img src="/smileys/49_triumph.png" /> <img src="/smileys/109_vulcan.png" /> <img src="/smileys/102_point_up_2.p </div>
</div>
Could someone help me with this? Why is the HTML tag for <img> suddenly destroyed?

Looking at your output:
<img src="/smileys/smiley2.png" /> <img src="/smileys/smiley3.png" /> <img src="/smileys/smiley5.png" /> <img src="/smileys/smiley4.png" /> <img src="/smileys/smiley15.png" /> <img src="/smileys/smiley6.png" /> <img src="/smileys/smiley7.png" /> <img src="/smileys/smiley8.png" /> <img src="/smileys/smiley10.png" /> <img src="/smileys/smiley9.png" /> <img src="/smileys/smiley12.png" /> <img src="/smileys/49_triumph.png" /> <img src="/smileys/109_vulcan.png" /> <img src="/smileys/102_point_up_2.p
The above string's length is 499 characters. I strongly believe that your message field in the database table is limited to 500 characters or something and the output is truncated to those bits.
Solution / Suggestion
If you are using MySQL Database Server, I would strongly recommend you changing the database type from VARCHAR(500) to TEXT or LONGTEXT.

Your database field probably has a length limit. You might want to raise that, but there’s a more important initial fix: store the original text in the database and perform the replacements on the output instead.
This is especially important because it looks like you’re probably vulnerable to HTML injection right now. Make sure to run htmlspecialchars before doing the replacement and be aware of how you need to encode your output to make it safe. How to prevent XSS with HTML/PHP? might be a good start.

Related

how to store html string in php variable using a foreach loop

I'm new to php. This is in relation to wordpress and I'm terribly confused.
Basically, I am passing an array of names from another file (via ajax and json) and into a php function. This function will loop through each name and generate html code to display to the page with an image. I would like to store this htmlcode as a string into a variable to be used in another part of my app (specifically to append it to a post to update in real time, but that's a separate issue).
My ajax response is showing the result I want, just not stored in a string. It is also saying the path to my images can't be found despite the path being correct. It seems like I'm either concatenating something wrong or putting quotes in the wrong place, or something else. I want to store all the html generated in $html_string (which I know won't load my app correctly as I'm displaying the code here, it was just the last thing I've tried so I left it in there).
My code:
<?php
add_action('wp_ajax_nopriv_test_function', 'test_function');
add_action('wp_ajax_test_function', 'test_function');
function test_function() {
if ( isset($_POST) ) {
$nameData = $_POST['nameData'];
//Strip any double escapes then use json_decode to create an array.
$nameDecode = json_decode(str_replace('\\', '', $_POST['nameData']));
// Anything outputted will be returned in the response
foreach ($nameDecode as $key => $name) {
$html_string .= ?> <img src="<?php bloginfo('template_directory');?>/images/baseball/team0.jpg"> <p> <?php echo $name ?> <p /> '
<?php ' }
echo json_encode($html_string);
// print_r($html_string);
}
die();
} ?>
Current output:
ajax success! <img src="http://card-store.local/wp-content/themes/card-store-theme/images/baseball/team0.jpg"> <p> Eleanora <p />
<img src="http://card-store.local/wp-content/themes/card-store-theme/images/baseball/team0.jpg"> <p> Eleanora <p />
<img src="http://card-store.local/wp-content/themes/card-store-theme/images/baseball/team0.jpg"> <p> george <p />
<img src="http://card-store.local/wp-content/themes/card-store-theme/images/baseball/team0.jpg"> <p> george <p />
<img src="http://card-store.local/wp-content/themes/card-store-theme/images/baseball/team0.jpg"> <p> george <p />
null
card-store.local/:1 GET http://card-store.local/%22http:/card-store.local/wp-content/themes/card-store-theme/images/baseball/team0.jpg/ 404 (Not Found)
Desired output:
$html_string = '<img src="http://card-store.local/wp-content/themes/card-store-theme/images/baseball/team0.jpg"> <p> Eleanora <p />
<img src="http://card-store.local/wp-content/themes/card-store-theme/images/baseball/team0.jpg"> <p> Eleanora <p />
<img src="http://card-store.local/wp-content/themes/card-store-theme/images/baseball/team0.jpg"> <p> george <p />
<img src="http://card-store.local/wp-content/themes/card-store-theme/images/baseball/team0.jpg"> <p> george <p />
<img src="http://card-store.local/wp-content/themes/card-store-theme/images/baseball/team0.jpg"> <p> george <p />';
How can I achieve this?
This is how concatenation with multi variables in php works
$html_string .= '<img src="'.bloginfo('template_directory').'"/images/baseurl/team0.jpg <p>'.$name.'</p>';
This may help you
php concatenation
You can try this
foreach ($nameDecode as $key => $name) {
$html_string .= '<img src="'.bloginfo('template_directory').'"/images/baseball/team0.jpg"> <p>'.$name.' <p />';
}

i'm taking image url from database. But it is not working in img tag in php

The name of the column is : link. variable-type:varchar.
<img src="<?php echo$link;?>" style="width:300px; height:400px;" />
</html>
Your echo command could be missing an ";"
$link=$row['link'];
<img src="<?php echo $link; ?>" style="width:300px; height:400px;" />
Should work better.

how to edit <img> tag in the string

<p> </p>
<p><img src="../../../..//js/uploads/images/selva.png" alt="" /></p>
<p>we are checkng our website</p>
<p>kfoaskf</p>
<p>asldfjas</p>
<p>jasdklfk'sd</p>
<p><img src="../../../..//js/uploads/images/images.jpg" alt="" /></p>
This is my string values. i need to change only this
<img src="../../../..//js/uploads/images/images.jpg"> to
<img src="js/uploads/images/images.jpg">
for every image ,i need to modify the path.
how to do it? and my string values also differ at every time
Try this bro
$str='<p> </p>
<p><img src="../../../..//js/uploads/images/selva.png" alt="" /></p>
<p>we are checkng our website</p>
<p>kfoaskf</p>
<p>asldfjas</p>
<p>jasdklfk\'sd</p>
<p><img src="../../../..//js/uploads/images/images.jpg" alt="" /></p>';
echo str_replace("../../../..//js/uploads/images/images.jpg","/js/uploads/images/images.jpg",$str);

calling a php img string in html

Pretty straight forward simple question, can you open a php code block to call image information in html? I don't think I phrased that right. Here is my code:
<img src="../inventory_images/' . <?php echo $item_number; ?> . '.jpg" width="150" height="150" border="2" />
This code is within the tags
I'm just trying to post a photo using the $item_number variable (which is also the name of the image file i.e. $item_number = T3144 and the image file is name T3144.jpg ). Also if there is a better way to accomplish this suggestions are happily accepted. Sorry to take up bandwidth with such a remedial question but for some reason I can't seem to answer this question in research. Thanks for taking the time everyone.
Your code is wrong, try:
<img src="../inventory_images/<?php echo $item_number;?>.jpg" width="150" height="150" border="2" />
with what you have it looks like the code you had would print
src="../inventory_images/' . whateveritem_numberis . '.jpg"
Yes that is perfectly fine, but make sure that this code is in a file that ends with .php or it will not get parsed by PHP. Also, you need to take out the single quotes and periods:
<img src="../inventory_images/<?php echo $item_number; ?>.jpg" width="150" height="150" border="2" />
Unless the above HTML is in an echo statement, you need to change it to this:
<img src="../inventory_images/<?php echo $item_number; ?>.jpg" width="150" height="150" border="2" />
That will in-turn look like this:
<img src="../inventory_images/T3144.jpg" width="150" height="150" border="2" />
Of course, that is going off of your example where $item_number = 'T3144';.
The single quotes and periods are used for concatenating variables inside of strings.

Using regex to wrap images in tags

I've been using regex to wrap my images in < a > tags and altering their paths etc.
I know using dom for this is better, having read a lot of threads about wrapping, but I'm unable to understand how to.
This is what I'm using:
$comments = (preg_replace('#(<img.+src=[\'"]/uploads/userdirs/admin)(?:.*?/)(.+?)\.(.+?)([\'"].*?>)#i', '<a class="gallery" rel="'.$pagelink.'" href=/uploads/userdirs/'.$who.'/$2.$3>$1/mcith/mcith_$2.$3$4</a>', $comments));
It successfully wraps each image in the tags I want. But only if the string provided ($comments) has the right markup.
<p><img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960" /></p>
<p><img src="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024" /></p>
When presented like this, it works. I'm using tinymce so it wraps in < p > when I do a linebreak with enter. But when I don't do that, when I just insert images one after another so the HTML looks like this, it won't:
<p><img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960" /><img src="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024" /></p>
It will instead wrap those 2 images in the same < a > tag. Making the output look like this:
<p><a class="gallery" rel="test" href="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg">
<img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960">
<img src="/uploads/userdirs/admin/mcith/mcith_100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024">
</a></p>
Which is wrong. The output I want is this:
<p><a class="gallery" rel="test2" href="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg"><img src="/uploads/userdirs/admin/mcith/mcith_100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024"></a></p>
<p><a class="gallery" rel="test2" href="/uploads/userdirs/admin/1154686260226.jpg"><img src="/uploads/userdirs/admin/mcith/mcith_1154686260226.jpg" alt="" width="1280" height="800"></a></p>
I've left out a few details, but here's how I would do it using DOMDocument:
$s = <<<EOM
<p><img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960" /></p>
<p><img src="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024" /></p>
EOM;
$d = new DOMDocument;
$d->loadHTML($s);
foreach ($d->getElementsByTagName('img') as $img) {
$img_src = $img->attributes->getNamedItem('src')->nodeValue;
if (0 === strncasecmp($img_src, '/uploads/userdirs/admin', 23)) {
$a = $d->createElement('a');
$a->setAttribute('class', 'gallery');
$a->setAttribute('rel', 'whatever');
$a->setAttribute('href', '/uploads/userdirs/username/' . $img_src);
// disconnect image tag from parent
$img->parentNode->replaceChild($a, $img);
// and move to anchor
$a->appendChild($img);
}
}
echo $d->saveHTML();
You should change .* in your regular expression with [^>]*. The latter means: any character expect than >. Because regular expression gets as long match as possible. Without this additional condition, this ends up with two <img>'s matched.

Categories