views:

174

answers:

4

Hi, I have two classes in a PHP application, B extending A for example. Class A has a function which returns some of its other properties in the form of an array of SQL insert queries eg

Class A {
$property_a;
$property_b;
$property_c;
$property_d;

function queries() {
$queries = array();
$queries[] = "INSERT INTO xxx VALUES " . $this->property_a . ", " . $this->property_b";
$queries[] = "INSERT INTO yyy VALUES " . $this->property_b . ", " . $this->property_d";
}
}

I would like class B to have a similar (identical) function which does the same thing for class B's properties, whilst still maintaining the values from class A. The idea being that each query will be passed through a final function all at the same time ie:

$mysqli->query("START TRANSACTION");
foreach($queries as $query) {
if(!$mysqli($query)) {
$mysqli->rollback();
}
}

IF all OK $mysqli->commit();

What would be the simplest way to achieve this? Any advice and ideas appreicated. Thanks!

A: 

Use a getter function to grab the properties in queries(). In each class you can then control what values the queries function is using.

Byron Whitlock
A: 

You can't really carry over stuff from one instance to another without initializing the newer class with the other instance's information. So you can extend A to change B's query function contents, then initialize B with an A instance:

class A {
    protected $propa = "";
    protected $propb = "";
    //etc

function query { /*...*/ }
}

class B extends A {
    function __construct( A $classA )
    {
        $this->propa = $classA->propa;
        // etc
    }
    function query()
    {
        //B-type queries
    }
}

$A = new A();
// set stuff in a
new B( $A );

If A and B are 100% the same (including query function), just clone A: $a = new A(); $b = clone $a;

Kevin Peno
A: 

so you want to use the properties in class A and class B? you can do this by using parent. in class B:

function queries(){ $queries = array() //stuff to get queries

return array_merge($queries,parent::queries()); }

GSto
You couldn't use parent::$property to get property values on an instance of a class. You could do this with static classes, but it is unlikely that this would lead to the desired result.
Kevin Peno
that's not what I'm doing at all. I'm calling a parent method, not a value.
GSto
+3  A: 

Within B::queries() you can call the parent's implementation of that method and append your data to the array a::queries() returns.

class B extends A {
  protected $property_e=5;
  public function queries() {
    $queries = parent::queries();
    // In a real application property_e needs to be sanitized/escaped
    // before being mixed into the sql statement.
    $queries[] = "INSERT INTO zzz VALUES " . $this->property_e;
    return $queries;
  }
}
$b = new B;
foreach( $b->queries() as $q ) {
  echo $q, "\n";
}

But you might (also) want to look into an ORM library like e.g. doctrine.

VolkerK
+1 Doctrine rocks!
Byron Whitlock
Thanks,One more question. Is it possible to extend this process even further?eg to have a class C which can access its parent function as well as its parent's parent function?Hope that makes sense lol
Dan
c::queries() calls its parent's implementation (B::queries()) which calls its parent's implementation (A::queries()). A::queries() returns an array, B::queries() adds its elements and returns the array, C::queries() appends its elements and returns the array. This can go on forever if you like ;-)
VolkerK