When I attempt to connect to my SQL database with my pdo_object.php file, my model.php returns this error:
Fatal error: Class 'Db' not found in /path/model.php on line 8
I made sure all of the permissions are correct and credentials are correct for all of my files. Here are the two files in question.
Not really sure what the issue is here so any help would be awesome.
pdo_object.php
<?php
$user = 'someusername';
$pass = 'somepassword';
$db_info='somehost';
try {
$db = new PDO($db_info, $user, $pass);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
?>
and then model.php
<?php
include('pdo_object.php');
class Model{
public $db;
public function __construct(){
$this->db = Db::getDb();
}
public function getAllRecords($sql, $parameters = null){
$stm = $this->db->prepare($sql);
$stm->execute($parameters);
return $stm->fetchAll();
}
public function getOneRecord($sql, $parameters = null){
$stm = $this->db->prepare($sql);
$stm->execute($parameters);
return $stm->fetch();
}
}
?>
Where is class Db { //blah }? Nowhere. But you HAVE defined $db in the first file.
I also recommend dependency injection, rather than calling static class methods inside your class. Essentially, pass the $db in in the constructor:
public function __construct(PDO $db)
{
$this->db = $db;
}
And instantiate like so:
$model = new Model($db);
The Db class was not present in the pdo_object.php file, thus resulting in the index.php file throwing an error when referencing a non existing class.
class Db {
private static $db;
public static function getDb() {
if(!self::$db) {
try {
$dsn = 'somehost; dbname=somedbname';
self::$db = new PDO($dsn, 'username', 'password');
self::$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ);
} catch (PDOException $e) {
die('Connection error: ' . $e->getMessage());
}
}
return self::$db;
}
}
Related
I wanna get data on table and write a class. But this class doesn't work because pdo doesn't access. How can I get table data with this class?
$db = new PDO("mysql:host=localhost;dbname=xxx;charset=utf8", "xxx", "xxx");
class uye extends PDO{
var $id;
var $kadi;
function cek($id){
$query = $db->query("SELECT * FROM btc WHERE id='{$id}'", PDO::FETCH_ASSOC);
if ( $query->rowCount() ) {
foreach( $query as $row ){
$this->id=$row["id"];
$this->kadi=$row["kadi"];
}
}
}
}
$bilgiler=new uye;
$bilgiler->cek(1);
echo $bilgiler->kadi;
So I'm running this off of fetching all data as I dont know where you're getting $id from.
I generally break my code up into files and folders as I found this easier to work with and others to work on.
// database connection file (dbc.php)
class Database
{
private $host = "127.0.0.1";
private $db = "";
private $user = "";
private $password = "";
public $conn;
public function dbConnect()
{
$this->conn = null;
try
{
$this->conn = new PDO("mysql:host=" . $this->host . ";dbname=" . $this->db, $this->user, $this->password);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $exception)
{
echo "Connection error: " . $exception->getMessage();
}
return $this->conn;
}
}
I then make a common file, this is where you can store all of your frequently used functions or your static functions
// Common file (common.php)
require_once('dbc.php');
class DBCommon
{
private $conn;
public function __construct()
{
$database = new Database();
$db = $database->dbConnect();
$this->conn = $db;
}
public function run($sql)
{
$stmt = $this->conn->prepare($sql);
return $stmt;
}
}
So to explain this a little more, you will see a function of run() this is just to save the tedious $this->conn->prepare on every query.. Now you can run $this->run()
The next would be your class file.. this is where your logic goes:
// your class file... (class.btc.php)
require_once "common.php";
class BTC extends DBCommon
{
public function getQuery()
{
$stmt = $this->run("SELECT * FROM `btc`");
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_OBJ))
{
$rows[] = $row;
}
return $rows;
}
}
Self explanatory..
And then your calling method.. Lets say index.php
// File you're calling your class from (index.php)
require_once "class.btc.php";
$fetch = new BTC();
$returnData = $fetch->getQuery();
foreach ($returnData as $data)
{
echo
"<p>$data->something</p>
<p>$data->somethingElse</p>";
}
It seems a little long winded I know, but the time you'll save overall will help!
This question already has an answer here:
Fatal error Call to a member function prepare() on null [closed]
(1 answer)
Closed 5 years ago.
I know there were a lot of answers related to this error, but I still don't know how to solve it... I'm trying to make the database connection, which would connect to the database and insert user's entered values in it and i got this error. I've created 2 files (with different classes):
Here is a connection file:
<?php
class Connection {
// Setting Database Source Name (DSN)
public function __construct() {
$dsn = 'mysql:host=localhost;dbname=employees';
// Setting options
$options = array (PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
// Making the connection to the database
try {
$this->dbh = new PDO($dsn, 'root', '', $options);
}
catch (PDOException $e) {
$this->error = $e->getMessage();
}
}
}
$connection = new connection();
?>
And here is users.php file:
<?php
include 'connection.php';
class Users {
public $name;
public $surname;
public $employmentDate;
public function __construct()
{
if(isset($_POST['Submit'])) {
$this->name = $_POST['name'];
$this->surname = $_POST['surname'];
$this->employmentDate = $_POST['employmentDate'];
}
}
// Inserting users values to the database table
public function insertUserValues() {
$stmt= 'INSERT INTO employee (name,surname,employment_date) VALUES (:name,:surname,:employmentDate)';
$stmt = $this->dbh->prepare();
$stmt->bindValue(':name',$name, PDO::PARAM_STR);
$stmt->bindValue(':surname',$surname, PDO::PARAM_STR);
$stmt->bindValue(':employmenDate',$employmentDate, PDO::PARAM_STR);
$stmt->execute([$this->name,$this->surname,$this->employmentDate]);
}
}
$users = new Users();
$users->insertUserValues();
?>
I guess there are some mistakes in code structure, but I'm just learning, so. The code line which throws the error 18 line in users.php file:
$stmt = $this->dbh->prepare();
Please someone tell me where I am doing a mistake, thank you for any help.
You just have somes mistakes in your code. Try to use this lines :
Connection file :
<?php
class Connection {
public $dbh;
// Setting Database Source Name (DSN)
public function __construct() {
$dsn = 'mysql:host=localhost;dbname=employees';
// Setting options
$options = array (PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
// Making the connection to the database
try {
$this->dbh = new PDO($dsn, 'root', '', $options);
}
catch (PDOException $e) {
$this->error = $e->getMessage();
}
}
}
$connection = new connection();
users.php file :
<?php
include 'connection.php';
class Users {
public $name;
public $surname;
public $employmentDate;
public $connection;
public function __construct($connection)
{
$this->connection = $connection;
if(isset($_POST['Submit'])) {
$this->name = $_POST['name'];
$this->surname = $_POST['surname'];
$this->employmentDate = $_POST['employmentDate'];
}
}
// Inserting users values to the database table
public function insertUserValues() {
$query = 'INSERT INTO employee (name,surname,employment_date) VALUES (:name,:surname,:employmentDate)';
$stmt = $this->connection->dbh->prepare($query);
$stmt->bindValue(':name',$this->name, PDO::PARAM_STR);
$stmt->bindValue(':surname',$this->surname, PDO::PARAM_STR);
$stmt->bindValue(':employmentDate',$this->employmentDate, PDO::PARAM_STR);
$stmt->execute();
}
}
$users = new Users($connection);
$users->insertUserValues();
Explanations :
You have to pass the $connection variable to your users class (or import it with global $connection;)
Your connection file has to make visible the dbh property, otherwise you will not be able to make any query on your database
PDO prepare() method is waiting for a query in first argument
You don't need to pass an array to execute() method if you already have binded your values before
You are referring to $this from outside the class scope. You probably want
$connection->dbh->prepare();
You could make your connection class to a singleton:
class Connection {
private static $instance = null;
// Setting Database Source Name (DSN)
public function __construct() {
$dsn = 'mysql:host=localhost;dbname=employees';
// Setting options
$options = array (PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
// Making the connection to the database
try {
$this->dbh = new PDO($dsn, 'root', '', $options);
} catch (PDOException $e) {
$this->error = $e->getMessage();
}
}
public static function __callStatic($name, $args) {
if (self::$instance == null) {
self::$instance = new self();
}
call_user_func_array([ self::$instance->dbh, $name], $args);
}
}
Then use it as follows:
Connection::prepare(); //or connection::any_pdo_function
I'm having this error when I try to insert data in my database. I've searched the reasons of this error and I think my codes are right and I'm not supposed to get the error. My codes are these:
config.php
<?php
class DatabaseConnection{
public function __construct(){
try{
$pdo = new PDO('mysql:host=localhost;dbname=test','root',''); //'mysql:host=host;dbname=dbname','mysqluser','mysqlpassword'
}
catch (PDOException $e){
exit('Database error');
}
}
}
?>
functions.php
<?php
require "config.php";
class LoginRegister{
function __construct(){
$database= new DatabaseConnection();
}
public function registerUser($username,$password,$name,$email){
global $pdo; //THIS IS THE LINE WITH ERROR
$query=$pdo->prepare("SELECT id FROM usuarios WHERE nombre_usuario=? AND correo_e=?");
$query->execute(array($username,$email));
$num=$query->rowCount();
if($num==0){
$query = $pdo->prepare("INSERT INTO usuarios(nombre_usuario,nombre_real,password,correo_e) VALUES (?,?,?,?)");
$query->execute(array($username,$password,$name,$email));
return true;
}else{
return print "Username or E_mail in use";
}
}
}
?>
register.php
<?php
require_once "functions.php";
$user = new LoginRegister();
?>
...HTML CODE...
<?php
if($_SERVER['REQUEST_METHOD'] == 'POST'){
$username=$_POST['nombre_usuario'];
$password=$_POST['password'];
$name=$_POST['nombre_real'];
$email=$_POST['correo_e'];
if(empty($username) or empty($password) or empty($name) or empty($email)){
echo "Error... Field must not be empty";
}else{
$register = $user->registerUser($username,$password,$name,$email);
if($register){
echo "Register done <a href='login.php'>Click here</a> for login";
}else{
echo "Username or E_mail in use";
}
}
}
?>
...HTML CODE...
As you can see, I declared the variable $pdo inside the registerUser functions, besides the variables that contain the name, username, password and email are parameters of the same function.
I know this is a several times duplicated question but I cannot solve this error with the solutions in the other ones.
There are several problems with your code.
Two were explained in the other answer, which will make your code work (eventually it all was spoiled), but it's still wrong approach, which will connect to database as many times as many objects you have.
Change DatabaseConnection class this way
class DatabaseConnection{
public $pdo;
public function __construct(){
$user = 'root';
$pass = '';
$dsn = 'mysql:charset=utf8;dbname=test;host=localhost;charset=utf8';
$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
);
$this->pdo = new PDO($dsn, 'root', '', $opt);
}
}
Change LoginRegister constructor this way
function __construct($db){
$this->db= $db;
}
And make register.php this way
require_once "functions.php";
$db = new DatabaseConnection();
$user = new LoginRegister($db->pdo);
and then in LoginRegister use $this->db instead of $pdo all the way.
The main idea to make $db connection an external service for the application class. Otherwise it will be all the same as despised global, but just in another form.
I'm sorry but I must say hat horrible code. You are making all the worst mistakes. First NEVER use global, just never do it. Google it for an explanation why.
Now the variables you create in your constructors only have scope there so they are never avaliable in your other class or method. That is why $pdo is not a PDO object it is just a local var with null value. Try this:
class DatabaseConnection{
private $pdo;
public function __construct(){
try{
$this->pdo = new PDO('mysql:host=localhost;dbname=test','root',''); //'mysql:host=host;dbname=dbname','mysqluser','mysqlpassword'
}
catch (PDOException $e){
exit('Database error');
}
}
public function getPdo()
{
return $this->pdo;
}
class LoginRegister{
private $database;
function __construct(){
$this->database= new DatabaseConnection();
}
public function registerUser($username,$password,$name,$email){
$pdo = $this->database->getPdo();
$query=$pdo->prepare("SELECT id FROM usuarios WHERE nombre_usuario=? AND correo_e=?");
Now this is still horrible but at least it will work. You really must read up on object oriented programming from a good book, one that also teaches you about design patterns and SOLID, DRY and other best practices.
Here I have used php singleton PDO connection with mysql. Hope this will be help
<?php
class DB {
protected static $instance;
protected function __construct() {
if(empty(self::$instance)) {
try {
self::$instance = new PDO("mysql:host=localhost;dbname=techprojects", 'root', '');
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
} catch(PDOException $error) {
echo $error->getMessage();
}
}
}
public static function getInstance() {
if(empty(self::$instance)) {
try {
new DB();
//var_dump(self::$instance);
} catch(PDOException $error) {
echo $error->getMessage();
}
}
//var_dump(self::$instance);
return self::$instance;
}
private function __clone() {
// Stopping Clonning of Object
}
private function __wakeup() {
// Stopping unserialize of object
}
}
?>
<?php
try {
$db = DB::getInstance();
$db1 = DB::getInstance();
$sqlExample = 'SELECT * FROM keywords';
$stm = $db->prepare($sqlExample);
$stm->execute();
$result = $stm->fetchAll(PDO::FETCH_ASSOC);
var_dump($db);
var_dump($db1);
echo "<pre>";
print_r($result);
echo "</pre>";
} catch (Exception $e) {
print $e->getMessage();
}
?>
I have a PHP class with two methods. One connects to a MySQL database for output, and the other connects to a MySQL database for input.
My question is, for both functions, I repeated the code for connecting to the database. What would be a better way to maybe have a third function in the class to connect to the DB and have the other two call the function to establish the connection, rather than repeat the code twice? I'm a PHP n00b trying to improve my OOP coding. Notice how I connected to the DB twice--using the exact same code:
class output_mysql {
var $db_name = 'database';
var $db_username = 'name';
var $db_password = 'mypassword';
function print_table_cell($tbl_name, $colm_name, $array_index_num) {
try {
$pdo = new PDO("mysql:host=localhost;dbname=$this->db_name", $this->db_username, $this->db_password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
$error = 'Unable to connect to the database server.';
include 'output_mysql_error.php';
exit();
}
try {
$sql = "SELECT $colm_name FROM $tbl_name";
$result = $pdo->query($sql);
}
catch (PDOException $e) {
$error = 'Error fetching content: ' . $e->getMessage();
include 'output_mysql_error.php';
exit();
}
while ($row = $result->fetch()) {
$all_content[] = $row["$colm_name"];
}
echo $all_content[$array_index_num];
}
function update_content($tbl_name, $colm_name, $error_message_text, $id_num) {
try {
$pdo = new PDO("mysql:host=localhost;dbname=$this->db_name", $this->db_username, $this->db_password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch (PDOException $e) {
$error = 'Unable to connect to the database server.';
include 'output_mysql_error.php';
exit();
}
try {
$sql = 'UPDATE website_content SET
content = :content,
date_added = CURDATE()
WHERE id = :id';
$s = $pdo->prepare($sql);
$s->bindValue(':content', $error_message_text);
$s->bindValue(':id', $id_num);
$s->execute();
}
catch (PDOException $e) {
$error = 'Error: ' . $e->getMessage();
include 'output_mysql_error.php';
exit();
}
}
}
This question is tagged [oop], but the code in it is far from OOP.
Your methods are doing waaaaaaaaaaaaay too much. What you should do is inject the database connection into the constructor of the output_mysql class (which is a terrible name btw).
namespace App\Page;
class Content
{
private $dbConnection;
public function __construct(\PDO $dbConnection)
{
$this->dbConnection = $dbConnection
}
public update($id, $content)
{
$stmt = $this->dbConnection->prepare('UPDATE website_content SET content = :content, date_added = CURDATE() WHERE id = :id');
$stmt->execute([
'id' => $id,
'content' => $content,
]);
}
}
$dbConnection = new \PDO("mysql:host=localhost;dbname=$this->db_name", $this->db_username, $this->db_password);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pageContent = new \App\Page\Content($dbConnection);
$pageContent->update(1, 'new content');
If you have a method called print_table_cell you are probably doing OOP wrong, because it probably means you code is doing too much and probably violates the Single Responsibility Principle. I mean a class in almost all circumstances would never need to be able to access any column of just any table.
class Model
{
protected $pdo;
/**
* Inject the pdo driver in the model.
*/
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function print_table_cell($tbl_name, $colm_name, $array_index_num)
{
// Use the pdo object $this->pdo
}
}
// Create the connection
$dbName = '';
$dbUsername = '';
$dbPassword = '';
$pdo = new PDO("mysql:host=localhost;dbname=$dbName", $dbUsername, $dbPassword);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Create your model and inject the pdo object.
$model = new Model($pdo);
$model->print_table_cell() ...
As said above you need to use prepared statements, because PDO will escape the values which prevents SQL injections. But anyway all input data must be filtered : you have some basic filters http://php.net/manual/fr/function.filter-var.php.
The model class should only interact with the database, and doesn't print anything.
For priting output you can use a so called View class that get data from the model and displays it.
class View
{
protected $model;
public function __construct(Model $model)
{
$this->model = $model;
}
public function render()
{
echo $this->model->getData();
}
}
class Model
{
protected $pdo;
public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}
public function getData()
{
// Do your query here with $this->pdo and prepared statement.
// and return the data
}
}
$pdo = new PDO(...);
$model = new Model($pdo);
$view = new View($model);
$view->render();
I have a question regarding my PDO class. It's not working and creates this error: "Notice: Undefined variable: db in classes.php on line 21 Fatal error: Call to a member function prepare() on a non-object in classes.php on line 32. I tried to fix this code for several hours but i don't find the error. Your help would be appreciated!
Thank you in advance.
<?
// classes.php
class Connection{
public static $db;
function __construct()
{
try {
$this->$db = new PDO('mysql:host=localhost;dbname=vnm', '--', '--', array(PDO::ATTR_PERSISTENT => true));
$this->$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}
public function GetAccess()
{
return $db;
}
}
class Page
{
public function show_page($s_p1)
{
$db = Connection::GetAccess();
$id = "1";
$stmt = $db->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute();
while($row = $stmt->fetch())
{
print_r($row);
}
}
}?>
Static members must be accessed using static::. You directly access $db in your code, and incorrectly use $this->db, when you should be using static::$db. You also need to declare GetAccess as a public static function.
Also, calling Connection::GetAccess doesn't actually instantiate the class, so static::$db will probably be null, unless you create your singleton instance elsewhere.
You can read more about singletons here: http://www.talkphp.com/advanced-php-programming/1304-how-use-singleton-design-pattern.html
try this. I removed all static methods.
<?
// classes.php
class Connection{
public $db;
function __construct()
{
try {
$this->$db = new PDO('mysql:host=localhost;dbname=vnm', '--', '--', array(PDO::ATTR_PERSISTENT => true));
$this->$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}
public function GetAccess()
{
return $this->$db;
}
}
class Page
{
public function show_page($s_p1)
{
$con = new Connection();
$db = $con->GetAccess();
$id = "1";
$stmt = $db->prepare('SELECT * FROM users WHERE id = :id');
$stmt->execute();
while($row = $stmt->fetch())
{
print_r($row);
}
}
}?>