iT邦幫忙

2

PHP輸出中文亂碼 utf8

起初是看蔡承洋老師的影片作學習,後來想在文章抓取的頁面多加分頁功能,才發現原本學的沒有用物件導向,於是乎嘗試做修正,但最後的結果就是資料庫抓下來的資料輸出到網頁,中文的部分變成亂碼,資料庫的設定都沒有做更動,本來是能正常顯示中文的,弄了好幾個小時,到處爬資料也沒法解決,希望各位高手幫幫忙,指點小弟哪裏錯了,謝謝

下圖二網路上有說會影響,但我在修程式碼時沒動過資料庫,最後要弄也不知道怎麼調整ಥ_ಥ



連接資料庫(檔案名:db.php)

<?php
class db{
    public $host="localhost";
    public $dbuser="root";
    public $dbpw="stust";
    public $dbname="my_db";
    public $result;

    function _construct(){
         $this->sql_connect_db();
         $this->sql_db_encode();
    }

    function sql_connect_db(){
        return mysqli_connect($this->host,$this->dbuser,$this->dbpw,$this->dbname);
    }

    function sql_db_encode(){
        if($this->sql_connect_db()){
        return mysqli_query($this->sql_connect_db(),"SET NAMES utf8");
        //echo "連線成功";
        }
        else{
            return  "連線失敗<br>".mysqli_connect_error();
        }
    }
}
$db=new db();
?>

換頁功能(檔案名:page_switch.php)

<?php
require_once "db.php";
class ps extends db{
    public $data_nums=0; //資料總數
    public $per=5; //每頁幾筆資料
    public $page; //目前頁碼
    public $pages; //總頁數
    function _construct(){

    }
    //算總共幾筆資料
    function datascount($sql_string){
        $data_nums=mysqli_num_rows(mysqli_query($this->sql_connect_db(),$sql_string));
        $this->data_nums=$data_nums;
        return $data_nums;
    }
    //算總共幾頁
    function pagescount($per){
        $this->pages=ceil($this->data_nums/$per);
        $pages=$this->pages;
        return $pages;
    }
    //指定頁面的頁數陣列
    function number_array($site){
        $pages=$this->pages;
        if($pages>=1){
            echo "共".$this->data_nums."筆 ";
            for($i=1;$i<=$pages;$i++){
                echo "<a href='$site?p=".$i."' style="."text-decoration:none;".">".$i." </a>";
            }
        }
        else{
            echo "頁碼錯誤";
        }
        echo "共".$this->pages."頁 ";
    }
}
$ps=new ps();
?>

資料轉陣列(檔案名:function.php)

<?php
require_once "page_switch.php";
class search_data extends ps{
    public $sql_string;
    public $data_nums; //資料總數
    public $per; //每頁幾筆資料
    public $result;
    function _construct(){

    }
    //抓取發佈文章
    function get_publish_article($sql_string){
        $sql=$sql_string;
        $per=5;
        $this->datascount($sql);
        $this->pagescount($per);
        if(!isset($_GET['p'])){
            $page=1;
        }else{
            $page=intval($_GET{'p'});
        }
        $start=($page-1)*$per; //每一頁開始的資料序號
        $sql = $sql.' LIMIT '.$start.', '.$per;
        $query=mysqli_query($this->sql_connect_db(),$sql);
        if($query){
            if(mysqli_num_rows($query)>0){
                while($row=mysqli_fetch_assoc($query)){
                $result[]=$row;
                }
            }
        }else{
            echo "{$sql_string}語法執行失敗,錯誤內容:".mysqli_error($this->sql_connect_db());
        }
        return $result;
    }
?>

另外想知道上面的mysqli_error($this->sql_connect_db())為何無法正常顯示,連結的資料庫的方法確認沒錯,但不知為何就是跑不出來= =

實作頁面(檔案名article_list.php)

<!DOCTYPE html5>
<?php
    require_once "php/function.php";
    $datas=$sd->get_publish_article("SELECT * FROM `article` WHERE `publish`= 1");
?>

<html lang="zh-TW" dir="ltr">
<head>
    <meta charset="utf8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>所有文章</title>
    <meta name="description" content="art 公司官方網站,藝術創作!">
    <meta name="author" content="黎濠源">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <link rel="shortcut icon" href="image/bulb-curvy-flat.ico">
    <link rel="stylesheet" href="css/style.css">
</head>
<body>

<?php include_once 'menu.php'?>

<div class="main">
    <div class="container">
        <div class="row">
            <div class="col">
<?php
    $count=0;
    if(!empty($datas)):
    foreach ($datas as $article) :
    // $abstract=strip_tags($datas[content]); 去除掉html標籤的語法
    $abstract=mb_substr($article['content'],0,130);
?>
<div class="card">
    <h5 class="card-header text-white bg-info mb-3">
        <a href='article.php?i=<?php echo $article['id']?>' target=_self ><?php echo "$article[title]";?></a>
    </h5>
    <div class="card-body">
        <span class="badge badge-info"><?php echo $article['category'];?></span>
        <span class="badge badge-danger"><?php echo $article['create_date'];?></span>

<?php
    $str=mb_strlen($abstract);
    if($str<65):
?>
        <p class="card-text"><?php echo $abstract?></p>
<?php else: ?>
        <p class="card-text"><?php echo $abstract."......"?></p>
<?php endif ?>
<?php $count+=1; ?>
    </div>

</div>
<?php if($count<5): ?>
<hr>
<?php endif ?><p>
<?php endforeach ?>
<?php endif ?>
            </div>
        </div>
    </div>

<div class=page style='text-align:center'>
<?php echo $sd->number_array('article_list.php') ?>
</div><p>

<?php require_once 'footer.php'; ?>

</div>
</body>
</html>

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
3
小魚
iT邦大師 1 級 ‧ 2019-12-06 09:25:23
最佳解答

都9012年了,
不考慮學PDO嗎?

看更多先前的回應...收起先前的回應...

因為在一千年以後...
而且轉眼間9012又要過了 (菸

我只想問,為何是9012年。猜數字遊戲嘛。我回答1a3b

淺水員 iT邦大師 6 級 ‧ 2019-12-06 14:30:02 檢舉

小魚對程式的熱愛,立志寫程式寫到9012年。

小魚 iT邦大師 1 級 ‧ 2019-12-06 15:02:16 檢舉

不應該是2A2B嗎?

大大沒說小弟的還不知道有PDO這個方法,所以大大會比較推薦使用PDO去做連接嗎?要是是的話我等會有先把MYSQLI的版本弄好,再去學跟試作PDO的版本(`・ω・´)b

小魚 iT邦大師 1 級 ‧ 2019-12-06 15:12:48 檢舉

不是我推薦,
是官方推薦.

了解,爬過一點資料好像官方之後也是以PDO發展為主,有找到相關的學習文章,能試問大大知道我原本的方法哪裏錯了嗎,怕現在改PDO的方法錯更多ಥ_ಥ

其實因為php7已經棄用了mysql相函數的用法了。(雖然還是可以掛進去就是了)

最好還是學一下pdo

小魚 iT邦大師 1 級 ‧ 2019-12-06 18:18:08 檢舉

其實PDO用法也是類似,
不會差太多.

好的,我再試試,謝謝大大

終於用好PDO的版本,網頁也有正常顯示(☍﹏⁰)。,結果如下圖

連接資料庫(檔案名:db.php)

<?php
@session_start();
class dbc{
    private $mysql_address;
    private $mysql_username;
    private $mysql_password;
    private $mysql_database;
    public $db;

    public function __construct(){

    }

    public function database_connect($mysql_address,$mysql_username,$mysql_password,$mysql_database){
        $this->mysql_address=$mysql_address;
        $this->mysql_username=$mysql_username;
        $this->mysql_password=$mysql_password;
        $this->mysql_database=$mysql_database;
        try {
            $db = new PDO("mysql:host=".$this->mysql_address.";charset=utf8mb4;dbname=".$this->mysql_database, $this->mysql_username, $this->mysql_password);
            //$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);//Suggested to uncomment on production websites
            $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);//Suggested to comment on production websites
            $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
            $this->db=$db;
        }catch(PDOException $e) {
            //show error
            echo '<p class="bg-danger">'.$e->getMessage().'</p>';
            exit;
        }
    }
    public function __destruct(){
        $this->db = null;
    }
}
?>

換頁功能(檔案名:page_switch.php)

<?php
require_once "db.php";
class ps extends dbc{
    public $data_nums; //資料總數
    public $per; //每頁幾筆資料
    public $page; //目前頁碼
    public $pages; //總頁數

    function __construct(){

    }
    //算總共幾筆資料
    function datascount($sql_string){
        $statement=$this->db->query($sql_string);
        $data_nums=$statement->rowcount();
        $this->data_nums=$data_nums;
        return $data_nums;
    }
    //算總共幾頁
    function pagescount($per){
        $pages=ceil($this->data_nums/$per);
        $this->pages=$pages;
        return $pages;
    }
    //指定頁面的頁數陣列
    function number_array($site){
        $pages=$this->pages;
        if($pages>=1){
            echo "共".$this->data_nums."筆 ";
            for($i=1;$i<=$pages;$i++){
                echo "<a href='$site?p=".$i."' style="."text-decoration:none;".">".$i." </a>";
            }
        }
        else{
            echo "頁碼錯誤";
        }
        echo "共".$this->pages."頁 ";
    }
}
?>

資料轉陣列(檔案名:function.php)

<?php
require_once "page_switch.php";
class search_data extends ps{
    public $sql_string;
    public $data_nums; //資料總數
    public $per; //每頁幾筆資料
    public $data_sum; //當前頁面有幾筆資料

    function __construct(){

    }
    //抓取發佈文章
    function get_publish_article($sql_string){
        $sql=$sql_string;
        $per=5;
        $this->datascount($sql);
        $this->pagescount($per);
        if(!isset($_GET['p'])){
            $page=1;
        }else{
            $page=intval($_GET{'p'});
        }
        $start=($page-1)*$per; //每一頁開始的資料序號
        $sql = $sql.' limit '.$start.', '.$per;
        $query=$this->db->query($sql);
        if($query->rowcount()>0){
            $data_sum=$query->rowcount();
            $this->data_sum=$data_sum;
            return $query;
        }else{
            echo "查無資料";
        }
    }

}
$sd=new search_data();
$sd->database_connect("localhost","root","stust","my_db");
?>

實作頁面(檔案名article_list.php)

<!DOCTYPE html5>
<?php
    require_once "php/function.php";
    $datas=$sd->get_publish_article("SELECT * FROM `article` WHERE `publish`= 1");
?>

<html lang="zh-TW" dir="ltr">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>所有文章</title>
    <meta name="description" content="art 公司官方網站,藝術創作!">
    <meta name="author" content="黎濠源">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <link rel="shortcut icon" href="image/bulb-curvy-flat.ico">
    <link rel="stylesheet" href="css/style.css">
</head>
<body>

<?php include_once 'menu.php'?>

<div class="main">
    <div class="container">
        <div class="row">
            <div class="col">
<?php
    $count=0;
    if(!empty($datas)):
    foreach ($datas as $article) :
    // $abstract=strip_tags($datas[content]); 去除掉html標籤的語法
    $abstract=mb_substr($article['content'],0,130);
?>
<div class="card">
    <h5 class="card-header text-white bg-info mb-3">
        <a href='article.php?i=<?php echo $article['id']?>' target=_self ><?php echo "$article[title]";?></a>
    </h5>
    <div class="card-body">
        <span class="badge badge-info"><?php echo $article['category'];?></span>
        <span class="badge badge-danger"><?php echo $article['create_date'];?></span>

<?php
    $str=mb_strlen($abstract);
    if($str<65):
?>
        <p class="card-text"><?php echo $abstract?></p>
<?php else: ?>
        <p class="card-text"><?php echo $abstract."......"?></p>
<?php endif ?>
    </div>

</div>
<?php
    $count=$sd->data_sum;
    if($count>1){
        $sd->data_sum--;
        echo "<hr>";
    }
?><p>
<?php endforeach ?>
<?php endif ?>
            </div>
        </div>
    </div>

<div class=page style='text-align:center'>
<?php echo $sd->number_array('article_list.php') ?>
</div><p>

<?php include_once 'footer.php'; ?>
</div>
</body>
</html>
1

用 sql_db_encode 去連接。不要直接用sql_connect_db

會少做一個 SET NAMES utf8 造成你讀取資料編碼錯誤。

謝謝大大,先試試PDO連接資料庫,有成功再傳程式碼跟結果

1
阿展展展
iT邦好手 1 級 ‧ 2019-12-06 08:26:26

你有點教錯喔。他是用mysqli的
而且他程式有,只是沒用到他。

/images/emoticon/emoticon04.gif

/images/emoticon/emoticon41.gif

1
一級屠豬士
iT邦大師 1 級 ‧ 2019-12-06 10:11:20
看更多先前的回應...收起先前的回應...

哈!!果然這邊才是重點。你沒說我還沒注意到。
果然是大神。

星空大大,你這樣講,小弟擔不起啊.

大大感恩,要是您沒提醒我就要一直錯下去了...

這種兩個底線的雷,你不是第一個踩到的,也不會是最後一個.
幸好你有用正確的方式貼程式碼上來.

想說親手打比較記得住,結果沒注意到要兩個底線,真的謝謝您有提醒我(゚ω゚;)

我要發表回答

立即登入回答