call to undefined function mysqli init

Полет нормальный. Без происшествий.

Переход на PHP7: работа над ошибками

Итак, у вас есть старенький, но уж очень милый сердцу сайт, который вы решаетесь из жалости (или, возможно, перечитав Хабра) перевести на PHP7. С волнением ожидая резкого роста производительности, вы смахиваете пыль с бедного сайта и решительно переключаете в панели управления хостингом версию PHP.

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

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

Резервные копии

Делаем резервные копии сайта (а заодно и баз данных). Ведь кто не делает резервные копи — сам себе враг, верно? Для разного рода экспериментов имеет смысл добавить еще один сайт на хостинге и скопировать в него файлы, которые мы сейчас будем править.

Журналы ошибок

Настроим ведение журнала ошибок PHP в файл .htaccess (если он не был настроен ранее):

php_value display_errors 0
php_value log_errors 1
php_value error_log /home/vasya/domains/mysite.ru/logs/error.log

Работа с MySQL

Допустим, сайт использует базы данных, и вы видите ошибки вроде такой:

Fatal error: Uncaught Error: Call to undefined function mysql_connect()

Это оттого, что в современных версиях PHP (начиная с PHP 5.5.0) оригинальное расширение MySQL не поддерживается. Разработчики рекомендуют использовать MySQLi или PDO. Попробуем перейти на MySQLi, это просто:

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

$link = mysql_connect(‘localhost’, $user, $password)
mysql_select_db($dbname, $link)
mysql_query(‘set names cp1251’)

можно заменить на:

$link = mysqli_connect(‘localhost’, $user, $password, $dbname)
mysqli_query($link, ‘set names cp1251’)

Другие популярные функции легко меняются на их аналоги с буквой ‘i’:

mysqli_fetch_array()
mysqli_fetch_row()
mysqli_fetch_assoc()
mysqli_fetch_array()
mysqli_num_rows()
mysqli_insert_id()
mysqli_close()

В результате этих несложных действий данные из БД должны успешно собираться и отправляться.

Кодировка

Настоящий олдскул — это сайт в CP1251 (как минимум). Всё превратилось в ромбики или прочие козяблики?

Скорее всего, достаточно будет указать кодировку в .htaccess таким образом:

php_value default_charset «cp1251»

Регулярные выражения

Также вы можете наблюдать ошибки следующего рода:

Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead

Это означает, что модификатор /e, который позволял передать произвольной функции результат регулярного выражения, теперь не поддерживается. В таких случаях рекомендуется использовать функцию preg_replace_callback

Допустим, у нас есть такое регулярное выражение:

с заменой на preg_replace_callback оно должно выглядеть вот так:

$string=preg_replace_callback(«/:([a-z]<1,10>):/», create_function(‘$matches’, ‘return print_smile($matches[1])’), $string)

здесь все просто, регулярное выражение теперь указывается в качестве первого аргумента (без модификатора /e, разумеется), а в качестве второго аргумента указывается анонимная функция (которая будет выполнена после применения регулярного выражения) с двумя аргументами: массив $matches, где будут сохранены данные, совпадающие с регулярным выражением и вызов внешней функции с аргументами. В данном примере внешняя функция называется print_smile и ей передается аргументом первое найденное вхождение. То, что в preg_replace было \1 (первое найденное вхождение) станет $matches[1] (если аргументов было больше, то будет $matches[2], $matches[3] и так далее).

Вот еще один пример, посложнее:

$out=preg_replace_callback(‘/ (.*?) /s’, create_function(‘$matches’, ‘return feed_out_sub_rm($matches[2], «‘.$base_prefix.’», «‘.$nick.’», «‘.$id_entry.’») ‘), $out)

здесь легко запутаться в кавычках, будьте внимательны.

Копаясь в регулярных выражениях, можно вспомнить еще про две функции, которые с версии PHP 5.3.0 считаются устаревшими (и не поддерживаются). Симптомы следующие:

Fatal error: Uncaught Error: Call to undefined function ereg_replace()

Если регулярное выражение в ereg_replace простое, то можно обойтись просто установкой граничных символов, как здесь:

Fatal error: Uncaught Error: Call to undefined function split()

Если регулярное выражение посложнее, то пробуем преобразовать к preg_split.

На этом пока все. Удачной отладки.
Много полезных материалов по теме можно найти на сайте разработчиков.

Если что-то не получается, или ваш случай совсем не похож на наши примеры — пишите комментарии, попробуем разобраться вместе.

Для того, чтобы оставлять комментарии к посту, авторизуйтесь, используя свой аккаунт в социальных сетях ВКонтакте/FaceBook, или аккаунт в Google/Яндекс.

Всем привет. Перенёс сайт на ВМ Centos 7.
Набор джентльмена: apache, php, mysql.

Запустил файл restore.php развернул бэкап, отдельно развернул дамп в бд. Захожу на сайт, получаю:

Следуя тому, что выдал гугль, в файле /bitrix/php_interface/dbconn.php добавил константу define(«BX_USE_MYSQLI», false), а в файле /bitrix/.settings.php изменил ‘\Bitrix\Main\DB\MysqlConnection’ на ‘\Bitrix\Main\DB\MysqliConnection’. Ошибка всё равно остаётся.

Были рекомендации
1) раскомментировать в php.ini строку «extension=php_mysqli.dll», но у меня её нет.
2) по пути «/etc/php.d/» создать файл «30-mysqli.ini» и добавить туда строку «extension=mysqli.so». Ошибка осталась. Я понять не могу, почему ошибка сохраняется.

phpinfo() отрабатывает хорошо.
Подскажите, в какую сторону можно ещё копнуть?)

При развертывании резервной копии сайта на Bitrix у себя на хостинге увидел ошибку:

Fatal error: Call to undefined function BitrixMainDBmysql_connect() in . on line 40

Как оказалось, на предыдущем хостинге использовался PHP 5.x, а на моем PHP 7.0, а mysql_connect «. устарело, начиная с версии PHP 5.5.0, и удалено в PHP 7.0.0. Используйте вместо него MySQLi или PDO_MySQL.«

В Bitrix нужно включить использование mysqli_connect следующим способом (подсказал знающий человек, сам бы долго разбирался)

  1. В конце файла itrixphp_interfacedbconn.php , перед ?> , нужно добавь строку define(«BX_USE_MYSQLI», true);
  2. В файле itrix.settings.php , в настройках
    ‘connections’ =>
    array (
    ‘value’ =>
    array (
    ‘default’ =>
    array (
    ‘className’ => ‘\Bitrix\Main\DB\MysqlConnection‘,
    ‘host’ => ‘localhost’,
    ‘database’ => ‘dbName’,
    ‘login’ => ‘root’,
    ‘password’ => ‘123456’,
    ),
    ),
    ),
    Заменить на ‘className’ => ‘\Bitrix\Main\DB\MysqliConnection‘,

Все заработало, Bitrix «завелся»)

Проблема описана еще в 2014 году на форуме Bitrix, и может возникнуть на старых проектах, в обновлении ядра 14.5.2 добавлена полная поддержка mysqli. Включать mysqli нужно отдельно для старого и нового ядра.

Оцените статью