I have a Laravel application that works with a database with charset latin1
(I cannot change it).
In my .env
I have the following configuration:
DB_CONNECTION_INTRANET=mysql
DB_HOST_INTRANET=xxxxx
DB_PORT_INTRANET=3306
DB_DATABASE_INTRANET=xxx
DB_USERNAME_INTRANET=xxx
DB_PASSWORD_INTRANET=xxx
DB_CHARSET_INTRANET='latin1'
DB_COLLATION_INTRANET='latin1_swedish_ci'
In config/database.php
I use this configuration:
'mysqlIntranet' => [
'driver' => env('DB_CONNECTION_INTRANET'),
'host' => env('DB_HOST_INTRANET'),
'port' => env('DB_PORT_INTRANET'),
'database' => env('DB_DATABASE_INTRANET'),
'username' => env('DB_USERNAME_INTRANET'),
'password' => env('DB_PASSWORD_INTRANET'),
'unix_socket' => env('DB_SOCKET_INTRANET', ''),
'charset' => env('DB_CHARSET_INTRANET'),
'collation' => env('DB_COLLATION_INTRANET'),
],
And the model use this connection:
class Cliente extends Model
{
protected $connection = 'mysqlIntranet';
When I perform SELECT estado FROM clientes
(I work from console) I get the following result:
+---------------+
| estado |
+---------------+
| Informado |
| Contratación |
However, although I configure charset in Laravel, when I run this code:
$client = Cliente::query()->first();
$estado = $client->getAttribute('estado');
var_dump($estado . " - " . mb_detect_encoding($estado));
$estado2 = utf8_encode($estado);
var_dump($estado2 . " - " . mb_detect_encoding($estado2));
I get this strange result:
string(20) "Contrataci�n - UTF-8"
string(21) "Contratación - UTF-8"
I don't understand why the configuration of .env
doesn't do the work - any ideas?
====================== UPDATE ======================
I tried to simulate the problem in local, and found out that Laravel works fine. I created this DB:
CREATE DATABASE my_db CHARACTER SET latin1 COLLATE latin1_swedish_ci;
with .env
values:
DB_CHARSET_INTRANET="latin1"
DB_COLLATION_INTRANET='latin1_swedish_ci'
and everything worked fine, as expected.
I decided to try setting the following configuration in my server:
DB_CHARSET_INTRANET="utf8"
DB_COLLATION_INTRANET='utf8_general_ci'
and to my big surprise I managed to retrieve the values correctly!
Just in case, I checked directly in the MySql server:
> SELECT * FROM information_schema.SCHEMATA WHERE schema_name = "xxx";
+--------------+-------------+----------------------------+------------------------+----------+
| CATALOG_NAME | SCHEMA_NAME | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH |
+--------------+-------------+----------------------------+------------------------+----------+
| NULL | xxx | latin1 | latin1_swedish_ci | NULL |
+--------------+-------------+----------------------------+------------------------+----------+
> SELECT T.table_name, CCSA.*
FROM information_schema.`TABLES` T, information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA
WHERE CCSA.collation_name = T.table_collation AND T.table_schema = "xxx";
+-------------+-------------------+--------------------+
| table_name | COLLATION_NAME | CHARACTER_SET_NAME |
+-------------+-------------------+--------------------+
| clientes | latin1_swedish_ci | latin1 |
| clientes_sm | latin1_swedish_ci | latin1 |
+-------------+-------------------+--------------------+
So now I have things work, I would only like to understand why...