OOP duplicate extends - php

I have two classes which both extend from SQL class
like this:
class SQL {
private $db_connect_id;
function connect($ad, $db, $us, $pa){
$this->db_connect_id = mssql_connect($ad, $us, $pa);
mssql_select_db ($db, $this->db_connect_id) or die('sql error');
}
function sql_query($query = ""){
unset($this->query_result);
if($query != ""){
$this->num_queries++;
$this->query_result = #mssql_query($query, $this->db_connect_id) or die('error query');
}
if($this->query_result){
unset($this->row[$this->query_result]);
unset($this->rowset[$this->query_result]);
return $this->query_result;
}
}
}
class WEB extends SQL {
function __construct(){ $this->connect(params) }
function __destruct(){ $this->disconnect() }
}
class AUTH extends SQL {
function __construct(){ $this->connect(params) }
function __destruct(){ $this->disconnect() }
}
the problem is that if I call both of them
$WEB = new WEB();
$AUTH = new AUTH();
the $WEB won't work anymore. It loses its connection with the database and it changes the db_connect_id with the db_connect_id from AUTH...
I think this is a stupid question and I'm too tired, but I have to finish.
Where I'm doing wrong?
Thank you

http://php.net/manual/en/function.mssql-connect.php
There is fourth param new_link that must be passed as true (because default is false).

It's impossible to tell from the limited code you've posted, but I think it's pretty clear that you have some singleton-like behavior going on i.e., all instances of SQL and its subclasses are sharing references.
Maybe if you replaced bla bla with the actual code we could narrow it down for you.

There is nothing wrong with the code as presented in your question.
The problem you are describing is symptomatic of using a static property of the SQL class, possibly to hold a database connection resource.
A static property is shared between all instances of a class, which is the behaviour you appear to be describing.
This type of design will work the way you want:
class SQL {
private $database;
function connect() {
$this->datavbase = ....;
};
}
class WEB extends SQL {
function __construct(){ $this->connect(params) }
function __destruct(){ $this->disconnect() }
}
class AUTH extends SQL{
function __construct(){ $this->connect(params) }
function __destruct(){ $this->disconnect() }
}
This type of design will not work the way you want:
class SQL {
private static $database;
function connect() {
$this->datavbase = ....;
};
}
class WEB extends SQL {
function __construct(){ $this->connect(params) }
function __destruct(){ $this->disconnect() }
}
class AUTH extends SQL{
function __construct(){ $this->connect(params) }
function __destruct(){ $this->disconnect() }
}

Related

PHP - Good design pattern for static database connection class

I have a "static" class which connects to database and has various functions. The current base layout is as follows:
class DB {
private static $con;
private function __construct() {};
private static function init() {
if(is_null(self::$con) {
// Initialize database connection
}
}
public static someMethod1() {
self::init();
// Do stuff
}
public static someMethod2() {
self::init();
// Do stuff
}
public static someMethod2() {
self::init();
// Do stuff
}
}
My intention is to be easily be able to call these methods as: DB::someMethod1(). However, as you can see, I am having to cehck for initialization at every method beginning. Is this a good coding practice? Is there a better design pattern available? Initially I thought of builder pattern but that doesn't really fit here in my opinion.
It looks like you are trying to ensure that there is a single instance of your DB class AND also that the instance is available as a single, globally available constant.
I'd recommend separating those two concerns in order to simplify the implementation.
First, I'd focus on getting the database access object right. Plain objects are simpler to test and inject as dependencies than static functions. For example,
class DBThing
{
private $con;
public static function build()
{
return new static('theconnection');
}
function __construct($con)
{
$this->con = $con;
}
public function someMethod1()
{
echo "someMethod1: $this->con\n";
}
public function someMethod2()
{
echo "someMethod2: $this->con\n";
}
public function someMethod3()
{
echo "someMethod3: $this->con\n";
}
}
Gives you an object you can easily test and replace with alternate implementations if needed.
Second, I'd focus on the object lifecycle and making it discoverable in the application.
If you're really OK with a single instance and the global state that implies, then something like this gets you close to the interface you asked for in your original post.
$DB = DBThing::build();
$DB->someMethod1();
$DB->someMethod2();
$DB->someMethod3();
In general, I discourage global state but I'd have to know more about your application to know if it's appropriate in your case.
I just wrote a simple db class for a coding test. Take a look at how I used here: https://github.com/TheRealJAG/Valuation-Vision-Full-Stack-Test/blob/master/classes/db.php
class DB
{
private static $instance = null;
private $db;
private $host = '';
private $username = '';
private $password = '';
private $database = '';
private function __construct()
{
$this->db = new mysqli($this->host, $this->username, $this->password, $this->database);
if ($this->db->connect_error) {
throw new Exception("Connection to the mysql database failed: " . $this->db->connect_error);
}
}
public static function connection()
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance->db;
}
}
I'm 100% sold on the approach, but with the time I had for the test this is what I wrote. My biggest concern was that I only had 1 db connection open.

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";
}
}

What is the use of constructor in abstract class in php

I followed this link already before asking - Answer is in JAVA context and this for constructor in PHP .
Since I am starter, my implementation of my PHP code in OOP concepts, so I am really willing to know about the usage and benefits or when to use constructor in PHP abstract class.
Please provide an example in real world context to grab the concept better.
PS - Although I am following PHP Manuals to understand OOP concepts but I am finding it little bit hard to understand, any help with the links/blog to follow is really appreciable.
My Code -
<?php
abstract class grandClass
{
abstract function grandmethod();
function __construct()
{
echo "I am grandClass constructor";
}
}
abstract class parentClass extends grandClass
{
abstract function raiseFlag();
function grandmethod()
{
echo "This is grandmethod!!!","<br />";
}
public function getValue()
{
echo "Zero is the blackhole for the numbers!!","<br />";
}
}
class childClass extends parentClass
{
function raiseFlag()
{
echo "Peaceful thoughts!!","<br />";
}
}
$myobj = new childClass();
$myobj->raiseFlag();
$myobj->getValue();
$myobj->grandmethod();
Constructor in abstract class is the same as in concrete class. Use constructors when they are needed, for example, if you need to intialize some data or assign some resources.
I'll give you an example:
abstract class Db
{
protected $pdo;
public function __construct($pdo)
{
$this->pdo = $pdo;
}
abstract function select($table, $fields);
}
class Db_Mysql extends Db
{
public function select($table, $fields)
{
// Build MySQL specific select query
// then execute it with $this->pdo
}
}
class Db_Pgsql extends Db
{
public function select($table, $fields)
{
// Build PostgreSQL specific select query
// then execute it with $this->pdo
}
}
// Usage:
$db = new Db_Mysql($pdo);
$db->select('users', array('id', 'name'));

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

OO PHP where to reference singleton class?

I am going to use singleton classes to manage both DB connections and references to application settings.
It seems a little messy to have to use the following code in every method in order to access the db class.
$db = DB::getInstance();
Is there a more efficient way of going about it?
Any advice appreciated.
Thanks
I often use the Registry pattern, where this behavior occurs as well. I always set a instance variable in the constructor of my models to point to the Registry entry;
class Registry {
private static $_instance;
private $_registry;
private function __construct() {
$_registry = array();
}
public static function getInstance() {
if (!Registry::$_instance) {
Registry::$_instance = new Registry();
}
return Registry::$_instance;
}
public function add($key, &$entry) {
$this->_registry[$key] = &$entry;
}
public function &get($key) {
return $this->_registry[$key];
}
public function has($key) {
return ($this->get($key) !== null);
}
}
Model example;
class MyModel {
private $_db;
public function __construct() {
$this->_db = Registry::getInstance()->get('dbKey');
}
/* Every function has now access to the DAL */
}
Instantiation example;
$dal = new Db(...);
Registry::getInstance()->add('dbKey', $dal);
...
$model = new MyModel();
$model->doDbStuff();
Another approach is to always pass the reference as a parameter to each constructor.
Of course I only use this behavior when most of the methods in my model use the reference, if only a few (one or two) methods have use of the reference, I call the Registry/Singleton like you showed.
It is not messy. This is an intended behavior of Singletons. And, actually, this is just one line of code. Do you wish to make it even more compact? :)
My preferred method is to create a Base class which all the classes that need db access descend from. Base calls the singleton(s) in its constructor. All its children call their parent constructor. e.g.:
class Base {
protected $db;
public function __construct(){
$this->db = DB::getInstance();
}
}
class Achild extends Base {
protected $var1;
public function __construct($arg){
parent::__construct();
$this->var1=$arg;
}
}
I know what you mean... hate that ::getInstance() stuff! So go and use static methods:
class DB {
private static $db;
public static function getInstance() {
if(!self::$db) {
self::$db = new DBconnector();
}
}
public static function query($query) {
return self::$db->query($query);
}
}
Usage is much nicer:
$result = DB::query('SELECT whatever;');
And if you use PHP 5.3 you can write a __callStatic similar to this, to forward all the method calls to the object:
public static function __callStatic($method, $args) {
call_user_func_array(array(self::$db, $method), $args);
}
And to make me happy, add an __autoloader so that you can access DB without any worries any time!

Categories