Précédent   Forum des professionnels en informatique > PHP > Langage
Langage Forum sur le langage PHP, la POO, les conventions, la sécurité, etc. Avant de poster : FAQ Langage, toutes les FAQ PHP, cours langage et sources PHP
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 28/01/2012, 20h21   #1
Membre à l'essai
 
Inscription : novembre 2007
Messages : 88
Détails du profil
Informations personnelles :
Localisation : Belgique

Informations forums :
Inscription : novembre 2007
Messages : 88
Points : 23
Points : 23
Par défaut PHP et imap problème utf7

Bonjour à tous, je sais pas si je suis dans le bon forum, si jamais n'hésitez pas à me le faire savoir.

Je viens vers vous car je suis occupés de créer une classe imap afin de me construire mon webmail de gmail, en passant par de l'ajax

Ma méthode :
j'appel une page PHP en ajax, qui est parfaitement affiché dont voici la source de cette page :
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
28
29
30
 
// Inclusion de la classe
include("RnImapGeneric.class.php");
$f = (isset($_POST['f'])) ? utf8_decode($_POST['f']) : 'INBOX';
$box = new RnImapGeneric('imap.gmail.com:993/imap/ssl','monMail@gmail.com','********');
$box->connect($f);
$nbTotal = $box->getCountMessages();
$msgs = $box->listMessages();
$box->disconnect();
$h = '<table border="0" cellpadding="0" cellspacing="0" style="line-height:25px;">'
   . '  <tr>'
   . '    <th style="width:20px;border-left: 1px solid #999;padding: 2px;background: #ccc;border-top: 1px solid #eee;border-bottom: 1px solid #999;text-decoration:none;color:#000;"><input type="checkbox" name="selectAll" id="selectAll" value="0" /></th>'
   . '    <th style="text-align:left;width:200px;padding: 2px;background: #ccc;border-top: 1px solid #eee;border-bottom: 1px solid #999;text-decoration:none;color:#000;">Expéditeur</th>'
   . '    <th style="text-align:left;padding: 2px;background: #ccc;border-top: 1px solid #eee;border-bottom: 1px solid #999;text-decoration:none;color:#000;">Sujet</th>'
   . '    <th style="border-right: 1px solid #999;width:115px;padding: 2px;background: #ccc;border-top: 1px solid #eee;border-bottom: 1px solid #999;text-decoration:none;color:#000;">Date</th>'
   . '  </tr>';
 
foreach($msgs as $k => $tab){
    $from = (strlen($tab['from']) > 25) ? substr($tab['from'],0,25)."..." : $tab['from'];
    $sujet = (strlen($tab['subject']) > 120) ? substr($tab['subject'],0,120)."..." : $tab['subject'];
    $bold = ($tab['etat'] == 0) ? "bold" : "normal";
    $h .= '  <tr style="font-weight:'.$bold.';">'
       . '    <td style="text-align:center;border-left: 1px solid #999;"><input type="checkbox" name="select_'.$k.'" id="select_'.$k.'" value="0" /></td>'
       . '    <td style="padding-left:2px;">'.$from.'</td>'
       . '    <td style="padding-right:25px;padding-left:2px;">'.$sujet.'</td>'
       . '    <td style="text-align:center;border-right: 1px solid #999;">'.$tab['date'].'</td>'
       . '  </tr>';
}   
$h .= '</table>';
echo utf8_encode($h);
avec ça j’obtiens bien les la liste des message (par défaut de la boîte de réception), j'encode le retour en utf8 puisque je passe par ajax pour l'affiché sinon mes caractère sépciaux se transforme en caractère bizar, et je décode le paramètre post pour récupérer le nom du dossier ciblé.

Mon problème est le suivant :
Voici l'exemple de lien posant problème
Code :
1
2
 
<a class="getBox" title="[Gmail]/Messages envoyés" href="#">Messages envoyés</a>
Dans mon fichier appelé je decode bien le paramètre post et c'est la que ca pose souci

voici ma fonction ajax (avec jQuery)
Code :
1
2
3
4
5
6
7
8
9
10
11
 
$(".getBox").click(function(){
    var divLoad = $('<div class="loader" id="loader"><img src="images/loading.gif" alt="Chargement" /><span>Chargement...</span></div>');
    $(document.body).append(divLoad);
    $.ajax({ type    : 'POST', 
                  url     : 'msgBoxList.ajx.php',
                data    : 'f='+$(this).attr('title'),
                success : function(h){ 
                    $("#msgBox").html(h); $("#loader").remove(); }
    });
});
le paramètre f contient : [Gmail]/Messages envoyés
d'ou le décode de l'utf8 afin d'obtenir [Gmail]/Messages envoyés

Voici ma classe en développement (biensûr y'a de l'optimisation à faire des chose peut-être inutile etc...), c'est la première fois que je traite le sujet imap
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
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
 
<?php
class RnImapGeneric{
 
    private $box = false;
    private $prm = array('HOST' => false, 'USER' => false, 'PWD' => false);
 
    public $dir = array('Boîte de réception' => false, 
                        'Messages envoyés' => false, 
                        'Corbeille' => false, 
                        'Brouillons' => false, 
                        'Spam' => false, 
                        'Important' => false, 
                        'Suivis' => false, 
                        'Tous les messages' => false);
 
    private $notFolder = array('INBOX','[Gmail]','Trash');     
 
    public function __construct($h=false,$u=false,$p=false){
        if($h != false){ $this->prm['HOST'] = $h; }
        if($u != false){ $this->prm['USER'] = $u; }
        if($p != false){ $this->prm['PWD'] = $p; }
    }
 
    public function connect($f=false){
        $fold = ($f != false) ? $f : '';
		$this->box = imap_open("{".$this->prm['HOST']."}".$fold, $this->prm['USER'], $this->prm['PWD']);
	}
 
    public function disconnect(){ 
        imap_close($this->box); 
    }
 
    public function getCountMessages(){
		return intval(imap_num_msg($this->box));
	}
 
    public function getBoxDirectory(){
		return imap_list($this->box, "{imap.gmail.com:993/imap/ssl}", "*");
	}
 
    public function directoryToArr(){
        $d = $this->getBoxDirectory();
        foreach($d as $k => $nm){
            $nm = str_replace('{imap.gmail.com:993/imap/ssl}','',imap_utf7_decode($nm));
            if(preg_match('#/#',$nm)){
                $dir = explode('/',$nm);
                if(!in_array($dir[0],$this->notFolder)) $this->dir[$dir[0]][$dir[1]] = false;
            }
            else{
                if(!in_array($nm,$this->notFolder)) $this->dir[$nm] = false;
            }
        }
        return $this->dir;
    }
 
    public function replaceRealName($name){
        $gmail = array('Messages envoyés', 'Corbeille', 'Brouillons', 'Spam', 'Important', 'Suivis', 'Tous les messages');
        if($name == "Boîte de réception"){ return 'INBOX'; }
        if(in_array($name,$gmail)){ return ('[Gmail]/'.$name); }
        else{ return $name; }
    }
 
    public function directoryToUl(){
        $arr = $this->directoryToArr();
        $h = '<ul id="imap_directory">';
        foreach($arr as $k => $v){
            $msg = $this->countFolderMsg('INBOX');
            if(is_array($msg)){ $txt = $msg[0]."/".$msg[1]; }
            else{ $txr = $msg; }
            $rName = $this->replaceRealName($k);
            //$rName = str_replace("&","comercialparse",$rName);
            $nb = ($k == "Boîte de réception") ? ' <b>('.$msg[1].')</b>' : '';
            $t = (!is_array($v)) ? ' title="'.$rName.'"' : '';
            $c = (!is_array($v)) ? ' class="getBox"' : '';
            $h .= '<li><a href="#"'.$t.$c.'>'.$k.$nb.'</a>';
            if(is_array($v)){
                $h .= '<ul>';
                foreach($v as $k2 => $v2){
                    $rName2 = $this->replaceRealName($k2);
                    $h .= '<li><a href="#" title="'.$rName2.'" class="getBox">'.$k2.'</a></li>';
                }
                $h .= '</ul>';
            }
            $h .= '</li>';
        }
        $h .= '</ul>';
        return $h;
    }
 
    public function countFolderMsg($f){
      $status = imap_status($this->box, '{'.$this->prm['HOST'].'}'.$f, SA_ALL);
      if($status){
         return array($status->messages,$status->unseen);
      }
      else{
        return "imap_status failed: " . imap_last_error() . "\n";
      }
    } 
 
    public function parseSubject($str){
        if(preg_match("#=\?.{0,}\?Q\?#",$str)){
            $str=quoted_printable_decode($str);
            $str=preg_replace("#=\?.{0,}\?[Qq]\?#","",$str);
            $str=preg_replace("#\?=#","",$str);
        } 
        if(preg_match("#=\?.{0,}\?[Bb]\?#",$str)){
            $arrHead=split("#=\?.{0,}\?[Bb]\?#",$str);
            while(list($key,$value)=each($arrHead)){
                if(preg_match("#\?=#",$value)){
                    $arrTemp=split("\?=",$value);
                    $arrTemp[0]=base64_decode($arrTemp[0]);
                    $arrHead[$key]=join("",$arrTemp);
                }
            }
            $str=join("",$arrHead);
        }
        // Supprime les underscore qui apparaise pour une raison que j'ignore sur certain message
        $str = str_replace("_"," ",$str); 
        // Supprime les point d'interogation qui apparaisse aussi pour une raison que j'ignoe sur certain message
        $str = str_replace("?","",$str); 
        return $str;  
    }
 
    public function listMessages() {
        $tb_messages = array();
        for($i=1; $i<=imap_num_msg($this->box); $i++) {
            $msg = array();
            $header = imap_headerinfo($this->box, $i);
            $msg['subject'] = (isset($header->subject)) ? $this->parseSubject($header->subject) : 'Pas de sujet';
            $msg['id'] = (isset($header->message_id)) ? $header->message_id : false;
            if (isset($header->from[0]->personal)) { $personal = $this->parseSubject($header->from[0]->personal); } 
            else { $personal = $this->parseSubject($header->from[0]->mailbox); }
            $msg['fromMail'] = $header->from[0]->mailbox.'@'.$header->from[0]->host;
            $msg['from'] = $personal;
            $msg['etat'] = ($header->Unseen == 'U') ? 0 : 1;
            $msg['date'] = strftime("%d/%m/%Y %H:%M",$header->udate);
            $tb_messages[] = $msg;
        }
        return(array_reverse($tb_messages,true));
    } 
 
    public function ListMsgBox(){
        return imap_headers($this->box);
    }
 
    private function _getMessages($mailsId){
		$i = 0;
		foreach($mailsId as $mailId){
			$results[$i] = imap_header($this->box, $mailId);
			$i++;
		}
		return $results;
	}
 
    public function getAllMessages()
	{
		$mailsId = imap_search($this->box, 'ALL');
		return $this->_getMessages($mailsId);
	}
 
 
}
?>
On peut constater que le seul moment ou j'utilise le décodage utf7 dans la classe c'est sur le nom des dossiers afin de récupérer mes accents (é au lieu de &AQ-s)

Donc je clic sur mon lien (Meassages envoyés) et là BAM erreur

Code :
Notice: Unknown: IMAP protocol error: Invalid Arguments: Failed to parse UTF7 string (errflg=2) in Unknown on line 0
et
Code :
Notice: Unknown: Invalid Arguments: Failed to parse UTF7 string (errflg=2) in Unknown on line 0
Au vue de la précision de l'erreur difficile de trouver d'ou viens l'erreur, si ce n'est que ca à un rapport avec l'utf7 que je n'utilise qu'une seul et unique fois pour le décodage

Donc voilà vous avez toute ma source posant le problème, et j'ai beau tourné le problème dans tous les sens je n'arrive à rien

Si quelqu'un à une idée d'ou pourrait venir le problème et m'aider à le résoudre je l'en remercie d'avance.

PS : Sur les dossiers ne comportant pas d'accent ou autre ca fonctionne parfaitement.

Bien à vous
Splifferwolf
splifferwolf est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2012, 14h55   #2
Membre à l'essai
 
Inscription : novembre 2007
Messages : 88
Détails du profil
Informations personnelles :
Localisation : Belgique

Informations forums :
Inscription : novembre 2007
Messages : 88
Points : 23
Points : 23
Problème résolut

en réalité y'a un souci avec le imap_utf7_decode et encode
les caractère décodé ne sont plus les même une fois encodé j'ai donc (après quelques heures de recherches trouver une fonction qui parse manuellement utf7 vers utf8 et inversement

J'ai définit l'encode de fichier en utf8 (ca evite de devoir faire des utf8_decode et encode)

Pour ceux que cela intéresse voici les fonctions en question
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
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
 
function utf7_to_utf8($str){
  $Index_64 = array(
      -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
      -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
      -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, 63,-1,-1,-1,
      52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
      -1, 0, 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,-1, -1,-1,-1,-1,
      -1,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,-1, -1,-1,-1,-1
  );
 
  $u7len = strlen($str);
  $str = strval($str);
  $p = $err = '';
 
  for ($i=0; $u7len > 0; $i++, $u7len--){
    $u7 = $str[$i];
    if ($u7 == '&'){
      $i++;
      $u7len--;
      $u7 = $str[$i];
      if ($u7len && $u7 == '-'){ $p .= '&'; continue; }
 
      $ch = 0;
      $k = 10;
      for (; $u7len > 0; $i++, $u7len--){
        $u7 = $str[$i];
        if ((ord($u7) & 0x80) || ($b = $Index_64[ord($u7)]) == -1) break;
        if ($k > 0){ $ch |= $b << $k; $k -= 6; }
        else{
          $ch |= $b >> (-$k);
          if ($ch < 0x80){
            /* Printable US-ASCII */
            if (0x20 <= $ch && $ch < 0x7f) return $err;
            $p .= chr($ch);
          }
          else if ($ch < 0x800){
            $p .= chr(0xc0 | ($ch >> 6));
            $p .= chr(0x80 | ($ch & 0x3f));
          }
          else{
            $p .= chr(0xe0 | ($ch >> 12));
            $p .= chr(0x80 | (($ch >> 6) & 0x3f));
            $p .= chr(0x80 | ($ch & 0x3f));
          }
 
          $ch = ($b << (16 + $k)) & 0xffff;
          $k += 10;
        }
      }
 
      /* Non-zero or too many extra bits */
      if ($ch || $k < 6) return $err;
 
      /* BASE64 not properly terminated */
      if (!$u7len || $u7 != '-') return $err;
 
      /* Adjacent BASE64 sections */
      if ($u7len > 2 && $str[$i+1] == '&' && $str[$i+2] != '-') return $err;
    }
    /* Not printable US-ASCII */
    else if (ord($u7) < 0x20 || ord($u7) >= 0x7f) return $err;
    else $p .= $u7;
  }
  return $p;
}
 
function utf8_to_utf7($str)
{
  $B64Chars = array(
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
    'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
    't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
    '8', '9', '+', ','
  );
 
  $u8len = strlen($str);
  $base64 = $i = 0;
  $p = $err = '';
 
  while ($u8len){
    $u8 = $str[$i];
    $c = ord($u8);
    if ($c < 0x80){ $ch = $c; $n = 0; }
    else if ($c < 0xc2) return $err;
    else if ($c < 0xe0){ $ch = $c & 0x1f; $n = 1; }
    else if ($c < 0xf0){ $ch = $c & 0x0f; $n = 2; }
    else if ($c < 0xf8){ $ch = $c & 0x07; $n = 3; }
    else if ($c < 0xfc){ $ch = $c & 0x03; $n = 4; }
    else if ($c < 0xfe){ $ch = $c & 0x01; $n = 5; }
    else return $err;
    $i++;
    $u8len--;
 
    if ($n > $u8len) return $err;
 
    for ($j=0; $j < $n; $j++){
      $o = ord($str[$i+$j]);
      if (($o & 0xc0) != 0x80) return $err;
      $ch = ($ch << 6) | ($o & 0x3f);
    }
 
    if ($n > 1 && !($ch >> ($n * 5 + 1))) return $err;
 
    $i += $n;
    $u8len -= $n;
 
    if ($ch < 0x20 || $ch >= 0x7f){
      if (!$base64){
        $p .= '&';
        $base64 = 1;
        $b = 0;
        $k = 10;
      }
      if ($ch & ~0xffff)
        $ch = 0xfffe;
 
      $p .= $B64Chars[($b | $ch >> $k)];
      $k -= 6;
      for (; $k >= 0; $k -= 6) $p .= $B64Chars[(($ch >> $k) & 0x3f)];
 
      $b = ($ch << (-$k)) & 0x3f;
      $k += 16;
    }
    else{
      if ($base64){
        if ($k > 10) $p .= $B64Chars[$b];
        $p .= '-';
        $base64 = 0;
      }
 
      $p .= chr($ch);
      if (chr($ch) == '&') $p .= '-';
    }
  }
 
  if ($base64){
    if ($k > 10) $p .= $B64Chars[$b];
    $p .= '-';
  }
 
  return $p;
}
Voili voilou

Merci à... ben moi pour m'être auto-solutionner xD
Bien à vous
Splifferwolf
splifferwolf est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 17h17.


 
 
 
 
Partenaires

Hébergement Web