Aller au contenu

mime en PHP


ste

Sujets conseillés

Elo all...

J'étais en train de lire l'article suivant sur Cybercodeur.NET :

Développer avec les standards Web qui parle de la façon de servir le bon mime type (entre autres...) et renvoie sur cet autre article : Serving up XHTML with the correct MIME type

où la gestion du mime type est plus fine en ce sens qu'elle tient compte d'un certain "q-rating" !

Quelqu'un pourrait m'expliquer très clairement ce qu'est précisement le "q-rating", ou, plutôt, ce qu'est l'indice "q" ... car le "q-rating", j'en comprend le sens !?

En fait, pourquoi cet indice "q" s'appelle ainsi ?

-2- Plus précisement, dans l'article de Keystone, il précise cet exemple que je reproduis ici, pour plus de clareté :

$charset = "iso-8859-1";
$mime = "text/html";
function fix_code($buffer) {
return (preg_replace("!\s*/>!", ">", $buffer));
}
if(stristr($_SERVER["HTTP_ACCEPT"],"application/xhtml+xml")) {
   if(preg_match("/application\/xhtml\+xml;q=([01]|0\.\d{1,3}|1\.0)/i",$_SERVER["HTTP_ACCEPT"],$matches)) {
       $xhtml_q = $matches[1];
       
       if(preg_match("/text\/html;q=q=([01]|0\.\d{1,3}|1\.0)/i",$_SERVER["HTTP_ACCEPT"],$matches)) {
           $html_q = $matches[1];
           
           if((float)$xhtml_q >= (float)$html_q) $mime = "application/xhtml+xml";
       }
   }
   else $mime = "application/xhtml+xml";
}

if($mime == "application/xhtml+xml") {
$prolog_type = "<?xml version=\"1.0\" encoding=\"$charset\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n";
}
else {
ob_start("fix_code");
   $prolog_type = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html lang=\"en\">\n";
}

header("Content-Type: $mime;charset=$charset");
header("Vary: Accept");
print $prolog_type;

Ma question est :

il n'y aurait pas, à mon avis, par hasard, une erreur, au niveau du matching correspondant à l'entête "text/html" :

if(preg_match("/text\/html;q=q=([01]|0\.\d{1,3}|1\.0)/i",$_SERVER["HTTP_ACCEPT"],$matches)) {
          $html_q = $matches[1];
         
          if((float)$xhtml_q >= (float)$html_q) $mime = "application/xhtml+xml";
      }

et, plus précisement au niveau du match de l'indice 'q', justement !?

Car, il me semble que :

q=q=([01]|0\.\d{1,3}|1\.0)

n'est pas correct ?! Peut-on me confirmer mon analyse ?

merci d'avance.

Lien vers le commentaire
Partager sur d’autres sites

Bon, je test et mets en pratique !

Le bon mime type est bien renseigné, ainsi que le prologue adhoc ...

A la différence, que j'ai créé une class pour le gèrer !

le seul soucis dans ma class est que le tampon ob_start("fix_code") ne fonctionne pas apparament puisque les entités ne sont "corrigées"...

Voici le code de ma class

J'ai bien essayé en changeant ob_start("fix_code") par ob_start("set_agent::fix_code") ou ob_start($this->fix_code) ... mais je n'ai toujours rien en résultat !

Quelqu'un(e) aurait une idée ? une suggestion ?

Lien vers le commentaire
Partager sur d’autres sites

Un navigateur peut, ou ne peut pas traiter du XHTML en tant que XML (application/xhtml+xml). Il n'y a pas de demi-mesure...

La négociation du contenu à ce niveau, AMHA, doit rester totalement indifférente au "q-rating".

Modifié par LaurentDenis
Lien vers le commentaire
Partager sur d’autres sites

Merci de ta précision, tu confirmes ce que j'en pense, à savoir pourquoi gèrè du "q-rating" s'il le peut !

Ce qui ne régle par le comportement de la function fixe_code au sein du tampon ob_start ; personne n'a d'idée du tout !?!

Lien vers le commentaire
Partager sur d’autres sites

J'ai eu des problèmes avec cet 'ob_start'.

Il marchait en 'local', mais pas sur serveur.

Tu devrais essayer tout simplement :

        ob_start();
       ob_implicit_flush();

Anonymus.

Lien vers le commentaire
Partager sur d’autres sites

Dans la class PHP que j'ai créé, ca ne veut pas fonctionner ; même avec cet 'ob_implicit_flush' ...

Donc, test de la function en dehors de la class, comme une fonction normale, et là, ca le fait !

:wacko::unsure:<_<

Lien vers le commentaire
Partager sur d’autres sites

J'ai bien essayé en changeant ob_start("fix_code") par ob_start("set_agent::fix_code") ou ob_start($this->fix_code) ... mais je n'ai toujours rien en résultat !

Tu devrais essayer en passant par une variable. Au lieu de

ob_start("fix_code") ou ob_start($this->fix_code)

essaie :

$var = $this->fix_code();
ob_start("$var");

Tu fais deux appels à la fonction ob_start. Tu as mis ob_implicit_flush(); pour les 2 ?

Tu devrais voir s'il y a des données envoyées avant ton ob_start.

Si tu le testes tout seul et qu'il marche alors qu'il ne marche pas dans l'objet, c'est peut etre parce que ton objet envoie des données avant.

Courage, la route est longue :D

Lien vers le commentaire
Partager sur d’autres sites

$var = $this->fix_code();
ob_start("$var");

Elo, Anonymous,

cela ne fonctionne pas, PHP me disant qu'il manque les informations de la $buffer (définie dans la function ...) !


function fix_code($buffer) {

return (preg_replace("!\s*/>!", ">", $buffer));

}

[code]

...

Tu devrais voir s'il y a des données envoyées avant ton ob_start.

Si tu le testes tout seul et qu'il marche alors qu'il ne marche pas dans l'objet, c'est peut etre parce que ton objet envoie des données avant.

Quant à cela, mon fichier index appelle cette class en premier !

dont le code est toujours visible

PS: je te remercie quand même...

Modifié par ste
Lien vers le commentaire
Partager sur d’autres sites

Bon...

Tu vas envoyer 2 arguments à ob_start. Ou plutot un tableau de 2 arg.

ob_start(array("nom_de_l'objet","nom_de_la_fonction");

et ca va marcher ;)

Lien vers le commentaire
Partager sur d’autres sites

Dans le code que tu as mis en ligne, tu mets :

ob_start(array("web_agent","fix_code"));

Il aurait fallut mettre :

ob_start(array("set_agent","fix_code"));

le nom de l'objet. ;)

Ca marche ?

Lien vers le commentaire
Partager sur d’autres sites

Bonjour...

-1- Annymous, merci de ton soutien, et désolé pour hier, d'autres obligations professionnelles m'ont accaparé ...

-2- Anonymous, oui, cela fonctionne !

-3- Peux-tu prendre le temps de m'expliquer ?

Pourquoi cela fonctionne lorsque c'est retourné ainsi dans un tableau ?!

Entre temps, je vais aller faire un tour su PHP.net, histoire de voir, si je peux trouver une explication ...

-4- A ceci :

ob_start(array("web_agent","fix_code"));

Il aurait fallut mettre :

ob_start(array("set_agent","fix_code"));

Instinctivement, j'ai failli l'écrire ainsi ... mais j'avais compris que 'set_agent' était ma class, et 'web_agent' : l'objet ... va falloir que je reprenne mes leçons sur le nommage et l'usage de class en PHP ! B)

Lien vers le commentaire
Partager sur d’autres sites

Instinctivement, j'ai failli l'écrire ainsi ... mais j'avais compris que 'set_agent' était ma class, et 'web_agent' : l'objet ... va falloir que je reprenne mes leçons sur le nommage et l'usage de class en PHP !  B)

Euh... c'est toi qu'à raison .. :(:whistling:

Php.net ? => http://www.php.net/fr/ob-start

Ca commence à devenir intéressant dans les messages (en anglais) des contributions ;)

L'explication ? Je ne l'ai pas vraiment, c'est une convention de nommage. De la même facon que l'on ne peut pas avoir accès à une méthode de classe sans passer par la classe, ou par un objet, (d'où le $this-> ), il faut déclarer l'objet dans le 'ob_start' pour qu'il sache à quoi fait référence la 'fonction' (méthode) :blink:

... j'ai été clair ? :wacko:

Lien vers le commentaire
Partager sur d’autres sites

Euh... c'est toi qu'à raison .. :(  :whistling:

Php.net ? => http://www.php.net/fr/ob-start

Ca commence à devenir intéressant dans les messages (en anglais) des contributions ;)

L'explication ? Je ne l'ai pas vraiment, c'est une convention de nommage. De la même facon que l'on ne peut pas avoir accès à une méthode de classe sans passer par la classe, ou par un objet, (d'où le $this-> ), il faut déclarer l'objet dans le 'ob_start' pour qu'il sache à quoi fait référence la 'fonction' (méthode)  :blink:

... j'ai été clair ?  :wacko:

Je viens de lire la page de PHP.net

Sinon, oui, je t'ai compris, même si c'est un peu nébuleux, parce que je connais les 'expressions'...

If you're using object-orientated code in PHP you may, like me, want to use a call-back function that is inside an object (i.e. a class function). In this case you send ob_start a two-element array as its single argument. The first element is the name of the object (without the $ at the start), and the second is the function to call. So to use a function 'indent' in an object called '$template' you would use <?php ob_start(array('template', 'indent')); ?>.

Ce qui est intéressant est qu'il fait la même erreur de langage ;)

Mais, pour tous ceux qui auraient un doute :

- php.net::ref.classobj.php

et expliqué plus clairement sur : lephpfacile.com

Modifié par ste
Lien vers le commentaire
Partager sur d’autres sites

Non, il faut prendre en compte le coefficient de préférence (l'indice q dans les en-têtes http). S'il est présent dans la norme http, ce n'est pas pour rien.

L'ordre des différents type mimes listés dans l'en-tête accept n'a pas de particularité, c'est à dire qu'un type mime plus à gauche qu'un autre ne signifie pas que c'est le type mime "préféré". Le seul moyen pour l'agent utilisateur de classer les types mimes supportés par ordre de préférence est d'utiliser le coefficient de préférence.

Cela semble peu important dans le cas présent, mais transposons cela sur les préférences de langage:

Accept-Language: fr,en,*

Quel est le langue préférée de l'utilisateur ? Impossible de savoir. D'où l'utilité du coeff. de préférence:

Accept-Language: fr,en;q=0.9,*;q=0.1

Je préfère des documents en français mais si tu n'as pas ce document dans cette langue, j'accepterai un document en anglais. Si tu ne l'as pas non plus en anglais, envoie moi ce que tu as.

Lien vers le commentaire
Partager sur d’autres sites

Pour ceux que ca intéresse, voici la version finale sous LGPL, que chacun peut donc réutiliser ...

Class set_agent

Sert à gèrer le mime type supporté par les navigateurs,

  à retourner la DTD correcte dans un prologue,

  à compresser les données par bufferisation de sortie si la compression est supportée par le navigateur,

  à corriger le code XHTML en HTML, si le navigateur n'est pas capable d'afficher du XHTML avec le bon mime type, par bufferisation de sortie

Lien vers le commentaire
Partager sur d’autres sites

à corriger le code XHTML en HTML, si le navigateur n'est pas capable d'afficher du XHTML avec le bon mime type, par bufferisation de sortie

Je vois mal l'intérêt de cette conversion en HTML. Si le navigateur ne supporte pas application/xhtml+xml, XHTML1.0 peut lui être servi en text/html s'il respecte http://www.w3.org/TR/xhtml1/#guidelines

Lien vers le commentaire
Partager sur d’autres sites

XHTML 1.0 : oui, peut l'être ...

Je ne vais pas rentrer dans une bataille XHTML 1.0 Strict doit-il être servi en text/html ou non ... le W3C nous dit qu'il peut l'être ; le bouquin O'Reilly nous dit qu'il est préférable d'utiliser application/xhtml+xml, surtout si le format natif est du XML - ce qui en soit est normal - ce qui signifie aussi qu'il peut l'être !

Voilà, pour mes sources...

Après cela peut être une "source" de départ, pour gèrer plus finement, ces navigateurs qui peuvent gérer du XHTML 1.0 au moins en text/html ... sans oublier qu'ils sont incapables de le faire en application/xml ... afin de leur retourner du xhtml 1.0.

Soit !

Il me semble simplement que c'est beaucoup de travail, pour si peu.

D'autant que beaucoup de ces navigateurs "à la vieille sauce" ne gèrent même pas le xhtml correctement, dixit O'Reilly.

Lien vers le commentaire
Partager sur d’autres sites

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...