【问题标题】:Can someone explain to me how it appears that mysqli's class methods have their own sub-methods?有人可以向我解释一下 mysqli 的类方法是如何有自己的子方法的吗?
【发布时间】:2015-01-30 22:19:56
【问题描述】:

例如:

$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;

【问题讨论】:

  • 因为查询返回一个mysqli_result 对象 - 我怀疑这是“阅读手册”的情况:php.net/manual/en/book.mysqli.php
  • 一个方法很少返回自身,它返回数据结构,如对象、字符串、数组等。$m$q 在您的情况下是对象,分别从 mysqli::__construct() 和 @ 返回987654332@
  • @RichardBernards:我认为构造方法不能返回值...?
  • 如何使用 OOP 复制这种行为? 那是一个对象!!!一定要和@CD001一起去。 看书 PHP: Classes and Objects
  • 很公平,我一直在阅读有关 PHP OOP 的文章,我只需要更好地了解它。

标签: php oop methods properties extends


【解决方案1】:

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

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(如果你很懒,你可以创建魔法 getter en setter (see here)。你会得到这样的东西:

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. 如果您有很多重复项并且当然允许您使用继承(它是一个 is-a 关系吗?),您也可以使用继承结构来代替实现接口。

您的最终代码可能(作为接口示例)是这样的:

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(); 

【讨论】:

    猜你喜欢
    • 2016-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    相关资源
    最近更新 更多