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.
Related
Is there a way that i can access $connect in all functions on class?
class topicClass {
function viewTopic() {
function grabId() {
global $connection;
}
function grabTopic(){
global $connection;
}
function grabReplies(){
global $connection;
}
}
}
Instead of writing it over and over?
Define it as a property of your class, like so:
class topicClass {
private $connection;
public function __construct() {
$this->connection = "myConnectionString";
}
function viewTopic() {
// you can then refer to $this->connection here
}
...
}
When you do:
var cls = new topicClass();
the construct() will be called and will assign the value to connection, and you can then refer to it in the other functions.
NOTE: In the example I gave, I used private. You may need to change that to public, depending on where you need to access it.
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";
}
}
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.
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);
I have a global variable outside my class = $MyNumber;
How do I declare this as a property in myClass?
For every method in my class, this is what I do:
class myClass() {
private function foo() {
$privateNumber = $GLOBALS['MyNumber'];
}
}
I want this
class myClass() {
//What goes here?
var $classNumber = ???//the global $MyNumber;
private function foo() {
$privateNumber = $this->classNumber;
}
}
EDIT: I want to create a variable based on the global $MyNumber but
modified before using it in the methods
something like: var $classNumber = global $MyNumber + 100;
You probably don't really want to be doing this, as it's going to be a nightmare to debug, but it seems to be possible. The key is the part where you assign by reference in the constructor.
$GLOBALS = array(
'MyNumber' => 1
);
class Foo {
protected $glob;
public function __construct() {
global $GLOBALS;
$this->glob =& $GLOBALS;
}
public function getGlob() {
return $this->glob['MyNumber'];
}
}
$f = new Foo;
echo $f->getGlob() . "\n";
$GLOBALS['MyNumber'] = 2;
echo $f->getGlob() . "\n";
The output will be
1
2
which indicates that it's being assigned by reference, not value.
As I said, it will be a nightmare to debug, so you really shouldn't do this. Have a read through the wikipedia article on encapsulation; basically, your object should ideally manage its own data and the methods in which that data is modified; even public properties are generally, IMHO, a bad idea.
Try to avoid globals, instead you can use something like this
class myClass() {
private $myNumber;
public function setNumber($number) {
$this->myNumber = $number;
}
}
Now you can call
$class = new myClass();
$class->setNumber('1234');
Simply use the global keyword.
e.g.:
class myClass() {
private function foo() {
global $MyNumber;
...
$MyNumber will then become accessible (and indeed modifyable) within that method.
However, the use of globals is often frowned upon (they can give off a bad code smell), so you might want to consider using a singleton class to store anything of this nature. (Then again, without knowing more about what you're trying to achieve this might be a very bad idea - a define could well be more useful.)
What I've experienced is that you can't assign your global variable to a class variable directly.
class myClass() {
public $var = $GLOBALS['variable'];
public function func() {
var_dump($this->var);
}
}
With the code right above, you get an error saying "Parse error: syntax error, unexpected '$GLOBALS'"
But if we do something like this,
class myClass() {
public $var = array();
public function __construct() {
$this->var = $GLOBALS['variable'];
}
public function func() {
var_dump($this->var);
}
}
Our code will work fine.
Where we assign a global variable to a class variable must be inside a function. And I've used constructor function for this.
So, you can access your global variable inside the every function of a class just using $this->var;
What about using constructor?
class myClass {
$myNumber = NULL;
public function __construct() {
global myNumber;
$this->myNumber = &myNumber;
}
public function foo() {
echo $this->myNumber;
}
}
Or much better this way (passing the global variable as parameter when inicializin the object - read only)
class myClass {
$myNumber = NULL;
public function __construct($myNumber) {
$this->myNumber = $myNumber;
}
public function foo() {
echo $this->myNumber;
}
}
$instance = new myClass($myNumber);
If you want to access a property from inside a class you should:
private $classNumber = 8;
I found that globals can be used as follows:
Create new class:
class globalObj{
public function glob(){
global $MyNumber;
return $this;
}
}
So, now the global is an object and can be used in the same way:
$this->glob();
class myClass
{
protected $foo;
public function __construct(&$var)
{
$this->foo = &$var;
}
public function foo()
{
return ++$this->foo;
}
}