Absolute und relative URL verrechnen - Performancetricks

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Absolute und relative URL verrechnen - Performancetricks

    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:

    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, -11) == '/')
      
    $basepath substr($basepath0strlen($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://'07true) == 0) {
            return 
    $url;
        }
        else {
            
    //Eventuellen führenden Slash entfernen
            
    if ($url[0] == '/'$url substr($url1strlen($url) - 1);
        }
        
    //Wieviele Verzeichnisse muss hochgegangen werden?
        
    $dirsup substr_count($url'../');
        
    $i strlen($basepath);
        while (
    $slash <= $dirsup) {
            
    $slash += ($basepath[--$i] == '/');
        }
        return 
    substr($basepath0$i). '/'str_replace('../'''$url);

    Sie war allerdings weniger performant.
    Lag an der while-Schleife.

    Daher meine zweite Version eher mit Arrays:

    PHP-Code:
    function absurl($basepath$url){
    if (
    substr_compare($url'http://'07true) == 0) {
            return 
    $url;
        }
        else {
            
    //Eventuellen führenden Slash entfernen
            
    if ($url[0] == '/'$url substr($url1strlen($url) - 1);
        }

        
    $arr explode('/'$basepath);
        return 
    implode('/'array_slice($arr0count($arr)
                      - 
    substr_count($url'../'))). '/'str_replace('../'''$url);

    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.
    PHP-Code:
    function verrecke_elend()
    {
        die(
    'Aaargh!');


  • #2
    Kommt drauf an, was du mit der Ausgabe der Funktion vorhast. Für deine drei Beispiele da oben gibt
    PHP-Code:
    function absurl($b$u) { return $b.$u; } 
    nämlich folgende URLs zurück:
    - http://www.google.com/site/lala//so/test.gif
    - http://www.google.com/site/lala/so/test.gif
    - http://www.google.com/site/lala/../../test.gif

    Die kannst du mir nichts, dir nichts in <img src="..."> verwursten.

    Performanter als die Stringverkettung gehts wohl nicht. Allerdings kann man auf die Funktion dann komplett verzichten, Strings kann man auch direkt verketten und spart sich so den Overhead eines Funktionsaufrufs.

    Kommentar


    • #3
      Re: Absolute und relative URL verrechnen - Performancetricks

      Original geschrieben von CadEx

      Meine Frage an euch: geht es noch performanter und/oder trickreicher?
      aufgrund deiner Frage schiebe ich den Thread mal nach BS, denn das hat im Codeschnipsel nichts verloren

      Kommentar

      Lädt...
      X