stuck on this. Lets start with code.
Settings.php
class settings{
public $db_host;
public $db_username;
public $db_password;
public $db_database;
public function db_settings(){
/*$db_host = "localhost";
$db_username = "root";
$db_password = "";
$db_database = "eveonline";*/
$this->db_host = "localhost";
$this->db_username = "root";
$this->db_password = "";
$this->db_database = "eveonline";
}
This is where I want to use this
class xmlUpdate{
include_once ('./lib/settings.php'); //This wont work
public $itemCount;
public function dbItemCount(){
include_once ('./lib/settings.php');// This will work, but only in this function
In this case its for database varables, so I dont have to duplicate code whenever I want to make a database connection.
How can I use the database varables in another class, the whole class, not just the function where it allows me to include?
I would put the include into the __construct() function of your class, instantiate a new Class, read out the variables put them in local variables in your class.
class xmlUpdate{
public $db_host;
public $db_username;
public $db_password;
public $db_database;
function __construct(){
include_once('./lib/settings.php');
$settings = new settings();
$this->db_host = settings->db_host;
$this->db_username= settings->db_username;
$this->db_password= settings->db_password;
$this->db_database= settings->db_database;
}
}
Or you could make you xmlUpdate class extend the settings class.
This might be a possible approach, the Database class could also have connect and disconnect, query etc. function. Write a __autoload function so you don't have to include any files. Another simple approach would be to define all the data in the index.php -> define('DB_HOST', 'localhost'); and later access it via DB_HOST.
class DataBase {
private static $instance = null;
public $db_host;
public $db_username;
public $db_password;
public $db_database;
private function __construct() {
$this->db_host = "localhost";
$this->db_username = "root";
$this->db_password = "";
$this->db_database = "eveonline";
}
private function __clone() {
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new DataBase;
}
return self::$instance;
}
}
class Xml {
protected $db;
public function __construct() {
$this->db = DataBase::getInstance();
}
public function getUsername() {
return $this->db->db_username;
}
}
// test
$xml = new Xml;
print $xml->getUsername() . "\n";
you could make them static or follow a singleton pattern
I think that what you're trying to do is have some GLOBAL type of thing you can access from anywhere.
As the user busypeoples suggests, you could try using the singlton pattern if you want to include some complicated behavior for the database like connections. Look up the singleton pattern and you should definitely be able to find some PHP specific examples.
If all you want to do is share some simple connection string, password and user for the database then you can use the define statement.
//the db_info.php file
define( 'DB_NAME', 'mydevdatabase' );
define( 'DB_IP', '127.0.0.1' );
define( 'DB_USER', 'bob' );
define( 'DB_PASSWORD', 'password' );
Afterward, you can just include this file at the beginning of any PHP file and use the constants.
//some other php file
require_once( 'db_info.php' );
class Test
{
public function tester()
{
$some = DB_IP;
$other = DB_USER;
//your other code
}
public function otherfunction()
{
$some = DB_IP;
$other = DB_USER;
//your code
}
}
Related
I've recently encountered an error in my code:
PHP Parse error: syntax error, unexpected '$connection' (T_VARIABLE), expecting function (T_FUNCTION) in
From what I've googled the issue is not setting public/private/protected before, or not creating the database connection in the construct function.
The database connection class code:
class databaseConnection {
//Database information
protected $mysqliUser = "";
protected $mysqliHost = "localhost";
protected $mysqlipass = "";
protected $mysqlidbname = "";
public $con;
public function __construct() {
$this->con = new mysqli($this->mysqliHost,$this->mysqliUser,$this-
>mysqlipass,$this->mysqlidbname);
}
}
A snippet of the class code that is receiving the error:
private $conn;
$conn = new databaseConnection;
Any help to point me in the right direction is much appreciated.
above the private declaration is just the class creation class
createSession
In which case your $conn = new databaseConnection; either needs visibility, or should be in a method. Hard to tell which without seeing all the class and the odd indentation you have.
So put that in the method it belongs in (perhaps the constructor?) or set it to private, protected, or public - whichever it was intended for.
Check this out.
It really works..
connect.php
class DBConnect {
private static $connection;
private static $host = "localhost";
private static $user = "root";
private static $pwd = "";
private static $dbname = "yourDBName";
public static function connect() {
$host = self::$host;
$user = self::$user;
$pwd = self::$pwd;
$dbname = self::$dbname;
self::$connection = new mysqli($host, $user, $pwd, $dbname) or die('Error connecting..');
return self::$connection;
}
}
myclass.php
require_once('connect.php');
class MyClass {
private $connObj;
public function __construct() {
$this->connObj = DBConnect::connect();
}
public function select() {
$conn = $this->connObj;
$sql = "SELECT * FROM table_name";
$query = $conn->query($sql);
$res = $query->fetch_assoc();
// your code..
}
}
$obj = new MyClass();
$obj->select();
Hope, this code snippet works fine for you. :) :)
Config.php
class Config {
public static $dbserver = "hostedserverURL";
}
DB.php
require 'Config.php'
class DB {
private $server = Config::$dbserver; // compile-error
private $user = "user";
private $password = "password";
private $database = "databasename";
private $db;
}
compile-error says "syntax error, unexpected '$dbserver', expecting 'identifier' or 'class'"
If I remove the $ and change the line to private $server = Config::dbserver; , the compile-error is gone. but this is not correct.
I get a Runtime error in that case.
Fatal error: Undefined class constant 'Config::dbserver' in ..
So I have to retain the $ , Also as per this SO thread: Fatal error: Undefined class constant
This is where I am making use of it,
public function __construct()
{
$this->db = new PDO(
"mysql:host={$this->server};dbname={$this->database};charset=utf8",
$this->user,
$this->password
);
return $this;
}
Question: How can I refer the static variable dbserver and make that as default value for $server of class DB ? Any ideas please
You can not assign variables in classes from functions and other classes or non-trivial expressions until 5.6. You will have to set the variable using a function within the class.
For now type in php -v into your terminal to see what version you are using. Otherwise if you want to use that functionality, upgrade PHP to PHP 5.6
https://wiki.php.net/rfc/const_scalar_exprs
This is a php (version < 5.6) limitation, however you can simply initialize the properties in the constructor:
class DB
{
private $server;
private $user;
private $password;
private $database;
private $db;
public function __construct()
{
$this->server = Config::$dbserver; // No compile-error
$this->user = "user";
$this->password = "password";
$this->database = "databasename";
$this->db = new PDO(
"mysql:host={$this->server};dbname={$this->database};charset=utf8",
$this->user,
$this->password
);
//return $this; no need for this
}
}
Or upgrade to a later (5.6+) version of php.
Also, from a design perspective, having the various variables hard-coded and scattered over 2 files is needlesy complicated. Ideally have them all injected in the constructor:
public function__construct($server, $user, $password, $database)
{
$this->server = $server;
$this->user = $user;
//etc
}
failing that have them all declared in the config class:
public function__construct()
{
$this->server = Config::$server;
$this->user = Config::$user;
//etc
}
You can't use variables from outside the class, even if you require them in the same file.
You could do this:
class DB {
private $server;
private $user = "user";
private $password = "password";
private $database = "databasename";
private $db;
public function __construct(){
require 'Config.php';
$this->server = Config::$dbserver; //Will set the $server variable of the instantiated class.
}
}
I have the following, however I'm unable to access the database functions outside of the initial db class?
Thanks!
database.php
class db
{
private $connection;
public function __construct()
{
$this->connection = new PDO();
}
}
admin.php
class admin
{
private $connection
public function __construct(db $connection)
{
$this->connection = $connection;
}
function myFunc()
{
// How do I access the connection here?
}
}
main.php
//include db.php
//include admin.php
$connection = new db();
$admin = new admin($connection);
// How do I access the DB here?
First of all, why are you encapsulating PDO just to class containing that one object? Cannot you use PDO directly?
One of the common practices would be to implement getter in db class, like:
class db {
...
public function getPDO(){
return $this->connection;
}
}
Another way is to re-implement every function (why would you do that?!), or use __call magic function...
Or just make $connection public ;)
Or you could extend PDO class (I'm not sure whether it'll work):
class DB extends PDO {
public function __construct ( $dsn, $username = null, $password = null, $driver_options = array()){
parent::__construct( $dsn, $username, $password, $driver_options);
... more of your stuff
}
public function myFunc(){
$this->...
}
}
ok, you really need to go and read up on object-oriented design, and access modifiers. I'll explain what you need to do here, but this is a band-aid solution, and you need to deeply understand how things are working here.
In your admin class, you defined the connection as a private attribute of the class. So in the myFunc function, you simply do $this->connection to access the connection that you created in the constructor.
In your main.php file, the object you are getting rom initializing a DB object is not the connection. It is the db object as a whole, so you can not pass the connection by itself to the admin class (it is defined as private, so nobody outside the class can view it). However, why do you need to pass it to the admin class? Managing the DB connection should be the responsibility of the DB class.
In other words, what are you trying to achieve by exposing the DB connection to the admin class?
Upate: based on the reply here is a suggested answer:
class Database {
private $connection;
public function __construct() {
$this->connection = new PDO();
}
}
class Admin {
private $db;
public function __construct() {
$this->db = new Database();
}
public function myFunc() {
$this->db->query('...');
}
}
In your main.php file:
$admin = new Admin();
$admin->myFunc();
Keep in mind, every admin object is going to create a new connection to the DB, so if you create many admin objects you might face some issues. You can get around this by declaring the DB to be a singleton.
How about this:Updated
<pre>
<?php
class DB {
private $host;
private $user;
private $pass;
private $dbase;
private $connection;
public function __construct($host,$user,$pass,$dbase)
{
$this->host = $host;
$this->user = $user;
$this->pass = $pass;
$this->dbase = $dbase;
$this->connection = new PDO("mysql:host=$this->host;dbname=$this->dbase", $this->user, $this->pass);
}
public function connect()
{
return $this->connection;
}
public function close()
{
unset($this->connection);
return true;
}
}
$dbh = new DB('localhost','root','','inventory');
$result = $dbh->connect()->query("SELECT * FROM products")->fetchAll(PDO::FETCH_ASSOC);
print_r($result);
?>
</pre>
Updated with files separation
database.php
class db
{
private $connection;
public function __construct()
{
$this->connection = new PDO();
}
}
admin.php
class admin
{
private $connection
public function __construct(db $connection)
{
$this->connection = $connection;
}
function myFunc()
{
return $this->connection->prepare('SQL');
}
function getConnection()
{
return $this->connection;
}
}
main.php
require_once 'database.php';
require_once 'admin.php';
$connection = new db();
$admin = new admin($connection);
$admin->myFunc()->execute();
Not sure of OOP syntax to do this...
I'd like to have aclass that calls the mysqli object
class Voovid_DB {
private $host = 'localhost';
private $user = 'blahblah';
private $password = 'blahblah';
private $name = 'blahblah';
public function __contstuct(){
$dbh= new mysqli( $this->host, $this->user, $this->password, $this->name );
return $dbh;
}
//get and set methods for host, user etc... go here
}
now I'd like to access all the mysqli methods like so
$dbconnect = new Voovid_DB();
if ( $result = $dbconnect->query( "SELECT first_name, last_name FROM members WHERE member_id=9" ) ) {
while ( $row = $result->fetch_assoc() ) {
$first_name = ucfirst( $row['first_name'] );
$last_name = ucfirst( $row['last_name'] );
}
} else {
$errors = $dbconnect->error;
}
i'm new to PHP OOP and not sure how to get to the mysqli methods inside the Voovid_DB class
You have to either extend the MySQLi class, or build a proxy around it.
The easiest is probably to extend it:
class Voovid_DB extends MySQLi {
private $host = 'localhost';
private $user = 'blahblah';
private $password = 'blahblah';
private $name = 'blahblah';
public function __construct(){
// call parent (MySQLi) constructor
parent::__construct( $this->host, $this->user, $this->password, $this->name );
}
// no need for other methods, they already are there
}
Notice the extends MySQLi.
Then your second code snipet should work.
Or, build a proxy:
class Voovid_DB {
private $host = 'localhost';
private $user = 'blahblah';
private $password = 'blahblah';
private $name = 'blahblah';
private $dbh;
public function __construct(){
$this->dbh = new MySQLi($this->host, $this->user, $this->password, $this->name);
}
// this will proxy any calls to this class to MySQLi
public function __call($name, $args) {
return call_user_func_array(array($this->dbh,$name), $args);
}
}
You could define a __call method:
public function __call($method, $arguments) {
return call_user_func_array(array($this->dbh, $method), $arguments);
}
__call is invoked if an undefined or inivisible method is called.
you code is correct.
the only thing you have to do is to make sure that you define your functions in Voovid_DB as public.
private or protected methods cannot be accessed from other classes
store your mysqli object in a public field in your class then you can access it like this:
$dbconnect->mysqlField->query
Constructors aren't supposed to return anything. When you say $dbconnect = new Voovid_DB(); you would normally be trying to create a Voovid_DB object, but it looks like you're using it to try an make a mysqli object. Don't make this the constructor and call the function after you create the voovid_db object.
$obj = new voovid_DB();
$dbConnect = $obj->createMysqli();
When building dynamic websites I use a php include to make my connections to the database. The included file is very basic:
mysql_connect($hostname = 'host', $username = 'user', $password = 'password');
mysql_select_db('database');
This works fine.
In some places I use an AJAX system to create drag-and-drop reordering of database records which updates the database at the same time, it is adapted from something I found on the internet. This uses its own connection code:
class SortableExample {
protected $conn;
protected $user = 'user';
protected $pass = 'password';
protected $dbname = 'database';
protected $host = 'host';
public function __construct() {
$this->conn = mysql_connect($this->host, $this->user, $this->pass);
mysql_select_db($this->dbname,$this->conn);
}
This also woks fine.
What it means, however, is that I have to add the username, password, host and database to two separate files. Sometimes the second one is forgotten and causes the website to fail.
My question is, how can I either combine both connection files into one, OR how can I get the second block of code to accept external variables so that I only have to enter the actual values in one place?
Your last question is easy.
db.config.php
$host = '';
$user = '';
$pass = '';
$db = '';
db.plain.php
include 'db.config.php';
$conn = mysql_connect($host, $user, $pass);
mysql_select_db($db,$conn);
db.class.php
include 'db.config.php';
class SortableExample
{
protected $conn;
public function __construct()
{
global $host, $user, $pass, $db;
$this->conn = mysql_connect($host, $user, $pass);
mysql_select_db($db,$this->conn);
}
}
You can simply put the database connection code in another file and included that everywhere you need it.
Create a single entry point for your database connection.
Use a Singleton with lazy instantiation for that:
class ConnectionProvider {
protected $conn;
protected $user = 'user';
protected $pass = 'password';
protected $dbname = 'database';
protected $host = 'host';
private static $__instance;
private function __construct() {
$this->conn = mysql_connect($this->host, $this->user, $this->pass);
mysql_select_db($this->dbname,$this->conn);
}
public static function getInstance() {
if ( self::$__instance == null) {
self::$__instance = new ConnectionProvider();
}
return self::$__instance;
}
public function getConnection() {
return $this->conn;
}
}
And then, from your code
ConnectionProvider::getInstance()->getConnection();
to use the connection wherever you need it.
SortableExample would thus become:
class SortableExample {
protected $conn;
public function __construct() {
$this->conn = ConnectionProvider::getInstance()->getConnection();
}
...
}