使用对象的php OOP

使用对象的php OOP,php,oop,Php,Oop,我有两个目标: 一, 此var\u dump为: object(mysqli)#6 (0) { } object(Classes_dbFactory)#7 (1) { ["_connection:protected"]=> object(mysqli)#8 (0) { } } 二, mysqli连接var\u dump的此包装为: object(mysqli)#6 (0) { } object(Classes_dbFactory)#7 (1) { ["_connect

我有两个目标:

一,

var\u dump
为:

object(mysqli)#6 (0) {
}
object(Classes_dbFactory)#7 (1) {
  ["_connection:protected"]=>
  object(mysqli)#8 (0) {
  }
}
二,

mysqli连接
var\u dump
的此包装为:

object(mysqli)#6 (0) {
}
object(Classes_dbFactory)#7 (1) {
  ["_connection:protected"]=>
  object(mysqli)#8 (0) {
  }
}
如果我这样做:

$city = $mysqli->real_escape_string($city);
$city = $conn->real_escape_string($city);
它起作用了。但是,如果我这样做:

$city = $mysqli->real_escape_string($city);
$city = $conn->real_escape_string($city);
我得到了对未定义方法类的
调用\u dbFactory::real\u escape\u string()


有没有一种方法可以使用
对象(Classes\dbFactory)
中的
对象(mysqli)
,从而可以使用现有的原生mysqli方法?

您是否检查了
Classes\dbFactory
类中的方法?也许有一个可以返回数据库对象

那么您的代码可能如下所示:

$conn=newclasses\u dbFactory(“MySQLi”、DB\u主机、DB\u用户、DB\u密码、DB\u名称)

$database=$conn->getDatabaseObject()//全部组成..

您是否检查了
类\u dbFactory
类中的方法?也许有一个可以返回数据库对象

那么您的代码可能如下所示:

$conn=newclasses\u dbFactory(“MySQLi”、DB\u主机、DB\u用户、DB\u密码、DB\u名称)

$database=$conn->getDatabaseObject()//完全是虚构的。

您可以懒散地将未定义的方法代理给mysqli对象,是的

class Classes_dbFactory {

   protected $connection;

   /* constructor not shown for simplicity */

   public function __call($method, $args) {
      $callable = array($this->connection, $method);
      if(is_callable($callable) {
         return call_user_func_array($callable, $args);
      }
  }
}
然而,如果您实际上打算支持多个数据库和/或扩展,这可能会让人困惑,因为您的“连接”可能有一组完全不同的方法。我会让工厂返回一个特定类型的DB项目,该项目旨在包装一个单独的扩展,如mysqli、PDO、oci等


正如其他人所建议的,您可能只想
getConnection
访问真实的连接对象以调用其方法。当然,您可以直接在类上为常用方法添加一些代理。但是,您将再次遇到多个db/驱动程序支持和API差异的问题。

您可能对此很懒惰,并将未定义的方法代理到mysqli对象,是的

class Classes_dbFactory {

   protected $connection;

   /* constructor not shown for simplicity */

   public function __call($method, $args) {
      $callable = array($this->connection, $method);
      if(is_callable($callable) {
         return call_user_func_array($callable, $args);
      }
  }
}
然而,如果您实际上打算支持多个数据库和/或扩展,这可能会让人困惑,因为您的“连接”可能有一组完全不同的方法。我会让工厂返回一个特定类型的DB项目,该项目旨在包装一个单独的扩展,如mysqli、PDO、oci等


正如其他人所建议的,您可能只想
getConnection
访问真实的连接对象以调用其方法。当然,您可以直接在类上为常用方法添加一些代理。但是,您将再次遇到多个db/驱动程序支持和API差异的问题。

如果
Classes\u dbFactory
是一个直接的包装器,它应该代理所有未定义的函数调用到protected\u connection属性,那么您可以将其添加到
Classes\u dbFactory

public function __call($method, $args){
     return call_user_function_array(array($this->_connection, $method), $args);
}

这会将所有未在类上实现的方法调用向下代理到受保护的属性。

如果
Classes\u dbFactory
是一个直接的包装器,应该将所有未定义的函数调用向下代理到受保护的连接属性,那么您可以将其添加到
Classes\u dbFactory

public function __call($method, $args){
     return call_user_function_array(array($this->_connection, $method), $args);
}

这会将所有未在类上实现的方法调用向下代理到受保护的属性。

是否有方法使用对象(类\u dbFactory)内的对象(mysqli),以便可以使用现有的本机mysqli方法?

有。但是,由于您已经声明了
\u connection
属性
protected
,因此需要添加一个方法来检索其实例

//...Classes_dbFactory
function getConnection()
{
  return $this->_connection;
}
然后在客户端代码中,您可以使用:

$db = new Classes_dbFactory();
$conn = $db->getConnection();
$city = $conn->real_escape_string($city);
您甚至可以添加以下内容:

function real_escape_string($string)
{
  return $this->_connection->real_escape_string($string);
}

是否有方法使用对象(Classes\dbFactory)内部的对象(mysqli),以便使用现有的本机mysqli方法?

有。但是,由于您已经声明了
\u connection
属性
protected
,因此需要添加一个方法来检索其实例

//...Classes_dbFactory
function getConnection()
{
  return $this->_connection;
}
然后在客户端代码中,您可以使用:

$db = new Classes_dbFactory();
$conn = $db->getConnection();
$city = $conn->real_escape_string($city);
您甚至可以添加以下内容:

function real_escape_string($string)
{
  return $this->_connection->real_escape_string($string);
}

请考虑在编码和调试时删除错误抑制运算符(@)。当你使用它的时候,你会扔掉潜在的有用信息。正如你所说的,
Classes\u dbFactory
是一个包装。您需要公开其中的连接对象,或者定义一些直通方法。您需要在
类\u dbFactory
上定义一个方法
real\u escape\u string()
,该方法反过来在其受保护的属性
\u connection
上调用
real\u escape\u string()
——这是许多可能性之一。简而言之,您需要以某种方式针对受保护的属性调用
real\u escape\u string()
,而不是针对
$conn
。什么是
Classes\u dbFactory
?实际上根本不应该使用@。您应该将调用包装在某个内容中,以捕获任何可能的错误并执行所需的操作。所有“@”都是慢下来的,因为它经常需要打开和关闭错误报告。请考虑在编码和调试时移除错误抑制操作符(@)。当你使用它的时候,你会扔掉潜在的有用信息。正如你所说的,
Classes\u dbFactory
是一个包装。您需要公开其中的连接对象,或者定义一些直通方法。您需要在
类\u dbFactory
上定义一个方法
real\u escape\u string()
,该方法反过来在其受保护的属性
\u connection
上调用
real\u escape\u string()
——这是许多可能性之一。简而言之,您需要以某种方式针对受保护的属性调用
real\u escape\u string()
,而不是针对
$conn
。什么是
Classes\u dbFactory
?您实际上不应该