0

I'm working on a project where I use php to grab a random greek word from a xampp sql server . I then use str_shuffle() to randomize the word order (ex. bye => ybe).However using str_shuffle() on greek letters returns the word with many ???? in place of most greek letters . If I remove str_shuffle() from my code the greek word is displayed correctly with no ??? . I have written code that ensures I have the correct encoding but str_shuffle() is the problem .

<h1 id = "hidden-word">The word is :
                <?php 
                    
                    $link = mysqli_connect('localhost' , 'root' , '' ,'dodecanese');
                    if(!$link){
                        echo 'Error connecting to DB';
                        exit;
                    }

                    mysqli_query($link,"SET NAMES 'utf8'");

                    $query = "SELECT island_name FROM dodecanese ORDER BY RAND() LIMIT 1";
                    $result = mysqli_query($link, $query);
                    if(!$result){
                        echo 'There is an issue with the DB';
                        exit;
                    }
                    $row = mysqli_fetch_assoc($result); 
                    //str shuffle creates ?
                    echo '<span id = "random-island">'.str_shuffle($row['island_name']). '</span>';
                ?>
        
</h1> 

I also have encoding <meta charset="utf-8"/> on html . I have seen many posts about this and especially the UTF-8 all the way through but it did not help . I would appreciate your help with this . Thank you in advance .

Preben Huybrechts
  • 5,853
  • 2
  • 27
  • 63
vasilis 123
  • 585
  • 1
  • 12
  • 26
  • `str_shuffle` is not relevant. It's the storage of Greek that seems to be the issue. See "question mark" in https://stackoverflow.com/questions/38363566/trouble-with-utf8-characters-what-i-see-is-not-what-i-stored – Rick James Jul 30 '20 at 15:30

2 Answers2

1

I've looked in the the PHP manual for str_shuffle and found out in the comments that indeed there are problems with some unicode chars.

But there is also a solution there - which I've tested for you, and it works:

<?php

function str_shuffle_unicode($str) {
    $tmp = preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
    shuffle($tmp);
    return join("", $tmp);
}


$a = "γκξπψ";
$b = str_shuffle($a);
$c = str_shuffle_unicode($a);

echo $a; // γκξπψ
echo "<br/>str_shuffle: ".$b; // ξ��κ�ψ�
echo "<br/>str_shuffle_unicode: ".$c; // κξγπψ
?>
Dharman
  • 30,962
  • 25
  • 85
  • 135
verjas
  • 1,793
  • 1
  • 15
  • 18
0

Unfortunately str_shuffle() does not work with multibyte characters and there is no (or at least I do not know such) built-in function to do that. As a workaround you can write one your own. For example the below code will split the string into array of single letters, shuffle the array and then join its elements back to string (I used Cyrillic letters for the example):

$str = "абвгдежзий";
$temp = mb_str_split($str,1);
shuffle($temp);
$str = join("", $temp);
echo $str;

The above function mb_str_split is a PHP 7.4+ only. If you are using earlier version, you can use preg_split:

$str = "абвгдежзий";
$temp = preg_split("//u", $str, 0);
shuffle($temp);
$str = join("", $temp);
echo $str;

the more uncomfortable preg_match_all:

$str = "абвгдежзий";
preg_match_all('/./u', $str, $temp);
shuffle($temp[0]);
$str = join("", $temp[0]);
echo $str;

or even looping and adding to the array char-by-char (that way you save a regex call):

$str = "абвгдежзий";
$len = mb_strlen($str, 'UTF-8');
$temp = [];
for ($i = 0; $i < $len; $i++) {
    $temp[] = mb_substr($str, $i, 1, 'UTF-8');
}
shuffle($temp);
$str = join("", $temp);
echo $str;
Philip Petrov
  • 975
  • 4
  • 8