Précédent   Forum des professionnels en informatique > PHP > Langage > Fonctions
Fonctions Forum d'entraide sur les fonctions PHP. Avant de poster -> FAQ fonctions et Sources diverses
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 25/02/2011, 14h21   #1
Membre du Club
 
Homme
Développeur Web
Inscription : juillet 2009
Messages : 54
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : juillet 2009
Messages : 54
Points : 27
Points : 27
Par défaut afficher des lignes de même longueur

Bonjour,

je dois afficher une liste de produits (une centaine), et par souci d'esthétique je voudrais que toutes les lignes de cette liste aient une longueur similaire (ordre d'apparition de chaque produit indifférent).

Pour l'instant je fais comme cela, mais c'est trop approximatif :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
$mon_array = array('prune', 'pissenlit', 'cresson', 'framboise', 'chataigne', 'choux de Bruxelles', 'celeri rave', 'poire', 'noix', 'kiwi', 'navet', 'carotte', 'nectarine', 'groseille', 'fruit de la passion', 'tomate', 'betteraves', 'raisin', 'papaye', 'abricot', 'orange', 'grenade', 'ciboulette', 'oignon', 'pêche', 'cerise', 'choux-fleurs', 'banane', 'amande', 'haricots secs', 'melon', 'pistache', 'citron', 'figue', 'myrtille', 'champignon', 'endive', 'rutabaga', 'pomme', 'mangue', 'courge', 'fraise', 'datte', 'échalottes', 'cardon', 'pastèque', 'litchi', 'ananas', 'brocoli', 'coing', 'asperge', 'lentilles sêches', 'mandarine', 'pamplemousse', 'noisette', 'pois cassés', 'petits pois frais', 'kaki', 'olives', 'courgette', 'salsifis', 'artichaut', 'aubergine');
 
$nb_lettres=0;
 
foreach($mon_array as $produit)
{
$nb_lettres+= strlen($produit);
 
if ($nb_lettres<50) { echo $produit,' '; }
 
else { echo '<br />'; $nb_lettres=0;  }
}
Y aurait-il un moyen d'avoir des longueurs de lignes plus homogènes?

Merci d'avance de votre aide!
gambic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 15h20   #2
Modérateur
 
Avatar de Benjamin Delespierre
 
Benjamin Delespierre
Développeur Web
Inscription : février 2010
Messages : 2 984
Détails du profil
Informations personnelles :
Nom : Benjamin Delespierre
Âge : 24
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : février 2010
Messages : 2 984
Points : 5 014
Points : 5 014
Hello

Tu peux faire ça de deux façon:
- soit tu définis une taille maximum pour le conteneur de la chaine avec du CSS coté client (au rique que des lettres soient coupées ce qui est complêtement inhéstétique)
- soit tu coupes / complêtes les chaines avec PHP.

Prennons l'exemple suivant:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
$strings = array(
'foobar',
'lorem ipsum sit amet',
'hey dude, PHP rocks!'
);
 
define('STRING_MAX_SIZE', 6);
 
array_walk($strings, function (&$item, $key, $max_size) {
  if (strlen($item) >= $max_size) {
        $item = substr($item, 0, $max_size);
  }
}, STRING_MAX_SIZE);
 
var_dump($strings);
On itère sur le tableau de chaines avec un array_walk auquel on passe une closure qui vérifie si la chaine est trop longue et si oui, la tronque.

Affiche:
Code :
1
2
3
4
5
 
array
  0 => string 'foobar' (length=6)
  1 => string 'lorem ' (length=6)
  2 => string 'hey du' (length=6)
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom
Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même).

Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...".
Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug.

Les boutons et existent, servez-vous en
Benjamin Delespierre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 17h18   #3
Membre du Club
 
Homme
Développeur Web
Inscription : juillet 2009
Messages : 54
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : juillet 2009
Messages : 54
Points : 27
Points : 27
Merci Benjamin, mais je souhaiterais réaliser cela sans devoir tronquer des noms de produits.

Il me faudrait une fonction qui permette de mettre dans chaque ligne un nombre de lettres équivalent (à 2 ou 3 près) en jouant sur le nombre de mots par ligne.

Par exemple :
- raisin fraise coing kaki poire (30 lettres)
- choux de Bruxelles pamplemousse (31 lettres)

Une idée?
gambic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 17h27   #4
Modérateur
 
Inscription : septembre 2010
Messages : 7 101
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 101
Points : 8 465
Points : 8 465
pourquoi tu fais pas un text-align en CSS ?
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 17h46   #5
Membre Expert
 
Inscription : septembre 2010
Messages : 1 239
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 239
Points : 1 561
Points : 1 561
Si tu veux couper ta chaine sur un espace (pour garder des mots entiers si la longueur du premier mot est inférieur à la longueur maximale désirée) tu peux faire :

Code :
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
$mon_array = array('prune', 'pissenlit', 'cresson', 'framboise', 'chataigne', 'choux de Bruxelles', 'celeri rave', 'poire', 'noix', 'kiwi', 'navet', 'carotte', 'nectarine', 'groseille', 'fruit de la passion', 'tomate', 'betteraves', 'raisin', 'papaye', 'abricot', 'orange', 'grenade', 'ciboulette', 'oignon', 'pêche', 'cerise', 'choux-fleurs', 'banane', 'amande', 'haricots secs', 'melon', 'pistache', 'citron', 'figue', 'myrtille', 'champignon', 'endive', 'rutabaga', 'pomme', 'mangue', 'courge', 'fraise', 'datte', 'échalottes', 'cardon', 'pastèque', 'litchi', 'ananas', 'brocoli', 'coing', 'asperge', 'lentilles sêches', 'mandarine', 'pamplemousse', 'noisette', 'pois cassés', 'petits pois frais', 'kaki', 'olives', 'courgette', 'salsifis', 'artichaut', 'aubergine');
 
function truncate(&$string, $key, $size ) {
 
	$encodage = 'utf-8';
 
        $chaine = mb_substr($string, 0, $size, $encodage); // coupe la chaine à la taille max désirée
 
        if ($chaine == mb_substr($string, 0, $size + 1, $encodage)) // pas de modif    
          {
             $string = $chaine;
          }
         else 
          {    
            // recherche le dernier espace (s'il y en a un)
            if ($lastSpace = strrpos($chaine, ' '))
            $string = substr($chaine, 0, $lastSpace); 
            else
            $string = $chaine;
          }
}
 
array_walk($mon_array, 'truncate' , 12);
 
echo '<pre>';
print_r($mon_array);
echo '</pre>';
Le troisième paramètre de array_walk indique la longueur maximale.

Dans la fonction truncate, définir la variable $encodage selon ton encodage.
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 25/02/2011, 18h05   #6
Membre Expert
 
Inscription : septembre 2010
Messages : 1 239
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 239
Points : 1 561
Points : 1 561
... en option dans la deuxième partie de la fonction truncate tu peux mettre des points de suspension s'il reste des lettres ou des mots à afficher :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function truncate(&$string, $key, $size ) {
 
		$encodage = 'utf-8';
 
        $chaine = mb_substr($string, 0, $size, $encodage); // coupe la chaine à la taille max désirée
 
        if ($chaine == mb_substr($string, 0, $size + 1, $encodage))
			{ // pas de modif    
				$string = $chaine;
			}
			else
			{  
				// recherche le dernier espace (s'il y en a un)
				if ($lastSpace = strrpos($chaine, ' '))
				$string = substr($chaine, 0, $lastSpace).'...'; 
				else
				$string = $chaine.'...';
			}
}
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 18h29   #7
Membre chevronné
 
Inscription : mars 2005
Messages : 583
Détails du profil
Informations forums :
Inscription : mars 2005
Messages : 583
Points : 651
Points : 651
Hello,

Je crois pas qu'il existe une fonction de coupure de lignes qui respecte les règles de césure en PHP

Du coup, vu ce que je comprends de la problématique, j'irais dans le sens de stealth35 et je laisserais HTML faire son travail.

Un truc du genre :

Code :
1
2
3
4
 
<p style="width: 40ex; text-align: justify;">
poire, banane, clémentine, topinambour, patate, poireau, carotte, chou, cerise, fraise, navet
</p>
__________________
Pourfendeur de singletons en croisade
Petibidon est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 18h40   #8
Modérateur
 
Avatar de Benjamin Delespierre
 
Benjamin Delespierre
Développeur Web
Inscription : février 2010
Messages : 2 984
Détails du profil
Informations personnelles :
Nom : Benjamin Delespierre
Âge : 24
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : février 2010
Messages : 2 984
Points : 5 014
Points : 5 014
Tiens avec ça on garde les mots entiers:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
$strings = array(
'foobar',
'lorem ipsum sit amet',
'hey dude, PHP rocks!'
);
 
define('STRING_MAX_SIZE', 6);
 
array_walk($strings, function (&$item, $key, $max_size) {
  $item = trim($item);
  if (strlen($item) >= $max_size) {
     if (strpos($item, ' ') === false) {
        $item = substr($item, 0, $max_size);
     }
     else {
        $chunks = explode(' ', $item); $str = "";
        while (($chunk = current($chunks)) && strlen($str." $chunk") <= $max_size) { $str .= " $chunk"; next($chunks); } 
        $item = trim($str);
     }
  }
}, STRING_MAX_SIZE);
 
var_dump($strings);
Et on respecte le MAX_SIZE
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom
Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même).

Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...".
Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug.

Les boutons et existent, servez-vous en
Benjamin Delespierre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 19h15   #9
Membre Expert
 
Inscription : septembre 2010
Messages : 1 239
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 239
Points : 1 561
Points : 1 561
@Benjamin Delespierre

Je parierais bien 100 contre 1 que ma fonction, tout en étant plus simple, est plus performante que la tienne et le sera d'autant plus que les chaines à tronquer seront longues
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 19h35   #10
Modérateur
 
Avatar de Benjamin Delespierre
 
Benjamin Delespierre
Développeur Web
Inscription : février 2010
Messages : 2 984
Détails du profil
Informations personnelles :
Nom : Benjamin Delespierre
Âge : 24
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : février 2010
Messages : 2 984
Points : 5 014
Points : 5 014
C'est juste: 0.24 sur 1000 entrées avec la tienne contre 0.45 sur 1000 entrées avec la mienne.

Ton algo est mieux pensé que le mien
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom
Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même).

Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...".
Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug.

Les boutons et existent, servez-vous en
Benjamin Delespierre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 19h46   #11
Modérateur
 
Inscription : septembre 2010
Messages : 7 101
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 101
Points : 8 465
Points : 8 465
et moi ma fonction elle est 15 000x plus optimisé que la votre :
Code :
echo wordwrap(implode(' ', $mon_array), 50, '<br />');
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 25/02/2011, 19h55   #12
Modérateur
 
Avatar de Benjamin Delespierre
 
Benjamin Delespierre
Développeur Web
Inscription : février 2010
Messages : 2 984
Détails du profil
Informations personnelles :
Nom : Benjamin Delespierre
Âge : 24
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : février 2010
Messages : 2 984
Points : 5 014
Points : 5 014
C'est pas tout à fait l'usage qu'on voulait au départ mais c'est vrai que ça marche comme ça.

J'ai fait ça pour clore le débat:
Code :
1
2
3
4
 
$str = "lorem ispum sit amet bla bla bla";
$size = 10;
echo substr($str, 0, ($offset = strpos(substr($str, 0, $size), ' ')) !== false ? $offset : $size);
Ce qui n'est rien d'autre qu'un condensat de la fonction cité plus haut.
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom
Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même).

Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...".
Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug.

Les boutons et existent, servez-vous en
Benjamin Delespierre est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 20h19   #13
Modérateur
 
Inscription : septembre 2010
Messages : 7 101
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 101
Points : 8 465
Points : 8 465
mais ca pas du-tout ca qu'il veut...
il faire du justifier pas tronquer un texte...
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 21h26   #14
Membre Expert
 
Inscription : septembre 2010
Messages : 1 239
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 239
Points : 1 561
Points : 1 561
Citation:
Envoyé par Benjamin Delespierre Voir le message
Ton algo est mieux pensé que le mien
Faut dire qu'on avait déjà étudié la question

Utiliser "strlen" est plus gourmand que "substr" sur des chaînes assez longues, et comme de plus ensuite tu explosais la chaîne pour faire des concaténations, mon pari n'était pas trop risqué
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 22h10   #15
Membre Expert
 
Inscription : septembre 2010
Messages : 1 239
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 239
Points : 1 561
Points : 1 561
Citation:
Envoyé par stealth35 Voir le message
mais ca pas du-tout ca qu'il veut...
il faire du justifier pas tronquer un texte...
Oui mais le "justifier" peux élargir les espacements entre les mots sans limite mais ne peux pas les rétrécir sans limite. Il y aura donc fatalement des pb.

Avec le tronquage de certains titres, suivis de points de suspension pour ceux qui ont été tronqués, on peut imaginer un "title" dans la balise html qui contiendrait le texte entier. En travaillant un peu les infobulles, ça pourrait être sympas.

Bah sinon, on peut le faire à l'affichage en javascript : en mesurant la largeur effective du titre et puis en jouant sur le letter-spacing, dans une certaine mesure, pour réduire le texte à la valeur maximale autorisée, et si letter-spacing trop petit on tronque comme avec la fonction php.
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/02/2011, 22h24   #16
Modérateur
 
Inscription : septembre 2010
Messages : 7 101
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 7 101
Points : 8 465
Points : 8 465
Citation:
Envoyé par ABCIWEB Voir le message
Oui mais le "justifier" peux élargir les espacements entre les mots sans limite mais ne peux pas les rétrécir sans limite. Il y aura donc fatalement des pb.

Avec le tronquage de certains titres, suivis de points de suspension pour ceux qui ont été tronqués, on peut imaginer un "title" dans la balise html qui contiendrait le texte entier. En travaillant un peu les infobulles, ça pourrait être sympas.

Bah sinon, on peut le faire à l'affichage en javascript : en mesurant la largeur effective du titre et puis en jouant sur le letter-spacing, dans une certaine mesure, pour réduire le texte à la valeur maximale autorisée, et si letter-spacing trop petit on tronque comme avec la fonction php.
je le redis y'a rien a tronquer la dedans lui il veut juste une fonction pour que au final ca donne :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
prune pissenlit cresson framboise chataigne choux
de  Bruxelles  celeri rave  poire noix kiwi navet
carotte  nectarine  groseille fruit de la passion
tomate  betteraves  raisin  papaye abricot orange
grenade    ciboulette    oignon    pêche   cerise
choux-fleurs  banane  amande  haricots secs melon
pistache citron figue  myrtille champignon endive
rutabaga   pomme   mangue   courge   fraise datte
échalottes  cardon pastèque litchi ananas brocoli
coing    asperge   lentilles   sêches   mandarine
pamplemousse  noisette  pois  cassés  petits pois
frais kaki  olives  courgette  salsifis artichaut
aubergine
__________________
http://blog.stealth35.com/
stealth35 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/02/2011, 04h01   #17
Membre Expert
 
Inscription : septembre 2010
Messages : 1 239
Détails du profil
Informations forums :
Inscription : septembre 2010
Messages : 1 239
Points : 1 561
Points : 1 561
Citation:
Envoyé par stealth35 Voir le message
je le redis y'a rien a tronquer la dedans lui il veut juste une fonction pour que au final...
Ha oui effectivement si c'est ça, la question n'a rien à faire dans le forum php

Donc du CSS, et s'il ne veut pas que des expressions (mots composés) soient coupées par un retour ligne ça peut se faire en javascript (si on veut bien faire les choses).

Sinon au passage, pas bon ton exemple avec wordwrap : on ne peut quand même plus conseiller des fonctions incompatibles utf-8 de nos jours
__________________
- Réalisations
- Interface graphique : génération en javascript d'objets défilants, texte et/ou images, mode horizontal ou vertical.
ABCIWEB est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2011, 13h01   #18
Membre du Club
 
Homme
Développeur Web
Inscription : juillet 2009
Messages : 54
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Multimédia et Internet

Informations forums :
Inscription : juillet 2009
Messages : 54
Points : 27
Points : 27
Merci pour ces solutions intéressantes. Toutefois, il semble qu'aucune ne soit exactement ce que je veux, car je me suis mal exprimé (ou ce que je demande est impossible?)

En fait, j'ai un array avec une longue liste de mots et courtes expressions (issus d'une base de données) et je voudrais faire des lignes "justifiées" sans tronquer les mots ni me baser sur les espaces (car il y a des espaces dans les expressions).
Je dois donc uniquement me baser sur le nombre de caractères par ligne, en jouant sur le nombre de mots/expressions par ligne ET sur l'ordre d'apparition des mots/expressions.

En d'autres termes, il faudrait que la fonction décide "intelligemment" du placement des mots. Par exemple : s'il manque 15 caractères pour finir une ligne, elle prend un mot de 15 lettres, ou 2 mots de 7 lettres (+1 espace), ou 3 mots de 4 lettres (+2 espaces), etc.

Si quelqu'un avait une solution miracle... Merci d'avance!
gambic est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/02/2011, 13h05   #19
Modérateur
 
Avatar de Benjamin Delespierre
 
Benjamin Delespierre
Développeur Web
Inscription : février 2010
Messages : 2 984
Détails du profil
Informations personnelles :
Nom : Benjamin Delespierre
Âge : 24
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : février 2010
Messages : 2 984
Points : 5 014
Points : 5 014
En effet c'est assez différent de ta demande de départ.

Ce que tu cherches à faire s'apparente plus à un tag cloud dans ce cas, il faudrait que tu cherches dans cette voie.
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom
Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même).

Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...".
Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug.

Les boutons et existent, servez-vous en
Benjamin Delespierre est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h59.


 
 
 
 
Partenaires

Hébergement Web