PDO константы выборки данных

PDO константы выборки данных

Устанавливают режим выборки значений из результата запроса. Указываются, как правило, в методах PDOStatement::fetchAll() и PDOStatement::fetch(). Или можно раз, и надолго установить режим выборки таким образом:

PDOStatement->setFetchMode(PDO::FETCH_ASSOC);

И после, (за исключением особых случаев) вызывать методы PDOStatement::fetchAll() и PDOStatement::fetch() уже без параметров.

PDO::FETCH_LAZY ( 1 )
Определяет, что метод fetch должен возвратить каждую строку как объект с именами переменных, которые соответствуют именам столбцов, возвращенным в наборе результатов. PDO:: FETCH_LAZY создает свойства объекта, соответствующие именам столбцов выборки. Не может использоваться с методом PDOStatement::fetchAll(). Так же добавляет в результирующий объект свойство queryString – которое содержит строку запроса:

Трассировка результирующего объекта запроса :


  SELECT
   `id`, `city`, `country_id`, CONCAT(city,country_id) AS `city`
  FROM
   `gp_cities`

- здесь и далее будет использоваться этот же запрос, в нём умышленно задвоены результирующие столбцы ` city ` .

Результат:


 PDORow Object
 (
    [queryString] => SELECT id,city,country_id, CONCAT(city,country_id) AS city FROM gp_cities LIMIT 0,10
    [id] => 199185
    [city] => Абердин (аэропорт)11488
    [country_id] => 11488
 )

PDO::FETCH_ASSOC ( 2 )
Определяет, что метод fetch должен возвратить каждую строку как ассоциативный массив, имена ключей массива будут соответствовать именам столбцов в наборе результата. Если набор результатов содержит несколько столбцов с одним и тем же именем, PDO::FETCH_ASSOC выберет из задвоенных столбцов результат последнего из них.

  SELECT
   `id`, `city`, `country_id`, CONCAT(city,country_id) AS `city`
  FROM
   `gp_cities`

Результат:

 Array
 (
    [id] => 199185
    [city] => Абердин (аэропорт)11488
    [country_id] => 11488
 )

PDO::FETCH_NAMED ( 11 )
Тоже что и PDO::FETCH_ASSOC
PDO::FETCH_NUM ( 3 )
Тоже что и PDO::FETCH_ASSOC только возвращённый массив будет индексный.

  SELECT
    `id`, `city`, `country_id`, CONCAT(city,country_id) AS `city`
  FROM
    `gp_cities`

Результат:

  Array
 (
    [0] => 199185
    [1] => Абердин (аэропорт)
    [2] => 11488
    [3] => Абердин (аэропорт)11488
 )

PDO::FETCH_BOTH ( 4 )
Гибрид PDO::FETCH_ASSOC и PDO::FETCH_NUM Результирующий массив будет смешанным (индексы + именованные ключи). Причем индексная часть будет содержать значения всех столбцов выборки даже с задвоенными именами, а ассоциативная часть выберет из задвоенных столбцов результат последнего из них.

  "SELECT
   `id`, `city`, `country_id`, CONCAT(city,country_id) AS `city`
  FROM
   `gp_cities`"

Результат:

 
  Array
 (
    [id] => 199185
    [0] => 199185
    [city] => Абердин (аэропорт)11488
    [1] => Абердин (аэропорт)
    [country_id] => 11488
    [2] => 11488
    [3] => Абердин (аэропорт)11488
 )

PDO::FETCH_OBJ ( 5 )
Определяет, что метод fetch должен возвратить каждую строку как объект с именами свойств, которые соответствуют именам столбцов, возвращенным в наборе результатов. В случае с применением PDOStatement::fetchAll() – вернёт массив объектов.

Результат:

 
  Array
 (
    [0] => stdClass Object
        (
            [id] => 199185
            [city] => Абердин (аэропорт)11488
            [country_id] => 11488
        )

    [1] => stdClass Object
        (
            [id] => 166961
            [city] => Авалон (Аэропорт)934
            [country_id] => 934
        )
    ...
 }

PDO::FETCH_BOUND ( 6 )
Определяет, что метод fetch должен возвратить TRUE и назначить значения столбцов в наборе результатов к переменным PHP, с которыми они были связаны при помощи PDOStatement::bindParam() или PDOStatement::bindColumn() методов:

  $sql = 'SELECT id,city,country_id FROM gp_cities LIMIT 0,5';

  $stmt = $dbh->prepare($sql);
  $stmt->execute();

  $stmt->bindColumn(1, $city);
  $stmt->bindColumn(2, $country_id);

  while( $stmt->fetch( PDO::FETCH_BOUND ))
  {
    echo "city = ".$city.";\t country_id=".$country_id."<br />";
  }

Результат:


  city = 199185;	country_id=Абердин (аэропорт)
  city = 166961;	country_id=Авалон (Аэропорт)
  city = 198410;	country_id=Авока Бич
  city = 942;           country_id=Аделаида
  city = 198234;	country_id=Айвенго

PDO::FETCH_COLUMN ( 7 )
Определяет, что метод fetch должен возвратить только единственный запрашиваемый столбец из следующей строки в наборе результатов. Ещё так же можно указать номер столбца:
  $sql = 'SELECT 
            `id`, `city`, `country_id`, CONCAT(city,country_id) AS `city` 
           FROM
            `gp_cities` 
           LIMIT 
            0,5';

  echo '<pre>';
  print_r( $dbh->query($sql)->fetchAll(PDO::FETCH_COLUMN,3) );
  echo '</pre>';

Результат:

 Array
 (
    [0] => Абердин (аэропорт)11488
    [1] => Авалон (Аэропорт)934
    [2] => Авока Бич934
    [3] => Аделаида934
    [4] => Айвенго934
 )

PDO::FETCH_CLASS ( 8 )

Определяет, что fetch - метод должен возвратить новый экземпляр запрашиваемого класса, проецируя столбцы на соответствующие (их именам) свойства в классе.

Примечание:

если свойство не существует, в запрашиваемом классе будет вызван магический метод __set(). В конструктор создаваемого объекта, можно передавать параметры в виде массива:

 


  $stmt->setFetchMode(PDO::FETCH_CLASS, 'SomeClass',array('republic'));

Пример:


  $sql = 'SELECT `id`, `city`, `country_id` FROM gp_cities LIMIT 2';
  $stmt = $dbh->query($sql);	

  class SomeClass
  {		
    private $id;
    private $city;
    private $country_id;
    private $status;		
    static  $count = NULL;

    public function __construct($status = '')
    {
        self::$count ++;
        $this->status = $status;
    }
  }    
  // «SomeClass»  строка-имя класса, чьи объекты будут создаваться: 
  $stmt->setFetchMode(PDO::FETCH_CLASS, 'SomeClass', array('republic'));

  echo '<pre>';
  print_r( $stmt->fetchAll() );
  echo '</pre>';
  echo SomeClass::$count;

Результат:

 Array
 (
    [0] => SomeClass Object
        (
            [id:private] => 199185
            [city:private] => Абердин (аэропорт)
            [country_id:private] => 11488
            [status:private] => republic
        )

    [1] => SomeClass Object
        (
            [id:private] => 166961
            [city:private] => Авалон (Аэропорт)
            [country_id:private] => 934
            [status:private] => republic
        )
 )
2
PDO::FETCH_INTO ( 9 )

Определяет, что метод fetch должен обновить существующий экземпляр запрашиваемого класса, проецируя столбцы на соответствующие свойства в классе.

Может я что то и не понял, но судя по экспериментам это примерно, то же, что и PDO::FETCH_CLASS за исключением мелких деталей:

  $sql = 'SELECT `id`, `city`, `country_id` FROM gp_cities LIMIT 2';		

  class SomeClass
  {		
    public $id;
    public $city;
    public $country_id;
    public $status;

    public function __construct($status = '')
    {
      $this->status = $status;
    }
  }
  $stmt = $dbh->query($sql);
  // Параметры передаются в конструктор напрямую:
  $stmt->setFetchMode(PDO::FETCH_INTO, new SomeClass('federation'));	
  // Теперь проходим циклом по самому PDOStatement, минуя вызов метода
  // PDOStatement->fetch() или PDOStatement->fetchAll()
  foreach($stmt AS $some_obj)
  {
    echo '<pre>';
    var_dump( $some_obj );
    echo '</pre>';	
  }

Результат возвращается в виде отдельного объекта:

 SomeClass Object
 (
    [id] => 199185
    [city] => Абердин (аэропорт)
    [country_id] => 11488
    [status] => federation
 )
 SomeClass Object
 (
    [id] => 166961
    [city] => Авалон (Аэропорт)
    [country_id] => 934
    [status] => federation
 )

PDO::FETCH_FUNC ( 10 )
Работает только с методом PDOStatement::fetchAll(), и устанавливается тоже только в нём. Возвращает результат через вызов указанной функции, используя столбцы каждой результирующей строки в качестве параметров вызываемой функции. Тут всё ясно из названия и примера:

  $sql = 'SELECT `id`, `city`, `country_id` FROM gp_cities LIMIT 2';		

  function callMe($id=0,$city=0,$country_id=0)
  {
    // Здесь можно похимичить с входными данными...
    // Ну, а множественное значение можно вернуть, к примеру
    // массивом:
    return array($id.'+++', $city.'***', $country_id.'###');
  }    

  $stmt = $dbh->query($sql);
  $res = $stmt->fetchAll(PDO::FETCH_FUNC, callMe);

  echo '<pre>';
  print_r( $res );
  echo '</pre>';

Результат:

 Array
 (
    [0] => Array
        (
            [0] => 199185+++
            [1] => Абердин (аэропорт)***
            [2] => 11488###
        )

    [1] => Array
        (
            [0] => 166961+++
            [1] => Авалон (Аэропорт)***
            [2] => 934###
        )
 )

PDO::FETCH_GROUP ( 65536 )
Возвращает массив значений, сгруппированных по значению определённого столбца результирующей строки. Есть смысл использовать с другими константами, указывая их через побитовое «или»:

  $sql = 'SELECT 
            `cit`.`id`, `cit`.`city`, `cit`.`country_id`, `cnt`.`country`
          FROM 
            `gp_countries` AS `cnt` 				
          INNER JOIN 
            `gp_cities` AS `cit` 
          ON 
            `cit`.`country_id` = `cnt`.`id`';		

  $stmt = $dbh->query($sql);
  $res = $stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_ASSOC);

  echo '<pre>';
  print_r( $res );
  echo '</pre>';

Результат:

 Array
 (
    [198471] => Array
        (
            [0] => Array
                (
                    [city] => Яррагон
                    [country_id] => 934
                    [country] => Австралия
                )
        )

    [184033] => Array
        (
            [0] => Array
                (
                    [city] => Аберзее
                    [country_id] => 700
                    [country] => Австрия
                )
        )
     ...
 )

По мне так лучше сделать это средствами SQL:

  'SELECT 
    `cit`.`id`, `cit`.`city`, `cit`.`country_id`, `cnt`.`country`
  FROM 
    `gp_countries` AS `cnt` 				
  INNER JOIN 
    `gp_cities` AS `cit` 
  ON 
    `cit`.`country_id` = `cnt`.`id`
  GROUP BY
    `cit`.`country_id`'

PDO::FETCH_UNIQUE ( 196608 )
Позволяет получить только уникальные значения из результирующего набора данных. Может работать в паре с другими константами через побитовое "или". Ещё один, на мой взгляд, избыточный функционал: на хрена гонять трафик, если можно отсеять данные ещё на этапе запроса: "SELECT DISTINCT …"
PDO::FETCH_KEY_PAIR ( 12 )
Доступный с PHP 5.2.3.
Выдает результат запроса в виде массива, где 1-ый столбец - ключ второй является значением. Как следствие требование: sql–запрос должен возвращать два столбца в ответе:

  $sql = 'SELECT `id`, `city` FROM `gp_cities` ORDER BY city DESC';

  $stmt = $dbh->query($sql);

  echo '<pre>';
  print_r($stmt->fetchAll(PDO::FETCH_KEY_PAIR));
  echo '</pre>';

Результат:

 Array
 (
    [174853] => Яффа
    [145423] => Яунде
    [167845] => Ятелей
    ...
 )

Иначе, если столбца не два: General error: PDO::FETCH_KEY_PAIR fetch mode requires the result set to contain extactly 2 columns

PDO:: FETCH_CLASSTYPE ( 262144 )
Возвращает объекты класса, имя которого соответствует имени первого столбца результирующей строки. Это в теории. На деле же, если использовать её отдельно – возвращает смешанный массив, если совместно: PDO::FETCH_CLASS|PDO::FETCH_CLASSTYPE То возвращает объекты StdClass… Ещё народ пишет, что устанавливать значения можно только непосредственно в методах получения: PDOStatement::fetchAll() и PDOStatement::fetch(). А у меня так и не получилось создать объекты того класса, которого хотелось… В общем: хотели как лучше, получилось как всегда.
PDO::FETCH_SERIALIZE ( 524288 )
Доступен с PHP 5.1.0
Тоже что и PDO:: FETCH_INTO, но возвращаемые объекты представляются в виде сериализованной строки. От этой штуки я так и не получил адекватного результата, по ходу она глючит, так как на сайте php сообщается о каких то найденных багах… в общем следующий код:

  class myclass
  {
    public $id = '';
    public $foo = '';
    public $bar = '';

    public function __construct($a,$b,$c)
    {
      $this->id = $a;
      $this->foo = $b;
      $this->bar = $c;
      printf("%s()\n", __METHOD__);
    }
    public function __sleep()
    {
      printf("%s()\n", __METHOD__);
      return array_keys(get_class_vars(__CLASS__));
    }
    public function __wakeup()
    {
      printf("%s()\n", __METHOD__);
      return "any data from unserialize()";
    }
  }
  // Проверка возможности сериализации (не напортачил ли я чего…)
  echo '<pre>';
  $obj1 = new myclass('one','two','three');
  $tmp  = serialize($obj1);
  echo $tmp;
  $obj2 = unserialize($tmp);
  print_r($obj2);
  echo '</pre>';

  $stmt = $dbh->query("SELECT city,id,country_id FROM `gp_cities`");
  $stmt->fetchAll(PDO::FETCH_CLASS|PDO::FETCH_SERIALIZE, "myclass", array('one','two','three'));

Выдаёт следующее:

  myclass::__construct()
  myclass::__sleep()
  O:7:"myclass":3:{s:2:"id";s:3:"one";s:3:"foo";s:3:"two";s:3:"bar";s:5:"three";}myclass::__wakeup()
  myclass Object
  (
    [id] => one
    [foo] => two
    [bar] => three
  )
  myclass::__construct() SQLSTATE[HY000]: General error: cannot unserialize class

То есть стандартные функции: serialize() unserialize() отрабатывают нормально, а PDO::FETCH_SERIALIZE с какого то, не может восстановить объект, к тому же спрашивается на хрена его восстанавливать, если указано, что возвращается строка? Да к тому же зачем то вызывается конструктор. В общем проходим мимо :)

PDO::FETCH_PROPS_LATE ( 1048576 )
Доступен начиная с PHP 5.2.0 Используется, как правило в качестве дополнения: PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE Сообщает, что сначала нужно вызвать конструктор, а потом уже присвоить значения свойствам. То есть, если в конструкторе данные модифицируются, то при указании этой константы изменения в конструкторе пролетают мимо.
PDO::FETCH_ORI_NEXT (0 )
Получает следующую строку в наборе результатов. Работает только с прокручиваемыми курсорами.
PDO::FETCH_ORI_PRIOR ( 1 )
Получает предыдущую строку в наборе результатов. Работает только с прокручиваемыми курсорами.
PDO::FETCH_ORI_FIRST ( 2 )
Получает первую строку в наборе результатов Работает только с прокручиваемыми курсорами.
PDO::FETCH_ORI_LAST ( 3 )
Получает последнюю строку в наборе результатов. Работает только с прокручиваемыми курсорами.
PDO::FETCH_ORI_ABS ( 4 )
Получает запрашиваемую строку номером ряда из набора результатов. Работает только с прокручиваемыми курсорами.
PDO::FETCH_ORI_REL ( 5 )
Получает запрашиваемую строку с относительным положением от настоящего положения курсора в наборе результатов. Работает только с прокручиваемыми курсорами.
  $sql = 'SELECT * FROM `gp_cities` ORDER BY city DESC';

  $stmt = $dbh->prepare($sql,array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));

  $stmt->execute();

  while($row1 = $stmt->fetch(PDO::FETCH_OBJ, PDO::FETCH_ORI_NEXT) )
  {
    print_r($row1);
  }

Добавить комментарий


Защитный код
Обновить



Кто на сайте
Сейчас 101 гостей онлайн