开发者

Instantiating classes and accessing methods from different classes

I'm trying to use a Class_B function in one of Class_A's functions. But a lot of Class_B's functions include $this which causes problems. These are both classes (each class is of course in its own file):

class Class_A
{
   function hello()
   {
      require('class_b.php');
      echo 'Hello ' . Class_B::person();
   }

   function bye()
   {
      require('class_b.php');
      echo 'Bye ' . Class_B::person();
   }
}

class Class_B
{
   function person()
   {
      // various operations and variables
      echo $this->get_user($id);
   }
}

When I run the Class_A file I get Call to undefined method Class_A::person() in (...) because I think the $this value is changed when I instantiate the Class_A class. It overrules the Class_B value. How can I stop this?

Also, another question: how can I access Class_B from every function in Class_A? I don't want to redeclare the class. Do I need to do this:

class Class_A
{
  开发者_如何学运维 function function1()
   {
      require('class_b.php');
      $class_b = new Class_B();
      // code
   }

   function function2()
   {
      require('class_b.php');
      $class_b = new Class_B();
      // code
   }
}

Or do I need to use a constructor or something?


By Class_B::person() you are calling the method statically. So you should declare the person() method as static and can't use $this because you don't have an instance of Class_B.

If you need an instance of Class_B, just create it and store in the class_B on construction.

class Class_A {
  private $b;
  function __construct()
  {
    $this->b = new Class_B();
  }     
  function stuff()
  {
    $this->b->person();
  }


Don't put require inside a method. Code in an included file inherits the scope of the place where you include it, and in your example, bad things happen. Also, for class definition scripts, consider require_once instead of require, to avoid multiple definitions.

As a rule of thumb, put all includes and requires at the top of your script. Better yet, set up a class autoloader, and register it in an auto_prepend script. That way, you won't have to manually include anything at all (at least not for class definitions).


What you might want is dependency injection, whereby you pass an object of Class_B into Class_A's constructor and hold it as a property in Class_A. It then becomes available in Class_A as $this->classB or similar.

// Include Class_B code outside the class.
require_once('class_b.php');
class Class_A {
  // Property to hold Class_B
  public $b;

  // Constructor
  public function __construct($b) {
    $this->b = $b;
  }

  public function function1(){
     // code
     $this->b;
  }
  public function function2(){
     // code
     $this->b;
  }
}

// Now call your objects:
// The Class_B which will be injected into A
$b = new Class_B();
// Your Class_A, which holds an instance of Class_B as a property
$a = new A($b);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜