Visualizzazione risultati 1 fino 10 di 10
Like Tree3Likes
  • 2 Post By mzanella
  • 1 Post By mzanella

Discussione: Proviamo a migrare da php5.6 a php7.3

  1. #1
    L'avatar di habbolifeforum
    habbolifeforum non è connesso Utente giovane
    Data registrazione
    14-07-2018
    Messaggi
    30

    Predefinito Proviamo a migrare da php5.6 a php7.3

    Buongiorno a tutti. Con questo thread vorrei provare insieme a voi a migrare da php5.6 a php7.3. Più che altro vorrei farmi un'idea di quante e quali siano le funzioni e le parti del mio sito che dovrei cambiare...

    Non so se potrò affrontare questa discussione tutta in questo topic, ma se necessario ne aprirò altri.

    Direi di iniziare con il primo errore che compare, ovvero questo:

    Fatal error: Uncaught Error: Call to undefined function mysql_connect() in /membri/....

    Fin qui ok, le funzioni mysql infatti non sono più supportate e devono essere sostituite con mysqli

    Prendiamo ad esempio in considerazione questo pezzo di codice (ho messo insieme vari pezzi di funzioni frequenti che utilizzo):

    Codice PHP:
    <?php
    $connessione
    = mysql_connect("localhost", "habbolifeforum", "NULL") or die("Connessione non riuscita: " . mysql_error);
    mysql_set_charset("UTF8", $connessione);
    mysql_select_db("my_habbolifeforum", $connessione);

    $query = mysql_query("SELECT widgets_css FROM cms_config");
    $i = mysql_fetch_array($query);

    $query_num = mysql_query("SELECT COUNT(*) AS num FROM news WHERE (news.date < " . time() . ") AND news.type='habbo'") or die(mysql_error());

    $info_num = mysql_fetch_array($query_num);

    $num = ceil($info_num['num'] / $results_per_page);

    $n = 0;
    while (
    $info = mysql_fetch_array($query))
    {
    $badges = explode(",", $info['badges']);
    }
    ?>
    Teoricamente basta sostituire mysql con mysqli e il problema dovrebbe essere risolto, giusto?

    L'ho fatto e il "fatal error" scompare, ma successivamente la pagina rimane bianca cos'è che manca o bisogna cambiare?

    Accetto suggerimenti o modifiche da applicare al codice che ho messo sopra (una volta visto come bisogna modificarlo lo imparo e lo applico al resto del mio sito)

    Grazie in anticipo!

  2. #2
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,894

    Predefinito

    Su mysqli_query esiste un secondo parametro che è destinato alla query mentre il primo è la connessione https://www.php.net/manual/en/mysqli.query.php doc php.net online
    Poi oltre a usare mysqli_set_character dovrai specificare una query con SET NAMES UTF8 (alcune vecchie configurazioni legacy hanno bisogno di forzare la connessione).
    Puoi anche togliere mysqli_select_database poiché con mysqli già sarà utilizzato in mysqli_connect (sono 4 parametri invece di 3 come nella vecchia versione) e altervista offre unicamente un database con my_nickaltervista.
    Ultima modifica di darbula : 10-01-2021 alle ore 23.16.08

  3. #3
    L'avatar di habbolifeforum
    habbolifeforum non è connesso Utente giovane
    Data registrazione
    14-07-2018
    Messaggi
    30

    Predefinito

    Ah ecco! Grazie per le delucidazioni e per i chiarimenti

    Mi leggo con calma la documentazione e faccio delle modifiche al codice. Appena ho finito eventualmente lo pubblico in versione aggiornata

  4. #4
    L'avatar di habbolifeforum
    habbolifeforum non è connesso Utente giovane
    Data registrazione
    14-07-2018
    Messaggi
    30

    Predefinito

    darbula ci sei? Ti aggiorno un po' su quello che ho modificato e cambiato sul mio sito di test per provare a passare da php 5.6 a php 7.1. (Non c'è bisogno che commenti riga per riga, ma solo che mi avvisi se alcune cose le ho sbagliate o se hai dei consigli)

    - Ho sostituito mysql_connect con mysqli_connect + ho aggiunto il quarto parametro, ovvero il nome del database (e quindi ho rimosso mysql_select_db)

    - mysql_set_charset l'ho sostituito con mysqli_set_charset (non ho capito però cosa mi avevi detto di fare oltre a questo)

    - A mysql_connect ho rimosso or die("Could not connect to database, error: ".mysql_error()); e ho aggiunto questo if:

    Codice PHP:
    // Controllo connessione
    if (!$connect) {
    die(
    "Connessione fallita: " . mysqli_connect_error());
    }
    - Ho aggiunto mysqli_close($connect) in fondo (nel footer del sito). Ho fatto bene?

    - Dopo ogni query io ero solito mettere or die(mysql_error_alert()), l'ho sostituito con or die(mysqli_error($connect)). Ci ho quindi aggiunto le info della connessione come parametro. Va bene?

    - mysql_fetch_array l'ho sostituito semplicemente con mysqli_fetch_array

    - mysql_num_fields l'ho sostituito semplicemente con mysqli_num_fields

    - mysql_field_name ho visto che non è più supportato/esistente... l'ho sostituito con mysqli_fetch_field_direct, senza però alterare i vecchi parametri che gli passavo.

    - mysql_num_rows l'ho sostituito semplicemente con mysqli_num_rows

    - mysql_real_escape_string l'ho sostituito con mysqli_real_escape_string + ho dovuto aggiungere le info sulla connessione come primo parametro della funzione.

    - La più importante... mysql_query l'ho sostituita con mysqli_query e come primo parametro gli ho dovuto mettere le info sulla connessione. Ecco un confronto:

    Codice PHP:
    // Prima
    mysql_query("SELECT * FROM cms_pages WHERE code = '".$code."'") or die(mysql_error_alert());
    // Dopo
    mysqli_query($connect, "SELECT * FROM cms_pages WHERE code = '".$code."'") or die(mysqli_error($connect));
    Davvero non capisco perché abbiano dovuto complicare le cose. Prima era più pulito, ora bisogna ogni volta mettere questa cavolo di informazione per la connessione...

    E qui inizia il primo problema... Ho creato la variabile globale $connect a cui ci associo le informazioni del DB:

    Codice PHP:
    $connect = mysqli_connect($db_host, $db_user, $db_pass, $db_database);
    Il problema è che ora con questa versione di PHP devo mettere tale variabile come primo parametro di ogni query, giusto?

    Solo che io ho mille funzioni e classi sparse in tutti i file del sito... non è tanto il problema di aggiungerlo manualmente, ma il fatto che tale variabile all'interno delle funzioni non viene vista. Come posso fare?

    So che potrei mettere questo all'inizio di ogni funzione (o ancora peggio passarglielo come parametro):

    Codice PHP:
    global $connect;
    Lo trovo però così ridondante e scomodo. Hai qualche consiglio o suggerimento da darmi?

    ----

    Mi sembra assurdo di dover infilare sto $connect ovunque. Guarda quest'altro esempio (quattro connect in una sola riga):

    Codice PHP:
    function update_value($json_name, $json, $name, $new_value)
    {
    // Roba che ho tagliato
    global $connect;

    mysqli_query($connect, "UPDATE cms_config SET `".mysqli_real_escape_string($connect, (trim($json_name))."` = '".mysqli_real_escape_string($connect, ($result)."'") or die(mysqli_error($connect));

    return
    $result;
    }
    Ultima modifica di habbolifeforum : 13-01-2021 alle ore 19.28.15

  5. #5
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    Citazione Originalmente inviato da habbolifeforum Visualizza messaggio
    Davvero non capisco perché abbiano dovuto complicare le cose. Prima era più pulito, ora bisogna ogni volta mettere questa cavolo di informazione per la connessione...

    E qui inizia il primo problema... [...] Solo che io ho mille funzioni e classi sparse in tutti i file del sito... non è tanto il problema di aggiungerlo manualmente, ma il fatto che tale variabile all'interno delle funzioni non viene vista.
    [...] So che potrei mettere [global] all'inizio di ogni funzione (o ancora peggio passarglielo come parametro):
    [...]Lo trovo però così ridondante e scomodo. Hai qualche consiglio o suggerimento da darmi?
    [...]Mi sembra assurdo di dover infilare sto $connect ovunque.
    È interessante che tu l'abbia osservato, questi sono precisamente alcuni dei motivi per cui le cose sono state cambiate.
    Anche prima c'era il parametro relativo alla connessione, veri per esempio $link_identifier in mysql_query. Leggendo la documentazione viene indicato che, se il secondo parametro non viene passato, è utilizzato quello relativo all'ultima connessione aperta. Se nessuna connessione è stata aperta, viene implicitamente chiamato mysql_connect, sperando che funzioni come per magia, in quanto viene chiamato senza argomenti. Era una gestione abbastanza ridicola, per usare un eufemismo.

    Un discorso diverso va fatto in riferimento "all'ultima connessione aperta": questo presuppone(va) un contesto e uno stato globali. Era come se ci fosse un global $connessione; implicitamente ovunque, quindi era aperto a tutti i classici problemi del caso, soprattutto race condition in caso di programmazione concorrente (e considerando che le ultime versioni di PHP hanno ampliato il supporto ai thread POSIX non è strano vedere un minimo di sicurezza adottata anche nelle connessione ai database).
    Andando un po' più sul tecnico c'è un ulteriore problema nell'avere la connessione disponibile nello stato globale: un garbage collector non sarebbe in grado di deallocarla se non alla fine dell'esecuzione, il che è un ovvio problema di prestazioni (oppure in caso di chiusura esplicita, ma questo va contro l'idea stessa di servirsi di un GC).

    Riguardo alla "pulizia", quello che si fa tipicamente è usare un approccio a oggetti. Prendi per esempio i data mapper o gli active record: una singola classe è responsabile di tutte le interazioni con la base di dati. La connessione viene stabilita una volta sola (e preferibilmente inserita tramite dependency injection), in modo che sia sempre visibile nello stato locale dell'oggetto. Sia PDO che la versione a oggetti di mysqli seguono quest'approccio.
    La versione procedurale di mysqli, essendo appunto procedurale, non può, e richiede il passaggio del parametro esplicito.

    Per i siti web, che sono applicazioni tutto sommato semplici, nulla di tutto questo ha portato reali miglioramenti (quando mai qualcuno apriva più connessioni diverse simultanee in un sito web?), solo la "seccatura" di un parametro in più nel caso in cui non si usi un approccio a oggetti. In altri contesti, invece, tutto di guadagnato.

    I suggerimenti che do più spesso:


  6. #6
    darbula non è connesso AlterGuru 2500
    Data registrazione
    24-04-2011
    Messaggi
    2,894

    Predefinito

    Aggiungo la differenza tra classe nativa e classe definita dall'utente.
    Questo è un semplice esempio di estendere la classe mysqli al genitore FooMysqli della propria classe, senza verifica di sorte per charset e nemmeno Preparated Statement.
    Codice PHP:
    class FooMysqli extends mysqli {
    public function
    __construct($host, $user, $pass, $db, $port, $socket, $charset) {
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
    parent::__construct($host, $user, $pass, $db, $port, $socket);
    $this->set_charset($charset);
    $this->query("SET NAMES '$charset'");
    }
    }

    $db = new FooMysqli('localhost', 'user', 'my_password', 'my_user', 3306, null, 'utf8'); // per altervista occorre solo il my_database
    $resultset = $db->query('SELECT NOW()');
    while (
    $row = $resultset->fetch_row()) {
    echo
    $row[0];
    }

  7. #7
    L'avatar di habbolifeforum
    habbolifeforum non è connesso Utente giovane
    Data registrazione
    14-07-2018
    Messaggi
    30

    Predefinito

    Grazie per la spiegazione, sei stato molto chiaro e mi hai risolto parecchi dubbi "esistenziali"

    In effetti sarebbe meglio adottare un approccio ad oggetti, anche se io fin dal passato sono stato legato a quello procedurale... vedrò in futuro quando riscriverò il sito di cambiare questa cosa.

    Ora sto continuando a sostituire le funzioni mysql con quelle mysqli... appena ho finito testo tutto il sito per vedere se funzione (sperando che non ci siano altre cose da cambiare)

    Ti tengo aggiornato! Grazie per le spiegazioni

  8. #8
    mzanella non è connesso AlterGuru
    Data registrazione
    29-12-2015
    Messaggi
    1,954

    Predefinito

    In effetti sarebbe meglio adottare un approccio ad oggetti, anche se io fin dal passato sono stato legato a quello procedurale... vedrò in futuro quando riscriverò il sito di cambiare questa cosa.
    Sempre stato anche io un fan dell'approccio procedurale . Non che ci sia molta scelta quando la velocità di esecuzione è uno dei punti chiave.
    PHP però ha intrapreso un'altra strada, ormai ci sono funzionalità che, pur essendo concepibili anche in un contesto procedurale, sono state rese fruibili solo in quello a oggetti. Per esempio l'autoloader: includere automaticamente un file quando viene chiamata una funzione non definita non è più complesso che includerne uno in caso di istanziazione di classe non definita, eppure questa funzionalità non è offerta per le funzioni, mentre per le classi sì.
    habbolifeforum likes this.

    I suggerimenti che do più spesso:


  9. #9
    Sigilonline non è connesso Utente giovane
    Data registrazione
    12-04-2009
    Messaggi
    37

    Predefinito

    Citazione Originalmente inviato da habbolifeforum Visualizza messaggio
    Teoricamente basta sostituire mysql con mysqli e il problema dovrebbe essere risolto, giusto?
    In pratica sì... in teoria è esattamente quello che non si dovrebbe fare.

    L'estensione mysqli non è pensata per essere usata direttamente, è pensata per passare attraverso un gestore delle query al quale delegare la connessione, la preparazione degli statement e la validazione dell'input. A fare il binding dei parametri tutte le volte a mano si impazzisce (e lo so bene perchè nel 2020 sono migrato a PHP 7.3 anch'io).

    Visto che comunque ci sono da riscrivere tutte le chiamate, il consiglio che posso dare è di appoggiarsi su un gestore di query semplice ma fatto bene. Personalmente ho usato questo, è un singolo file .php comodissimo da copiarsi in root e includere ovunque serva la connessione al database:

    https://github.com/colshrapnel/safemysql
    Ultima modifica di Sigilonline : 16-01-2021 alle ore 18.15.58

  10. #10
    L'avatar di habbolifeforum
    habbolifeforum non è connesso Utente giovane
    Data registrazione
    14-07-2018
    Messaggi
    30

    Predefinito

    Capito, interessante

    Proverò a darci un'occhiata, grazie!

Regole di scrittura

  • Non puoi creare nuove discussioni
  • Non puoi rispondere ai messaggi
  • Non puoi inserire allegati.
  • Non puoi modificare i tuoi messaggi
  •