predefinidas - operadores en php
Nombres exóticos para métodos, constantes, variables y campos-¿Error o característica? (4)
Esta pregunta comienza a mencionar nombres de clase en el título, pero luego continúa con un ejemplo que incluye nombres exóticos para métodos, constantes, variables y campos. En realidad, hay diferentes reglas para esto. Comencemos con los que no distinguen entre mayúsculas y minúsculas.
Identificadores insensibles a mayúsculas y minúsculas (nombres de clase y función / método)
La pauta general aquí sería usar solo caracteres ASCII imprimibles. La razón es que estos identificadores están normalizados a su versión en minúscula, sin embargo, esta conversión depende de la configuración regional. Considere el siguiente archivo PHP, codificado en ISO-8859-1:
<?php
function func_á() { echo "worked"; }
func_Á();
¿Funcionará este script? Tal vez. Depende de qué devolverá tolower
(
193
)
, que depende de la configuración regional:
$ LANG=en_US.iso88591 php a.php worked $ LANG=en_US.utf8 php a.php Fatal error: Call to undefined function func_Á() in /home/glopes/a.php on line 3
Por lo tanto, no es una buena idea usar caracteres que no sean ASCII. Sin embargo, incluso los caracteres ASCII pueden causar problemas en algunas configuraciones regionales. Vea esta discusión . Es probable que esto se solucione en el futuro haciendo una minería independiente de la configuración regional que solo funcione con caracteres ASCII.
En conclusión, si usamos codificaciones multibyte para estos identificadores que no distinguen entre mayúsculas y minúsculas, estamos buscando problemas. No es solo que no podamos aprovechar la insensibilidad de las mayúsculas y minúsculas. En realidad, podríamos encontrarnos con colisiones inesperadas porque todos los bytes que componen un carácter de múltiples bytes se convierten individualmente en minúsculas utilizando las reglas de configuración regional. Es posible que dos caracteres de varios bytes diferentes se correlacionen con la misma representación de flujo de bytes modificados después de aplicar las reglas de minúsculas de configuración regional a cada uno de los bytes.
Identificadores de mayúsculas y minúsculas (variables, constantes, campos)
El problema es menos grave aquí, ya que estos identificadores distinguen entre mayúsculas y minúsculas. Sin embargo, solo se interpretan como bytestreams. Esto significa que si usamos Unicode, debemos usar consistentemente la misma representación de bytes; no podemos mezclar UTF-8 y UTF-16; tampoco podemos usar listas de materiales.
De hecho, debemos apegarnos a UTF-8. Fuera del rango ASCII, UTF-8 usa bytes de 0xc0 a 0xfd y los bytes de camino están en el rango de 0x80 a 0xbf, que están en el rango permitido por el manual. Ahora digamos que usamos el caracter "Ġ" en un archivo codificado en UTF-16BE. Esto se traducirá a 0x01 0x20, por lo que el segundo byte se interpretará como un espacio.
Tener caracteres multibyte que se lean como si fueran caracteres de un solo byte, por supuesto, no es compatible con Unicode en absoluto. PHP tiene soporte para múltiples bytes en la forma del interruptor de compilación "--enable-zend-multibyte" (a partir de PHP 5.4, el soporte multibyte está compilado por defecto, pero deshabilitado; puedes habilitarlo con zend.multibyte=On
php.ini). Esto le permite declare la codificación de la secuencia de comandos:
<?php
declare(encoding=''ISO-8859-1'');
// code here
?>
También manejará listas de materiales, que se utilizan para detectar automáticamente la codificación y no formar parte de la salida. Sin embargo, hay algunas desventajas:
- Golpe de Peformance, memoria y CPU. Almacena una representación del script en una codificación interna de varios bytes, que ocupa más espacio (y también parece almacenar en la memoria la versión original) y también gasta algo de CPU convirtiendo la codificación.
- La compatibilidad con varios bytes generalmente no está compilada, por lo que está menos probada (más errores).
- Problemas de portabilidad entre las instalaciones que tienen el soporte compilado y los que no.
- Se refiere solo a la etapa de análisis sintáctico; no resuelve el problema descrito para los identificadores que no distinguen entre mayúsculas y minúsculas.
Finalmente, existe el problema de la falta de normalización: el mismo carácter puede representarse con diferentes puntos de código Unicode (independientemente de la codificación). Esto puede llevar a algunos errores muy difíciles de rastrear.
después de un poco de confusión en los comentarios a
Pensé que me convertí en una pregunta. De acuerdo con el manual de PHP, un nombre de clase válido debe coincidir con [a-zA-Z_/x7f-/xff][a-zA-Z0-9_/x7f-/xff]*
. Pero aparentemente, esto no se aplica, ni se aplica a ninguna otra cosa:
define(''π'', pi());
var_dump(π);
class ␀ {
private $␀ = TRUE;
public function ␀()
{
return $this->␀;
}
}
$␀ = new ␀;
var_dump($␀ );
var_dump($␀->␀());
funciona bien (aunque mi IDE no puede mostrar ␀). ¿Puede una persona erudita aclarar esto por mí? ¿Podemos usar cualquier Unicode? Y si es así, ¿desde cuándo? No es que realmente quisiera usar algo más que A-Za-z_
pero tengo curiosidad.
Aclaración: no estoy buscando un Regex para validar nombres de clase, ni sé si PHP usa internamente el Regex que sugiere en el manual. Lo que me confundió (y aparentemente a los otros tipos en la pregunta relacionada) es por qué cosas como $☂ = 1
se pueden usar en PHP. Se suponía que PHP6 sería la versión de Unicode, pero PHP6 está en pausa. Pero si no hay soporte Unicode, ¿por qué puedo hacer esto entonces?
Según entiendo, las versiones actuales de PHP tienen soporte unicode, pero es inconsistente. Como otros han sugerido, esto se abordaría en PHP6, que se canceló (no se pospuso). Al final del día, algunos personajes "exóticos" funcionarán y otros no; y obviamente, como sugirió, es mejor quedarse con A-Za-z0-9_
.
Al mismo tiempo, he escuchado rumores de que la discusión Unicode se reinició recientemente, presumiblemente desde cero, ya que la propuesta original para UTF-16 en PHP6 involucró toneladas de esfuerzo con muy poco retorno.
Nota al pie: por lo que he leído, la próxima versión principal de PHP será PHP 5.4, que podría incluir integración horizontal (rasgos), taquigrafía de matriz, servidor HTTP incorporado y alguna otra funcionalidad muy necesaria.
Su carácter está codificado como 0x80 0x90 0xe2
o algo así, por lo que coincide con su 0x80 0x90 0xe2
cuando no interpreta el Unicode (trabajando en bytes individuales).
Un nombre de clase válido comienza con una letra o guión bajo, seguido de cualquier número de letras, números o guiones bajos. Como expresión regular, se expresaría así: [a-zA-Z_ / x7f- / xff] [a-zA-Z0-9_ / x7f- / xff] *.
(Desde php.net)