Perché molti sviluppatori PHP odiano usare isset () e / o una qualsiasi delle funzioni difensive di PHP come empty ()?


27

Su stackoverflow, vedo che questo problema si ripresenta continuamente:

Perfino Pekka (che offre molti solidi consigli su PHP) si è scontrato con il E_NOTICEmostro temuto e sperava in una soluzione migliore rispetto all'utilizzo di isset(): isset () e empty () rendono il codice brutto

Personalmente, utilizzo isset()e empty()in molti luoghi per gestire il flusso delle mie applicazioni. Per esempio:

public function do_something($optional_parameter = NULL) {
    if (!empty($optional_parameter)) {
        // do optional stuff with the contents of $optional_parameter
    }
    // do mandatory stuff
}  

Anche un semplice frammento come questo:

if (!isset($_REQUEST['form_var'])) {
    // something's missing, do something about it.
}

mi sembra molto logico. Non sembra gonfio, sembra un codice stabile. Ma molti sviluppatori accendono le loro applicazioni con E_NOTICEle funzioni abilitate, scoprono molte frustranti comunicazioni "indice di array non inizializzate" e poi fanno una smorfia alla prospettiva di verificare le variabili definite e di "sporcare" il loro codice isset().

Presumo che altre lingue gestiscano le cose in modo diverso. Parlando per esperienza, JavaScript non è educato come PHP. Una variabile non definita in genere interrompe l'esecuzione dello script. Inoltre, (parlando per inesperienza ) sono sicuro che linguaggi come C / C ++ semplicemente rifiuterebbero di essere compilati.

Quindi, gli sviluppatori PHP sono semplicemente pigri? (non parlando di te, Pekka, so che stavi eseguendo il refactoring di una vecchia applicazione.) O altre lingue gestiscono le variabili indefinite in modo più grazioso rispetto al richiedere al programmatore di verificare prima se sono definite?

(So ​​che ci sono altri E_NOTICEmessaggi oltre alle variabili indefinite, ma quelli sembrano essere quelli che causano il maggior dispiacere)

Addendum
Dalle risposte finora, non sono il solo a pensare che isset()non sia un eccesso di codice. Quindi, mi chiedo ora, ci sono problemi con i programmatori in altre lingue che fanno eco a questo? O è solo un problema di cultura PHP?


4
Purtroppo ho visto gli sviluppatori di php lavorare anche con "avvisi" disattivati.
Viper_Sb

Ahia. Questo è triste.
Stephen,

1
Non essendo un utente PHP, mi chiedo: perché dovresti controllare le variabili non definite?
Winston Ewert,

2
@ Winston: Il problema con PHP (contrariamente a molte altre lingue) è che PHP consente molte combinazioni di configurazione. Ad esempio, il programmatore può decidere di ignorare avvisi, avvisi e notifiche di deprecazione. Gli sviluppatori più esperti lavoreranno con error_reporting impostato per segnalare tutto. PHP ha anche molte funzioni che generano errori e restituiscono codici di stato anziché generare eccezioni. Bisogna essere molto intimi con il linguaggio per essere in grado di programmare in modo difensivo e di successo. Molte altre lingue non consentono la scelta. Strict è di solito l'opzione predefinita e unica.
Wil Moore III,

1
Non mi piace isset () a causa della verbosità che aggiunge. Una migliore forma di @ sarebbe una bella alternativa.
Kzqai,

Risposte:


34

Codifico E_STRICTe nient'altro.

L'uso di assegni vuoti e isset non rende il tuo codice brutto, ma rende il tuo codice più dettagliato. Nella mia mente qual è la cosa peggiore in assoluto che può accadere dal loro utilizzo? Scrivo qualche altro personaggio.

Versi sulle conseguenze del non usarli, per lo meno avvertimenti.


7
Anche il mio ambiente di sviluppo lo è E_STRICT. Sopprimo tutti gli errori nella produzione, ma questo è solo per garantire che nulla mi sia sfuggito nello sviluppo.
Stephen,

2
+1 Josh, sono allo stesso modo. Quando programmi in E_STRICT, sai che non avrai mai sorprese nel tuo codice. L'unico modo per volare, imo.
EricBoersma,

3
@Stephen: disattiva sempre gli errori per la produzione. Questa è solo una rete di sicurezza. Lo sviluppo dovrebbe (IMO) essere sempre E_STRICT. Scrivi il codice e risolvi tutti gli avvisi e gli errori.
Josh K,

mi stai pappagallo? :)
Stephen,

@Stephen: sono d'accordo. :)
Josh K,

17

Penso che gli avvisi su elementi sconosciuti siano un errore di progettazione in PHP. Non sono sicuro che sia possibile correggere l'errore ora, ma produce un sacco di codice del bollettino come if(isset($foo['abc']) && $foo['abc'] == '123')- questo codice non dovrebbe avere isset, poiché l'intento è quello di verificare se c'è '123' in un determinato posto di $fooe se non c'è nulla lì è sicuramente non "123". L'unica ragione per cui devi scrivere il doppio del codice è a causa di questo sfortunato errore di progettazione in PHP. E , purtroppo, gli avvisi in PHP sono molto costosi, quindi disabilitarli non è un'opzione per il codice in cui le prestazioni sono un problema.

Quindi sì, rende il codice IMHO brutto e mi infastidisce. E non è per mancanza di esperienza: uso PHP dal 1998 e ricordo quando c'era l' .php3estensione e significava "non è PHP 2". Forse sono pigro :) Ma la pigrizia - almeno un certo tipo - è una virtù per un programmatore.

D'altra parte, l'uso valido di issete empty- proprio come quelli del post originale - va bene. Penso solo che PHP sia troppo zelante riguardo agli avvisi in luoghi in cui isset/emptynon sono realmente necessari.


3
Destra. È una questione di verbosità. $eg = isset($_GET['eg'])? $_GET['eg'] : null;è ridicolmente dettagliato. Vorrei davvero che ci fosse un altro operatore che non fosse "la soppressione degli errori" di per sé per sostituire il significato breve di $eg = @$_GET['eg'];"accetta-la-non-esistenza-di-questa-matrice-chiave-come-un-null". Di questi tempi tendo ad usare una funzione breve.
Kzqai,

7
Concordato. 4 anni dopo, entra nel Null Coalesce Operator: wiki.php.net/rfc/isset_ternary che ci dà$eg = $_GET['eg'] ?? null;
Steve,

O semplicemente fallo ora con l'operatore di soppressione degli errori, ad es $eg = @$_GET['eg'] ?: null;. In genere non lo uso, ma in questo caso ci aspettiamo esplicitamente quell'errore e decidiamo di ignorarlo. È un personaggio più lungo della nullità e non è buono (sopprime tutti gli errori, e potrebbe esserci un ArrayAccess che fa cose funky lì, non solo un array), ma in generale fa il lavoro.
El Yobo,

12

Credo che PHP, come linguaggio gratuito, interpretato e utilizzato sul Web, abbia un'alta percentuale di programmatori non professionisti e non addestrati che non sono pienamente consapevoli del perché dovrebbero codificare in modo difensivo e vedono gli avvisi come un altro errore non necessario .

Ho sempre sentito questi punti da sviluppatori junior e programmatori di script autodidatta:

  • Perché inizializzare una variabile se verrà comunque all'esistenza?
  • Perché verificare se esiste qualcosa prima di usarlo, undefined equivale a false comunque?
  • Se prefisso @ risolve il mio codice, perché complicare le cose?

Se non hanno mai sperimentato un linguaggio fortemente tipizzato o sperimentato le insidie ​​di variabili non dichiarate / non motivate, assumono alcune convinzioni. Trovo che di solito si arrendano dopo aver provato il piacere del debug del codice per circa un'ora per scoprire che era un errore di battitura in un nome di variabile che causava il problema.

L'altro fattore forte è l'uso di PHP nel settore web, che tende ad essere molto più interessato alla produttività che alla sicurezza e alla qualità del codice.


10
"Credo che PHP [...] abbia una percentuale molto elevata di programmatori non professionisti e non addestrati" In qualità di sviluppatore PHP dedicato, non posso essere più d'accordo con te. +1
Stephen,

@Stephen Beh, ultimamente codice principalmente in PHP e jQuery, anche se ho un'istruzione formale, ma il codice che vedi come un professionista di cui diventi responsabile prima ... a volte sfida la convinzione. ;-)
Orbling

1
Penso che sia un vero problema con PHP. A parte alcune stranezze nel linguaggio (che stanno lentamente risolvendo in ogni nuova versione) c'è un'aria di dilettantismo intorno ad esso. Immagino che essere uno sviluppatore professionista di PHP possa essere frustrante a volte, perché ti viene paragonato al "nipote del capo da dietro l'angolo".
Erik van Brakel,

1
@Erik PHP era un parente abbastanza povero di Perl dieci anni fa, ora è un linguaggio interpretato abbastanza ragionevole, in particolare per l'uso del web. C'è una ragione per cui aziende come Facebook lo usano. Ma poiché è disponibile ovunque, il set amatoriale lo usa ampiamente e questo ne offusca la reputazione.
Orbling

5

Sì, sono pigri. Molti comunque ...

Sfortunatamente la mentalità di molti programmatori di PHP è "Non ha senso codificare in modo difensivo se è possibile ottenere lo stesso risultato finale più rapidamente facendo affidamento sul linguaggio per gestire gli errori causati da variabili mancanti ecc. Ecc." Lo so, ho lavorato con molti di loro.

Tendono anche a essere quelli che misteriosamente si dirigono verso un pranzo presto quando la loro mancanza di una corretta gestione e segnalazione degli errori porta fuori i server live per diverse ore ...


5
-1 per l'opinione soggettiva sui programmatori PHP.
Josh K,

4
@Josh, essendo stato un programmatore senior di PHP per 4 anni e mezzo e codificato PHP on e off dal 1999, temo di essere in qualche modo soggettivo. Avrei dovuto qualificarmi con "D'altra parte, i programmatori PHP più esperti non sono pigri e fanno le cose correttamente" ...
Gruffputs

1
Che dovresti avere.
Josh K,

5

Cerco di evitare l'uso di isset () e empty () evitando l'uso di array come oggetti di trasferimento dati. Creare una classe che può essere configurata per accettare un set limitato di proprietà con valori predefiniti sani e convalidare l'input per tali proprietà. Può persino implementare l'interfaccia ArrayAccess in modo da poterlo usare come un array. Ciò consente anche di utilizzare il suggerimento del tipo nelle firme del metodo per rilevare errori quando qualcuno tenta di passare il tipo di entità errato al metodo.


Un approccio molto interessante.
Toby,

2

Una delle domande poste è la mia, quindi lasciatemi ripetere.

Molti sviluppatori confondono la presenza di molti isset()come segno di qualità. Dà un'apparenza di affidabilità e alcune persone la pensano anche come funzionalità di sicurezza.

Ma devi tenere conto del fatto che PHP non è un linguaggio compilato. È un linguaggio di scripting con un sistema di tipo dinamico. Gli errori E_NOTICE sono solo errori per nome. E se molti issetvengono utilizzati con la sola intenzione di sopprimere gli avvisi, in realtà stai solo codificando il linguaggio .

Quindi, gli sviluppatori PHP sono semplicemente pigri?

Questo è davvero il caso se vedi un'abbondanza di avvisi e avvertimenti lanciati. Molti neofiti non si preoccupano degli avvisi, ed è di solito il risultato di un completamente disabilitato error_reporting(0).

Ti sbagli però che altri sviluppatori non hanno riconosciuto E_NOTICE solo perché non erano @ o soppressi da isset. Almeno questa era la mia intenzione alla base delle domande sulle comunicazioni . Non sono qualcosa di cui sbarazzarsi, ma a volte importanti informazioni di debug.

Come tutte le generalizzazioni, l'uso sconsiderato di isset non porta a un codice ottimale. È importante differenziare dove issete emptysono necessari e dove sono sale sintattico .

O è solo un problema di cultura PHP?

No, gli "errori" variabili non definiti non sono solo un problema PHP. Bash, TCL e Perl o JavaScript consentono l'uso di variabili non definite. Questa caratteristica linguistica immanente non è vista come un difetto lì comunque. Esistono costrutti di linguaggio simili per verificare la presenza di valori non definiti. Tuttavia non sono usati costantemente come in PHP, a causa dei valori indefiniti che non sono stati definiti erroneamente come "errore".


1

Interessante. Non uso quasi mai isset (). Il mio codice PHP è raramente in uno stato in cui non so se una variabile è stata impostata in primo luogo. Ogni variabile GET o POST utilizzata è accessibile tramite una funzione che fornirà un valore predefinito se non esiste. I valori predefiniti nelle chiamate di funzione sono in genere impostati esplicitamente su 0 o stringhe vuote.


+1. Passare a una funzione o a un metodo di classe è una buona soluzione. Io in realtà DO fare questo, ma in un pizzico miei precedenti esempi ancora aspetto pulito e poco gonfio a me.
Stephen,

0

Uso isset e ne svuoto un sacco. Ma soprattutto sono i luoghi che menzioni, come l'elaborazione $ _REQUEST, nel caso in cui qualcuno abbia sbagliato i parametri. Nei casi in cui ho il controllo su tutte le variabili che volano in giro, trovo che di solito non ne ho bisogno.


0

Non mi piace usare isset, ma se ci sono masse di codice fatte da un altro, allora può essere una grazia salvifica. Ho scritto il seguente codice per aiutare con questo problema, invece di usare isset () isseter ($ a, $ b) restituirà $ b se $ a non è definito o vuoto, o la funzione restituisce un valore nullo. Eventuali miglioramenti, benvenuto:

//returns var or NULL (if undefined)
//$reserve optional second value is returned as $default if undefined
function isseter(&$default,&$reserve=NULL)
{
$default = isset($default) ? $default : NULL;
$reserve = isset($reserve) ? $reserve : NULL;
if ((!$default) && ($reserve)) $default=$reserve;
return $default;
}
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.