Trigger __construct function from another class - php

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

Related

PHP Database Class query Fatal error

Folks,
Let me preface this by stating that I'm trying to learn OOP so rather than use one of the existing Mysqli abstraction layers out there, I wanted to write my own Class.
I have the class defined in a file, and I'm just trying to get a generic query working before I start writing specific query functions.
<?php
/* Database Config */
define('DB_NAME', 'project');
define('DB_USER', 'foo');
define('DB_PASS', 'bar');
define('DB_HOSTNAME', '127.0.0.1');
class Database {
private $host;
private $user;
private $pw;
private $db;
public $con;
public function __construct($hostname, $user, $pass, $db) {
$this->DB_HOSTNAME = $hostname;
$this->DB_USER = $user;
$this->DB_PASS = $pass;
$this->DB_NAME = $db;
}
public function connect() {
$this->con = new mysqli($this->hostname, $this->user, $this->pass, $this->db)
or die('Database unavailable');
$this->con->set_charset ('utf8');
}
public function query($sql) {
$stmt = $this->con->query($sql);
}
}
// Create a single global instance of the database class
global $DB;
$DB = new Database();
?>
Then I created a simple test.php containing:
<?php
include_once("include/config.inc");
if ($DB) {
$sql = "select user_login, user_name from users where 1 order by user_name, user_login";
$stmt = $DB->query($sql) or die($DB->errno.__LINE__);
$result = $stmt->fetch_array(MYSQLI_ASSOC);
var_dump($result);
}
else die('Database Unavailable');
?>
When I call that page I get
Fatal error: Call to a member function query() on a non-object in /www/htdocs/project/include/db.class.php on line 33
I'm not getting a die from the test page, so I believe it can reach the database, and I know the table holds data and the query works because if I switch to non Class based DB definition I get an array with expected data.
So I'm pretty sure it's a problem I created in the Class, I just can't figure out what it is. Advice please?
Seems your object wasn't created
this is your construct. It means when you create object you need to specify parameters
public function __construct($hostname, $user, $pass, $db)
Do it like this
$DB = new Database('hostname', 'dbuser', 'dbpass', 'db');
Your class is initialized fine, that's not the issue. The issue is that it can't find the query function on con, since you're not calling connect before you call query.
You should add a line inside your query function to call connect if con doesn't yet exist or isn't active, so you don't have to remember to call it before calling query.

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.

PHP - PDO 'config' file equivalent

This may be a question that has been answered before - if so please just leave a comment below and I'll remove this one.
I have been learning classes in PHP and at the same time making the jump to PDO.
One concept I cant seem to find is how to acomplish the equivalent to this with classes:
config.php
<?php
$host = 'localhost';
$user = 'user';
$pass = 'pass';
$con = mysql_connect($host, $user, $pass) or die("MySQL Error");
mysql_select_db("account_db", $con);
?>
another.php
<?php
require_once('config.php');
$selectStatement = "SELET foo FROM bar";
$selectQuery = mysql_query($selectStatement, $con);
?>
I haven't quite figured out how I would create a config file/class for a PDO connection and then use it in another class, i.e. Users as below:
<?php
class Users
{
private $_userId;
function setUserId($username)
{
// Use a predefined database handle to connect to a database to get the users ID - I assume using a preconfigured $dbh handle via an include or extend?
$sth = $dbh->prepare("SELECT id FROM users WHERE username = :username");
$sth->bindParam(':username', $username);
...
}
}
?>
Thanks all :)
In my projects, I prefer using a class with a static member which holds the PDO object.
<?php
class DB
{
private static $instance = null;
public static function get()
{
if(self::$instance == null)
{
try
{
self::$instance = new PDO('mysql:host=localhost;dbname=name', 'user', 'abc123');
}
catch(PDOException $e)
{
// Handle this properly
throw $e;
}
}
return self::$instance;
}
}
The I can access it like so:
<?php
require 'DB.php';
class Users
{
private $_userId;
function setUserId($username)
{
// Using DB::get() to get the PDO object
$sth = DB::get()->prepare("SELECT id FROM users WHERE username = :username");
$sth->bindParam(':username', $username);
...
}
}

OO database class

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.

Categories