Equivalent de innerhtml javascript, mais global

Soyez le premier à donner votre avis sur cette source.

Snippet vu 8 198 fois - Téléchargée 17 fois

Contenu du snippet

Cette fonction renvoie un tableau du contenu de toutes les occurrences d'une balise, HTML ou non, de la chaîne de caractères passée en paramètre.
Ce tableau de contenu possède deux indices $Result[Ligne][Colonne].
Le nombre de colonnes par ligne peut soit être fixé par un nombre, soit être déterminé par une valeur, prise en compte ou non dans $Result, marquant le début de chaque ligne.

J'ai écrit cette fonction car j'en ai une autre qui, après requêtage SQL, me renvoie le code HTML du résultat en <TABLE>. Mais, pour des raisons de formatage de certaines valeurs, il me fallait récupérer le contenu des <TD>.

Source / Exemple :


<?php
function InnerHTML($HTML,$Balise,$Prem_val='',$Affiche_prems=true,$Nbre_bal=0)
{
  /*
  $HTML contient le code html contenant la table dont on veut extraire la valeur des cellules

  $Balise correspond à la balise dont on veut extraire le contenu.
  Ne pas mettre les "<" et ">".
  CONTRAINTE : dans le code HTML, la balise doit être collée à "<"
  <td... est correct et <          td... ne l'est pas.

  $Prem_val correspond à la valeur qui est prise pour déterminer une nouvelle ligne.
  InnerHTML est INSENSIBLE à la casse concernant $Prem_val. Pour changer cela remplacer les stripos par strpos.

  $Affiche_prems permet d'inclure (true) ou non (false) dans le tableau d'extraction $Prem_val si cette option est prise.

  $Nbre_bal détermine le nombre de contenus de balise composant une ligne.
  Si $Prem_val et $Nbre_bal sont renseignés, c'est $Prem_val qui prime.

  Si $Nbre_bal est supérieur à 0, $Affiche_prems est toujours true

  Sachant qu'entre <td> et </td> il peut y avoir en théorie n'importe quoi (autres balises, saut de ligne...), on ne peut pas utiliser <td>(:alnum:+)</td> pour le masque

  Si on utilise <td>(.+)</td> ça ne marche pas non plus car la partie extraite dans un preg_match_all sera celle comprise entre le premier <td> et le dernier </td>.
  Tous les autres couples <td>...</td> ne seront pas pris en compte.

  On décompose donc l'extraction.*/

  if(strlen($Prem_val)===0)//On va extraire les valeurs par nombre de ligne
  {                        //==>Si $Nbre_bal n'est pas renseigné il faut qu'il soit supérieur à 0
    $Affiche_prems=true;   //par contre, s'il est renseigné on garde la valeur passée en paramètre.
    if($Nbre_bal===0) $Nbre_bal=1;
  }
  else//Cela signifie que on va extraire les ligne par une valeur
  {
    $Nbre_bal=0;//Si $Nbre_bal a malencontreusement été renseigné en même temps que $Prem_val,
  }//On remet cette variable à 0 pour que l'extraction par valeur soit détectée (confère **)

  $Compteur=$Nbre_bal+1;
  preg_match_all('~<'.$Balise.'[^>]*>~is',$HTML,$Deb_balise);

  foreach($Deb_balise[0] as $Val)
  {
    $Val=substr($HTML,strpos($HTML,$Val)+strlen($Val));//On enlève tout ce qu'il y a avant le <td> y compris ce dernier
    $Temp=substr($Val,0,stripos($Val,'</'.$Balise.'>'));
    $HTML=substr($HTML,stripos($HTML,'</'.$Balise.'>')+strlen($Balise));//On supprime le code <td>...</td> que l'on vient d'extraire
    $Taille=count($Recup)-1;

    if($Nbre_bal>0)//**On traite une ligne par nombre de balise)
    {
      if($Compteur<$Nbre_bal)
      {
        $Recup[$Taille][]=$Temp;
        ++$Compteur;
      }
      else
      {
        $Recup[$Taille+1][]=$Temp;
        $Compteur=1;
      }
    }
    else//Par valeur de balise commune
    {
      if($Taille===-1)$Taille=0;//C'est que $Prem_val n'est pas en première position

      if(stripos($Temp,$Prem_val)===false)
      {
        if(count($Recup[$Taille])===0)
        {
          $Taille2=0;
        }
        else
        {
          $Taille2=count($Recup[$Taille])-1;
        }

        if($Recup[$Taille][$Taille2]===NULL)
        {
          $Recup[$Taille][$Taille2]=$Temp;
        }
        else
        {
          $Recup[$Taille][]=$Temp;
        }
      }
      else
      {
        if($Compteur==1)
        {
          $Compteur=0;
        }
        else
        {
          $Compteur=$Taille+1;
        }

        if($Affiche_prems===true)
        {
          $Recup[$Compteur][]=$Temp;
        }
        else
        {
          $Recup[$Compteur][]=NULL;
        }
        /*
        if($Compteur==1)
        {
          $Compteur=0;
        }
        else
        {
          $Compteur=$Taille+1;
        }

        Pour pouvoir insérer des contenus de balise se trouvant avant $Prem_val si cette valeur n'est pas en première position,
        on a forcé la taille à 0.
        Si $Prem_val est en première position dans le tableau renvoyé dans $Deb_balise[0] alors $Taille, au lieu d'être à 0 sera à 1
        Pour corriger cela on fait tourner le $Compteur.
        Ainsi, si la première valeur de $Deb_balise[0] est égale à $Prem_val, le premier indice du tableau de résultat sera 0.

  • /
} ++$Compteur; } } return $Recup; } ?>

Conclusion :


Un petit exemple:
$HTML='<table border="1">
<tr>
<td width="463"> <p>ID</p><dd> fgfg</dd>
</td>
<td width="463">
<p>a</p>
</td>
<td width="463"> <p>1</p>
</td>
<td width="463">
<p>Lu ndi</p>
</td>
</tr>
<tr>
<td width="463">
<p>ID</p>
</td>
<td width="463">
<p>b</p>
</td>
<td width="463">
<p>2</p>
</td>
<td width="463">
<p>Mardi</p>
</td>
</tr>
<tr>
<td width="463">
<p>ID</p>
</td>
<td width="463">
<p>c</p>
</td>
<td width="463">
<p>3</p>
</td>
<td width="463">
<p>Mercredi</p>
</td>
</tr>
<tr>
<td width="463">
<p>ID</p>
</td>
<td width="463">
<p>d</p>
</td>
<td width="463">
<p>4</p>
</td>
<td width="463">
<p>Jeudi</p>
</td>
</tr>
<tr>
<td width="463">
<p>ID</p>
</td>
<td width="463">
<p>e</p>
</td>
<td width="463">
<p>5</p>
</td>
<td width="463">
<p>Vendredi</p>
</td>
</tr>
<tr>
<td width="463">
<p>ID</p>
</td>
<td width="463">
<p>f</p>
</td>
<td width="463">
<p>6</p>
</td>
<td width="463">
<p>Samedi</p>
</td>
</tr>
</table>';

$Cell=InnerHTML($HTML,'td','id');
print_r($Cell) donnera

Array
(
[0] => Array
(
[0] => <p>ID</p><dd> fgfg</dd>

[1] =>
<p>a</p>

[2] => <p>1</p>


[3] =>
<p>Lu ndi</p>

)

[1] => Array
(
[0] =>
<p>ID</p>

[1] =>
<p>b</p>

[2] =>
<p>2</p>

[3] =>
<p>Mardi</p>


)

[2] => Array
(
[0] =>
<p>ID</p>

[1] =>
<p>c</p>

[2] =>
<p>3</p>

[3] =>
<p>Mercredi</p>

)

[3] => Array
(
[0] =>
<p>ID</p>


[1] =>
<p>d</p>

[2] =>
<p>4</p>

[3] =>
<p>Jeudi</p>

)

[4] => Array
(
[0] =>
<p>ID</p>

[1] =>
<p>e</p>


[2] =>
<p>5</p>

[3] =>
<p>Vendredi</p>

)

[5] => Array
(
[0] =>
<p>ID</p>

[1] =>
<p>f</p>

[2] =>
<p>6</p>


[3] =>
<p>Samedi</p>

)

)

$Cell=InnerHTML($HTML,'p','',false,10);
print_r($Cell) donnera

Array
(
[0] => Array
(
[0] => ID
[1] => a
[2] => 1
[3] => Lu ndi
[4] => ID
[5] => b
[6] => 2
[7] => Mardi
[8] => ID
[9] => c
)

[1] => Array
(
[0] => 3
[1] => Mercredi
[2] => ID
[3] => d
[4] => 4
[5] => Jeudi
[6] => ID
[7] => e
[8] => 5
[9] => Vendredi
)

[2] => Array
(
[0] => ID
[1] => f
[2] => 6
[3] => Samedi
)

)

A voir également

Ajouter un commentaire

Commentaires

kankrelune
Messages postés
1293
Date d'inscription
mardi 9 novembre 2004
Statut
Membre
Dernière intervention
21 mai 2015

Le résultat est le même mais isset() est plus rapide car ce n'est pas une fonction... .. . ;o)

@ tchaOo°
cs_8Tnerolf8
Messages postés
30
Date d'inscription
vendredi 25 novembre 2005
Statut
Membre
Dernière intervention
17 novembre 2009

Effectivement, en testant l'indice 0 d'une chaîne de caractère, on peut utiliser isset, mais je trouve que cela revient au même que de tester sur la longueur de la chaîne.

Bonne journée.

Tnérolf
kankrelune
Messages postés
1293
Date d'inscription
mardi 9 novembre 2004
Statut
Membre
Dernière intervention
21 mai 2015

Non parce que ce n'est pas la variable en elle même que tu test mais le premier offset de la chaine... lorsque que tu utilise les crochets sur une chaine (ou les accolades mais elle vont disparaitre avec php6) tu pointe sur un caractère de ta chaine en gros ta chaine se comporte comme un tableau où chaque entrée est un caractère... donc...

$str = 'test';
echo $str[0] // affichera t

Si tu regarde le code que je te donne je test la présence du premier caractère dans la chaine... s'il n'y en a pas on peut donc en déduire que la chaine est vide...

$str = 'test';
var_dump(isset($str[0])); // true
$str = '';
var_dump(isset($str[0])); // false

bien entendu si tu fais...

isset($str)

Ca te renverra toujours true vu que la variable existe... .. .

Voili voilou

@ tchaOo°
cs_8Tnerolf8
Messages postés
30
Date d'inscription
vendredi 25 novembre 2005
Statut
Membre
Dernière intervention
17 novembre 2009

Bonsoir

Merci pour tes précisions concernant la différence de temps d'exécution entre l'opérateur ternaire et le if classique.
A mon tour de m'expliquer :

function InnerHTML($HTML,$Balise,$Prem_val='',$Affiche_prems=true,$Nbre_bal=0)

Tu peux remarquer que $Prem_val est initialisée à vide si aucune valeur n'est passée en paramètre. Donc, la variable est déclarée et un isset($Prem_val) renverra true.

Bonne soirée.

Tnérolf
kankrelune
Messages postés
1293
Date d'inscription
mardi 9 novembre 2004
Statut
Membre
Dernière intervention
21 mai 2015

Salut

"Je n'ai pas utilisé if(isset($Prem_val) car cette variable est affectée par défaut à une valeur vide dans la déclaration de la fonction."

Je n'ai pas compris... .. .

"Concernant les opérateurs ternaires, préconises-tu de les remplacer par"

Oui tout à fait le bloc de condition classique est bien plus rapide d'éxécution (2 à 3 fois si je me souviens bien)

@ tchaOo°

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.