• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • PDOStatement::setFetchMode()

    (PHP 5 >= 5.1.0, PHP 7, PECL pdo >= 0.2.0)

    为语句设置默认的获取模式。

    说明

    PDOStatement::setFetchMode(int $mode): bool
    PDOStatement::setFetchMode(int$PDO::FETCH_COLUMN,int $colno): bool
    PDOStatement::setFetchMode(int$PDO::FETCH_CLASS,string $classname,array $ctorargs): bool
    PDOStatement::setFetchMode(int$PDO::FETCH_INTO,object $object): bool

    参数

    $mode

    获取模式必须是PDO::FETCH_*系列常量中的一个。

    $colno

    列号。

    $classname

    类名。

    $ctorargs

    构造函数参数。

    $object

    对象。

    返回值

    成功时返回TRUE,或者在失败时返回FALSE

    范例

    设置获取模式

    The following example demonstrates how PDOStatement::setFetchMode() changes the default fetch mode for a PDOStatement object.下面的例子示范如何用PDOStatement::setFetchMode()来为一个 PDOStatement 对象更改默认的获取模式。

    <?php
    $sql = 'SELECT name, colour, calories FROM fruit';
    try {
      $stmt = $dbh->query($sql);
      $result = $stmt->setFetchMode(PDO::FETCH_NUM);
      while ($row = $stmt->fetch()) {
        print $row[0] . "\t" . $row[1] . "\t" . $row[2] . "\n";
      }
    }
    catch (PDOException $e) {
      print $e->getMessage();
    }
    ?>
    

    以上例程会输出:

    apple   red     150
    banana  yellow  250
    orange  orange  300
    kiwi    brown   75
    lemon   yellow  25
    pear    green   150
    watermelon      pink    90
    
    if you want to fetch your result into a class (by using PDO::FETCH_CLASS) and want the constructor to be executed *before* PDO assings the object properties, you need to use the PDO::FETCH_PROPS_LATE constant:
    <?php
    $stmt = $pdo->prepare("your query");
    $stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "className", $constructorArguments);
    # pass parameters, if required by the query
    $stmt->execute($parameters);
    foreach ($stmt as $row)
    {
      // do something with (each of) your object
    }
    ?>
    
    Something very helpful is knowing how to access namespaces from the function. It took me a minute (and Google) to figure out. The ::class property is going to be your best friend in this case.
    <?php
    $stmt->setFetchMode(PDO::FETCH_CLASS, Name\Space\Class::class);
    ?>
    
    Some note on PDO :: FETCH_CLASS | PDO :: FETCH_CLASSTYPE
    It took me some time, to realize, that you can not use this fetch-mode in $stm->setFetchMode(), when you want to retrieve objects from the database whereas the type is defined by the first column in the resultset.
    You have to define this mode directly in the $stm->fetch() method.
    To make it clearer:
    $stm = $pdo->query("SELECT * FROM `foo`);
    $stm->setFetchMode(FETCH_CLASS | PDO :: FETCH_CLASSTYPE);
    $object = $stm->fetch();
    Will not return the expected object, whereas
    $stm = $pdo->query("SELECT * FROM `foo`");
    $object = $stm->fetch(FETCH_CLASS | PDO :: FETCH_CLASSTYPE);
    will give you the object of the class, defined in the first column of `foo`.
    To fetch the rows into an existing instance of a class, use PDO::FETCH_INTO and pass the object as the second parameter. 
    The class _must_ have the column names declared as public members, or the script will die. But overloading with __set() and __get() lets it handle any column your query throws at it. 
    Set the fetch mode right after you call prepare(). It appears you _must_ use execute() - fetch() won't work. A small example, adapted from ext/pdo/tests/pdo_025.phpt:
    <?php
    class Test
    {
      protected $cols;
      
      function __set($name, $value) {
        $this->cols[$name] = $value;
      }
      
      function __get($name) {
        return $this->cols[$name];
      }
    }
    $obj = new Test();
    $db = PDOTest::factory();
    $stmt = $db->prepare("select * from test");
    $stmt->setFetchMode(PDO::FETCH_INTO, $obj);
    $stmt->execute();
    foreach ($stmt as $a) {
      print_r($a);
    }
    print_r($obj); // contains the same values as the last iteration above
    ?>
    
    PDO::FETCH_CLASS may be used only with this method and it takes up to three parameters then:
     - int mode
     - string className
     - array constructorArgs (optional)
    <?php
    $stmt = $pdo -> query('your query');
    $stmt -> setFetchMode(PDO::FETCH_CLASS, 'yourClass', array(0 => false));
    while($row = $stmt -> fetch())
    {
      // $row is an object of "yourClass" class
    }
    $stmt -> closeCursor();
    ?>
    Note also that the constructor is called AFTER the data is set on the object.