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'");              
}

希望对某人有所帮助。