【问题标题】:php help - instantiate functionphp帮助 - 实例化函数
【发布时间】:2011-04-09 05:06:13
【问题描述】:

以下是做什么的?

public static function find_by_sql($sql="") 
{
    global $database;
    $result_set = $database->query($sql);
    $object_array = array();
    while ($row = $database->fetch_array($result_set)) 
    { 
        // fetch_array=mysql_fetch_array
        $object_array[] = self::instantiate($row);
    }
    return $object_array;
} 

private static function instantiate($record) 
{
    $object = new self;
    foreach($record as $attribute=>$value)
    {
        if($object->has_attribute($attribute))
        {
            $object->$attribute = $value;
        }
    }
    return $object;
}

private function has_attribute($attribute) 
{
    return array_key_exists($attribute, $this->attributes());
}

protected function attributes() 
{ 
    // return an array of attribute names and their values
    $attributes = array();
    foreach(self::$db_fields as $field) 
    {
        if(property_exists($this, $field)) 
        {
            $attributes[$field] = $this->$field;
        }
    }
    return $attributes;
}

类属性是,

public $id;
public $username;
public $password;
public $first_name;
public $last_name;
public $power;

所以 while 循环遍历每一行,但 instantiate 函数有什么作用呢? instantiate 是如何优化脚本的?

另外,$object = new self 是什么意思,这是类的新实例吗?当您返回$object 时,您返回的是什么?

谢谢,丹尼尔。

【问题讨论】:

    标签: php oop


    【解决方案1】:

    instantiate 函数根据包含的类创建一个新对象(“实例化”只是指从某物创建一个实例,在这种情况下,是它所在的类),在这种情况下,该函数遍历提供的数组,检查其键是否定义在类的attributes 数组中,如果是,则使用这些键的值填充对象。

    在 while 循环中,$object_array 为每一行填充了包含类的单独实例。

    这个实例化调用不会优化脚本(它会稍微减慢它,因为它必须调用函数而不是,例如,只是将行插入到数组中),但它的原因可能是:1)以一种可以对它们使用对象方法的方式包装行,以及 2) 确保未在类上指定为属性的 SQL 列不会暴露在返回数组的行中。

    对于self,请参阅What does new self(); mean in PHP?。基本上,是的,$object = new self 创建了该类的一个新实例,因为self 表示当前类。这很方便,因为如果您决定更改类名,则无需更改此引用。

    全局变量 btw 是一个问题,因为全局变量更适合提供给类实例以避免名称冲突。

    【讨论】:

      【解决方案2】:

      self 只是引用当前类的快捷方式。 $this 引用当前对象的方式相同。

      class Foo {
          public function bar() {
              new self;
              new Foo;
          }
      }
      

      这些都是相同的东西,都从类Foo 中实例化一个新对象。使用self 更加优雅,因为您可以更改Foo 的类名,而不必在每次使用时都重命名。

      所以你的::instantiate 函数正在做的是实例化同一类的新对象,在其上设置一些属性并返回它。对self::instantiate 的调用只是静态调用instantiate 方法,就像$this->instantiate() 将其作为当前对象的方法调用一样。

      【讨论】:

      • 感谢您的解释,您能告诉我这是否是最佳做法吗?这是每个人都从数据库中获取数据并从中创建对象的方式吗?如果不是,那么正确的方法是什么?感谢您的宝贵时间!
      • @youngcouple10 这与每个人 的做法不同,但“静态构造函数”是一种有效的使用方式。只是这个例子中的private static function instantiate 没问题,尽管课程的其余部分使用了一些不好的做法,比如global
      • 谢谢,但我接受实例化函数的一般想法是正常的。为什么全局不好?你个人有使用的实例化函数吗?
      • 搜索global为什么不好,说的够多了。是的,我个人正在使用类似的代码。
      • 感谢您的帮助和时间。最后一件事,在 PHP 中是否可以将静态属性设置为函数的结果? public $table = get_class();?如果没有,为什么不呢?
      【解决方案3】:

      instantiate 函数从 db 返回的数组数据中创建一个类实例,然后返回对象实例。然后将该实例 eis 添加到 find_by_sql() 返回的数组中。本质上它执行从数据库列到对象实例属性的数据映射。

      我必须说...这个实现闻起来不太好:-)

      【讨论】:

      • 你能解释一下为什么这个实现听起来不太好,那么最佳实践是什么
      【解决方案4】:

      这里instantiate 函数正在创建同一类的新对象。 $Object = new self; 创建同一个类的一个对象,在这里它分配给同一个类的一个属性,这当然是一个糟糕的实现,并不是所有必需的。您可以保留一个数组来保存值,因为如果要检索值,则需要遍历对象数组。

      【讨论】:

        猜你喜欢
        • 2010-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-19
        • 1970-01-01
        • 2011-10-14
        • 2012-03-20
        相关资源
        最近更新 更多