简体   繁体   English

PHP SQL find™和其他特殊字符

[英]PHP SQL find ™ and other special characters

I have a large dB table where I need to search and replace certain char etc. Some of these are special char. 我有一个很大的dB表,我需要在其中搜索和替换某些字符等。其中一些是特殊字符。

First I am trying just find before changing the statement to Update replace type. 首先,我尝试在将语句更改为Update replace type之前找到。

Below runs ok for 下面可以运行

$Search_for = '%apple%'; 

But fails on Special char 但是在特殊字符上失败

So for this example we will concentrate on the ™ ( as pasted from the field) 因此,在此示例中,我们将专注于™(从字段粘贴)

$search_what = 'LongDescription';
$Search_for = '%™%';
SearchToSee($conn,$search_what,$Search_for);

and the function 和功能

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

So how do I format the $Search_for = ? 那么如何格式化$Search_for =

For reason further on and other systems I have to run each find replace char differently and replace with its own different letters. 出于其他原因,我必须在其他系统上运行每个find,它们以不同的方式替换char并以其自己的不同字母进行替换。

So Far I have tried: 到目前为止,我已经尝试过:

in PHP myadmin WHERE LongDescription LIKE '%™%' works !! 在PHP myadmin中, LongDescription就像'%™%'一样有效!

in the php: 在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

Do I need to change the encoding to pass to SQL ? 我需要更改编码以传递给SQL吗?

Now tried: 现在尝试:

        $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" but still not special characters. 哪个回声为?,并且适用于“ APPLE”之类的专有名词,但仍不是特殊字符。

First off, you are partially correct. 首先 ,您部分正确。 The encoding towards Mysql must be correct. Mysql的编码必须正确。 But I guess that is not your problem, as PHP sets this for you IIRC. 但是我想这不是您的问题,因为PHP为您设置了IIRC。 Just do a select '™'; 只需select '™';一个select '™'; and see if you are getting the correct feedback in PHP. 并查看您是否在PHP中获得正确的反馈。 If not, check your encoding settings. 如果没有,请检查您的编码设置。

But secondly where I would suspect the problem to exist, is the collation that you use. 但是第二 ,我怀疑存在问题的地方是您使用的排序规则。 Depending on the collation special characters are ignored or seen as others when working with strings. 根据排序规则,使用字符串时会忽略特殊字符或将其视为其他字符。

Collations are set client side, so it could be that the default PHP collation is different from the one set by phpMyAdmin, causing the different behaviour you see. 排序规则是在客户端设置的,因此默认的PHP排序规则可能与phpMyAdmin设置的排序规则不同,从而导致您看到不同的行为。

select * from
  (select 'privé' as word) as t
where word like '%e%'

The above will or will not hit, depending on which collations are used. 上面的内容是否会命中,取决于所使用的归类。

But the below will certainly not hit: 但是以下内容肯定不会成功:

select * from
  (select 'privé' COLLATE utf8_bin as word) as t
where word like '%e%' COLLATE utf8_bin;

But the next will again certainly hit: 但是下一个肯定会再次出现:

select * from
  (select 'privé' COLLATE utf8_general_ci as word) as t
where word like '%e%' COLLATE utf8_general_ci;

Try checking your collations and character sets from PHP and phpMyAdmin with: 尝试使用以下命令从PHP和phpMyAdmin检查归类和字符集:

select
  @@collation_server,
  @@collation_connection,
  @@character_set_server,
  @@character_set_client;

A third suggestion that I can give is to check if you indeed are storing and searching for the exact same character. 我可以提出的第三个建议是检查您是否确实在存储和搜索完全相同的字符。 If I do echo ord('™'); 如果我echo ord('™'); in PHP, I get 226 . 在PHP中,我得到226 Could it be that your stored value and value that you search with have different ordinal values? 可能是您的储值和搜索的值具有不同的序数值吗? I'm not sure this is possible, but maybe you are using different encodings that have the same character with different ordinal values? 我不确定这是否可行,但也许您使用的是具有相同字符且具有不同序数值的不同编码?

mysqli_set_charset('utf8') -- or related function. mysqli_set_charset('utf8')-或相关功能。

The snippets of strings you showed imply you have "double encoding". 您显示的字符串摘要意味着您具有“双重编码”。

Do SELECT HEX(col), col FROM tbl WHERE ... to see what was stored for ™. SELECT HEX(col), col FROM tbl WHERE ...以查看为™存储了什么。 If it is stored in correctly as utf8, you should see e284a2, which, when displayed as latin1, show "â„¢". 如果它以utf8的形式正确存储,则应该看到e284a2,当显示为latin1时,它显示为“⢢”。 If it is double-encoded then you will get hex 'C3A2E2809EC2A2' or 'â„¢'; 如果是双重编码,则将得到十六进制的“ C3A2E2809EC2A2”或“—。

Once we determine whether the data is stored correctly, we can focus on what needs fixing in the INSERT versus the SELECT. 一旦确定了数据是否正确存储 ,我们就可以专注于需要在INSERT和SELECT中修复的内容。 Possibly it is in the PHP code. 可能在PHP代码中。

For more discussion of the problem, see http://mysql.rjweb.org/doc.php/charcoll . 有关该问题的更多讨论,请参见http://mysql.rjweb.org/doc.php/charcoll

Edit... 编辑...

OK, I see that you have latin1 encoding for space(20),TM(99),space(20). 好的,我看到您对space(20),TM(99),space(20)具有latin1编码。

Plan A: Everything should be working: If the column is CHARACTER SET latin1 and you used set_charset('utf8') in PHP, then things should have "just worked". 计划A:一切都应该正常工作:如果set_charset('utf8') CHARACTER SET latin1并且您在PHP中使用了set_charset('utf8') ,那么事情应该就“正常”了。 This is because that combination should have converted the latin1 x99 to/from the utf8 xE284A2. 这是因为该组合应该已将latin1 x99转换为utf8 xE284A2,或从其中转换。 Are assumptions wrong? 假设是否错误?

Plan B: Switch to latin1 in PHP settings, html meta, etc. 方案B:在PHP设置,html meta等中切换到latin1。

Plan C: Fix the data in the tables (and probably leave the PHP alone). 计划C:修复表中的数据(并且可能不使用PHP)。 This probably involves an ALTER to CONVERT the tables. 这可能涉及更改表的ALTER。 Are the column(s) currently defined as CHARACTER SET latin1? 该列当前是否定义为CHARACTER SET latin1? (Do SHOW CREATE TABLE.) (执行SHOW CREATE TABLE。)

Plan D: Start over. 计划D:重新开始。 (This involves dropping the tables, recreating them, re-populating them, etc. -- This may be practical if you are just now starting with the database.) (这涉及删除表,重新创建它们,重新填充它们,等等。-如果您刚刚从数据库开始,这可能是实用的。)

(There is no "double encoding".) (没有“双重编码”。)

Thanks to Rick and Nl-X Turns out that in the 感谢Rick和Nl-X在

    <?php require_once(' dB connection.... 

it was PDO which would not allow the encoding to be changed. 是PDO,它不允许更改编码。

So solution add a 所以解决方案添加一个

     $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);

and the function 和功能

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

Hope that helps someone. 希望能对某人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM