Conflit entre deux REGEXP

Invité
Invité n'ayant pas de compte PHPfrance

02 sept. 2006, 18:35

Bonjour à tous,
Voici un petit problème que je n'arrive pas à résoudre... J'ai une fonction qui doit transformer les URL en liens cliquables et une fonction de BBCode pour la balise image. Or, la balise [ IMG ] peut contenir ... une URL. et ma première fonction transforme alors l'url de l'image en lien clicable ; ce qui donne des : <img src="<a href="http://site.com/image.gif"> alt="" /> ... comment résoudre ce problème ? Voici les lignes de code, dans l'ordre
<?php
function rogneurl1($url)
{
$nb = strlen($url[0]);
$link = ($nb > 50) ? substr($url[0], 0, 50)."(...)" : $url[0];
$lien = '<a href="'.$url[0].'">'.$link.'</a>';
return $lien;
}
function rogneurl2($url)
{
$nb = strlen($url[4]);
$link = ($nb > 50) ? substr($url[4], 0, 50)."(...)" : $url[4];
$lien = $url[2].'<a href="http://www.'.$url[4].'">www.'.$link.'</a>';
return $lien;
}
function ck($img)
{
ini_set('allow_url_fopen', '1');
$image='';
if (@fclose(@fopen($img[1], 'r')))
{
$tab = getimagesize($img[1]); // on récupère la taille de l'image
$width = ($tab[0] > 370) ? ' width="370"' : '';
$image = '<img src="'.$img[1].'"'.$width.' alt="Image Utilisateur" />';
}
return $image;
}
function bbcode($chaine)
{
$chaine = preg_replace_callback('#\[img ](.+?)\[/img ]#si','ck',$chaine);
$chaine = preg_replace_callback("`(((ftp://)|(http(s?)://))(([[:alnum:]]|[-\%\.\?\=\#\_\:\&\/\~\+\@\,\;])*))`i",'rogneurl1',$chaine);
$chaine = preg_replace_callback("`(([^/])www\.|(^www\.))(([[:alnum:]]|[-\%\.\?\=\#\_\:\&\/\~\+\@\,\;])*)`i",'rogneurl2',$chaine);
}
?>
D'avance merci

maya
Invité n'ayant pas de compte PHPfrance

03 sept. 2006, 01:22

personne ne voit ce qui clocherait ?

Mammouth du PHP | 19672 Messages

03 sept. 2006, 06:43

Ajoute une assertion négative en début de masque pour les urls se trouvant dans des balises img, quelque chose du genre :

Code : Tout sélectionner

^(?<!src=\")...etc...
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

maya
Invité n'ayant pas de compte PHPfrance

03 sept. 2006, 14:47

$chaine = preg_replace_callback("`^(?<!src=\")(((ftp://)|(http(s?)://))(([[:alnum:]]|[-\%\.\?\=\#\_\:\&\/\~\+\@\,\;])*))`i",'rogneurl1',$chaine);
$chaine = preg_replace_callback("`^(?<!src=\")(([^/])www\.|(^www\.))(([[:alnum:]]|[-\%\.\?\=\#\_\:\&\/\~\+\@\,\;])*)`i",'rogneurl2',$chaine); 
Merci Cyrano, j'ai essayé comme ci dessus, mais ça ne marche pas, les URL ne se transforment plus en lien cliquable.... meme si la balise [ img ] fonctionne de nouveau :s
J'ai essayé avec (^!src=\") puis avec (!^src=\") puis (^!(src=\")) mais sans succès...

D'avance merci pour votre aide

Mammouth du PHP | 19672 Messages

03 sept. 2006, 15:56

Curieux... je viens de faire ceci qui fonctionne : l'expression pour les masques de toutes les urls possibles est à affiner, mais l'exemple est fonctionnel:
<?php
function clicable($url)
{
    $lien = "<a href=\"". $url[1] ."\">". $url[1] ."</a>";
    return $lien;
}

$masque = "#((?<!href=\")(?<!src=\")(?:(?:ftp://)|(?:http(?:s?)://))(?:[a-zA-Z-_]*\.)+(?:[a-z]{2,4})(?:(?:/[a-z]*)*(?:\.[a-z]{3,4}))?)#i";
$chaine  = '<img src="http://www.phpfrance.com/forums/images/logo_phpfrance.gif"/>Lien vers http://www.monsite.com/index.php en principe clicable.<br />';
$chaine .= 'Avec une autre adresse dans la suite du texte, par exemple vers http://www.phpfrance.com/forums/index.php, ça fonctionne toujours';
$texte = preg_replace_callback($masque, clicable, $chaine);
echo($texte);
?>
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

maya
Invité n'ayant pas de compte PHPfrance

03 sept. 2006, 16:17

Je te remercie infiniment Cyrano ! Ca fonctionne effectivement !
Sur le modèle de ton 2e post, j'ai réessayé avec ta première suggestion en enlevant ^ et en plaçant (?<!src=\") après la première parenthese :
<?php $chaine = preg_replace_callback("`((?<!src=\")((ftp://)|(http(s?)://))(([[:alnum:]]|[-\%\.\?\=\#\_\:\&\/\~\+\@\,\;])*))`i",'rogneurl1',$chaine);
$chaine = preg_replace_callback("`((?<!src=\")([^/])www\.|(^www\.))(([[:alnum:]]|[-\%\.\?\=\#\_\:\&\/\~\+\@\,\;])*)`i",'rogneurl2',$chaine); 
Et ça marche aussi ! Merci encore !
Par contre, j'ai une deuxième difficulté (différente de celle d'origine du post), c'est par rapport à la fonction ck (cf premier post du topic), qui est sensée verifier l'existence de l'image et de la redimensionner le cas échéant. Cette fonction ne fonctionne pas avec les images présentes sur le site ... Est ce possible de changer cela ?
Meme quand j'enleve la vérification de l'existence, l'image n'est pas redimensionnée. Et sinon rien n'apparait.

maya
Invité n'ayant pas de compte PHPfrance

03 sept. 2006, 18:36

Par rapport à mon post précédent, dois-je utiliser un parse_url() pour récupérer le nom de domaine du site sur lequel est hebergé l'image et s'il est différent de mon site, vérifier l'existence de l'image avec ini_set('allow_url_fopen', '1');
if (@fclose(@fopen($img[1], 'r'))) etc
et si il est hebergé sur mon site faire avec if(file_exists()) ... etc

??? ça me parait tout de meme compliqué. mais je ne vois rien qui puisse t etre plus simple.

Sinon, getimagesize n'a pas l'air de fonctionner avec getimagesize("http://www.monsite.com/img.gif"); (où monsite.com est mon site, c'est à dire que l'utilisateur entre l'url complete, d'une image hebergée sur mon serveur ça ne marche pas ...) Est ce normal ? Y a t il un moyen de contourner ce problème ?

D'avance merci

maya
Invité n'ayant pas de compte PHPfrance

04 sept. 2006, 00:38

Voilà, j'ai donc réécri la fonction ck, de façon à traiter toutes les URL d'image, qu'elles soient issues de mon serveur ou non. Voici ma nouvelle fonction : pouvez vous me dire s'il y a des problèmes ? En tout cas elle fonctionne parfaitement ! :)
function ck($img) 
	{
	$image='';
	$location = parse_url($img[1]);
	if($location[host]==$_SERVER['HTTP_HOST'])
		{
		if(file_exists($_SERVER['HTTP_RACINE'].$location[path]))
			{
			$exist = "ok";
			$imgpath = $_SERVER['HTTP_RACINE'].$location[path];	
			}
		}
	else
		{
	     ini_set('allow_url_fopen', '1');
	     if (@fclose(@fopen($img[1], 'r'))) 
	    	{
			$exist = "ok";
			$imgpath = $img[1];
	     	}		
		}
	if($exist=="ok")
		{
		$tab = getimagesize($imgpath);
	    if($tab[0] > 370)
			{
			$width = ' width="370"';
			$linkgd = '<br /><a href="'.$imgpath.'" onclick="window.open(this.href, \'image\', \'width='(.$tab[0]+15).', height='.($tab[1]+15).', top=5, left=5, toolbar=no, menubar=yes, location=yes, resizable=yes, scrollbars=yes, status=no\'); return false;">Agrandir l\'image</a>';
			}
		else
			{
			$width = 'width="'.$tab[0].'" height="'.$tab[1].'"';
			$linkgd = '';
			} 
	    $image = '<img src="'.$img[1].'"'.$width.' class="imgpost" alt="Image Utilisateur" />'.$linkgd;
		}
     return $image;
	} 

Mammouth du PHP | 19672 Messages

04 sept. 2006, 06:18

Dans l'ensemble, ça a l'air convenable. Il reste quelques points de détails comme par exemple des index de tableaux écrits comme des constantes, c'est à dire non encadrés par des séparateurs de chaines de caractères, et l'absence de deux alternatives, regarde ce que ça donne, j,ai commenté pour le second point :
<?php
function ck($img)
{
    $image = '';
    $location = parse_url($img[1]);
    if($location['host'] == $_SERVER['HTTP_HOST'])
    {
        if(file_exists($_SERVER['HTTP_RACINE'] . $location['path']))
        {
            $exist = "ok";
            $imgpath = $_SERVER['HTTP_RACINE'] . $location['path'];
        }
    }
    else
    {
        ini_set('allow_url_fopen', '1');
        if (@fclose(@fopen($img[1], 'r')))
        {
            $exist = "ok";
            $imgpath = $img[1];
        }
        // Pas de else ? Que se passe-t-il si l'ouverture du fichier échoue ?
    }
    if($exist == "ok")
    {
        $tab = getimagesize($imgpath);
        if($tab[0] > 370)
        {
            $width = ' width="370"';
            $linkgd = '<br /><a href="'. $imgpath .'" onclick="window.open(this.href, \'image\', \'width='. $tab[0]+15 .', height='. $tab[1]+15 .', top=5, left=5, toolbar=no, menubar=yes, location=yes, resizable=yes, scrollbars=yes, status=no\'); return false;">Agrandir l\'image</a>';
        }
        else
        {
            $width = 'width="'. $tab[0] .'" height="'. $tab[1] .'"';
            $linkgd = '';
        }
        $image = '<img src="'. $img[1] .'"'. $width .' class="imgpost" alt="Image Utilisateur" />'. $linkgd;
    }
    // Pas de else ? Et si la variable $exist n'est pas définie, que se passe-t-il ?
    return $image;
}
?>
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

maya
Invité n'ayant pas de compte PHPfrance

04 sept. 2006, 15:37

Effectivement, si $exist!="ok", c'est à dire en clair, si l'image n'existe pas, il ne se passe rien. Au début de la fonction on a $image=''; Si l'image existe, on affecte une autre valeur à $image . Sinon, on considère qu'il n'y a pas d'image. Sinon concernant les parentheses, ($tab[0]+15), je les avait rajouté parceque sinon ça faisait une erreur php. mais bon, dans ce cas là je vais faire $w = $tab[0]+15; $H = $tab[1]+15;