有人可以向我解释一下 mysqli 的类方法如何看起来有自己的子方法


Can someone explain to me how it appears that mysqli's class methods have their own sub-methods?

例如:

$m = new mysqli('host', 'user', 'pass', 'db');
$q = $m->query('SELECT stuff FROM table');
while ($row = $q->fetch_assoc()) {
    // do stuff
}

query方法如何最终拥有自己独特的"子方法",如fetch_assoc()

如何使用 OOP 复制此行为?

编辑 ...这被认为是正确的和/或良好的做法吗?

class MyClass {    
   function myMethod() {
      return new AnotherClass();
   }
}
class AnotherClass {
   function __construct() {
       $this->stuff = 'stuff';
   }
}

然后,我可以做:

$obj = new MyClass;
$stuff_getter = $obj->myMethod();
echo $stuff_getter->stuff;

这有点基于您的意见,但是因为我认为很多人都在为此苦苦挣扎,所以我将提供有关此案的一些一般信息。首先,你不能说这是否是一种好的做法。这取决于意图和背景。请参阅此代码:

class MyClass {    
   function myMethod() {
      return new AnotherClass();
   }
} 

可以吗?是的,你正在做的事情没关系,但请注意,你在这里有很强的依赖性。如果您出于某种原因想要拥有不同的实现AnotherClass您需要更改代码。可以通过使用依赖项注入来防止这种情况。在AnotherClass中实现一个接口并将其注入MyClass .当你有另一个AnotherClass实现时,你可以像"旧"版本一样传递它。如何实现这一点也取决于代码的意图是什么,但我将提供您的代码的基本示例。

class MyClass {   
    private $aClass = null;
    function __construct($aClass)
   {
        $this->aClass = $aClass;
   }
   function myMethod() {
      return new $this->aClass();
   }
}
interface AnInterface
{
}
class AnotherClass implements AnInterface {
   function __construct() {
       $this->stuff = 'stuff';
   }
}

$obj = new MyClass(new AnotherClass());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->stuff;

现在使用它,我可以像往常一样创建AnotherClass的另一个实现并将其传递给MyClass。而不是我需要添加另一个函数的方案。例如:

class AnotherClass2 implements AnInterface {
   function __construct() {
       $this->stuff = 'another stuff';
   }
}
$obj = new MyClass(new AnotherClass2());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->stuff;

我注意到的第二件事是你没有定义变量。我认为这有点基于意见,但我强烈反对公共变量(在您的情况下是默认的(。创建一个变量并在构造函数中分配该变量。创建 getter 和 setter(如果你懒惰,你可以创建 magic getters en setters(见这里(。你会得到这样的东西:

class AnotherClass implements AnInterface {
   private $stuff;
   function __construct() {
       $this->stuff = 'stuff';
   }
   public function getStuff()
   {
        return $this->stuff;
   }
}
$obj = new MyClass(new AnotherClass());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->getStuff(); 

我希望这能清楚地说明你的构造,尽管这可能不能完全回答你的问题。

关于这一点的两个说明。

  1. 该接口在 PHP 中并不总是必需的,但它肯定是最佳实践。
  2. 而不是实现接口,如果你
  3. 有很多重复,你也可以使用继承结构,当然你可以使用继承(它是一个是关系吗?

您的最终代码可能是(作为接口示例(如下所示:

class MyClass {   
    private $aClass = null;
    function __construct($aClass)
   {
        $this->aClass = $aClass;
   }
   function myMethod() {
      return new $this->aClass();
   }
}
interface AnInterface
{
    public function getStuff();
}
class AnotherClass implements AnInterface {
   private $stuff;
   function __construct() {
       $this->stuff = 'stuff';
   }
   public function getStuff()
   {
        return $this->stuff;
   }
}
class AnotherClass2 implements AnInterface {
   private $stuff;
   function __construct() {
       $this->stuff = 'another stuff';
   }
   public function getStuff()
   {
        return $this->stuff;
   }
}

$obj = new MyClass(new AnotherClass());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->getStuff(); 
$obj = new MyClass(new AnotherClass2());
$stuff_getter = $obj->myMethod();
echo $stuff_getter->getStuff();