[Risolto] Errore Sqlstate[22021] Nel Caricamento Di Un File Nel Db

Ho seguito questo piccolo wiki:

http://www.yiiframework.com/wiki/2/

per poter implementare un caricamento di un file nel db.

L’errore riportato è il seguente:




CDbCommand ha riportato un errore nell'esecuzione della query SQL: SQLSTATE[22021]: Character not in repertoire: 7 ERROR: invalid byte sequence for encoding "UTF8": 0xc7ec. 



Io utilizzo postgres e come tipo per l’attributo ho scelto bytea.

Mi sembra un errore del pdo più che di yii, io ho seguito alla lettera il wiki.

Cosa mi consigliate per aggirare il problema?

Hai in problema di encoding, non so come sistemarlo con postrees, ma con mysql si fa una set names utf8

ho già settato il db nel main.php con

‘charset’ => ‘utf8’,

non dovrebbe comportarsi come il set names ?

Per aggirare il problema, … io non salverei l’immagine nel database.

Ho letto un pò in giro di questo errore ricorrente (non in yii), ho googlato, ho provato e riprovato

alla fine sto utilizzando una soluzione accettabile.

all’inizio son riuscito ad evitare l’errore in oggetto in questo modo:




$this->file_content = pg_escape_bytea(file_get_contents($file->tempName));



in effetti col query browser di pgAdmin riuscivo a vedere che qualcosa era stato memorizzato.

Al momento dell’estrazione però, anche passandogli un pg_unscape_bytea il file estratto era corrotto.

Poi mi sono imbattuto in un fix su github:

con titolo: can read but not save binary data e.g. BYTEA on PostgreSQL. Ok che non salvasse ma almeno doveva leggerli :D … intanto ho fixato il file CDbConnection.php come su github (uscirà sulla 1.1.13), e poi ho cambiato strada,

ho capito che l’Active Record non trattava il dato come doveva esser trattato, quindi a questo punto per il caricamento mi sono costruito una query facendo il bind dei parametri e in particolare PDO::PARAM_LOB, parametro aggiunto con il fix del file di Yii:




$sql="UPDATE ".$t." SET file_content=:file_content WHERE id=:id";

$connection = Yii::app()->db;

$command=$connection->createCommand($sql);

// bind bytea

$command->bindParam(":file_content",file_get_contents($file->tempName),PDO::PARAM_LOB);

$command->bindParam(":id",$a->id,PDO::PARAM_INT);

$command->execute();



e per l’estrazione:




$connection = Yii::app()->db;

$sql="SELECT file_size,file_type,file_name,file_content FROM ".$t." WHERE stato_progetto=$id";

$dataReader=$connection->createCommand($sql)->query();


$dataReader->bindColumn(1,$file_size);

$dataReader->bindColumn(2,$file_type);

$dataReader->bindColumn(3,$file_name);

$dataReader->bindColumn(4,$file_content);

		

while($dataReader->read()!==false)

{

	header('Pragma: public');

	header('Expires: 0');

	header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

	header('Content-Transfer-Encoding: binary');

	header('Content-length: '.$file_size);

	header('Content-Type: '.$file_type);

	header('Content-Disposition: attachment; filename='.$file_name);

	echo $file_content;

}



anche nell’estrazione ho provato a caricare il model ma $model->file_content, restituisce un riferimento

e non il file.

Spero possa servire a qualcuno quest’altra avventura.

Se avete consigli, ovviamente, sempre bene accetti.

Sembra un bug della cdbconnnetion per postgree, io salvo i file con mysql e non ho mai avuto problemi.

Se hai chiaro come fare scattare l’errore prova a scrivere un post nel forum dei bug, cosi’ gli sviluppatori se ne accorgono e ti possono quanto meno dire se e’ un errore o se stai sbagliando qualcosa.

certo. ho aperto un issue, vi faccio sapere.