Workerman/MySQL

Introduzione

Spesso i programmi residenti in memoria incontrano l'errore mysql gone away quando utilizzano MySQL. Questo è dovuto all'assenza di comunicazione per un lungo periodo tra il programma e MySQL, che porta alla disconnessione da parte del server MySQL. Questa classe per il database può risolvere questo problema, in quanto, se si verifica l'errore mysql gone away, verrà eseguito automaticamente un secondo tentativo.

Dipendenze dell'estensione

Questa classe MySQL dipende da due estensioni, pdo e pdo_mysql. Se mancano queste estensioni, si otterrà un errore Undefined class constant 'MYSQL_ATTR_INIT_COMMAND' in .....

Eseguendo il comando php -m dalla riga di comando, verranno elencate tutte le estensioni PHP CLI installate. Se mancano pdo o pdo_mysql, è necessario installarle manualmente.

Sistema CentOS

PHP5.x

yum install php-pdo
yum install php-mysql

PHP7.x

yum install php70w-pdo_dblib.x86_64
yum install php70w-mysqlnd.x86_64

Se non si trovano i nomi dei pacchetti, è possibile provare a cercare con yum search php mysql.

Sistema Ubuntu/Debian

PHP5.x

apt-get install php5-mysql

PHP7.x

apt-get install php7.0-mysql

Se non si trovano i nomi dei pacchetti, è possibile provare a cercare con apt-cache search php mysql.

Impossibile installare usando i metodi sopra menzionati?

Se i metodi sopra citati non funzionano, si prega di fare riferimento al manuale di Workerman - Appendici - Installazione dell'estensione - Metodo 3: Installazione da codice sorgente.

Installazione di Workerman/MySQL

Metodo 1:

È possibile installare l'estensione tramite Composer eseguendo il seguente comando da riga di comando (in quanto il repository di Composer si trova all'estero, l'installazione potrebbe essere molto lenta).

composer require workerman/mysql

Dopo il successo del comando sopra, verrà creata la cartella "vendor" e sarà necessario inclusa nel proprio progetto il file "autoload.php" all'interno della cartella "vendor".

require_once __DIR__ . '/vendor/autoload.php';

Metodo 2:

Download del codice sorgente, decomprimere la cartella e posizionarla all'interno del proprio progetto in una posizione qualsiasi, quindi richiamare direttamente il file sorgente.

require_once '/percorso/tuo/di/mysql-master/src/Connection.php';

Nota

Si consiglia vivamente di inizializzare la connessione al database nel callback onWorkerStart, al fine di evitare l'inizializzazione della connessione prima dell'esecuzione di Worker::runAll();. Se la connessione viene inizializzata prima dell'esecuzione di Worker::runAll();, ciò verrà effettuato all'interno del processo principale, e i processi figlio erediteranno questa connessione. L'utilizzo della stessa connessione al database da parte del processo principale e di quello figlio potrebbe causare errori.

Esempio

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('websocket://0.0.0.0:8484');
$worker->onWorkerStart = function($worker)
{
    // Memorizzare l'istanza di db come variabile globale (oppure memorizzarla come membro statico di una classe)
    global $db;
    $db = new \Workerman\MySQL\Connection('host', 'port', 'user', 'password', 'nome_db');
};
$worker->onMessage = function(TcpConnection $connection, $data)
{
    // Ottenere l'istanza di db tramite la variabile globale
    global $db;
    // Eseguire SQL
    $all_tables = $db->query('show tables');
    $connection->send(json_encode($all_tables));
};
// Esegui il worker
Worker::runAll();

Utilizzo specifico di MySQL/Connection

// Inizializza la connessione al database
$db = new \Workerman\MySQL\Connection('host', 'port', 'user', 'password', 'nome_db');

// Ottieni tutti i dati
$db->select('ID,Sex')->from('Persons')->where('sex= :sex AND ID = :id')->bindValues(array('sex'=>'M', 'id' => 1))->query();
// Equivalente a
$db->select('ID,Sex')->from('Persons')->where("sex= 'M' AND ID = 1")->query();
// Equivalente a
$db->query("SELECT ID,Sex FROM `Persons` WHERE sex='M' AND ID = 1");

// Ottenere una riga di dati
$db->select('ID,Sex')->from('Persons')->where('sex= :sex')->bindValues(array('sex'=>'M'))->row();
// Equivalente a
$db->select('ID,Sex')->from('Persons')->where("sex= 'M' ")->row();
// Equivalente a
$db->row("SELECT ID,Sex FROM `Persons` WHERE sex='M'");

// Ottieni una colonna di dati
$db->select('ID')->from('Persons')->where('sex= :sex')->bindValues(array('sex'=>'M'))->column();
// Equivalente a
$db->select('ID')->from('Persons')->where("sex= 'F' ")->column();
// Equivalente a
$db->column("SELECT `ID` FROM `Persons` WHERE sex='M'");

// Ottieni un singolo valore
$db->select('ID')->from('Persons')->where('sex= :sex')->bindValues(array('sex'=>'M'))->single();
// Equivalente a
$db->select('ID')->from('Persons')->where("sex= 'F' ")->single();
// Equivalente a
$db->single("SELECT ID FROM `Persons` WHERE sex='M'");

// Query complessa
$db->select('*')->from('table1')->innerJoin('table2','table1.uid = table2.uid')->where('age > :age')->groupBy(array('aid'))->having('foo="foo"')->orderByASC/*orderByDESC*/(array('did'))
->limit(10)->offset(20)->bindValues(array('age' => 13));
// Equivalente a
$db->query('SELECT * FROM `table1` INNER JOIN `table2` ON `table1`.`uid` = `table2`.`uid`
WHERE age > 13 GROUP BY aid HAVING foo="foo" ORDER BY did LIMIT 10 OFFSET 20');

// Inserimento
$insert_id = $db->insert('Persons')->cols(array(
    'Firstname'=>'abc',
    'Lastname'=>'efg',
    'Sex'=>'M',
    'Age'=>13))->query();
Equivalente a
$insert_id = $db->query("INSERT INTO `Persons` ( `Firstname`,`Lastname`,`Sex`,`Age`)
VALUES ( 'abc', 'efg', 'M', 13)");

// Aggiornamento
$row_count = $db->update('Persons')->cols(array('sex'))->where('ID=1')
->bindValue('sex', 'F')->query();
// Equivalente a
$row_count = $db->update('Persons')->cols(array('sex'=>'F'))->where('ID=1')->query();
// Equivalente a
$row_count = $db->query("UPDATE `Persons` SET `sex` = 'F' WHERE ID=1");

// Cancellazione
$row_count = $db->delete('Persons')->where('ID=9')->query();
// Equivalente a
$row_count = $db->query("DELETE FROM `Persons` WHERE ID=9");

// Transazioni
$db->beginTrans();
....
$db->commitTrans(); // oppure $db->rollBackTrans();