Caratteristiche nascoste di PHP? [chiuso]


174

So che sembra una domanda pungente, ma lasciami spiegare da dove vengo.

Fuori dal college ho trovato lavoro in un negozio PHP. Ho lavorato lì per un anno e mezzo e ho pensato di aver imparato tutto ciò che c'era da sapere sulla programmazione.

Poi ho ottenuto un lavoro come negozio di sviluppo interno individuale presso una grande azienda in cui tutto il lavoro era in C #. Nel mio impegno per la posizione ho iniziato a leggere un sacco di blog e libri e ho subito capito quanto mi sbagliavo a pensare di sapere tutto. Ho imparato a conoscere i test unitari, l'iniezione delle dipendenze e i motivi del decoratore, il principio di progettazione dell'accoppiamento libero, la composizione sul dibattito sull'ereditarietà e così via e così via - Sto ancora assorbendo moltissimo tutto. Inutile dire che il mio stile di programmazione è cambiato completamente nell'ultimo anno.

Ora mi ritrovo a raccogliere un progetto php facendo un po 'di codice per lo start-up di un amico e mi sento completamente limitato rispetto alla programmazione in C #. Mi disturba davvero il fatto che tutte le variabili nell'ambito di una classe debbano essere citate aggiungendo '$ this->'. Mi dà fastidio che nessuno degli IDE che ho provato abbia un ottimo intellisense e che i miei metodi di test unitari SimpleTest debbano iniziare con la parola "test". Mi fa impazzire il fatto che la digitazione dinamica mi impedisca di specificare implicitamente quale tipo di parametro si aspetta un metodo e che devi scrivere un'istruzione switch per fare sovraccarichi di metodo. Non sopporto che non puoi avere spazi dei nomi nidificati e che devi usare l'operatore :: per chiamare il costruttore della classe base.

Ora non ho intenzione di iniziare un dibattito tra PHP e C #, ma quello che intendo dire è che sono sicuro che ci sono alcune funzionalità di PHP che non conosco o che conosco ma che non riesco a usare correttamente. Sono ambientato nel mio universo C # e ho problemi a vedere fuori dalla ciotola di vetro.

Quindi ti sto chiedendo, quali sono le tue funzionalità preferite di PHP? Quali sono le cose che puoi fare in esso che non puoi o sono più difficili nelle lingue .Net?


Paradigma OO rotto? Per me è la peggior caratteristica "nascosta" che scopri.
Knoopx,

Questi thread sono abbastanza divertenti ... Perché per il team che lavoro con "funzionalità nascosta" è una frase in codice che significa "bug". E sai cosa ... A volte scoprire una funzione nascosta non è necessariamente una buona cosa ...
Ganesh Shankar

@Ganesh il bug di un uomo è un'altra caratteristica nascosta
dell'uomo

Risposte:


328

Documentazione . La documentazione ottiene il mio voto. Non ho trovato una documentazione online più approfondita per un linguaggio di programmazione - tutto il resto che devo mettere insieme da vari siti Web e pagine man.


60
Sono d'accordo. Essere in grado di digitare www.php.net/function_name e ottenere un riferimento il più delle volte è fantastico.
Allain Lalonde,

1
Questa è una grande caratteristica di PHP, ma non la definirei davvero nascosta ... Se avessi mai cercato su Google i parametri del metodo, ecc., Finiresti su php.net.
John Bubriski

27
Sono anche d'accordo. La cosa più bella del manuale sono i commenti degli utenti. Raramente ho visto altre documentazioni avere quelle. Possono contenere vere gemme. L'unico aspetto negativo è che IMHO hanno potato un po 'troppo presto.
Sander Marechal,

3
@Phoexo "un po 'meno leggibile" ??? Non ho mai capito e non capirò mai MSDN, mentre i documenti PHP sono facili e chiari.
lauriys,

3
Disaccordo. L'unico motivo per cui la documentazione è "buona" è a causa di alcuni dei commenti degli utenti che collegano tutti i buchi nelle note ufficiali.
Rob Howard,

179

Array . A giudicare dalle risposte a questa domanda, non credo che le persone apprezzino appieno quanto siano semplici e utili gli array in PHP. Gli array PHP fungono contemporaneamente da elenchi, mappe, stack e strutture di dati generici. Le matrici sono implementate nel core della lingua e sono utilizzate ovunque, il che si traduce in una buona posizione della cache della CPU. Perl e Python usano entrambi costrutti di linguaggio separati per elenchi e mappe, risultando in più copie e trasformazioni potenzialmente confuse.


11
Gli elementi dell'array PHP sono ordinati.
user8134,

117
Il mio passaggio iniziale da PHP a C # mi ha quasi ucciso. In C #, le matrici sono solo una struttura semplice con dimensioni statiche e indice numerico. In PHP, gli array sono il nastro isolante dell'universo!
Dinah,

4
Sono anche d'accordo. Quando giocavo con Java per un incarico Uni, rimasi sbalordito da quanto fossero rigidi, nessuna flessibilità. Mi ha fatto davvero apprezzare quanto siano buoni gli array di PHP.
Christian,

11
Sono sicuro che gli array php sono fantastici, ma 40 voti per il commento che bussa agli array C #? Se un array C # non soddisfa le necessità, ci sono molte opzioni. ArrayList e raccolte generiche sono entrambi molto potenti. Esistono numerosi tipi di collezioni per esigenze specifiche. L'unico vero vantaggio di PHP a questo proposito è che non offre alcuna opzione da cui un programmatore deve decidere. O usi l'array o non hai una variabile indicizzabile.
G-Wiz,

24
D'altra parte, la sintassi per le matrici fa schifo completamente. In molti linguaggi di scripting è possibile creare un semplice array 2D in questo modo: [[1, 2], [3, 4]], confrontare questo alla versione di PHP: array(array(1, 2), array(3, 4)).
Rene Saarsoo,

167

I gestori di stream ti consentono di estendere il "FileSystem" con una logica che, per quanto ne so, è abbastanza difficile da fare nella maggior parte delle altre lingue.

Ad esempio con il gestore di flussi MS-Excel è possibile creare un file MS Excel nel modo seguente:

$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);

Credo che anche il framework KIO ti consenta di farlo, ma è disponibile solo per le applicazioni desktop basate su KDE.
MiffTheFox,

21
IMHO con un approccio OO adeguato sarebbe molto più sensato di questo pasticcio con i gestori di stream. Sì, è carino poter leggere / scrivere file Excel, ma deve funzionare in questo modo?
Anti Veeranna,

3
Forse è così, ma questo approccio incapsula la complessità in un'interfaccia comune alla maggior parte degli sviluppatori PHP ... senza richiedere loro di apprendere concetti orientati agli oggetti che potrebbero essere al di là di essi.
Allain Lalonde,

13
Se lavori con Amazon S3, dai un'occhiata a Zend_Amazon_S3, che fornisce un'interfaccia di streaming per URL come 's3: // {bucket-name} / path'.
davidtbernal,

Ho usato questo per creare un semplice DSL per il mio livello di visualizzazione semplicemente leggendo il file PHP, facendo un po 'di sostituzione della stringa e passando attraverso eval (). Ad esempio, l'ho reso tale da poter utilizzare i tag brevi ogni volta che scelgo e faccio @ -> someVar in modo da poter accedere ai dati a livello di vista.
Jasper Bekkers,

131

I metodi magici sono metodi fall-through che vengono chiamati ogni volta che invochi un metodo che non esiste o assegni o leggi una proprietà che non esiste, tra le altre cose.

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);
}

A C ++ sviluppatore qui potrebbe notare, che PHP permette di sovraccaricare alcuni operatori, ad esempio, ()o (string). In realtà PHP consente di sovraccaricare ancora di più, ad esempio l' []operatore ( ArrayAccess ), il foreachcostrutto del linguaggio ( Iterator e IteratorAggregate ) e la countfunzione ( numerabile ).


4
Come esempio utile di ciò che può essere ottenuto con i metodi magici, vai a phpcodetips.blogspot.com/2008/07/domain-model-validation.html
grom,

6
Disaccordo. Questo è molto più debole di strutture simili in Smalltalk, Ruby & Python (e presumibilmente è stato copiato da uno di questi)
finnw,

34
Il fatto che l'implementazione di PHP di questa funzionalità sia più debole di quelle di altre lingue, non lo rende meno utile in PHP.
Allain Lalonde,

2
__call()è fantastico nei framework con map domain.com/controller/method/
alex

7
I metodi magici sono anche lenti come l'inferno. Usali attentamente.
Alex Weinstein,

95

La classe standard è un contenitore pulito. L'ho imparato solo di recente.

Invece di utilizzare un array per contenere gli attributi server

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

Puoi usare una classe standard

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

Ciò è particolarmente utile quando si accede a queste variabili in una stringa

$string = $person['name'] . ' is ' . $person['age'] . ' years old.';
// vs
$string = "$person->name is $person->age years old.";

43
"{$ person ['name']} è {$ person ['age']} anni" funziona.
Kornel,

27
"persona [nome] è $ persona [età] anni" funzionerà anche ... Niente virgolette, niente parentesi graffe :)
majelbstoat

16
$ string = sprintf ("% s ha% d anni.", $ person ['name'], $ person ['age']);
Daniel Sloof,

60
Mentre siamo in tema: (oggetto) array ("name" => 'bob', 'age' => 5)
Annika Backstrom,

30
@majelbstoat: l'eliminazione delle virgolette rallenterebbe lo script perché l'interprete PHP cercherà di vedere se 'nome' ed 'età' sono stati impostati con define (...). È anche una cattiva pratica considerando che sarebbe possibile capovolgere totalmente i tasti a cui si accede in ciascun caso: define ('age', 'name'); define ( 'name', 'l'età');
brianreavis,

90

I file di inclusione possono avere un valore di ritorno che è possibile assegnare a una variabile.

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

// index.php
$config = include 'config.php';
echo $config['db']['host']; // example.org

@ Peter MOLTO utile per la gestione degli errori di eccezione db-> localhost.
Talvi Watia,

È comodo per impostare un file di configurazione rapido e sporco.
Frank Farmer,

Perché restituisci questo array? Se un file incluso contiene un array è immediatamente utilizzabile in include.
fabrik,

5
@fabrik perché sarebbe variabile globale e disponibile nell'intero ambito principale. È abbastanza spiacevole, è molto meglio.
Mikulas Dite,

ho lavorato su un progetto nel framework Yii e quel progetto ha un file di configurazione in cui l'array è stato restituito in questo modo, ora capisco perché il file era così.
Simer Twilio Toronto sviluppatore il

83

Puoi trarre vantaggio dal fatto che l' oroperatore ha una precedenza inferiore rispetto =a fare questo:

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

Se il valore della prima assegnazione corrisponde a true, la seconda assegnazione viene ignorata. Un altro esempio:

$record = get_record($id) 
  or throw new Exception("...");

7
Non sono del tutto convinto di questo, penso; anche se sembra non essere soggetto a errori, è controintuitivo e ciò di per sé può promuovere errori.
thomasrutter,

14
@Pies: un modo è il seguente codice piuttosto disordinato per essere onesti: $ page = isset ($ _ GET ['page'])? (int) $ _ GET ['page']: 1; // Il vantaggio è che non è richiesta la soppressione degli errori.
DisgruntledGoat

3
ripensandoci, poiché stai cercando un numero intero che potresti usare invece: $ page = is_int ($ _ GET ['page'])? $ _GET ['page']: 1;
DisgruntledGoat

4
Vale la pena notare che il codice after orverrà eseguito se il codice precedente orrisulta nel valore numerico 0. Quindi semanticamente potrebbe essere meno probabile con qualcosa del genere $_GET['page'], ma ovviamente possono sorgere le circostanze ed è bene fare attenzione.
mancanza di palpebre

3
Vale anche la pena notare che l' oroperatore è una versione precedente precedente ||dell'operatore. Inoltre, +1 perché è altamente espressivo e spesso dimentico che è possibile. Dovrebbe essere usato più spesso ed è assolutamente chiaro in ciò che fa. Non so come codifichi "veri maschi", quindi non posso commentarlo.
ciglia

80

__autoload()(class-) file aiutati da set_include_path().

In PHP5 non è ora necessario specificare lunghi elenchi di istruzioni "include_once" quando si esegue OOP decente.

Basta definire un piccolo set di directory in cui i file della libreria di classi sono strutturati in modo sano e impostare il percorso di inclusione automatica:

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

Ora la __autoload()routine:

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');
}

Ora PHP includerà automagicamente i file necessari su richiesta, risparmiando tempo e memoria di analisi.


spl_autoload_register () è meglio usare?
alex,

19
Ovviamente! __autoload () è PHP4 ma spl_autoload_register () è un "collegamento in cascata" non distruttivo dei metodi di caricamento automatico.
Willem,

3
Una funzionalità utile, ma l'unica avvertenza è quando trovi un'istanza di una data classe, rende un po 'più difficile cercare la posizione di un file di classe. Definire esplicitamente le inclusioni nella parte superiore ti dà un elenco finito di classi coinvolte e la loro posizione esatta.
Cory House,

È una bella funzionalità, ma solo per aggirare la situazione di non avere il codice precompilato, quindi non sa dove sarà la classe. L'aspetto negativo di questo è che non puoi avere 2 classi con lo stesso nome, anche se si trovano in spazi dei nomi diversi.
Kibbee,

3
Dai un'occhiata al propsal PSR-0 del PHP Standards Working Group (con gli sviluppatori di ZF, Symfony, Doctrine, CakePHP, Solar, ecc.) Durante l'implementazione del caricamento automatico: groups.google.com/group/php-standards/web / psr-0-final-proposta
Philippe Gerber,

76

Facilità . La più grande caratteristica è quanto sia facile per i nuovi sviluppatori sedersi e scrivere script "funzionanti" e comprendere il codice.

La caratteristica peggiore è quanto sia facile per i nuovi sviluppatori sedersi e scrivere script "funzionanti" e pensare di capire il codice.

L' apertura della comunità che circonda PHP e l'enorme quantità di progetti PHP disponibili come open source sono molto meno intimidatori per chi entra nel mondo dello sviluppo e come te, può essere un trampolino di lancio verso lingue più mature.

Non discuterò delle cose tecniche come molti prima di me, ma se guardi a PHP come a una comunità piuttosto che a un linguaggio web, una comunità che ti ha abbracciato chiaramente quando hai iniziato a sviluppare, i vantaggi parlano davvero da soli.


3
Sicuramente un bel commento. Python è stata la mia prima lingua ed è stato fantastico, ma la mancanza di progetti che ho sentito in grado di comprendere ha creato una barriera. Con PHP posso cercare praticamente tutto sulla documentazione e capirlo ... le risorse disponibili sul web sono incredibili.
dscher,

76

Variabili e funzioni variabili senza dubbio!

$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!

Lo stesso concetto si applica ai parametri degli oggetti ($ some_object -> $ some_variable);

Molto molto carino. Rendere la codifica con loop e pattern molto semplici ed è più veloce e più sotto controllo di eval (Thanx @Ross & @Joshi Spawnbrood!).


111
le variabili variabili stanno effettivamente rendendo il codice meno leggibile e più soggetto a errori.
Elzo Valugi,

8
E la gente lo usa davvero? Amico, odierei leggere queste fonti.
Gary Willoughby,

27
Le variabili variabili sono una delle peggiori funzionalità offerte da PHP.
davidtbernal,

10
9 Le variabili variabili su 10 vengono sostituite meglio con array in modo da avere tutti i dati in un unico posto, è possibile scorrere su di esso eccetera. Solo in alcune circostanze molto specifiche potrebbero essere utili.
Jasper Bekkers,

7
Per favore, non fare in modo che i neofiti usino quella "caratteristica".
whiskeysierra,

68

È possibile utilizzare le funzioni con un numero indefinito di argomenti utilizzando il 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);

?>

1
Stavo per pubblicare questo. Un po 'come la proprietà argomenti nelle funzioni JS.
alex

67

Adoro i file remoti . Per lo sviluppo Web, questo tipo di funzionalità è estremamente utile.

Devi lavorare con i contenuti di una pagina web? Un semplice

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

e hai un handle di file pronto all'uso, proprio come qualsiasi altro file normale.

O che ne dite di leggere un file remoto o una pagina Web direttamente in una stringa?

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

L'utilità di questo particolare metodo è difficile da sopravvalutare.

Vuoi analizzare un'immagine remota? Che ne dici di farlo tramite FTP?

$imageInfo = getimagesize('ftp://user:password@ftp.example.com/image/name.jpg');

Quasi tutte le funzioni PHP che funzionano con i file possono funzionare con un file remoto. Puoi anche include()o require()codificare i file in remoto in questo modo.


2
È così bello! Per fare questo, ad esempio in Java, è necessario includere un file jar gazillion e scrivere un sacco di codice boilerplate.
Kimble,

16
"Puoi anche includere () o richiedere () file di codice in remoto in questo modo." Ovviamente, includere () ing un file su un server che non controlli è un'idea terribile, terribile.
Frank Farmer,

4
@Frank - sì, beh, avrebbe presumere che si sarebbe compreso il codice da un server che si ha fatto il controllo.
zombat,

1
Il punto è che l'inclusione remota dei file è un problema di sicurezza PHP comune: en.wikipedia.org/wiki/Remote_File_Inclusion#PHP .
Frank Farmer,

63

strtr ()

È estremamente veloce, così tanto che rimarrai stupito. Internamente probabilmente usa una struttura pazza di tipo b-tree per organizzare le partite in base ai loro prefissi comuni. Lo uso con oltre 200 trovare e sostituire stringhe e passa ancora attraverso 1 MB in meno di 100 ms. Per tutte le stringhe, ma banalmente piccole, strtr () è anche significativamente più veloce di strtolower () nel fare esattamente la stessa cosa, anche tenendo conto del set di caratteri. Probabilmente potresti scrivere un intero parser usando successive chiamate strtr e sarebbe più veloce della solita corrispondenza di espressioni regolari, capire il tipo di token, produrre questo o quello, il prossimo tipo di espressione regolare.

Stavo scrivendo un normalizzatore di testo per dividere il testo in parole, minuscole, rimuovere punteggiatura ecc. E strtr era il mio coltellino svizzero, ha battuto i pantaloni dalle espressioni regolari o addirittura str_replace ().


1
Probabilmente è più veloce perché sostituisce i singoli caratteri.
staticsan,

10
strtr () non esegue semplicemente sostituzioni di caratteri singoli. Può sostituire sottostringhe di lunghezza arbitraria con altre sottostringhe di lunghezza arbitraria e sembra comunque molto veloce.
thomasrutter,

1
Hai detto che in alcuni casi è stato più veloce di Strtolower, puoi dimostrarlo? Ho fatto un piccolo benchmark e l'ho trovato falso.
The Pixel Developer

1
Ho scoperto che su stringhe piccole di 80 caratteri era più lenta di quelle più potenti e su stringhe grandi di 1 MB era più veloce. Probabilmente c'è un overhead di tipo a costo fisso ogni volta che viene chiamato. Stavo semplicemente usando strtr ($ this-> string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); La stringa su cui stavo operando era un tipico testo inglese ("The quick brown fox", quel genere di cose).
Thomas Rutter

Ho appena letto questo post e poi ho fatto una ricerca su Google e ho trovato: simplemachines.org/community/index.php?topic=175031.0 Qualche idea su quale sia giusto?
Flipper

61

Una caratteristica non molto nota di PHP è extract(), una funzione che decomprime un array associativo nello spazio dei nomi locale. Questo probabilmente esiste per l'aborminazione autoglobale ma è molto utile per il templating:

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();
}

Ora puoi usare render_template('index.html', array('foo' => 'bar'))e solo $foocon il valore "bar"appare nel modello.


15
Mi sarei arrabbiato con te per aver suggerito che extract () in qualche modo fosse una buona caratteristica. Ma immagino che usarlo sia abbastanza utile. Suppongo sia l'unica volta che l'ho visto usato dove è una buona idea!
thomasrutter,

5
extract () semplifica notevolmente il rotolamento del proprio sistema di templating estremamente leggero. +1
Dinah,

14
Anche il suo inverso, compatto (), è carino: $ a = 1; $ b = 2; compatto ('a', 'b'); // == array ('a' => $ a, 'b' => $ b)
Annika Backstrom,

2
Sì, è probabilmente l'unico uso davvero efficace di extract ().
staticsan,

4
Suggerirei di non usare parole comuni come nomi di argomenti di funzioni in questo caso, poiché il contesto $ da cui estrai () potrebbe contenere valori negli indici 'as_string' o 'template_name'. L'uso di EXTR_SKIP è accettabile, ma sposta il problema solo altrove (ovvero se il modello prevede un $ as_string otterrà il valore errato per esso.)
Michał Tatarynowicz,

52

Range () non è nascosto di per sé, ma vedo ancora molte persone che ripetono:

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

quando potrebbero usare:

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

E puoi fare cose semplici come

foreach (range(date("Y"), date("Y")+20) as $i)
{
print "\t<option value=\"{$i}\">{$i}</option>\n";
}

3
puoi fare foreach ($ array come $ key => $ value) {} che è ancora più semplice.
SilentGhost,

15
Potrebbe essere una micro-ottimizzazione, ma vale la pena notare che per e mentre sono molto più veloci e richiedono meno memoria rispetto a foreach.
JAL

3
Dovresti provare Python. È semplice come "for i in range (12)", oppure puoi utilizzare la xrange più efficiente.
Ponkadoodle,

2
@SilentGhost: avresti ancora bisogno di un array per iniziare, il che non è sempre il caso. @Newbie: elaborato per favore?
Alec,

1
@flexxy, a parte, NON lo è. Considera questo: phpbench.com scorri verso il basso fino a Read Loop.
Buddy,

44

Lo spazio Web abilitato per PHP è generalmente meno costoso di qualcosa con (asp) .net. Si potrebbe chiamare che una caratteristica ;-)


3
È anche molto più economico configurare più server se non devi pagare per Windows Server su ognuno.
MiffTheFox,

4
L'unico posto che conosco di Windows è conveniente in un'università che ottiene sconti STEEEEP sul software del server in quanto è più economico per il mio reparto acquistare 100 copie di Windows di quanto sia addestrare i nostri amministratori su Linux (che in parte mi rende triste ma la loro configurazione di Windows è pulita e ben configurata).
dcousineau,

4
Per ora, ma devi effettuare il passaggio una sola volta, mentre prima o poi dovrai acquistare nuove licenze ...
e-satis

42

La staticparola chiave è utile al di fuori di un punto di vista OOP. È possibile implementare in modo semplice e veloce la 'memoization' o la memorizzazione delle funzioni nella cache con qualcosa di semplice come:

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

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

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

La staticparola chiave crea una variabile che persiste solo nell'ambito di quella funzione oltre l'esecuzione. Questa tecnica è ottima per le funzioni che colpiscono il database come get_all_books_by_id(...)o get_all_categories(...)che chiameresti più di una volta durante il caricamento della pagina.

Avvertenza: assicurati di trovare il modo migliore per creare una chiave per il tuo hash, in quasi tutte le circostanze quanto md5(...)sopra NON è una buona decisione (problemi di velocità e lunghezza di output), l'ho usato a scopo illustrativo. sprintf('%u', crc32(...))o spl_object_hash(...)potrebbe essere molto meglio a seconda del contesto.


7
Solo una funzione copiata da C / C ++
GetFree

2
@GetFree Non credo che nessuno negherebbe che quasi tutto il PHP è stato copiato da C, C ++, Perl, ecc.
Frank Farmer,

1
La copia è la cosa migliore che si possa fare.
NikiC,

1
PHP non valido. Copia sempre funzionalità da altri. Dovrebbe invece scrivere tutto da zero! (Nel caso in cui la minima possibilità sia presa sul serio: sto scherzando)
Halil Özgür

42

Una bella caratteristica di PHP è la CLI . Non è così "promosso" nella documentazione, ma se hai bisogno di script di routine / app console, usare cron + php cli è davvero veloce da sviluppare!


Dovrei davvero esaminare questo, ho diversi lavori cron che recuperano uno script PHPwget http://example.com...
DisgruntledGoat

L'interfaccia della riga di comando è anche un modo eccellente per eseguire il debug spot, poiché verranno visualizzati avvisi / errori senza che sia necessario modificare le preferenze di segnalazione degli errori.
Glacials,

40

Quindi trucco "e stampa"

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

Fa eco a Blah se $ flag è vero. NON FUNZIONA CON ECHO.

Questo è molto utile nel modello e sostituisce il? : che non sono proprio facili da leggere.


24
Personalmente trovo l'operatore ternario molto più ovvio che sfruttare il cortocircuito di valutazione di un logico e.
Vicent Marti,

26
In realtà è lo stesso numero di caratteri di <? Php if ($ flag) stampa "Blah"
troppo php il

3
Le parentesi non sono facili da digitare come "e", specialmente sulla mia tastiera francese insanguinata ;-)
e-satis

7
@tutti i commenti - Non si tratta di quanto in breve si può ottenere! Si tratta di leggibilità e facilità d'uso per le persone modello, che a volte non sono nemmeno programmatori.
Tor Valamo,

6
Vorrei commentare che l'istruzione if () è più semplice e più leggibile. È sicuramente più facile per me capire che sfruttare essenzialmente un effetto collaterale dell'operatore "and" in PHP, in cui è facile commettere un errore (o sembrare che sia un errore quando leggi il codice in seguito). Ad esempio, come affermato, questo non funzionerà nel modo desiderato con 'echo'. Con if () non ci sono gotchas come questo.
thomasrutter,

37

Puoi usare il carattere meno nei nomi delle variabili come questo:

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

Perché usarlo Nessuna idea: forse per un modello CSS? O qualche strano JSON che devi produrre. È una caratteristica strana :)


2
Funziona con i nomi dei metodi? Potrebbe essere utile per i framework che usano un router e voglio domain.com/something-with-minuses/view/
alex

6
Le parentesi graffe consentono di accedere alle proprietà dell'oggetto con trattini, punti e altre entità non alfanumeriche. Uno dei motivi per usarlo è quando si ha a che fare con xml, dove i nomi delle entità possono essere punteggiati come in NITF / NewsML <body.content>. Se usi SimpleXML, accederai in questo modo $item->DataContent->body->{'body.content'}.
Jesse Kochis,

2
Le variabili PHP possono assumere qualsiasi carattere quando vengono utilizzate in questo modo, anche spazi e newline.
Principiante

Questo sarebbe molto utile quando si utilizza in SimpleXML ... fantastico. Grazie per la condivisione.
KyleFarris,

34

La sintassi HEREDOC è la mia funzione nascosta preferita. Sempre difficile da trovare perché non puoi Google per <<< ma ti impedisce di dover sfuggire a grossi blocchi di HTML e ti consente comunque di rilasciare variabili nello stream.

echo <<<EOM
  <div id="someblock">
    <img src="{$file}" />
  </div>
EOM;

2
HEREDOC è il mio modo preferito di creare e utilizzare istruzioni SQL.
bdl

11
Nota: la EOM di chiusura; non può essere rientrato.
micahwittman,

Buono, ma inutile se si utilizzano modelli. Inoltre ostacola la corretta indentazione.
Manos Dilaverakis,

7
Caro dio, questo è il pezzo di codice più brutto che abbia mai visto. Se stai usando HEREDOC, allora non hai separato la presentazione dalla logica.
Lotus Notes

@Byron: non devi usarlo per la presentazione, può essere usato per qualsiasi stringa. Vedi il commento di bdl.
Tom Pažourek,

34

Probabilmente non molti sanno che è possibile specificare "variabili" costanti come valori predefiniti per i parametri di funzione:

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

Le stringhe possono essere utilizzate come se fossero matrici :

$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"

3
Quest'ultimo è elegante. Anche se non ho idea di quando sarebbe meglio di qualche altro metodo per rimuovere un personaggio. +1 comunque
George Mauer,

3
Probabilmente è più efficiente che chiamare una funzione per farlo. Le stringhe sono normalmente memorizzate contigue nella memoria, quindi arrivare a $ str [4] è banale. La memorizzazione di stringhe come matrici di caratteri è comune alla maggior parte delle lingue che derivano da C.
sjobe,

1
Non è necessario utilizzare una costante definita come valore predefinito. È anche perfettamente valido: foot della funzione ($ param1, $ default = array ('key' => 'value'), $ default_s = 'String', $ default_i = 10, $ default_b = false). Comunque hai ragione nel notare che non puoi usare una variabile come argomento predefinito.
dcousineau,

@dcousineau Il tuo esempio è perfettamente valido poiché array () non è una funzione ma un costrutto di linguaggio. Le chiamate di funzione non sono consentite come valori predefiniti per gli argomenti.
Jamol,

4
Fai attenzione a trattare le stringhe come array se hai stringhe multi-byte (lingue straniere, ecc.)
philfreo,

33

L'unica cosa più utile sul codice PHP è che se non capisco bene una funzione vedo che posso cercarla usando un browser e digitando:

http://php.net/function

Il mese scorso ho visto la funzione "range" in alcuni codici. È una delle centinaia di funzioni che non sono mai riuscito a usare ma che si rivelano davvero utili:

http://php.net/range

Quell'URL è un alias per http://us2.php.net/manual/en/function.range.php . Questa semplice idea, di mappare funzioni e parole chiave su URL , è fantastica.

Vorrei che altre lingue, framework, database, sistemi operativi abbiano un meccanismo altrettanto semplice per cercare la documentazione.


5
range()può essere utile perforeach( range(1, 10) as $i) { };
alex

Se hai FireFox; basta digitare PHP functionnella barra degli indirizzi farà una ricerca su Google "Mi sento fortunato" e finirai quasi sempre sulla pagina di documentazione php corretta.
Kolky,

30

Commenti rapidi sui blocchi

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


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

Questi commenti consentono di alternare se un blocco di codice è commentato con un carattere.


14
Questo non è proprio specifico di PHP. Funziona in qualsiasi lingua che supporti i // ...commenti di linea e i /* ... */commenti di blocco.
Jordan Ryan Moore,

tutte le utility di pulizia del codice finiscono per odiarti per l'utilizzo di questo ...;)
Talvi Watia,

3
Ho anche usato /** /prima e /**/dopo. È possibile attivare o disattivare il blocco rimuovendo e aggiungendo lo spazio nel primo. Questo ha un ulteriore vantaggio nel lavorare con CSS (e altre lingue che non supportano i // ... commenti).
Kingjeffrey,


@aleemb, astenersi dal fare ulteriori modifiche a questa domanda.
Sam152,

29

La mia lista ... la maggior parte di essi rientra più nelle "funzioni nascoste" che nelle "funzioni preferite" (spero!), E non tutte sono utili, ma ... 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');

Puoi anche annidare operatori ternari, a volte è utile.

// 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.  

Bene, per ora mi fermo :-)


Hmm, è passato un po '..

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

Quindi, ho appena scoperto che puoi passare qualsiasi stringa come nome di metodo SE la racchiudi tra parentesi graffe. Purtroppo non è possibile definire alcuna stringa come metodo, ma è possibile catturarle con __call () ed elaborarle ulteriormente se necessario. Hmmm ....

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

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

Ho trovato questa piccola gemma nei commenti di Reddit:

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

Non puoi chiamare le funzioni all'interno di {} direttamente in questo modo, ma puoi usare le variabili-holding-the-function-name e chiamarle! (* e * puoi usare anche variabili variabili)


2
Si prega di non abusare dell'operatore di confronto ternario; questo porta all'offuscamento del codice.
staticsan,

Wow. Ciò potrebbe totalmente intaccare la tua lista $ GLOBALS. Cattiva pratica. Sul serio.
Talvi Watia,

Esiste ancora un contest offuscato di PHP?
Lotus Notes

Bene, trucco con lo scambio - impressionante e utile, grazie.
OZ_

1
${''} = 456;hahaha .... piuttosto l'abuso.
Skurmedel,

26

Manipolazione di array.
Tonnellate di strumenti per lavorare e manipolare le matrici. Potrebbe non essere univoco per PHP, ma non ho mai lavorato con un linguaggio che lo abbia reso così semplice.


come cosa per esempio? Mi sembra che le funzioni siano tutte nominate in modo strano e posizionate nello spazio dei nomi globale. Inoltre non riesco a pensare a nulla di altrettanto semplice in un'altra lingua, tranne forse $ arr [] = $ newvalue per l'aggiunta di valori - è fantastico
George Mauer,

8
Bene, l'array PHP è una struttura di dati che può essere facilmente utilizzata come stack, coda, deque, list, hashtable, ecc. È piuttosto flessibile per le esigenze più comuni, senza ricorrere a nient'altro che alle funzioni array_ *.
Camilo Díaz Repka,

6
Python fa array (come elenchi e tuple) molto meglio di PHP.
troppo php, il

26

Sono un po 'come te, ho programmato PHP per oltre 8 anni. Ho dovuto seguire un corso .NET / C # circa un anno fa e mi è piaciuto molto il linguaggio C # (odiato ASP.NET) ma mi ha reso uno sviluppatore PHP migliore.

PHP come lingua è piuttosto scadente, ma sono estremamente veloce con esso e lo stack LAMP è fantastico. Il prodotto finale supera di gran lunga la somma delle parti.

Detto questo, in risposta alla tua domanda:

http://uk.php.net/SPL

Adoro SPL , la classe di raccolta in C # era qualcosa che mi piaceva non appena ho iniziato con esso. Ora posso avere la mia torta e mangiarla.

Andrea


24

Sono un po 'sorpreso che nessuno lo abbia ancora menzionato, ma uno dei miei trucchi preferiti con gli array sta usando l'operatore plus. È un po 'come array_merge()ma un po' più semplice. Ho trovato che di solito è quello che voglio. In effetti, prende tutte le voci nell'RHS e le fa apparire in una copia dell'LHS, sovrascrivendole se necessario (cioè non è commutativo). Molto utile per iniziare con un array "predefinito" e aggiungere alcuni valori reali tutti in un colpo solo, lasciando i valori predefiniti in atto per i valori non forniti.

Esempio di codice richiesto:

// 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 );

$defaultsdovrebbe essere$control_defaults
diEcho il

3
Penso che non sia chiaro come array_merge quando hai molto codice da mantenere. Almeno quando usi la funzione array_merge, è evidente che hai a che fare con le matrici.
Sylvain,

E quel fatto che stai facendo ... + array( ...non è abbastanza per segnalarlo? :-)
staticsan

Di quale versione di PHP hai bisogno per questo?
Lotus Notes

Questa è una grande funzionalità e va notato che l'array sul lato "destro" del "+" non sovrascriverà le chiavi esistenti dell'array sul lato "sinistro" del "+".
Wil Moore III,

21

Eccone uno, mi piace il modo in cui l'impostazione dei valori predefiniti sui parametri di funzione non forniti è molto più semplice:

function MyMethod($VarICareAbout, $VarIDontCareAbout = 'yippie') { }

4
Stranamente ho visto questa "funzione nascosta" in Google Reader la scorsa settimana. Non capisco cosa ci sia nascosto: è la sintassi di base. Prova ad esempio ($ var = true).
Ross,

8
Più facile di cosa? La maggior parte delle lingue ha questa funzione.
Christian Davén,

10
Più facile di C # (e penso C ++ e Java)
George Mauer

8
C ++ supporta i valori dei parametri predefiniti.
sjobe,

2
c # non supporta affatto i valori predefiniti. devi scrivere una funzione sovraccarica e dichiarare sempre il valore che è semplicemente ingombrante
DeveloperChris

21

Veloce e sporco è l'impostazione predefinita.
Il linguaggio è pieno di utili scorciatoie, questo rende PHP il candidato perfetto per (piccoli) progetti che hanno un breve time-to-market. Non che un codice PHP pulito sia impossibile, ci vuole solo qualche sforzo ed esperienza in più.

Ma adoro PHP perché mi permette di esprimere ciò che voglio senza scrivere un saggio.

PHP:

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

GIAVA:

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

E sì, questo include non digitare Int .


4
dovresti usare invece strpos: if (false! == strpos ("one cat", "cat")) {
OIS

17
@OIS lo scopo del suo esempio era di illustrare e confrontare la corsa di una partita regex veloce, non come trovare la stringa "cat" in "one cat".
dcousineau,

19
Java: if (Pattern.matches ("cat", "one cat")) {// do qualcosa} Smetti di lamentarti di Java se non lo conosci.
whiskeysierra,

3
+1 Willi come si fa preg_replace ('/ ([<[]! - \ s *) (\ S *?) (\ S * - [>]]?) / Se', "\ $ this- > Scegli ('\\ 1', '\\ 2', '\\ 3', \ $ data) ", $ text); in Java? Questo trova un commento nel testo di input e quindi chiama una funzione con gli elementi corrispondenti che in questo caso $ this-> sceglie (...) decide con quale sostituire la corrispondenza e restituisce i risultati.
DeveloperChris

1
Regex è PHP è piuttosto scadente ... Preferirei avere Regex in stile Perl o JavaScript in cui il file //è incorporato nel linguaggio.
cdmckay,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.