Hallo, liebe Leute,
ich habe mal vor einer Weile auf inquake.de (ehemals planetquake.de) einen Contest zur Programmierung einer Funktion ausgerufen, die aus einer absoluten URL und einer relativen URL eine absolute URL zusammensetzt. Es gibt in PHP eine ähnliche Funktion, die aber die aktuelle absolute URL nimmt, man keine übergeben.
Die Signatur meiner Funktion ist folgendermaßen:
absurl($basepath, $url)
Nachfolgend einige Eingabeparameter mit der erwarteten Ausgabe:
Eingabe:
$basepath = 'http://www.google.com/site/lala/';
$url = '/so/test.gif';
Ausgabe:
http://www.google.com/site/lala/so/test.gif
Eingabe:
$basepath = 'http://www.google.com/site/lala/';
$url = 'so/test.gif';
Ausgabe:
http://www.google.com/site/lala/so/test.gif
Eingabe:
$basepath = 'http://www.google.com/site/lala/';
$url = '../../test.gif';
Ausgabe:
http://www.google.com/test.gif
Die erste Antwort (von Evilseye) hatte mich ein wenig verwundert, sie war recht lang und sah nicht performant aus:
Dann dachte ich, ich könnte mit meiner Funktion groß daherkommen:
Sie war allerdings weniger performant.
Lag an der while-Schleife.
Daher meine zweite Version eher mit Arrays:
Die ist die schnellste. In meinen Performancetests (ähnlich denen vom Hund), performten die Funktionen bei vielen Durchläufen in etwa so:
Evilseyes: 0,38 sek
Meine 1.: 0,48 sek
Meine 2. 0,25 sek
Meine Frage an euch: geht es noch performanter und/oder trickreicher?
Freue mich auf eure Antworten.
ich habe mal vor einer Weile auf inquake.de (ehemals planetquake.de) einen Contest zur Programmierung einer Funktion ausgerufen, die aus einer absoluten URL und einer relativen URL eine absolute URL zusammensetzt. Es gibt in PHP eine ähnliche Funktion, die aber die aktuelle absolute URL nimmt, man keine übergeben.
Die Signatur meiner Funktion ist folgendermaßen:
absurl($basepath, $url)
Nachfolgend einige Eingabeparameter mit der erwarteten Ausgabe:
Eingabe:
$basepath = 'http://www.google.com/site/lala/';
$url = '/so/test.gif';
Ausgabe:
http://www.google.com/site/lala/so/test.gif
Eingabe:
$basepath = 'http://www.google.com/site/lala/';
$url = 'so/test.gif';
Ausgabe:
http://www.google.com/site/lala/so/test.gif
Eingabe:
$basepath = 'http://www.google.com/site/lala/';
$url = '../../test.gif';
Ausgabe:
http://www.google.com/test.gif
Die erste Antwort (von Evilseye) hatte mich ein wenig verwundert, sie war recht lang und sah nicht performant aus:
PHP-Code:
function absUrl($basepath, $url)
{
// remove "http://" from basepath and store it to
// the resultstring
$basepath = str_replace ("http://", "", $basepath);
$result = "http://";
// check if unexpected slashes are on end of url
// and remove them
while (substr($basepath, -1, 1) == '/')
$basepath = substr($basepath, 0, strlen($basepath)-1);
// write both urls to temp arrays and store
// the number of items from each array
$tempUrl1 = explode("/", $url);
$sizeUrl1 = count ($tempUrl1);
$tempUrl2 = explode("/", $basepath);
$sizeUrl2 = count($tempUrl2);
// count the number of relative "dir up"
$counter = 0;
for ($i = 0; $i < $sizeUrl1; $i++)
if (strcmp($tempUrl1[$i], "..") == 0)
$counter++;
// write basepath to resultstring
for ($i = 0; $i < $sizeUrl2-$counter; $i++)
{
if (strcmp($tempUrl2[$i], "") != 0) {
$result .= $tempUrl2[$i];
if ($i < $sizeUrl2-$counter)
$result .= "/";
}
}
// append relative url to resultstring
for ($i = 0; $i < $sizeUrl1; $i++)
{
if ((strcmp($tempUrl1[$i], "..") != 0) &&
(strcmp($tempUrl1[$i], "") != 0)) {
$result .= $tempUrl1[$i];
if ($i < $sizeUrl1-1)
$result .= "/";
}
}
return $result;
}
Dann dachte ich, ich könnte mit meiner Funktion groß daherkommen:
PHP-Code:
function makeAbsoluteURL($basepath, $url) {
//Wenn $url mit http anfängt, zurückgeben, da absolut
if (substr_compare($url, 'http://', 0, 7, true) == 0) {
return $url;
}
else {
//Eventuellen führenden Slash entfernen
if ($url[0] == '/') $url = substr($url, 1, strlen($url) - 1);
}
//Wieviele Verzeichnisse muss hochgegangen werden?
$dirsup = substr_count($url, '../');
$i = strlen($basepath);
while ($slash <= $dirsup) {
$slash += ($basepath[--$i] == '/');
}
return substr($basepath, 0, $i). '/'. str_replace('../', '', $url);
}
Lag an der while-Schleife.
Daher meine zweite Version eher mit Arrays:
PHP-Code:
function absurl($basepath, $url){
if (substr_compare($url, 'http://', 0, 7, true) == 0) {
return $url;
}
else {
//Eventuellen führenden Slash entfernen
if ($url[0] == '/') $url = substr($url, 1, strlen($url) - 1);
}
$arr = explode('/', $basepath);
return implode('/', array_slice($arr, 0, count($arr)
- substr_count($url, '../'))). '/'. str_replace('../', '', $url);
}
Evilseyes: 0,38 sek
Meine 1.: 0,48 sek
Meine 2. 0,25 sek
Meine Frage an euch: geht es noch performanter und/oder trickreicher?
Freue mich auf eure Antworten.
Kommentar