PHP SQL 查找 ™ 和其他特殊字符
PHP SQL find ™ and other special characters
我有一个很大的 dB table,我需要在其中搜索和替换某些字符等。其中一些是特殊字符。
首先,我尝试在将语句更改为更新替换类型之前先查找。
低于 运行 可以
$Search_for = '%apple%';
但在特殊字符上失败
所以对于这个例子,我们将专注于 ™(从现场粘贴)
$search_what = 'LongDescription';
$Search_for = '%™%';
SearchToSee($conn,$search_what,$Search_for);
和函数
function SearchToSee ($conn,$search_what,$Search_for) {
$stmt = $conn->prepare(" SELECT * FROM table_name WHERE $search_what Like '$Search_for' ");
$stmt->execute();
foreach ( $stmt as $row ) {
print_r ($row);
}
那么我该如何格式化 $Search_for =
呢?
由于进一步的原因和其他系统,我必须运行每个找到不同的替换字符并替换为自己不同的字母。
到目前为止我已经尝试过:
在 PHP myadmin WHERE LongDescription
LIKE '%™%' 有效!!
在php:
$Search_for = '%apple%'; works but not special char
$Search_for = '%™%';// Not Working
$Search_for = '%_™%';// Not Working
$Search_for = '™';// Not Working
$Search_for = '%™%';// Not Working
我需要更改编码才能传递给 SQL 吗?
现在试过:
$Search_for2 = '™';
$Search_for3 = mb_convert_encoding($Search_for2, 'UTF-8', 'UTF-8');
echo $Search_for3;
$Search_for = '%'.$Search_for3.'%';
which echo's â„¢ and works for a proper term like "APPLE" 但仍然不是特殊字符。
先关闭,你说对了一部分。 Mysql 的编码必须正确。但我想这不是你的问题,因为 PHP 为你设置了 IIRC。只需执行 select '™';
并查看您是否在 PHP 中获得正确的反馈。如果不是,请检查您的编码设置。
但其次我怀疑问题存在的地方是您使用的排序规则。根据排序规则,特殊字符在处理字符串时会被忽略或视为其他字符。
排序规则是在客户端设置的,因此默认的 PHP 排序规则可能与 phpMyAdmin 设置的排序规则不同,导致您看到不同的行为。
select * from
(select 'privé' as word) as t
where word like '%e%'
以上是否会命中,取决于使用的排序规则。
但是下面肯定打不中:
select * from
(select 'privé' COLLATE utf8_bin as word) as t
where word like '%e%' COLLATE utf8_bin;
不过下次肯定还会再打:
select * from
(select 'privé' COLLATE utf8_general_ci as word) as t
where word like '%e%' COLLATE utf8_general_ci;
尝试检查 PHP 和 phpMyAdmin 中的排序规则和字符集:
select
@@collation_server,
@@collation_connection,
@@character_set_server,
@@character_set_client;
我可以给出的第三个建议 是检查您是否确实在存储和搜索完全相同的字符。如果我在 PHP 中执行 echo ord('™');
,我会得到 226
。会不会是你的储值和你搜索的值序数不一样?我不确定这是否可行,但也许您使用的是具有相同字符但序号不同的不同编码?
mysqli_set_charset('utf8') -- 或相关函数。
您显示的字符串片段暗示您有 "double encoding"。
执行 SELECT HEX(col), col FROM tbl WHERE ...
查看为 ™ 存储的内容。如果它以 utf8 格式正确存储,您应该看到 e284a2,当显示为 latin1 时,它显示“™”。如果它是双重编码的,那么您将得到十六进制 'C3A2E2809EC2A2' 或 'â„¢';
一旦我们确定数据是否正确存储,我们就可以专注于 INSERT 与 SELECT 中需要修复的内容。可能它在 PHP 代码中。
有关该问题的更多讨论,请参阅 http://mysql.rjweb.org/doc.php/charcoll。
编辑...
好的,我看到你有 space(20),TM(99),space(20).
的 latin1 编码
计划 A:一切都应该正常:如果列是 CHARACTER SET latin1
并且您在 PHP 中使用了 set_charset('utf8')
,那么事情应该 "just worked"。这是因为该组合应该已将 latin1 x99 to/from 转换为 utf8 xE284A2。假设是否错误?
B 计划:在 PHP 设置、html 元等中切换到 latin1
计划 C:修复表中的数据(并且可能不理会 PHP)。这可能涉及 ALTER 以转换表。当前是否将列定义为 CHARACTER SET latin1? (显示创建 TABLE。)
D计划:重新开始。 (这涉及删除表、重新创建它们、重新填充它们等。如果您刚刚开始使用数据库,这可能很实用。)
(没有"double encoding".)
感谢 Rick 和 Nl-X
结果是
<?php require_once(' dB connection....
PDO 不允许更改编码。
所以解决方案加一个
$conn2=mysqli_connect($servername,$username,$password,.......
$search_what = 'Table_Name';
$Search_for2 = '™';
$Search_for = '%'.$Search_for2.'%';
$Replace_with = 'TRADE MARK';
SearchToSee($conn2,$search_what,$Search_for,$Replace_with,$Search_for2);
和函数
function SearchToSee ($conn2,$search_what,$Search_for,$Replace_with,$Search_for2) {
mysqli_set_charset($conn2, 'utf8'); // change as required
mysqli_query($conn2, "SET NAMES 'utf8';");// change as required
mysqli_query($conn2, "SET CHARACTER SET 'utf8';");// change as required
mysqli_query($conn2, "SET COLLATION_CONNECTION = 'utf8_unicode_ci';"); // change as required
// below makes it simple to see what your changing
$result = mysqli_query($conn2, "SELECT * FROM $table WHERE $search_what Like '$Search_for'");
$result2 = mysqli_query($conn2, "select
@@collation_server,
@@collation_connection,
@@character_set_server,
@@character_set_client;");
foreach ($result2 as $grr) {
echo '<br>';
print_r ($grr);// shows result of new settings need to match last line
echo '<br>Array ( [@@collation_server] => latin1_swedish_ci [@@collation_connection] => latin1_swedish_ci [@@character_set_server] => latin1 [@@character_set_client] => latin1 ) '; // original N/W $grr
echo '<br>latin1_swedish_ci ---- utf8_general_ci ---- latin1 ----- utf8 <br><br>'; // from @@ checks in phpmyadmin on table.
}
// TO Update
mysqli_query($conn2, "UPDATE Table_Name SET $search_what = replace($search_what, '$Search_for2', '$Replace_with') WHERE $search_what Like '$Search_for'");
}
希望对某人有所帮助。
我有一个很大的 dB table,我需要在其中搜索和替换某些字符等。其中一些是特殊字符。
首先,我尝试在将语句更改为更新替换类型之前先查找。
低于 运行 可以
$Search_for = '%apple%';
但在特殊字符上失败
所以对于这个例子,我们将专注于 ™(从现场粘贴)
$search_what = 'LongDescription';
$Search_for = '%™%';
SearchToSee($conn,$search_what,$Search_for);
和函数
function SearchToSee ($conn,$search_what,$Search_for) {
$stmt = $conn->prepare(" SELECT * FROM table_name WHERE $search_what Like '$Search_for' ");
$stmt->execute();
foreach ( $stmt as $row ) {
print_r ($row);
}
那么我该如何格式化 $Search_for =
呢?
由于进一步的原因和其他系统,我必须运行每个找到不同的替换字符并替换为自己不同的字母。
到目前为止我已经尝试过:
在 PHP myadmin WHERE LongDescription
LIKE '%™%' 有效!!
在php:
$Search_for = '%apple%'; works but not special char
$Search_for = '%™%';// Not Working
$Search_for = '%_™%';// Not Working
$Search_for = '™';// Not Working
$Search_for = '%™%';// Not Working
我需要更改编码才能传递给 SQL 吗?
现在试过:
$Search_for2 = '™';
$Search_for3 = mb_convert_encoding($Search_for2, 'UTF-8', 'UTF-8');
echo $Search_for3;
$Search_for = '%'.$Search_for3.'%';
which echo's â„¢ and works for a proper term like "APPLE" 但仍然不是特殊字符。
先关闭,你说对了一部分。 Mysql 的编码必须正确。但我想这不是你的问题,因为 PHP 为你设置了 IIRC。只需执行 select '™';
并查看您是否在 PHP 中获得正确的反馈。如果不是,请检查您的编码设置。
但其次我怀疑问题存在的地方是您使用的排序规则。根据排序规则,特殊字符在处理字符串时会被忽略或视为其他字符。
排序规则是在客户端设置的,因此默认的 PHP 排序规则可能与 phpMyAdmin 设置的排序规则不同,导致您看到不同的行为。
select * from
(select 'privé' as word) as t
where word like '%e%'
以上是否会命中,取决于使用的排序规则。
但是下面肯定打不中:
select * from
(select 'privé' COLLATE utf8_bin as word) as t
where word like '%e%' COLLATE utf8_bin;
不过下次肯定还会再打:
select * from
(select 'privé' COLLATE utf8_general_ci as word) as t
where word like '%e%' COLLATE utf8_general_ci;
尝试检查 PHP 和 phpMyAdmin 中的排序规则和字符集:
select
@@collation_server,
@@collation_connection,
@@character_set_server,
@@character_set_client;
我可以给出的第三个建议 是检查您是否确实在存储和搜索完全相同的字符。如果我在 PHP 中执行 echo ord('™');
,我会得到 226
。会不会是你的储值和你搜索的值序数不一样?我不确定这是否可行,但也许您使用的是具有相同字符但序号不同的不同编码?
mysqli_set_charset('utf8') -- 或相关函数。
您显示的字符串片段暗示您有 "double encoding"。
执行 SELECT HEX(col), col FROM tbl WHERE ...
查看为 ™ 存储的内容。如果它以 utf8 格式正确存储,您应该看到 e284a2,当显示为 latin1 时,它显示“™”。如果它是双重编码的,那么您将得到十六进制 'C3A2E2809EC2A2' 或 'â„¢';
一旦我们确定数据是否正确存储,我们就可以专注于 INSERT 与 SELECT 中需要修复的内容。可能它在 PHP 代码中。
有关该问题的更多讨论,请参阅 http://mysql.rjweb.org/doc.php/charcoll。
编辑...
好的,我看到你有 space(20),TM(99),space(20).
的 latin1 编码计划 A:一切都应该正常:如果列是 CHARACTER SET latin1
并且您在 PHP 中使用了 set_charset('utf8')
,那么事情应该 "just worked"。这是因为该组合应该已将 latin1 x99 to/from 转换为 utf8 xE284A2。假设是否错误?
B 计划:在 PHP 设置、html 元等中切换到 latin1
计划 C:修复表中的数据(并且可能不理会 PHP)。这可能涉及 ALTER 以转换表。当前是否将列定义为 CHARACTER SET latin1? (显示创建 TABLE。)
D计划:重新开始。 (这涉及删除表、重新创建它们、重新填充它们等。如果您刚刚开始使用数据库,这可能很实用。)
(没有"double encoding".)
感谢 Rick 和 Nl-X 结果是
<?php require_once(' dB connection....
PDO 不允许更改编码。
所以解决方案加一个
$conn2=mysqli_connect($servername,$username,$password,.......
$search_what = 'Table_Name';
$Search_for2 = '™';
$Search_for = '%'.$Search_for2.'%';
$Replace_with = 'TRADE MARK';
SearchToSee($conn2,$search_what,$Search_for,$Replace_with,$Search_for2);
和函数
function SearchToSee ($conn2,$search_what,$Search_for,$Replace_with,$Search_for2) {
mysqli_set_charset($conn2, 'utf8'); // change as required
mysqli_query($conn2, "SET NAMES 'utf8';");// change as required
mysqli_query($conn2, "SET CHARACTER SET 'utf8';");// change as required
mysqli_query($conn2, "SET COLLATION_CONNECTION = 'utf8_unicode_ci';"); // change as required
// below makes it simple to see what your changing
$result = mysqli_query($conn2, "SELECT * FROM $table WHERE $search_what Like '$Search_for'");
$result2 = mysqli_query($conn2, "select
@@collation_server,
@@collation_connection,
@@character_set_server,
@@character_set_client;");
foreach ($result2 as $grr) {
echo '<br>';
print_r ($grr);// shows result of new settings need to match last line
echo '<br>Array ( [@@collation_server] => latin1_swedish_ci [@@collation_connection] => latin1_swedish_ci [@@character_set_server] => latin1 [@@character_set_client] => latin1 ) '; // original N/W $grr
echo '<br>latin1_swedish_ci ---- utf8_general_ci ---- latin1 ----- utf8 <br><br>'; // from @@ checks in phpmyadmin on table.
}
// TO Update
mysqli_query($conn2, "UPDATE Table_Name SET $search_what = replace($search_what, '$Search_for2', '$Replace_with') WHERE $search_what Like '$Search_for'");
}
希望对某人有所帮助。