Pull to refresh

Comments 63

Прощу прощения. Вам времени не жалко своего?
Просто я считаю работу с БД таким образом — просто потерей времени. Есть достаточное количество ORM на PHP, которые действительно способны сократить время разработки.
Бесспорно. Но значит ли это что можно не уметь работать с БД без них. Я вот тоже пользовался возможностями фрейморков и уже забыл как работать с БД напрямую, а тут понадобилось переносить базу данных, где некоторые таблицы сотни мегабайт. Вы можете сказать про сервера с десятками гигабайт оперативки, но в моем случае не было таких серверов, а был средний впс, а делать нужно.
Придет время, когда наравне с обычными таблицами будут здоровенные view'хи. Тогда sql вспоминается на раз и узнается о нем много нового. А составлять запросы, когда через ORM это будет быстрее, секурнее и ООП-шнее — не стоит.
>> А составлять запросы, когда через ORM это будет быстрее, секурнее и ООП-шнее — не стоит.
Птому что это не круто? ;-)
Угу, а потом DBA за голову хватаются, когда видят, что ORM нагенерил.

ORM не отменяет необходимости писать некоторые запросы вручную.
Много вы DBA знаете в веб-разработке?
Много вы DBA знаете, которые не умеют работать с ORM?
Много ли DBA вы знаете?
1. да
2. им пофигу на ОRМ, вообще. DBA сказал, как написать запрос — разработчик пишет, если ОRМ не позволяет, значит, выбросить ОRМ.
3. да
По-вашему, веб-разработка это только сайтики что ли? Мы занимаемся облачным докуменооборотом, там основной клиент — браузер. Хитов дикое количество, без оптимизации запросов не обойтись. И да, у нас есть DBA и не один.
Если статья окажется кому-то полезной, то жалеть будет не о чем. Статей по mysqli не русском совсем не много, внес свой посильный вклад.
По статье видно что труд приложили, но…
а) В начале была затравка про сравнение с PDO, но его так и невидно
б) Сама статья по сути рерайт мануала по php, ни сравнений (даже с mysql), ни особенностей, ни нюансов, ни специфических функций (тех же асинхронных запросов).
в) Код сам по себе тоже любопытен. Получение результата селекта начиная с выполнения запроса — 16 строк кода с комментами и в случае ошибки die, как-то это не очень в плане демонстрации «как надо делать».
а) Извиняюсь, если кого ввел в заблуждение, не хотел, в будущем буду осторожнее
б) Не соглашусь. Я понимаю, что могло сложиться такое впечатление из за справочного стиля изложения. В мануал я заглядывал только для того что бы посмотреть какие примеры там используются. Текст писал исключительно из головы. Нюансы особенности и специфичные функции которые мне показались интересными я осветил, если это не заметно, видимо не получилось.
В) Примеры слабые не спорю. Основной упор делал на текст.
Ещё внесу свои 5 рублей в казну — код ужасен. Если вы начинающий — ещё не страшно (пока), но пора смотреть в сторону идеализации кода до удобочитаемого уровня. Тем более, что это примеры. Ваши читатели будут использовать конструкцию с шестью(!!!) «or», а потом их уволят нахрен.
Было бы не плохо, если бы кто нибудь написал алтернативный более правильный красивый код этого фрагмента с 6 OR.
Очень примерно:

  1. class Result
  2. {
  3.  private $stmt = null;
  4.  private $result = null;
  5.  public function __construct($min, $max)
  6.  {
  7.      $stmt = $mysqli->stmt_init();
  8.      try {
  9.          $this->prepare();
  10.          $this->bind($min, $max);
  11.          $this->execute();
  12.          $this->attachResult();
  13.          $this->store();
  14.          $this->fetch();
  15.          $this->close();
  16.     } catch (Exception $e) {
  17.      Debug.log('Select Error (' . $stmt->errno . ') ' . $stmt->error);
  18.     }
  19.  }
  20.  
  21.  // подготовливаем запрос, там куда будут вствлятся данные отмечаем символом ? (плейсхолдоры)
  22.  private function prepare()
  23.  {
  24.     $this->stmt->prepare("SELECT title FROM sk2_articles WHERE id > ? and id < ?")
  25.  }
  26.  
  27.  // привязываем переменные к плейсхолдорам
  28.  private function bind($min, $max)
  29.  {
  30.     $this->stmt->bind_param('ii', $min, $max);
  31.  }
  32.  
  33.  // отрправляем даные, которые на данный момент находятся в привязанных переменных
  34.  private function execute()
  35.  {
  36.     $this->stmt->execute();
  37.  } 
  38.  
  39.  // привязывем переменую для получения в нее результата
  40.  private function attachResult()
  41.  {
  42.     $this->stmt->bind_result($this->result);
  43.  }
  44.  
  45.  // делаем запрос буферизированным,
  46.  // если бы этой строки не было, запрос был бы небуферезированым 
  47.  private function store()
  48.  {
  49.     $this->stmt->store_result();
  50.  }
  51.  
  52.  // получение результата в привязанную переменную
  53.  private function fetch()
  54.  {
  55.     $this->stmt->fetch();
  56.  }
  57.  
  58.  private function close()
  59.  {
  60.     $stmt->close();
  61.  }
  62.  
  63.  public function getResult()
  64.  {
  65.     return $this->result;
  66.  }
  67. }
  68.  
  69. $id_min = 81;
  70. $id_max = 88;
  71. $result = new Result($id_min, $id_max);
  72. print $result->getResult();
* This source code was highlighted with Source Code Highlighter.
Спасибо за пример.
Во время написания статьи думаешь не сколько о применимости кода, сколько об его наглядности и краткости. Ни кто не хочет разбираться в большом коде. К тому же мне кажется любому очевидно, что в статьях подобно этой выкладывают не готовые решения, которые можно использовать в продакшин.
Ну и смысл тянуть эту портянку в демо-статью — показать, что GoF прочитал? Замечания на будущее: комментарии — на английском, в формате phpdoc (а не коменнтариями, как сейчас). И self-described члены класса обычно не требуют description.
скорее Фаулера по рефакторингу я прочитал
Ожидал увидеть асинхронные запросы.
Вы наверное о небуферизированный запросах. Я старался раскрыть тему, что бы было понятно как их делать. С примерами, к сожалению действительно как то плохо. Боялся, что будет слишком объемно, видимо зря.
Нет, именно о асинхронных.
Пример из мануала:
ru2.php.net/mysqli.poll#refsect1-mysqli.poll-examples

Асинхронные запросы доступны если расширение скомпилировано с использованием mysqlnd (используется по умолчанию начиная с PHP 5.4).
Так в чем преимущество в сравнении с PDO?
Про недостаток я написал. Про преимущество ни чего не скажу, так как не работал с PDO.
В век серверов по 50 евро с 24 Гб памяти эти недостатки как-то теряются на фоне.
Видимо вы не о том недостатке. Я о том, что в MySQLi плейсхолдоры не могут быть именованными, и соответственно мы зависим от порядка их объявления.
Тогда вообще: возьмите на вооружение Doctrine ORM или Propel ORM. Про низкоуровневые слои типа PDO или mysqli — забудьте. Вспоминайте про них только тогда, когда это будет ну очень нужно. Разницы нет, честно.
Ждал этого коммента) Написали бы это с самого начала… +1
Как только я увидел что у mysqli неименованные плейсхолдеры, это полностью исключило этот бакенд в качестве использования… PDO, только PDO, к тому же позволит максимально легко сменить базу данных в будущем.
Значит, закон 94-ФЗ вас не касается. Повезло.
real_connect()
real_query()
real_escape_string()

Я понимаю, разработчики MySQL долбанутые, у них самые часто используемые функции начинаются с «real_».

Я понимаю, разработчики расширения mysql тупо один-в-один скопировали API MySQL со всеми идиотскими префиксами.

Но вот на кой ИКС разработчики MySQLi вытворили то же самое? У разработчиков PHP какая-то болезненная любовь к «безопасным» префиксам?

А если бы разработчики MySQL назвали функции mysql_secure_escape_string_with_support_for_character_encoding, разработчики PHP его точно так же скопировали бы? Так ведь это время не за горами, для MySQL придумают новую версию, старые оставят для обратной совместимости и пометят устаревшими.
Если судить по минусам, то всем очень удобно перед каждой функцией писать «real_».

Неожиданно.
Не всем. Мне удобнее «unreal_».
Последние годы я писал сайты исключительно на фреймворках, что избавляло меня от работы с БД напрямую. Некоторое время назад начал работу над сайтом на чистом php

Зачем понадобился чистый PHP, к слову?
а это нормальный период. Многие через него проходят и не редко есть идея: «Создать свой фреймворк». Ну или подобное что-то.
Жалко денег на дорогой сервер. Сайт приносит мало денег, а посетителей много, хотелось что бы ни чего лишнего небыло, тогда можно обходиться средним vpsом
средним vps'ом можно обходиться если правильно продумать кэширование ;)
Вот хочет заказчик видеть реальное число просмотров поста в блоге, чтоб на каждое F5 цифра была новая, и запрос к БД уже надо делать. А главное PHP вызывать нужно.
(a) чтоб на каждое F5 цифра была новая, и (b) запрос к БД уже надо делать

Из а не следует b. Что мешает обновить счетчик в кеше при регистрации просмотра?
Смотря о каком кеше речь идёт. Одно дело о кеше страницы для анонимусов, другое даже для тысячи зареганных пользователей, у каждого из которых своя страница, большая часть из которых могут эту страницу и не открыть. Третье — кеш запроса к БД.
О кеше количества просмотров поста в блоге. В данном случае не вижу разницы между анонимусами/зареганными пользователями — один инкремент счетчика в мемкеше/редисе решает вопросы с рил-тайм апдейтами для любого типа пользователей.
Это будет кеш запроса к БД, а не кеш страницы. И есть подозрение, что большого выигрыша кеширование в мемкеше запроса вроде SELECT * FROM posts WHERE id = ? не даст, поскольку СУБД тоже кешировать умеет.
MySQL из рук вон плохо кеширует — при любом изменении таблицы сбрасываются кеши всех запросов, в которых эта таблица участвовала, даже если изменилась запись, которая в резалт-сетах не встречалась. Так что память лучше потратить на buffer pool (key cache для MyISAM) и кешировать данные вне базы (разумеется более интеллектуально).
Ладно вам уже, у любого решения есть критерий разумной применимости. Если заказчик хочет realtime счетчик и готов за это платить железом — флаг ему в руки =) Если не готов, но может раскошелиться на бОльший срок разработки — аналогично. Флаг в руки, только другой расцветки. Можно хоть аккумулировать эти счетчики в redis и скидывать в БД по времени или кол-ву хитов.

А если заказчик хочет и рыбку съесть и удовольствие получить — то нужен ли вам такой заказчик? ;)
Ну вся эта ветка началась с предположения, что железо сильно ограниченно, от того и пляшем.
А вот про это планировал написать, но забыл. Для создания постоянного подключения необходимо перед именем хоста при создании подключения добавить «p:». Изначально этой возможности в mysqli не было, но с версии PHP 5.3 ее вернули.
Отлично. Я не знал об этом синтаксисе и «отсутсвие» pconnect в MySQLi было для меня сдерживающим переход на MySQLi фактором
UFO just landed and posted this here
Там вон выше ОРМ обсуждают, а вы тут про скорость плейсхолдеров :)
денег например :(
И чем это отличается от официальной документации? То же самое другими словами. Никаких собственных мыслей не привнесено.
Кстати забавный аргумент про возможность «легко» перескочить на другую базу, вот сколько не было проектов ну не разу не пригодилось.

И еще один забавный момент — бывают проекты где вся логика зашита в базе, и данные получаются посредством процедур, там вообще пофиг что использовать, хоть ORM, хоть PDO, хоть mysqli, правда, если не изменяет память кто то из последних двух не умеет принимать множественный результат.
PDO выйграл.

/**
* @var PDO
*/
$db;

$statement = $db->prepare($sql);

$statement = $db->execute(array($param));

$result = $statement->fetchAll();

// Ещё короче.
$statement = $db->query($sql, array($param));

$result = $statement->fetchAll();
Неправда, выйграл войн.
Sign up to leave a comment.

Articles