The only proper guide on PDO (eng.)

Фанат

oncle terrible
Команда форума
По сути оно пишется исключительно ради "…->prepare()->execute();", ибо достало.
Больше ни для чего.
Я пришел к выводу, что лучше отдельный метод сделать для этого. Получится и короче, и мутить со своим классом не надо.

PHP:
$db->run($sql, $params) ->fetch();
//все равно лучше чем
$db->prepare($sql)->execute($params)->fetch();
- то есть, копья ломать не из-за чего
 
Последнее редактирование:

AnrDaemon

Продвинутый новичок
Ну, вероятно, да. Выкинуть StatementWrapper и закрыть тему.
Спасибо за идею.
 

Фанат

oncle terrible
Команда форума
Кстати, никто не высказался по таким животрепещущим темам, как, например, эякуляция эмуляция.
А я ведь там Феррару пнул. Все больше мне кажется, что единственная область,в которой он специалист - это торговля лицом.
 

fixxxer

К.О.
Партнер клуба
А что не так с тем комментом Феррары? Вроде все корректно - "PDO prepares will not defend you from all possible SQL-Injection attacks. For certain obscure edge-cases", ну и вполне корректный кейс (хоть и маловероятный). Истерики не вижу - ну разве что некоторая некорректность в том, что суть проблемы вовсе не в prepares :)
 

AnrDaemon

Продвинутый новичок
Некорректность там не некоторая. Там именно выбран кейс, не имеющий отношения к обсуждаемой проблеме.
Если это то, и чём я думаю.

@Фанат, "Calling stored procedures in PDO" - PDOStatement::closeCursor() не?
 

Фанат

oncle terrible
Команда форума
"Calling stored procedures in PDO" - PDOStatement::closeCursor() не?
Ну, это скорее костыль, или даже лом. Тупо закрыть, похерив все результаты - это неправильно. Там ниже, в разделе про мультизапросы объяснено, как мне кажется, довольно убедительно.
 

AnrDaemon

Продвинутый новичок
Не тупо закрывать, а закрывать, когда больше не нужны результаты.
Зачем наворачивать малопонятный код, когда можно просто сказать "Ша, свободен! Следующий!"…
 

Фанат

oncle terrible
Команда форума
А что не так с тем комментом Феррары? Вроде все корректно - "PDO prepares will not defend you from all possible SQL-Injection attacks. For certain obscure edge-cases", ну и вполне корректный кейс (хоть и маловероятный). Истерики не вижу - ну разве что некоторая некорректность в том, что суть проблемы вовсе не в prepares :)
Понимаешь, это вопрос восприятия.
Средний бабуин понимает эту историю так - "эмуляция небезопасна!!!!11111".
плюс этих едж кейсов больше не осталось - все давно пофикшено. Юзаешь неподдерживаемую версию - это твоя проблема, не софта. Там и других багов будет дофига.
Ок, сменю hysterical на appealing, но мне не нравится, как он розжигает.
 

Фанат

oncle terrible
Команда форума
Не тупо закрывать, а закрывать, когда больше не нужны результаты.
Зачем наворачивать малопонятный код, когда можно просто сказать "Ша, свободен! Следующий!"…
а где ж там малопонятный? Для единственного результата просто просто nextRowset()
Если у нас есть еще один ровсет, то правильно будет сделать некст, а не рубить с плеча.

А если у нас много результатов, то закрывать в принципе нельзя.
 

AnrDaemon

Продвинутый новичок
Сколько там всего результсетов - вопрос десятый.
Если они тебе нужны - ты БУДЕШЬ юзать PDOStatement::nextRowset().
А если ты знаешь, что там нет ничего интересного - нафига?…
 

Фанат

oncle terrible
Команда форума
Сколько там всего результсетов - вопрос десятый.
Если они тебе нужны - ты БУДЕШЬ юзать PDOStatement::nextRowset().
А если ты знаешь, что там нет ничего интересного - нафига?…
если знаю, то выбор между closeCursor() и nextRowset().
Я не вижу принципиального преимущества первого над вторым, и не вижу, почему второе малопонятнее первого.
при том что второе более последовательно и менее грубо.
 

fixxxer

К.О.
Партнер клуба
Понимаешь, это вопрос восприятия.
Средний бабуин понимает эту историю так - "эмуляция небезопасна!!!!11111".
плюс этих едж кейсов больше не осталось - все давно пофикшено.
Остались в фреймворках (старых версий), которые charset пихают в init command -> set names в целях совместимости.
Вот, скажем, я не уверен насчет Yii1, кажется, там что-то такое видел. Или в Laravel 4, что ли? Не помню, но где-то было.
 

AnrDaemon

Продвинутый новичок
Виноват, каюсь…
Код:
PDO::MYSQL_ATTR_INIT_COMMAND => version_compare('5.3.6', '<') ? 'SET NAMES utf8;' : '',
 

AnrDaemon

Продвинутый новичок
Здесь начали, здесь, пожалуй, и закончим.
PHP:
class PDOWrapper extends PDO
{
// public mixed  errorCode ( void )
// public array  errorInfo ( void )
// public int    exec ( string $statement )
// public mixed  getAttribute ( int $attribute )
// static array  getAvailableDrivers ( void )
// public string lastInsertId ([ string $name = NULL ] )
// public string quote ( string $string [, int $parameter_type = PDO::PARAM_STR ] )
// public bool   inTransaction ( void )

/*
// public bool beginTransaction ( void )
  public function beginTransaction()
  {
    parent::beginTransaction();
    return $this;
  }

// public bool   commit ( void )
  public function commit()
  {
    parent::commit();
    return $this;
  }

// public bool   rollBack ( void )
  public function rollBack()
  {
    parent::rollBack();
    return $this;
  }
*/

// public __construct ( string $dsn [, string $username [, string $password [, array $options ]]] )
  public function __construct($dsn, $username = null, $password = null, $options = array())
  {
    parent::__construct($dsn, $username, $password, $options);
    $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
      ->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
  }

// public bool   setAttribute ( int $attribute , mixed $value )
  public function setAttribute($attribute, $value)
  {
    parent::setAttribute($attribute, $value);
    return $this;
  }

  public function run($query, $arguments = array())
  {
    $stmt = $this->prepare($query);
    $stmt->execute($arguments);
    return $stmt;
  }

  public function get($query, $arguments = array())
  {
    return $this->run($query, $arguments)->fetch();
  }

  public function getColumn($query, $arguments = array())
  {
    return $this->run($query, $arguments)->fetchColumn();
  }

  public function getAll($query, $arguments = array())
  {
    return $this->run($query, $arguments)->fetchAll();
  }
}
Сделать PDOWrapper::run() приватной или так оставить?…
 

AnrDaemon

Продвинутый новичок
Вот раздел "Running multiple queries with PDO" я не понял.

PHP:
$res = $_pdo->query('SELECT 1 as `id`; SELECT 2 as `id`');

print_r($res->fetchAll());
while($res->nextRowset())
  print_r($res->fetchAll());

$res = $_pdo->query('SELECT 3 as `id`');
получаю
Код:
PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2014 Cannot execute queries
while other unbuffered queries are active.  Consider using PDOStatement::fetchAll().  Alternatively, if your code is only ever
going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.' in
C:\home\Daemon\Documents\_PHP\PDOWrapper\Check.php:33
Stack trace:
#0 C:\home\Daemon\Documents\_PHP\PDOWrapper\Check.php(33): PDO->query('SELECT 3 as `id...')
#1 {main}
  thrown in C:\home\Daemon\Documents\_PHP\PDOWrapper\Check.php on line 33
Нужна какая-то особая версия PHP/MySQL?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
а вы не могли бы для умственно отсталых заодно и ссылку на упоминаемые обсуждения постить? :) а то ж непонятно оп чом вы

по поводу статьи, я бы предложил правки spelling немного, статья на гитхабе есть?
 

hell0w0rd

Продвинутый новичок
По сути оно пишется исключительно ради "…->prepare()->execute()->fetchAll();", ибо достало.
Больше ни для чего.
оО. А чего бы не завернуть в ...->fetch('...', [$userId]); ?)
А вообще как можно столько эту тему мусолить, все уже умные люди давно написали: https://github.com/nkt/flame :D
 
Сверху