Use of included class in another class - php

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);

Related

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.

Passing mysqli to class for function use

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();

php global within a class but outside a function?

I can access $conn from within my function like so:
function xyz($a){
global $conn;
....
}
I am wondering if there is a way to do this within a class ex.
class abc
{
global $conn;
public function xyz($a)
{
$conn->execute...
}
public function xya($a)
{
$conn->execute...
}
}
The above method gives me an error. I know I can access it like so:
class abc
{
public function xyz($a)
{
global $conn;
$conn->execute...
}
public function xya($a)
{
global $conn;
$conn->execute...
}
}
I hope you can understand what I mean. Thanks in advance for the help.
Your second example is possible, your first isn't. There is no such thing as having a member variable of a class that is a global variable, or of using scope like you are in your first example.
Generally, however, I would recommend to avoid using the global keyword completely. I do a lot of PHP programming and have never used it in anything serious (indeed, anything at all in the last 10 or so years).
If you need to be able to access a variable throughout your class, I'd pass the variable in to your class constructor, like this:
class abc
{
private $conn;
function __construct($conn)
{
$this->conn = $conn;
}
public function xyz($a)
{
$this->conn->execute();
}
public function xya($a)
{
$this->conn->execute();
}
}
Then you'd have
$myabc = new abc($conn);
That way, you're being explicit about what variable is available to what functions. It also makes it easier/possible in future to give different values of $conn to different classes or even rename what $conn is, and yet you won't have to go through all your classes and change each reference to that variable.
With global variables, it is a lot harder to track which variable is available to which functions, or do it in a structured way. Also, there's more temptation to keep piling on more dependencies on global variables until you lose the benefit of having classes.
Assign it to a class variable.
$conn = 'something';
class abc
{
private $conn;
public function __construct($conn) {
$this->conn = $conn;
}
public function xyz($a)
{
$this->conn->execute...
}
public function xya($a)
{
$this->conn->execute...
}
}
Instead of assigning it in the constructor, you can also use a setter method such as:
public function setConn($conn) {
$this->conn = $conn;
}
or (though I do not recommend this) set the variable to public scope within the class which lets you change it at will:
class abc{
public $conn;
...
}
$abc = new abc;
$abc->conn = $conn;
You cannot have global as a modifier .
You can do what you want in one the following was :
$con;
class abc
{
private $conn;
public function __construct($conn) {
$this->conn = $con;
} .....
}
OR
class abc
{
static public $conn; ....
}
And for one of the object you instantiate it instead on instantiating for the global .
It's dirty (I do not like "global" at all) but it should work:
// ...
private $var;
public function foo() {
global $var;
$this->var = $var;
}
// ...
Yes, just change global to var or public,private,protected.
Example:
class myClass {
public $myClassVar = "Apples";
public __construct(){
echo( $this->myClassVar );
}
}
For more on visibility of these variables (public,private,protected), see this page on PHP.net.

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