Ik heb hier een mooie method van een class die non-SSL URL's omzet naar mijn SSL camo-proxy.
Het werkt echt heel mooi, maar... ik merk dat setAttribute op lijn 11 wordt genegeerd.

Ik zie dat er in de img-tag die in de for-loop aangeroepen wordt wel netjes de URL wordt ge-replaced, maar er komt geen nieuw attribuut bij die 'data-original-src' heet?

Waarom negeert hij dit?


<?php
public function parse($string) {
	if($this->settings['camo_enabled'] == true) {
	    $doc = new DOMDocument();
	    $doc->loadHTML($string);
	    $images = $doc->getElementsByTagName('img');
	    //$imgarray = array();
	    foreach ($images as $image) {
		$url = $image->getAttribute('src');
		if(substr($url, 0, 8) != 'https://') {
		    $image->setAttribute('data-original-src', $url);
		    $camo = $this->proxy_url($url);
		    $string = str_replace($image->getAttribute('src'), $camo, $string);
		    unset($url, $camo);
		}
	    }
	}
	return $string;
    }
?>
De documentatie van getElementsByTagName() zegt hierover:
This function returns a new instance of class DOMNodeList containing all the elements with a given local tag name.

Oftewel, je bent naar alle waarschijnlijkheid gegevens in een aparte kopie aan het wijzigen die alleen binnen de scope van de functie bestaat, het origineel blijft ongewijzigd.

Meerdere oplossingen mogelijk. Je zou bijvoorbeeld de functie in eerste instantie rechtstreeks het object (DOMDocument) kunnen voeren. Objecten zijn call by reference dus ben je daarmee direct in het origineel aan het werken.
Met je str_replace() vervang je alleen de src in de originele HTML ($string). Als je ook het data-original-src terug wilt zien zul je de hele <image> tag moeten vervangen.
Euh...?
Maar getAttribute() werkt wel.
Het is puur dat setAttribute() niet werkt.


Ik zie het al, ik ga kijken of ik de image-tag opnieuw op kan bouwen.
Als je image URL's een beetje netjes/consequent tussen quootjes staan zou je het ook zo kunnen doen (stel altijd tussen ")

$src = $image->getAttribute('src');
$string = str_replace($src, "$camo\" data-original-src=\"$src", $string);

Een soort van HTML-injectie zeg maar (de bestaande src=" en sluit " recyclen).

Als de quootjes niet consequent zijn kun je evt nog met een regex aan de slag, maar dan wordt het al gauw nasty.

[size=xsmall]Toevoeging op 21/09/2017 22:51:50:[/size]

Gaat trouwens fout als hetzelfde plaatje (URL) 2x in de $string voorkomt
Als ik zo denk kan ik beter met een foreach alle attributen langsgaan, element opnieuw opbouwen, en de eerste img weer wissen. Dan ben je pas robuust bezig. ;-)

Die injectie ziet er wel kazig uit, inderdaad.

Reageren