1

My table:

+--------+----------+
| U_COD  |  U_NAME  |
+--------+----------+
|   01   |  Daniel  |
+--------+----------+
|   02   |  Ñandu   |
+--------+----------+
|   03   |  Pañ     |
+--------+----------+

I am connecting and doing a simple query to my firebird database like this:

$host = 'firebird:dbname=my/dir/db_test.gdb;charset=UTF8';
$password = 'mypass';
$username = 'myuname';

try{
  $db = new PDO($host, $username, $password);
  $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
}catch(PDOException $e){
  echo "Failed: " . $e->getMessage();
}

$getData=$db->prepare("SELECT * FROM T_TEST ORDER BY U_NAME ASC");
$getData->execute();
$arrData=$getData->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($arrData);

But when I run the file, all the values ​​that in my database include some "ñ" letter appear as null, like this:

[
    {"U_COD":"01","U_NAME":"Daniel"}, 
    {"U_COD":"02","U_NAME":null},
    {"U_COD":"03","U_NAME":null}
]

I would like to know what I'm doing wrong, let me know if you need any other details from my firebird database.

EDIT

a var_dump($arrData) shows the values but with a "�" when there should be a "ñ" letter:

array(3) {
  [0]=>
  array(2) {
    ["U_COD"]=>
    string(2) "01"
    ["U_NAME"]=>
    string(6) "Daniel"
  },
  array(2) {
    ["U_COD"]=>
    string(2) "02"
    ["U_NAME"]=>
    string(5) "�andu"
  },
  array(2) {
    ["U_COD"]=>
    string(2) "03"
    ["U_NAME"]=>
    string(3) "Pa�"
  }
}
  • Maybe this will help https://stackoverflow.com/questions/4475548/pdo-mysql-and-broken-utf-8-encoding/21373793 – RiggsFolly Jan 11 '21 at 17:19
  • @RiggsFolly Ok, I've tryed those solutions but no one solved my problem, maybe it is a firebase problem. – Roberto Sepúlveda Jan 11 '21 at 18:40
  • maybe this should be my first question: ¿Is php+pdo+firebase utf8 compatible? – Roberto Sepúlveda Jan 11 '21 at 18:45
  • Did you read the firebird tag info.... Please quote your firebird version on all questions – RiggsFolly Jan 11 '21 at 18:56
  • @RiggsFolly it is v 2.5 – Roberto Sepúlveda Jan 11 '21 at 19:12
  • What is the character set of column `U_NAME`? – Mark Rotteveel Jan 12 '21 at 08:56
  • 1
    See the "chat" column on the right and the queries used to diagnose charset settings in different PHP and Firebird aspects at https://topanswers.xyz/databases?q=1462 – Arioch 'The Jan 13 '21 at 12:23
  • @Arioch'The Ive executed that query in the same code above and the json throws the following: `[{"RDB$CHARACTER_SET_NAME":"NONE "}]` – Roberto Sepúlveda Jan 13 '21 at 17:53
  • this result: `"NONE "` has too many white spaces, is that normal? – Roberto Sepúlveda Jan 13 '21 at 18:18
  • use `TRIM` funciton if you don't like it. That is how SQL standard defines CHAR typed columns vs VARCHAR typed ones – Arioch 'The Jan 14 '21 at 06:47
  • I do not know intrinsics about PDO library, but your general course is that both database and conneciton should have explicit charsets declared, UTF8 or some MBCS maybe like WIN1251 for Russian (Firebird Char/Varchar columns have 32KB size limit and in UTF8 one letter stands for 4 bytes, sometimes it matters), see the talk in that link about charsets and how they work together, there is much more than one query there! Also https://blog.codinghorror.com/there-aint-no-such-thing-as-plain-text/ – Arioch 'The Jan 14 '21 at 06:51

1 Answers1

2

The problem is that the character set of the column is NONE, and there is probably a mismatch between the bytes stored in the column (for example it was stored using an encoding like WIN1252), and your connection character set (UTF8). Given the source column has no explicit character set, Firebird cannot transliterate the characters to the connection character set, and instead the bytes are sent as is, and the byte for ñ is not valid in UTF8, so PHP replaces it with the unicode replacement character.

As a short term solution, you could try to explicitly specify the correct connection character set (eg WIN1252) or explicitly cast the column (eg cast(U_NAME as varchar(100) character set win1252)), but for the long term solution, you need to make sure that you define your columns with an explicit character set. In your current setup, you are likely logically corrupting your data if you write data from multiple applications, each using their own implicit or explicit connection character set (eg one application writes using WIN1252, another using UTF8, then - without an explicit character set of the column - one cannot correctly read data written by the other).

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • I get it. The firebird database was created by using Delphi 5.0, I am trying to read the data with php7. What do you recommmend me to do? – Roberto Sepúlveda Jan 18 '21 at 18:12
  • @RobertoSepúlveda See the second paragraph. The simplest is probably to recreate your database structure with an explicit character set and pump the data (making sure the correct character set is used). A short term workaround is probably to use a different connection character set (one that matches the actual character set of the stored data). – Mark Rotteveel Jan 19 '21 at 10:59
  • from this answer ive being searching the solution and with this code line at the top of my php file im now getting all the "ñ" letters correctly: `header('Content-type: text/plain; charset=ISO-8859-1');`. Ive tryed with many charsets and finally that helped. The only missing thing is that `json_encode` still puts null values when "ñ" appears, so Ive solved it by iterating the result and making the json string "by hand". – Roberto Sepúlveda Jan 25 '21 at 18:18