1

I have a pdo class works great with English but when I try to insert Arabic text it doesn't work well

This the class:

class DB extends config
{
        # @object, The PDO object
        protected $pdo;

        # @object, PDO statement object
        private $sQuery;

        # @bool ,  Connected to the database
        private $bConnected = false;

        # @object, Object for logging exceptions    
        private $log;

        # @array, The parameters of the SQL query
        private $parameters;

        protected $table;
        protected $values;
       /**
        *   Default Constructor 
        *
        *   1. Instantiate Log class.
        *   2. Connect to database.
        *   3. Creates the parameter array.
        */
                public function __construct($table)
                { 
                        parent::__construct();
                        $this->log = new Log(); 
                        $this->Connect();
                        $this->parameters = array();
                        $this->table = $table;
                }

       /**
        *   This method makes connection to the database.
        *   
        *   1. Reads the database settings from a ini file. 
        *   2. Puts  the ini content into the settings array.
        *   3. Tries to connect to the database.
        *   4. If connection failed, exception is displayed and a log file gets created.
        */
                private function Connect()
                {
                        $dsn = 'mysql:dbname='.$this->settings["dbname"].';host='.$this->settings["host"];
                        try 
                        {
                                # Read settings from INI file, set UTF8
                                $this->pdo = new PDO($dsn, $this->settings["user"], $this->settings["password"], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));

                                # We can now log any exceptions on Fatal error. 
                                $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

                                # Disable emulation of prepared statements, use REAL prepared statements instead.
                                $this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

                                # Connection succeeded, set the boolean to true.
                                $this->bConnected = true;
                        }
                        catch (PDOException $e) 
                        {
                                # Write into log
                                echo $this->ExceptionLog($e->getMessage());
                                die();
                        }
                }
        /*
         *   You can use this little method if you want to close the PDO connection
         *
         */
                public function CloseConnection()
                {
                        # Set the PDO object to null to close the connection
                        # http://www.php.net/manual/en/pdo.connections.php
                        $this->pdo = null;
                }

       /**
        *   Every method which needs to execute a SQL query uses this method.
        *   
        *   1. If not connected, connect to the database.
        *   2. Prepare Query.
        *   3. Parameterize Query.
        *   4. Execute Query.   
        *   5. On exception : Write Exception into the log + SQL query.
        *   6. Reset the Parameters.
        */  
                private function Init($query,$parameters = "")
                {
                # Connect to database
                if(!$this->bConnected) { $this->Connect(); }
                try {
                                # Prepare query
                                $this->sQuery = $this->pdo->prepare($query);

                                # Add parameters to the parameter array 
                                $this->bindMore($parameters);

                                # Bind parameters
                                if(!empty($this->parameters)) {
                                        foreach($this->parameters as $param)
                                        {
                                                $parameters = explode("\x7F",$param);
                                                $this->sQuery->bindParam($parameters[0],$parameters[1]);
                                        }       
                                }

                                # Execute SQL 
                                $this->succes   = $this->sQuery->execute();     
                        }
                        catch(PDOException $e)
                        {
                                        # Write into log and display Exception
                                        echo $this->ExceptionLog($e->getMessage(), $query );
                                        die();
                        }

                        # Reset the parameters
                        $this->parameters = array();
                }

       /**
        *   @void 
        *
        *   Add the parameter to the parameter array
        *   @param string $para  
        *   @param string $value 
        */  
                public function bind($para, $value)
                {   
                        $this->parameters[sizeof($this->parameters)] = ":" . $para . "\x7F" . utf8_encode($value);
                }
       /**
        *   @void
        *   
        *   Add more parameters to the parameter array
        *   @param array $parray
        */  
                public function bindMore($parray)
                {
                        if(empty($this->parameters) && is_array($parray)) {
                                $columns = array_keys($parray);
                                foreach($columns as $i => &$column) {
                                        $this->bind($column, $parray[$column]);
                                }
                        }
                }
       /**
        *       If the SQL query  contains a SELECT or SHOW statement it returns an array containing all of the result set row
        *   If the SQL statement is a DELETE, INSERT, or UPDATE statement it returns the number of affected rows
        *
        *       @param  string $query
        *   @param  array  $params
        *   @param  int    $fetchmode
        *   @return mixed
        */          
                public function query($query,$params = null, $fetchmode = PDO::FETCH_ASSOC)
                {
                        $query = trim($query);

                        $this->Init($query,$params);

                        $rawStatement = explode(" ", $query);

                        # Which SQL statement is used 
                        $statement = strtolower($rawStatement[0]);

                        if ($statement === 'select' || $statement === 'show') {
                                return $this->sQuery->fetchAll($fetchmode);
                        }
                        elseif ( $statement === 'insert' ||  $statement === 'update' || $statement === 'delete' ) {
                                return $this->sQuery->rowCount();   
                        }   
                        else {
                                return NULL;
                        }
                }

      /**
       *  Returns the last inserted id.
       *  @return string
       */   
                public function lastInsertId() {
                        return $this->pdo->lastInsertId();
                }   

       /**
        *   Returns an array which represents a column from the result set 
        *
        *   @param  string $query
        *   @param  array  $params
        *   @return array
        */  
                public function column($query,$params = null)
                {
                        $this->Init($query,$params);
                        $Columns = $this->sQuery->fetchAll(PDO::FETCH_NUM);     

                        $column = null;

                        foreach($Columns as $cells) {
                                $column[] = $cells[0];
                        }

                        return $column;

                }   
       /**
        *   Returns an array which represents a row from the result set 
        *
        *   @param  string $query
        *   @param  array  $params
        *       @param  int    $fetchmode
        *   @return array
        */  
                public function row($query,$params = null,$fetchmode = PDO::FETCH_ASSOC)
                {               
                        $this->Init($query,$params);
                        return $this->sQuery->fetch($fetchmode);            
                }
       /**
        *   Returns the value of one single field/column
        *
        *   @param  string $query
        *   @param  array  $params
        *   @return string
        */  
                public function single($query,$params = null)
                {
                        $this->Init($query,$params);
                        return $this->sQuery->fetchColumn();
                }
       /**  
        * Writes the log and returns the exception
        *
        * @param  string $message
        * @param  string $sql
        * @return string
        */
        private function ExceptionLog($message , $sql = "")
        {
                $exception  = 'Unhandled Exception. <br />';
                $exception .= $message;
                $exception .= "<br /> You can find the error back in the log.";

                if(!empty($sql)) {
                        # Add the Raw SQL to the Log
                        $message .= "\r\nRaw SQL : "  . $sql;
                }
                        # Write into log
                        $this->log->write($message);

                return $exception;
        }
        public function binding($values = array()){
            foreach($values as $key => $value){
                $this->bind($key,$value);
                $this->values[$key] = $value;
            }
        }
        public function add($where = NULL){
            $sql = "INSERT INTO {$this->table} (";
            $i=0;
            foreach($this->values as $key => $value){
                if($i+1 == count($this->values))
                {
                    $sql.= $key;
                }  
                else 
                {
                    $sql.= $key.',';
                }

                $i++;
            }
            $sql .= ') values (';
            $i=0;
            foreach($this->values as $key => $value){
                if($i+1 == count($this->values))
                {
                    $sql.= ":{$key}";
                }  
                else 
                {
                    $sql.= ":{$key},";
                }

                $i++;
            }
            $sql .= ')';
            if(!empty($where)){
                $sql+=$where;
            }
            $query = $this->query($sql);
            return $query;
        }
        public function delete($id){
            $sql = "DELETE FROM {$this->table} WHERE id = :id";
            $this->bind("id",$id);
            $query = $this->query($sql);
            return $query;
        }
        public function update($where){
            $sql= "UPDATE {$this->table} SET";
            $i=0;
            foreach($this->values as $key => $value){
                if($i == count($this->values))
                {
                    $sql.= "{$key} = ':{$key}'";
                }  
                else 
                {
                    $sql.= "{$key} = ':{$key}',";
                }
                $i++;
            }
            $sql .= $where;
            $query = $this->query($sql);
            return $query;
        }
}

when i use it as this

include_once './includes/int.php';
$db = new Db("test");
$db->binding(array(
    "test" => "ابلابا"
));
$add = $db->add();
print_r( $db->row("select * from test where id = 5"));

it gives me this

Array ( [id] => 5 [test] => Ø§Ø¨ÙØ§Ø¨Ø§ ) 

I make the collection of the columns in phpMyadmin

utf8mb4_unicode_ci

edit:

My table collection is

utf8_unicode_ci

Edit 2:

I had checked all this question but all of this i have already made it

edit 3:

<?php header('Content-Type: text/html; charset=utf-8');?>
<html>
    <head>
        <meta charset="UTF-8">
        <title>title</title>
    </head>
    <body>

<?php
include_once './includes/int.php';
$db = new Db("test");
$db->binding(array(
    "test" => "ابلابا"
));
$add = $db->add();
print_r( $db->row("select * from test where id = 12"));
?>
    </body>
</html>

and still doesn't work

Community
  • 1
  • 1
tom fox
  • 126
  • 1
  • 3
  • 12

2 Answers2

2

In your Connect function within your DB class, add this line :

$this->pdo = new PDO($dsn, $this->settings["user"], $this->settings["password"], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$this->pdo->exec("SET CHARACTER SET utf8"); // <-- HERE

And make sure you set the right encoding charset within your html page :

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

Remove utf8_encode within bind function :

public function bind($para, $value){   
    $this->parameters[sizeof($this->parameters)] = ":" . $para . "\x7F" . $value;
}
JC Sama
  • 2,214
  • 1
  • 13
  • 13
0

First you need to alter table with given query. Then check value in your table see that value is arabic or not.After that when you display value you need to set header utf8 in your code.

add charset = utf8

In your table.

ALTER TABLE `dbname`.`tablename` CHANGE `columnname` `columnname` VARCHAR(255) CHARSET utf8 NOT NULL; 
Navjot Singh
  • 514
  • 4
  • 14
  • this doesn't work the problem in adding it doesn't add it well and in the database it doesn't look Arabic text and i have added the header with no work also – tom fox Mar 17 '15 at 12:49