Compter sans prendre en compte les balises

Eléphanteau du PHP | 41 Messages

24 oct. 2011, 19:14

Bonjour,

je vais essayer d'être claire
BUT : afficher un texte depuis une table sql en 2 colonnes - colonne1 = 300 mots - colonne2 = le reste
MOYENS : affichage de la colonne1 OK, affichage de la colonne2 pas loin du OK
LE PROBLEME : je souhaiterais que ma fonction récupère le nombre de mots à partir du 300e sans prendre en compte les balises <div> et <br>

MON CODE :
function finchaine($chaine2, $nbmots2) { 
	$tab2 = explode(" ",$chaine2); 
	if (count($tab2) == $nbmots2) { 
	$affiche1 = $chaine2; 
	} else { 
	$affiche1 = " $tab2[300]"; 
		for ($i=300; $i<$nbmots2; $i++) { 
	$affiche1 .= " $tab2[$i]"; 
	} 
	} 
	return $affiche1; 
	} 
	$mots_complets2 = $contenu;
	$nbmots2 = count(preg_split("`\\W`", $contenu, 0, PREG_SPLIT_NO_EMPTY));
	$mot_courts2 = finchaine($mots_complets2, $nbmots2); 
	echo $mot_courts2;
Si j'affiche un chiffre indicatif je n'ai pas de soucis hormis le fait que si mon texte est plus long ça ne sera pas affiché.
Si je mets le compteur comme au-dessus, il me compte les balises html comprises et j'ai plusieurs messages d'erreurs lorsque l'on dépasse le nombre de mots à afficher
Notice: Undefined offset: 456 in C:\wamp\www\monsite\actualite.php on line 78
C'est logique!

J'ai bien tenté ça :
$nbmots2 = count(preg_split("<[<div>]*>", $contenu, 0, PREG_SPLIT_NO_EMPTY));
Mais ça veut pas :( il m'affiche plus de 2500 mots alors qu'il n'y en a que 570 environ...

Je m'en remets à vous, car je cherche, je cherche mais je ne trouve pas de solution :)

Merci d'avance !

ViPHP
xTG
ViPHP | 7331 Messages

24 oct. 2011, 19:27

C'est une belle usine que tu nous concoctes là. :P

Regardes plutôt du côté de strip_tags() et str_word_count().

Eléphanteau du PHP | 41 Messages

24 oct. 2011, 20:46

Si ya moyen de faire une fonction plus "propre" je suis preneuse de conseils! :)

ViPHP
xTG
ViPHP | 7331 Messages

24 oct. 2011, 20:49

Eh beh comme je te l'ai conseillé. Utilises strip_tags pour supprimer les balises, puis str_word_count te retournera le nombre de mots.

Eléphanteau du PHP | 41 Messages

24 oct. 2011, 21:10

Je pensais que le code complet était moisi :mrgreen:

Par rapport à ton conseil, le soucis c'est que j'ai besoin de mes balises pour la mise en page. C'est juste pour le comptage des mots qu'elles ne doivent pas être prises en compte. Pour l'instant ça m'enlève bien les balises <div></div> mais étrangement il ne veut pas ne pas compter les <br> et <strong>.

Que je fasse :
echo count(str_word_count($contenu, 1, '/(<)([^>]*?<)/'));

ou
echo count(str_word_count($contenu, 1, '<div></div><br><strong></strong>'));

Mammouth du PHP | 568 Messages

24 oct. 2011, 21:16

Et concrètement le but c'est quoi ? Afficher le début d'un texte et le tronquer afin d'ajouter un lire la suite ?

Eléphanteau du PHP | 41 Messages

24 oct. 2011, 22:23

Concrêtement j'ai un texte saisi via TinyEditor depuis mon backoffice (c'est un article), ainsi on peut y greffer des liens, des caractères en gras, et des paragraphes. Tout cela est inséré dans la BDD. Pour l'affichage, le texte est sur 2 colonnes. On est pas encore à pouvoir faire comme InDesign, à attribuer une taille de colonne laissant le texte passer tout seul sur la seconde... Donc je prends les 300 premiers mots que je mets dans ma colonne1, et dans la colonne 2 je prends le "reste" des mots à partir du 300e mot.

Or, le soucis c'est que si j'attribue une valeur max de mots (pour les multiples textes), j'ai un message d'erreur. Donc, comme les articles ne vont pas avoir un nombre de mots stricte, le truc c'est de compter le nombre de mots pour chaque article, et sans les balises car avec cela me fait des mots en trop, donc des messages erreur du type : Notice: Undefined offset: 458 in C:\wamp\www\monsite\actualite.php on line 78

Ouala :)

Mammouth du PHP | 568 Messages

24 oct. 2011, 23:14

Concrêtement j'ai un texte saisi via TinyEditor depuis mon backoffice (c'est un article), ainsi on peut y greffer des liens, des caractères en gras, et des paragraphes. Tout cela est inséré dans la BDD. Pour l'affichage, le texte est sur 2 colonnes. On est pas encore à pouvoir faire comme InDesign, à attribuer une taille de colonne laissant le texte passer tout seul sur la seconde... Donc je prends les 300 premiers mots que je mets dans ma colonne1, et dans la colonne 2 je prends le "reste" des mots à partir du 300e mot.

Or, le soucis c'est que si j'attribue une valeur max de mots (pour les multiples textes), j'ai un message d'erreur. Donc, comme les articles ne vont pas avoir un nombre de mots stricte, le truc c'est de compter le nombre de mots pour chaque article, et sans les balises car avec cela me fait des mots en trop, donc des messages erreur du type : Notice: Undefined offset: 458 in C:\wamp\www\monsite\actualite.php on line 78

Ouala :)
Tu peux nous montrer le code ?

Eléphanteau du PHP | 41 Messages

25 oct. 2011, 09:08

Voila le code :)
<?php include('header.php');

$id_transmit=$_GET['id'];
if (!isset($_GET["id"]) OR !is_numeric($_GET['id'])){

header('actualites.php');
}else{
	include('manager/connect.php');

	$page = mysql_query("SELECT * FROM actu WHERE id='".mysql_real_escape_string
($id_transmit)."'");

	if(mysql_num_rows($page) == 0)
	{
		header('actualites.php');
	}
	else
	{
		while($affiche = mysql_fetch_array($page))
		{
			$titre=$affiche['titre'];
			$date=$affiche['date'];
			$img_une=$affiche['img_une'];
			$img_art=$affiche['img_art'];
			$contenu=$affiche['news'];
?>
<div id="contenu">

<section>
	<h2><?php echo $titre; ?></h2>
	<h4><?php echo $date; ?></h4>
	
	<p class="actu">
<?php	
	function debutchaine($chaine, $nbmots) { 

	$tab = explode(" ",$chaine); 
	if (count($tab) <= $nbmots) { 
	$affiche2 = $chaine; 
	} else { 
	$affiche2 = " $tab[0]"; 
		for ($i=1; $i<$nbmots; $i++) { 
	$affiche2 .= " $tab[$i]"; 
	} 
	} 
	return $affiche2; 
	} 
	$mots_complets = $contenu;
	$nbmots = 335; 
	$mot_courts = debutchaine($mots_complets, $nbmots); 
	echo $mot_courts; 
?>
</p>
	<span class="actu_plus"><a href="actualites.php" class="btn_plus">Retourner à la page précédente <img src="img/b_retour.jpg"></a></span>
	<p class="actu2">
<?php
function finchaine($chaine2, $nbmots2) { 

	$tab2 = explode(" ",$chaine2); 
	if (count($tab2) == $nbmots2) { 
	$affiche1 = $chaine2; 
	} else { 
	$affiche1 = " $tab2[335]"; 
		for ($i=335; $i<$nbmots2; $i++) { 
	$affiche1 .= " $tab2[$i]"; 
	} 
	} 
	return $affiche1; 
	} 
	
	$mots_complets2 = $contenu;
	$nbmots2 = count(str_word_count($contenu, 1, '/(<)([^>]*?<)/'));
	$mot_courts2 = finchaine($mots_complets2, $nbmots2); 
	echo $mot_courts2;
	break;
		}
	}
}
?>
</p>

</section>

<?php include('footer.php'); ?>

Mammouth du PHP | 568 Messages

25 oct. 2011, 10:25

Tu veux compter le nombre de mot sans formatage => ok

Tu veux pouvoir afficher les 300 premiers mots dans une colonne avec le formatage, et le reste dans une seconde colonnes => c'est bien ça ?

Et comment tu gère le cas ou le 300ème mots tombe dans une phrase englobé dans une balise <p> ? Tu risque de créer des balises ouvertes qui ne seront pas fermé, non ?

Pour le reste pas encore regarder ton code.

Eléphanteau du PHP | 41 Messages

25 oct. 2011, 11:14

Justement là je veux compter les mots sans prendre en compte les balises. Avoir le nombre de mots sans balise. Ça n'empêche pas d'avoir les balises qui mettent en forme derrière... Après peut-être que WAMP est trop pointilleux et que j'aurais pas de message d'erreur sur le serveur en ligne.

ViPHP
xTG
ViPHP | 7331 Messages

25 oct. 2011, 11:56

Couper une chaîne en respectant les balises c'est la chose la plus compliqué à faire en fait. ^^
Il n'y a pas de raison de se chopper des warnings ou autre... (sauf si le code est mal rédigé)
Le souci est de couper le texte en plein milieu d'une base, la fermer pour la première partie et la réouvrir pour la seconde. :/
Bref c'est un joli casse-tête où il faudra mieux plancher sur l'algo avant même de penser à coder.

Eléphanteau du PHP | 41 Messages

25 oct. 2011, 12:03

Oui c'est peu ergonomique quand on y pense... Je peux également proposer d'intégrer des tags [colonne][/colonne] [colonne_last][/colonne–last], plus besoin de me casser la tête en PHP, ça ne sera que du css et du html, mon domaine. Après est-ce que l'utilisateur va capter le fonctionnement... C'est toujours ça le soucis, on essaie de faire au plus simple pour l'utilisateur au risque de faire un truc bof.

Mammouth du PHP | 568 Messages

25 oct. 2011, 14:21

Couper une chaîne en respectant les balises c'est la chose la plus compliqué à faire en fait. ^^
Il n'y a pas de raison de se chopper des warnings ou autre... (sauf si le code est mal rédigé)
Le souci est de couper le texte en plein milieu d'une base, la fermer pour la première partie et la réouvrir pour la seconde. :/
Bref c'est un joli casse-tête où il faudra mieux plancher sur l'algo avant même de penser à coder.
Et du coup je suis pas sûr que ce soit la meilleur idée, généralement quand je donne la possibilité à un utilisateur d'utiliser un composant comme tinymce ou autre, c'est justement pour permettre la mise en forme de texte et donc en aucun cas venir derrière pour modifier le texte.

Par contre, ce que j'ai déjà fait et qui me parait plus propre, c'est d'ajouter dans mon formulaire un champs description courte, qui elle sera utiliser pour l'affichage simple avec un lien + d'infos

Sinon dernier recourt, tu ne prend pas en compte le formatage du texte dans ta page qui liste, seulement dans la page détail.

ViPHP
xTG
ViPHP | 7331 Messages

25 oct. 2011, 14:47

Sinon si le but est juste une règle d'affichage c'est faisable avec une règle CSS sur le container.
http://www.quirksmode.org/css/multicolumn.html