OO database class - php

I'm trying to learn object oriented programming more clearer by creating a database class in PHP.
This is what i have right now. I'm getting an error about $mysqli being an undefined variable when i try to call it using $db->query();
Please explain how to make the variable $mysqli defined.
<?php
class phpDatabaseClass {
public function __construct()
{
$mysqli = new mysqli(DBhost, DBusername, DBpassword, DBname);
}
public function query()
{
$sql = 'select * from users';
$results = $mysqli->query($sql);
if(($results->num_rows) > 0)
{
echo 'We have: '.$results->num_rows;
}
}
}
?>
In another file i am instantiating the object and then calling a function like this:
require 'phpDatabaseClass.php';
define('DBhost', 'localhost');
define('DBusername', 'root');
define('DBpassword', 'root');
define('DBname', 'campbellCustomCoatings');
$db = new phpDatabaseClass();
$db->query();

Your instance of mysqli will need to be a member of your class, have a look here...
class phpDatabaseClass {
private $mysqli;
public function __construct()
{
$this->mysqli = new mysqli(DBhost, DBusername, DBpassword, DBname);
}
public function query()
{
$sql = 'select * from users';
$results = $this->mysqli->query($sql);
if(($results->num_rows) > 0)
{
echo 'We have: '.$results->num_rows;
}
}
}
Also, because you are learning, try extending the PDO class to learn about inheritance.
Also, slightly tangential, but generally constants are named with ALL_CAPS_WITH_UNDERSCORE_SEPARATORS.
Also, database stuff in global defines can be risky, as every piece of PHP can access it. I know WordPress does it, but trust me that the quality of its code is questionable. Its popularity however, is without doubt huge.

The problem I can see is trying to make $mysqli persist between function calls inside the same object.
What needs to be done is to have the variable stored as an instance variable, which are qualified by $this->[VARIABLE]:
<?php
class phpDatabaseClass {
public function __construct()
{
$this->mysqli = new mysqli(DBhost, DBusername, DBpassword, DBname);
}
public function query()
{
$sql = 'select * from users';
$results = $this->mysqli->query($sql);
if(($results->num_rows) > 0)
{
echo 'We have: '.$results->num_rows;
}
}
}
?>
I'd look into using PDO.

Related

Trigger __construct function from another class

I've created a class which is named connect, it includes a construct function for my database:
construct.php
<?php
include('includes/constants.php');
class connect {
public $db;
function __construct() {
$this->db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME) or die();
}
}
?>
I'm trying to reach this class & function from within another class:
mysql.php
<?php
include_once('construct.php');
$connect = new connect();
class mysql {
function verifyLogInData($email, $password) {
$query = "SELECT * FROM users WHERE email = ? AND password = ? LIMIT 1";
if($stmt = $connect->db->prepare($query)) {
$stmt->bind_param('ss', $email, $password);
$stmt->execute();
if($stmt->fetch()) {
$stmt->close();
return true;
}
}
}
}
?>
However, it seems like I can't trigger the $connect object. What would be the right way to do this or should I trigger this function with another method?
Line which is giving me the error:
if($stmt = $connect->db->prepare($query)) {
Thanks in advance.
PS: Any advice on my code is very much appreciated :)
You need to understand variable scope. In this case, you can pass the instance into the method:
function verifyLogInData($email, $password, $connect) {...}
Though it might be better to inject it into the mysql class via the constructor, or indeed to merge the two into a single class - i dont see a good reson to have two when they are so closely coupled

Call to a member function query on a non-object

I receive this Fatal Error when working with objects in PHP:
Call to a member function query() on a non-object
index.php:
$db = new PDO("mysql:host=localhost;dbname=world;charset=utf8", "root", "xxx");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn = new Connection($db);
$data = $conn->getCities();
foreach ($data as $row) {
print_r($row);
}
connection.php:
class Connection {
protected $db;
public function _construct(PDO $db) {
$this->db = $db;
}
public function getCities() {
return $this->db->query("SELECT * FROM city"); \\ Error here
}
}
In a single file it works fine:
$db = new PDO("mysql:host=localhost;dbname=world;charset=utf8", "root", "xxx");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$data = $db->query("SELECT * FROM city");
foreach($data as $row) {
print_r($row);
}
What is it about the object orientation I'm not understanding, or is there another reason?
If your code snippet is a copy/paste and is completely accurate, then you may have a very simple typo in the constructor. In PHP, they must start with two underscores in a row, and your code has only one:
class Connection {
public function _construct(PDO $db) {
$this->db = $db;
}
}
should become
class Connection {
public function __construct(PDO $db) {
$this->db = $db;
}
}
The explanation is this: Your existing code contains no syntactical or even semantic errors. There is simply a method called _construct that never gets called. When you make the new object, is is constructing the object, passing in a never-used $db that gets silently ignored.

Calling database set method inside construct

I am new to OOP so this is probably a simple solution. I am trying to clean up my code a little bit so that I don't have to do so much when I create an object. My code is below:
include "Database.php";
Class Database {
protected $conn;
public function setDb($conn){
$this->conn = $conn;
}
}
Class Images extends Database{
protected $conn;
protected $stmt;
function __construct(){
}
public function RetrieveImages(){
$this->stmt = $this->conn->prepare('SELECT * FROM `pictures`');
$this->stmt->execute();
$boom = $this->stmt->fetchAll();
return $boom;
}
}
$db = new Images();
$db->setDb($conn);
$test = $db->RetrieveImages();
var_dump($test);
Database.php:
try{
$conn = new PDO('mysql:host=localhost;dbname=testing', 'blah','boom!');
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){
echo'ERROR: ' . $e->getMessage();
}
This code is working fine but I would like to automate the $db->setDb($conn); part. Is there a way I can call this automatically so I can initiate the object like
$db = new Images();
$db->RetrieveImages();
I have tried adding
$db = new Database();
$db->setDb($conn);
to the constructor method inside the Images class but I get an error
Call to a member function prepare() on non object
I tried several different ways to get this working but I am not able to do so.
Is there a way I can call this automatically so I can initiate the object
That's not a very desirable property of any code; it prevents testability of your code; ignoring the unfortunate naming of your classes I would set it up like this:
class Database
{
protected $conn;
public function __construct($conn)
{
$this->conn = $conn;
}
}
Then your Images class becomes:
class Images extends Database
{
public function RetrieveImages()
{
$stmt = $this->conn->prepare('SELECT * FROM `pictures`');
$stmt->execute();
return $stmt->fetchAll();
}
}
To call the whole thing:
// $conn was created in "Database.php"
$images = new Images($conn);
print_r($images->RetrieveImages());
Your Database class has no database anythings.
It does not do anything.
You need to have a MySQLi or PDO object somewhere to do databsse calls.

OOP PHP - Returning $connection from functions (please see code)

Procedural PHP works for me, but when I try to code like I do in objective C I cannot seem to get the functions to work. I think it has something to do with my variable scope and the functions not returning any values. Where am I going wrong with my code here?
<?php
require_once("constants.php");
class Main {
public $menu;
public $connection;
function connectToDatabase() {
//connect to database & check connection
$connection = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); }
}
function queryDatabase($select, $from) {
$result = mysqli_query($connection,"SELECT $select FROM $from");
}
function closeDatabaseConnection() {
mysqli_close($connection);
}
function displayMenu() {
//connect to database & check connection
connectToDatabase();
//get menu data
queryDatabase(*, pages);
//construct menu data
echo '<ul class="mainNavigation">';
while($row = mysqli_fetch_array($result))
{
echo '<li><a href="' . $row['filename'] . '.php">';
echo $row['menu_name'];
echo '</a></li>';
}
echo '</ul>';
//close connection
closeDatabaseConnection();
}
function displayFooter() {
}
function getUser() {
}
function userLogIn() {
}
}
?>
if you want to use a method or variable inside it's own class, you have to put $this-> in front of it. For exmaple this connectToDatabase(); would become this $this->connectToDatabase();
Instead of using $connection, you should use $this->connection, and run it like so:
$Db = new Main();
$Db->connectToDatabase();
If you want to access a property inside a method, make sure to reference it with $this->prop, rather than just $prop. If the method is static, use self::prop instead.
$this refers to the current instantiation of the class. You would use the scope resolution operator (::) if the method/property is static (DBConnection::connection DBConnection::connectToDatabase())/
Also, I'd rename class 'Main' to something else like DBConnection (PHP doesn't use main methods like C does), then:
$Db = new DBConnection();
$Db->connectToDatabase();
Because in PHP, although you can have one class in one PHP file named connection.php, with a class of Main, if you have another class following the same pattern, then you'll have two Main classes.
There are all kinds of things wrong with this class, so I will focus on a few key points and maybe you can fix it from there without us having a total rewrite
First, consider this:
public $connection;
function connectToDatabase() {
//connect to database & check connection
$connection = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); }
}
You declare a class variable $connection, which is ok. But in your function you assign a local variable instead of accessing the class variable. From within a class, you would call all class members using $this. So the function should be:
function connectToDatabase() {
//connect to database & check connection
$this->connection = mysqli_connect(DB_SERVER, DB_USER, DB_PASS, DB_NAME);
if (mysqli_connect_errno()) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); }
}
Now, other methods attempt to call functions but they need to do the same thing:
function displayMenu() {
//connect to database & check connection
// this should just check to see if $connection is populated. if not then call this method
$this->connectToDatabase();
And this method is not accessing the class var for connection:
function queryDatabase($select, $from) {
$result = mysqli_query($this->connection,"SELECT $select FROM $from");
}
those few examples should give you the basic idea of accessing class methods and variables. You can ask specific questions and we may update, but for now this should get you going.
Here is a mysqli connection class that I use regularly. It might not answer your question but you can study it and it should help you better understand the concept. It did for me anyway.
class DBConnection
{
protected $mysqli;
private $db_host='localhost';
private $db_name='';
private $db_username='';
private $db_password='';
public function __construct() {
$this->mysqli = new mysqli($this->db_host,$this->db_username,
$this->db_password, $this->db_name) or die($this->mysqli->error);
return $this->mysqli;
}
public function getLink() {
return $this->mysqli;
}
public function query($query) {
return $this->mysqli->query($query);
}
public function real_escape_string($str) {
return $this->mysqli->real_escape_string($str);
}
function __destruct(){
$this->mysqli->close();
}
}
And then when you need to connect to the database in another class call it in the construct function like so:
public function __construct(DBConnection $mysqli) {
$this->mysqli = $mysqli->getLink();
}

mysql_connect vs mysqli_connect

i'm having a bit of an issue trying to use mysqli_connect the same way i use mysql_connect
this would be an example of my code:
QUERY.PHP
class classQuery{
public function __construct(){
require('conex/classConex.php');
require('conex/statement/classStatement.php');
$this->ObjConex = new classConex;
$this->ObjStatement = new classStatement;
}
public function Query($email){
$this->ObjConex->Conex();
$query='SELECT user_email from table where email='.mysql_real_escape_string($email).'';
$consulta = $this->ObjStatement->Select($query);
return $consulta;
}
CLASS STATEMENT
class classStatement{
public function __construct(){
$this->ObjConex = new classConex;
}
public function Select($query){
$query_execute = mysql_query($query);
while($row = mysql_fetch_row($query_execute)){
$consulta=htmlentities($row[0]);
}
return $consulta;
}
}
CLASS CONEX
class classConex{
public function Conex(){
require ('conex.php');
mysql_connect ($server,$dbuser,$dbpasswd) or die('Error de Conexión');
mysql_select_db($dbname);
}
}
Ok, now i want to use mysqli_connect instead of mysql_connect, according to php manual my new connect class should be something like this:
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
now that my connection is an object i won't be able to execute my query from ClassStatement the same way i'm doing it, i have tested returning the object from the connect class but that means more code that i find redundant...is there a more elegant way to do this?
mysql_connect creates a global connection that you are depending on. This is already inelegant. You will have a lot more control (especially if you need to maintain multiple connections simultaneously) if you treat the connection as an object instance -- which is what mysqli forces you to do.
It's not redundant either .. it's just clear.
How about structuring your class like this:
class Database {
public function __construct ( $server, $dbuser, $dbpasswd, $dbname ) {
$this->dbhandle = new mysqli($server, $dbuser, $dbpasswd, $dbname);
}
public function Select ($query) {
$result = $this->dbhandle->query($query);
while ( $row = $result->fetch_row() ){
// Whatever you're doing here...
//$consulta = htmlentities($row[0]);
}
return $consulta;
}
}
So you could use it with this code:
class Query{
public function __construct(){
require('conex/classDatabase.php');
$this->Database = new Database($host, $user, $pass, $dbname);
}
public function Query ($email) {
$query = "SELECT user_email from table where email='".mysql_real_escape_string($email)."'";
$consulta = $this->Database->Select($query);
return $consulta;
}
}
I've included the object oriented syntax in my examples. Since you're using objects anyway, you'll probably get along with it.
Mysqli_connect is the newer version of mysql library.
Here I in mysqli stands for improved.
Few things have been introduced with Mysqli.
They are,
1.Prepared statements.
2.Object oriented interface.
3.Support for multiple statements.
4.Embedded server support.

Categories