Fonction utile : abs2rel

lundi 16 janvier 2012 à 23:00

La voila. Si j'ai une bête noire en PHP, c'est bien elle... je l'ai refait une dixaine de fois facilement au cours des 3 dernières années et à chaque fois je me contentait d'une version approximative qui me suffisais pour un cas précis. J'avais toujours des problèmes avec elle.

Et après plusieurs centaines de tentatives, en me basant tantôt sur parse_url ou pathinfo, voici enfin une version acceptable. Disons que pour l'instant, elle a passé tous mes tests avec succès et même si je sais que dans 6 mois je devrait sans doute la refaire, je vous présente abs2rel :

<?php
define('HTML_FILE', 'http://'. $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);

function abs2rel ($sLinkFrom, $sLinkTo) {
    $sLinkToCopy    = $sLinkTo;
    $sPath = '';
   
    /*
     *    $sPattern     = '(';
     *    $sPattern    .=    '[^\.\/\#\?]+://';                          //    http://
     *    $sPattern    .=    '[^\/\#\?]+(\.[^\/\#\?]+)?';                //    www.domain.ext
     *    $sPattern    .=    '(\/[^\/\#\?\.]+)*';                        //    [[/folder1[/folder2]]...]
     *    $sPattern    .=    '(\/[^\/\#\?\.]+\/|\.[^\/\#\?\.]+|\/?)';    //    /file.ext
     *    $sPattern    .= ')';                                           //   
     *    $sPattern    .= '([\/|\#|\?].*)?';                             //    #anchor OR ?get_variables OR /etc.
     */
   
    // Decoupe de linkFrom :
    preg_match('#^(([^\.\/\#\?]+://[^\/\#\?]+(\.[^\/\#\?]+)?(\/[^\/\#\?\.]+)*(\/[^\/\#\?\.]+\/|\.[^\/\#\?\.]+|\/?))([\/|\#|\?].*)?)$#', $sLinkFrom, $aMatchs);
    $sLinkFrom = $aMatchs[2];
   
    // Decoupe de linkTo :
    preg_match('#^(([^\.\/\#\?]+://[^\/\#\?]+(\.[^\/\#\?]+)?(\/[^\/\#\?\.]+)*(\/[^\/\#\?\.]+\/|\.[^\/\#\?\.]+|\/?))([\/|\#|\?].*)?)$#', $sLinkTo, $aMatchs);
    $sLinkTo = $aMatchs[2];
    $sAdd = isset($aMatchs[6]) ? $aMatchs[6] : '';
    $sExt = isset($aMatchs[5]) ? $aMatchs[5] : '';
   
   
    $aParseFrom    = parse_url($sLinkFrom);
    $aParseTo    = parse_url($sLinkTo);
   
    if ( ($aParseFrom['scheme']!=$aParseTo['scheme']) || ($aParseFrom['host']!=$aParseTo['host']) ) {
        return $sLinkToCopy;
    }
   
    $sPathFrom        = $aParseFrom['path'];
    $sPathTo        = $aParseTo['path'];
    $sPathFromCopy    = $sPathFrom;
   
    if ( $sPathFrom==$sPathTo ) {
        if ( strlen($sAdd)>0 ) {
            if ( $sAdd{0}=='/' ) {
                if ( $sExt=='' ) {
                    $sAdd = './' . $sAdd;
                } else {
                    $sAdd = substr($sLinkTo, strrpos($sLinkTo, '/', -2)+1 ) . $sAdd;
                }
            }
            return $sAdd;
        } else {
            return '';
        }
    }
   
    while ( !preg_match('#^'. $sPathFrom .'#', $sPathTo) && strlen($sPathFrom)>0 ) {
        $sPath .= '../';
        $sPathFrom = substr($sPathFrom, 0, strrpos($sPathFrom, '/', -2)+1 );
    }
   
    if ( $sPathFrom=='/' ) {
        return $sPathTo . $sAdd;
    }
   
    if ( $sPathFromCopy{ strlen($sPathFromCopy)-1 } != '/' ) {
        if ( strlen($sPath)>0 ) {
            $sPath = substr($sPath, 3);
        } else {
            $sPath = substr($sPathFromCopy, strrpos($sPathFromCopy, '/', -2)+1 );
        }
    }
   
    return $sPath . substr($sPathTo, strlen($sPathFrom) ) . $sAdd;
}

En bref...

Dernier article

La dictature sur facebook

Cette semaine, l'actu, c'est Facebook qui trébuche. Le réseau social vient en effet de supprimer le droit de vote de ses membres. On a aussi GoogleNow sur Chrome, des nouvelles pas très réjouissantes de l'UIT, du piratage, l'étoile de la mort de Star Wars et une évasion échoué.

Ressources externes