I got an error when I want to consume a Rest API using postaman and docker.
The error is marked in this line of code: Error in php Connection Error: could not find driver
<?php
class Materias {
// DB stuff
private $conn;
private $table = 'materias';
// Materias Properties
public $clave_materia;
public $nombre_materia;
public $semestre;
public $creditos;
// Constructor with DB
public function __construct($db) {
$this->conn = $db;
}
// Get Materias
public function read() {
// Create query
$query = 'SELECT * FROM ' . $this->table;
// Prepare statement
$stmt = $this->conn->prepare($query);
// Execute query
$stmt->execute();
return $stmt;
}
// Get Single Materia
public function read_single() {
// Create query
$query = 'SELECT * FROM ' . $this->table . 'WHERE clave_materia = ?';
// Prepare statement
$stmt = $this->conn->prepare($query);
// Bind clave_materia
$stmt->bindParam(1, $this->clave_materia);
// Execute query
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
// Set properties
$this->nombre_materia = $row['nombre_materia'];
$this->semestre = $row['semestre'];
$this->creditos = $row['creditos'];
}
// Create Post
public function create() {
// Create query
$query = 'INSERT INTO ' . $this->table . ' SET clave_materia = :clave_materia, nombre_materia = :nombre_materia, semestre = :semestre, creditos = :creditos';
// Prepare statement
$stmt = $this->conn->prepare($query);
// Clean data
$this->clave_materia = htmlspecialchars(strip_tags($this->clave_materia));
$this->nombre_materia = htmlspecialchars(strip_tags($this->nombre_materia));
$this->semestre = htmlspecialchars(strip_tags($this->semestre));
$this->creditos = htmlspecialchars(strip_tags($this->creditos));
// Bind data
$stmt->bindParam(':clave_materia', $this->clave_materia);
$stmt->bindParam(':nombre_materia', $this->nombre_materia);
$stmt->bindParam(':semestre', $this->semestre);
$stmt->bindParam(':creditos', $this->creditos);
// Execute query
if($stmt->execute()) {
return true;
}
// Print error if something goes wrong
printf("Error: %s.\n", $stmt->error);
return false;
}
// Update Post
public function update() {
// Create query
$query = 'UPDATE ' . $this->table . '
SET nombre_materia = :nombre_materia, semestre = :semestre, creditos = :creditos
WHERE clave_materia = :clave_materia';
// Prepare statement
$stmt = $this->conn->prepare($query);
// Clean data
$this->nombre_materia = htmlspecialchars(strip_tags($this->nombre_materia));
$this->semestre = htmlspecialchars(strip_tags($this->semestre));
$this->creditos = htmlspecialchars(strip_tags($this->creditos));
$this->clave_materia = htmlspecialchars(strip_tags($this->clave_materia));
// Bind data
$stmt->bindValue(':nombre_materia', $this->nombre_materia);
$stmt->bindValue(':semestre', $this->semestre);
$stmt->bindValue(':creditos', $this->creditos);
$stmt->bindValue(':clave_materia', $this->clave_materia);
// Execute query
if($stmt->execute()) {
return true;
}
// Print error if something goes wrong
printf("Error: %s.\n", $stmt->error);
return false;
}
// Delete Post
public function delete() {
// Create query
$query = 'DELETE FROM ' . $this->table . ' WHERE clave_materia = :clave_materia';
// Prepare statement
$stmt = $this->conn->prepare($query);
// Clean data
$this->clave_materia = htmlspecialchars(strip_tags($this->clave_materia));
// Bind data
$stmt->bindParam(':clave_materia', $this->clave_materia);
// Execute query
if($stmt->execute()) {
return true;
}
// Print error if something goes wrong
printf("Error: %s.\n", $stmt->error);
return false;
}
}
Error:
Connection Error: could not find driver<br />
<b>Fatal error</b>: Uncaught Error: Call to a member function prepare() on null in /var/www/html/models/Materias.php: 24
Stack trace:
#0 /var/www/html/api/materias/read.php(17): Materias->read()
#1 {main
}
thrown in <b>/var/www/html/models/Materias.php</b> on line <b>24</b><br />
**bd connection**
<?php
class Database {
// DB Params
private $host = 'localhost';
private $db_name = 'reticula';
private $username = 'root';
private $password = 'test ';
private $conn;
// DB Connect
public function connect() {
$this->conn = null;
try {
$this->conn = new PDO('mysql:host=' . $this->host . ';dbname=' . $this->db_name, $this->username, $this->password);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo 'Connection Error: ' . $e->getMessage();
}
return $this->conn;
}
}
This is where you call matters
<?php
// Headers
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
include_once '../../config/Database.php';
include_once '../../models/Materias.php';
// Instantiate DB & connect
$database = new Database();
$db = $database->connect();
// Instantiate blog post object
$materias = new Materias($db);
// Blog post query
$result = $materias->read();
// Get row count
$num = $result->rowCount();
// Check if any posts
if($num > 0) {
// Post array
$materias_arr = array();
// $posts_arr['data'] = array();
while($row = $result->fetch(PDO::FETCH_ASSOC)) {
extract($row);
$materias_item = array(
'clave_materia' => $clave_materia,
'nombre_materia' => $nombre_materia,
'semestre' => $semestre,
'creditos' => $creditos
);
// Push to "data"
array_push($materias_arr, $materias_item);
// array_push($posts_arr['data'], $post_item);
}
// Turn to JSON & output
echo json_encode($materias_arr);
} else {
// No Posts
echo json_encode(
array('message' => 'No Posts Found')
);
}
Related
I'm trying to get data from a table using a public function in PHP, but I get this error:
Uncaught Error: Call to a member function prepare() (PDO, php)
I'm searching for 2, 3 hours... But no result is similar or I did not understand.
<?php
class Config {
public static $SQL;
private function __construct() {
$host_name = "localhost";
$base_user = "root";
$base_pass = "";
$base_name = "home_page";
try {
self::$SQL = new PDO("mysql:host=$host_name;dbname=$base_name", $base_user, $base_pass);
self::$SQL->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch(PDOException $e) {
die("Something went wrong, database connection closed. Reason: ". $e->getMessage());
}
}
public static function GetData($table, $data, $id) {
$wc = Config::$SQL->prepare('SELECT `'.$data.'` FROM `'.$table.'` WHERE `ID` = ?');
$wc->execute(array($id));
$r_data = $wc->fetch();
return $r_data[$data];
}
}
?>
And I use this in my base file:
<h1><?php echo Config::GetData("page_details", "Moto", 1) ?></h1>
The error is from this line:
$wc = self::$SQL->prepare('SELECT `'.$data.'` FROM `'.$table.'` WHERE `ID` = ?');
Is there any particular reason why you want to use STATICeverywhere? The common approach is using public, dynamic methods and properties. I rewrote your sample with suggested naming convention in PHPs OOP, it works:
<?php
class Config
{
/** #var PDO $conn */
private $conn = null;
public function __construct()
{
$host_name = "localhost";
$base_user = "root";
$base_pass = "";
$base_name = "home_page";
try {
$this->conn = new PDO("mysql:host=$host_name;dbname=$base_name", $base_user, $base_pass);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully"; // <- this is unnnesesary
} catch (PDOException $e) {
die("Something went wrong, database connection closed. Reason: " . $e->getMessage());
}
}
public function findById($table, $data, $id)
{
$stmt = $this->conn->prepare('SELECT `' . $data . '` FROM `' . $table . '` WHERE `uid` = ?');
$stmt->execute(array($id));
return $stmt->fetch(PDO::FETCH_ASSOC);
}
}
// just for test
$cfg = new Config();
print_r($cfg->findById('foo', '*', 1));
or in your case
<?php echo $cfg->findById("page_details", "Moto", 1)['Moto'] ?>
I have this code
<?php
class Objekt{
// database connection and table name
private $conn;
private $table_name = "objects";
// object properties
public $id;
public $id_group;
public $title;
public $description;
public $lat;
public $lng;
public $icon;
public $tagsraw;
// constructor with $db as database connection
public function __construct($db){
$this->conn = $db;
}
function create(){
// query to insert record
$query = "INSERT INTO
" . $this->table_name . "
SET
id_group=:id_group, title=:title, description=:description, lat=:lat, lng=:lng, icon=:icon;
SELECT max(id) AS id FROM objects;";
// prepare query
$stmt = $this->conn->prepare($query);
// sanitize
$this->id_group=htmlspecialchars(strip_tags($this->id_group));
$this->title=htmlspecialchars(strip_tags($this->title));
$this->description=htmlspecialchars(strip_tags($this->description));
$this->lat=htmlspecialchars(strip_tags($this->lat));
$this->lng=htmlspecialchars(strip_tags($this->lng));
$this->icon=htmlspecialchars(strip_tags($this->icon));
// bind values
$stmt->bindParam(":id_group", $this->id_group);
$stmt->bindParam(":title", $this->title);
$stmt->bindParam(":description", $this->description);
$stmt->bindParam(":lat", $this->lat);
$stmt->bindParam(":lng", $this->lng);
$stmt->bindParam(":icon", $this->icon);
// execute query
if($stmt->execute()){
//$stmt->execute();
/*
ERROR below here
Uncaught PDOException: SQLSTATE[HY000]: General error
stack trace:
#0 PDOStatement ->fetch(2)
#1 Objekt->create()
*/
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$this->id = $result['id'];
echo "$this->id";
//get tags matches
$tags = [];
$this->tagsraw = preg_replace('/\s+/', '', $this->tagsraw);
$tags = explode(',', $this->tagsraw);
$id_tags = [];
for ($i = 0; $i < sizeof($tags); $i++) {
$query = "SELECT id FROM category WHERE title=" . tags[i];
$stmt = $this->conn->prepare($query);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_OBJ);
$id_tags[i] = $result->id;
}
for ($i = 0; $i < sizeof($id_tags); $i++) {
$query = "INSERT INTO category_object SET id_object=" . $this->id . ", id_category=" . $id_tags[i];
$stmt = $this->conn->prepare($query);
$stmt->execute();
}
return true;
}
return false;
}
What I want to do:
Insert Object and create a relation to a category_object table over foreign keys id_object / id_category
What I would like to improve:
What do I have to do to delete an insert if it fails (where should I put a try/catch or something else)
What is wrong with my fetch? I Select the value from max(id) to get the value of my inserted object, why is it throwing an Exception
I have another Warning why is it telling me that
for ($i = 0; $i < sizeof($id_tags); $i++) {
$query = "INSERT INTO category_object SET id_object=" . $this->id . ", id_category=" . $id_tags[i];
$stmt = $this->conn->prepare($query);
$stmt->execute();
}
will be deprecated in future php versions..
Use transactions.
Any insert/update/delete done within a transaction will not be actually executed against the database until you call commit(), and you can always roll back the changes, abandoning them in case of failure.
In your code, you should be OK with replacing if($stmt->execute()){ with
try {
$this->conn->beginTransaction();
$stmt->execute();
// ...everything else from inside the if statement here...
$this->conn->commit();
return true;
} catch (\Exception $e) {
$this->conn->rollback();
return false;
}
I am in the process of learning PDO and am trying to implement it in my current project. When I used mysqli, I could get detailed info about any error using mysqli_error($connection). I googled at what the comparable for PDO would be and found this post, and decided to implement it in my code. However, I am unable to get any error messages even when I know there is an obvious error in the sql statement.
Relevant code:
class Database {
public $connection;
function __construct() {
$this->open_database_connection();
}
public function open_database_connection() {
try {
$this->connection = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME, DB_USER, DB_PASSWORD);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->connection->setAttribute( PDO::ATTR_EMULATE_PREPARES, false);
} catch(PDOException $e) {
echo $e->getMessage();
die('Could not connect');
}
} // end of open_database_connection method
public function query($sql, $params = []) {
try {
$query = $this->connection->prepare($sql);
} catch (Exception $e) {
var_dump('mysql error: ' . $e->getMessage());
}
foreach($params as $key => $value) {
if ($key === ':limit') {
$query->bindValue($key, $value, PDO::PARAM_INT);
} else {
$query -> bindValue($key, $value);
}
}
try {
$query->execute();
} catch(Exception $e) {
echo 'Exception -> ';
var_dump($e->getMessage());
}
/*
DID NOT WORK:
if (!$query->execute()) {
print_r($query->errorinfo());
}*/
$result = $query->fetchAll(PDO::FETCH_ASSOC);
$this->confirm_query($result);
return $result;
} // end of query method
function confirm_query($query) {
if (!$query) {
die('mysql error: ');
}
}
When I run the code, I do get the "mysql error", but I do not get any details about it. What am I doing wrong?
Update: As requested, I am providing additional details below.
What I am trying to do is get the user's login detail to be verified. To that end, once the user inputs his credentials , this code runs:
if (isset($_POST['submit'])) {
$username = trim($_POST['username']);
$password = trim($_POST['password']);
//check the database for the user
$user_found = User::verify_user($username, $password);
Relevant code from the User class:
public static function verify_user($username, $password) {
global $db;
$username = $db->escape_string($username);
$password = $db->escape_string($password);
$values = [ ":username" => $username,
":password" => $password,
":limit" => 1
];
$result_array = self::find_this_query("SELECT * FROM users WHERE username=:username AND password=:password LIMIT :limit", true, $values);
return !empty($result_array)? array_shift($result_array) : false;
}
public static function find_this_query($sql, $prepared = false, $params = []) {
global $db;
$the_object_array = array();
$result = $db->query($sql, $params);
$arr_length = count($result);
for ($i = 0; $i < $arr_length; $i++) {
$the_object_array[] = self::instantiation($result[$i]);
}
return $the_object_array;
}
public static function instantiation($the_record) {
$the_object =new self; //we need new self because $the_record corresponds to one user!
foreach($the_record as $the_attribute => $value) {
if ($the_object->has_the_attribute($the_attribute)) {
$the_object->$the_attribute = $value;
}
}
return $the_object;
}
public function has_the_attribute($attribute) {
$object_properties = get_object_vars($this);
return array_key_exists($attribute, $object_properties);
}
You have to use PDO::errorInfo():
(...)
public function query($sql, $params = []) {
try {
$query = $this->connection->prepare($sql);
if( !$query )
{
$error = $this->connection->errorInfo();
die( "mysql error: {$error[2]}" );
}
} catch (Exception $e) {
var_dump('mysql error: ' . $e->getMessage());
}
(...)
}
PDO::errorInfo returns an array:
Element 0: SQLSTATE error code (a five characters alphanumeric identifier defined in the ANSI SQL standard);
Element 1: Driver-specific error code;
Element 2: Driver-specific error message.
I'm trying to connect using a simle db class. For some reason it only print out
"Initiate DB class"
test.php
include 'db.class.php';
echo 'Initiate DB class';
$db = new DB();
echo 'DB class did load';
db.class.php
class DB extends mysqli {
private static $instance = null;
private function __construct () {
parent::init();
$host = 'localhost';
$user = 'root';
$pass = 'MY_PASS';
$dbse = 'MY_DB';
parent::real_connect($host, $user, $pass, $dbse);
if (0 !== $this->connect_errno):
die('MySQL Error: '. mysqli_connect_error());
//throw new Exception('MySQL Error: '. mysqli_connect_error());
endif;
}
public function fetch ($sql, $id = null, $one = false) {
$retval = array();
if ($res = $this->query($sql)):
$index = 0;
while ($rs = $res->fetch_assoc()):
if ($one):
$retval = $rs; break;
else:
$retval[$id ? $rs[$id] : $index++] = $rs;
endif;
endwhile;
$res->close();
endif;
return $retval;
}
}
I have tried to search my log files for error but they come out empty.
Ok got it,
In your call to db your calling new DB(); which mean you're trying to call the constructor of your DB class.
In your DB class it looks like you're trying to create a singleton, but something is missing normally there would be something to assign the instance the database connection, and something that asks the instance if it's empty create a new connection or if it's not use the same instance.
At the end of the day to make this work you can change your constructor to public.
Try this:
Db_class:
class Db_class{
/***********************CONNECT TO DB*********************/
public function db_connect(){
$user = '***';
$db = '***';
$password = '***';
$host = '***';
try {
$dbh = new PDO("mysql:host=$host;dbname=$db", $user, $password);
}
catch(PDOException $err) {
echo "Error: ".$err->getMessage()."<br/>";
die();
}
return $dbh;
}
/******************PREPARE AND EXECUTE SQL STATEMENTS*****/
public function query($statement){
$keyword = substr(strtoupper($statement), 0, strpos($statement, " "));
$dbh = $this->db_connect();
if($dbh){
try{
$sql = $dbh->prepare($statement);
$exe = $sql->execute();
}
catch(PDOException $err){
return $err->getMessage();
}
switch($keyword){
case "SELECT":
$result = array();
while($row = $sql->fetch(PDO::FETCH_ASSOC)){
$result[] = $row;
}
return $result;
break;
default:
return $exe;
break;
}
}
else{
return false;
}
}
Other PHP:
$db = new Db_class();
$sql = "SQL STATEMENT";
$result = $db->query($sql);
Your constructor is marked as private which means new DB will raise an error. I see you have a private property to store an instance, are you missing the singleton method to return a new object?
This question already has answers here:
Call to a member function on a non-object [duplicate]
(8 answers)
Closed 10 years ago.
I'm new to php oop.here i wanted to do database connectivity with singleton class but i got error like this:
Fatal error: Call to a member function getOne() on a non-object in C:\xampp\htdocs\singleton\new\singleton_db.php
here i have given two file
1.singleton_db.php
<?php
class database
{
public $query;
public $results;
public $conn;
public static $database;
//connect to the database
public function __construct()
{
$this->conn = mysql_connect('localhost','root','');
if ($this->conn)
{
mysql_select_db('test1');
}
}
public static function instance()
{
if (!isset(self::$database)) {
self::$database = new database();
}
return self::$database;
}
function getOne($sql) {
$result = $this->conn->getOne($sql); //Error in this line
if(database::isError($result)) {
throw new Exception($result->getMessage(), $result->getCode());
}
return $result;
}
function startTransaction() {
//autoCommit returns true/false if the command succeeds
return $this->conn->autoCommit(false);
}
function commit() {
$result = $this->conn->commit();
if(database::isError($result)) {
throw new Exception($result->getMessage(), $result->getCode());
}
$this->conn->autoCommit(true);
return true;
}
function abort() {
$result = $this->conn->rollback();
if(database::isError($result)) {
throw new Exception($result->getMessage(), $result->getCode());
}
return true;
}
//returns numerically indexed 1D array of values from the first column
public function insert($table, $arFieldValues) {
$fields = array_keys($arFieldValues);
$values = array_values($arFieldValues);
// Create a useful array of values
// that will be imploded to be the
// VALUES clause of the insert statement.
// Run the mysql_real_escape_string function on those
// values that are something other than numeric.
$escVals = array();
foreach($values as $val) {
if(! is_numeric($val)) {
//make sure the values are properly escaped
$val = "'" . mysql_real_escape_string($val) . "'";
}
$escVals[] = $val;
}
//generate the SQL statement
$sql = " INSERT INTO $table (";
$sql .= join(', ', $fields);
$sql .= ') VALUES(';
$sql .= join(', ', $escVals);
$sql .= ')';
$hRes = mysql_query($sql);
if(! is_resource($hRes)) {
$err = mysql_error($this->conn) . "\n" . $sql;
throw new Exception($err);
}
return mysql_affected_rows($hRes);
}
}
2.data.php
<?php
require_once('singleton_db.php');
try {
$db = database::instance();
} catch (Exception $e) {
// No point continuing...
die("Unable to connect to the database.");
}
$sql = "SELECT count(1) FROM mytable";
$count = $db->getOne($sql);
print "There are $count records in mytable!<br>\n";
// start a transaction
$db->startTransaction();
// do an insert and an update
try {
$arValues = array();
$arValues['id'] = '#id#';
$arValues['myval'] = 'blah blah blah';
$newID = $db->insert('mytable', $arValues);
print "The new record has the ID $newID<br>\n";
// update the record we just created
$arUpdate = array();
$arUpdate['myval'] = 'foobar baz!';
$affected = $db->update('mytable', $arUpdate, "id = $newID");
print "Updated $affected records<br>\n";
// write the changes to the database
$db->commit();
} catch (Exception $e) {
// some sort of error happened - abort the transaction
// and print the error message
$db->abort();
print "An error occurred.<br>\n" . $e->getMessage();
}
?>
What could I do to fix this ?
Your problem is you haven't defined the
getOne();
method properly. The property
$this->conn
Is just the result of mysql_connect() function which is a "MySQL link identifier on success, or FALSE on failure". It is not an object, and such, you can not ask it for the getOne(); method.