tom fox tom fox - 5 months ago 17
SQL Question

Arabic characters doesn't add in pdo

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

Answer

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