35 votes

Noms exotiques pour les méthodes, constantes, variables et champs - Bug ou fonctionnalité?

après une certaine confusion dans les commentaires pour

Je pensais en faire une question. Selon le manuel PHP, valide nom de la classe doit correspondre à l'encontre [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*. Mais apparemment, ce n'est pas assurée, ni pour quoi que ce soit d'autre:

define('π', pi());
var_dump(π);

class ␀ {
    private $␀ = TRUE;
    public function ␀()
    {
        return $this->␀;
    }
}

$␀ = new ␀;
var_dump($␀ );
var_dump($␀->␀());

fonctionne très bien (même si mon IDE ne peut pas montrer ␀). Certains érudit clair ce pour moi? Peut-on utiliser Unicode? Et si oui, depuis quand? Non pas que j'ai réellement envie d'utiliser quoi que ce soit, mais A-Za-z_ mais je suis curieux.

Précisions: je ne suis pas après une Regex pour valider les noms de classe, je ne sais si PHP utilise en interne la Regex qu'il suggère dans le manuel. La chose qui me troublait (et, apparemment, les autres gars dans la question) est le pourquoi des choses comme $☂ = 1 peut être utilisé en PHP. PHP6 était suppposed à l'Unicode version mais PHP6 est en hiatus. Mais si il n'y a pas de support de l'Unicode, pourquoi ne puis-je faire alors?

46voto

Artefacto Points 50896

Cette question commence à mentionner les noms de classe dans le titre, mais ensuite, on passe à un exemple qui comprend des noms exotiques pour les méthodes, les constantes, les variables et les champs. Il y a effectivement des règles différentes pour ces. Commençons avec la casse chers.

Insensibles à la casse (identificateurs de classe et de la fonction/méthode de noms)

La directive générale ici serait de n'utiliser que des caractères ASCII imprimables. La raison en est que ces identifiants sont normalisées dans leur version en minuscules, cependant, cette conversion est dépendant des paramètres régionaux. Considérez les points suivants fichier PHP, encodé en ISO-8859-1:

<?php
function func_á() { echo "worked"; }
func_Á();

Sera ce script fonctionne? Peut-être. Cela dépend de ce que l' tolower(193) sera de retour, qui est dépendant de paramètres régionaux:

$ LANG=en_US.utf88591 php a.php
travaillé
$ LANG=en_US.utf8 php a.php

Fatal error: Call to undefined function func_Á() in /home/glopes/a.php sur la ligne 3

Par conséquent, il n'est pas une bonne idée d'utiliser des caractères non-ASCII. Cependant, même les caractères ASCII peuvent provoquer des problèmes dans certaines localités. Voir cette discussion. Il est probable que cela sera corrigé dans le futur en faisant un jeu de paramètres régionaux indépendants de la mise en minuscules qui fonctionne uniquement avec des caractères ASCII.

En conclusion, si nous utilisons multi-octets codages pour ces insensibles à la casse identifiants, nous sommes à la recherche d'ennuis. Ce n'est pas seulement que nous ne pouvons pas profiter de l'affaire à l'insensibilité. Nous pourrions d'ailleurs de lancer dans les collisions inattendues parce que tous les octets qui composent une de caractères multi-octets sont individuellement transformé en minuscules à l'aide des paramètres régionaux de règles. Il est possible que deux types de caractères multi-octets de la carte à la même modifié flux d'octets de la représentation après l'application de la locale minuscules règles de chacun des octets.

Sensible à la casse (identificateurs de variables, des constantes, des champs)

Le problème est moins grave, car ces identifiants sont sensibles à la casse. Cependant, ils sont tout simplement interprétée comme bytestreams. Cela signifie que si nous utilisons Unicode, on doit toujours utiliser la même représentation en octets; nous ne pouvons pas mélanger UTF-8 et UTF-16; nous ne pouvons pas utiliser les Nomenclatures.

En fait, nous devons nous en tenir à l'UTF-8. En dehors de la plage ASCII, UTF-8 utilise le plomb d'octets à partir de 0xc0 à 0xfd et le sentier d'octets dans la gamme 0x80 à 0xbf, qui sont dans la plage autorisée par le manuel. Maintenant, nous allons dire que nous utilisons le caractère "Ġ" en UTF-16BE fichier encodé. Cela permettra de passer à 0x01 0x20, de sorte que le deuxième octet sera interprété comme un espace.

Ayant des caractères multi-octets lus comme s'ils étaient des caractères à un octet est, bien sûr, pas de support de l'Unicode à tous. PHP n'ont certains multi-octets dans la forme de la compilation d'un commutateur "--enable-zend-multibyte" (depuis PHP 5.4, multi-octets de soutien est compilé par défaut, mais désactivé; vous pouvez l'activer avec zend.multibyte=On en php.ini). Cela vous permet de déclarer l'encodage du script:

<?php
declare(encoding='ISO-8859-1');
// code here
?>

Il permettra également de gérer les Nomenclatures, qui sont utilisés pour la détection automatique de l'encodage et de ne pas devenir partie de la sortie. Il ya, cependant, quelques inconvénients:

  • Celle-ci a frappé, à la fois de mémoire et de cpu. Il stocke une représentation du script à l'intérieur d'encodage multi-octet, ce qui prend plus de place (et il semble également stocker en mémoire la version originale) et il passe aussi certains CPU conversion de l'encodage.
  • Multi-octets est généralement pas compilé, il est donc moins testé (plus de bugs).
  • Des problèmes de portabilité entre les installations qui ont la compiler le support et ceux qui n'en ont pas.
  • Se réfère uniquement à l'analyse de la scène; ne résout pas le problème décrit pour la casse, les identificateurs.

Enfin, il y a le problème de l'absence de normalisation – le même caractère peut être représenté avec les différents points de code Unicode (indépendamment de l'encodage). Cela peut conduire à certains très difficile de suivre les bugs.

5voto

Scharron Points 5866

Votre caractère est codé en 0x80 0x90 0xe2 ou quelque chose comme ça, donc il correspond à votre expression rationnelle lorsque vous n'interprétez pas l'unicode (en travaillant sur des octets uniques).

2voto

Jarsäter Points 343

Un nom de classe valide commence par une lettre ou un trait de soulignement, suivi d'un nombre quelconque de lettres, de chiffres ou de traits de soulignement. En tant qu'expression régulière, elle s'exprimerait ainsi: [a-zA-Z_ \ x7f- \ xff] [a-zA-Z0-9_ \ x7f- \ xff] *.

(De php.net)

1voto

webjawns.com Points 1285

De ma compréhension, la version actuelle de PHP sont quelques-support de l'unicode, mais il est incompatible. Comme d'autres l'ont suggéré, que cela allait être abordé dans PHP6, qui a été annulé (non reporté). À la fin de la journée, quelques "exotique" de caractères de travail, et d'autres ne le seront pas; et bien évidemment, comme vous l'avez suggéré, il est préférable de coller avec A-Za-z0-9_.

Dans le même temps, j'ai entendu des rumeurs que l'unicode discussion a été redémarré récemment, sans doute à partir de zéro, comme l'origine de la proposition pour l'UTF-16 dans PHP6 impliqués tonnes d'effort avec très peu de retour.

Note de côté: à Partir de ce que j'ai lu, la prochaine grande version de PHP sera PHP 5.4, qui pourraient figurer l'intégration horizontale (les traits), la matrice de la sténographie, le serveur HTTP intégré, et quelques autres fonctionnalités nécessaires.

http://www.mail-archive.com/internals@lists.php.net/msg35720.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X