Passing mysqli to class for function use - php

Probably asked many times but I am hard-headed.
I have the following class to manage a MySQL db.
class blog {
function show ($mysqli) {
// Code working on $mysqli here
}
}
Since I will be using $mysqli in many functions inside of this class I read that I can create constructors in order to pass the $mysqli variable to the class and use it inside of each function so I can do something like:
$blog = new blog($mysqli);
$blog -> show();
Is this possible?

This is called Dependency injection.
Just use a field $mysqli in your class and initialize it in your constructor and use it via $this->mysqli:
class blog {
private $mysqli;
function __construct(mysqli $mysqli) {
$this->mysqli = $mysqli;
}
function show () {
// Code working on $this->mysqli here
}
}

To store it in the class, would be something like:
class blog {
private $mysqli;
function __construct($dbi) {
$this->mysqli = $dbi;
}
function show () {
$this->mysqli->query(); //example usage
// Code working on $mysqli here
}
}
And then in your code to use the class:
$blog = new blog($mysqli);
$blog->show();

Related

Class not printing variable

Im trying to understand objects & classes. But Im having a problem. Im trying to pass a variable from a class into another class.
Why Im doing this is mostly because I want to understand more how classs work but also for future where Im gonna need to send database connection into classes.
Here is my code simplified for the problem:
class databaseConnection
{
public function connect(){
return "localhost";
}
}
class like
{
private $database;
public function __construct(){
$this->database = databaseConnection::connect();
}
public function addLike()
{
return $database;
}
}
$obj = new like;
echo $obj->addLike();
But this doesn't show anything. What i thought the results would be is echo "localhost";
Why isn't this working?
connect is not a static method, you should either change it to static or create an instance.
// if you use databaseConnection::connect();
public static function connect(){
or
$db = new databaseConnection;
$this->database = $db->connect();
And you also need to change
public function addLike()
{
// use $this to access object property
return $this->database;
}
You are calling databaseConnection::connect() as a static method. Modify it to:
public static function connect(){ }
Edit - as #Shankar Damodaran pointed, also add:
public function addLike()
{
return $this->database;
}
First of all you should really follow convention and start naming classes StartingWithCapitalLetter.
Secondly, "::" operator is used to call static methods (to put it simply - you don't have to create object of a class to call them, if they are public).
Normally, to call object's method you use operator "->", like $object->method(arguments);
So in your case, you need to first create an object of your databaseConnection class (because you can't call methods on not-initialized methods) and then call "connect" on it, like that:
$connection = new databaseConnection();
$database = $connection->connect();
To pass a parameter, you need to modify the method declaration
public function connect($parameter){
return "Connecting to " ... $parameter;
}
and call it with
$database = $connection->connect($parameter);
On a sidenote, you should really use parenthesis when creating objects of a class, like:
$obj = new like();
echo $obj->addLike();
Also, as deceze pointed out, you need to access class variable using $this instead of accessing local method variable:
public function addLike()
{
return $this->database;
}
public function addLike()
{
return $this->database;
}
$database and $this->database are two different variables. $database is a local function variable which does not exist, it's not the object property you set before.

MySQLI in classes and in functions

My question is rather simple and after checking a few bits and bobs on here I feel its best to ask a new question.
Lets say I have 2 classes
class FirstClass {
function test() {
return "info";
}
}
class SecondClass {
function test() {
return "info";
}
}
Then I have my mysqli object
$mysqli = new mysqli(host, user, password, db);
What do i need to do to be able to use the mysqli object inside the functions inside the classes.
This is my 2 thoughts so far although I haven't placed it on a site for testing yet.
class FirstClass {
global $mysqli;
function test() {
$mysqli->query("some query");
return "info";
}
}
or
class FirstClass {
function test() {
global $mysqli;
$mysqli->query("some query");
return "info";
}
}
I am pretty sure I can setup a construct if need be but I just need to know which way is the best way/only way to share the mysqli object.
Thanks
EDIT:
So I have done a hell of a load of learning and now have a lot more experience with passing info in and out.
Here is a latest working example type that I use.
namespace Page;
use mysqli;
class edit extends details{
protected $db;
//this function is actually in the details class but there is no point in demoing 2 classes
function __construct(mysqli $con){
$this->db = $con;
}
}
To expand what Kneel told you in comments and to counter the other answer
class foo {
function __construct($mysqli){
$this->mysqli = $mysqli;
}
function test() {
return $this->mysqli->query("some query");
}
}
is what it have to be.
You should create a mysqli instance somewhere outside the class and then pass it in coustructor.
You could use __construct() to initialize your MYSQLi. You can then access it around your class with $this.
class FirstClass {
public function __construct(){
$this->mysqli = new mysqli("host", "user", "password", "db");
}
function test() {
$this->mysqli->query("some query");
return "info";
}
}
If you wanted to use it in your second class too, you could construct it in the same way or extend your first class.
class SecondClass extends FirstClass {
public function __construct(){
parent::__construct();
}
function test() {
return "info";
}
}

Classes using mysqli

I am building an API in PHP and I have a question. I'm using classes, and some of these classes need to access my database. However, I don't want to define variables for the database in every single class in order to open it, or have to send my mysqli object as a parameter of every single class constructor.
What would be the best way to go about this? Do I define a global variable of some kind?
A classic solution would be as follows
Create an instance of dbatabase handler class, either raw mysqli (worse) or better abstraction class (way better)
In the constructor of your application class take this db class instance as a parameter and assign it to a local variable
Use this variable with your class.
A quick example:
class Foo()
{
protected $db;
function __construct($db);
{
$this->db = $db;
}
function getBar($id)
{
return $this->db->getOne("SELECT * FROM bar WHERE id=?i", $id);
}
}
$db = new safeMysql();
$foo = new Foo($db);
$bar = $foo->getBar($_GET['id']);
How about using a static classes?
class mysqli_wrapper {
private static $db = null;
public static function open() {
GLOBAL $opts; // this can be global or setup in other ways
if (!self::$db) {
self::close();
self::$db = null;
}
self::$db = #mysqli_connect('p:'.$opts['hn'], $opts['un'], $opts['pw'], $opts['db']);
return self::$db;
}
public static function query($qry) {
return mysqli_query ( self::$db, $qry );
}
public static function affected_rows() { return #mysqli_affected_rows(self::$db); }
public static function error() { return #mysqli_error(self::$db); }
public static function close() { #mysqli_close(self::$db); }
} // end mysqli_wrapper
mysqli_wrapper::open(); // Here's how to call it
In a system I maintain my app needs to access its own MySQL db, as well as remote Oracle and SQL Server databases, and I use a trait for it. Here's a simplification of my code, just using MySQL:
dbaccess.php
trait DatabaseAccess {
protected $db;
private $host = 'host', $dbName = 'db', $username = 'username', $password = 'pword';
public function connectToMysql() {
$this->db= new mysqli(......);
}
}
then in myclass.php
require 'dbaccess.php';
class MyClass {
use DatabaseAccess;
//class code.....
}
All elements of DatabaseAccess will be available as if you hand-typed them in MyClass.
Note: if you're using PHP < 5.4, then this solution won't be possible.

Use of included class in another class

I'm trying to use a database class (ADOdb for PHP) but I don't know how to use it in another class.
Example:
<?php
include_once("adodb.inc.php");
$conn = NewADOConnection('mysql');
class Contacts {
public function getData(){
$conn->Connect(...);
//do something
}
}
?>
I think the problem is that I can not call $conn because its defined outside the class.
Notice: Undefined variable: conn
Fatal error: Call to a member function Connect() on a non-object
Maybe I'm doing it the wrong way, but I really don't know how to fix this.
Can somebody please help me out? Thanks a lot!
Why not simply do like this ?!
<?php
include_once("adodb.inc.php");
$conn = NewADOConnection('mysql');
$conn->Connect(...);
class Contacts {
protected $_connection;
public function __construct($conn)
{
$this->_connection = $conn;
}
public function getData(){
//do something
}
}
$contacts = new Contacts($conn);
$foobar = new FooBar($conn);
?>
It makes sense to establish connection outside the class, and then pass in already workable object. And of-course to share the same connection object among all the classes which require it.
P.S i would really reallly recommend to drop ADODB and start learning PDO.
You have a number of choices:
Use the global reserve word:
<?php
include_once("adodb.inc.php");
$conn = NewADOConnection('mysql');
class Contacts {
public function getData(){
global $conn;
$conn->Connect(...);
//do something
}
}
?>
Or pass $conn to your object on creation
$contacts = new Contacts($conn);
class Contacts {
protected $conn;
public function __construct($conn){
$this->conn = $conn;
}
public function getData(){
$this->conn->Connect(...);
//do something
}
}
?>
Or you could yous a Singleton data connection object. But that is considered a anti-pattern so I would inject your dependency as in option 2.
you need to reference the global variable:
<?php
include_once("adodb.inc.php");
$conn = NewADOConnection('mysql');
class Contacts {
public function getData(){
global $conn;
$conn->Connect(...);
//do something
}
}
?>
That said, you would probably be better off using dependency injection like this:
<?php
class Contacts {
private $db;
public function setDB($conn) {
$this->db = $conn;
}
public function getData(){
if (!$this->db) {
throw new Exception();
}
$conn = $this->db;
$conn->Connect(...);
//do something
}
}
?>
And then include your adodb include and instantiation in an initialization section.
Edit: Please see this article on Dependency Injection as getting into the habit of using this (and not globals) may save a lot of headaches down the road.
$conn is out of your variable scope. Use the following to make it work:
class Contacts {
public function getData(){
global $conn;
$conn->Connect(...);
//do something
}
}
Another way to do it is to have a reference to the variable inside your object:
class Contacts {
private $ref;
public function __construct($conn)
{
$this->ref = $conn;
}
public function getData(){
$ref->Connect(...);
//do something
}
}
$contacts = new Contacts($conn);

php mysqli class

My basic problem is I am having trouble accessing a class from within another class. Here is what I have set up so far:
My DB class:
class db {
public static $mysqli;
public function __construct(){}
static function con(){
if(!self::$mysqli){
self::$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
}
return self::$mysqli;
}
}
This works all fine and dandy when I just call it from a function like such:
function defineSettings(){
if ($query = db::con()->prepare(...my query...)) {
$query->execute();
$query->bind_result($1, $2, $3);
$query->fetch();
$query->close();
}
db::con()->close();
}
However, I am having trouble accessing this db->con() method from within another class' method. I have tried extending it to a new class, but maybe I am doing it wrong. An example of how to use this from a new class would be much appreciated! Thanks!
Not 100% sure if I understood your question, but the class below should show how you can get the db object from the Db class, and then use it in another function
class Example2 {
private $db;
public function test() {
if (!$this->db) {
$this->db = db::con();
}
//Do your stuff
}
public function test2() {
$this->db->close();
}
}

Categories