una schuman saltadora que para paises minas maniobra las hace funciona desactivar contra consecuencias con como antipersonal antipersona php performance

php - schuman - paises con minas antipersona



Las minas terrestres de PHP en general (24)

¿Qué sorpresas encontraron otras personas al escribir aplicaciones web PHP? Está el problema conocido y por resolver con la herencia de la clase de tiempo de compilación, pero sé de un par de otros y quería probar y crear una lista de los principales problemas del lenguaje.

Nota:

He ocupado varios puestos como desarrollador Sr. PHP5, por lo que el trabajo de PHP paga mis cuentas, esta pregunta no tiene como objetivo reventar PHP como un idioma, ya que todos los idiomas con los que he trabajado tienen algunas sorpresas conocidas o no tan conocidas. .


El gran problema del que he visto caer a la gente es la precisión (en php y en otros idiomas).

Si quieres un poco de diversión compara cualquier flotador con un todo con> = y descubre cuántas veces obtienes el resultado esperado.

Esta ha sido la perdición de muchas personas que trabajan con dinero dentro de PHP e intentan tomar decisiones lógicas basadas en comparaciones que no permiten redondear a un número entero.

Por ejemplo, tela

La tela se vende en unidades de 1 yarda o 1 yarda y también mantiene un inventario de la medición exacta que queda de la tela.

Si este sistema no se expresa en números enteros y se expresa en puntos flotantes, será increíblemente difícil tomar decisiones sólidas.

Su mejor opción es expresar 1 yarda media como 1, por ejemplo, si tiene 300 yardas de tela, tendría un inventario de 600 (600 unidades de media yarda).

De todos modos, ese es mi problema, tengo tiempo para refacturar 4 meses de programación debido a que no entiendo la precisión ...


Era algo obvio después del hecho, pero un error conocido tiene que ver con el alcance y las referencias cuando se usa en foreach.

foreach($myArray as &$element){ //do something to the element here... maybe trim or something more complicated } //Multiple lines or immediately after the loop $element = $foobar;

La última celda de su matriz ahora se ha convertido en $ foobar porque la referencia en el foreach anterior todavía está en el ámbito de contexto actual.


Los problemas de rendimiento con las aplicaciones PHP suelen ser uno de los siguientes:

  • Acceso al sistema de archivos: lectura y escritura en el disco
    • Aquí es donde APC, eAccelerator, etc. son útiles, reducen el acceso al sistema de archivos almacenando en caché los archivos PHP analizados en la memoria
  • Base de datos: consultas lentas, grandes conjuntos de datos
  • E / S de red: accediendo a recursos externos

Es bastante raro encontrarse con problemas de rendimiento con PHP (o cualquier aplicación web escrita en cualquier idioma). Los problemas anteriores suelen ser órdenes de magnitud más lentos que la ejecución del código.

Como siempre, perfila tu código!


Memoria total mientras se ejecuta PHP Muchos proyectos grandes solo incluyen todos los archivos de clase y los usan cuando los necesitan. Esto se suma a la memoria total que PHP necesita usar para cada ejecución.

También proyecta usar marcos o marcos porque esto podría duplicar fácilmente el uso de la memoria.

Así que emplea una carga condicional de tus archivos de clase, no tienes nada cargado que no estés usando


No estar al tanto de la precedencia del operador puede causar algunos problemas:

if ($foo = getSomeValue() && $bar) { // … } // equals if ($foo = (getSomeValue() && $bar)) { // … }


No estoy seguro de si esto cuenta, pero la necesidad de compilar scripts PHP es un gran problema de rendimiento. En cualquier proyecto serio de PHP necesita algún tipo de caché de compilación como APC , eAccelerator , PHP Accelerator o la (comercial) Zend Platform .


Otro error en PHP, he visto este error de personas que vienen de otros idiomas pero no a menudo.

<?php /** * regular */ echo (true && true); // 1 echo (true && false); // nothing echo (true || false); // 1 echo (false || false); // nothing echo (true xor false); // 1 echo (false xor false); // nothing /** * bitwise */ echo (true & true); // 1 echo (true & false); // 0 echo (true | false); // 1 echo (false | false); // 0 echo (true ^ false); // 1 echo (false ^ false); // 0 ?>


__autoload() resultó ser una gran mina para mí recientemente. Algunas de nuestras bibliotecas y códigos heredados usan class_exists() e intenta cargar automáticamente las clases que nunca debieron cargarse de esa manera. Muchos errores y advertencias fatales. class_exists() todavía se puede usar si tiene autocarga, pero el segundo parámetro (nuevo desde PHP 5.2.0) tiene que establecerse en false


El silenciador @ error siempre debe evitarse.

Un ejemplo:

// Don''t let the user see an error if this unimportant header file is missing: @include ''header.inc.php'';

Con el código anterior, nunca sabrá sobre ningún error en ninguno de los códigos en header.inc.php , o cualquiera de las funciones llamadas desde header.inc.php , y si hay un error fatal en alguna parte, su página web detenerse sin forma de averiguar cuál fue el error.


Mi favorito PHP gotcha:

Considere esto incluir:

# ... lots of code ... $i = 42; # ... more code ...

Entonces usa esto incluye en alguna parte:

for($i = 0; $i < 10; $i++){ # ... include ''that_other_file.php''; }

Luego intenta adivinar cuántas veces se ejecuta el ciclo. Sí, una vez. El alcance léxico (y el alcance dinámico adecuado) son problemas resueltos. Pero no en PHP.


NULL y la cadena "0" son pura maldad en Php

if ("0" == false) //true if ("0" == NULL) //true if ("0" == "NULL")//true


Solo pensé en una sorpresa más. array_map que aplica una devolución de llamada a una matriz, es un grave asesino de rendimiento. No estoy totalmente seguro de por qué, pero creo que tiene algo que ver con la copia de PHP en el mecanismo de escritura de los bucles.



Referencias recurrentes pierden memoria

Si crea dos objetos y los almacena dentro de las propiedades uno del otro, el recolector de basura nunca los tocará:

$a = new stdClass; $b = new stdClass; $a->b = $b; $b->a = $a;

Esto es bastante fácil de hacer cuando una clase grande crea un pequeño objeto auxiliar que generalmente almacena la clase principal:

// GC will never clean up any instance of Big. class Big { function __construct() { $this->helper = new LittleHelper($this); } } class LittleHelper { function __construct(Big $big) { $this->big = $big; } }

Siempre que PHP esté dirigido a solicitudes de páginas rápidas y cortas, no es probable que solucionen este problema. Esto significa que no se puede depender de PHP para daemons u otras aplicaciones que tengan una larga vida útil.


al principio uno podía pasar mucho tiempo depurando ese tipo de código:

$a = 1; echo $a; # 1 echo "$a"; # 1 echo ''$a''; # $a

malditas citas! Muy frustrante :(


  • foreach () está copiando silenciosamente la matriz en el fondo e iterando a través de esa copia. Si tiene una gran matriz, esto degradará el rendimiento. En esos casos, las opciones de referencia de foreach () son nuevas en php5 o usan un bucle for ().

  • Tenga en cuenta la igualdad (==) frente a la identidad (===).

  • Tenga en cuenta lo que constituye empty () frente a lo que constituye isset ().

Más minas terrestres ahora que tengo más tiempo:

  • No compare las carrozas por la igualdad. PHP no es matlab y simplemente no está diseñado para una aritmética precisa de coma flotante. Prueba este:

if (0.1 + 0.2 == 0.3) echo "equal"; else echo "nope"; // <-- ding ding

  • Del mismo modo, ¡no olvides tus octals! Un int w / a cero inicial se convierte en octal.

if (0111 == 111) echo "equal"; else echo "nope"; // <-- ding ding


No recibir mensajes de compilación para las ramas if / else:

if( $foo ) { some_function(); } else { non_existing_function(); // oops! }

PHP no mencionará que la función non_existing_function no existe hasta que ingrese una situación donde $foo es falso.

Olvidando establecer:

error_reporting( E_ALL );

Entonces los avisos no son capturados, pasando la depuración del tiempo:

  • variables no existentes
  • propiedades inválidas del objeto
  • claves de matriz inválidas

Pegando cadenas de diferentes "tipos" / fuentes, sin escapar de ellas:

// missing mysql_real_escape_string() or an int cast ! $sql = "SELECT * FROM persons WHERE id=$id"; // missing htmlentities() and urlencode() ! $html = "<a href=''?page=$id''>$text</a>";


Si está acostumbrado a idiomas con operadores lógicos inteligentes, intentará hacer cosas como:

$iShouldTalkTo = $thisObj || $thatObj;

En PHP, $iShouldTalkTo ahora es un valor booleano. Estás obligado a escribir:

$iShouldTalkTo = $thisObj ? $thisObj : $thatObj;

De todos los ejemplos de cómo las primeras decisiones de diseño en PHP intentaron sostener las manos de programadores incompetentes a cambio de obstaculizar a los competentes, ese puede ser el que más me irrita.

El daño cerebral profundo en la construcción del switch() abunda. Considera esto:

switch($someVal) { case true : doSomething(); break; case 20 : doSomethingElse(); break; }

Resulta que doSomethingElse() nunca será llamado, porque ''case true'' absorberá todos los casos verdaderos de $ someVal.

Creo que eso es justificable, tal vez? Bueno, prueba este:

for($ix = 0; $ix < 10; $ix++) { switch($ix) { case 3 : continue; default : echo '':''; } echo $ix; }

Adivina cuál es su resultado? Debería ser: 0: 1: 2: 4: 5: 6: 7: 8: 9, ¿verdad? No, es: 0: 1: 23: 4: 5: 6: 7: 8: 9. Es decir, ignora la semántica de la declaración de continue y la trata como un break .


Uno de los peores es el concepto de "matrices asociativas" de PHP , que son híbridos totalmente fallidos de una matriz, un diccionario y una lista. Los autores de PHP parecen no estar seguros de cómo debería comportarse en cada caso, lo que conduce a rarezas, como el comportamiento diferente del operador de arrays plus y array_merge .

php > $a = array(1=>''one''); php > $b = array(2=>''two''); php > var_dump($a+$b); /* plus preserves original keys */ array(2) { [1]=> string(3) "one" [2]=> string(3) "two" } php > var_dump(array_merge($a,$b)); /* array_merge reindexes numeric keys */ array(2) { [0]=> string(3) "one" [1]=> string(3) "two" } php > $a = array(1=>''one''); php > $b = array(1=>''another one''); php > var_dump($a+$b); /* plus ignores duplicate keys, keeping the first value */ array(1) { [1]=> string(3) "one" } php > var_dump(array_merge($a,$b)); /* array_merge just adds them all, reindexing */ array(2) { [0]=> string(3) "one" [1]=> string(11) "another one" } php > $a = array(1,2,3); php > $b = array(4,5,6); /* non-associative arrays are really associative arrays with numeric keys… */ php > var_dump($a+$b); /* … so plus doesn’t work as you’d normally expect */ array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } php > var_dump(array_merge($a,$b)); /* you should use array_merge instead */ array(6) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) [5]=> int(6) }


Cadenas numéricas convertidas automáticamente a enteros

Ese es de lejos el truco más feo y oscuro en PHP. Siempre que tenga una cadena que tenga todos los dígitos, automáticamente se tratará como si fuera un número entero en algunos casos.

php > var_dump("0" == "00"); bool(true)

Esto puede ser realmente desagradable combinado con las "matrices asociativas" de PHP, lo que lleva a rarezas donde $a == $b no implica, que $arr[$a] == $arr[$b];

php > var_dump(array(''00''=>''str(zerozero)'', ''0''=>''str(zero)'')); array(2) { ["00"]=> string(13) "str(zerozero)" [0]=> string(9) "str(zero)" }


Typecasting y triple igual

En general, en la mayoría de los idiomas, cuando opera con dos tipos diferentes de datos, obtiene una excepción o uno de ellos se convierte en uno más general. En lenguaje, con excepción de PHP, la cadena se considera más general que entero. Solo en PHP tienes:

php > var_dump(''nada'' == 0); bool(true)

Para hacer frente a ese PHP introdujo el operador de triple igualdad. Lo cual, por definición, devuelve verdadero si los valores son del mismo tipo y del mismo valor. Funciona para el ejemplo anterior:

php > var_dump(''nada'' === 0); bool(false)

Pero también se comporta bastante feo cuando en realidad te gustaría que los valores sean iguales.

php > var_dump(0.0 === 0); bool(false)

Si vienes a trabajar con PHP con experiencia de cualquier otro idioma, es probable que tengas problemas con esto.


$x = array(); $x == null ? "true": "false";

La salida es "verdadera".

$x = array("foo"); $x == null ? "true": "false";

La salida es "falsa";


¿De acuerdo con Why llamando a una función tan lenta (como strlen, count, etc.) en un valor referenciado?

Si pasa una variable a una función por referencia, y luego llama a una función, es increíblemente lenta.

Si recorre la llamada a la función y la variable es grande, puede ser de varios órdenes de magnitud más lenta que si la variable se pasa por valor.

Ejemplo:

<?php function TestCount(&$aArray) { $aArray = range(0, 100000); $fStartTime = microtime(true); for ($iIter = 0; $iIter < 1000; $iIter++) { $iCount = count($aArray); } $fTaken = microtime(true) - $fStartTime; print "took $fTaken seconds/n"; } $aArray = array(); TestCount($aArray); ?>

Esto siempre lleva unos 20 segundos para ejecutarse en mi máquina (en PHP 5.3).

Pero si cambio la función para pasar el valor (es decir, la function TestCount($aArray) lugar de la function TestCount(&$aArray) ), se ejecuta en aproximadamente 2 ms, ¡ literalmente 10.000 veces más rápido !

Lo mismo es cierto para cualquier función que pase por valor: ambas funciones strlen , como strlen , y para funciones definidas por el usuario.

¡Este es un tarpit bastante aterrador del que antes no era consciente!

Afortunadamente, hay una solución simple que es aplicable en muchos casos: use una variable local temporal dentro del ciclo y cópiela a la variable de referencia al final.


require_once e include_once a menudo pueden dar lugar a mayores asesinos de rendimiento cuando se usan en exceso. Si incluye / requiere un archivo que contiene una clase ... un patrón como ese puede ahorrarle tiempo de procesamiento.

class_exists("myFoo") or require("myFoo.someClass.php");

Actualización: Esto todavía es un problema - http://www.techyouruniverse.com/software/php-performance-tip-require-versus-require_once

Actualización: lea la respuesta seleccionada para la siguiente pregunta: ¿Sufriría el rendimiento el uso de carga automática en php y la búsqueda del archivo de clase? Si se implementa en esta línea, se minimiza de la mejor manera posible las penalizaciones para el archivo include / requires.