PDOStatement
在线手册:中文  英文

PDOStatement::setFetchMode

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

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

说明

bool 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 )

参数

mode

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

colno

列号。

classname

类名。

ctorargs

构造函数参数。

object

对象。

返回值

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

范例

Example #1 设置获取模式

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


PDOStatement
在线手册:中文  英文

用户评论:

ronhenry at netspeed dot com dot au (2010-08-04 20:43:57)

To create an object instance via the constructor solely from the result of the PDO query you must use PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, followed by the name of the class, then an array consisting of the names of the constructor elements. This may be specified in setFetchMode() for prepared statements, or fetch*() otherwise. This forces PDO to create your object instance by calling the constructor.

e.g setFetchMode (PDO::FETCH_CLASS , 'classname', array('paramName1', 'paramName2', ...).

An example using a prepared statement (without variable bindings) and fetchALL().

<?php
class Test
{
  private 
$id;
  private 
$a;
  private 
$b;

  function 
__construct ($id$a$b)
  {
    
$this->id $id;
    
$this->$a;
    
$this->$b;
  }

  public function 
display()
  {
    echo 
"<p>id: $this->id, a: $this->a, b: $this->b</p>";
  }
}

$testx = new Test(10'AAA''BBB' );
$testx->display();
$testx NULL;

try
{
  
$pdo = new PDO('mysql:host=127.0.0.1;dbname=Testing''user''pswd', array (PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION));
  
  
// Prepared statement
  
$stmt $pdo->prepare("SELECT id, a, b FROM test WHERE id = 1");
  
$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE"Test", array('id''a''b'));
  
$stmt->execute();
  foreach (
$stmt as $test)
    
$test->display();

  
// Same again with fetchALL()
  
$stmt $pdo->query("SELECT id, a, b FROM test WHERE id = 2");
  
$test $stmt->fetchALL(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE'Test', array('id''a''b'));
  
$test[0]->display();
    
  
$pdo NULL;
}
catch (
PDOException $e)
{
  echo 
'Error: '$e->__toString();
}
?>

You can avoid all this PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE and constructor fuss, and create an object instance from the result of a PDO query without a constructor, and with class properties declared as public, protected, private, or not at all:  just let PDO use reflection injection to populate your object instance with data from your query. This is PDO's default action. PDO will inject the specified variables into your object instance before php calls the constructor, so you should either not have a constructor, or have one with no parameters. Of course, you may have problems using this as a normal class. Also see the comments about reflection injection below.

<?php
class Test1
{
  public function 
display()
  {
    echo 
"<p>id: $this->id, a: $this->a, b: $this->b</p>";
  }
}

try
{
  
$pdo = new PDO('mysql:host=127.0.0.1;dbname=Testing''user''pswd', array (PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION));
  
  
$stmt $pdo->prepare("SELECT id, a, b FROM test WHERE id = 1");
  
$stmt->setFetchMode(PDO::FETCH_CLASS"Test1");
  
$stmt->execute();
  foreach (
$stmt as $test1)
    
$test1->display();

  
$stmt $pdo->query("SELECT id, a, b FROM test WHERE id = 2");
  
$test1s $stmt->fetchALL(PDO::FETCH_CLASS'Test1');
  foreach (
$test1s as $test1)
    
$test1->display();

  
$pdo NULL;
}
catch (
PDOException $e)
{
  echo 
'Error: '$e->__toString();
}
?>

You can also use variables with PDO::FETCH_CLASS and the constructor parameter array, what you do is up you.

Reflection injection increases the risk of variable, code, and SQL injection if user input is used unwisely, so ALWAYS validate user input on the server side, and ONLY insert it into your SQL via bound parameters in prepared SQL statements. If you do not use PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, and a constructor element name array, you should be especially careful.
See: http://www.owasp.org/index.php/Reflection_injection for a non php description of reflection injection.

Dormilich at netscape dot net (2010-07-13 02:16:22)

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
}
?>

harlequin2 at gmx dot de (2008-06-10 05:22:24)

You can also set the fetch mode to FETCH_ASSOC if you do not need the column index. This reduces both the size of the resultset and is faster in some cases.

<?php
$stmt 
$dbh->prepare("SELECT mykey, myvalue FROM mytable");
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$arrValues $stmt->fetchAll();
foreach (
$arrValues as $row){
    print 
$row["mykey"]." -> ".$row["myvalue"]."<br />\n";
}
?>

stein_AT_rhrk.uni-kl.de (2007-11-19 16:04:24)

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`.

matt at kynx dot org (2006-02-18 03:13:30)

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
?>

Dariusz Kielar (2006-02-12 22:55:43)

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(=> 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.

易百教程