PHP Desempaquete la pregunta
-
20-09-2019 - |
Pregunta
list(,$nfields) = unpack ( "N*", substr ( $response, $p, 4 ) ); $p += 4;
La pregunta es por qué "N*"
si substr
¿Deberían devolver 4 bytes, y serán desempaquetados como n? ¿Y por qué la doble asignación?
Actual: Este código es parte de Esfinge Conector PHP nativo. Después de un pirateo de código, quedó claro que este código extrae entero de 4 bytes. Pero la lógica detrás de la doble asignación y substr
/ N*
todavía no está claro para mí. Estoy ofreciendo una recompensa para finalmente entenderlo.
Solución
Necesitaríamos ver el historial de revisión del archivo, pero algunas posibilidades son:
- Estos son los restos de un algoritmo anterior que fue despojado progresivamente de funcionalidad pero que nunca se limpió.
- Es el código de espagueti típico que todos producimos después de una mala noche.
- Es una optimización que acelera el código para grandes cadenas de entrada.
Todos estos son sinónimos:
<?php
$packed = pack('N*', 100, 200, 300);
// 1
var_dump( unpack('N*', $packed) );
// 2
var_dump( unpack('N*', substr($packed, 0, 4)) );
var_dump( unpack('N*', substr($packed, 4, 4)) );
var_dump( unpack('N*', substr($packed, 8, 4)) );
// 3
var_dump( unpack('N', substr($packed, 0, 4)) );
var_dump( unpack('N', substr($packed, 4, 4)) );
var_dump( unpack('N', substr($packed, 8, 4)) );
?>
Hice el típico punto de referencia de repetición típica con tres enteros y 1 es mucho más rápido. Sin embargo, una prueba similar con 10,000 enteros muestra que 1 es el más lento:-!
0.82868695259094 seconds
0.0046610832214355 seconds
0.0029149055480957 seconds
Al ser un motor de texto completo donde el rendimiento es imprescindible, me atrevería a decir que es una optimización.
Otros consejos
El código es probablemente un error. Este tipo de bucle es precisamente la razón por la cual *
existe ...
desempaquetado ("n*", substr ($ respuesta, $ p, 4));
Especifica el formato a usar al desempacar los datos de subStr ()
N - Unsigned Long, siempre 32 bits, gran pedido de bytes de endian