0

In PHP, is it possible to have a function within a class that's non-static, but also isn't an instance function?

For example, if I have the following:

class A
{
   public $i;

   function setValue($val) {
      $this->i = $val;
   }
}  

$a1 = new A;
$a1->setValue(5);
echo $a1->i; // result: 5

$a2 = new A;
$a2->setValue(2);
echo $a2->i; // result: 2

Can I add a function to that class that can have "visibility" of all instances of itself so I can do something like so (which I know doesn't work, but communicates my thought):

class A
{
   public $i;

   function setValue($val) {
      $this->i = $val;
   }

   function getTotal() {
      return sum($this->i); // I know sum() isn't a built-in function, but it helps explain what I want. I'm not sure if $this makes sense here too.
   }
}  

$a1 = new A;
$a1->setValue(5);
echo $a1->i; // result: 5

$a2 = new A;
$a2->setValue(2);
echo $a2->i; // result: 2

echo A::getTotal(); // returns: 7

I guess A::getTotal() means getTotal() would need to be static, but if it was static then it wouldn't then be able to "see" each class instance.

Is this type of thing possible, and what's the correct terminology I should be using?

Turgs
  • 1,729
  • 1
  • 20
  • 49

4 Answers4

4

No, there is no built-in instance enumeration, you will need to keep references to each instantiated object yourself. You can keep an array of instances in a static property of the class and populate it in your __construct(). You can then have a static method loop over this array and process all instances.

lanzz
  • 42,060
  • 10
  • 89
  • 98
  • ...or you could keep a static counter variable, and have all the instances modify it when their value is changed. You would need to make the instance value `private` and provide a setter for this to work though. But +1 for the generally correct answer. – DaveRandom Jul 03 '12 at 13:27
  • I assume the `sum()` example is just an example. Not every such aggregation can be efficiently pre-calculated on every change, so it makes sense to me to suggest a more-general approach. – lanzz Jul 03 '12 at 13:35
1

I think you would like something like this:

 class A
{
   public $i;

   function setValue($val) {
      $this->i = $val;
   }
}  

$a1 = new A;
$a1->setValue(5);
echo $a1->i; // result: 5

$a2 = new A;
$a2->setValue(2);
echo $a2->i; // result: 2

$total = 0;
foreach( get_defined_vars() as $name => $obj ) {
  if ( $obj instanceof A ) {
    $total += $obj->i;
  }
}
echo $total; // returns: 7

The function you need here is "get_defined_vars". But it only gets the variables within the current scope!

Steven Van Ingelgem
  • 872
  • 2
  • 9
  • 25
0

Just make the class member of the sum static as well. If you do this, then you will need to make sure it's maintained properly within each class (i.e. setValue needs to update that sum appropriarely).

This is probably not a great way to do things, though. I think it would get pretty confusing. In what context do you need the sum that you don't have access to all the instances?

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
0

Are you looking for a protected function foo($s){...} which the class can use but cannot be accessed from the outside? (PHP5 only)