2013-07-29 2 views
0

Я пытаюсь понять, как лучше всего использовать подготовленные команды mysqli, и я также довольно новичок в объектно-ориентированном PHP.Использование инструкции mySQL, подготовленной в нескольких экземплярах класса

Я понимаю, что подготовка инструкции, а затем ее выполнение несколько раз намного эффективнее, чем просто повторение одного и того же запроса.

Класс ниже выбирает звуковой объект по первичному ключу. Если мне нужно было иметь несколько экземпляров этого класса в том же скрипте, я бы получил преимущества подготовленного заявления?

Будет ли это хорошим кандидатом на хранимую процедуру?

class sound { 
    public $id; 
    public $name; 
    public $musickey; 

    public function __construct($id) { 
     $this->id = $id; 
     $sqli = new mysqli(); 
     if($stmt = $con->prepare("SELECT name, musickey FROM sounds WHERE id = ?")) { 
     $stmt->bind_param("i", $this->id); 
     $stmt->execute(); 
     $stmt->bind_result($name, $musickey); 
} 

Надеюсь, мой вопрос не является дубликатом. Я пытался найти что-то на эту тему, но иногда правильное решение может быть столь же сложно, как найти ответ.

ответ

2

Я понимаю, что подготовка инструкции, а затем ее выполнение несколько раз намного эффективнее, чем просто повторение одного и того же запроса.

Исправить. Поскольку подготовленный на стороне сервера оператор (то, что использует mysqli), только отправляет связанные аргументы в базу данных для последующих исполнений вместо всего запроса. Кроме того, серверу баз данных не придется переписывать запрос, но он может повторно использовать подготовленный. Таким образом, это может повлиять на получение данных. Поэтому теоретически это более эффективно.

См. http://php.net/manual/en/mysqli.quickstart.prepared-statements.php.

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

Он также имеет дополнительное преимущество protecting you from SQL Injection.

Класс ниже выбирает звуковой объект по первичному ключу. Если мне нужно было иметь несколько экземпляров этого класса в том же скрипте, я бы получил преимущества подготовленного заявления?

Нет. Поскольку mysqli будет запускать запрос серверу каждый раз, когда вы создаете новый экземпляр для подготовки этого утверждения. В дополнение к вызову выполнения. Таким образом, вы ничего не выигрываете. Было бы проще, а затем просто использовать что-то вроде

$query = sprintf('SELECT name, musickey FROM sounds WHERE id = %d', $id); 

, а затем выполнить, что в целом запрос, если вы действительно хотите один экземпляр каждого идентификатора.

Если вы хотите сделать это с помощью подготовленных операторов, вы хотите только один экземпляр, который готовит один раз, но вы можете передавать идентификаторы несколько раз.

Будет ли это хорошим кандидатом на хранимую процедуру?

Если вы положили логику приложения в хранимые процедуры, вы делаете свое приложение менее портативным. Если вы хотите изменить систему баз данных в какой-то момент, вам нужно будет воссоздать хранимые процедуры. Это зависит от вас, чтобы сделать осознанный выбор. Если вам не нужно менять систему базы данных, это может быть жизнеспособным.Я предпочитаю держать логику внутри приложения.

Я также довольно новичок в объектно-ориентированном PHP.

One aspect of OOP is about encapsulating and hiding information (и сложность) от клиента. Таким образом, наличие публичных объектов не является лучшей идеей. Кроме того, doing work in the constructor is not what the constructor is for. Конструктор должен поместить ваш объект в допустимое состояние. И поскольку подготовка делает запрос, который вы хотите отложить, пока он не понадобится.

С учетом всего сказанного, рассмотрим

interface FindById 
{ 
    public function findById($id); 
} 

class SoundFinder implements FindById 
{ 
    private $mysqli; 
    private $statement; 
    private $query = "SELECT name, musickey FROM sounds WHERE id = ?"; 

    public function __construct(mysqli $mysqli) 
    { 
     $this->mysqli = $mysqli; 
    } 

    private function prepare() 
    { 
     $this->statement = $mysqli->prepare($this->query) 
    } 

    public function findById($id) 
    { 
     if (!$this->statement) { 
      $this->prepare(); 
     } 
     $this->statement->bind_param("i", $this->id); 
     $this->statement->execute(); 
     $this->statement->bind_result($name, $musickey); 
     $this->statement->free_result(); 
     return array($name, $musickey); 
    } 
} 

Затем вы можете использовать его как это:

$connection = new mysqli(/* your connection data */); 
$soundFnder = new SoundFinder($connection); 
$sound42 = $soundFinder->findById(42); 
$sound314 = $soundFinder->findById(314); 
+0

Я знал, что мне не хватает чего-то довольно фундаментального. Я не думал о создании, а затем повторно использовал только один экземпляр класса. Отличное объяснение. Спасибо. – Brian

+0

Я не собираюсь поднимать мертвые потоки, но в функции подготовки, не должен ли это $ this-> mysqli-> prepare() ?? Если бы я был уверен, я бы отредактировал сообщение – Adsy2010

-1

является гораздо более эффективным, чем просто повторять один и тот же запрос.

Вы понимаете это неправильно.
Dunno, который сказал вам это, но нет «намного больше».
Разница вряд ли заметна и часто не стоит беспорядка. Особенно в случае такого простого поиска первичного ключа.

Я получаю выгоду от подготовленного заявления?

Я сомневаюсь.

Если такое место когда-нибудь узкое место (в только причины заморачиваться с какой бы то ни оптимизациями, заметьте), то wouild лучше выбрать все данные в один запросе.

Смежные вопросы