Perché il suggerimento tipo "tradizionale" non è consentito in PHP?

Ho appena scoperto che l' hint di tipo è permesso in PHP, ma non per ints, stringhe, bool o float.

Perché PHP non consente l'hint di tipo per tipi come interi, stringhe, …?

PHP digitato in modo approssimativo, in cui i tipi "primitivi" vengono automaticamente manipolati in base al context in cui vengono utilizzati. Il tipo di suggerimento non cambierebbe davvero questo, poiché una string potrebbe essere usata come int, o viceversa. L'invocazione del tipo sarebbe davvero utile solo per tipi complessi come matrici e oggetti, che non possono essere giocosamente manipolati come inti, archi o altri primitivi.

Per dirla in un altro modo, dal momento che PHP non ha alcun concetto di tipi specifici, non si potrebbe richiedere un int da qualche parte perché non sa cosa sia realmente un INT . D'altra parte, un object è di un certo tipo, dal momento che una MyClass non è intercambiabile con MyOtherClass .


Solo per riferimento, ecco cosa succede quando provi a convertire tra tali tipi (non una list esaustiva):

Conversione in object ( ref )
"Se un object viene convertito in un object, non viene modificato: se un valore di qualsiasi altro tipo viene convertito in un object, viene creata una nuova istanza della class integrata stdClass . Se il valore era NULL, la nuova istanza sarà vuoto. Le matrici vengono convertite in un object con properties; denominate da chiavi e valori corrispondenti. Per qualsiasi altro valore, una variabile membro denominata scalare conterrà il valore. "

Object to int / float ( ref )
comportmento indefinito

Oggetto a boolean ( ref )
in PHP5, sempre VERO

Oggetto da string ( rif )
Se necessario, verrà chiamato il metodo magico __toString() dell'object.

Oggetto su matrix ( ref )
"Se un object viene convertito in un arrays, il risultato è un arrays i cui elementi sono le properties; dell'object.Le chiavi sono i nomi delle variables membro, con alcune eccezioni degne di nota: le properties; dei numbers interi non sono accessibili, le variables private hanno il nome della class anteposto al nome variabile: le variables protette hanno un prefisso '*' anteposto al nome della variabile.Questi valori predefiniti hanno byte null su entrambi i lati. Ciò può provocare alcuni comportmenti imprevisti. "

Matrice su int / float ( ref )
comportmento indefinito

Array to boolean ( ref )
Se l'arrays è vuoto (cioè nessun elemento), viene valutato FALSE – altrimenti, TRUE.

Array to string ( ref )
la string "Array"; utilizzare print_r() o var_dump() per printingre il contenuto di un arrays

Matrice per object ( ref )
"Le matrici vengono convertite in un object con properties; denominate da chiavi e valori corrispondenti."

A partire da PHP 7.0 è disponibile il supporto per bool , int , float e string . Il supporto è stato aggiunto nei tipi scalari RFC . Ci sono due modalità: debole e rigorosa. Consiglio di leggere la RFC per comprendere appieno le differenze, ma essenzialmente le conversioni di tipo avvengono solo in modalità debole.

Dato questo codice:

 function mul2(int $x) { return $x * 2; } mul2("1"); 

In modalità debole (che è la modalità predefinita) questo convertirà "1" in 1 .

Per abilitare i tipi strict aggiungi declare(strict_types=1); all'inizio del file. In modalità rigorosa verrà emesso un errore:

Errore irreversibile: l'argomento 1 passato a mul2 () deve essere di tipo integer, string data

Non è corretto chiamarlo "tipo suggerimento". "Hinting" implica che si tratta di una digitazione opzionale, un semplice suggerimento piuttosto che un requisito, tuttavia i parametri di function digitati non sono affatto facoltativi – se si assegna un tipo errato, si ottiene l'errore fatale. Chiamarlo "type hinting" è stato un errore.

Ora per i motivi per cui non esiste una digitazione primitiva per i parametri di function in PHP. PHP non ha una barriera tra i tipi primitivi – cioè, string, integer, float, bool – sono più o less intercambiabili, puoi avere $a = "1"; e quindi echo $a+3; e ottieni 4 . Tutte le funzioni interne funzionano anche in questo modo – se la function si aspetta una string e tu passi un integer, viene convertito in string, se la function si aspetta un float e ottiene un integer, viene convertito in float, ecc. Questo è diverso dai tipi di object – non c'è conversione tra, per esempio, SimpleXMLElement e DirectoryIterator : né potrebbe esserci, non avrebbe alcun senso.

Pertanto, se si introduce una function che accetta un integer 1 e non una string 1 , si crea incompatibilità tra funzioni interne e funzioni utente e si creano problemi per qualsiasi codice che presuppone che siano praticamente uguali. Questo sarebbe un grande cambiamento nel modo in cui i programmi PHP si comportno, e questo cambiamento dovrà essere propagato attraverso tutto il codice usando tali funzioni – poiché altrimenti rischienetworking errori durante la transizione tra codice "strict" e "non-strict". Ciò implicherebbe una necessità di tipi variables, properties; tipizzate, valori restituiti digitati, ecc. – grandi cambiamenti. E poiché PHP non è un linguaggio compilato, non si ottengono benefici dal controllo di tipo statico con i lati negativi di esso – si ottengono solo inconvenienti ma non la sicurezza aggiunta. Questo è il motivo per cui la digitazione dei parametri non è accettata in PHP.

C'è un'altra opzione: la tipizzazione coercitiva, ovvero un comportmento analogo a quello che fanno le funzioni interne: la conversione tra tipi. Sfortunatamente, questo non soddisfa i sostenitori della tipizzazione rigorosa, e quindi non è stato trovato alcun consenso fino ad ora, e quindi nessuno è presente.

D'altra parte, i tipi di object non sono mai stati controversi: è chiaro che non c'è alcuna conversione tra loro, nessun codice presuppone che siano intercambiabili e che i controlli possano essere solo severi per loro, ed è il caso delle funzioni interne ed esterne. Pertanto, l'introduzione di tipi di object rigorosi non rappresentava un problema.