I am using PDO for MySQL database connection, selecting, updating and deleting.
But I have a problem with selecting rows with special characters, for instance, I want to select a page title with 'Judge-Fürstová Mila',
Table page,
id title content
1 Judge-Fürstová Mila xxx
SQL,
SELECT *
FROM page
WHERE title = 'Judge-Fürstová Mila'
Returns result if I query via phpmyadmin.
But it return 0 with PDO,
$sql = ' SELECT *
FROM page
WHERE title = ?';
$items = $connection->fetch_assoc($sql,'Judge-Fürstová Mila');
Below is my db class,
class database_pdo
{
# database handler
protected $connection = null;
# make a connection
public function __construct($dsn,$username,$password)
{
try
{
# MySQL with PDO_MYSQL
$this->connection = new PDO($dsn, $username, $password);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e)
{
# call the get_error function
$this->get_error($e);
}
}
# don't forget to add getter method to get $this->connection, it's just a good practice.
public function get_connection()
{
return $this->connection;
}
public function fetch_assoc($query, $params = array())
{
try
{
# prepare the query
$stmt = $this->connection->prepare($query);
# if $params is not an array, let's make it array with one value of former $params
if (!is_array($params)) $params = array($params);
# execute the query
$stmt->execute($params);
# return the result
return $stmt->fetch();
}
catch (PDOException $e)
{
# call the get_error function
$this->get_error($e);
}
}
Have I missed something in my db class or something else?
Try to add charset=UTF-8 in your $dsn, and change
$this->connection = new PDO($dsn, $username, $password);
to
$this->connection = new PDO($dsn, $username, $password, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
I believe it is that SET NAMES utf8 thingie, at least it was in my case
Related
I think I've a problem in understanding how OOP works. I already changed the code that it works, but it isn't the propper way I think. Following scenario (No, I'm not creating a userlogin by myself, its really just for local dev. to understand OOP better):
I've a database.php file:
class Database {
/* Properties */
private $conn;
private $dsn = 'mysql:dbname=test;host=127.0.0.1';
private $user = 'root';
private $password = '';
/* Creates database connection */
public function __construct() {
try {
$this->conn = new PDO($this->dsn, $this->user, $this->password);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "";
die();
}
return $this->conn;
}
}
So in this class I'm creating a database connection and I return the connection (object?)
Then I have a second class, the famous User class (actually I'm not using autoload, but I know about it):
include "database.php";
class User {
/* Properties */
private $conn;
/* Get database access */
public function __construct() {
$this->conn = new Database();
}
/* Login a user */
public function login() {
$stmt = $this->conn->prepare("SELECT username, usermail FROM user");
if($stmt->execute()) {
while($rows = $stmt->fetch()) {
$fetch[] = $rows;
}
return $fetch;
}
else {
return false;
}
}
}
So thatare my two classes. Nothing big, as you see. Now, don't get confued about the function name login - Actually I just try to select some usernames and usermails from database and displaying them. I try to achieve this by:
$user = new User();
$list = $user->login();
foreach($list as $test) {
echo $test["username"];
}
And here comes the problem. When I execute this code, I get the following error message:
Uncaught Error: Call to undefined method Database::prepare()
And I'm not sure that I really understand what causes this error.
The code works well when I change the following things:
Change $conn in database.php to public instead of private (I think thats bad...? But when its private, I can only execute querys inside of the Database class, I'm right? So should I put all these querys in the Database class? I think that's bad, because in a big project it will get become really big..)
And the second change I've to do is:
Change $this->conn->prepare to $this->conn->conn->prepare in the user.php file. And here I've really no Idea why.
I mean, in the constructor of the user.php I've a $this->conn = new Database() and since new Database will return me the connection object from DB class, I really don't know why there have to be a second conn->
Do not create classes such as your Database class as it's rather useless. It would make sense to create a database wrapper if it adds some extra functionality to PDO. But given its current code, better to use vanilla PDO instead.
Create a single $db instance from either vanilla PDO or your database class.
Pass it as a constructor parameter into every class that needs a database connection
database.php:
<?php
$host = '127.0.0.1';
$db = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$opt = [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new \PDO($dsn, $user, $pass, $opt);
user.php
<?php
class User {
/* Properties */
private $conn;
/* Get database access */
public function __construct(\PDO $pdo) {
$this->conn = $pdo;
}
/* List all users */
public function getUsers() {
return $this->conn->query("SELECT username, usermail FROM user")->fetchAll();
}
}
app.php
include 'database.php';
$user = new User($pdo);
$list = $user->getUsers();
foreach($list as $test) {
echo $test["username"],"\n";
}
output:
username_foo
username_bar
username_baz
Check out my (The only proper) PDO tutorial for more PDO details.
iam using phalcon, I tried to execute query from controller, query run my model
<?php
use Phalcon\Mvc\Model;
use Phalcon\Mvc\Model\Query;
class CakupanBu extends Phalcon\Mvc\Model
{
public static function getJenisBU()
{
header("Access-Control-Allow-Origin: *");
header('Content-type:application/json;charset=utf-8');
$data = array();
$query = new Query(
'SELECT id_jenis_bu,count(jumlah_bu) as jumlah FROM CakupanBu group by id_jenis_bu',
$this->getDI()
);
// Execute the query returning a result if any
$jbus = $query->execute();
foreach ($jbus as $jbu) {
$data[] = array(
'id_jenis' => $jbu->id_jenis_bu,
'jumlah' => $jbu->jumlah,
);
}
return json_encode($data);
}
}
But sadly this is not working, and I ended up with an error.
<b>Fatal error</b>: Uncaught Error: Using $this when not in object context in 'CakupanBU.php:14'
from controller i call :
$jbus=CakupanBU::getJenisBU();
Could anyone give me solution? thanks you
Your function is static, so there is no $this.
To get the DI, you would replace your $this->getDI() with \Phalcon\DI::getDefault()
Hey guys I am learning OOP in php. I come across some issue, when I try to customize PDO in my own class. Basically I have tried to return the row and fetch it outside my class. Unfortunately I would not work. I get this error "Call to a member function fetch() on a non-object". Have a look and give me some tips if You can. Many thanks.
$connection = new MySql(DBUSER, DBPASS);
$row = $connection->query("select * from users", "name");
while($row->fetch(PDO::FETCH_ASSOC)){
echo "<p>". $row["name"] ."</p>";
}
And here is how the MySql class look like:
class MySql{
private $dbc;
private $user;
private $pass;
function __construct($user="root", $pass=""){
$this->user = $user;
$this->pass = $pass;
try{
$this->dbc = new PDO("mysql:host=localhost; dbname=DBNAME;charset=utf8", $user, $pass);
}
catch(PDOException $e){
echo $e->getMessage();
echo "Problem z Połączeniem do MySql sprawdź haslo i uzytkownika";
}
}
public function query($query, $c1=""){
$mysqlquery = $this->dbc->prepare($query);
$mysqlquery->execute();
return $row = $mysqlquery->fetch(PDO::FETCH_ASSOC);
/* I WANT TO PERFORM COMENTED CODE OUTSIDE THE CLASS
while($row = $mysqlquery->fetch(PDO::FETCH_ASSOC)){
if($c1!=""){
echo "<p>". $row[$c1] ."</p>";
}
}
*/
}
If you want to return $mysqlquery to iterate over it, you have to return $mysqlquery, not just one row.
Here is a better version of your class, with dramatically improved error handling and security. But still awful configurability though.
class MySql{
private $dbc;
function __construct($user="root", $pass=""){
$dsn = "mysql:host=localhost; dbname=DBNAME;charset=utf8";
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
$this->dbc = new PDO($dsn, $user, $pass, $opt);
}
public function query($query, $data = array()){
$stm = $this->dbc->prepare($query);
$stm->execute($data);
return $stm;
}
}
$connection = new MySql(DBUSER, DBPASS);
$stm = $connection->query("select * from users WHERE name = ?", array("name"));
while($row = $stm->fetch()){
echo "<p>". $row["name"] ."</p>";
}
I am trying to construct an object from a stored procedure will yii.
http://www.yiiframework.com/doc/api/1.1/CDbDataReader
I am unsure how to use the function $dataReader->readObject('image', $image);
to construct an object- anyone any ideas if this is the correct way or if this is very slow way of constructing objects
function __construct($image) {
print "In BaseClass constructor\n";
}
public static function getImageFromAliasTitle($alias_title)
{
// $alias_title =Utils::checkEnteredData($alias_title);
$connection = Yii::app()->db;
$command = $connection->createCommand("CALL get_associated_image_detail(:in_image_alias_title, :in_image_visible, :in_image_approved, :in_album_visible, :in_album_approved)");
$command->bindParam(":in_image_alias_title",$alias_title,PDO::PARAM_STR);
$command->bindValue(":in_image_visible",'1',PDO::PARAM_STR);
$command->bindValue(":in_image_approved",'Yes',PDO::PARAM_STR);
$command->bindValue(":in_album_visible",'1',PDO::PARAM_STR);
$command->bindValue(":in_album_approved",'Yes',PDO::PARAM_STR);
try{
$dataReader = $command->query();
if($dataReader->count() >0)
{
$image = $dataReader->read();
}
$dataReader->readObject('image', $image);
// $image = $dataReader->read();
$dataReader->nextResult();
$album = $dataReader->readAll();
$dataReader->nextResult();
$tag = $dataReader->readAll();
$dataReader->nextResult();
$user_image = $dataReader->readAll();
$dataReader->close();
}
catch(Exception $e){
Yii::log('', CLogger::LEVEL_ERROR, 'Message Here...');
}
return $image;
}
What about this:
foreach($row as $dataReader->readAll()){
echo $row["image"];
}
if It does not help then try to print:
print_r($dataReader->readAll());
Before I used PDO and it worked fine but I had problems with inserting pictures. Now I switched to SQLite3 and the pictures are now stored correctly. But I'm experiencing a strange problem with SQLite3. Every INSERT INTO command is done twice. And this only concerns INSERT, because I had no problems with UPDATE or DELETE.
This is my test script
<?php
require_once('class.DatabaseQuery.php');
$db = new DatabaseQuery();
$sql = 'INSERT INTO Bezeichnungen(Bezeichnung_de,Bezeichnung_en,Bezeichnung_it) values("test","test","test");';
$result = $db->ExecuteQuery($sql);
echo "<pre>";
print_r($result);
echo "</pre>";
?>
This is my database class:
<?php
class DatabaseQuery {
private $_handle;
public function ExecuteQuery($sql, $params = array())
{
echo $sql;
echo "<strong>execute Query params</strong><pre>";
print_r ($params);
echo "</pre>";
echo count($params);
// make new connection if not available
if($this->_handle == null)
$this->Connect();
// make prepared statement
$query = $this->_handle->prepare($sql);
// add values to prepared statement depending on type
foreach($params as $key => $value)
{
if(is_int($value)){
$query->bindValue(':'.$key, $value, SQLITE3_INTEGER);
}else if(is_null($value)){
$query->bindValue(':'.$key, $value, SQLITE3_NULL);
}else if(strpos($value, "home/www/") !== false){
$value=file_get_contents($value);
$query->bindValue(':'.$key, $value, SQLITE3_BLOB);
$value="X'" . strtoupper(bin2hex($value));
}else{
$query->bindValue(':'.$key, $value, SQLITE3_TEXT);
}
}
$result = $query->execute();
// get all results
while($row = $result->fetchArray(SQLITE3_ASSOC)){
$res[] = $row;
}
//var_dump($x);
return $res;
}
public function Connect()
{
$this->_handle = new SQLite3("database.db");
}
public function Disconnect()
{
// close database connection
$this->_handle->close();
}
}
?>
And this is the create statement of my table
CREATE TABLE Bezeichnungen
(
_id INTEGER PRIMARY KEY,
Bezeichnung_de TEXT,
Bezeichnung_en TEXT,
Bezeichnung_it TEXT
)
Either I'm using SQLite3 the wrong way or the used library has a bug.
I'm using PHP 5.3.9, SQLite3 module version 0.7-dev and SQLite Library 3.7.7.1.
Perhaps someone can test my code on his plattform and tells me if he has the same problem.