Блог


Переход с mysql на mysqli

Свершилось!

Старый добрый драйвер mysql  (не путать с СУБД MySQL) объявлен вне закона. Ну то есть deprecated  Пока не совсем, но всё же. Ликуют поборники универсальных и тормознутых классов-велосипедов для работы с СУБД, наконец то они увидели пользу от своих монструозных поделок. 

Да фиг с ними, пусть радуются. У нас возникла небольшая проблема и мы её сейчас решим. Решим без всяких "универсальных" велосипедов, во сто крат проще.


Что нужно, что бы перевести проект на mysqli Первым делом необходимо взвесить все за и против. Дело в том, что mysql  будет жить на хостингах еще минимум лет 20. Хостеры не дураки, создавать себе проблемы.  Панику разводят только  параноики, как в случае с концом света. 

 

 

 

 

Собственно ничего не случилось, просто объявили о прекращении поддержки. Дык mysql настолько обкатана, что в ней и не нуждается. Так что если проект работает, не трогайте его. Никакого профита не будет, это точно.

 

Но все же если прижало, не печальтесь. Все до безумия просто. Вот маленькая утилитка

(MMiC  Mysql  MysqlI  Converter), которая переведет ваш сайт с mysql на mysqli за несколько секунд. 

 

 

Не верите? Ну тогда смотрим, как это устроено.

 

Для начала уясним разницу. Драйвер mysqli предоставляет два интерфейса. Разрабы тоже не дураки и понимают, что не у всех тараканы в голове. Один интерфейс объектно-ориентированный. Второй процедурный. Второй на самом деле очень мало отличается от mysql. Вот его и зюзаем.

Основное отличие в том, что теперь для организации запроса в основную функцию необходимо передать объект, а не указатель на ресурс. А его не поместишь в константу. И передать его нужно обязательно. Причем передать его нужно первым аргументом,  не вторым. Так что тут нам не обойтись без обертки. Если кто юзал обертку, ему проще. Кто не юзал, сейчас научу. Обертка, это пользовательская функция, которая расширяет возможности штатной. Ну или подстраивает её под свои нужды. Вот мы и напишем сейчас такую, которая будет похожа на mysql_query():


1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
<?php


    $link 
= @mysqli_connect('localhost''root''''test'
                           or die(
'No connect'); 


    function 
mysqlQuery($sql
    {
        global 
$link
     
        
$result mysqli_query($link$sql
                  or die(
mysqli_error($link)); 
     
        return 
$result;
    }

 

 В таком виде она уже готова к работе. Но это не есть гут. Мы передали объект в функцию из глобального пространства. Сам по себе global не так страшен, как его малюют, но в нашем случае он не годится.

 

Дело в том, что этот объект требуется аргументом не только в этой функции. Но и во многих других. Допустим mysqli_insert_id() А она может находиться где угодно, в любой нашей функции или классе. Прописывать в каждую функцию global $link; мы задолбаемся. Так что нужно решить проблему раз и на всегда.

Делается это очень просто. Пишем маленький классик и делаем этот линк свойством.

1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
<?php



class DB
{
    static 
$link;
    static 
$count 0

    
    public static function 
connect()
    {
// Синглтончик-с в целях экономии
        
if(empty(self::$link))
        {
            
self::$link = @mysqli_connect('localhost''root''''test'
                           or die(
'No connect'); 
            
            
mysqli_set_charset(self::$link'utf8');
        }
    }
}

// Запускаем не отходя от кассы
    
DB::connect();

 

Поместить этот класс нужно в файл с названием db.php в доступном для автолоада месте. Ну или просто подключать по мере необходимости. В классе реализован синглтон, а значит мы будем иметь только один коннект, сколько раз бы не дергали класс.

Теперь эта переменная доступна в любом месте. Стоит только прописать так:

1
 2
 3
 4
 5
 6
 7
 8
 9
 10
<?php


    
function mysqlQuery($sql
    {
        
$result mysqli_query(db::$link$sql
                  or die(
mysqli_error(db::$link)); 
     
        return 
$result;
    }    

 

По факту мы получили глобальную переменную без явного объявления её таковой. И обертка теперь у нас приняла подобающий вид, и можно продолжать реплейсить свой проект.

Дальше все просто. Берем функцию mysql и меняем её на аналог mysqli.

 

Так вот, утилитка MMiC делает это все сама. И создает класс, и меняет функции.

 

Нужно отметить, что не все аналоги есть. Допустим понадобится новая реализация функции mysql_result(). Утилитка сделает и это. А остальные используются очень редко, программа покажет, где они присутствуют в проекте. И тогда можно что-то с ними решить. Либо написать свою реализацию, либо исключить из логики.

 

Главное не забывайте подключить новый файл коннекта. Он должен быть доступен отовсюду, где есть запросы.

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

 

Ну и удачи. Если что не так - пишите)

 

Николай aka twin
Теги: MySQL

Комментарии (26)

Alex
02-04-2013
Спасибо за статью!
Андрей
02-04-2013
Я согласен с "Дело в том, что mysql  будет жить на хостингах еще минимум лет 20. Хостеры не дураки, создавать себе проблемы. "  Поэтому пока не перехожу)
Андрей
02-04-2013
twin а ты перевел свои поделки / рабочие проекты на mysqli ?? или пока тоже не паришься ?
twin
02-04-2013
Я перевел. Для того и писал утилитку. Это не столько из-за паранойи, сколько из-за того, что бы не было разброда в версиях. Обновления я пишу на I, а они не пойдут на старые проекты.
Иван
05-04-2013
twin: В классе реализован синглтон

Это ни синглтон никакой, во даешь
twin
06-04-2013
А что это? И что же тогда синглтон?
Иван
08-04-2013
Что такое Синглтон, описано в той же википедии: Гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа.
А то что у вас реализовано, просто проверка на непустоту переменной, даже статической переменной внутри функции лучше это можно было бы реализовать,без класса. Ее то внутри функции не поменяешь, а у вас любой код внешний может ее затереть...
twin
08-04-2013
Википедию пишут люди. Порой случайные. И она никак не может являться авторитетным источником. Это просто чье то частное мнение. А синглтон происходит от слова сингл, одиночка. Синглтон должен гарантировать единичое исполнение какого то действия при попытке многократного вызова. В нашем случае нет никаких экземпляров, класс статический. Это тоже частная реализация синглтона. Если мы несколько раз обратимся к методу, коннект все равно будет осуществлен единожды. Что уже есть суть синглтон. Просто нужно мыслить шире, а не хватать верхушки, тем более в сомнительных источниках.
Иван
14-04-2013
Википедию пишет сообщество, оспаривать инфу из википедии - моветон.
Да про этот паттерн и его смысл сказано не только в вики.
Все что ты своим кодом сделал - это используешь класс, как глобальную переменную.
Налицо непонимание ооп кухни.
У тебя же в любом участке кода можно написать DB::$link = @mysqli_connect(что то новое) и линк изменится. Все как в тупой глобальной переменной. А паттерн синглтон КАК РАЗ ОТ ТАКОГО должен защищать.
twin
20-04-2013
Википедию пишет сообщество, оспаривать инфу из википедии - моветон.
Именно. Сообщество. Кто во что горазд. А авторитетным источником можно считать только стандарты. В RFC есть подобное определение к примеру?

Моветон, это принимать на веру чужое мнение. И тем более выдавать его за догму.

Да, я использую свойство, как глобальную переменную. О чем и сразу написал. Только причем тут синглтон? Синглтоном организован коннект. Можно хоть сто раз вызвать метод DB::connect(), соединение с СУБД будет осуществлено только один раз. Это и есть синглтон, его частная реализация. Всё, остальное - демагогия чистой воды.

Еще раз повторю, нужно смотреть шире и не путать задницу с пальцем. Мне нужна была глобальная переменная, я её организовал. Нужно было уберечься от множественного коннекта, я организовал синглтон. Что там пишут в википедии такие как ты традиционалисты, мне плевать. Ибо признавать авторитетными источниками могу только стандарты и мануал разработчика ЯП. Для программиста важна неортогональность, возможность решения задач различными, в том числе и оригинальнымим способами.

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

Человек должен быть свободным. Программист тем более. Именно на этом держится прогресс, потому что повторять за другими ума много не нужно.
Павел
14-04-2013
Как ее запустить? Скачал, запускаю, ничего не происходит.
Иван
15-04-2013
Я бы вообще побоялся и поостерегся запускать код от таких товарищей.
Которые очевидные и общеизвестные вещи имеют склонность отрицать.
Не говорит о их адекватности. А программист ДОЛЖЕН быть адекватным, чтобы верно оценивать ситуацию.
Запустишь эту программку, она тебе и пол диска сотрет, кто его знает что они там умеют вообще.
twin
20-04-2013
А ни кто и не заставляет

Ходи строем, дуй на воду, не ход в лес, там волки. И вообще, чего привязался, ну со мной споришь, пожалуйста. К людям чего лезешь? Альтруист-благодетель?
twin
20-04-2013
Обратитесь в техподдержку, разберемся.
killervampire
20-04-2013
Хотелося бы подробнее прочитать про рубрикатор. Хотя он и есть в уроке про блог №2, но вот както мало слишком информации ДЕТАЛЬНОЙ (вакуум) про него ...
akuchkovsky
01-05-2013
Добрый день. А почему не MariaDB?

http://www.netangels.ru/support/overview/mysql-vs-mariadb/
twin
09-05-2013
Ну наверное потому что тут рассматривалась именно MySQL
Анна
21-05-2013
Статья супер, единственное место где нормально все описано, на своих ошибках конечно учатся, но не всегда есть время, спасибо большое за статью)
kp
24-07-2013
Спасибки, отличная статья. Наконец-то нормальное адекватное мнение, а не "срочно все переделываем, несмотря на отсутствие еще нормальной документации".
DupleX
09-09-2014
Интересно, спасибо.

Я пожалуй дополню класс старой поддержкой mysql для PHP4, пока он есть на некоторых хостингах

1
2
3
4
5
6
7
8
9


if(!function_exists("mysqli_connect")) 
{
// PHP4 code

}



Это можно в самом классе сделать, или сделать родительский - 2 дочерних. Кода немного, так что оба варианта приемлимы.
Дима
05-01-2015
Растолкуйте мне пожалуйста? Сервер irsys поддерживает mysqli?
twin
06-01-2015
Разумеется. Все наши уроки построены на mysqli_
Дима
06-01-2015
http://irbis-team.com/15/21?PHPSESSID=7fdc6237dd62a3725f2d297d20908d6e
Вот этот пример не пашет.

Warning: mysqli_query() expects at least 2 parameters, 1 given in C:\WebServers\home\localhost\www\test\www\index.php on line 6

Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, null given in C:\WebServers\home\localhost\www\test\www\index.php on line 10
twin
08-01-2015
Да. Там действительно была ошибка в листинге.
Исправили.
Дима
30-04-2015
Не подскажете, почему выдаёт непрестанно вот такую ошибку?

Warning: mysqli_fetch_array() [function.mysqli-fetch-array]: magic_quotes_runtime are deprecated since PHP 5.3
twin
02-05-2015
Это потому что включены "магические кaвычки".
Alex
03-03-2016
Большое спасибо за утилиту! Перевел свой проект - все работает.

 
Наверх