Características ocultas de PHP? [cerrado]

174

Sé que esto suena como una pregunta puntual, pero déjame explicarte de dónde vengo.

Fuera de la universidad conseguí un trabajo en una tienda PHP. Trabajé allí durante un año y medio y pensé que había aprendido todo lo que había que aprender sobre programación.

Luego conseguí un trabajo como taller de desarrollo interno de un solo hombre en una corporación considerable donde todo el trabajo estaba en C #. En mi compromiso con el puesto, comencé a leer un montón de blogs y libros y rápidamente me di cuenta de lo equivocado que estaba al pensar que lo sabía todo. Aprendí sobre las pruebas unitarias, la inyección de dependencia y los patrones decoradores, el principio de diseño del acoplamiento flojo, la composición sobre el debate de la herencia, y así sucesivamente. Todavía lo estoy absorbiendo todo. No hace falta decir que mi estilo de programación ha cambiado completamente en el último año.

Ahora me encuentro recogiendo un proyecto de PHP haciendo algo de codificación para el inicio de un amigo y me siento completamente limitado en comparación con la programación en C #. Realmente me molesta que todas las variables en un ámbito de clase tengan que ser mencionadas agregando '$ this->'. Me molesta que ninguno de los IDE que he probado tengan muy buena inteligencia y que mis métodos de prueba de unidad SimpleTest tengan que comenzar con la palabra 'prueba'. Me vuelve loco que la escritura dinámica me impida especificar implícitamente qué tipo de parámetro espera un método, y que usted tiene que escribir una declaración de cambio para realizar sobrecargas de métodos. No puedo soportar que no puedas tener espacios de nombres anidados y que tengas que usar el operador :: para llamar al constructor de la clase base.

Ahora no tengo intención de iniciar un debate PHP vs C #, más bien lo que quiero decir es que estoy seguro de que hay algunas características de PHP que no conozco o que aún no uso correctamente. Estoy ambientado en mi universo C # y tengo problemas para ver fuera del recipiente de vidrio.

Entonces, pregunto, ¿cuáles son sus características favoritas de PHP? ¿Qué cosas puedes hacer en él que no puedes o son más difíciles en los idiomas .Net?

George Mauer
fuente
Roto paradigma OO? Para mí es la peor característica "oculta" que descubres.
knoopx
Estos hilos son un poco divertidos ... Porque para el equipo con el que trabajo "característica oculta" es una frase de código que significa "error". Y sabes qué ... A veces descubrir una característica oculta no es necesariamente algo bueno ...
Ganesh Shankar
@Ganesh el error de un hombre es la característica oculta de otro hombre ...
Xeoncross

Respuestas:

328

Documentación . La documentación obtiene mi voto. No he encontrado una documentación en línea más exhaustiva para un lenguaje de programación; todo lo demás lo tengo que reunir de varios sitios web y páginas de manual.

Kyle Cronin
fuente
6060
Estoy de acuerdo. Poder escribir www.php.net/function_name y obtener una referencia la mayor parte del tiempo es genial.
Allain Lalonde
1
Esta es una gran característica de PHP, pero realmente no lo llamaría oculto ... Si alguna vez buscó en Google los parámetros del método, etc., terminaría en php.net.
John Bubriski
27
Estoy de acuerdo también Lo mejor del manual son los comentarios de los usuarios. Raramente he visto otras documentaciones que tengan esos. Pueden contener gemas reales. El único inconveniente es que, en mi humilde opinión, se podaron demasiado pronto.
Sander Marechal
3
@Phoexo "un poco menos legible" ??? Nunca entendí y nunca entenderé MSDN, mientras que los documentos PHP son fáciles y claros.
lauriys
3
Discrepar. La única razón por la que la documentación es "buena" es porque algunos de los comentarios de los usuarios tapan todos los agujeros en las notas oficiales.
Rob Howard
179

Las matrices . A juzgar por las respuestas a esta pregunta, no creo que las personas aprecien completamente cuán fáciles y útiles son las matrices en PHP. Las matrices PHP actúan como listas, mapas, pilas y estructuras de datos genéricos, todo al mismo tiempo. Las matrices se implementan en el núcleo del idioma y se utilizan en todas partes, lo que da como resultado una buena ubicación de la caché de la CPU. Perl y Python usan construcciones de lenguaje separadas para listas y mapas, lo que resulta en más copias y transformaciones potencialmente confusas.

usuario8134
fuente
11
Los elementos de la matriz PHP están ordenados.
user8134
117
Mi primer movimiento de PHP a C # casi me mata. En C #, las matrices son solo una estructura simple con un tamaño estático y un índice numérico. ¡En PHP, las matrices son la cinta adhesiva del universo!
Dinah
44
Yo tambien estoy de acuerdo. Al jugar con Java para una asignación de Uni, me sorprendió lo rígidos que eran, sin flexibilidad en absoluto. Realmente me hizo apreciar lo buenos que son los arreglos PHP.
Christian
11
Estoy seguro de que las matrices de php son geniales, pero ¿40 votos por el comentario que golpea las matrices de C #? Si una matriz C # no se ajusta a la necesidad, hay muchas opciones. ArrayList y las colecciones genéricas son muy poderosas. Existen numerosos tipos de colecciones para necesidades específicas. La única ventaja real de php a este respecto es que no proporciona ninguna opción de la que un programador debe decidir. Usted usa una matriz o no tiene una variable indexable.
G-Wiz
24
Por otro lado, la sintaxis para las matrices es una mierda. En muchos lenguajes de script puede crear una sencilla matriz 2D de este modo: [[1, 2], [3, 4]], comparar esto con la versión de PHP: array(array(1, 2), array(3, 4)).
Rene Saarsoo
167

Los controladores de transmisión le permiten ampliar el "FileSystem" con una lógica que, hasta donde yo sé, es bastante difícil de hacer en la mayoría de los otros idiomas.

Por ejemplo, con el controlador MS-Excel Stream puede crear un archivo MS Excel de la siguiente manera:

$fp = fopen("xlsfile://tmp/test.xls", "wb");
if (!is_resource($fp)) { 
    die("Cannot open excel file");
}

$data= array(
    array("Name" => "Bob Loblaw", "Age" => 50),  
    array("Name" => "Popo Jijo", "Age" => 75),  
    array("Name" => "Tiny Tim", "Age" => 90)
); 

fwrite($fp, serialize($data));
fclose($fp);
Allain Lalonde
fuente
Creo que el marco KIO también le permite hacer esto, pero eso solo está disponible para aplicaciones de escritorio basadas en KDE.
MiffTheFox
21
En mi humilde opinión, tener un enfoque OO adecuado sería mucho más sensato que este lío con los controladores de flujo. Sí, es lindo poder leer / escribir archivos de Excel, pero ¿tiene que funcionar así?
Anti Veeranna
3
Tal vez sea así, pero este enfoque encapsula la complejidad en una interfaz que es común para la mayoría de los desarrolladores de PHP ... sin requerirles que aprendan conceptos orientados a objetos que podrían estar más allá de ellos.
Allain Lalonde
13
Si está trabajando con Amazon S3, consulte Zend_Amazon_S3, que proporciona una interfaz de transmisión para URL como 's3: // {bucket-name} / path'.
davidtbernal
He usado esto para crear un DSL simple para mi capa de vista simplemente leyendo el archivo PHP, haciendo un reemplazo de cadena y pasándolo a través de eval (). Por ejemplo, lo hice de tal manera que pueda usar etiquetas cortas cada vez que elija y haga @ -> someVar para poder acceder a los datos a nivel de vista.
Jasper Bekkers
131

Los métodos mágicos son métodos fallidos que se llaman cada vez que invocas un método que no existe o asignas o lees una propiedad que no existe, entre otras cosas.

interface AllMagicMethods {
    // accessing undefined or invisible (e.g. private) properties
    public function __get($fieldName);
    public function __set($fieldName, $value);
    public function __isset($fieldName);
    public function __unset($fieldName);

    // calling undefined or invisible (e.g. private) methods
    public function __call($funcName, $args);
    public static function __callStatic($funcName, $args); // as of PHP 5.3

    // on serialize() / unserialize()
    public function __sleep();
    public function __wakeup();

    // conversion to string (e.g. with (string) $obj, echo $obj, strlen($obj), ...)
    public function __toString();

    // calling the object like a function (e.g. $obj($arg, $arg2))
    public function __invoke($arguments, $...);

    // called on var_export()
    public static function __set_state($array);
}

Un desarrollador de C ++ aquí podría notar que PHP permite sobrecargar algunos operadores, por ejemplo, ()o (string). En realidad, PHP permite sobrecargar aún más, por ejemplo, el []operador ( ArrayAccess ), la foreachconstrucción del lenguaje ( Iterator e IteratorAggregate ) y la countfunción ( Contable ).

NikiC
fuente
44
Como ejemplo útil de lo que se puede lograr con métodos mágicos, vaya a phpcodetips.blogspot.com/2008/07/domain-model-validation.html
grom
66
Discrepar. Esto es mucho más débil que las instalaciones similares en Smalltalk, Ruby y Python (y es de suponer que fue copiado de uno de estos)
finnw
34
El hecho de que la implementación de PHP de esta funcionalidad sea más débil que esos otros lenguajes, no la hace menos útil en PHP.
Allain Lalonde
2
__call()es genial en marcos con map domain.com/controller/method/
alex
77
Los métodos mágicos también son lentos como el infierno. Úselos con cuidado.
Alex Weinstein el
95

La clase estándar es un contenedor ordenado. Solo me enteré recientemente.

En lugar de usar una matriz para contener varios atributos

$person = array();
$person['name'] = 'bob';
$person['age'] = 5;

Puedes usar una clase estándar

$person = new stdClass();
$person->name = 'bob';
$person->age = 5;

Esto es particularmente útil cuando se accede a estas variables en una cadena

$string = $person['name'] . ' is ' . $person['age'] . ' years old.';
// vs
$string = "$person->name is $person->age years old.";
Dean Rather
fuente
43
"{$ persona ['nombre']} tiene {$ persona ['edad']} años" funciona.
Kornel
27
"persona [nombre] tiene $ persona [edad] años" también funcionará ... Sin comillas, sin llaves :)
majelbstoat
16
$ string = sprintf ("% s tiene% d años", $ person ['name'], $ person ['age']);
Daniel Sloof
6060
Mientras estamos en el tema: (objeto) array ("name" => 'bob', 'age' => 5)
Annika Backstrom
30
@majelbstoat: Sacar las comillas ralentizaría la secuencia de comandos porque el intérprete PHP buscará si 'nombre' y 'edad' se han definido con definir (...). También es una mala práctica considerar que sería posible voltear totalmente las teclas a las que se accede en cada caso: define ('edad', 'nombre'); define ('nombre', 'edad');
brianreavis 03 de
90

Los archivos de inclusión pueden tener un valor de retorno que puede asignar a una variable.

// config.php
return array(
    'db' => array(
        'host' => 'example.org',
        'user' => 'usr',
        // ...
    ),
    // ...
);

// index.php
$config = include 'config.php';
echo $config['db']['host']; // example.org
Philippe Gerber
fuente
@ Peter MUY útil para el manejo de errores de excepción db-> localhost.
Talvi Watia el
Es conveniente para configurar un archivo de configuración rápido y sucio.
Frank Farmer
¿Por qué devuelves esta matriz? Si un archivo incluido contiene una matriz, se puede usar en la inclusión de inmediato.
fabrik
55
@fabrik porque sería una variable global y estaría disponible en todo el ámbito principal. Eso es bastante desagradable, esto es mucho mejor.
Mikulas Dite el
Trabajé en un proyecto en el marco de Yii y ese proyecto tiene un archivo de configuración en el que la matriz se devolvió así, ahora entiendo por qué el archivo era así.
Simer Twilio Toronto desarrollador
83

Puede aprovechar el hecho de que el oroperador tiene menos prioridad que =hacer esto:

$page = (int) @$_GET['page'] 
  or $page = 1;

Si el valor de la primera asignación se evalúa como true, la segunda asignación se ignora. Otro ejemplo:

$record = get_record($id) 
  or throw new Exception("...");
Pies
fuente
77
No estoy muy convencido de esto, creo; a pesar de que parece no ser propenso a errores, es contra-intuitivo, y eso en sí mismo puede promover errores.
thomasrutter
14
@Pies: una forma es el siguiente código bastante desordenado para ser honesto: $ page = isset ($ _ GET ['page'])? (int) $ _ GET ['página']: 1; // La ventaja de esto es que no se requiere supresión de errores.
DisgruntledGoat
3
pensando bien, ya que está buscando un número entero que podría usar en su lugar: $ page = is_int ($ _ GET ['page'])? $ _GET ['página']: 1;
DisgruntledGoat
44
Vale la pena señalar que el código posterior orse ejecutará si el código anterior orda como resultado el valor numérico 0. Por lo tanto, semánticamente puede ser menos probable con algo así $_GET['page'], pero obviamente la circunstancia puede surgir y es bueno tener cuidado.
párpado
3
También vale la pena señalar que el oroperador es una versión del ||operador con un precedente inferior . Además, +1 porque esto es altamente expresivo y a menudo olvido que es posible. Debe usarse con más frecuencia, y es absolutamente claro en lo que hace. Sin embargo, no sé cómo codifican los "hombres reales", así que no puedo comentar sobre eso.
párpado
80

__autoload()(clase) archivos ayudados por set_include_path().

En PHP5 ahora no es necesario especificar largas listas de declaraciones "include_once" cuando se hace una OOP decente.

Simplemente defina un pequeño conjunto de directorios en el que los archivos de la biblioteca de clases estén estructurados de manera sensata y configure la ruta de inclusión automática:

set_include_path(get_include_path() . PATH_SEPARATOR . '../libs/');`

Ahora la __autoload()rutina:

function __autoload($classname) {
    // every class is stored in a file "libs/classname.class.php"

    // note: temporary alter error_reporting to prevent WARNINGS
    // Do not suppress errors with a @ - syntax errors will fail silently!

    include_once($classname . '.class.php');
}

Ahora PHP incluirá automáticamente los archivos necesarios a pedido, conservando el tiempo de análisis y la memoria.

Wimmer
fuente
¿Es mejor usar spl_autoload_register ()?
alex
19
¡Por supuesto! __autoload () es PHP4 pero spl_autoload_register () es una "conexión en cadena" no destructiva de los métodos de carga automática.
Willem el
3
Una característica útil, pero la única advertencia es que cuando encuentras una instancia de una clase determinada, hace que sea un poco más difícil localizar la ubicación de un archivo de clase. La definición explícita de incluye en la parte superior le brinda una lista finita de clases involucradas y su ubicación exacta.
Cory House el
Es una buena característica, pero solo para sortear la situación de no tener el código precompilado, por lo que no sabe dónde va a estar la clase. La gran desventaja de esto es que no puede tener 2 clases con el mismo nombre, incluso si están en espacios de nombres diferentes.
Kibbee
3
Eche un vistazo a la propuesta PSR-0 del Grupo de trabajo de estándares de PHP (con desarrolladores de ZF, Symfony, Doctrine, CakePHP, Solar, etc.) al implementar la carga automática: groups.google.com/group/php-standards/web / psr-0-final-offer
Philippe Gerber
76

Facilidad . La mejor característica es lo fácil que es para los nuevos desarrolladores sentarse y escribir scripts "de trabajo" y comprender el código.

La peor característica es lo fácil que es para los nuevos desarrolladores sentarse y escribir scripts "funcionales" y pensar que entienden el código.

La apertura de la comunidad que rodea a PHP y la gran cantidad de proyectos de PHP disponibles como código abierto es mucho menos intimidante para alguien que ingresa al mundo del desarrollo y, como usted, puede ser un trampolín hacia lenguajes más maduros.

No debatiré las cuestiones técnicas que muchos tienen antes que yo, pero si miras PHP como una comunidad en lugar de un lenguaje web, una comunidad que claramente te abrazó cuando comenzaste a desarrollar, los beneficios realmente hablan por sí mismos.

Chris Ridenour
fuente
3
Definitivamente un buen comentario. Python fue mi primer idioma y fue increíble, pero la falta de proyectos que me pareció capaz de entender creó una barrera. Con PHP puedo buscar casi cualquier cosa en la documentación y resolverla ... los recursos disponibles en la web son increíbles.
dscher
76

¡Variables variables y funciones sin duda!

$foo = 'bar';
$bar = 'foobar';
echo $$foo;    //This outputs foobar

function bar() {
    echo 'Hello world!';
}

function foobar() {
    echo 'What a wonderful world!';
}
$foo();    //This outputs Hello world!
$$foo();    //This outputs What a wonderful world!

El mismo concepto se aplica a los parámetros del objeto ($ some_object -> $ some_variable);

Muy, muy agradable. La codificación de Make con bucles y patrones es muy fácil, y es más rápida y está más controlada que Eval (¡Thanx @Ross & @Joshi Spawnbrood!).

Jrgns
fuente
111
Las variables variables en realidad están haciendo que el código sea menos legible y más propenso a errores.
Elzo Valugi
8
¿Y la gente realmente usa esto? Hombre, odiaría leer estas fuentes.
Gary Willoughby el
27
Las variables variables son una de las peores características que ofrece PHP.
davidtbernal
10
9 De 10 veces las variables variables se reemplazan mejor con matrices para que tenga todos los datos en un solo lugar, puede iterar sobre ellos, etc. Solo en algunas circunstancias muy específicas podrían ser útiles.
Jasper Bekkers
77
No hagas que los novatos usen esa "característica".
whiskeysierra
68

Puede usar funciones con un número indefinido de argumentos usando func_get_args().

<?php

function test() {

    $args = func_get_args();
    echo $args[2]; // will print 'd'
    echo $args[1]; // will print 3
}

test(1,3,'d',4);

?>
TheBrain
fuente
1
Estaba a punto de publicar esto. Algo así como la propiedad de argumentos en las funciones JS.
alex
67

Me encantan los archivos remotos . Para el desarrollo web, este tipo de característica es excepcionalmente útil.

¿Necesita trabajar con los contenidos de una página web? Un simple

$fp = fopen('http://example.com');

y tiene un identificador de archivo listo para usar, como cualquier otro archivo normal.

¿O qué tal leer un archivo remoto o una página web directamente en una cadena?

$str = file_get_contents('http://example.com/file');

La utilidad de este método en particular es difícil de exagerar.

¿Quieres analizar una imagen remota? ¿Qué tal hacerlo a través de FTP?

$imageInfo = getimagesize('ftp://user:[email protected]/image/name.jpg');

Casi cualquier función PHP que funcione con archivos puede funcionar con un archivo remoto. Incluso puede include()o require()archivos de código de forma remota de esta manera.

zombat
fuente
2
¡Esto es muy lindo! Para hacer esto, por ejemplo, en Java, debe incluir una gran cantidad de archivos jar y luego escribir mucho código repetitivo.
Kimble
16
"Incluso puede incluir () o requerir () archivos de código de forma remota de esta manera". Por supuesto, incluir () un archivo en un servidor que no controlas es una idea terrible, terrible.
Frank Farmer
44
@Frank - Sí, bueno, uno podría suponer que usted estaría incluido el código de un servidor que hizo el control.
zombat
1
El punto es que la inclusión remota de archivos es un problema de seguridad PHP común: en.wikipedia.org/wiki/Remote_File_Inclusion#PHP .
Frank Farmer,
63

strtr ()

Es extremadamente rápido, tanto que te sorprendería. Internamente, probablemente utiliza alguna estructura de tipo b-tree loco para organizar sus coincidencias por sus prefijos comunes. Lo uso con más de 200 cadenas de búsqueda y reemplazo y todavía pasa por 1 MB en menos de 100 ms. Para todas las cadenas, excepto trivialmente pequeñas, strtr () es incluso significativamente más rápido que strtolower () para hacer exactamente lo mismo, incluso teniendo en cuenta el conjunto de caracteres. Probablemente podría escribir un analizador completo utilizando llamadas strtr sucesivas y sería más rápido que la coincidencia de expresión regular habitual, averiguar el tipo de token, generar esto o aquello, el siguiente tipo de expresión regular.

Estaba escribiendo un normalizador de texto para dividir el texto en palabras, minúsculas, eliminar signos de puntuación, etc. y strtr era mi navaja suiza, superaba a los pantalones con expresiones regulares o incluso str_replace ().

thomasrutter
fuente
1
Probablemente sea más rápido porque hace reemplazos de un solo carácter.
staticsan
10
strtr () no solo realiza reemplazos de un solo carácter. Puede reemplazar las subcadenas de longitud arbitraria con otras subcadenas de longitud arbitraria, y todavía parece muy rápido.
thomasrutter
1
Mencionaste que era más rápido que strtolower en algunos casos, ¿puedes probarlo? Hice un pequeño punto de referencia y me pareció falso.
The Pixel Developer
1
Descubrí que en cadenas pequeñas de, digamos, 80 caracteres, era más lento que strtolower, y en cadenas grandes de, digamos, 1 MB, era más rápido. Probablemente haya algún tipo de costo fijo general cada vez que se llama. Simplemente estaba usando strtr ($ this-> string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); La cadena en la que estaba operando era un texto típico en inglés ("El zorro marrón rápido", ese tipo de cosas).
thomasrutter
Acabo de leer esta publicación y luego busqué en Google y encontré: simplemachines.org/community/index.php?topic=175031.0 ¿ Alguna idea de cuál es la correcta?
Flipper
61

Una característica no tan conocida de PHP es extract(), una función que desempaqueta una matriz asociativa en el espacio de nombres local. Esto probablemente existe para la aborto autoglobal, pero es muy útil para crear plantillas:

function render_template($template_name, $context, $as_string=false)
{
    extract($context);
    if ($as_string)
        ob_start();
    include TEMPLATE_DIR . '/' . $template_name;
    if ($as_string)
        return ob_get_clean();
}

Ahora puede usar render_template('index.html', array('foo' => 'bar'))y solo $foocon el valor "bar"aparece en la plantilla.

Armin Ronacher
fuente
15
Me enojaría contigo por sugerir que extract () de alguna manera fuera una buena característica. Pero supongo que su uso es bastante útil. ¡Supongo que es la única vez que lo he visto usar donde es una buena idea!
thomasrutter
55
extract () hace que sea muy sencillo rodar su propio sistema de plantillas extremadamente ligero. +1
Dinah
14
Su inverso, compacto (), también es bueno: $ a = 1; $ b = 2; compacto ('a', 'b'); // == array ('a' => $ a, 'b' => $ b)
Annika Backstrom el
2
Sí, ese es probablemente el único uso realmente bueno de extract ().
staticsan
44
Sugeriría no usar palabras comunes como nombres de argumentos de función en este caso, ya que el contexto $ del que extrae () podría contener valores en los índices 'as_string' o 'template_name'. Usar EXTR_SKIP es aceptable, pero solo mueve el problema a otra parte (es decir, si la plantilla espera un $ as_string obtendrá el valor incorrecto).
Michał Tatarynowicz 03 de
52

Range () no está oculto per se, pero todavía veo mucha gente iterando con:

for ($i=0; $i < $x; $i++) { 
    // code...
}

cuando podrían estar usando:

foreach (range(0, 12) as $number) {
    // ...
}

Y puedes hacer cosas simples como

foreach (range(date("Y"), date("Y")+20) as $i)
{
print "\t<option value=\"{$i}\">{$i}</option>\n";
}
Darren Newton
fuente
3
puedes hacer foreach ($ array como $ key => $ value) {} que es aún más simple.
SilentGhost
15
Puede ser una microoptimización, pero vale la pena señalar que por un tiempo son mucho más rápidos y requieren menos memoria que foreach.
JAL
3
Deberías probar Python. Es tan simple como "for i in range (12)", o puede usar el xrange más eficiente.
Ponkadoodle
2
@SilentGhost: aún necesitaría una matriz para comenzar, lo cual no siempre es el caso. @Newbie: ¿elaborado por favor?
Alec
1
@flexxy, aparentemente, NO lo es. Considere esto: phpbench.com desplácese hacia abajo Read Loop.
Amigo
44

El espacio web habilitado para PHP suele ser menos costoso que algo con (asp) .net. Usted puede llamar a eso una característica ;-)

VolkerK
fuente
3
También es mucho más barato configurar varios servidores si no tiene que pagar por Windows Server en cada uno.
MiffTheFox
44
El único lugar que conozco donde Windows es rentable es en una universidad que obtiene descuentos de DETENCIÓN en el software del servidor en la medida en que es más barato para mi departamento comprar 100 copias de Windows que capacitar a nuestros administradores en Linux (que parcialmente me entristece pero su configuración de Windows está limpia y bien configurada).
dcousineau
44
Por ahora, pero hay que hacer el cambio solo una vez, mientras que usted tiene que comprar nuevas licencias, tarde o temprano ...
e-satis
42

La staticpalabra clave es útil fuera de un punto de vista de OOP. Puede implementar rápida y fácilmente la 'memorización' o el almacenamiento en caché de funciones con algo tan simple como:

<?php
function foo($arg1)
{
    static $cache;

    if( !isset($cache[md5($arg1)]) )
    {
        // Do the work here
        $cache[md5($arg1)] = $results;
    }

    return $cache[md5($arg1)];
}
?>

La staticpalabra clave crea una variable que persiste solo dentro del alcance de esa función después de la ejecución. Esta técnica es ideal para funciones que afectan a la base de datos get_all_books_by_id(...)o get_all_categories(...)que llamaría más de una vez durante una carga de página.

Advertencia: asegúrese de encontrar la mejor manera de hacer una clave para su hash, en casi todas las circunstancias lo md5(...)anterior NO es una buena decisión (problemas de velocidad y longitud de salida), lo usé con fines ilustrativos. sprintf('%u', crc32(...))o spl_object_hash(...)puede ser mucho mejor dependiendo del contexto.

revs dcousineau
fuente
77
Solo una función copiada de C / C ++
GetFree
2
@GetFree Yo no creo que nadie puede negar que la casi totalidad de PHP ha sido copiado de C, C ++, Perl, etc
Frank Farmer
1
Copiar es lo mejor que se puede hacer.
NikiC
1
Mal PHP. Siempre está copiando características de otros. ¡Debería escribir todo desde cero! (En el caso de la más mínima posibilidad de que esto se tome en serio: estoy bromeando)
Halil Özgür
42

Una buena característica de PHP es la CLI . No está tan "promocionado" en la documentación, pero si necesita scripts de rutina / aplicaciones de consola, ¡usar cron + php cli es realmente rápido de desarrollar!

Lucacri
fuente
Realmente debería investigar esto, tengo varios trabajos cron que obtienen un script PHP a través dewget http://example.com...
DisgruntledGoat
La CLI también es una excelente manera de depurar, ya que las advertencias / errores se mostrarán sin que tenga que cambiar sus preferencias de informes de errores.
Glaciales
40

Luego truco "e imprimir"

<?php $flag and print "Blah" ?>

Se hará eco de Blah si $ flag es verdadero. NO FUNCIONA CON ECHO.

Esto es muy útil en la plantilla y reemplazar el? : que no son realmente fáciles de leer.

e-satis
fuente
24
Yo mismo encuentro que el operador ternario es mucho más obvio que explotar el cortocircuito de evaluación de una lógica y.
Vicent Marti
26
En realidad, esa es la misma cantidad de caracteres que <? Php if ($ flag) imprime "Blah"
demasiado php
3
Los paréntesis no son tan fáciles de escribir como "y", especialmente en mi maldito teclado francés ;-)
e-satis
77
@todos los comentarios - ¡No se trata de lo corto que puedes conseguirlo! Se trata de legibilidad y facilidad de uso para las personas de plantilla, que a veces ni siquiera son programadores.
Tor Valamo
66
Yo comentaría que la declaración if () es más fácil y más legible. Ciertamente es más fácil para mí entender que explotar esencialmente un efecto secundario del operador 'y' en PHP, donde es fácil cometer un error (o parece que es un error cuando lees el código más adelante). Por ejemplo, como se indicó, esto no funcionará de la manera que desee con 'echo'. Con if () no hay trucos como este.
thomasrutter
37

Puede usar el carácter menos en nombres de variables como este:

class style
{
  ....
  function set_bg_colour($c)
  {
    $this->{'background-color'} = $c;
  }
}

¿Por qué usarlo? No tengo idea: ¿tal vez para un modelo CSS? O algún JSON extraño que necesites generar. Es una característica extraña :)

monk-e-boy
fuente
2
¿Funciona con nombres de métodos? Podría ser útil para frameworks que usan un enrutador y quiero domain.com/something-with-minuses/view/
alex
66
Las llaves se permiten acceder a propiedades de objetos que tienen guiones, puntos y otras entidades no alfanuméricas. Una razón para usarlo es cuando se trata con xml, donde los nombres de entidad se pueden puntear como en NITF / NewsML <body.content>. Si usa SimpleXML, accedería de esta manera $item->DataContent->body->{'body.content'}.
Jesse Kochis
2
Las variables PHP pueden tomar cualquier carácter cuando se usa de esa manera, incluso espacios y líneas nuevas.
Novato
Esto sería muy útil cuando se usa en SimpleXML ... increíble. Gracias por compartir.
KyleFarris
34

La sintaxis de HEREDOC es mi característica oculta favorita. Siempre es difícil de encontrar, ya que no puedes buscar en Google <<< pero evita que tengas que escapar de grandes fragmentos de HTML y aún te permite colocar variables en la secuencia.

echo <<<EOM
  <div id="someblock">
    <img src="{$file}" />
  </div>
EOM;
Pablo Livardo
fuente
2
HEREDOC es mi forma favorita de construir y usar sentencias SQL.
bdl
11
Nota: la MOE de cierre; No se puede sangrar.
micahwittman
Bien, pero no tiene sentido si usa plantillas. Además, se interpone en el camino de la sangría adecuada.
Manos Dilaverakis
77
Querido Dios, ese es el código más feo que he visto. Si está utilizando HEREDOC, entonces no ha separado la presentación de la lógica.
Lotus Notes
@Byron: No tiene que usarlo para la presentación, puede usarse para cualquier cadena. Ver el comentario de bdl.
Tom Pažourek
34

Probablemente no muchos sepan que es posible especificar "variables" constantes como valores predeterminados para los parámetros de función:

function myFunc($param1, $param2 = MY_CONST)
{
//code...
}

Las cadenas se pueden usar como si fueran matrices :

$str = 'hell o World';
echo $str; //outputs: "hell o World"

$str[0] = 'H';
echo $str; //outputs: "Hell o World"

$str[4] = null;
echo $str; //outputs: "Hello World"
jamolkhon
fuente
3
Ese último es ingenioso. Aunque no tengo idea de cuándo sería mejor que algún otro método para eliminar un personaje. +1 no obstante
George Mauer
3
Probablemente sea más eficiente que llamar a una función para hacerlo. Las cadenas se almacenan normalmente de forma contigua en la memoria, por lo que llegar a $ str [4] es trivial. El almacenamiento de cadenas como matrices de caracteres es común a la mayoría de los idiomas que derivan de C.
sjobe
1
No tiene que usar una constante definida como valor predeterminado. Lo siguiente también es perfectamente válido: función pie ($ param1, $ default = array ('key' => 'value'), $ default_s = 'String', $ default_i = 10, $ default_b = false). Sin embargo, tiene razón al señalar que no puede usar una variable como argumento predeterminado.
dcousineau
@dcousineau Su ejemplo es perfectamente válido ya que array () no es una función sino una construcción de lenguaje. Las llamadas a funciones no están permitidas como valores predeterminados para los argumentos.
Jamol
44
Tenga cuidado al tratar las cadenas como matrices si tiene cadenas de varios bytes (idiomas extranjeros, etc.)
philfreo
33

Lo más útil del código PHP es que si no entiendo una función, veo que puedo buscarla usando un navegador y escribiendo:

http://php.net/function

El mes pasado vi la función "rango" en algún código. Es una de las cientos de funciones que nunca pude usar, pero resultó ser realmente útil:

http://php.net/range

Esa url es un alias para http://us2.php.net/manual/en/function.range.php . Esa idea simple, de funciones de mapeo y palabras clave para URL , es increíble.

Deseo que otros idiomas, marcos, bases de datos, sistemas operativos tengan un mecanismo tan simple para buscar documentación.

artlung
fuente
55
range()puede ser útil paraforeach( range(1, 10) as $i) { };
alex
Si tienes Firefox; simplemente escriba PHP functionen la barra de direcciones, hará una búsqueda en Google 'Me siento afortunado' y casi siempre termina en la página de documentación de php correcta.
Kolky
30

Comentarios rápidos de bloque

/*
    die('You shall not pass!');
//*/


//*
    die('You shall not pass!');
//*/

Estos comentarios le permiten alternar si un bloque de código se comenta con un carácter.

Sam152
fuente
14
Esto no es realmente específico de PHP. Esto funciona en cualquier idioma que admita // ...comentarios de línea y /* ... */comentarios de bloque.
Jordan Ryan Moore, el
cualquier utilidad de limpieza de código termina odiándote por usar esto ...;)
Talvi Watia
3
También he usado /** /antes y /**/después. Puede alternar el bloque eliminando y agregando el espacio en el primero. Esto tiene una ventaja adicional de trabajar con CSS (y otros idiomas que no admiten // ... comentarios).
kingjeffrey
FWIW, enlace al artículo original aleembawany.com/2009/01/27/lazy-block-comment-trick
aleemb
@aleemb, abstenerse de realizar más modificaciones a esta pregunta.
Sam152
29

Mi lista ... la mayoría de ellos se encuentran más en las "características ocultas" que en las "características favoritas" (¡espero!), Y no todas son útiles, pero ... sí.

// swap values. any number of vars works, obviously  
list($a, $b) = array($b, $a);

// nested list() calls "fill" variables from multidim arrays:  
$arr = array(  
  array('aaaa', 'bbb'),  
  array('cc', 'd')  
);  
list(list($a, $b), list($c, $d)) = $arr;  
echo "$a $b $c $d"; // -> aaaa bbb cc d  

// list() values to arrays  
while (list($arr1[], $arr2[], $arr3[]) = mysql_fetch_row($res)) { .. }  
// or get columns from a matrix  
foreach($data as $row) list($col_1[], $col_2[], $col_3[]) = $row;

// abusing the ternary operator to set other variables as a side effect:  
$foo = $condition ? 'Yes' . (($bar = 'right') && false) : 'No' . (($bar = 'left') && false);  
// boolean False cast to string for concatenation becomes an empty string ''.  
// you can also use list() but that's so boring ;-)  
list($foo, $bar) = $condition ? array('Yes', 'right') : array('No', 'left');

También puede anidar operadores ternarios, a veces resulta útil.

// the strings' "Complex syntax" allows for *weird* stuff.  
// given $i = 3, if $custom is true, set $foo to $P['size3'], else to $C['size3']:  
$foo = ${$custom?'P':'C'}['size'.$i];  
$foo = $custom?$P['size'.$i]:$C['size'.$i]; // does the same, but it's too long ;-)  
// similarly, splitting an array $all_rows into two arrays $data0 and $data1 based  
// on some field 'active' in the sub-arrays:  
foreach ($all_rows as $row) ${'data'.($row['active']?1:0)}[] = $row;

// slight adaption from another answer here, I had to try out what else you could  
// abuse as variable names.. turns out, way too much...  
$string = 'f.> <!-? o+';  
${$string} = 'asdfasf';  
echo ${$string}; // -> 'asdfasf'  
echo $GLOBALS['f.> <!-? o+']; // -> 'asdfasf'  
// (don't do this. srsly.)

${''} = 456;  
echo ${''}; // -> 456  
echo $GLOBALS['']; // -> 456  
// I have no idea.  

Bien, me detendré por ahora :-)


Hmm, ha pasado un tiempo ...

// just discovered you can comment the hell out of php:
$q/* snarf */=/* quux */$_GET/* foo */[/* bar */'q'/* bazz */]/* yadda */;

Entonces, acabo de descubrir que puede pasar cualquier cadena como nombre de método SI la encierra con llaves. No puede definir ninguna cadena como método, por desgracia, pero puede atraparlas con __call () y procesarlas aún más según sea necesario. Hmmm ...

class foo {
  function __call($func, $args) {
    eval ($func);
  }
}

$x = new foo;
$x->{'foreach(range(1, 10) as $i) {echo $i."\n";}'}();

Encontré esta pequeña joya en los comentarios de Reddit:

$foo = 'abcde';
$strlen = 'strlen';
echo "$foo is {$strlen($foo)} characters long."; // "abcde is 5 characters long."

No puede llamar a las funciones dentro de {} directamente de esta manera, ¡pero puede usar variables-holding-the-function-name y llamarlas! (* y * también puedes usar variables variables en él)

MSpreij
fuente
2
No utilice en exceso el operador de comparación ternario; Esto lleva a la ofuscación del código.
staticsan
Guau. Eso podría controlar tu lista de $ GLOBALS. Mala práctica. Seriamente.
Talvi Watia
¿Ya hay un concurso de PHP ofuscado?
Lotus Notes
Bueno, truco con intercambio: impresionante y útil, gracias.
OZ_
1
${''} = 456;jajaja .... todo el abuso.
Skurmedel
26

Manipulación de matrices.
Toneladas de herramientas para trabajar y manipular matrices. Puede que no sea exclusivo de PHP, pero nunca he trabajado con un lenguaje que lo haya hecho tan fácil.

MattBelanger
fuente
como que por ejemplo? Me parece que todas las funciones se nombran y colocan de manera extraña en el espacio de nombres global. Además, no puedo pensar en nada que no sea tan fácil en otro idioma, excepto tal vez $ arr [] = $ newvalue para agregar valores, eso es genial
George Mauer el
8
Bueno, la matriz PHP es una estructura de datos que se puede usar fácilmente como una pila, cola, deque, lista, tabla hash, etc. Es bastante flexible para las necesidades más comunes, sin recurrir a nada más que a las funciones array_ *.
Camilo Díaz Repka
66
Python hace arreglos (como listas y tuplas) mucho mejor que PHP.
demasiado php
26

Soy un poco como tú, he codificado PHP por más de 8 años. Tuve que tomar un curso .NET / C # hace aproximadamente un año y realmente disfruté el lenguaje C # (odiaba ASP.NET) pero me convirtió en un mejor desarrollador de PHP.

PHP como lenguaje es bastante pobre, pero soy extremadamente rápido con él y la pila de LAMP es increíble. El producto final supera con creces la suma de las partes.

Dicho esto, en respuesta a tu pregunta:

http://uk.php.net/SPL

Me encanta el SPL , la clase de colección en C # fue algo que me gustó tan pronto como comencé con él. Ahora puedo tener mi pastel y comerlo.

Andrés

Andrew Taylor
fuente
24

Estoy un poco sorprendido de que nadie lo haya mencionado todavía, pero uno de mis trucos favoritos con las matrices es usar el operador plus. Es un poco como array_merge()pero un poco más simple. He descubierto que generalmente es lo que quiero. En efecto, toma todas las entradas en el RHS y las hace aparecer en una copia del LHS, sobrescribiendo según sea necesario (es decir, no es conmutativo). Muy útil para comenzar con una matriz "predeterminada" y agregar algunos valores reales en un solo golpe, mientras se dejan los valores predeterminados para los valores no proporcionados.

Código de muestra solicitado:

// Set the normal defaults.
$control_defaults = array( 'type' => 'text', 'size' => 30 );

// ... many lines later ...

$control_5 = $control_defaults + array( 'name' => 'surname', 'size' => 40 );
// This is the same as:
// $control_5 = array( 'type' => 'text', 'name' => 'surname', 'size' => 40 );
staticsan
fuente
$defaultsdebería ser$control_defaults
diEcho
3
Creo que no es tan claro como array_merge cuando tienes mucho código para mantener. Al menos, cuando usa la función array_merge, es evidente que se trata de matrices.
Sylvain
¿Y ese hecho que estás haciendo ... + array( ...no es suficiente para señalar esto? :-)
staticsan
¿Qué versión de PHP necesitas para esto?
Lotus Notes
Esta es una gran característica y debe tenerse en cuenta que la matriz en el lado "derecho" de "+" no sobrescribirá las teclas existentes de la matriz en el lado "izquierdo" de "+".
Wil Moore III
21

Aquí hay uno, me gusta cómo establecer valores predeterminados en los parámetros de función que no se proporcionan es mucho más fácil:

function MyMethod($VarICareAbout, $VarIDontCareAbout = 'yippie') { }
George Mauer
fuente
44
Curiosamente, vi esta "característica oculta" en Google Reader la semana pasada. No entiendo qué hay oculto al respecto: es una sintaxis básica. Pruebe if ($ var = true) por ejemplo.
Ross
8
¿Más fácil que qué? La mayoría de los idiomas tienen esta característica.
Christian Davén
10
Más fácil que C # (y creo que C ++ y Java)
George Mauer
8
C ++ admite valores de parámetros predeterminados.
sjobe
2
C # no admite valores predeterminados en absoluto. usted tiene que escribir una función sobrecargada y siempre declarar el valor que es simplemente engorroso
DeveloperChris
21

Rápido y sucio es el valor predeterminado.
El lenguaje está lleno de atajos útiles. Esto hace que PHP sea el candidato perfecto para proyectos (pequeños) que tienen poco tiempo de comercialización. No es que el código PHP limpio sea imposible, solo requiere un esfuerzo extra y experiencia.

Pero me encanta PHP porque me permite expresar lo que quiero sin escribir un ensayo.

PHP:

if (preg_match("/cat/","one cat")) {
   // do something
}

JAVA:

import java.util.regex.*;
Pattern p = Pattern.compile("cat");
Matcher m = p.matcher("one cat")
if (m.find()) {
  // do something
}

Y sí, eso incluye no escribir Int .

Bob Fanger
fuente
44
debería usar strpos en su lugar: if (false! == strpos ("one cat", "cat")) {
OIS
17
@OIS el propósito de su ejemplo fue ilustrar y comparar la ejecución de una coincidencia rápida de expresiones regulares, no cómo encontrar la cadena "cat" en "one cat".
dcousineau
19
Java: if (Pattern.matches ("cat", "one cat")) {// haz algo} Deja de quejarte de java si no lo sabes.
whiskeysierra
3
+1 Willi, ¿cómo haces preg_replace ('/ ([<[]! - \ s *) (\ S *?) (\ S * - [>]]?) / Se', "\ $ this- > Elija ('\\ 1', '\\ 2', '\\ 3', \ $ data) ", $ text); en Java Esto encuentra un comentario en el texto de entrada y luego llama a una función con los elementos coincidentes que en este caso $ this-> choose (...) decide con qué reemplazar la coincidencia y devuelve los resultados.
DeveloperChris
1
Regex es PHP es bastante malo ... Prefiero tener Regex estilo Perl o JavaScript donde //está integrado en el lenguaje.
cdmckay