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.
Related
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 have an issue accessing top level variables from sub-level class.
Here's an example...
Application.php:
class Application {
var $config;
var $db;
function __construct() {
include_once('Configuration.php');
include_once('Database.php');
$this->config = new Configuration;
$this->db = new Database;
}
}
Configuration.php:
class Configuration {
var $dbhost = 'localhost';
}
Database.php:
class Database {
function __construct() {
echo parent::config->dbhost;
}
}
It is clear to me that usage of parent is wrong here as the subclass does not extend the parent class, but how do I access it?
Thank you.
You should create a Base class that in its construct creates a $db link. Then let all classes that require database access extend that class. Your nomenclature here with "parent class" is incorrect.
class Base {
private $db; // Make it read-only
function __construct() {
$this->db = DB::connect(); // It's a good practice making this method static
}
function __get($property) {
return $this->$property;
}
}
class Application {
public $config;
function __construct() {
parent::__construct();
require_once 'Configuration.php';
require_once 'Database.php';
$this->config = new Configuration();
}
function random_function() {
$this->db(....) // Has full access to the $db link
}
}
The parent notation is used to access the parent of the object in the object hierarchy. What you are doing here is trying to get at the caller, not the parent
The way that you would do this is to pass in an instance of your configuration to the database object.
class Database {
protected $config;
public function __construct(Configuration $config){
$this->config = $config;
}
public function connect(){
//use properties like $this->config->username to establish your connection.
}
}
The parent notation is used when you extend a class and make a child class to call methods on the parent .
class MySuperCoolDatabase extends Database {
protected $is_awesome;
public function __construct(Configuration $config){
// do all the normal database config stuff
parent::__construct($config);
// make it awesome
$this->is_awesome = true;
}
}
This defines a child class, which is a type definition that serves the same role as the base class with a slightly different implementation. Instances of this can still be said to be a Database.... just a different kinds of database.
Well, although I think that Orangepills answer is better. If you dont want to use it and since all variables are public, you could simply pass the variable like this:
class Application {
var $config;
var $db;
function __construct() {
include_once('Configuration.php');
include_once('Database.php');
$this->config = new Configuration;
$this->db = new Database($this->config->dbhost);
}
}
class Configuration {
var $dbhost = 'localhost';
}
class Database {
function __construct($dbhost) {
echo $dbhost;
}
}
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.
Is there any other way instead of using global everytime I need to access a global variable inside a function?
$db = new ezSQL_mysql("root", "", "payroll", "localhost");
class employee{
function get_emp(){
global $db;
}
}
In normal global-scope functions, either use the global keyword, or $GLOBALS['db'] superglobal array (which is preferable for readability). The other alternative is to pass the global variable into the function as a parameter.
In your class, the best method is dependency injection. Your class constructor receives the $db as a parameter, which makes it available to all class methods:
// $db was created at global scope
$db = new ezSQL_mysql("root", "", "payroll", "localhost");
class employee {
public $db;
// $db already created in your script is passed as a dependency
// to the class constructor
public function __construct($db) {
$this->db = $db;
}
// Access it as $this->db inside the class
public function get_emp() {
do_something($this->db);
}
}