IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

fonction pour collecter les liens et URLs dans une chaine


Sujet :

Langage PHP

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Par défaut fonction pour collecter les liens et URLs dans une chaine
    Bonjour les gens!

    J'ai écris une fonction pour collecter les liens et URLs dans une chaine de caractère. Il est fort possible que ca existe déjà mais je n'en ai pas trouvé, de plus il fallait que la fonction réponde à certains critères, a savoir être assez rapide et prendre en compte les balises <base> dans les pages html.

    Pour la rapidité, j'ai choisi de ne pas faire la recherche de liens avec des expressions régulières dans toute la chaine de caractère, mais de faire la recherche avec un strpos et ensuite de traiter le petit bout de chaine extrait avec ereg() (à vous de me dire ce que vous en pensez )

    La fonction collecte les liens, les textes associés et les extensions des fichiers si fichiers il y a.

    Voici le code si cela peut aider qqun ou pour les courageux qui veulent y jeter un coup d'oeil (je sais, je code très compact...). Critiques bienvenues!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    function get_link($string,$baseurl=""){
    $url=array();
    $urltexte=array();
    $urlext=array();
    $len=strlen($string);
    $pos=-1;
    $base=ereg_replace("(/$)|(/[^/]*\.[^/]*$)","",$baseurl)."/";
    $nextbasepos=strpos($string,"<base");
    while ((($pos=strpos($string,"<a",$pos+1))!==false) && (($pos2=strpos($string,'>',$pos+1))!==false) && (($pos3=strpos($string,"<",$pos2+1))!==false)){
    $str=substr($string,$pos,$pos3-$pos+1);
     
    while (($nextbasepos!==false) && ($nextbasepos < $pos)){
    if ((($pos4=strpos($string,">",$nextbasepos+1))!==false)
    && ereg('href[ ]*=[ ]*"[ ]*(http://[^"]*)"',substr($string,$nextbasepos,$pos4-$nextbasepos+1),$arr)) $base=ereg_replace("(/$)|(/[^/]*\.[^/]*$)","",trim($arr[1]))."/";
    $nextbasepos=$pos4 ? strpos($string,"<base",$pos4) : false;
    }
     
    $pos=$pos3;
    if (ereg('href[^"]*"[ ]*([^"#][^"]*)"[^>]*>([^<]*)<',$str,$arr)){
    $http=(substr(trim($arr[1]),0,7)==="http://");
    array_push($url,($link=$http ? trim($arr[1]) : $base.ereg_replace("^/","",trim($arr[1]))));
    array_push($urltexte,$arr[2]);
     
    array_push($urlext,ereg("[^?#]*[^/?#]/[a-zA-Z0-9_.\-]+(\.[a-zA-Z0-9]+)(\?|#|$)",$link,$arr2) ? $arr2[1] : "");
    echo htmlentities($link."DFD".ereg("[^?#]*[^/?#]/[a-zA-Z0-9_.\-]+(\.[a-zA-Z0-9]+)(\?|#|$)",$link,$arr2)."RR".$arr2[1])."<br>";
    }
    }
     
    return array($url,$urltexte,$urlext);
    }
    j'ai rédigé un petit tuto ici:
    http://www.idees-et-solutions.fr/idees.php?page=id163
    (critiques bienvenues aussi sur le tuto) et j'y a mis une autre fonction qui en plus cherche les URL qui ne sont pas en lien (commencant par http:// et www. )

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Par défaut
    oups j'ai oublié de retirer les "echo" de test. Voici le code nettoyé des echo:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    function get_link($string,$baseurl=""){
    $url=array();
    $urltexte=array();
    $urlext=array();
    $len=strlen($string);
    $pos=-1;
    $base=ereg_replace("(/$)|(/[^/]*\.[^/]*$)","",$baseurl)."/";
    $nextbasepos=strpos($string,"<base");
    while ((($pos=strpos($string,"<a",$pos+1))!==false) && (($pos2=strpos($string,'>',$pos+1))!==false) && (($pos3=strpos($string,"<",$pos2+1))!==false)){
    $str=substr($string,$pos,$pos3-$pos+1);
     
    while (($nextbasepos!==false) && ($nextbasepos < $pos)){
    if ((($pos4=strpos($string,">",$nextbasepos+1))!==false)
    && ereg('href[ ]*=[ ]*"[ ]*(http://[^"]*)"',substr($string,$nextbasepos,$pos4-$nextbasepos+1),$arr)) $base=ereg_replace("(/$)|(/[^/]*\.[^/]*$)","",trim($arr[1]))."/";
    $nextbasepos=$pos4 ? strpos($string,"<base",$pos4) : false;
    }
     
    $pos=$pos3;
    if (ereg('href[^"]*"[ ]*([^"#][^"]*)"[^>]*>([^<]*)<',$str,$arr)){
    $http=(substr(trim($arr[1]),0,7)==="http://");
    array_push($url,($link=$http ? trim($arr[1]) : $base.ereg_replace("^/","",trim($arr[1]))));
    array_push($urltexte,$arr[2]);
     
    array_push($urlext,ereg("[^?#]*[^/?#]/[a-zA-Z0-9_.\-]+(\.[a-zA-Z0-9]+)(\?|#|$)",$link,$arr2) ? $arr2[1] : "");
    }
    }
     
    return array($url,$urltexte,$urlext);
    }

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Par défaut
    Encore trouvé une erreur. Version corrigée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    function get_link($string,$baseurl=""){
    $url=array();
    $urltexte=array();
    $urlext=array();
    $len=strlen($string);
    $pos=-1;
    $base=ereg_replace("(/$)|(/[^/]*\.[^/]*$)","",$baseurl)."/";
    $base2=ereg("http://[^/]+/",$base,$arr3) ? $arr3[0] : $base;
    $nextbasepos=strpos($string,"<base");
    while ((($pos=strpos($string,"<a",$pos+1))!==false) && (($pos2=strpos($string,'>',$pos+1))!==false) && (($pos3=strpos($string,"<",$pos2+1))!==false)){
    $str=substr($string,$pos,$pos3-$pos+1);
     
    while (($nextbasepos!==false) && ($nextbasepos < $pos)){
    if ((($pos4=strpos($string,">",$nextbasepos+1))!==false)
    && ereg('href[ ]*=[ ]*"[ ]*(http://[^"]*)"',substr($string,$nextbasepos,$pos4-$nextbasepos+1),$arr)) $base=ereg_replace("(/$)|(/[^/]*\.[^/]*$)","",trim($arr[1]))."/";
    $nextbasepos=$pos4 ? strpos($string,"<base",$pos4) : false;
    }
     
    $pos=$pos3;
    if (ereg('href[^"]*"[ ]*([^"#][^"]*)"[^>]*>([^<]*)<',$str,$arr)){
    $http=(substr(trim($arr[1]),0,7)==="http://");
    $sousdoss=ereg("^[^?#]*/[^?#]*(#|\?|$)",trim($arr[1]));
    array_push($url,($link=($http ? trim($arr[1]) : ($sousdoss ? $base2 : $base).ereg_replace("^/","",trim($arr[1])))));
    array_push($urltexte,$arr[2]);
     
    array_push($urlext,ereg("[^?#]*[^/?#]/[a-zA-Z0-9_.\-]+(\.[a-zA-Z0-9]+)(\?|#|$)",$link,$arr2) ? $arr2[1] : "");
    }
    }
     
    return array($url,$urltexte,$urlext);
    }

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Par défaut
    (Dernière?) version. J'ai corrigé quelques petites choses et maintenant cette fonction get_link devrait interpréter les liens exactement comme Firefox (je ne sais pas si c'est la meilleure référence ms en tout cas Firefox se débrouille mieux que i.e...je sais ce n'est pas une nouvelle)

    Au cas ou ce ne serait pas clair, je rappelle que cette fonction ne fait pas que collecter les liens présents dans les <a href="">, elle interprète aussi ces liens en fonction des balises <base> comme le ferait un navigateur (en l'occurence firefox), collecte les textes correspondant aux liens et collecte les extensions des fichiers vers lesquels pointent les liens, si fichier il y a

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    function get_link($string,$inibase1=""){
    $url=array();
    $urltexte=array();
    $urlext=array();
    $len=strlen($string);
    $pos=-1;
    $debut=strtok($inibase1,"#?");
    $inibase1=ereg("^http://[^/]*",$debut) ? $debut."/".substr($inibase1,strlen($debut)) : $inibase1;
    $inibase2=ereg_replace("^(http://.+)/[^/]*$","\\1",
    ereg_replace("^http://[/]*","http://",$debut))."/";
    $inibase3=ereg_replace("^(http://[^/]+)/.*","\\1",$inibase2)."/";
    $base1=$inibase1;$base2=$inibase2;$base3=$inibase3;
    $nextbasepos=strpos($string,"<base");
    while ((($pos=strpos($string,"<a ",$pos+1))!==false) && (($pos2=strpos($string,'>',$pos+1))!==false) && (($pos3=strpos($string,"<",$pos2+1))!==false)){
    $str=substr($string,$pos,$pos3-$pos+1);
    while (($nextbasepos!==false) && ($nextbasepos < $pos)){
    if ((($pos4=strpos($string,">",$nextbasepos+1))!==false)
    && ereg('href[ ]*=[ ]*"[ ]*(http:[^"]*)"',substr($string,$nextbasepos,$pos4-$nextbasepos+1),$arr)){
    $basex=trim($arr[1]); $base1=((substr($basex,0,7)==="http://") ? $basex : ((substr($basex,0,6)==="http:/") ? $inibase3.substr($basex,6) : $inibase2.substr($basex,5)));
    $debut=strtok($base1,"#?");
    $base1=ereg("^http://[^/]*",$debut) ? $debut."/".substr($base1,strlen($debut)) : $base1;
    $base2=ereg_replace("^(http://.+)/[^/]*$","\\1",
    ereg_replace("^http://[/]*","http://",$debut))."/";
    $base3=ereg_replace("^(http://[^/]+)/.*","\\1",$base2)."/";
    }
    $nextbasepos=$pos4 ? strpos($string,"<base",$pos4) : false;
    }
    $pos=$pos3;
    if (ereg('href[^"]*"[ ]*([^"]*)"[^>]*>([^<]*)<',$str,$arr)){
    $http=(substr(trim($arr[1]),0,7)==="http://");
    $root=(substr(trim($arr[1]),0,1)==="/");
    $self= !trim($arr[1]) || (substr(trim($arr[1]),0,1)==="#");
    array_push($url,($link=($http ? trim($arr[1]) : ($self ? strtok($base1,'#').trim($arr[1]) : ($root ? $base3.substr(trim($arr[1]),1) : $base2.trim($arr[1]))))));
    array_push($urltexte,$arr[2]);
     
    array_push($urlext,ereg("[^?#]*[^/?#]/[a-zA-Z0-9_.\-]+(\.[a-zA-Z0-9]+)(\?|#|$)",$link,$arr2) ? $arr2[1] : "");
    }
    }
     
    return array($url,$urltexte,$urlext);
    }
    Si un admin passe par la: est-il possible d'effacer les anciennes versions de la fonction et de ne laisser que la dernière?

  5. #5
    Membre chevronné
    Profil pro
    Responsable de service informatique
    Inscrit en
    Septembre 2004
    Messages
    352
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 352
    Par défaut
    Pour gagner un peu plus en perf, tu peux remplacer tes fonctions ereg* par preg*. En plus, elles commencent à être dépréciés et ne vont plus exister dans la nouvelle version de PHP.

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Par défaut
    Citation Envoyé par Chengj Voir le message
    Pour gagner un peu plus en perf, tu peux remplacer tes fonctions ereg* par preg*. En plus, elles commencent à être dépréciés et ne vont plus exister dans la nouvelle version de PHP.
    Merci Chengj pour ton conseil. Je n'ai pas encore un le temps de me pencher sur les expressions régulières avec preg et je comptais faire le changement quand je l'aurais fait (a moins que les expressions régulières ereg marchent telles quelles avec preg dans quel cas il suffit de changer le nom de la fonction).

  7. #7
    Membre chevronné
    Profil pro
    Responsable de service informatique
    Inscrit en
    Septembre 2004
    Messages
    352
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 352
    Par défaut
    On peut en gagner un peu plus au niveau des boucles ou en replaçant les "" par des '' à certains endroits. Pourrais-tu indenter ton code ? J'ne vois rien dedans

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    193
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 193
    Par défaut
    Citation Envoyé par Chengj Voir le message
    On peut en gagner un peu plus au niveau des boucles ou en replaçant les "" par des '' à certains endroits. Pourrais-tu indenter ton code ? J'ne vois rien dedans
    ' ' sont plus rapides que " " car " " interprete $etc comme une variable?

    Mon code est assez compact dc c'est pas facile de l'indenter naturellement, mais voila:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    function get_link($string,$inibase1=""){
    $url=array();
    $urltexte=array();
    $urlext=array();
    $len=strlen($string);
    $pos=-1;
    $debut=strtok($inibase1,"#?");
    $inibase1=ereg("^http://[^/]*",$debut) ? $debut."/".substr($inibase1,strlen($debut)) : $inibase1;
    $inibase2=ereg_replace("^(http://.+)/[^/]*$","\\1",
    ereg_replace("^http://[/]*","http://",$debut))."/";
    $inibase3=ereg_replace("^(http://[^/]+)/.*","\\1",$inibase2)."/";
    $base1=$inibase1;$base2=$inibase2;$base3=$inibase3;
    $nextbasepos=strpos($string,"<base");
    while ((($pos=strpos($string,"<a ",$pos+1))!==false) &&
     (($pos2=strpos($string,'>',$pos+1))!==false) &&
     (($pos3=strpos($string,"<",$pos2+1))!==false)){
    $str=substr($string,$pos,$pos3-$pos+1);
    while (($nextbasepos!==false) && ($nextbasepos < $pos)){
    if ((($pos4=strpos($string,">",$nextbasepos+1))!==false)
    && ereg('href[ ]*=[ ]*"[ ]*(http:[^"]*)"',substr($string,$nextbasepos,$pos4-$nextbasepos+1),$arr)){
    $basex=trim($arr[1]); 
     
    $base1=((substr($basex,0,7)==="http://") ? 
    $basex :
     ((substr($basex,0,6)==="http:/") ? 
    $inibase3.substr($basex,6) : 
    $inibase2.substr($basex,5)));
     
    $debut=strtok($base1,"#?");
    $base1=ereg("^http://[^/]*",$debut) ? $debut."/".substr($base1,strlen($debut)) : $base1;
    $base2=ereg_replace("^(http://.+)/[^/]*$","\\1",
    ereg_replace("^http://[/]*","http://",$debut))."/";
    $base3=ereg_replace("^(http://[^/]+)/.*","\\1",$base2)."/";
    }
    $nextbasepos=$pos4 ? strpos($string,"<base",$pos4) : false;
    }
    $pos=$pos3;
    if (ereg('href[^"]*"[ ]*([^"]*)"[^>]*>([^<]*)<',$str,$arr)){
    $http=(substr(trim($arr[1]),0,7)==="http://");
    $root=(substr(trim($arr[1]),0,1)==="/");
    $self= !trim($arr[1]) || (substr(trim($arr[1]),0,1)==="#");
     
    array_push($url, ($link=($http ?
     trim($arr[1]) : 
    ($self ?
     strtok($base1,'#').trim($arr[1]) :
     ($root ? $base3.substr(trim($arr[1]),1) :
     $base2.trim($arr[1]))))));
     
    array_push($urltexte,$arr[2]);
     
    array_push($urlext,
    ereg("[^?#]*[^/?#]/[a-zA-Z0-9_.\-]+(\.[a-zA-Z0-9]+)(\?|#|$)",$link,$arr2) ? $arr2[1] : "");
    }
    }
     
    return array($url,$urltexte,$urlext);
    }

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/05/2013, 22h18
  2. Réponses: 2
    Dernier message: 18/04/2011, 10h24
  3. Réponses: 10
    Dernier message: 10/02/2010, 08h49
  4. Réponses: 2
    Dernier message: 21/12/2009, 06h35
  5. Réponses: 6
    Dernier message: 07/02/2008, 12h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo