Translated using Weblate (Portuguese)
[phpmyadmin.git] / src / Charsets.php
blob3b5a573bdbe8ba1878209a810930fd948f181f93
1 <?php
2 /**
3 * MySQL charset metadata and manipulations
4 */
6 declare(strict_types=1);
8 namespace PhpMyAdmin;
10 use PhpMyAdmin\Charsets\Charset;
11 use PhpMyAdmin\Charsets\Collation;
12 use PhpMyAdmin\Dbal\DatabaseInterface;
14 use function __;
15 use function array_keys;
16 use function explode;
17 use function is_string;
18 use function ksort;
20 use const SORT_STRING;
22 /**
23 * Class used to manage MySQL charsets
25 class Charsets
27 /**
28 * MySQL charsets map
30 * @var array<string, string>
32 public static array $mysqlCharsetMap = [
33 'big5' => 'big5',
34 'cp-866' => 'cp866',
35 'euc-jp' => 'ujis',
36 'euc-kr' => 'euckr',
37 'gb2312' => 'gb2312',
38 'gbk' => 'gbk',
39 'iso-8859-1' => 'latin1',
40 'iso-8859-2' => 'latin2',
41 'iso-8859-7' => 'greek',
42 'iso-8859-8' => 'hebrew',
43 'iso-8859-8-i' => 'hebrew',
44 'iso-8859-9' => 'latin5',
45 'iso-8859-13' => 'latin7',
46 'iso-8859-15' => 'latin1',
47 'koi8-r' => 'koi8r',
48 'shift_jis' => 'sjis',
49 'tis-620' => 'tis620',
50 'utf-8' => 'utf8',
51 'windows-1250' => 'cp1250',
52 'windows-1251' => 'cp1251',
53 'windows-1252' => 'latin1',
54 'windows-1256' => 'cp1256',
55 'windows-1257' => 'cp1257',
58 /**
59 * The charset for the server
61 private static Charset|null $serverCharset = null;
63 /** @var array<string, Charset> */
64 private static array $charsets = [];
66 /** @var array<string, array<string, Collation>> */
67 private static array $collations = [];
69 /**
70 * Loads charset data from the server
72 * @param bool $disableIs Disable use of INFORMATION_SCHEMA
74 private static function loadCharsets(DatabaseInterface $dbi, bool $disableIs): void
76 /* Data already loaded */
77 if (self::$charsets !== []) {
78 return;
81 $sql = 'SELECT `CHARACTER_SET_NAME` AS `Charset`,'
82 . ' `DEFAULT_COLLATE_NAME` AS `Default collation`,'
83 . ' `DESCRIPTION` AS `Description`,'
84 . ' `MAXLEN` AS `Maxlen`'
85 . ' FROM `information_schema`.`CHARACTER_SETS`';
87 if ($disableIs) {
88 $sql = 'SHOW CHARACTER SET';
91 $res = $dbi->query($sql);
93 self::$charsets = [];
94 foreach ($res as $row) {
95 self::$charsets[$row['Charset']] = Charset::fromServer($row);
98 ksort(self::$charsets, SORT_STRING);
102 * Loads collation data from the server
104 * @param bool $disableIs Disable use of INFORMATION_SCHEMA
106 private static function loadCollations(DatabaseInterface $dbi, bool $disableIs): void
108 /* Data already loaded */
109 if (self::$collations !== []) {
110 return;
113 if ($dbi->isMariaDB() && $dbi->getVersion() >= 101000) {
114 /* Use query to accommodate new structure of MariaDB collations.
115 Note, that SHOW COLLATION command is not applicable at the time of writing.
116 Refer https://jira.mariadb.org/browse/MDEV-27009 */
117 $sql = 'SELECT `collapp`.`FULL_COLLATION_NAME` AS `Collation`,'
118 . ' `collapp`.`CHARACTER_SET_NAME` AS `Charset`,'
119 . ' `collapp`.`ID` AS `Id`,'
120 . ' `collapp`.`IS_DEFAULT` AS `Default`,'
121 . ' `coll`.`IS_COMPILED` AS `Compiled`,'
122 . ' `coll`.`SORTLEN` AS `Sortlen`'
123 . ' FROM `information_schema`.`COLLATION_CHARACTER_SET_APPLICABILITY` `collapp`'
124 . ' LEFT JOIN `information_schema`.`COLLATIONS` `coll`'
125 . ' ON `collapp`.`COLLATION_NAME`=`coll`.`COLLATION_NAME`';
126 } else {
127 $sql = 'SELECT `COLLATION_NAME` AS `Collation`,'
128 . ' `CHARACTER_SET_NAME` AS `Charset`,'
129 . ' `ID` AS `Id`,'
130 . ' `IS_DEFAULT` AS `Default`,'
131 . ' `IS_COMPILED` AS `Compiled`,'
132 . ' `SORTLEN` AS `Sortlen`'
133 . ' FROM `information_schema`.`COLLATIONS`';
135 if ($disableIs) {
136 $sql = 'SHOW COLLATION';
140 $res = $dbi->query($sql);
142 self::$collations = [];
143 foreach ($res as $row) {
144 self::$collations[$row['Charset']][$row['Collation']] = Collation::fromServer($row);
147 foreach (array_keys(self::$collations) as $charset) {
148 ksort(self::$collations[$charset], SORT_STRING);
153 * Get current server charset
155 * @param bool $disableIs Disable use of INFORMATION_SCHEMA
157 public static function getServerCharset(DatabaseInterface $dbi, bool $disableIs): Charset
159 if (self::$serverCharset !== null) {
160 return self::$serverCharset;
163 self::loadCharsets($dbi, $disableIs);
164 $serverCharset = $dbi->getVariable('character_set_server');
165 if (! is_string($serverCharset)) {// MySQL 5.7.8 fallback, issue #15614
166 $serverCharset = $dbi->fetchValue('SELECT @@character_set_server;');
169 self::$serverCharset = self::$charsets[$serverCharset] ?? null;
171 // MySQL 8.0.11+ fallback, issue #16931
172 if (self::$serverCharset === null && $serverCharset === 'utf8mb3') {
173 // See: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-11.html#mysqld-8-0-11-charset
174 // The utf8mb3 character set will be replaced by utf8mb4 in a future MySQL version.
175 // The utf8 character set is currently an alias for utf8mb3,
176 // but will at that point become a reference to utf8mb4.
177 // To avoid ambiguity about the meaning of utf8,
178 // consider specifying utf8mb4 explicitly for character set references instead of utf8.
179 // Warning: #3719 'utf8' is currently an alias for the character set UTF8MB3 [...]
180 return self::$charsets['utf8'];
183 return self::$serverCharset ?? Charset::fromServer(
184 ['Charset' => __('Unknown'), 'Description' => __('Unknown')],
189 * Get all server charsets
191 * @param bool $disableIs Disable use of INFORMATION_SCHEMA
193 * @return array<string, Charset>
195 public static function getCharsets(DatabaseInterface $dbi, bool $disableIs): array
197 self::loadCharsets($dbi, $disableIs);
199 return self::$charsets;
203 * Get all server collations
205 * @param bool $disableIs Disable use of INFORMATION_SCHEMA
207 * @return array<string, array<string, Collation>>
209 public static function getCollations(DatabaseInterface $dbi, bool $disableIs): array
211 self::loadCollations($dbi, $disableIs);
213 return self::$collations;
217 * @param bool $disableIs Disable use of INFORMATION_SCHEMA
218 * @param string $name Collation name
220 public static function findCollationByName(
221 DatabaseInterface $dbi,
222 bool $disableIs,
223 string $name,
224 ): Collation|null {
225 $charset = explode('_', $name)[0];
226 $collations = self::getCollations($dbi, $disableIs);
228 return $collations[$charset][$name] ?? null;