הוסטס - פורום אחסון האתרים הגדול בישראל

הוסטס - פורום אחסון האתרים הגדול בישראל (https://hosts.co.il/forums/index.php)
-   פורום תיכנות (https://hosts.co.il/forums/forumdisplay.php?f=14)
-   -   קידוד ב-mySQL (https://hosts.co.il/forums/showthread.php?t=60688)

ahoy 05-03-08 20:44

קידוד ב-mySQL
 
אהלן,

אני עובד על מערכת ניהול תוכן המבוססת mySQL. עד היום עבדתי בקידוד windows-1255 ונטענו לתוכה לא מעט תכנים.

כעת אני רוצה להסב את הסביבה ל- utf-8. הסבת הממשק עצמו קלה, הבעיה עם בסיס הנתונים עצמו ... נראה כי התכנים נשמרו בקידוד הישן ואם אני מציג אותם בדף המקודד utf-8 הם מוצגים כג'יבריש.

האם נתקלתם בזה? האם יש דרך לבצע המרה אוטומטית?

בניה 06-03-08 12:19

קודם כל, תגבה את כל מה שיש לך!
דרך הPHPMYADMIN בפעולות/operations אפשר להעתיק טבלה שלימה לטבלה חדשה בשניה.
כך גם יהיה קל לשחזר.

כדי להמיר אתה גם צריך לשנות את ההגדרות במסד עצמו(collation) לטבלה ולתאים.
וגם את המידע עצמו.

אני ממליץ לעשות את זה כך:
ליצור טבלה באותו מבנה עם collation utf8_unicode_ci
בשם
utf8_tablename
ליצור 2 חיבורים לMYSQL, אחד לטבלה הישנה ואחרי החיבור לישנה לשלוח שאילתה
קוד:

"SET NAMES 'hebrew'"
ובחיבור השני שדרכו תעבוד עם הטבלה החדשה
קוד:

"SET NAMES 'utf8'"
אחרי כן תשלוף את כל הנתונים מהטבלה הישנה, תמיר אותם ל utf8 עם iconv
קוד:

iconv("windows-1255", "UTF-8", $text);
ותכניס לטבלה החדשה.

ahoy 06-03-08 12:41

כבר כתבתי סקריפט PHP שעושה המרה בעזרת ICONV (אחרי ש-html_entity_decode גם לא עבד) באותה הטבלה וזה לא עבד:

$fieldsquery = "select * from ".$db.".".$table."";
$fields_result = mysql_query($fieldsquery);
$num_fields = mysql_num_fields($fields_result);

for ($j = 0; $j < $num_fields ; $j++)
{

$column = mysql_field_name($fields_result, $j);

$query = "select ".$column." from ".$db.".".$table."";
$result = mysql_query($query);
$num_result = mysql_num_rows($result);

for ($i = 0; $i < $num_result; $i++)
{
$thing1 = mysql_result($result,$i);

echo $thing1.'<br>';

//$thing2 = html_entity_decode($thing1, ENT_QUOTES, 'utf-8');

$things2 = iconv("windows-1255", "UTF-8", $thing1);

echo '<br>'.$thing2.'<br>';

$queryreplace = "update ".$db.".".$table." set ".$column." = '".$thing2."' where ".$column." = '".$thing1."'";
echo $queryreplace."<br>";
mysql_query($queryreplace);
}


... מה המשמעות של SET NAMES לקידוד? היכן זה אמרו להכנס?

בניה 06-03-08 15:20

ה SET NAMES זו שאילתה שקובעת את הקידוד של החיבור שלך עם המסד נתונים.
אם הקידוד של החיבור הוא latin1 ואתה מנסה להעביר UTF8 או ההפך אתה עלול לקבל סימני שאלה/גי'בריש.

וגם אתה חייב שהcollation במסד יוגדר כמו שצריך לפני שאתה מכניס אליו מידע בUTF8.

קוד שעבד לי:

PHP קוד:

<?php
error_reporting
(E_ALL);

set_time_limit(600);

    function 
sql_query($query)
    {
        global 
$con;
        
$trace debug_backtrace();

        
$file = &$trace[0]['file'];
        
$line = &$trace[0]['line'];

        
$res mysql_query($query$con);
        if(!
$res)
             die(
"\r\nSQL ERROR: [".$query."|".mysql_error()."] in "$file ." AT ".$line);
        else
            return 
$res;
    }

    function 
convert($str) {

        return 
iconv("windows-1255""UTF-8"$str);

    }

    function 
sql_escape($str){
        global 
$con;
        return 
mysql_real_escape_string($str$con);
    }

$db 'conv';

$table 'lalal';

$con mysql_connect('localhost''root');

mysql_select_db($db$con);

sql_query("SET NAMES 'hebrew'"$con);

$sql "SELECT * FROM " $db "." $table "";

$res sql_query($sql);

sql_query("SET NAMES 'UTF8'"$con);

$fields false;

$c 0;
$values = array();

$rows_num mysql_num_rows($res);

while(
$row mysql_fetch_assoc($res)) {


    if(
$c == 0) {
        
$sql "INSERT INTO `new_{$table}` (`" implode('`,`'array_keys($row)) . "`) VALUES ";

    }

    
$c++;

    
$row array_map('convert'$row);
    
$row array_map('sql_escape'$row);

    
$values[] = "('" implode("','"$row) . "')";

    if((!
$c%10) || $c == $rows_num) {
        
sql_query($sql implode(','$values));
        
$values = array();
    }
}


echo 
"{$c} rows converted";
?>

(אני צריך אחד גם לעצמי)

ahoy 07-03-08 16:36

היי,

יש בעיה, אחרי שהגדרתי שם-משתמש\סיסמא שהיו חסרים ... הוא לא יודע מה זו הטבלה החדשה שהגדרת ... וגם לי לא ברור:

PHP קוד:

 $sql "INSERT INTO `new_{$table}` (`" implode('`,`'array_keys($row)) . "`) VALUES "

עריכה:

א. הוספתי טבלה זמנית, כדי לראות אם זה עובד - לא.
ב. האם כדאי לשנות את הגדרת קידוד טבלת היעד ל-UTF-8?

בניה 07-03-08 23:09

כן, צריך ליצור טבלה חדשה בשם
new_tablname וכל ה collation בכל מקום שיהיו utf8_unicode_ci

ahoy 08-03-08 17:44

מאיזו סיבה זה לא עובד - כלומר זה ממיר אבל לקידוד לא ברור.

הסבתי את טבלת היעד ל-utf8_unicode_ci וגם את שדות טקסט היעד ... מה עוד יכול להיות בדרך?

בניה 08-03-08 20:26

ציטוט:

נכתב במקור על ידי ahoy (פרסם 614929)
מאיזו סיבה זה לא עובד - כלומר זה ממיר אבל לקידוד לא ברור.

הסבתי את טבלת היעד ל-utf8_unicode_ci וגם את שדות טקסט היעד ... מה עוד יכול להיות בדרך?


יכול להיות שכשאתה שולף את הנתונים אחרי ההמרה, הקידוד של השליפה לא טוב?
אם תוכל שלח לי עותק של הטבלה, אפילו רק עם שורה אחת ואני אנסה לבדוק את זה.


כל הזמנים הם GMT +2. הזמן כעת הוא 19:31.

מופעל באמצעות VBulletin גרסה 3.8.6
כל הזכויות שמורות ©
כל הזכויות שמורות לסולל יבוא ורשתות (1997) בע"מ