问题
Let's see if I can describe this properly...
I have an abstract class that when other classes extend from it, I'd like for the abstract class' data to be reset to zero.
The idea being that I have a pile of classes extending this and using MySQL table's for data structure. I don't want to query the DB with every class instantiation to determine the class' data ("SHOW COLUMNS FROM tablename
).
So for every class, I'd like for it to each "Have we created this class before? If so, we know the class' structure, if not, grab the table columns and create the class as well as store the table columns for later use."
I've been using the following for testing my idea:
$columns = array("Column 1", "Column 2", "Column 3");
abstract class AbstractClass {
protected static $colFields = array();
public function __construct() {
$this->setVars();
}
private function setVars() {
global $columns;
if (count(self::$colFields) == 0) {
var_dump("Array length is 0");
foreach ($columns as $key) {
self::$colFields[] = $key;
if (!isset($this->$key))
$this->$key = null;
}
}
else {
var_dump("Array length is not 0");
foreach (self::$colFields as $key) {
$this->$key = null;
}
}
}
public function test() {
var_dump($this);
}
}
class ObjectA extends AbstractClass {};
class ObjectB extends AbstractClass {};
$objectAA = new ObjectA();
$objectAB = new ObjectA();
$objectAC = new ObjectA();
$objectAC->test();
$objectBA = new ObjectB();
$objectBB = new ObjectB();
$objectBC = new ObjectB();
$objectBC->test();
And the script's output is:
string(17) "Array length is 0"
string(21) "Array length is not 0"
string(21) "Array length is not 0"
object(ObjectA)#3 (4) {
["className":protected]=>
string(7) "ObjectA"
["Column 1"]=>
NULL
["Column 2"]=>
NULL
["Column 3"]=>
NULL
}
string(21) "Array length is not 0"
string(21) "Array length is not 0"
string(21) "Array length is not 0"
object(ObjectB)#6 (4) {
["className":protected]=>
string(7) "ObjectB"
["Column 1"]=>
NULL
["Column 2"]=>
NULL
["Column 3"]=>
NULL
}
I'm expecting the first instantiation of ObjectB to output the "Array length is 0" segment, then continue on.
Can anyone help?
回答1:
I suggest that you do not store the cached table information in your abstract class. Create a new class called TableInformationRepository or something like that. Have your child class or abstract class query the TableInformationRepository for information about tables/classes. In the TableInformationRepository, cache the information you want keyed by class name or table name.
回答2:
To add to what Scott Saunders said - why not use a singleton for that?
http://php.net/manual/en/language.oop5.patterns.php - example #2
回答3:
In PHP, if you don't redeclare protected/public static fields in the subclasses, they will all belong to the same reference set. This means a change in a protected property will be reflected in all the classes.
Example:
class A {
public static $field = "1";
}
class B extends A { }
B::$field = 2;
echo A::$field; //2
On the other hand:
class A {
public static $field = "1";
}
class B extends A {
public static $field = "1";
}
B::$field = 2;
echo A::$field; //1
You can also break the reference set by hand:
class A {
public static $field = "1";
}
class B extends A { }
$v = 2;
B::$field = &$v;
unset($v);
echo A::$field; //1
回答4:
thanks for detailed explanation, I found very basic information on other site hope this help others. http://www.phptechi.com/php-5-abstract-class.html
来源:https://stackoverflow.com/questions/3391788/php5-abstract-classes-separate-copy-of-class-variables-for-each-child-class