【问题标题】:How to implement PDO FETCH_CLASS in correct way?如何以正确的方式实现 PDO FETCH_CLASS?
【发布时间】:2015-11-08 15:20:08
【问题描述】:

嗨,世界编程天才。我是PDO和OOP的新手,请理解。

我尝试做世界上最简单的事情——从 MySQL 的表中获取数据。

我想: 1) SELECT * from ...大约有 20 个字段。 2) 获取具有 4-6 个属性的对象数组。 3)我想用fetchAllFETCH_CLASS...

PDOStatement PDO::query ( string $statement , int $PDO::FETCH_CLASS , string $classname , array $ctorargs )

我发现我们可以传递一个参数数组但不能实现它。

那我在做什么呢?

 class handler{
connection etc..
public $params = array('surname','id','country','display' );
return $stmt->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'person',$this->params);


class person  {
public $surname=null;
public $id=null;
public $country=null;
public $status=null;

然后

__construct ()

我不会说 - 因为我有 50 个变种((( }

所以,我需要从 20 个字段中过滤选项以获取一个类,但不是在 SELECT 模式下而不是 *... 可能吗? 我知道你是天才! 新手见谅

更新

 function __construct($surname,$id,$country,$display) {
 $this->surname=$surname;
 $this->country=$country;
 $id->id->$id

// 这个对象中我唯一需要的 }

function __construct() {
$arg=array('surname','id');
foreach ($arg as $val) {
$this->{$val}=$$val;
}
} 

似乎它可能是下一个......不是构造函数来过滤属性......

更新 我尝试了@GolezTrol 提出的解决方案。 解决方案 1 主张... 注意:未定义的属性:Person::$_attributes in 如果我做 类实体{ 公共 $_attributes;

 function __construct() { ....

class Person extends Entity {
 public $_attributes;
}

它有效..但我得到一个对象...

[0] => Person Object
    (
    [_attributes] => Array
            (
                [0] => surname
                [1] => id
                [2] => country
                [3] => status
            )

        [id] => 298

.. 不好(

【问题讨论】:

  • 你说 " 然后 __construct () 我不会放它 - 因为我有 50 个变种((( }")。你能至少发布一个或两个?也许它会让你更清楚你打算实现什么。
  • 我认为FETCH_CLASS 已经将所有列映射到属性。如果您指定的类需要其构造函数的参数,您只需要指定最后一个参数。但是您不需要将“姓氏”等的值放入属性$surname
  • 感谢您的评论!我会指定。我选择 *。它有 20 个参数。我把所有东西都带进一个班级。一个对象实际上有 20 个字段,如表中所示。我希望我的对象有 4 个!从 20 提交的文件留下一个选择 * 选项)))有可能吗?像 $args=array of 4. 如果数组中有 20 个 .. $this -> {property} ->$property
  • 还是不清楚。您能否提供一个简化的示例(在您的原始问题中,而不是评论中)?
  • 嗯,对我来说仍然没有意义,并且有一定的代码气味 - 可能是 XY 问题?无论如何,这不是$classname 的工作方式。它首先创建类的实例,然后(在构造函数完成后)设置属性。你想达到什么目的? (不是如何。)

标签: php mysql arrays object pdo


【解决方案1】:

我认为您的意思是您只想加载您指定的属性,而不是从查询返回的所有值。您的尝试是通过将所需的字段名称传递给构造函数来做到这一点。

解决方案 1:只需指定属性数组并阻止其余部分

如果您从__set magic method 获得一点帮助,您的方法可能会奏效。使用func_get_args(),您可以将函数(在本例中为构造函数)的所有参数放入一个数组中。这样,您将获得传递给 fetch_all 的字段名称数组。

如果属性存在于提供给构造函数的数组中,magic setter 只会设置属性,因此本质上它会过滤掉所有不需要的字段。

优点:简单。后代类中不需要特定的实现。您可以只使用 Entity 作为所有实体的类。

缺点:每个属性都会调用magic setter并调用in_array这可能会很慢。 fetch_all 正在确定要读取哪些字段,而这可能应该是类的责任。

class Entity {

  function __construct() {
    $this->_attributes = func_get_args();
  }

  function __set($prop, $value) {
    if (in_array($prop, $this->_attributes)) {
      $this->$prop = $value;
    }
  }

}

// If you would need a descendant class to introduce methods, you can..
class Person extends Entity {
}


$stmt->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Person', array('id', 'surname', 'gender'))

解决方案 2:屏蔽所有不存在的属性

我认为类似的解决方案,但更清洁。实现魔法设置器并让它做......什么都没有。它将为不存在的属性调用,为不存在的属性调用。因此,在Person 中,您只需声明您想要读取的任何值。所有其他属性将被定向到空的 __set 方法,因此它们被隐式忽略。

优点:仍然很容易。几乎没有任何实施。您可以将空方法放在基类中,或者只在 Person 和您拥有的所有其他类中实现它。您只需在 Person 中声明属性。您甚至不需要在fetch_all 中指定要读取的字段。此外,读取现有属性的速度更快。

缺点:如果你想将不同的信息集读入同一个类,这是不可能的。下面我的示例中的人总是有一个 ID、姓氏和性别。如果您只想阅读实例 id,则必须引入另一个类。但是你想要那个吗?..

class Entity {
  function __set($prop, $value) {
    // Ignore any property that is not declared in the descendant class.
  }
}

class Person extends Entity {
  public $id = null;
  public $surname = null;
  public $gender = null;
}

$stmt->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Person')

解决方案 3:只读您想要的字段

这实际上是最好的解决方案。不要选择所有字段SELECT *,而是只选择您想要的字段:SELECT id, surname, gender ..。这样,您将不会拥有具有太多值的对象,但更重要的是,您还可以减少数据库的负载。数据库不需要获取数据,PHP 不需要接收数据,如果数据库服务器与 Web 服务器分开,还可以节省网络流量。所以在所有方面,我认为这是最好的选择。

【讨论】:

  • 哇!你让我印象深刻!没想到这么好的关注.. 非常感谢你 - 你理解我的想法是正确的。我会尝试所有这些,并且肯定会回来。再次感谢!附言我明确地理解第三种解决方案是最好的 - 因为不是 FetchAll 到类 - 只是循环 fetch_obj 并选择需要。唯一的麻烦(在我看来) - 我花了太多时间来制作一个 jquery 数据表来工作 - 这太疯狂了((对我来说......并且需要将一个缩短版本的人传递给表格......只有 4 个主要列,而其他一次我并行使用-差异来解释..我是疯狂的新手猴子))
  • everything 在没有 OOP 的情况下也可以工作......但是 smb 推给我可怜的脑袋,OOP 会有很大帮助((在这个阶段我没有看到任何优势......并继续执行程序,但使用新的 OOP 语法..只是两天的探索和阅读书籍。网络上缺乏实用的材料..他们是或差异或复制带有水果的教程)))
猜你喜欢
  • 2019-08-27
  • 1970-01-01
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 2019-03-31
  • 1970-01-01
  • 2016-05-24
  • 2019-04-05
相关资源
最近更新 更多