OOP question:Late static binding and generic classes

well,
i have seen design in lot of apps now a days.
class users
{

fun… save
{

}

fun …del
{

}
}

class post
{

fun… save
{

}

fun …del
{

}
}

i also do think if we have another class that handle for all the cases (add,delete) making it generic
and we just inherit from that class would be good but it is said that it would not work as expected before php 5.3 which doesnt support late static binding.
i have seen some tweak function/classes to make it work below 5.3,but feel that they are never safe esp during upgrades and team development.

I have been also following multiple functions in different classes for same operations(add,del in class 1…add,del in class2)

But i feel now,i should upgrade

so what are you guys doing?

what kind of approach do u use or suggest?

thanks

I think you are referring to what is generally called CRUD, searching that term should find you plenty of discussion on what ppl do.

Personally, I developed some basic CRUD for myself about a year ago, nothing very clever really, but sufficient to do 1 object to 1 table CRUD on the backend of my CMS. It builds on PDO, and picks up the table schema from an ini file.

Its all very crude, but works fine for my purposes.

There is an occasional issue with joins, but I sidestep that by simply allowing a passThru( $sql ) function.

I took a different tack on the website though.

After analysing the public side of things I found I save very little, but do an immense amount of database reading, plus far more complex joins are common on main site often to simply reduce the amount of db calls.

For thar reason I created a readonly class which is in effect a very simple “sql query builder” which I extend for each application (set of pages, if you prefer).

The readonly sql builder responds to something like this ( this is a really simple example )



include_once 'genericquery.class.php' ;
include_once 'news.readonly.model.php' ;

        $news_model = new newsreadonly( $PDO ) ;

            $news_fields = array(
             'slug'
            ,'title'
            ,'intro'
            );

        $news_model->setFields( $news_fields );

 // current() is specific to newsreadonly
 // and permits me to easily allow results paging

        $news = $news_model->current( 0, 10 ); 

        echo '<ul>' ; 
        if (count($news) ==0 ) echo '<li>No news to show.</li>' . PHP_EOL ;

            foreach( $news as $item ){
            echo '<li><a href="/news/' . $item['slug'] . '" title="' 
                 . $item['intro'] . '">' . $item['title'] . '</a></li>' . PHP_EOL ;
        
            }
        echo '</ul>' ; 

If I was doing it again though, I think I’d be tempted to use an ORM.

ok,sorry as i was not able to make it clear.

what i mean is ok CRUD but not crud only

class generic
{
function save//save that takes table name,field array and work for any object

}
function delete…

}//end of class

now

class users extends generic
{
function others

}

now later if we do
$user=new users();
$user->save();//wont work in below php 5.3
we need same save function in users class as well

THIS IS WHAT I MEAN.

now what i am thinking is forget about php below 5.3 and programming using this style and i need some suggestion
thanks

now later if we do
$user=new users();
$user->save();//wont work in below php 5.3
we need same save function in users class as well

is it true?
if user class is extending from class which have save() method then i think it works too in below PHP5.3.

comment if i misunderstood your problem Mr. Frank1

From where you came to know that an object of a class that extends another base class cannot access the method of base class? AFAIK, that is what the main logic of inheritance feature of OOP in PHP (if i am not wrong even in other languages too). It can access all the public and protected methods/functions of base class but not private.

Just try the following code in less than 5.3 version of PHP.


class Generic{
	public function save(){
		return 'Saved!';
	}
	
	public function delete(){
		return 'Deleted!';
	}
}

class Users extends Generic{
	public function cancel(){
		return 'Cancelled!';
	}
}

$objUser = new Users;
echo $objUser->save() . '<br />';
echo $objUser->delete() . '<br />';
echo $objUser->cancel();

Edit:
BTW, I have tested above code in my ‘PHP Version 5.2.9-2’.

Things to be noted while inherting:


class Generic{
	function __construct(){
		//initialisation of db object
	}
    public function save(){
    	//operation based on db object
        return 'Saved!';
    }
   
    public function delete(){
    	//operation based on db object
        return 'Deleted!';
    }
}

$objUser = new Users;
//Consider the test for following users class
echo $objUser->save() . '<br />';
echo $objUser->delete() . '<br />';


//doesn't work, guess why?
class Users extends Generic{
	function __construct(){
		
	}
	public function Cancel(){
		return 'Cancelled!';
	}
}

//works, guess why?
class Users extends Generic{
	function __construct(){
		parent::__construct();
	}
	public function cancel(){
		return 'Cancelled!';
	}
}

//works too, guess why?
class Users extends Generic{	
	public function cancel(){
		return 'Cancelled!';
	}
}

Let it be which you said works fine, but the following is the same what you said does not work, try it yourself:


class Generic{
    public function save(){
        return 'Saved!';
    }
    
    public function delete(){
        return 'Deleted!';
    }
}
 
class Users extends Generic{ 
	function __construct(){ 
		
	} 
	public function cancel(){ 
		return 'Cancelled!'; 
	} 
}
 
$objUser = new Users;
echo $objUser->save() . '<br />';
echo $objUser->delete() . '<br />';
echo $objUser->cancel();

I don’t know why this works at my end :slight_smile:

Edit:
You were messed up or you typed wrong, the second method does not work because it tries to call not defined constructor of base class. But if you define the constructor in base class then it works just fine as well. And the third one also works because it does not call the constructor of base class. Do you mean like that?

ok sorry again for not being able to make it more clear
sorry actually my examples were rough skeleton and trying to make it simple i made mistake there,yes indeed referring that way it should work.

I was actually trying to refer it ,in case of static functions and variables with the use of self
may be this tutorial shows what i meant
http://www.lornajane.net/posts/2009/PHP-5.3-Feature-Late-Static-Binding
OR
http://stackoverflow.com/questions/87192/when-would-you-need-to-use-late-static-binding

It shows the problem with out late static binding and late static binding came only after 5.3 only

i have a very good video which summarizes the problem but cannot upload it as it is a copyrighted material.

any way thanks,i did found lots of resources in other sites as well about this and bit clear about it now.

In php 5.3, this works.
BUT, it’s tricky, sometimes you get notices/warning for this:


$class = 'MyClass';
$class::$property = 5; # <<< in Zend Studio I get an error here, but it works.

This can be solved with:


$class = 'MyClass';
new $class::$property = 5;

But it’s kind of stupid … (static variable…)

In PHP<5.3, you need to use something like:


$foo = new foo;
call_user_func_array(array($foo, "bar"), array("three", "four"));

I use this in a similar project as yours.
1 main class with all the functionality witch is extended by all my models.
Each model contains a static array with the model’s db mapping / relationships.
I needed to use late static binding for getting those static fields / call static functions from children from the parent class.

@rajug
Sorry i missed out something. Let me elaborate more in generic class.

class Generic{
	private $_db;
    function __construct(){
        //initialisation of db object
        $this->_db = Registry::getInstance()->get('db');
    }
    public function save(){
        //operation based on db object
        $this->_db->save();
        return 'Saved!';
    }
   
    public function delete(){
        //operation based on db object
        $this->_db->delete();
        return 'Deleted!';
    }
}

$objUser = new Users;
//Consider the test for following users class
echo $objUser->save() . '<br />';
echo $objUser->delete() . '<br />';


//doesn't work, guess why?
class Users extends Generic{
    function __construct(){
        
    }
    public function Cancel(){
        return 'Cancelled!';
    }
}

//works, guess why?
class Users extends Generic{
    function __construct(){
        parent::__construct();
    }
    public function cancel(){
        return 'Cancelled!';
    }
}

//works too, guess why?
class Users extends Generic{    
    public function cancel(){
        return 'Cancelled!';
    }
}

Test & try to note the cases. Obviously you will discover something.@least i discovered something.

ok

by the way
is $this->_db = Registry::getInstance()->get(‘db’); native to php
as far as i know it is not

and what is signifance of that recursive function …does recursion bring any betterment than not recursing it…

and i think it doesnt work as the constructor of the child will be called overwriting the exisiting linkage…